#include "subrou.h"
#include "unipar.h"
+#include "unieml.h"
#include "devsoc.h"
#include "gestcp.h"
/* Procedure to send a line to remote */
/* */
/********************************************************/
-static void dooutgoing(SOCPTR *socptr,char *line)
+static int dooutgoing(SOCPTR *socptr,char *line)
{
-(void) soc_writebuffer(socptr,line,strlen(line));
-(void) soc_writebuffer(socptr,"\r\n",2);
+int count;
+
+count=soc_writebuffer(socptr,line,strlen(line));
+count+=soc_writebuffer(socptr,"\r\n",2);
+return count;
+}
+/*
+^L
+*/
+/************************************************/
+/* */
+/* procedure to set the link in TLS mode */
+/* */
+/************************************************/
+static _Bool gomodetls(SOCPTR *socptr)
+
+{
+#define WTLS 5 /*wait 5 sec for TLS */
+_Bool status;
+char *got;
+int phase;
+_Bool proceed;
+
+status=false;
+got=(char *)0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //Sending START TLS command
+ if (dooutgoing(socptr,GOTLS)!=(strlen(GOTLS)+2))
+ phase=999; //Unable to send STARTTLS sequence
+ break;
+ case 1 : //Get STARTTLS command status
+ if (tcp_getline(socptr,WTLS,&got)<=0)
+ phase=999; //Didn't get signon
+ break;
+ case 2 : //did we received the signon
+ if (got!=(char *)0) { //Always
+ int code;
+
+ code=0;
+ (void) sscanf(got,"%d",&code);
+ if (code!=SIGNON)
+ phase=999;
+ got=rou_freestr(got);
+ }
+ break;
+ case 3 : //initiating TLS-Crypted mode
+ if (soc_starttls(socptr)==false)
+ phase=999;
+ break;
+ case 4 : //eveythin is fine SOC in crypted mode
+ status=true;
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return status;
}
/*
\f
}
switch (getcmd(line)) {
case 1 : //GOTLS
- (void) rou_alert(0,"JMPDBG got GOTTLS");
- status=true;
+ if ((status=gomodetls(socptr))==false)
+ (void) report(numline,line,"Unable to set TLS mode");
break;
case 2 : //GOTLS
if (param==(char *)0)
/* crypted channel, return true is successful. */
/* */
/********************************************************/
-_Bool soc_starttls(SOCPTR *socptr,const char *peerip)
+_Bool soc_starttls(SOCPTR *socptr)
{
_Bool ok;
soc=(SOCTYP *)socptr;
if ((soc!=(SOCTYP *)0)&&(soc->modtls==false)) {
int tosend;
+ char *peerip;
char buffer[100];
+ peerip=soc_getaddrinfo(socptr,false,false);
(void) socpurge(soc,peerip);
tosend=snprintf(buffer,sizeof(buffer),"%d 2.0.0 Ready to start TLS%s",
SIGNON,CRLF);
(void) socpurge(soc,peerip);
ok=true;
}
+ peerip=rou_freestr(peerip);
}
return ok;
}
*/
/********************************************************/
/* */
-/* Procedure to set the serevr cerificate */
+/* Procedure to set the link certificate */
/* */
/********************************************************/
-static int set_server_certificate(SSL_CTX *ctx)
+static int set_server_certificate(TLSTYP *tls)
{
+#define OPEP "unitls.c:set_link_certificate"
int done;
const char *certpub[3];
int phase;
while (proceed==true) {
switch (phase) {
case 0 : //load CA trusted file
- if (SSL_CTX_use_certificate_chain_file(ctx,certpub[0])!=1) {
- (void) showtlserror((TLSTYP *)0,0,"Get trusted file");
+ if (SSL_CTX_use_certificate_chain_file(tls->ctx,certpub[0])!=1) {
+ (void) showtlserror(tls,0,"No chain Certificate");
phase=999; //no need to go furter
}
break;
case 1 : //loading default CA verify dir
- if (SSL_CTX_set_default_verify_paths(ctx)==0) {
- (void) showtlserror((TLSTYP *)0,0,"Get trusted file");
+ if (SSL_CTX_set_default_verify_paths(tls->ctx)==0) {
+ (void) showtlserror(tls,0,"No CA certificate");
phase=999; //no need to go furter
}
break;
case 2 : //set certificate
- if (SSL_CTX_use_certificate_file(ctx,certpub[1],SSL_FILETYPE_PEM)!=1) {
- (void) showtlserror((TLSTYP *)0,0,"Get local Certificate");
+ if (SSL_CTX_use_certificate_file(tls->ctx,certpub[1],SSL_FILETYPE_PEM)!=1) {
+ (void) showtlserror(tls,0,"No local Certificate");
phase=999; //no need to go furter
}
break;
case 3 : //set key
- if (SSL_CTX_use_PrivateKey_file(ctx,certpub[2],SSL_FILETYPE_PEM)!=1) {
- (void) showtlserror((TLSTYP *)0,0,"Get Private Key");
+ if (SSL_CTX_use_PrivateKey_file(tls->ctx,certpub[2],SSL_FILETYPE_PEM)!=1) {
+ (void) showtlserror(tls,0,"No local Certificate");
phase=999;
}
break;
case 4 : //verify management
- (void) SSL_CTX_set_purpose(ctx,X509_PURPOSE_ANY);
- (void) SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,(int(*)())0);
- (void) SSL_CTX_set_verify_depth(ctx,5);
- (void) SSL_CTX_set_options(ctx,SSL_OP_ALL);
- if (SSL_CTX_set_cipher_list(ctx,SSL_CIPHER_LIST)==0) {
- (void) showtlserror((TLSTYP *)0,0,"set cipher list");
+ (void) SSL_CTX_set_purpose(tls->ctx,X509_PURPOSE_ANY);
+ (void) SSL_CTX_set_verify(tls->ctx,SSL_VERIFY_PEER,(int(*)())0);
+ (void) SSL_CTX_set_verify_depth(tls->ctx,5);
+ (void) SSL_CTX_set_options(tls->ctx,SSL_OP_ALL);
+ if (SSL_CTX_set_cipher_list(tls->ctx,SSL_CIPHER_LIST)==0) {
+ (void) showtlserror(tls,0,"No cipher list");
phase=999;
}
break;
case 5 : //allowing partial write
- (void) SSL_CTX_set_mode(ctx,SSL_MODE_ENABLE_PARTIAL_WRITE);
+ (void) SSL_CTX_set_mode(tls->ctx,SSL_MODE_ENABLE_PARTIAL_WRITE);
break;
case 6 : //everything fine
done=true;
break;
default : //SAFE Guard
+ if (done==false) {
+ if (tls->ctx!=(SSL_CTX *)0) {
+ (void) SSL_CTX_free(tls->ctx);
+ tls->ctx=(SSL_CTX *)0;
+ }
+ }
proceed=false;
break;
}
phase++;
}
return done;
+#undef OPEP
}
/*
^L
break;
case 1 : //set certificate
if (server==true) {
- if (set_server_certificate(tls->ctx)==false)
+ if (set_server_certificate(tls)==false)
phase=999; //trouble, trouble no need to go furter
}
break;