From 170b56feaecc34b6ceae851e0fae5ee8e53b2032 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Thu, 8 Aug 2024 20:43:59 -0400 Subject: [PATCH] Starting to add SMTP command --- lib/Makefile | 15 +++++++- lib/devsoc.c | 11 ++++-- lib/lvleml.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/lvleml.h | 19 ++++++++++ lib/modrec.c | 34 ++++++----------- lib/subrou.c | 2 +- lib/unieml.c | 37 +++++++++++++++++- lib/unieml.h | 10 +++++ lib/unitls.c | 10 ++--- 9 files changed, 207 insertions(+), 35 deletions(-) create mode 100644 lib/lvleml.c create mode 100644 lib/lvleml.h diff --git a/lib/Makefile b/lib/Makefile index 4eb2505..12d2978 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -17,6 +17,7 @@ clean : #-------------------------------------------------------------------- OBJS= \ modrec.o \ + lvleml.o \ gestcp.o \ devsoc.o \ unieml.o \ @@ -36,7 +37,13 @@ modrec.o: \ gestcp.h \ modrec.h modrec.c +lvleml.o: \ + subrou.h \ + unieml.h \ + lvleml.h lvleml.c + gestcp.o: \ + subrou.h \ unieml.h \ uniprc.h \ unisig.h \ @@ -50,6 +57,7 @@ devsoc.o: \ devsoc.h devsoc.c unieml.o: \ + subrou.h \ unieml.h unieml.c unipar.o: \ @@ -71,12 +79,15 @@ unitls.o: \ subrou.o: \ subrou.h subrou.c +lvleml.h: \ + gestcp.h + gestcp.h: \ subrou.h \ - devsoc.h \ + devsoc.h uniprc.h: \ - subrou.h \ + subrou.h #-------------------------------------------------------------------- diff --git a/lib/devsoc.c b/lib/devsoc.c index efa201b..548087e 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -705,13 +705,16 @@ while (proceed==true) { *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->carin-=(got+strlen(soc->EOL)); + if (soc->carin>0) { + int delta; + + delta=got+strlen(soc->EOL); + (void) memmove(soc->carpile,soc->carpile+delta,soc->carin); + } soc->carpile[soc->carin]='\000'; break; default : //SAFE guard diff --git a/lib/lvleml.c b/lib/lvleml.c new file mode 100644 index 0000000..e27996e --- /dev/null +++ b/lib/lvleml.c @@ -0,0 +1,104 @@ +// vim: smarttab tabstop=8 shiftwidth=2 expandtab +/********************************************************/ +/* */ +/* Implement all routine to manage SMTP low level */ +/* exchange. */ +/* */ +/********************************************************/ +#include +#include +#include + +#include "subrou.h" +#include "unieml.h" +#include "lvleml.h" + + + +static _Bool modopen; //module open/close status +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to proceed with peer exchange */ +/* 3 return values: */ +/* -1 exit with trouble. */ +/* 0 normal exit. */ +/* 1 continue to proceed. */ +/* */ +/********************************************************/ +PUBLIC int eml_docontact(CONTYP *contact) + +{ +#define OPEP "lvleml.c:eml_docontact" +int status; + +status=1; +while (status>0) { + char *line; + TIMESPEC attend; + + attend.tv_sec=60; + attend.tv_nsec=0; + status=tcp_getline(contact,&attend,&line); + if (status<=0) //timeout or trouble? + break; //no need to go further + switch (eml_getcode(line)) { + case c_quit : //quit SMTP protocol + status=0; + break; + case c_unknown : //uknown keyword + if (line[0]!='\000') { //always + char info[300]; + + (void) snprintf(info,sizeof(info),"%d command <%s> is unknown",CMDBAD,line); + (void) tcp_write(contact,info,strlen(info)); + (void) tcp_write(contact,CRLF,strlen(CRLF)); + } + break; + default : + (void) rou_alert(0,"Unable to find keyword for <%s> (Bug?)",OPEP,line); + status=-1; + break; + } + } +return status; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to "open/close" module and do */ +/* homework purpose */ +/* return zero if everything right */ +/* */ +/********************************************************/ +int eml_modelvleml(_Bool mode) + +{ +#define OPEP "unidoc.c:soc_modeunisoc" + +int status; + +status=0; +if (mode!=modopen) { + (void) rou_modesubrou(mode); + switch ((int)mode) { + case true : + break; + case false : + break; + default : + (void) fprintf(stderr,"Calling %s with wrong mode='%d' (Bug?!):", + OPEP,(int)mode); + status=-1; + break; + } + modopen=mode; + } +return status; +#undef OPEP +} diff --git a/lib/lvleml.h b/lib/lvleml.h new file mode 100644 index 0000000..6172c1a --- /dev/null +++ b/lib/lvleml.h @@ -0,0 +1,19 @@ +// vim: smarttab tabstop=8 shiftwidth=2 expandtab +/********************************************************/ +/* */ +/* Define all routine to manage SMTP high level */ +/* exchange. */ +/* */ +/********************************************************/ +#ifndef LVLEML +#define LVLEML + +#include "gestcp.h" + +//procedure to extract line and proceed with peer contact +extern int eml_docontact(CONTYP *contact); + +//homework to be done before starting/stopping module. +extern int eml_modelvleml(_Bool mode); + +#endif diff --git a/lib/modrec.c b/lib/modrec.c index 2f26ae4..7c94a63 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -18,6 +18,7 @@ #include "unisig.h" #include "devsoc.h" #include "gestcp.h" +#include "lvleml.h" #include "modrec.h" static _Bool modopen; //boolean module open/close @@ -54,28 +55,15 @@ while (proceed==true) { printf("New client [%s] connected\n",contact->peerip); break; case 2 : //do contact - for (int i=0;i\n",got,line); - quit=(strcasecmp(line,"QUIT"CRLF)==0); - (void) tcp_write(contact,line,strlen(line)); - (void) free(line); - if (quit==true) { - (void) printf("remote quit\n"); - break; //remote disconnect - } + switch (eml_docontact(contact)) { + case -1 : //Signal received + break; + case 0 : //exit under timeout + (void) rou_alert(0,"Contact with peer <%s> closed by timeout", + contact->peerip); + break; + default : //exit under quit + break; } break; case 3 : //connection terminated @@ -319,8 +307,10 @@ if (mode!=modopen) { (void) sig_modeunisig(mode); (void) soc_modedevsoc(mode); (void) tcp_modegestcp(mode); + (void) eml_modelvleml(mode); break; case false : + (void) eml_modelvleml(mode); (void) tcp_modegestcp(mode); (void) soc_modedevsoc(mode); (void) sig_modeunisig(mode); diff --git a/lib/subrou.c b/lib/subrou.c index f18e416..134a4b7 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "34" +#define RELEASE "35" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unieml.c b/lib/unieml.c index 428a442..b0df332 100644 --- a/lib/unieml.c +++ b/lib/unieml.c @@ -7,11 +7,46 @@ /********************************************************/ #include #include +#include +#include "subrou.h" #include "unieml.h" -static _Bool modopen; //module open/close status +static _Bool modopen; //module open/close status +typedef struct { + CODTYP code; //keyword code + const char *key; //keyword itself + }VOCTYP; + +//this list order by key length +static VOCTYP vocsmtp[]={ + {c_quit,"QUIT"}, + {c_unknown,(const char *)0} + }; +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to return a protocol keywork code */ +/* */ +/********************************************************/ +PUBLIC CODTYP eml_getcode(char *keyword) + +{ +CODTYP code; +VOCTYP *ptr; + +code=c_unknown; +for (ptr=vocsmtp;ptr->code!=c_unknown;ptr++) { + if (strcasecmp(ptr->key,keyword)==0) { + code=ptr->code; + break; + } + } +return code; +} /* ^L */ diff --git a/lib/unieml.h b/lib/unieml.h index 7c2b2c5..316f7fb 100644 --- a/lib/unieml.h +++ b/lib/unieml.h @@ -10,6 +10,16 @@ #define CRLF "\r\n" //EOL within SMTP protocol #define SIGNON 220 //signon information +#define CMDBAD 502 //command not implemented + +//list of keyword +typedef enum { //list of SMTP protocol keyword + c_quit, //quit exchange + c_unknown //key word unknown + }CODTYP; + +//conver keyword to CODTYP +extern CODTYP eml_getcode(char *keyword); //homework to be done before starting/stopping module. extern int eml_modeunieml(_Bool mode); diff --git a/lib/unitls.c b/lib/unitls.c index f0c74b7..f2c3261 100644 --- a/lib/unitls.c +++ b/lib/unitls.c @@ -63,7 +63,7 @@ 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'", +(void) rou_alert(0,"showtlserror sslerror='%d' code='%d'", sslerror,SSL_get_error(tls->ssl,sslerror)); if (sslerror<=0) { char *detail; @@ -454,7 +454,9 @@ while (proceed==true) { break; case 1 : //set certificate status=SSL_shutdown(tls->ssl); - (void) printf("JMPDBG ssl_shutdown status='%d'\n",status); + if (status<0) + (void) rou_alert(0,"%s, Link with [%s], ssl_shutdown status='%d'", + OPEP,tls->peerip,status); break; default : //SAFE guard tls=freetls(tls); @@ -517,13 +519,12 @@ if (tls!=(TLSTYP *)0) { 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); + (void) showtlserror(tls,0,"show SSL error",OPEP); break; } (void) sleep(1); break; default : //some character sent - (void) printf("JMPDBG sofar '%d' sent='%d'\n",sofar,sent); sent+=sofar; if (sentssl=(SSL *)0)) { -- 2.47.3