S:MAIL FROM: <postmaster@example.com>
R:250 2.1.3 postmaster@example.com.. sender ok
S:RCPT TO: <postmaster@example.com>
-R:250 2.6.2 Address accepted
+R:250 2.6.4 Address accepted
S:RCPT TO: <postmaster@example.com>
-R:250 2.6.2 duplicate recipients will be consolidated
+R:250 2.6.4 duplicate recipients will be consolidated
S:RCPT TO: <webmaster@example.com>
-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: <onlylocal>
+R:553 5.6.2 Missing domain part
+S:RCPT TO: <local:test@example.com>
+R:553 5.6.2 ':' not allowed in email
#-------------------------------------------------------------------------
#-sending data
C:DATA
/************************************************/
/* */
/* 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
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;
phase++;
}
return success;
+#undef OPEP
}
/*
\f
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;
(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);
*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
+}
#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
//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