]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Working out the TLS contact sequence
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 7 Aug 2024 10:41:16 +0000 (06:41 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 7 Aug 2024 10:41:16 +0000 (06:41 -0400)
lib/gestcp.c
lib/subrou.c
lib/unitls.c
lib/unitls.h

index a6ca573bc35d7f0bc6e10533f54fc8a0ba8f53fe..bd29a3210607b570553d711d47041b7e8a73675e 100644 (file)
@@ -79,6 +79,9 @@ while (proceed==true) {
     case 2      :       //waiting for new character presence
       switch (soc_waitforchar(contact->socptr,attend)) {
         case -1         :       //trouble? signal?
+          if ((hangup==true)||(reload==true))
+            phase=999;          //we got a real signal
+          break;                //no need to read line
         case  0         :       //normal time out
           break;                //no need to read line
         default         :       //char available
index 868e65fa22cbd197e59eb7fc8df315941b6b0ef0..24f8c8acce38579df7bb93e4543bc911b612624d 100644 (file)
@@ -20,7 +20,7 @@
 
 //version definition 
 #define VERSION "0.3"
-#define RELEASE "28"
+#define RELEASE "29"
 
 //Public variables
 PUBLIC  int debug=0;            //debug level
index 211de2fbc7f2fd90d6c41d4500513c8a58d3f62a..067305a2717a60063441b75d7ac61132a25400c8 100644 (file)
@@ -7,6 +7,7 @@
 /********************************************************/
 #include        <openssl/err.h>
 #include        <openssl/x509v3.h>
+#include        <poll.h>
 #include        <stdio.h>
 
 #include       "subrou.h"
@@ -45,13 +46,17 @@ while ((error=ERR_get_error())!=0) {
 /*      fatal error found.                              */
 /*                                                      */
 /********************************************************/
-static _Bool showtlserror(TLSTYP *tls,int sslerror,char *msg)
+static _Bool showtlserror(TLSTYP *tls,int sslerror,char *msg,...)
 
 {
 #define OPEP    "unitls.c:showtlserror"
 _Bool good;
+va_list args;
+char info[300]; 
 
 good=true;
+va_start(args,msg);
+(void) vsnprintf(info,sizeof(info),msg,args);
 if (sslerror<=0) {
   char *detail;
   int code;
@@ -60,7 +65,7 @@ if (sslerror<=0) {
   detail="Unexpected error";
   switch (sslerror) {
     case 0      :
-      (void) showerrorstack(msg);
+      (void) showerrorstack(info);
       break;
     default     :
       if (tls->ssl==(SSL *)0)    //in case of trouble
@@ -94,15 +99,16 @@ if (sslerror<=0) {
           break;
         default                         :
           (void) rou_alert(0,"%s, caused by <%s>  Unexpected ssl error='%d'",
-                             OPEP,msg,code);
+                             OPEP,info,code);
           detail=(char *)0;
           break;
         }
       break;
     }
   if (detail!=(char *)0)
-    (void) rou_alert(4,"%s, caused by <%s>, error=<%s>",OPEP,msg,detail);
+    (void) rou_alert(4,"%s, caused by <%s>, error=<%s>",OPEP,info,detail);
   }
+va_end(args);
 return good;
 #undef  OPEP
 }
@@ -111,6 +117,106 @@ return good;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to wait for character on the TLS      */
+/*      tls channel.                                    */
+/*                                                      */
+/********************************************************/
+static _Bool dowait(TLSTYP *tls,TIMESPEC *attend)
+
+{
+#define OPEP    "unitls.c:dowait"
+
+_Bool done;
+struct pollfd polling[1];
+
+done=false;
+polling[0].events=POLLIN|POLLPRI;
+polling[0].revents=(short)0;
+polling[0].fd=SSL_get_fd(tls->ssl);
+switch (ppoll(polling,1,attend,(sigset_t *)0)) {
+  case -1       :
+    switch(errno) {     //received a signal, lets see...*
+      case EINTR:       //Yes could be a TERM/HANGUP signal
+        break;
+      default   :       //real problem
+        (void) rou_alert(0,"%s poll error '%s'",OPEP,strerror(errno));
+        done=true;      //No need to wait any more
+        break;
+      }
+    break;
+  case 0        :       //standard timeout
+    done=true;
+    break;
+  default       :
+    break;
+  }
+return done;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to "accept" link on an SSL channel    */
+/*                                                      */
+/********************************************************/
+static int doaccept(TLSTYP *tls)
+
+{
+#define OPEP    "unitls.c:doaccept"
+int status;
+X509 *peer;
+TIMESPEC attend;
+int done;
+
+status=-1;
+peer=(X509 *)0;
+attend.tv_sec=30;       //waiting 30 second to have a full SSL
+attend.tv_nsec=0;
+done=false;
+while (done==false) {
+  int sslerr;
+
+  status=SSL_accept(tls->ssl);
+  done=true;
+  switch (sslerr=SSL_get_error(tls->ssl,status)) {
+    case SSL_ERROR_NONE         :
+      status=0;
+      if ((peer=SSL_get_peer_certificate(tls->ssl))!=(X509 *)0) {
+        if (SSL_get_verify_result(tls->ssl)!=X509_V_OK)
+          status=-1;
+        (void) X509_free(peer);
+        }
+      break;
+    case SSL_ERROR_WANT_READ    :
+      done=dowait(tls,&attend);
+      break;
+    case SSL_ERROR_WANT_WRITE   :
+      done=false;
+      break;
+    case SSL_ERROR_SYSCALL      :       //EOF received?
+      if (ERR_get_error()==0)
+        tls->goteof=true;               //EOF received!
+      else
+        (void) showtlserror(tls,status,"%s SSL_SYSCALL pbs",OPEP);
+      status=-1;
+      break;
+    default     :
+      (void) showtlserror(tls,status,"%s SSL_accept fatal error (sslerr='%d')",
+                                      OPEP,sslerr);
+      status=-1;
+      break;
+    }
+  }
+return status;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to open an SSL channel                */
 /*                                                      */
 /********************************************************/
@@ -148,6 +254,7 @@ certpub[2]="./kleenex/key.pem";   //JMPDBG test
 phase=0;
 proceed=true;
 while (proceed==true) {
+  (void) fprintf(stderr,"JMPDBG set_server_certificate phase='%d'\n",phase);
   switch (phase) {
     case 0      :       //load CA trusted file
       if (SSL_CTX_use_certificate_chain_file(ctx,certpub[0])!=1) {
@@ -222,9 +329,11 @@ if (server==true)
 phase=0;
 proceed=true;
 while (proceed==true) {
+  (void) fprintf(stderr,"JMPDBG tlsopentls phase='%d'\n",phase);
   switch (phase) {
     case 0      :       //prepare the structure first;
       tls=(TLSTYP *)calloc(1,sizeof(TLSTYP));
+      tls->handle=handle;
       tls->server=server;
       if ((tls->ctx=SSL_CTX_new(tls_methode()))==(SSL_CTX *)0) {
         (void) showtlserror(tls,0,"Get CTX");
@@ -312,6 +421,52 @@ return got;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to accept a TLS connection from peer. */
+/*                                                      */
+/********************************************************/
+PUBLIC int tls_accept(TLSTYP *tls)
+
+{
+#define OPEP    "unitls.c:tls_accept"
+int status;
+int phase;
+int proceed;
+
+status=-1;
+phase=0;
+proceed=true;
+while (proceed==true) {
+  switch (phase) {
+    case 0      :       //checking TLS
+      if (tls==(TLSTYP *)0) {
+        (void) rou_core_dump("%s, TLS pointer is NULL! (bug?)",OPEP);
+        phase=000;      //trouble trouble
+        }
+      break;
+    case 1      :       //checking TLS
+      if ((tls->bio=BIO_new_fd(tls->handle,BIO_NOCLOSE))==(BIO *)0) {
+        (void) rou_core_dump("%s, Unable to get the BIO (error=<%s>)",
+                              OPEP,strerror(errno));
+        }
+      break;
+    case 2      :       //set BIO properly
+      (void) SSL_set_bio(tls->ssl,tls->bio,tls->bio);
+      status=doaccept(tls);
+      break;
+    default     :       //SAFE guard
+      proceed=false;
+      break;
+    }
+  phase++;
+  }
+return status;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to check if remote certificat is a    */
 /*      valide one.                                     */
 /*      return -1if trouble, 0 otherwise                */
index aeb1d1a7fe9aa76ece6e236ea71ae8e7d44eb08b..f46290172c26351186448f8a199465139e2646a6 100644 (file)
@@ -13,6 +13,8 @@
 
 typedef struct  {
         _Bool server;   //SSL server/client mode
+        _Bool goteof;   //SSL End Of File
+        int handle;     //device handle
         SSL_CTX *ctx;   //SSL context
         SSL *ssl;       //SSL link
         BIO *bio;       //SSL Basic input output
@@ -30,6 +32,9 @@ extern int tls_write(TLSTYP *tls,char *buffer,int tosend);
 //read from the SSL channel
 extern int tls_read(TLSTYP *tls,char *buffer,int maxread);
 
+//accept a TLS connection
+extern int tls_accept(TLSTYP *tls);
+
 //check peer certificat
 extern int tls_check_peer(TLSTYP *tls);