From 768603a09508515af729b24214269d9d343730fa Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Fri, 9 May 2025 15:29:17 -0400 Subject: [PATCH] routein eml_ismailok seems to be working --- data-feed/xxfeed.tst | 12 ++++-- lib/lvleml.c | 30 +++++++++++--- lib/unieml.c | 93 ++++++++++++++++++++++++++++++++++++++++++++ lib/unieml.h | 5 +++ 4 files changed, 131 insertions(+), 9 deletions(-) diff --git a/data-feed/xxfeed.tst b/data-feed/xxfeed.tst index 64070e5..5ab46fe 100644 --- a/data-feed/xxfeed.tst +++ b/data-feed/xxfeed.tst @@ -12,11 +12,17 @@ R:250-mailleur.example.com, link (cleartext) ready,... S:MAIL FROM: R:250 2.1.3 postmaster@example.com.. sender ok S:RCPT TO: -R:250 2.6.2 Address accepted +R:250 2.6.4 Address accepted S:RCPT TO: -R:250 2.6.2 duplicate recipients will be consolidated +R:250 2.6.4 duplicate recipients will be consolidated S:RCPT TO: -R:250 2.6.2 Address accepted +R:250 2.6.4 Address accepted +S:RCPT TO: +R:501 5.6.0 <> recipient not specified +S:RCPT TO: +R:553 5.6.2 Missing domain part +S:RCPT TO: +R:553 5.6.2 ':' not allowed in email #------------------------------------------------------------------------- #-sending data C:DATA diff --git a/lib/lvleml.c b/lib/lvleml.c index f652329..7fab83e 100644 --- a/lib/lvleml.c +++ b/lib/lvleml.c @@ -452,25 +452,29 @@ return success; /************************************************/ /* */ /* Procedure to manage a "RCPT TO:" */ -/* ommand from the SMTP client. */ +/* command from the SMTP client. */ /* */ /************************************************/ static _Bool checkto(CONTYP *contact,char *rcptto) { +#define OPEP "lvleml.c:checkto," _Bool success; const char *detail; +char *report; _Bool proceed; int phase; success=false; detail="Address accepted"; +report=(char *)0; proceed=true; phase=0; while (proceed==true) { + //(void) rou_alert(0,"JMPDBG %s phase='%d' rcptto=<%s>",OPEP,phase,rcptto); switch (phase) { case 0 : //do we have an originator - if ((rcptto==(char *)0)||(strlen(rcptto)<3)) { + if ((rcptto==(char *)0)||(strlen(rcptto)==0)) { (void) transmit(contact,"%d 5.6.0 <%s> recipient not specified", BADPAR,rcptto); phase=999; //no need to go further @@ -485,13 +489,21 @@ while (proceed==true) { rcptto[strlen(rcptto)-1]='\000'; (void) memmove(rcptto,rcptto+1,strlen(rcptto)); break; - case 2 : //Storing rcpt to + case 2 : //checking repto format + if (eml_isemailok(rcptto,&report)==false) { + (void) transmit(contact,"%d 5.6.2 %s",NOTEML,report); + report=rou_freestr(report); + phase=999; //no need to go further + } + break; + case 3 : //Storing rcpt to if (eml_addemail(&(contact->rcptto),rcptto)==false) { detail="duplicate recipients will be consolidated"; } break; - case 3 : //everything ok - (void) transmit(contact,"%d 2.6.2 %s",CMDOK,detail); + case 4 : //everything ok + (void) transmit(contact,"%d 2.6.4 %s",CMDOK,detail); + success=true; break; default : //SAFE guard proceed=false; @@ -500,6 +512,7 @@ while (proceed==true) { phase++; } return success; +#undef OPEP } /* @@ -541,11 +554,13 @@ PUBLIC int eml_docontact(CONTYP *contact) int status; int got; int delay; +int penalty; _Bool proceed; status=1; got=0; delay=300; //5 minutes standard delay +penalty=1; if (debug>1) delay/=10; //30 sec in debug mode proceed=true; @@ -605,7 +620,10 @@ while (proceed==true) { (void) checkfrom(contact,line); break; case c_rcpt : //Doing rpt scanning - (void) checkto(contact,line); + if (checkto(contact,line)==false) { + (void) sleep(penalty); //relaxing bad guys + penalty*=2; + } break; case c_rset : //Doing session reset proceed=doreset(contact,line); diff --git a/lib/unieml.c b/lib/unieml.c index 5e0551c..babf6df 100644 --- a/lib/unieml.c +++ b/lib/unieml.c @@ -301,4 +301,97 @@ if (status==true) *emails=(char **)rou_addlist((void **)*emails,strdup(email)); return status; } +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to check if email address is */ +/* acceptable. */ +/* */ +/********************************************************/ +PUBLIC _Bool eml_isemailok(char *email,char **rapport) + +{ +#define OPEP "unieml.c:eml_isemailok" + +int status; +char *localpart; +char *domain; +int phase; +_Bool proceed; + +status=false; +localpart=(char *)0; +domain=(char *)0; +phase=0; +proceed=true; +while (proceed==true) { + //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase); + switch (phase) { + case 0 : //do we have an email + if (email==(char *)0) { + (void) rou_alert(0,"%s Email missing! (bug?)",OPEP); + proceed=false; + } + break; + case 1 : //duplicating email to localpart + localpart=strdup(email); + if (strlen(localpart)==0) { + *rapport=strdup("email address is empty"); + phase=999; //never reached + } + break; + case 2 : //splitting local domain part + if ((domain=strchr(localpart,'@'))!=(char *)0) + domain++; + if (domain==(char *)0) { + *rapport=strdup("Missing domain part"); + phase=999; //never reached + } + break; + case 3 : //checking localpart email + if (strlen(localpart)>0) { //always + char *ptr; + char cmt[200]; + ptr=localpart; + while (*ptr!='\000') { + switch (*ptr) { + case ' ' : + case '<' : + case '>' : + case '(' : + case '[' : + case ']' : + case ';' : + case ':' : + (void) snprintf(cmt,sizeof(cmt),"'%c' not allowed in email",*ptr); + *rapport=strdup(cmt); + *(ptr+1)='\000'; //exiting; + phase=999; //No need to go further + break; + } + ptr++; + } + } + break; + case 4 : //checking domain part + if (strlen(domain)==0) { + *rapport=strdup("No domain part"); + phase=999; //No need to go further + } + break; + case 5 : //everythin fine + status=true; + break; + default : //SAFE guard + localpart=rou_freestr(localpart); + proceed=false; + break; + } + phase++; + } +return status; +#undef OPEP +} diff --git a/lib/unieml.h b/lib/unieml.h index a3a7953..01343d0 100644 --- a/lib/unieml.h +++ b/lib/unieml.h @@ -19,6 +19,7 @@ #define BADPAR 501 //error in parameters #define CMDBAD 502 //command not implemented #define DATRJC 521 //Data Rejected +#define NOTEML 553 //Not an email address //list of keyword @@ -60,4 +61,8 @@ extern int eml_closeqfile(FILE *qfile); //of email address extern _Bool eml_addemail(char ***emails,char *email); +//procedure to check email address format +//of an email address +extern _Bool eml_isemailok(char *email,char **report); + #endif -- 2.47.3