]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Mejor reorganisation about devsoc module
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Mon, 5 Aug 2024 22:45:22 +0000 (18:45 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Mon, 5 Aug 2024 22:45:22 +0000 (18:45 -0400)
Makefile
app/Makefile
lib/Makefile
lib/devsoc.c
lib/devsoc.h
lib/gestcp.c
lib/gestcp.h
lib/modrec.c
lib/subrou.c
lib/unissl.c
lib/unissl.h

index b191f2269d1faeefc1cc4245fc5665808f091626..3919fb509a25c7e7890e4265fb9dce9e3eea8028 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,6 @@ install       :
 
 #--------------------------------------------------------------------
 SUBDIR =                                                               \
-          kleenex                                                      \
           lib                                                          \
           app                                                          \
 
index 1996e6d09cefea6651f25ef0a2315b150c8a96a8..1246d9b745824eb179dfe62cdbf30648060c5fec 100644 (file)
@@ -37,6 +37,7 @@ CFLAGS        =  -I ../lib -Wall $(OPTIME)
 LIBAI  =  ../lib/libAI.a
 LIBS   =       $(LIBAI)                        \
                -lcrypto                        \
+               -lssl                           \
 
 #--------------------------------------------------------------------
 #Dependances
index a7e2650a2ff84bff420d7b05795b3e5a95ddf075..86644be876603e920947310c04a212a3d55818ce 100644 (file)
@@ -44,7 +44,9 @@ gestcp.o:                                     \
 
 devsoc.o:                                      \
           subrou.h                             \
+          unieml.h                             \
           uniprc.h                             \
+          unissl.h                             \
           devsoc.h devsoc.c
 
 unieml.o:                                      \
index aefaf7cd10fbd8b2227febb77227850b15b3ddf9..a9007f0187047d2f8931565dcc4c76de0bd3cd77 100644 (file)
 #include        <errno.h>
 #include        <fcntl.h>
 #include        <netdb.h>
+#include        <poll.h>
 #include        <stdio.h>
 #include        <stdlib.h>
 #include        <string.h>
 #include        <unistd.h>
 
 #include       "subrou.h"
+#include       "unieml.h"
 #include       "uniprc.h"
 #include       "unissl.h"
 #include       "devsoc.h"
 #define HINTFLG AI_CANONNAME
 #endif
 
+#define MXCARIN 200     //maximun number of char within carpile
+
 typedef struct  {
         PROTYP proto;   //Connexion protocol type
+        int handle;     //connexion handle
+        SSL_CTX *ctx;   //encryption context
+        int maxcarin;   //absolute number within carin
+        char *EOL;      //End of line marker
+        int carin;      //number of char within incpt;
+        char *carpile;  //area to store incoming char
         char *ip;       //Binding IP    //IPV4 or IPV6
         char *port;     //Binding Port
         char *hostname; //binding hostname
         time_t lasttry; //successful binding last time
         int iteration;  //number of soc slot used on the IP
-        int handle;     //connexion handle
         }SOCTYP;
 
 static  _Bool modopen;        //module open/close status
@@ -48,7 +57,7 @@ static  _Bool modopen;        //module open/close status
 /*                                                     */
 /*                                                      */
 /********************************************************/
-static SOCPTR *freebinding(SOCPTR *socptr)
+static SOCPTR *freesocket(SOCPTR *socptr)
 
 {
 if (socptr!=(SOCPTR *)0) {
@@ -58,6 +67,7 @@ if (socptr!=(SOCPTR *)0) {
   soc->hostname=rou_freestr(soc->hostname);
   soc->ip=rou_freestr(soc->ip);
   soc->port=rou_freestr(soc->port);
+  soc->carpile=rou_freestr(soc->carpile);
   (void) free(soc);
   socptr=(SOCPTR *)0; 
   }
@@ -68,6 +78,92 @@ return socptr;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to create a new socket                */
+/*                                                     */
+/*                                                      */
+/********************************************************/
+static SOCTYP *newsocket()
+
+{
+SOCTYP *soc;
+
+soc=(SOCTYP *)calloc(1,sizeof(SOCTYP));
+soc->maxcarin=MXCARIN;
+soc->carin=0;
+soc->EOL=strdup(CRLF);
+soc->carpile=(char *)calloc(soc->maxcarin,sizeof(char));
+return soc;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to duplicate a socket                 */
+/*                                                      */
+/********************************************************/
+static SOCTYP *dupsocket(SOCTYP *soc)
+
+{
+SOCTYP *newsoc;
+
+newsoc=(SOCTYP *)newsocket();
+newsoc->proto=soc->proto;
+newsoc->hostname=strdup(soc->hostname);
+newsoc->ip=strdup(soc->ip);
+newsoc->port=strdup(soc->port);
+newsoc->iteration=soc->iteration;
+newsoc->handle=-1;
+return newsoc;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to wait and get a new handle          */
+/*                                                      */
+/********************************************************/
+static int getnewhandle(SOCTYP *soc)
+
+{
+#define OPEP    "devsoc.c:getnewhandle"
+
+int newhandle;
+
+if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) {
+  if (errno==EAGAIN)
+    errno=EWOULDBLOCK;
+  switch (errno) {
+    case EWOULDBLOCK    :
+      (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> is in no_block mode "
+                         "(Bug?!, errno=<%s>)",
+                         OPEP,soc->ip,soc->port,strerror(errno));
+      break;
+    case EINVAL         :
+      (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> not available "
+                         "(Bug?!, errno=<%s>)",
+                         OPEP,soc->ip,soc->port,strerror(errno));
+      break;
+    case EINTR          :
+      (void) rou_alert(3,"%s Socket on IP/PORT <%s/%s> got a signal "
+                         "(errno=<%s>)",
+                         OPEP,soc->ip,soc->port,strerror(errno));
+      break;
+    default             :
+      (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> (errno=<%s>)",
+                         OPEP,soc->ip,soc->port,strerror(errno));
+      break;
+    }
+  }
+return newhandle;
+#undef  OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to bind a socket to a specific        */
 /*     address and return the linked handle            */
 /*                                                      */
@@ -75,7 +171,7 @@ return socptr;
 static int bindhandle(struct addrinfo *ai,SOCTYP *soc)
 
 {
-#define        OPEP    "unisoc.c:bindhandle,"
+#define        OPEP    "devsoc.c:bindhandle,"
 #define        BFSZ    30      //working buffer size
 
 int handle;
@@ -167,7 +263,7 @@ if (socptr!=(SOCPTR **)0) {
 
   socs=(SOCTYP **)socptr;
   for (i=0;socs[i]!=(SOCTYP *)0;i++) {
-    socs[i]=freebinding(socs[i]);
+    socs[i]=freesocket(socs[i]);
     }
   (void) free(socs);
   socptr=(SOCPTR **)0;
@@ -189,7 +285,7 @@ PUBLIC SOCPTR **soc_mkbindinf(SOCPTR **socptr,PROTYP proto,
 {
 SOCTYP *soc;
 
-soc=(SOCTYP *)calloc(1,sizeof(SOCTYP));
+soc=newsocket();
 soc->proto=proto;
 soc->ip=strdup(ip);
 soc->port=strdup(port);
@@ -229,7 +325,7 @@ return iterations;
 PUBLIC _Bool  soc_openbinding(SOCPTR *socptr)
 
 {
-#define OPEP    "unisoc.c:soc_openbinding"
+#define OPEP    "devsoc.c:soc_openbinding"
 
 _Bool done;
 SOCTYP *soc;
@@ -322,7 +418,7 @@ return done;
 PUBLIC void soc_closebinding(SOCPTR *socptr)
 
 {
-#define OPEP    "unisoc.c:soc_closebinding"
+#define OPEP    "devsoc.c:soc_closebinding"
 
 SOCTYP *soc;
 int phase;
@@ -363,63 +459,390 @@ while (proceed==true) {
 */
 /********************************************************/
 /*                                                     */
+/*      Procedure to wait for incoming character on     */
+/*      socket, waiting up to attend second.            */
+/*                                                     */
+/********************************************************/
+PUBLIC int soc_waitforchar(SOCPTR *socptr,TIMESPEC *attend)
+
+{
+register int status;
+
+status=-1;
+if (socptr!=(SOCTYP *)0) {      
+  struct pollfd polling[1];
+
+  polling[0].events=POLLIN|POLLPRI;
+  polling[0].revents=(short)0;
+  polling[0].fd=((SOCTYP *)socptr)->handle;
+  status=ppoll(polling,1,attend,(sigset_t *)0);
+  }
+return status;
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                     */
+/*      Procedure to return the next available line     */
+/*      within the socket carpile.                      */
+/*                                                     */
+/********************************************************/
+PUBLIC int soc_getnextline(SOCPTR *socptr,char **lineptr)
+
+{
+#define OPEP    "devsoc.c:soc_getnextline"
+
+int got;
+register SOCTYP *soc;
+char *eol;
+int phase;
+_Bool proceed;
+
+*lineptr=(char *)0;
+got=0;
+eol=(char *)0;
+soc=(SOCTYP *)socptr;
+phase=0;
+proceed=true;
+while (proceed==true) {
+  switch (phase) {
+    case 0      :       //Do we have dat in carpile
+      if (soc==(SOCTYP *)0) {
+        (void) rou_alert(0,"%s, socket binding reference is NULL (Bug!?)",OPEP);
+        phase=999;      //no need to go further
+        }
+    case 1      :       //Do we have char available in carpile
+      if (soc->carin==0)
+        phase=999;      //No char,no need to check for line
+      break;
+    case 2      :       //Do we have a CRLF
+      eol=strstr(soc->carpile,soc->EOL);
+      if (eol==(char *)0) 
+        phase=999;      //No End Of Line yet
+      break;
+    case 3      :       //duplicating carpile
+      *lineptr=calloc(soc->carin+1,sizeof(char));
+      *eol='\000';
+      (void) strcpy(*lineptr,soc->carpile);
+      (void) strcat(*lineptr,soc->EOL);
+      got=strlen(*lineptr);
+      break;
+    case 4      :       //managing carpile
+      soc->carin-=strlen(*lineptr);
+      if (soc->carin>0) 
+        (void) memmove(soc->carpile,soc->carpile+strlen(*lineptr),soc->carin);
+      soc->carpile[soc->carin]='\000';
+      break;
+    default     :       //SAFE guard
+      proceed=false;
+      break;
+    }
+  phase++;
+  }
+return got;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to send data to a tcp socket.         */
+/*      return the number of character transmitted, is  */
+/*      unable to send char return -1;                  */
+/*                                                      */
+/********************************************************/
+PUBLIC  int soc_writebuffer(SOCPTR *socptr,char *buffer,int tosend)
+
+{
+#define OPEP    "devsoc.c:soc_writebuffer"
+
+int sent;
+SOCTYP *soc;
+
+sent=-1;
+soc=(SOCTYP *)socptr;
+if (soc!=(SOCTYP *)0) {
+  int got;
+
+  got=recv(soc->handle,(char *)0,0,MSG_PEEK);
+  switch (got) {
+    case -1       :
+      if (errno==EWOULDBLOCK)
+        errno=EAGAIN;
+      switch (errno) {
+        case EAGAIN       :
+          sent=send(soc->handle,buffer,tosend,0);
+        break;
+      default           :
+        (void) rou_alert(9,"%s, Unexpected status '%02d' error=<%s> (errno='%d')\n",
+                            OPEP,got,strerror(errno),errno);
+        break;
+      }
+    default       :
+      (void) fprintf(stderr,"Got JMPDBG'%02d'\n",got);
+      break;
+    }
+  }
+return sent;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                     */
+/*      Procedure to read incoming character from the    */
+/*      socket.                                         */
+/*                                                     */
+/********************************************************/
+PUBLIC void soc_receive(SOCPTR *socptr)
+
+{
+SOCTYP *soc;
+
+soc=(SOCTYP *)socptr;
+if (soc!=(SOCTYP *)0) {
+  int got;
+  int limit;
+
+  limit=(soc->maxcarin-soc->carin)-1;
+  got=recv(soc->handle,soc->carpile+soc->carin,limit,MSG_DONTWAIT);
+  switch (got) {
+    case -1     :               //do not block
+      if (errno==EWOULDBLOCK)
+        errno=EAGAIN;
+      switch (errno) {
+        case EAGAIN     :       //no char available
+        break;
+      default           :
+        (void) fprintf(stderr,"JMPDBG soc_receive error=<%s>\n",strerror(errno));
+        break;
+        }
+      break;
+    case 0      :               //EOL?
+      break;
+    default     :               //we got som char from remote
+      soc->carin+=got;           //managing carpile
+      soc->carpile[soc->carin]='\000';
+      break;
+    }
+  }
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                     */
 /*      Procedure to wait an accept a connexion comming */
 /*      from a remote client.                           */
 /*      return the handle                               */
 /*                                                     */
 /********************************************************/
-PUBLIC int soc_accept(SOCPTR *socptr,int pos)
+PUBLIC SOCPTR *soc_accept(SOCPTR *socptr,int pos)
 
 {
-#define OPEP    "unisoc.c:soc_accept"
+#define OPEP    "devsoc.c:soc_accept"
 
+SOCTYP *newsoc;
 int newhandle;
-register SOCTYP *soc;
+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) {
+  switch (phase) {
+    case 0      :       //checking if soc is available
+      if (soc==(SOCTYP *)0) {
+        (void) rou_core_dump("%s, socket descripteur missing (Bug?)",OPEP);
+        phase=999;      //never reached
+        }
+      break;
+    case 1      :       //display ready on process status;
+      (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;
+        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
+          newsoc->ctx=ssl_getctx(true); //ssl in server mode
+          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;
+    }
+  phase++;
+  }
+return (SOCPTR *)newsoc;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                     */
+/*      Procedure to return the addrename or port       */
+/*      for local or remote socket.                     */
+/*                                                     */
+/********************************************************/
+PUBLIC char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool ip)
+
+{
+#define OPEP    "devsoc.c:soc_getaddrinfo"
+
+char *data;
+SOCTYP *soc;
+int mode;
+
+data=(char *)0;
+soc=(SOCTYP *)socptr;
+mode=NI_NAMEREQD;
+if (local==false)
+  mode=NI_NUMERICHOST;
+mode|=NI_NUMERICSERV;
 if (soc!=(SOCTYP *)0) {
-  (void) prc_settitle("Waiting contact (%02d/%02d) on %s:%s",
-                       pos,soc->iteration,soc->ip,soc->port);
-  if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) {
-    if (errno==EAGAIN)
-      errno=EWOULDBLOCK;
-    switch (errno) {
-      case EWOULDBLOCK    :
-        (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> is in no_block mode "
-                           "(Bug?!, errno=<%s>)",
-                           OPEP,soc->ip,soc->port,strerror(errno));
-      break;
-      case EINVAL         :
-        (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> not available "
-                           "(Bug?!, errno=<%s>)",
-                           OPEP,soc->ip,soc->port,strerror(errno));
-        break;
-      case EINTR          :
-        (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> got a signal "
-                           "(errno=<%s>)",
-                           OPEP,soc->ip,soc->port,strerror(errno));
-        break;
-      default             :
-        (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> (errno=<%s>)",
-                           OPEP,soc->ip,soc->port,strerror(errno));
-        break;
-      }
+  int status;
+  struct sockaddr connip;
+  socklen_t taille;
+  char host[NI_MAXHOST];
+  char serv[NI_MAXSERV];
+
+  taille=(socklen_t)(sizeof(connip));
+  if (local==true) 
+    status=getsockname(soc->handle,&connip,&taille);
+  else
+    status=getpeername(soc->handle,&connip,&taille);
+  switch (status) {
+    case -1     :               //trouble to read socket data
+      switch(errno) {
+        case ENOTCONN   :       //other side just vanished
+          break;
+        default         :
+          (void) rou_alert(0,"%s, Unable to socket data (local=%d, error=<%s>)",
+                          OPEP,local,strerror(errno));
+          break;
+        }
+      break;
+    default     :
+      if (getnameinfo(&connip,taille,host,sizeof(host),serv,sizeof(serv),mode)==0) {
+        if (ip==true)
+          data=strdup(host);
+        else
+          data=strdup(serv);
+        }
+      break;
     }
-  else {
-    int flags;
+  }
+return data;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                     */
+/*      Procedure to close and release exchange socket  */
+/*                                                     */
+/********************************************************/
+SOCPTR *soc_release(SOCPTR *socptr)
 
-    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));
-    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>)",
+{
+#define OPEP    "devsoc.c:soc_release"
+
+SOCTYP *soc;
+int phase;
+_Bool proceed;
+
+soc=(SOCTYP *)socptr;
+phase=0;
+proceed=true;
+while (proceed==true) {
+  switch (phase) {
+    case 0      :       //checking if soc is available
+      if (soc==(SOCTYP *)0) {
+        (void) rou_core_dump("%s, socket descripteur missing (Bug?)",OPEP);
+        phase=999;      //never reached
+        }
+      break;
+    case 1      :       //shuting dow the TCP link
+      if (shutdown(soc->handle,SHUT_RDWR)<0) {
+        switch (errno) {
+          case ENOTCONN :       //already disconnect by other side!
+            (void) rou_alert(0,"%s [%s:%s] Already disconnected (errno=<%s>)",
+                               OPEP,soc->ip,soc->port,strerror(errno));
+            break;
+         default       :
+            (void) rou_alert(0,"%s unable to shutdown [%s:%s] (errno=<%s>)",
+                                OPEP,soc->ip,soc->port,strerror(errno));
+            break;
+          }
+        }
+      break;
+    case 2      :       //closing connexion
+      if (close(soc->handle)<0) {
+        (void) rou_alert(0,"%s unable to close channel [%s:%s] properly "
+                           "(errno=<%s>)",
                             OPEP,soc->ip,soc->port,strerror(errno));
+        }
+      break;
+    case 3      :       //freeing the SSL contaxt
+      soc->ctx=ssl_releasectx(soc->ctx);
+      break;
+    case 4      :       //fee memory used by socket
+      soc=freesocket(soc);
+      socptr=(SOCPTR *)soc;
+      break;
+    default     :       //SAFE guard    
+      proceed=false;
+      break;
     }
+  phase++;
   }
-return newhandle;
+return socptr;
 #undef  OPEP
 }
 /*
@@ -444,12 +867,14 @@ if (mode!=modopen) {
   switch ((int)mode) {
     case true     :
       (void) rou_modesubrou(mode);
+      (void) eml_modeunieml(mode);
       (void) prc_modeuniprc(mode);
       (void) ssl_modeunissl(mode);
       break;
     case false    :
       (void) ssl_modeunissl(mode);
       (void) prc_modeuniprc(mode);
+      (void) eml_modeunieml(mode);
       (void) rou_modesubrou(mode);
       break;
     default       :
index d15fb63932c5f6c724946b406cdfb62a5d75184b..fbbc8faba8d8f8077305f9530ee799489a5a221e 100644 (file)
@@ -18,7 +18,7 @@ typedef struct sockaddr SOCKADDR;
 //defining email protocol value.
 typedef enum    {
         pro_smtp,       //text SMTP protocol, in clear mode
-        pro_startls,    //Text SMTP protocol, encrypted upon request
+        pro_starttls,   //Text SMTP protocol, encrypted upon request
         pro_smtps,      //Text SMTP protocol, text encrypted from start
         pro_unknwn      //Protcole undefined
         }PROTYP;
@@ -44,8 +44,26 @@ extern _Bool soc_openbinding(SOCPTR *socptr);
 //procedure to close ONE socket
 extern void soc_closebinding(SOCPTR *socptr);
 
+//procedure to wait form character on contact
+extern int soc_waitforchar(SOCPTR *socptr,TIMESPEC *attend);
+
+//procedure to return a char array with the available line
+extern int soc_getnextline(SOCPTR *socptr,char **lineptr);
+
+//procedure to send a buffer contens on channel
+extern int soc_writebuffer(SOCPTR *socptr,char *buffer,int tosend);
+
+//procedure to receive up to limit char from socket
+extern void soc_receive(SOCPTR *socptr);
+
 //procedure to wait and accept remote connexion
-extern int soc_accept(SOCPTR *socptr,int pos);
+extern SOCPTR *soc_accept(SOCPTR *socptr,int pos);
+
+//procedure to get information about addrbane and port
+extern char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool ip);
+
+//procedure to release/clsoe socket
+extern SOCPTR *soc_release(SOCPTR *socptr);
 
 //homework to be done before starting/stopping module.
 extern int soc_modedevsoc(_Bool mode);
index 7df10ced585b76c4f818663a9c97dbd9216e022b..b803f01ecd26b5b6e4fbe2c22785df7919701317 100644 (file)
 
 static  _Bool modopen;          //boolean module open/close
 /*
-\f
-*/
-/********************************************************/
-/*                                                     */
-/*     Procedure to find the hostname related to an    */
-/*      socket, if local is true return the local       */
-/*      hostname else return the remote PID.            */
-/*      if trouble, return a NULL pointer.              */
-/*                                                     */
-/********************************************************/
-static char *getaddrname(int handle,_Bool local)
-
-{
-#define OPEP    "gestcp.c:soc_getaddrname"
-
-char *name;
-
-struct sockaddr connip;
-socklen_t taille;
-int status;
-char host[NI_MAXHOST];
-
-name=(char *)0;
-taille=sizeof(connip);
-status=-1;
-if (local==true) {
-  if ((status=getsockname(handle,&connip,&taille))==0) {
-    if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NAMEREQD)==0)
-      name=strdup(host);
-    }
-  }
-else {
-  if ((status=getpeername(handle,&connip,&taille))==0) {
-    if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NUMERICHOST)==0)
-      name=strdup(host);
-    }
-  }
-if (status<0) {
-  switch (errno) {
-    case ENOTCONN       :       //other side just vanished
-      break;
-    default             :
-      (void) rou_alert(0,"%s, Unable to find reverse (local=%d, error=<%s>)",
-                          OPEP,local,strerror(errno));
-      break;
-    }
-  }
-return name;
-#undef  OPEP
-}
-/*
 ^L
 */
 /********************************************************/
@@ -86,14 +35,6 @@ static CONTYP *freecontact(CONTYP *contact)
 #define OPEP    "gesttcp.c:freecontact"
 
 if (contact!=(CONTYP *)0) {
-  if (contact->channel>=0) {
-    if (close(contact->channel)<0) {
-      (void) rou_alert(0,"%s unable to close channel properly (errno=<%s>)",
-                            OPEP,strerror(errno));
-      }
-    }
-  contact->carpile=rou_freestr(contact->carpile);
-  contact->EOL=rou_freestr(contact->EOL);
   contact->peerip=rou_freestr(contact->peerip);
   contact->locname=rou_freestr(contact->locname);
   (void) free(contact);
@@ -107,121 +48,6 @@ return contact;
 */
 /********************************************************/
 /*                                                      */
-/*     Procedure to check if char are available on     */
-/*      soc interface.                                  */
-/*      comming from the remote end.                    */
-/*                                                      */
-/********************************************************/
-static int waitforchar(CONTYP *tact,TIMESPEC *attend)
-
-{
-struct pollfd polling[1];
-
-polling[0].events=POLLIN|POLLPRI;
-polling[0].revents=(short)0;
-polling[0].fd=tact->channel;
-return ppoll(polling,1,attend,(sigset_t *)0);
-}
-/*
-^L
-*/
-/********************************************************/
-/*                                                      */
-/*     Procedure to read the maximun of characters     */
-/*      comming from the remote end.                    */
-/*                                                      */
-/********************************************************/
-static void readmaxchar(CONTYP *tact)
-
-{
-int limit;
-
-limit=(tact->maxcarin-tact->carin)-1;
-if (limit>0) {
-  int got;
-
-  got=recv(tact->channel,tact->carpile+tact->carin,limit,MSG_DONTWAIT);
-  (void) printf("readmax got '%d' char\n",got);
-  switch (got) {
-    case -1     :               //do not block
-      if (errno==EWOULDBLOCK)
-        errno=EAGAIN;
-      switch (errno) {
-        case EAGAIN     :       //no char available
-        break;
-      default           :
-        (void) fprintf(stderr,"JMPDBG readmax error=<%s>\n",strerror(errno));
-        break;
-        }
-      break;
-    case 0      :               //EOL?
-      break;
-    default     :               //we got som char from remote
-      tact->carin+=got;         //managing carpile
-      tact->carpile[tact->carin]='\000';
-      break;
-    }
-  }
-}
-/*
-^L
-*/
-/********************************************************/
-/*                                                      */
-/*     Procedure to locate CRLF within the current line*/
-/*      assigne memory and store carpile contents       */
-/*                                                      */
-/********************************************************/
-static int getnextline(CONTYP *tact,char **lineptr)
-
-{
-int got;
-char *eol;
-int phase;
-_Bool proceed;
-
-*lineptr=(char *)0;
-got=0;
-eol=(char *)0;
-phase=0;
-proceed=true;
-while (proceed==true) {
-  switch (phase) {
-    case 0      :       //Do we have dat in carpile
-      if (tact->carin==0)
-        phase=999;      //No char,no need to check for line
-      break;
-    case 1      :       //Do we have a CRLF
-      eol=strstr(tact->carpile,tact->EOL);
-      if (eol==(char *)0) 
-        phase=999;      //No End Of Line yet
-      break;
-    case 2      :       //duplicating carpile
-      *lineptr=calloc(tact->carin+1,sizeof(char));
-      *eol='\000';
-      (void) strcpy(*lineptr,tact->carpile);
-      (void) strcat(*lineptr,tact->EOL);
-      got=strlen(*lineptr);
-      break;
-    case 3      :       //managing carpile
-      tact->carin-=strlen(*lineptr);
-      if (tact->carin>0) 
-        (void) memmove(tact->carpile,tact->carpile+strlen(*lineptr),tact->carin);
-      tact->carpile[tact->carin]='\000';
-      break;
-    default     :       //SAFE guard
-      proceed=false;
-      break;
-    }
-  phase++;
-  }
-return got;
-}
-/*
-^L
-*/
-/********************************************************/
-/*                                                      */
 /*     Procedure to read char from remote peer, wait   */
 /*      for a CRLF AS EOL.                              */
 /*                                                      */
@@ -247,16 +73,16 @@ while (proceed==true) {
         }
       break;
     case 1      :       //get nextline
-      if ((got=getnextline(contact,lineptr))>0)
+      if ((got=soc_getnextline(contact->socptr,lineptr))>0)
         phase=999;      //we got a line.
       break;
     case 2      :       //waiting for new character presence
-      switch (waitforchar(contact,attend)) {
+      switch (soc_waitforchar(contact->socptr,attend)) {
         case -1         :       //trouble? signal?
         case  0         :       //normal time out
           break;                //no need to read line
         default         :       //char available
-          (void) readmaxchar(contact);
+          (void) soc_receive(contact->socptr);
           phase=0;              //check for new line
           break;
         }
@@ -275,37 +101,18 @@ return got;
 */
 /********************************************************/
 /*                                                      */
-/*     Procedure to send data to a tcp socket.         */
-/*      return the number of character transmitted, is  */
-/*      unable to send char return -1;                  */
+/*     Procedure to write buffer on the socket output  */
+/*      return the number of char sent on channel.      */
 /*                                                      */
 /********************************************************/
-PUBLIC int tcp_write(CONTYP *contact,char *buffer,int parnum)
+PUBLIC int tcp_write(CONTYP *contact,char *buffer,int tosend)
 
 {
 int sent;
-int got;
 
 sent=-1;
-got=recv(contact->channel,(char *)0,0,MSG_PEEK);
-switch (got) {
-  case -1       :
-    if (errno==EWOULDBLOCK)
-      errno=EAGAIN;
-    switch (errno) {
-      case EAGAIN       :
-        sent=send(contact->channel,buffer,parnum,0);
-        break;
-      default           :
-        (void) fprintf(stderr,"Got '%02d' error=<%s> (errno='%d')\n",
-                                     got,strerror(errno),errno);
-        break;
-      }
-    break;
-  default       :
-    (void) fprintf(stderr,"Got '%02d'\n",got);
-    break;
-  }
+if (contact!=(CONTYP *)0)
+  sent=soc_writebuffer(contact->socptr,buffer,tosend);
 return sent;
 }
 /*
@@ -341,20 +148,15 @@ while (proceed==true) {
       break;
     case 1      :       //waiting from contact
       contact=calloc(1,sizeof(CONTYP));
-      contact->socptr=socptr;
-      contact->maxcarin=MXCARIN;
-      contact->carin=0;
-      contact->EOL=strdup(CRLF);
-      contact->carpile=(char *)calloc(contact->maxcarin,sizeof(char));
-      if ((contact->channel=soc_accept(socptr,pos))<0) {
+      if ((contact->socptr=soc_accept(socptr,pos))==(SOCPTR *)0) {
         (void) rou_alert(0,"%s Unable to open contact",OPEP);
         contact=freecontact(contact);
         phase=999;      //no contact 
         }
       break;
     case 2      :       //check socket components
-      contact->locname=getaddrname(contact->channel,true);
-      contact->peerip=getaddrname(contact->channel,false);
+      contact->locname=soc_getaddrinfo(contact->socptr,true,false);
+      contact->peerip=soc_getaddrinfo(contact->socptr,false,false);
       if ((contact->locname==(char *)0)||(contact->peerip==(char *)0)) {
         (void) rou_alert(0,"%s Unable to establish contact entities",OPEP);
         contact=freecontact(contact);
@@ -421,18 +223,7 @@ while (proceed==true) {
       break;
     case 1      :       //properly closing remote contact
       (void) rou_alert(0,"Contact with IP=<%s> Exiting",contact->peerip);
-      if (shutdown(contact->channel,SHUT_RDWR)<0) {
-        switch (errno) {
-          case ENOTCONN :       //already disconnect by other side!
-            (void) rou_alert(0,"%s Already disconnected (errno=<%s>)",
-                               OPEP,strerror(errno));
-            break;
-          default       :
-            (void) rou_alert(0,"%s unable to shutdown (errno=<%s>)",
-                                OPEP,strerror(errno));
-            break;
-          }
-        }
+      contact->socptr=soc_release(contact->socptr);
       break;
     case 2      :       //freeing contact memory
       contact=freecontact(contact);              
index 219106239b2e2c0face52d683f4a3e88b0c5121b..6d985b19ca80e649c81195e8e6cc4fd6aa98cce4 100644 (file)
 #include        "devsoc.h"
 
 typedef struct  {
-        int channel;    //exchange channel handle
+        SOCPTR *socptr; //established contact context
         char *locname;  //socket local hostname
         char *peerip;   //socket remote peer IP
-        SOCPTR *socptr; //established contact context
-        int maxcarin;   //absolute number within carin
-        char *EOL;      //End of line marker
-        int carin;      //number of char within incpt;
-        char *carpile;  //area to store incoming char
         }CONTYP;
 
 //read a line from contact up to CRLF
 extern int tcp_getline(CONTYP *contact,TIMESPEC *attend,char **lineptr);
 
 //Transmit formated data to the contact channel
-extern int tcp_write(CONTYP *contact,char *buffer,int parnum);
+extern int tcp_write(CONTYP *contact,char *buffer,int tosend);
 
 //wait for an incoming contact
 extern CONTYP *tcp_getcontact(SOCPTR *socptr,int pos);
index 977646eb1debea6f6f3a59c767771418f4abf491..4acf4b2437c5e6d36aba598c53b2d826e496c6ce 100644 (file)
@@ -50,11 +50,10 @@ while (proceed==true) {
       if ((contact=tcp_getcontact(socptr,pos))==(CONTYP *)0)
         phase=999;      //No contact!
       break;
-    case 1      :       //forking process
-      printf("New client connected: %d\n",contact->channel);
+    case 1      :       //within forked process
+      printf("New client [%s] connected\n",contact->peerip);
       break;
     case 2      :       //do contact
-      printf("Client channel=%d (pid=%d)\n",contact->channel,getpid());
       for (int i=0;i<TESTL;i++) {
         TIMESPEC attend;
         char *line;
@@ -229,9 +228,9 @@ _Bool proceed;
 
 childs=(pid_t)0;
 bindings=(SOCPTR **)0;
-bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","1025",3);
-bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","1465",3);
-bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","1587",3);
+bindings=soc_mkbindinf(bindings,pro_smtps,"192.219.254.70","1465",3);
+//bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","1025",3);
+//bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","1587",3);
 nbrbind=rou_nbrlist((void **)bindings);
 phase=0;
 proceed=true;
index b33de6223ac1aab8f7438cc79cf7984c3342a0f7..f808aff9b782d64ce455814839a8b985ce66dac1 100644 (file)
@@ -20,7 +20,7 @@
 
 //version definition 
 #define VERSION "0.3"
-#define RELEASE "22"
+#define RELEASE "23"
 
 //Public variables
 PUBLIC  int debug=0;            //debug level
index aed299827e0016a5e6a1d5d0fff8de508d914b38..a68f7b3ce5dc8d37b203eabe857db66adfaca8a1 100644 (file)
@@ -6,8 +6,6 @@
 /*                                                     */
 /********************************************************/
 #include        <openssl/err.h>
-#include        <openssl/ssl.h>
-#include        <stdbool.h>
 #include        <stdio.h>
 
 #include       "subrou.h"
 
 static  _Bool modopen;        //module open/close status
 
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to realease all SSL contaxt           */
+/*                                                      */
+/********************************************************/
+PUBLIC SSL_CTX *ssl_releasectx(SSL_CTX *ctx)
+
+{
+(void) SSL_CTX_free(ctx);
+return (SSL_CTX *)0;
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to establish a working SSL context    */
+/*      Return SLL context or a NULL pointer            */
+/*                                                      */
+/********************************************************/
+PUBLIC SSL_CTX *ssl_getctx(_Bool server_mode)
+
+{
+#define OPEP    "unissl.c:ssl_getctx"
+
+SSL_CTX *ctx;
+const SSL_METHOD *(*tls_methode)();
+const char *certpub[2];
+int phase;
+_Bool proceed;
+
+ctx=(SSL_CTX *)0;
+tls_methode=TLS_client_method;
+if (server_mode==true)
+  tls_methode=TLS_server_method;
+phase=0;
+proceed=true;
+while (proceed==true) {
+  switch (phase) {
+    case 0      :       //Setting inital context
+      if ((ctx=SSL_CTX_new(tls_methode()))!=(SSL_CTX *)0) {
+        char reason[200];
+
+        (void) ERR_error_string(ERR_get_error(),reason);
+        (void) rou_core_dump("%s, Unable to set the SSL context err=<%s> (system?)",
+                              OPEP,reason);
+        phase=999;      //Useless, cire dump never return
+        }
+      break;
+    case 1      :       //getting certificat name
+      certpub[0]="./cert.pem";  //JMPDBG test 
+      certpub[1]="./key.pem";   //JMPDBG test 
+      break;
+    case 2      :       //set certificate
+      if (SSL_CTX_use_certificate_file(ctx,certpub[0],SSL_FILETYPE_PEM)!=1) {
+        char reason[200];
+
+        (void) ERR_error_string(ERR_get_error(),reason);
+        (void) rou_alert(0,"Unable to use certificate <%s> (error=<%s>)",
+                            certpub[0],reason);
+        (void) SSL_CTX_free(ctx);
+        ctx=(SSL_CTX *)0;
+        phase=999;
+        }
+      break;
+    case 3      :       //set key
+      if (SSL_CTX_use_PrivateKey_file(ctx,certpub[1],SSL_FILETYPE_PEM)!=1) {
+        char reason[200];
+
+        (void) ERR_error_string(ERR_get_error(),reason);
+        (void) rou_alert(0,"Unable to use certificate key <%s> (error=<%s>)",
+                            certpub[0],reason);
+        (void) SSL_CTX_free(ctx);
+        ctx=(SSL_CTX *)0;
+        phase=999;
+        }
+      break;
+    default     :       //SAFE guard
+      proceed=false;
+      break;
+    }
+  phase++;
+  }
+return ctx;
+#undef  OPEP
+}
 /*
 ^L
 */
index ef8d25bbc539d2ed1af8943bf43ac300e6d64119..018b6c9127bf530c3ca1b36c08689659da8e4529 100644 (file)
@@ -7,6 +7,15 @@
 #ifndef        UNISSL
 #define UNISSL
 
+#include        <stdbool.h>
+#include        <openssl/ssl.h>
+
+//releasing current SSL context;
+extern SSL_CTX *ssl_releasectx(SSL_CTX *ctx);
+
+//establishing SSL working context
+extern SSL_CTX *ssl_getctx(_Bool server_mode);
+
 //homework to be done before starting/stopping module.
 extern int ssl_modeunissl(_Bool mode);