From 7531a19461661edeb1e3091a7ad4d454396cb8a5 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Sat, 3 May 2025 07:19:08 -0400 Subject: [PATCH] Added tls_waitforchar procedure --- lib/unitls.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/unitls.h | 10 +++- 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/lib/unitls.c b/lib/unitls.c index b902347..26bfbfa 100644 --- a/lib/unitls.c +++ b/lib/unitls.c @@ -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 */ diff --git a/lib/unitls.h b/lib/unitls.h index b26a85e..1fcf217 100644 --- a/lib/unitls.h +++ b/lib/unitls.h @@ -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); -- 2.47.3