]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Added tls_waitforchar procedure
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Sat, 3 May 2025 11:19:08 +0000 (07:19 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Sat, 3 May 2025 11:19:08 +0000 (07:19 -0400)
lib/unitls.c
lib/unitls.h

index b90234756829b4d0528aa632a14c25d810b5a6b0..26bfbfac09ae9746c41f6d96dc3f79b0977868e6 100644 (file)
@@ -630,6 +630,164 @@ return got;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to wait for characeter to be available*/
+/*      on the tls link.                                */
+/*      Wait for at most mili-second time.              */
+/*                                                      */
+/********************************************************/
+PUBLIC int tls_waitforchar(TLSTYP *tls,u_int millisec)
+
+{
+#define        OPEP    "unitls.c:tls_waitforchar,"
+
+int status;
+struct pollfd polling[1];
+_Bool proceed;
+int phase;
+
+status=-1;
+polling[0].events=POLLIN|POLLPRI;
+polling[0].revents=(short)0;
+proceed=true;
+phase=0;
+while (proceed==true) {
+  switch (phase) {
+    case 0      :       //check TLS
+      if ((tls==(TLSTYP *)0)||(tls->handle<0)) {
+        (void) rou_alert(0,"%s TLS is not available (Bug?)",OPEP);
+        phase=999;      //trouble trouble (Bug?)
+        }
+      break;
+    case 1      :       //lets assume we are cleartext mode
+      polling[0].fd=tls->handle;
+      if (tls->tls==true) {     //we are crypted mode
+        if (tls->ssl==(SSL *)0) { //Is ssl definined
+          (void) rou_alert(0,"%s Crypted mode but no SSL (Bug?)",OPEP);
+          phase=999;      //trouble trouble (Bug?)
+          }
+        else
+          polling[0].fd=SSL_get_fd(tls->ssl);
+        }
+      break;
+    case 2      :       //lets wait for char
+      status=poll(polling,1,millisec);
+      switch (status) {
+        case -1         :       //Polling error
+          (void) rou_alert(0,"%s Polling error (error=<%s>",OPEP,strerror(errno));
+          break;
+        case  0         :       //polling time out
+                                //nothing to do
+          break;
+        case  1         :       //char is available.
+                                //nothing to do
+          break;
+        }
+      break;
+    default     :       //SAFE Guard
+      proceed=false;
+      break;
+    }
+  phase++;
+  }
+return status;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to accept a TLS connection from a     */
+/*      remote client.                                  */
+/*                                                      */
+/********************************************************/
+PUBLIC int tls_accept(TLSTYP *tls)
+
+{
+#define        OPEP    "unitls.c:tls_accept,"
+
+int statut;
+X509 *peer;
+int tic;
+int done;
+
+statut=-1;
+peer=(X509 *)0;
+tic=30;         //30 second MAX to extablish SSL connexio
+done=false;
+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));
+  }
+(void) SSL_set_bio(tls->ssl,tls->bio,tls->bio);
+while (done==false) {
+  int sslerr;
+
+  statut=SSL_accept(tls->ssl);
+  switch (sslerr=SSL_get_error(tls->ssl,statut)) {
+    case SSL_ERROR_NONE             :
+      statut=0;
+      if ((peer=SSL_get_peer_certificate(tls->ssl))!=(X509 *)0) {
+        if (SSL_get_verify_result(tls->ssl)!=X509_V_OK)
+          statut=-1;
+        (void) X509_free(peer);
+        }
+      done=true;
+      break;
+    case SSL_ERROR_WANT_READ :
+      switch(tls_waitforchar(tls,(u_int)1000)) {
+        case -1                     :
+          switch(errno) {      /*received a signal, lets see...*/
+           case EINTR       :  /*could be a TERM signal        */
+             break;    
+           default          :  /*hummm real code fault report  */
+             (void) rou_core_dump("%s poll error '%s'",OPEP,strerror(errno));
+              done=true;
+             statut=-1;
+             break;
+           }
+         break;
+        case  0                     :  /*standard time out             */
+          tic--; 
+          if (tic<=0) {
+            done=true;
+            (void) rou_alert(0,"%s, SSL_accept too long to establish",OPEP);
+           statut=-1;
+           }
+          break;
+       default              :
+          break;
+        }
+      break;
+#ifdef SSL_ERROR_WANT_ACCEPT
+    case SSL_ERROR_WANT_ACCEPT :
+#endif
+    case SSL_ERROR_WANT_WRITE  :
+      break;
+    case SSL_ERROR_SYSCALL:    /*EOF received          */
+      if (ERR_get_error()==0)
+       tls->goteof=true;               
+      else
+        (void) showtlserror(tls,statut,"%s SSL_SYSCALL pbs",OPEP);
+      statut=-1;
+      done=true;
+      break;
+    default                            :
+      (void) showtlserror(tls,statut,"%s SSL_accept fatal error "
+                                    "(sslerr='%d')",OPEP,sslerr);
+      statut=-1;
+      done=true;
+      break; 
+    }
+  }
+return statut;
+#undef   OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to check if remote certificat is a    */
 /*      valide one.                                     */
 /*      return -1if trouble, 0 otherwise                */
index b26a85eda522177e4e0ceb3b6bc757ad703022b2..1fcf217a9e1669d5afa819fe57b34b3ecc97830e 100644 (file)
@@ -14,6 +14,8 @@
 typedef struct  {
         _Bool server;   //SSL server/client mode
         _Bool goteof;   //SSL End Of File
+        _Bool tls;      //link in TLS (crypted) mode
+        BIO *bio;       //SSL Basic IO
         int handle;     //device handle
         char *peerip;   //Remote IP number
         char *locip;    //Local IP number
@@ -34,9 +36,15 @@ 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
+//wait for a char alvalable on channel
+extern int tls_waitforchar(TLSTYP *tls,u_int millisec);
+
+//accept from a TLS client connection
 extern int tls_accept(TLSTYP *tls);
 
+//connect to a TLS serveur connection
+extern int tls_connect(TLSTYP *tls);
+
 //check peer certificat
 extern int tls_check_peer(TLSTYP *tls);