From d602b563c41448f6d07063a963f106714ef6966b Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Thu, 19 Jun 2025 14:42:43 -0400 Subject: [PATCH] Still investiguating on TLS OK code --- Makefile | 11 +++- conf/mailleur.conf.dvl | 2 +- lib/gestcp.c | 27 +++++++++- lib/gestcp.h | 3 ++ lib/lvleml.c | 118 +++++++++++++++++++++++------------------ lib/lvleml.h | 1 + 6 files changed, 105 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 705a691..9e9318a 100644 --- a/Makefile +++ b/Makefile @@ -87,14 +87,19 @@ valfeed : debug #valgring of emlrcvr tlsrcvr : @ clear openssl s_client \ - -quiet \ + -trace \ -crlf \ + -status \ -CAfile certs/root-safe_CA.pem \ -cert certs/localhost-cert.pem \ -key certs/localhost-key.pem \ -starttls smtp \ - -connect $(TESTSRV):$(TESTPORT) + -connect mx1.free.fr:25 +# -connect smtp1.example.com:25 # -connect mailpostg.example.com:25 +# -connect courriel.colba.net:25 +# -connect mx1.free.fr:25 +# -connect $(TESTSRV):$(TESTPORT) go465 : @ clear @@ -122,6 +127,8 @@ go465 : tlsref: @ clear @ openssl s_client \ + -trace \ + -crlf \ -status \ -CAfile certs/root-safe_CA.pem \ -cert certs/localhost-cert.pem \ diff --git a/conf/mailleur.conf.dvl b/conf/mailleur.conf.dvl index c3b73cb..cffefe9 100644 --- a/conf/mailleur.conf.dvl +++ b/conf/mailleur.conf.dvl @@ -27,7 +27,7 @@ CA_VERIFY_SRV = 0 #to check PEER/client remote certificate CA_ROOT_CLT = "./certs/root-safe_CA.pem" CA_CERT_CLT = "./certs/localhost-chain-cert.pem" CA_KEY_CLT = "./certs/localhost-key.pem" -CA_VERIFY_CLT = 0 #to check PEER/server remote certificate +CA_VERIFY_CLT = 1 #to check PEER/server remote certificate #------------------------------------------------ #Configured for Postgresql database DB_TYPE = POSTGRESQL diff --git a/lib/gestcp.c b/lib/gestcp.c index 0f11251..b0ed5d0 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -20,6 +20,32 @@ #include "uniprc.h" #include "gestcp.h" +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to add a line to a TCP buffer */ +/* return the a point to the new busffer */ +/* */ +/********************************************************/ +PUBLIC char *tcp_addline(char *buffer,char *line) + +{ +register int taille; + +taille=0; +if (strlen(line)>0) { + taille=strlen(line)+strlen(CRLF)+2; + if (buffer==(char *)0) + buffer=(char *)calloc(taille,sizeof(char)); + taille+=strlen(buffer); + buffer=realloc(buffer,taille); + (void) strcat(buffer,line); + (void) strcat(buffer,CRLF); + } +return buffer; +} /* ^L */ @@ -108,7 +134,6 @@ if (socptr!=(SOCPTR *)0) { taille=strlen(buffer); if (taille>0) sent=soc_writebuffer(socptr,buffer,taille); - sent+=soc_writebuffer(socptr,CRLF,strlen(CRLF)); } return sent; } diff --git a/lib/gestcp.h b/lib/gestcp.h index e849aee..734a60c 100644 --- a/lib/gestcp.h +++ b/lib/gestcp.h @@ -24,6 +24,9 @@ typedef struct { MXTYP **mxs; //MX list form domain }RMTTYP; +//procedure to add a line to a buffer +PUBLIC char *tcp_addline(char *buffer,char *line); + //read a line from contact up to CRLF extern int tcp_getline(SOCPTR *socptr,u_int secwait,char **lineptr); diff --git a/lib/lvleml.c b/lib/lvleml.c index aa21f67..40793f0 100644 --- a/lib/lvleml.c +++ b/lib/lvleml.c @@ -125,7 +125,7 @@ return done; /* Procedure to transmit a string to the remot peer*/ /* */ /********************************************************/ -static void transmit(CONTYP *contact,const char *fmt,...) +static void transmit(CONTYP *contact,_Bool flush,const char *fmt,...) { va_list args; @@ -135,9 +135,13 @@ va_start(args,fmt); line=(char *)0; if (rou_vasprintf(&line,fmt,args)>0) { (void) log_fprintlog(contact->logptr,true,"%s",line); - (void) tcp_write(contact->socptr,line); - (void) free(line); + contact->transout=tcp_addline(contact->transout,line); } +if (flush==true) { + (void) tcp_write(contact->socptr,contact->transout); + contact->transout=rou_freestr(contact->transout); + } +line=rou_freestr(line); va_end(args); } /* @@ -165,7 +169,7 @@ if (contact!=(CONTYP *)0) { APPNAME, rou_getversion(), rou_ascsysstamp(time((time_t *)0))); - (void) transmit(contact,"%s",signon); + (void) transmit(contact,true,"%s",signon); } #undef FMT } @@ -188,9 +192,9 @@ sepa=' '; if (suite==true) sepa='-'; mode=soc_getstrmode(contact->socptr); -(void) transmit(contact,"%d%c%s, link (%s) ready, your IP/FQDN=[%s/%s]", - CMDOK,sepa,contact->locname,mode, - contact->peerip,contact->peername); +(void) transmit(contact,true,"%d%c%s, link (%s) ready, your IP/FQDN=[%s/%s]", + CMDOK,sepa,contact->locname,mode, + contact->peerip,contact->peername); } /* ^L @@ -471,7 +475,7 @@ while (proceed==true) { char *cmt; cmt="RCPT first. transaction protocol command out of sequence"; - (void) transmit(contact,"%d 5.5.0 %s",BADSEQ,cmt); + (void) transmit(contact,true,"%d 5.5.0 %s",BADSEQ,cmt); done=true; //lets say DATA will be issued proceed=false; //No recipients } @@ -486,7 +490,7 @@ while (proceed==true) { break; case 3 : //sending 'go ahead' to remote (void) clock_gettime(CLOCK_REALTIME,&start); - (void) transmit(contact,"%d 3.5.0 %s", + (void) transmit(contact,true,"%d 3.5.0 %s", DATAOK,"End data with ."); break; case 4 : //get incoming line, detect 'single dot' as end @@ -532,15 +536,15 @@ while (proceed==true) { total/=1024; //KBytes delta=rou_getdifftime(&start); fmt="%d 3.5.3 Message accepted for delivery (Session ID=<%s>)"; - (void) transmit(contact,fmt,CMDOK,contact->cursesid); + (void) transmit(contact,true,fmt,CMDOK,contact->cursesid); fmt="(DATA stream received: %d Kbytes within %d.%03d seconds)"; (void) log_fprintlog(contact->logptr,false,fmt,total,delta/1000,delta%1000); done=true; proceed=false; //task done break; default : //SAFE guard - (void) transmit(contact,"%d 5.5.4 %s", - DATRJC,"Server does not accept mail"); + (void) transmit(contact,true,"%d 5.5.4 %s", + DATRJC,"Server does not accept mail"); proceed=false; break; } @@ -569,7 +573,7 @@ static _Bool dohelo(CONTYP *contact,char *parameter) _Bool done; if ((done=isgoodfqdn(contact,parameter))==false) - (void) transmit(contact,"%d 5.5.4 %s.",BADPAR,DETAIL); + (void) transmit(contact,true,"%d 5.5.4 %s.",BADPAR,DETAIL); else (void) linkready(contact,false); return done; @@ -613,18 +617,19 @@ while (proceed==true) { switch (phase) { case 0 : //Do we have a parameter if ((done=isgoodfqdn(contact,parameter))==false) { - (void) transmit(contact,"%d 5.5.4 %s.",BADPAR,DETAIL); + (void) transmit(contact,true,"%d 5.5.4 %s.",BADPAR,DETAIL); phase=999; //Trouble trouble } break; case 1 : //thereis an FQDN (void) linkready(contact,true); - (void) transmit(contact,"%d-SIZE %ld",CMDOK,MXMSIZE); + (void) transmit(contact,false,"%d-SIZE %ld",CMDOK,MXMSIZE); if (soc_iscrypted(contact->socptr)==true) strstart++; for (int i=strstart;ehlostr[i]!=(char *)0;i++) { - (void) transmit(contact,"%d%s",CMDOK,ehlostr[i]); + (void) transmit(contact,false,"%d%s",CMDOK,ehlostr[i]); } + (void) transmit(contact,true,""); done=true; break; default : //SAFE guard @@ -660,24 +665,23 @@ while (proceed==true) { switch (phase) { case 0 : //do we have an originator if ((mailfrom==(char *)0)||(strlen(mailfrom)<3)) { - (void) transmit(contact,"%d 5.5.0 <%s> originator not specified", - BADPAR,mailfrom); + (void) transmit(contact,true,"%d 5.5.0 <%s> originator not specified", + BADPAR,mailfrom); phase=999; //no need to go further } break; case 1 : //do we have already a from if (contact->mailfrom!=(char *)0) { - (void) transmit(contact,"%d 5.5.1 '%s' %s", - BADPAR,contact->mailfrom, - "was previously defined as originator" - ); + (void) transmit(contact,true,"%d 5.5.1 '%s' %s", + BADPAR,contact->mailfrom, + "was previously defined as originator"); phase=999; //no need to go further } break; case 2 : //check from format if ((mailfrom[0]!='<')||(mailfrom[strlen(mailfrom)-1]!='>')) { - (void) transmit(contact,"%d 5.5.2 '%s' bad Format error", - BADPAR,mailfrom); + (void) transmit(contact,true,"%d 5.5.2 '%s' bad Format error", + BADPAR,mailfrom); phase=999; //no need to go further } mailfrom[strlen(mailfrom)-1]='\000'; @@ -685,8 +689,8 @@ while (proceed==true) { break; case 3 : //everything ok contact->mailfrom=strdup(mailfrom); - (void) transmit(contact,"%d 2.1.3 %s.. sender ok", - CMDOK,contact->mailfrom); + (void) transmit(contact,true,"%d 2.1.3 %s.. sender ok", + CMDOK,contact->mailfrom); break; default : //SAFE guard proceed=false; @@ -727,20 +731,20 @@ while (proceed==true) { switch (phase) { case 0 : //do we have a mailfrom if ((contact->mailfrom==(char *)0)||(strlen(contact->mailfrom)==0)) { - (void) transmit(contact,"%d Bad sequence of commands.",BADSEQ); + (void) transmit(contact,true,"%d Bad sequence of commands.",BADSEQ); phase=999; //no need to go further } break; case 1 : //do we have an originator if ((rcptto==(char *)0)||(strlen(rcptto)==0)) { - (void) transmit(contact,"%d 5.6.0 recipient not specified",BADPAR); + (void) transmit(contact,true,"%d 5.6.0 recipient not specified",BADPAR); phase=999; //no need to go further } break; case 2 : //check rcpt format if ((rcptto[0]!='<')||(rcptto[strlen(rcptto)-1]!='>')) { - (void) transmit(contact,"%d 5.6.1 '%s' bad Format error", - BADPAR,rcptto); + (void) transmit(contact,true,"%d 5.6.1 '%s' bad Format error", + BADPAR,rcptto); phase=999; //no need to go further } rcptto[strlen(rcptto)-1]='\000'; @@ -749,17 +753,17 @@ while (proceed==true) { case 3 : //checking rcptto format neu=eml_isemailok(rcptto,&report); if (neu==(RCPTYP *)0) { - (void) transmit(contact,"%d 5.6.2 %s",NOTEML,report); + (void) transmit(contact,true,"%d 5.6.2 %s",NOTEML,report); report=rou_freestr(report); phase=999; //no need to go further } break; case 4 : //Do we have a domain MX if (setlocdom(contact,neu)==false) { - (void) transmit(contact,"%d 5.6.3 %s (domain=%s)", - MISSMX, - "No valid MX found for recipient domain name", - neu->domain); + (void) transmit(contact,true,"%d 5.6.3 %s (domain=%s)", + MISSMX, + "No valid MX found for recipient domain name", + neu->domain); neu=eml_freerecipient(neu); //free recipient phase=999; //no need to go further } @@ -771,7 +775,7 @@ while (proceed==true) { } break; case 6 : //everything ok - (void) transmit(contact,"%d 2.6.4 %s <%s>",CMDOK,detail,rcptto); + (void) transmit(contact,true,"%d 2.6.4 %s <%s>",CMDOK,detail,rcptto); success=true; break; default : //SAFE guard @@ -796,16 +800,16 @@ static _Bool doreset(CONTYP *contact,char *parameter) { #define LOCSEQ "2.1.0" -(void) transmit(contact,"%d-%s flushed session %s", - CMDOK,LOCSEQ,contact->cursesid); +(void) transmit(contact,true,"%d-%s flushed session %s", + CMDOK,LOCSEQ,contact->cursesid); contact->numreset++; contact->recipients=(RCPTYP **)rou_freelist((void **)(contact->recipients), (genfree_t)eml_freerecipient); contact->mailfrom=rou_freestr(contact->mailfrom); contact->cursesid=rou_freestr(contact->cursesid); contact->cursesid=eml_getcursesid(contact->mainsesid,contact->numreset); -(void) transmit(contact,"%d %s opening new session %s", - CMDOK,LOCSEQ,contact->cursesid); +(void) transmit(contact,true,"%d %s opening new session %s", + CMDOK,LOCSEQ,contact->cursesid); return true; #undef LOCSEQ @@ -1443,12 +1447,12 @@ while (proceed==true) { proceed=doehlo(contact,line); break; case c_noop : //No Operation - (void) transmit(contact,"%d 2.0.0 OK, %s", - CMDOK,contact->mainsesid); + (void) transmit(contact,true,"%d 2.0.0 OK, %s", + CMDOK,contact->mainsesid); break; case c_quit : //QUIT SMTP protocol - (void) transmit(contact,"%d 2.0.0 Bye, closing connection CNT=%s", - QUITOK,contact->mainsesid); + (void) transmit(contact,true,"%d 2.0.0 Bye, closing connection CNT=%s", + QUITOK,contact->mainsesid); status=1; //every thing fine proceed=false; break; @@ -1467,14 +1471,19 @@ while (proceed==true) { case c_starttls : //EHLO start encrypted link in server mode switch (soc_starttls(contact->socptr,true)) { case true : //link now in TLS crypted mode + char *loc; + + loc=strdup(contact->fqdn); + //(void) doehlo(contact,loc); + loc=rou_freestr(loc); /* JMPDBG (void) transmit(contact,"%d Link now encrypted (cipher=<%s>)", CMDOK,soc_get_cipher_name(contact->socptr)); */ break; case false : //unable to establish link - (void) transmit(contact,"%d 5.3.3 command starttls not successful", - CMDBAD); + (void) transmit(contact,true,"%d 5.3.3 command starttls not successful", + CMDBAD); status=-1; proceed=false; break; @@ -1483,16 +1492,19 @@ while (proceed==true) { case c_unknown : //unknown keyword (void) rou_alert(0,"SMTP Command <%s> from [%s] is unknown (config?)", line,contact->peerip); - (void) transmit(contact,"%d-5.5.1 Unrecognized command, see RFC 5321",CMDBAD); - (void) transmit(contact,"%d-5.5.1 https://www.rfc-editor.org",CMDBAD); - (void) transmit(contact,"%d 5.5.1 session %s is still running", - CMDBAD,contact->mainsesid); + (void) transmit(contact,true,"%d-5.5.1 Unrecognized command, see RFC 5321", + CMDBAD); + (void) transmit(contact,true,"%d-5.5.1 https://www.rfc-editor.org",CMDBAD); + (void) transmit(contact,true,"%d 5.5.1 session %s is still running", + CMDBAD,contact->mainsesid); break; default : (void) rou_alert(0,"%s Unable to find entry for code='%d' (Bug?)",OPEP,code); - (void) transmit(contact,"%d-5.5.1 Unrecognized command, see RFC 5321",CMDBAD); - (void) transmit(contact,"%d 2.0.0 Bug!, closing connection Immediatly (%s)", - QUITOK,contact->mainsesid); + (void) transmit(contact,true,"%d-5.5.1 Unrecognized command, see RFC 5321", + CMDBAD); + (void) transmit(contact,true,"%d 2.0.0 Bug!, closing connection " + "Immediatly (%s)", + QUITOK,contact->mainsesid); status=-1; //remote is a trouble maker status=-3; proceed=false; diff --git a/lib/lvleml.h b/lib/lvleml.h index e514454..a3a1244 100644 --- a/lib/lvleml.h +++ b/lib/lvleml.h @@ -30,6 +30,7 @@ typedef struct { char *mailfrom; //current mail from originator RCPTYP **recipients; //List of email recipient LOGPTR *logptr; //reference to session log + char *transout; //data to be flush out to remote }CONTYP; -- 2.47.3