From 72c9bdcbc238cdd7a83465575d539352b1c332cc Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Fri, 9 Aug 2024 11:44:59 -0400 Subject: [PATCH] SSL chanell no working anymore --- lib/devsoc.c | 28 +++++++++++++++- lib/devsoc.h | 3 ++ lib/gestcp.c | 59 ++++++++++++++++++++++------------ lib/gestcp.h | 5 +++ lib/lvleml.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/subrou.c | 9 ++++-- lib/unieml.c | 4 ++- lib/unieml.h | 5 +++ lib/unitls.c | 6 +++- 9 files changed, 181 insertions(+), 29 deletions(-) diff --git a/lib/devsoc.c b/lib/devsoc.c index 548087e..523b163 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -480,6 +480,7 @@ int iterations; SOCTYP *soc; soc=(SOCTYP *)socptr; +iterations=0; if (soc!=(SOCTYP *)0) iterations=soc->iteration; return iterations; @@ -953,7 +954,7 @@ while (proceed==true) { phase=999; //never reached } break; - case 1 : //shuting dow the TCP link + case 1 : //shutting down the TCP link switch (soc->proto) { case pro_smtp : //plain socket case pro_starttls : //plain socket + STARTTLS @@ -1027,3 +1028,28 @@ if (mode!=modopen) { return status; #undef OPEP } +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to switch a plain socket channel to */ +/* crypted channel, return true is successful. */ +/* */ +/********************************************************/ +_Bool soc_starttls(SOCPTR *socptr,_Bool server) + +{ +_Bool ok; +SOCTYP *soc; + +ok=false; +soc=(SOCTYP *)socptr; +if ((soc!=(SOCTYP *)0)&&(soc->modtls==false)) { + if ((soc->tls=tls_opentls(soc->handle,server))!=(TLSTYP *)0) { + soc->modtls=true; + ok=true; + } + } +return ok; +} diff --git a/lib/devsoc.h b/lib/devsoc.h index 62cd75d..3915caf 100644 --- a/lib/devsoc.h +++ b/lib/devsoc.h @@ -65,6 +65,9 @@ extern char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool ip); //procedure to release/clsoe socket extern SOCPTR *soc_release(SOCPTR *socptr); +//procedure to initiate crypted mode on plain channel +extern _Bool soc_starttls(SOCPTR *socptr,_Bool server); + //homework to be done before starting/stopping module. extern int soc_modedevsoc(_Bool mode); diff --git a/lib/gestcp.c b/lib/gestcp.c index b6a4d16..65d692b 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -35,6 +35,7 @@ static CONTYP *freecontact(CONTYP *contact) #define OPEP "gesttcp.c:freecontact" if (contact!=(CONTYP *)0) { + contact->fqdn=rou_freestr(contact->fqdn); contact->peerip=rou_freestr(contact->peerip); contact->locname=rou_freestr(contact->locname); contact->locserv=rou_freestr(contact->locserv); @@ -89,8 +90,8 @@ while (proceed==true) { break; //no need to read line default : //char available phase=0; //check for new line - if (soc_receive(contact->socptr)==0) { - got=0; + if (soc_receive(contact->socptr)<0) { + got=-1; phase=999; //remote disconnected? } break; @@ -129,6 +130,39 @@ return sent; */ /********************************************************/ /* */ +/* Procedure to send a signon on the current */ +/* channel (either plain of crypted). */ +/* Return the number of char transmitted. */ +/* */ +/********************************************************/ +PUBLIC int tcp_signon(CONTYP *contact) + +{ +#define OPEP "gestcp.c:tcp_signon" +#define FMT "%d %s ESMTP %s-%s; %s%s" + +int sent; + +sent=0; +if (contact!=(CONTYP *)0) { + char signon[100]; + + (void) snprintf(signon,sizeof(signon),FMT, + SIGNON,contact->locname, + appname,rou_getversion(), + rou_ascsysstamp(time((time_t *)0)),CRLF); + if ((sent=tcp_write(contact,signon,strlen(signon)))<0) + (void) rou_alert(0,"%s Unable to send signon to remote",OPEP); + } +#undef FMT +#undef OPEP +return sent; +} +/* +^L +*/ +/********************************************************/ +/* */ /* Procedure to wait for a remote client. */ /* return all reference to the established contact.*/ /* */ @@ -174,24 +208,9 @@ while (proceed==true) { } break; case 3 : //contact is good sending signon - if (contact!=(CONTYP *)0) { //always - #define FMT "%d %s ESMTP %s-%s; %s%s" - - char signon[100]; - - (void) prc_settitle("Contact from peer '%s' started at %s", - contact->peerip, - rou_ascsysstamp(time((time_t *)0))); - (void) snprintf(signon,sizeof(signon),FMT, - SIGNON,contact->locname, - appname,rou_getversion(), - rou_ascsysstamp(time((time_t *)0)),CRLF); - if (tcp_write(contact,signon,strlen(signon))<0) { - (void) rou_alert(0,"%s Unable to send signon to remote",OPEP); - contact=freecontact(contact); - phase=999; //no contact - } - #undef FMT + if (tcp_signon(contact)<=0) { + contact=freecontact(contact); + phase=999; //no contact } break; default : //SAFE guard diff --git a/lib/gestcp.h b/lib/gestcp.h index 971f476..8655c59 100644 --- a/lib/gestcp.h +++ b/lib/gestcp.h @@ -14,6 +14,8 @@ typedef struct { SOCPTR *socptr; //established contact context + _Bool tlsok; //link is in crypted mode + char *fqdn; //fully qualified domain from peer char *locname; //socket local hostname char *locserv; //local service port char *peerip; //socket remote peer IP @@ -25,6 +27,9 @@ extern int tcp_getline(CONTYP *contact,TIMESPEC *attend,char **lineptr); //Transmit formated data to the contact channel extern int tcp_write(CONTYP *contact,char *buffer,int tosend); +//send signon on channel +extern int tcp_signon(CONTYP *contact); + //wait for an incoming contact extern CONTYP *tcp_getcontact(SOCPTR *socptr,int pos); diff --git a/lib/lvleml.c b/lib/lvleml.c index 3f44159..d6f6f97 100644 --- a/lib/lvleml.c +++ b/lib/lvleml.c @@ -37,6 +37,72 @@ va_start(args,fmt); va_end(args); } /* + +*/ +/************************************************/ +/* */ +/* Procedure to send an "HELO" message */ +/* if EHLO message is not accepted. */ +/* */ +/************************************************/ +static _Bool doehlo(CONTYP *contact,char *line) + +{ +static char *ehlostr[]= { + "-8BITMIME", + "-STARTTLS", + "-ENHANCEDSTATUSCODES", + "-AUTH PLAIN LOGIN", + " HELP", + (char *)0 + }; + +#define OPEP "unieml.c:doehlo" +#define DETAIL "syntax error (domain part missing), disconnecting" + +_Bool done; +char *fqdn; +int phase; +_Bool proceed; + +done=false; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Do we have + fqdn=strchr(line,' '); + if (fqdn!=(char *)0) { + while ((*fqdn==' ')||(*fqdn=='\t')) + fqdn++; + } + if ((fqdn==(char *)0)||(strlen(fqdn)==0)) { + (void) transmit(contact,"%d 5.5.4 %s",BADPAR,DETAIL); + phase=999; //Trouble trouble + } + break; + case 1 : //thereis an FQDN + contact->fqdn=rou_freestr(contact->fqdn); + contact->fqdn=strdup(fqdn); + (void) transmit(contact,"%d-%s ready, your IP=[%s]", + CMDOK,contact->locname,contact->peerip); + (void) transmit(contact,"%d-SIZE %ld",CMDOK,MXMSIZE); + for (int i=0;ehlostr[i]!=(char *)0;i++) { + (void) transmit(contact,"%d%s",CMDOK,ehlostr[i]); + } + done=true; + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return done; +#undef DETAIL +#undef OPEP +} +/* ^L */ /********************************************************/ @@ -66,13 +132,32 @@ while (proceed==true) { status=tcp_getline(contact,&attend,&line); if (status<=0) //timeout or trouble? break; //no need to go further + (void) printf("JMPDBG getline got <%s>\n",line); switch (eml_getcode(line)) { - case c_quit : //quit SMTP protocol - (void) transmit(contact,"%d closing connection",QUITOK); + case c_ehlo : //EHLO SMTP protocol + proceed=doehlo(contact,line); + break; + case c_quit : //QUIT SMTP protocol + (void) transmit(contact,"%d 2.0.0 Bye, closing connection",QUITOK); proceed=false; break; + case c_starttls : //EHLO start encryptel link + switch (soc_starttls(contact->socptr,true)) { + case true : //link now in TLS crypted mode + (void) tcp_signon(contact); + break; + case false : //unable to establish link + (void) transmit(contact,"%d 5.3.3 command starttls not successful", + CMDBAD); + status=-1; + proceed=false; + break; + } + break; case c_unknown : //uknown keyword - (void) transmit(contact,"%d command <%s> is unknown",CMDBAD,line); + (void) rou_alert(0,"Command <%s> from [%s] is unknown (config?)", + line,contact->peerip); + (void) transmit(contact,"%d 5.5.1 command <%s> is unknown",CMDBAD,line); break; default : (void) rou_alert(0,"Unable to find keyword for <%s> (Bug?)",OPEP,line); diff --git a/lib/subrou.c b/lib/subrou.c index 9a7aacf..e1e3496 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "36" +#define RELEASE "37" //Public variables PUBLIC int debug=0; //debug level @@ -50,7 +50,10 @@ static char *get_dropzone() char *dropzone; char command[100]; -dropzone=rou_apppath("/tmp/"APPNAME"-crash"); +(void) strcpy(command,"/tmp/"); +(void) strcat(command,APPNAME); +(void) strcat(command,"-crash"); +dropzone=rou_apppath(command); (void) snprintf(command,sizeof(command)-2,"mkdir -p %s",dropzone); (void) system(command); return dropzone; @@ -237,7 +240,7 @@ PUBLIC char *rou_apppath(const char *path) char *root; char *newpath; int taille; -char loc[3]; +char loc[300]; root=""; newpath=(char *)0; diff --git a/lib/unieml.c b/lib/unieml.c index b0df332..4f6c17c 100644 --- a/lib/unieml.c +++ b/lib/unieml.c @@ -21,7 +21,9 @@ typedef struct { //this list order by key length static VOCTYP vocsmtp[]={ + {c_ehlo,"EHLO"}, {c_quit,"QUIT"}, + {c_starttls,"STARTTLS"}, {c_unknown,(const char *)0} }; /* @@ -40,7 +42,7 @@ VOCTYP *ptr; code=c_unknown; for (ptr=vocsmtp;ptr->code!=c_unknown;ptr++) { - if (strcasecmp(ptr->key,keyword)==0) { + if (strncasecmp(ptr->key,keyword,strlen(ptr->key))==0) { code=ptr->code; break; } diff --git a/lib/unieml.h b/lib/unieml.h index e63b16b..004d605 100644 --- a/lib/unieml.h +++ b/lib/unieml.h @@ -8,14 +8,19 @@ #ifndef UNIEML #define UNIEML +#define MXMSIZE 52428800 //52 Megabytes #define CRLF "\r\n" //EOL within SMTP protocol #define SIGNON 220 //signon information #define QUITOK 221 //status on quit +#define CMDOK 250 //Everything OK +#define BADPAR 501 //error in parameters #define CMDBAD 502 //command not implemented //list of keyword typedef enum { //list of SMTP protocol keyword + c_ehlo, //EHLO command c_quit, //quit exchange + c_starttls, //Starting a TLS crypted link c_unknown //key word unknown }CODTYP; diff --git a/lib/unitls.c b/lib/unitls.c index f2c3261..5e4eef4 100644 --- a/lib/unitls.c +++ b/lib/unitls.c @@ -378,6 +378,7 @@ ready=false; phase=0; proceed=true; while (proceed==true) { + (void) printf("JMPDBG opentls phase='%d'\n",phase); switch (phase) { case 0 : //prepare the structure first; tls=(TLSTYP *)calloc(1,sizeof(TLSTYP)); @@ -491,6 +492,7 @@ if (tls!=(TLSTYP *)0) { int sofar; proceed=true; + (void) printf("JMPDBG sending <%s>\n",buffer); while (proceed==true) { proceed=false; sofar=SSL_write(tls->ssl,buffer,tosend); @@ -553,8 +555,10 @@ int got; got=-1; if (tls!=(TLSTYP *)0) { - if ((got=SSL_read(tls->ssl,buffer,maxread))<=0) + if ((got=SSL_read(tls->ssl,buffer,maxread))<=0) { (void) showtlserror(tls,got,"Trouble to read data"); + got=-1; + } } return got; } -- 2.47.3