#very simple test to feed SMTP server
#====================================================
-T:Very Simple email sending
+T:Testing if MX is found
R:220 mailleur.example.com ESMTP (cleartext) emlrcvr...
#====================================================
S:HELO example.com
S:MAIL FROM: <postmaster@example.com>
R:250 2.1.3 postmaster@example.com.. sender ok
S:RCPT TO: <dom1user1@subdom0.example.com>
-S:563 0.0.0 No valid MX found for recipient domain name (subdom0.example.com)
+R:563 5.6.3 No valid MX found for recipient domain name (rcpt=subdom0.example.com)
S:RCPT TO: <dom1user1@subdom1.example.com>
-R:250 3.5.3 Message accepted for delivery
+R:250 2.6.4 Address accepted
S:QUIT
R:221 2.0.0 Bye, closing connection...
#-------------------------------------------------------------------------
S:MAIL FROM: <postmaster@example.com>
R:250 2.1.3 postmaster@example.com.. sender ok
S:RCPT TO: <dom1user1@subdom0.example.com>
-R:563 0.0.0 No valid MX found for recipient domain name (subdom0.example.com)
+R:563 5.6.3 No valid MX found for recipient domain name (rcpt=subdom0.example.com)
S:RCPT TO: <dom1user1@subdom1.example.com>
R:250 2.6.4 Address accepted
S:QUIT
lvleml.o: \
subrou.h \
- unieml.h \
+ unieml.h unidns.h \
lvleml.h lvleml.c
gesspf.o: \
#include <unistd.h>
#include "subrou.h"
+#include "unidns.h"
#include "unieml.h"
#include "devlog.h"
#include "lvleml.h"
#define OPEP "lvleml.c:checkto,"
_Bool success;
const char *detail;
+const char *domain;
char *report;
_Bool proceed;
int phase;
success=false;
detail="Address accepted";
+domain=(const char *)0;
report=(char *)0;
proceed=true;
phase=0;
rcptto[strlen(rcptto)-1]='\000';
(void) memmove(rcptto,rcptto+1,strlen(rcptto));
break;
- case 2 : //checking repto format
- if (eml_isemailok(rcptto,&report)==false) {
+ case 2 : //checking rcptto format
+ if (eml_isemailok(rcptto,&domain,&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
+ case 3 : //Do we have a domain MX
+ if (domain!=(const char *)0) { //always
+ MXTYP **mx;
+
+ if ((mx=dns_getmx(domain))==(MXTYP **)0) {
+ (void) transmit(contact,"%d 5.6.3 %s (rcpt=%s)",
+ MISSMX,
+ "No valid MX found for recipient domain name",
+ domain);
+ phase=999; //no need to go further
+ }
+ mx=dns_freemxlist(mx);
+ }
+ break;
+ case 4 : //Storing rcpt to
if (eml_addemail(&(contact->rcptto),rcptto)==false) {
detail="duplicate recipients will be consolidated";
}
break;
- case 4 : //everything ok
+ case 5 : //everything ok
(void) transmit(contact,"%d 2.6.4 %s",CMDOK,detail);
success=true;
break;
/* from DNS record. */
/* */
/********************************************************/
-static char **extracting(RSPTYP *rsp,int rsplen,char *request,char *field)
+static char **extracting(RSPTYP *rsp,int rsplen,const char *request,char *field)
{
#define OPEP "unidns.c:extracting,"
/* MX preference (low preference first) */
/* */
/********************************************************/
-PUBLIC MXTYP **dns_getmx(char *domain)
+PUBLIC MXTYP **dns_getmx(const char *domain)
{
#define OPEP "unidns.c:dns_getmx"
switch (phase) {
case 0 : //Are the parameters available
if ((domain==(char *)0)||(strlen(domain)==0)) {
- (void) rou_alert(0,"%s missing domainame",OPEP);
+ (void) rou_alert(0,"%s missing domainname",OPEP);
phase=999; //trouble trouble
}
break;
- case 1 : //Requesting MX for domain
+ case 1 : //cleaning domain
+ if (domain!=(char *)0) { //always
+ char *ptr;
+
+ if ((ptr=strchr(domain,'@'))!=(char *)0) {
+ ptr++;
+ if (strlen(ptr)==0) {
+ (void) rou_alert(0,"%s Incorrect domainname <%s>",OPEP,domain);
+ phase=999; //trouble trouble
+ }
+ domain=ptr;
+ }
+ }
+ break;
+ case 2 : //Requesting MX for domain
+ (void) rou_alert(0,"%s JMPDBG domain=<%s>",OPEP,domain);
answer=myquery(domain,C_IN,T_MX,rsp.buf,sizeof(rsp.buf));
if (answer<=0)
phase=999; //Trouble trouble to get MX
break;
- case 2 : //extracting result
+ case 3 : //extracting result
if (answer>=sizeof(rsp.buf))
answer=sizeof(rsp.buf)-1;
list=extracting(&rsp,answer,domain,"MX");
if (list==(char **)0)
phase=999; //list empty?
break;
- case 3 : //ordering list
+ case 4 : //ordering list
answer=0;
for (int i=0;list[i]!=(char *)0;i+=2) {
if ((list[i+1]!=(char *)0)&&(strlen(list[i+1])>0)) {
//procedure to get a list of MX IP releated to a specific
//domain.
-extern MXTYP **dns_getmx(char *domain);
+extern MXTYP **dns_getmx(const char *domain);
//Procedure to check if an IP (Origin IP) is part
//of domain A record list
/* acceptable. */
/* */
/********************************************************/
-PUBLIC _Bool eml_isemailok(char *email,char **rapport)
+PUBLIC _Bool eml_isemailok(char *email,const char **domain,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;
+*domain=(const 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) {
+ if ((email==(char *)0)||strlen(email)==0) {
(void) rou_alert(0,"%s Email missing! (bug?)",OPEP);
proceed=false;
}
break;
- case 1 : //duplicating email to localpart
+ case 1 : //splitting local domain part
+ if ((*domain=strchr(email,'@'))!=(const char *)0)
+ (*domain)++;
+ if ((*domain)==(char *)0) {
+ *rapport=strdup("Missing domain part");
+ phase=999; //trouble trouble
+ }
+ break;
+ case 2 : //double checking domain part
+ if (strchr(*domain,'@')!=(char *)0) {
+ *rapport=strdup("malformed domain part");
+ *domain=(const char *)0;
+ phase=999; //trouble trouble
+ }
+ break;
+ case 3 : //duplicating email to localpart
localpart=strdup(email);
+ *(strchr(localpart,'@'))='\000'; //removing domain
if (strlen(localpart)==0) {
*rapport=strdup("email address is empty");
- phase=999; //never reached
+ phase=999; //trouble trouble
}
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
+ case 4 : //checking localpart email
if (strlen(localpart)>0) { //always
char *ptr;
char cmt[200];
}
}
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;
#define CMDBAD 502 //command not implemented
#define DATRJC 521 //Data Rejected
#define NOTEML 553 //Not an email address
+#define MISSMX 563 //NO MX found for recipient
//list of keyword
//procedure to check email address format
//of an email address
-extern _Bool eml_isemailok(char *email,char **report);
+extern _Bool eml_isemailok(char *email,const char **domain,char **report);
#endif