From 70ca90eb6959b04e0eb1e9045c01b3c0386f1772 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Wed, 7 Aug 2024 18:38:00 -0400 Subject: [PATCH] Still not able to establish a SSL link --- lib/devsoc.c | 176 +++++++++++++++++++++++++++++++++++++-------------- lib/subrou.c | 2 +- lib/unitls.c | 65 +++++++++++++++++-- 3 files changed, 187 insertions(+), 56 deletions(-) diff --git a/lib/devsoc.c b/lib/devsoc.c index c05cfa2..9fbb60b 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -113,7 +113,7 @@ newsoc->proto=soc->proto; newsoc->ip=strdup(soc->ip); newsoc->port=strdup(soc->port); newsoc->iteration=soc->iteration; -newsoc->handle=-1; +newsoc->handle=soc->handle; return newsoc; } /* @@ -121,7 +121,8 @@ return newsoc; */ /********************************************************/ /* */ -/* Procedure to wait and get a new handle */ +/* Procedure to wait incoming connexion on a */ +/* plain (not crypted) socket */ /* */ /********************************************************/ static int getnewhandle(SOCTYP *soc) @@ -131,6 +132,7 @@ static int getnewhandle(SOCTYP *soc) int newhandle; +(void) printf("JMPDBG soc handle='%d'\n",soc->handle); if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) { if (errno==EAGAIN) errno=EWOULDBLOCK; @@ -164,6 +166,125 @@ return newhandle; */ /********************************************************/ /* */ +/* Procedure to prepare plain incoming channel */ +/* */ +/********************************************************/ +static _Bool plainsoc(SOCTYP *soc) + +{ +#define OPEP "devsoc:plainsoc" + +_Bool good; +int newhandle; +int flags; +int phase; +_Bool proceed; + +good=false; +newhandle=-1; +flags=0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //First prepare a new socket + if ((newhandle=getnewhandle(soc))<0) { + phase=999; //no newhandle troub trouble + } + break; + case 1 : //getting newhandle flag + if ((flags=fcntl(newhandle,F_GETFL,0))<0) { + (void) rou_core_dump("%s, Unable to get socket descripteur on " + "IP/PORT <%s/%s> (Bug? error=<%s>)", + OPEP,soc->ip,soc->port,strerror(errno)); + phase=999; //never reached + } + break; + case 2 : //setting newhandle working mode + if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) { + (void) rou_core_dump("%s, Unable to set socket descripteur on " + "IP/PORT <%s/%s> (Bug? error=<%s>)", + OPEP,soc->ip,soc->port,strerror(errno)); + phase=999; //never reached + } + break; + case 3 : //Socket ready + soc->handle=newhandle; + good=true; + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return good; +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to wait and get a new handle */ +/* */ +/********************************************************/ +static SOCTYP *waitincoming(SOCTYP *soc) + +{ +#define OPEP "devsoc.c:waitincoming" + +SOCTYP *newsoc; +_Bool ready; +int phase; +_Bool proceed; + +(void) printf("JMPDBG starting from waitincoming\n"); +newsoc=(SOCTYP *)0; +ready=false; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //First prepare a new socket + newsoc=dupsocket(soc); + break; + case 1 : //wait for incoming connexion + switch (newsoc->proto) { + case pro_smtp : //plain socket + case pro_starttls : //plain socket + STARTTLS + ready=plainsoc(newsoc); + break; + case pro_smtps : //set secure socket + if ((newsoc->tls=tls_opentls(newsoc->handle,true))!=(TLSTYP *)0) + ready=tls_accept(newsoc->tls); + break; + default : + (void) rou_alert(0,"%s Protocol '%d' unset (Bug?)", + OPEP,(int)(newsoc->proto)); + break; + } + break; + case 2 : //wait for incoming connexion + if (ready==false) { + newsoc=soc_release(newsoc); //trouble touble + } + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +(void) printf("JMPDBG exit from waitincoming\n"); +return newsoc; +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ /* Procedure to bind a socket to a specific */ /* address and return the linked handle */ /* */ @@ -645,7 +766,7 @@ if (soc!=(SOCTYP *)0) { /* */ /* Procedure to wait an accept a connexion comming */ /* from a remote client. */ -/* return the handle */ +/* return a new socket. */ /* */ /********************************************************/ PUBLIC SOCPTR *soc_accept(SOCPTR *socptr,int pos) @@ -654,16 +775,12 @@ PUBLIC SOCPTR *soc_accept(SOCPTR *socptr,int pos) #define OPEP "devsoc.c:soc_accept" SOCTYP *newsoc; -int newhandle; SOCTYP *soc; -int flags; int phase; _Bool proceed; newsoc=(SOCTYP *)0; -newhandle=-1; soc=(SOCTYP *)socptr; -flags=0; phase=0; proceed=true; while (proceed==true) { @@ -678,51 +795,12 @@ while (proceed==true) { (void) prc_settitle("%s waiting on [%s:%s] (%02d/%02d)", appname,soc->ip,soc->port,pos,soc->iteration); break; - case 2 : //getting the new handle - if ((newhandle=getnewhandle(soc))<0) { - newhandle=-1; + case 2 : //waiting for new connection + if ((newsoc=waitincoming(soc))==(SOCPTR *)0) { + (void) rou_core_dump("%s, Contact from Remote not successful",OPEP); phase=999; //no need to go further } break; - case 3 : //getting newhandle flag - if ((flags=fcntl(newhandle,F_GETFL,0))<0) { - (void) rou_core_dump("%s, Unable to get socket descripteur on " - "IP/PORT <%s/%s> (Bug? error=<%s>)", - OPEP,soc->ip,soc->port,strerror(errno)); - phase=999; //never reached - } - break; - case 4 : //setting newhandle working mode - if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) { - (void) rou_core_dump("%s, Unable to set socket descripteur on " - "IP/PORT <%s/%s> (Bug? error=<%s>)", - OPEP,soc->ip,soc->port,strerror(errno)); - phase=999; //never reached - } - break; - case 5 : //preparing a new socket - newsoc=dupsocket(soc); - newsoc->handle=newhandle; - break; - case 6 : //configuring extra socket features - switch (newsoc->proto) { - case pro_smtp : //plain socket - case pro_starttls : //plain socket + STARTTLS - phase=999; - break; - case pro_smtps : //set secure socket - if ((newsoc->tls=tls_opentls(newsoc->handle,true))==(TLSTYP *)0) { - newsoc=soc_release(newsoc); //trouble trouble - break; - } - (void) tls_check_peer(newsoc->tls); - break; - default : //undefined socket type??? - (void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)", - OPEP,soc->proto); - break; - } - break; default : //SAFE guard proceed=false; break; diff --git a/lib/subrou.c b/lib/subrou.c index 24f8c8a..dd7e7f0 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "29" +#define RELEASE "30" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unitls.c b/lib/unitls.c index 067305a..0e6aa4b 100644 --- a/lib/unitls.c +++ b/lib/unitls.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "subrou.h" #include "unitls.h" @@ -57,6 +58,8 @@ char info[300]; good=true; va_start(args,msg); (void) vsnprintf(info,sizeof(info),msg,args); +(void) rou_alert(0,"JMPDBG showtlserror sslerror='%d' code='%d'", + sslerror,SSL_get_error(tls->ssl,sslerror)); if (sslerror<=0) { char *detail; int code; @@ -95,7 +98,9 @@ if (sslerror<=0) { detail="syscall error"; break; case SSL_ERROR_SSL : - detail=ERR_error_string(ERR_get_error(),(char *)0); + (void) showerrorstack(info); + //detail=ERR_error_string(ERR_get_error(),(char *)0); + detail="Bigre"; break; default : (void) rou_alert(0,"%s, caused by <%s> Unexpected ssl error='%d'", @@ -254,7 +259,6 @@ 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) { @@ -329,12 +333,14 @@ 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; + (void) SSL_library_init(); + (void) SSL_load_error_strings(); + (void) ERR_clear_error(); if ((tls->ctx=SSL_CTX_new(tls_methode()))==(SSL_CTX *)0) { (void) showtlserror(tls,0,"Get CTX"); tls=freetls(tls); @@ -384,14 +390,61 @@ return tls; PUBLIC int tls_write(TLSTYP *tls,char *buffer,int tosend) { +#define OPEP "unitls.c:tls_write" + int sent; -sent=-1; +sent=0; +(void) printf("JMPDBG sending<%s>\n",buffer); if (tls!=(TLSTYP *)0) { - if ((sent=SSL_write(tls->ssl,buffer,tosend))<=0) - (void) showtlserror(tls,sent,"Trouble to send data"); + _Bool proceed; + int sofar; + + proceed=true; + while (proceed==true) { + proceed=false; + sofar=SSL_write(tls->ssl,buffer,tosend); + switch (sent) { + case -1 : //trouble to write + switch (SSL_get_error(tls->ssl,-1)) { + case SSL_ERROR_WANT_READ : //"wanted" error + case SSL_ERROR_WANT_WRITE : + (void) usleep(1000); + proceed=true; + break; + default : + (void) showtlserror(tls,sofar,"%s Premature EOF with crypted link", + OPEP); + sent=-1; + break; + } + break; + case 0 : //no char sent + switch (SSL_get_error(tls->ssl,0)) { + case SSL_ERROR_SYSCALL : //EOF received? + tls->goteof=true; + if (ERR_get_error()!=0) + (void) rou_alert(0,"%s wrong EOF",OPEP); + break; + default : + (void) rou_alert(0,"%s Unexpected SSL_write error='%d'", + OPEP,SSL_get_error(tls->ssl,0)); + (void) showtlserror(tls,0,"%s JMPDBG Check what is SSL",OPEP); + break; + } + (void) sleep(1); + break; + default : //some character sent + (void) printf("JMPDBG sofar '%d' sent='%d'\n",sofar,sent); + sent+=sofar; + if (sent