]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Starting to implement the "STARTTLS" smtp command
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 2 Apr 2025 00:55:50 +0000 (20:55 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 2 Apr 2025 00:55:50 +0000 (20:55 -0400)
app/Makefile
app/feeder.c
lib/devsoc.c
lib/devsoc.h
lib/lvleml.c
lib/subrou.c
lib/unieml.h
lib/unitls.c

index ffae3413d0116962dd5c52d6f2a444c2a90d0784..4ca6c77f400fd4e96c79266da23d81c92a3f10e7 100644 (file)
@@ -66,10 +66,12 @@ emlrec.o:  emlrec.c                         \
           ../lib/subrou.h
 
 feeder.o:  feeder.c                            \
+          ../lib/gestcp.h                      \
+          ../lib/devsoc.h                      \
+          ../lib/unieml.h                      \
           ../lib/unipar.h                      \
           ../lib/subrou.h
 
-
 toremake:  Makefile $(LIBAI)
           touch toremake
           - rm -f $(EXE) *.o
index e076379fa4715ee4348117d14826857a82a18a84..4c9ca3712dcfc3bb175535cde67b00844fd1e129 100644 (file)
@@ -18,6 +18,7 @@
 
 #include       "subrou.h"
 #include       "unipar.h"
+#include       "unieml.h"
 #include       "devsoc.h"
 #include       "gestcp.h"
 
@@ -71,11 +72,71 @@ static void report(int numline,char *line,char *trouble)
 /*     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
@@ -132,8 +193,8 @@ if ((param=strchr(line,' '))!=(char *)0) {
   }
 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)  
index f683b79a0f2a6d9634a0e0db2d3dbdd857b7afab..ab16cdb4c0da27f15fe84255eeede094757e24f1 100644 (file)
@@ -1371,7 +1371,7 @@ return socptr;
 /*      crypted channel, return true is successful.     */
 /*                                                     */
 /********************************************************/
-_Bool soc_starttls(SOCPTR *socptr,const char *peerip)
+_Bool soc_starttls(SOCPTR *socptr)
 
 {
 _Bool ok;
@@ -1381,8 +1381,10 @@ ok=false;
 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);
@@ -1393,6 +1395,7 @@ if ((soc!=(SOCTYP *)0)&&(soc->modtls==false)) {
     (void) socpurge(soc,peerip);
     ok=true;
     }
+  peerip=rou_freestr(peerip);
   }
 return ok;
 }
index 01643e37333ab4ce7d0b46d5a5c1400c30221562..d8cffbea328a263711acca533a216581616ae5cc 100644 (file)
@@ -76,6 +76,6 @@ extern char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool getname);
 extern SOCPTR *soc_release(SOCPTR *socptr);
 
 //procedure to initiate crypted mode on plain channel
-extern _Bool soc_starttls(SOCPTR *socptr,const char *peerip);
+extern _Bool soc_starttls(SOCPTR *socptr);
 
 #endif
index 329389322b56d407dffebe547fdd0622a5700c63..a8f3f535bd16ace8c41e6d894703b43280226ddb 100644 (file)
@@ -375,7 +375,7 @@ while (proceed==true) {
       proceed=doreset(contact,line);
       break;
     case c_starttls     :       //EHLO start encryptel link
-      switch (soc_starttls(contact->socptr,contact->peerip)) {
+      switch (soc_starttls(contact->socptr)) {
         case true       :       //link now in TLS crypted mode
           contact->tlsok=true;
           (void) signon(contact);
index abd688988169ff707e29b0faaf4475294c254c1f..3e8e934a38322850e1c1aae84acb0b2cb4555088 100644 (file)
@@ -21,7 +21,7 @@
 
 //version definition 
 #define VERSION "0.6"
-#define RELEASE "42"
+#define RELEASE "43"
 #define BRANCH "dvl"
 
 //Public variables
index ebcf180581cdca826af3ac89a9bbe5d084ee7390..be4e9a66b29167898fba9ea850febd1ec4fd6b19 100644 (file)
@@ -19,6 +19,7 @@
 
 //SMTP avail command
 #define        MAILF   "MAIL FROM:"    //Mail from a sender
+#define GOTLS   "STARTTLS"      //Requesting crypted mode
 
 //list of keyword
 typedef enum    {               //list of SMTP protocol keyword
index 9aecd747aad4ba29940056660682af21178370ff..e677e71c517804ec5490d0da5c808c2b30dec2fb 100644 (file)
@@ -212,12 +212,13 @@ return tls;
 */
 /********************************************************/
 /*                                                      */
-/*     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;
@@ -232,52 +233,59 @@ proceed=true;
 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
@@ -393,7 +401,7 @@ while (proceed==true) {
       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;