From 58e274f99cabd330a6df05cccc32ce2f20a156b8 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Tue, 13 Aug 2024 17:13:37 -0400 Subject: [PATCH] Using peer reverse name --- lib/Makefile | 2 +- lib/devlog.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++- lib/devlog.h | 17 +++++ lib/devsoc.c | 54 +++++++++++--- lib/devsoc.h | 2 +- lib/gestcp.c | 20 +++-- lib/gestcp.h | 3 + lib/lvleml.c | 43 +++++++---- lib/modrec.c | 3 +- lib/subrou.c | 52 ++++++++++++- lib/subrou.h | 7 ++ 11 files changed, 369 insertions(+), 36 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 183777d..1b4db65 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -89,7 +89,7 @@ lvleml.h: \ gestcp.h: \ subrou.h \ - devsoc.h + devlog.h devsoc.h uniprc.h: \ subrou.h diff --git a/lib/devlog.c b/lib/devlog.c index d3acbcf..c4bfe00 100644 --- a/lib/devlog.c +++ b/lib/devlog.c @@ -4,14 +4,214 @@ /* Log management implementation module */ /* */ /********************************************************/ +#include +#include #include #include +#include #include "subrou.h" #include "uniprc.h" #include "devlog.h" -static _Bool modopen; //boolean module open/close +#define JRLDIR "/var/spool/clement/logs/" + + +typedef struct { + char *filename; //the log filename + FILE *file; //The log file pointer + TIMESPEC start; //log start time + }LOGTYP; + +static _Bool modopen; //boolean module open/close +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to free reference to a log device */ +/* */ +/********************************************************/ +static LOGTYP *freelog(LOGTYP *log) + +{ +if (log!=(LOGTYP *)0) { + log->filename=rou_freestr(log->filename); + (void) free(log); + log=(LOGTYP *)0; + } +return log; +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to open a session log to collect all */ +/* exchange with remote SMTP client. */ +/* return a NULL file pointeur if trouble. */ +/* */ +/********************************************************/ +PUBLIC LOGPTR *log_openlog(char *logname) + +{ +#define OPEP "devlog.c:log_openlog" + +LOGTYP *log; +int phase; +int proceed; + +log=(LOGTYP *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //do we have a log name? + if (logname==(char *)0) { + (void) rou_alert(0,"%s logname is missing (Bug!?)",OPEP); + phase=999; + } + break; + case 1 : //generating log file name + log=(LOGTYP *)calloc(1,sizeof(LOGTYP)); + log->filename=rou_apppath(JRLDIR); + log->filename=(char *)realloc(log->filename, + strlen(log->filename)+strlen(logname)+10); + (void) strcat(log->filename,logname); + (void) strcat(log->filename,".jrl"); + + break; + case 2 : //opening the log file + if ((log->file=fopen(log->filename,"w"))==(FILE *)0) { + (void) rou_alert(0,"%s Unable to open file <%s> (error=<%s>)", + OPEP,log->filename,strerror(errno)); + log=freelog(log); + } + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return (LOGPTR *)log; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to close a session log */ +/* return the close status. */ +/* */ +/********************************************************/ +PUBLIC LOGPTR *log_closelog(LOGPTR *logptr) + +{ +#define OPEP "devlog.c:log_closelog" + +LOGTYP *log; +int phase; +int proceed; + +log=(LOGTYP *)logptr; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //do we have a log name? + if (log==(LOGTYP *)0) { + (void) rou_alert(0,"%s log pointer is NULL (Bug!?)",OPEP); + phase=999; + } + break; + case 1 : //do we have a log name? + if (fclose(log->file)!=0) { + (void) rou_alert(0,"%s Unable to close log file <%s> (error=<%s>)", + OPEP,log->filename,strerror(errno)); + phase=999; + } + break; + default : //SAFE guard + logptr=freelog(log); + proceed=false; + break; + } + phase++; + } +return logptr; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to insert a formated string within */ +/* log file. */ +/* */ +/********************************************************/ +PUBLIC int log_fprintlog(LOGPTR *logptr,const char *format,...) + +{ +#define OPEP "devlog.c:log_fprintlog" +int taille; +LOGTYP *log; +char chrono[20]; +char *line; +va_list args; +int phase; +int proceed; + +taille=0; +log=(LOGTYP *)logptr; +(void) strcpy(chrono,""); +line=(char *)0; +va_start(args,format); +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //do we have a log name? + if (log==(LOGTYP *)0) { + (void) rou_alert(0,"%s log pointer is NULL (Bug!?)",OPEP); + phase=999; + } + break; + case 1 : //set time marker within log + if (log->start.tv_sec==0) { + (void) clock_gettime(CLOCK_REALTIME,&(log->start)); + (void) snprintf(chrono,sizeof(chrono),"00:00:00.000"); + } + else { + unsigned int delta; + + delta=rou_getdifftime(&(log->start)); + (void) snprintf(chrono,sizeof(chrono)," +%02d.%03d", + delta/1000,delta%1000); + } + break; + case 2 : //formating the line + if ((taille=rou_vasprintf(&line,format,args))<=0) { + (void) rou_alert(0,"%s Unable to format <%s> (Bug!?)",OPEP,format); + phase=999; + } + break; + case 3 : //string the formated line within logs + (void) fprintf(log->file,"%s %s\n",chrono,line); + line=rou_freestr(line); + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +va_end(args); +return taille; +#undef OPEP +} /* ^L */ diff --git a/lib/devlog.h b/lib/devlog.h index 0592e4a..b0c4b6b 100644 --- a/lib/devlog.h +++ b/lib/devlog.h @@ -8,6 +8,23 @@ #ifndef DEVLOG #define DEVLOG +#include + +typedef void LOGPTR; + +//procedure to open a session log +extern LOGPTR *log_openlog(char *logname); + +//procedure to close a previously open session log +extern LOGPTR *log_closelog(LOGPTR *logptr); + +//procedure to write a sequence within the current log +extern int log_fprintlog(LOGPTR *logptr,const char *format,...); + +//procedure to merge session log contents to +//current daily log +extern int log_mergelog(char *logname); + //homework to be done before starting/stopping module. extern int log_modedevlog(_Bool mode); diff --git a/lib/devsoc.c b/lib/devsoc.c index eb3bda8..3ee09fa 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -919,7 +919,7 @@ return (SOCPTR *)newsoc; /* for local or remote socket. */ /* */ /********************************************************/ -PUBLIC char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool ip) +PUBLIC char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool getname) { #define OPEP "devsoc.c:soc_getaddrinfo" @@ -930,10 +930,15 @@ int mode; data=(char *)0; soc=(SOCTYP *)socptr; -mode=NI_NAMEREQD; -if (local==false) - mode=NI_NUMERICHOST; -mode|=NI_NUMERICSERV; +mode=NI_NUMERICSERV; +switch (getname) { + case true : + mode|=NI_NAMEREQD; + break; + case false : + mode|=NI_NUMERICHOST; + break; + } if (soc!=(SOCTYP *)0) { int status; struct sockaddr connip; @@ -941,6 +946,8 @@ if (soc!=(SOCTYP *)0) { char host[NI_MAXHOST]; char serv[NI_MAXSERV]; + (void) strcpy(host,"Unknown IP"); + (void) strcpy(serv,"Unknown service"); taille=(socklen_t)(sizeof(connip)); if (local==true) status=getsockname(soc->handle,&connip,&taille); @@ -957,14 +964,43 @@ if (soc!=(SOCTYP *)0) { break; } break; - default : - if (getnameinfo(&connip,taille,host,sizeof(host),serv,sizeof(serv),mode)==0) { - if (ip==true) + case 0 : //NO trouble to read socket data + status=getnameinfo(&connip,taille,host,sizeof(host),serv,sizeof(serv),mode); + (void) printf("JMPDBG getname status='%d', local='%d' getname='%d'\n", + status,local,getname); + switch (status) { + case 0 : //everything fine + (void) printf("JMPDBG host=<%s>\n",host); + break; + case EAI_AGAIN : + case EAI_NONAME : + if (getname==true) + (void) strcpy(host,"No.Reverse"); + default : + (void) rou_alert(0,"%s, Unable to get name (local=%d, error=<%s>)", + OPEP,local,strerror(errno)); + break; + } + break; + default : //Unexpected touble to read socket + (void) rou_alert(0,"%s, status=%d Unexpected (local=%d, error=<%s>) (Bug?)", + OPEP,status,local,strerror(errno)); + break; + } + switch (local) { + case true : + switch (getname) { + case true : data=strdup(host); - else + break; + case false : data=strdup(serv); + break; } break; + case false : + data=strdup(host); + break; } } return data; diff --git a/lib/devsoc.h b/lib/devsoc.h index 0dd1c53..24b7679 100644 --- a/lib/devsoc.h +++ b/lib/devsoc.h @@ -60,7 +60,7 @@ extern int soc_receive(SOCPTR *socptr); 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); +extern char *soc_getaddrinfo(SOCPTR *socptr,_Bool local,_Bool getname); //procedure to release/clsoe socket extern SOCPTR *soc_release(SOCPTR *socptr); diff --git a/lib/gestcp.c b/lib/gestcp.c index 3c1a08f..6189396 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -32,12 +32,14 @@ static _Bool modopen; //boolean module open/close static CONTYP *freecontact(CONTYP *contact) { -#define OPEP "gesttcp.c:freecontact" +#define OPEP "gestcp.c:freecontact" if (contact!=(CONTYP *)0) { + contact->log=log_closelog(contact->log); contact->cursesid=rou_freestr(contact->cursesid); contact->mainsesid=rou_freestr(contact->mainsesid); contact->fqdn=rou_freestr(contact->fqdn); + contact->peername=rou_freestr(contact->peername); contact->peerip=rou_freestr(contact->peerip); contact->locname=rou_freestr(contact->locname); contact->locserv=rou_freestr(contact->locserv); @@ -199,19 +201,25 @@ while (proceed==true) { phase=999; //no contact } break; - case 2 : //check socket components - contact->locname=soc_getaddrinfo(contact->socptr,true,true); - contact->locserv=soc_getaddrinfo(contact->socptr,true,false); - contact->peerip=soc_getaddrinfo(contact->socptr,false,true); + case 2 : //Preparing contact contact->mainsesid=eml_getmainsesid(); contact->cursesid=eml_getcursesid(contact->mainsesid,contact->numreset); + contact->locname=soc_getaddrinfo(contact->socptr,true,true); + contact->locserv=soc_getaddrinfo(contact->socptr,true,false); + contact->peername=soc_getaddrinfo(contact->socptr,false,true); + contact->peerip=soc_getaddrinfo(contact->socptr,false,false); + contact->log=log_openlog(contact->mainsesid); + break; + case 3 : //check contact validity if ((contact->locname==(char *)0)||(contact->peerip==(char *)0)) { (void) rou_alert(0,"%s Unable to establish contact entities",OPEP); contact=freecontact(contact); phase=999; //no identity } break; - case 3 : //contact is good, then sending a signon + case 4 : //contact is good, then sending a signon + (void) log_fprintlog(contact->log,"SID: %s -> Contact open", + contact->mainsesid); if (tcp_signon(contact)<=0) { contact=freecontact(contact); phase=999; //no contact diff --git a/lib/gestcp.h b/lib/gestcp.h index ad822e7..758fc81 100644 --- a/lib/gestcp.h +++ b/lib/gestcp.h @@ -10,6 +10,7 @@ #include #include "subrou.h" +#include "devlog.h" #include "devsoc.h" typedef struct { @@ -19,9 +20,11 @@ typedef struct { char *locname; //socket local hostname char *locserv; //local service port char *peerip; //socket remote peer IP + char *peername; //socket remote peer FQDN int numreset; //number of SMTP reset received char *mainsesid;//session main ID char *cursesid; //current session ID + LOGPTR *log; //reference to session log }CONTYP; //read a line from contact up to CRLF diff --git a/lib/lvleml.c b/lib/lvleml.c index 0727d4b..7e892e0 100644 --- a/lib/lvleml.c +++ b/lib/lvleml.c @@ -11,6 +11,7 @@ #include "subrou.h" #include "unieml.h" +#include "devlog.h" #include "lvleml.h" @@ -28,12 +29,14 @@ static void transmit(CONTYP *contact,char *fmt,...) { va_list args; -char line[300]; +char *line; va_start(args,fmt); -(void) vsnprintf(line,sizeof(line),fmt,args); -(void) tcp_write(contact,line,strlen(line)); -(void) tcp_write(contact,CRLF,strlen(CRLF)); +line=(char *)0; +if (rou_vasprintf(&line,fmt,args)>0) { + (void) tcp_write(contact,line,strlen(line)); + (void) tcp_write(contact,CRLF,strlen(CRLF)); + } va_end(args); } /* @@ -127,8 +130,9 @@ while (proceed==true) { case 1 : //thereis an FQDN contact->fqdn=rou_freestr(contact->fqdn); contact->fqdn=strdup(parameter); - (void) transmit(contact,"%d-%s ready, your IP=[%s]", - CMDOK,contact->locname,contact->peerip); + (void) transmit(contact,"%d-%s ready, your IP=[%s/%s]", + CMDOK,contact->locname, + contact->peerip,contact->peername); (void) transmit(contact,"%d-SIZE %ld",CMDOK,MXMSIZE); if (contact->tlsok==true) strstart++; @@ -193,17 +197,19 @@ while (proceed==true) { attend.tv_sec=60; attend.tv_nsec=0; status=tcp_getline(contact,&attend,&line); - parameter=strchr(line,' '); - if (parameter==(char *)0) - parameter=strchr(line,'\t'); - if (parameter!=(char *)0) { - *parameter='\000'; - parameter++; - while ((*parameter==' ')||(*parameter=='\t')) - parameter++; - } if (status<=0) //timeout or trouble? break; //no need to go further + if (line!=(char *)0) { + parameter=strchr(line,' '); + if (parameter==(char *)0) + parameter=strchr(line,'\t'); + if (parameter!=(char *)0) { + *parameter='\000'; + parameter++; + while ((*parameter==' ')||(*parameter=='\t')) + parameter++; + } + } switch (eml_getcode(line)) { case c_helo : //HELO SMTP protocol proceed=dohelo(contact,line,parameter); @@ -267,11 +273,16 @@ int status; status=0; if (mode!=modopen) { - (void) rou_modesubrou(mode); switch ((int)mode) { case true : + (void) rou_modesubrou(mode); + (void) eml_modeunieml(mode); + (void) log_modedevlog(mode); break; case false : + (void) log_modedevlog(mode); + (void) eml_modeunieml(mode); + (void) rou_modesubrou(mode); break; default : (void) fprintf(stderr,"Calling %s with wrong mode='%d' (Bug?!):", diff --git a/lib/modrec.c b/lib/modrec.c index 82efff1..77503ee 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -55,7 +55,8 @@ while (proceed==true) { (void) prc_settitle("Processing incoming contact from [%s] on [%s:%s]", contact->peerip,contact->locname,contact->locserv); (void) rou_checkleak(true); - printf("New client [%s] connected pid='%05d'\n",contact->peerip,getpid()); + printf("New client [%s/%s] connected pid='%05d'\n", + contact->peerip,contact->peername,getpid()); break; case 2 : //do contact switch (eml_docontact(contact)) { diff --git a/lib/subrou.c b/lib/subrou.c index 11cf3e4..d651e6a 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -21,7 +21,7 @@ //version definition #define VERSION "0.4.1" -#define RELEASE "4" +#define RELEASE "5" //Public variables PUBLIC int debug=0; //debug level @@ -107,6 +107,30 @@ if ((debug>2)&&(current!=onoff)) { /********************************************************/ /* */ /* Procedure to assign enough memory to format */ +/* a string with va_list parameter. */ +/* Known as vasprintf in GNU_SOURCE. */ +/* */ +/********************************************************/ +PUBLIC int rou_vasprintf(char **str,const char *fmt,va_list ap) + +{ +int taille; +va_list sup; +char loc[10]; + +(void) va_copy(sup,ap); +if ((taille=vsnprintf(loc,4,fmt,ap))>0) { + *str=calloc(taille+2,sizeof(char)); + taille=vsnprintf(*str,taille+1,fmt,sup); + } +return taille; +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to assign enough memory to format */ /* a string. */ /* Known as asprintf in GNU_SOURCE. */ /* */ @@ -135,6 +159,32 @@ return taille; */ /********************************************************/ /* */ +/* Procedure to return the time difference between */ +/* current real-time at nano-second level and */ +/* time reference. */ +/* time difference unit is millisec. */ +/* */ +/********************************************************/ +PUBLIC unsigned int rou_getdifftime(TIMESPEC *start) + +{ +unsigned int result; + +result=0; +if (start!=(TIMESPEC *)0) { + TIMESPEC current; + + (void) clock_gettime(CLOCK_REALTIME,¤t); + result=(current.tv_sec-start->tv_sec)*1000; + result+=(current.tv_nsec-start->tv_nsec)/1000000; + } +return result; +} +/* + +*/ +/********************************************************/ +/* */ /* Procedure to return the current time */ /* expressed with a millisecond precision starting */ /* from the firt time it was called. */ diff --git a/lib/subrou.h b/lib/subrou.h index acd5598..912f0d4 100644 --- a/lib/subrou.h +++ b/lib/subrou.h @@ -31,9 +31,16 @@ extern char *appname; //application "official" name //open/close memory leak detector. extern void rou_checkleak(_Bool onoff); +//procedure to assign memory according a format and va list +extern int rou_vasprintf(char **str,const char *fmt,va_list ap); + //procedure to assign memory according a format and parameter list extern int rou_asprintf(char **str,const char *fmt,...); +//procedure to get the time difference between the current +//time and a TIMESPEC starttime +extern unsigned rou_getdifftime(TIMESPEC *start); + //procedure to return the current number of milli-second extern unsigned int rou_getmillisec(); -- 2.47.3