From 7af481eef1b20799663dd353047a549c46816377 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Fri, 16 Aug 2024 13:35:06 -0400 Subject: [PATCH] module gesspf.c is compiling --- lib/Makefile | 10 +- lib/gesspf.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/gesspf.h | 33 ++++ lib/subrou.c | 2 +- lib/unidns.c | 527 ++----------------------------------------------- lib/unidns.h | 20 +- 6 files changed, 601 insertions(+), 533 deletions(-) create mode 100644 lib/gesspf.c create mode 100644 lib/gesspf.h diff --git a/lib/Makefile b/lib/Makefile index 9ad5484..7587cc9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -18,7 +18,7 @@ clean : OBJS= \ modrec.o \ lvleml.o \ - gestcp.o \ + gesspf.o gestcp.o \ devlog.o devsoc.o \ unidns.o unieml.o \ unipar.o uniprc.o unisig.o unitls.o \ @@ -42,6 +42,10 @@ lvleml.o: \ unieml.h \ lvleml.h lvleml.c +gesspf.o: \ + subrou.h \ + gesspf.h gesspf.h + gestcp.o: \ subrou.h \ unieml.h \ @@ -62,7 +66,7 @@ devsoc.o: \ devsoc.h devsoc.c unidns.o: \ - subafn.h subrou.h \ + subrou.h \ unidns.h unidns.c unieml.o: \ @@ -98,7 +102,7 @@ gestcp.h: \ subrou.h \ devlog.h devsoc.h -unidns.h: \ +gesspf.h: \ subafn.h uniprc.h: \ diff --git a/lib/gesspf.c b/lib/gesspf.c new file mode 100644 index 0000000..6b32609 --- /dev/null +++ b/lib/gesspf.c @@ -0,0 +1,542 @@ +// vim: smarttab tabstop=8 shiftwidth=2 expandtab +/********************************************************/ +/* */ +/* Implement all routine to manage SMTP low level */ +/* exchange. */ +/* */ +/********************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "subrou.h" +#include "unidns.h" +#include "gesspf.h" + +#define MXDNS 10 //maximun number of DNS acess + +typedef enum { //mechanism definition + mch_all, //"all" + mch_a, //'a' + mch_exists, //"existe" + mch_include, //"include" + mch_ip4, //"ip4" + mch_ip6, //"ip6" + mch_mx, //"mx" + mch_ptr, //"mx" + mch_redirect, //"redirect" + mch_unknown //unknown mechanism + }MCHTYP; + +static _Bool modopen; //module open/close status +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to display SPF debug information */ +/* */ +/********************************************************/ +static void dbgspf(int dbg,char *proc,char *domain,AFNTYP *afnnum,char *seq,SPFENU status) + +{ +if (debug>-dbg) { + (void) rou_alert(dbg,"Origin=\"%s\"\n" + "\tCurrent SPF Value <%s>\n" + "\tPeer IP=[%s]\n" + "\tdomain=<%s> SPF=<%s>", + proc,spf_spfASCII(status),afnnum->strnumip,domain,seq); + } +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to parse mechanisme string */ +/* */ +/********************************************************/ +static MCHTYP tellmechanism(char *seq) + +{ +//MUST be set in the MCHTYP order +static char *voc[]= + { + "all", //allways match + "a", //addresss + "exists", //allways match + "include", //include sub domain + "ip4", //IPV4 address format + "ip6", //IPV5 address format + "mx", //MX definition + "ptr", //PTR definition + "redirect", //PTR definition + (char *)0 + }; + +MCHTYP mch; + +mch=mch_unknown; +for (int i=0;voc[i]!=(char *)0;i++) { + register int taille; + + taille=strlen(voc[i]); + if (strncmp(voc[i],seq,taille)!=0) + continue; + (void) memmove(seq,seq+taille,strlen(seq+taille)+1); + mch=(MCHTYP)i; + break; + } +return mch; +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to get the next SPF component */ +/* return a dynamic char pointer with the isolated */ +/* SPF sequence. */ +/* */ +/********************************************************/ +static char *getspfseq(char *fullspf) + +{ +char *seq; +int phase; +_Bool proceed; + +seq=(char *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Converting the IP number + if (fullspf==(char *)0) + phase=999; //no need to go further + break; + case 1 : //skipping blank + while ((*fullspf==' ')||(*fullspf=='\t')) + fullspf++; //scanning blank + if (strlen(fullspf)==0) + phase=999; //no need to go further + break; + case 2 : //detecting specific char + seq=strdup(fullspf); + if (strchr("?~-+",fullspf[0])!=(char *)0) { + seq[1]='\000'; //on char only + phase=999; //no need to go further + } + break; + case 3 : //cleaning sequence + if (seq!=(char *)0) { //always + char *ptr; + + if ((ptr=strchr(seq,' '))!=(char *)0) + *ptr='\000'; + if ((ptr=strchr(seq,'\t'))!=(char *)0) + *ptr='\000'; + } + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +return seq; +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to check the SPF MX values againt the */ +/* current afnnum. */ +/* return true if successful. */ +/* */ +/********************************************************/ +static _Bool checkmx(char *domain,AFNTYP *afnnum,char *seq) + +{ +_Bool found; + +found=false; +return found; +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to check ip peerip is within an */ +/* spf sequence */ +/* */ +/********************************************************/ +static _Bool checkip(char *domain,AFNTYP *afnnum,char *seq) + +{ +#define OPEP "gesspf.c:checkip" +_Bool found; +int cidr; +AFNTYP *target; +int phase; +_Bool proceed; + +found=false; +cidr=128; +target=(AFNTYP *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Converting the IP number + if (seq==(char *)0) { + (void) rou_alert(2,"%s Sequence missing from domain <%s> " + "(Wrong SPF sequence wrong)",OPEP,domain); + phase=999; + } + break; + case 1 : //calculating the local cidr + if (seq!=(char *)0) { //always + char *ptr; + + if ((ptr=strchr(seq,'/'))!=(char *)0) { + *ptr='\000'; + cidr=atoi(ptr+1); + } + } + break; + case 2 : //computing the target ipnumber + if ((target=afn_getipnum(seq))==(AFNTYP *)0) { + (void) rou_alert(0,"%s Unable to convert <%s> from " + "domain <%s> (SPF bug?)", + OPEP,seq,domain); + phase=999; //no need to go further + } + break; + case 3 : //calculating the local cidr + switch (afn_cmpipnum(afnnum,target,cidr)) { + case -1 : + (void) rou_alert(0,"%s Unable to compare IP [%s] from SPF " + "domain <%s> (errno=<%s>) (SPF?)", + OPEP,seq,domain); + break; + case 1 : + found=true; + break; + case 0 : + found=false; + break; + } + target=afn_freeipnum(target); + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return found; + +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to return an spf status according */ +/* sequence contents */ +/* */ +/********************************************************/ +static SPFENU checkseq(int *try,char *domain,char *seq,AFNTYP *afnnum,SPFENU spf) + +{ +#define OPEP "gesspf.c:checkseq" +SPFENU locspf; +int phase; +_Bool proceed; + +spf=spf_neutral; +locspf=spf_pass; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //is the sequence an SPF Mechanisms + if (strlen(seq)==1) { + switch (seq[0]) { + case '?' : + locspf=spf_neutral; + break; + case '~' : + locspf=spf_softfail; + break; + case '+' : + locspf=spf_pass; + break; + case '-' : + locspf=spf_fail; + break; + default : + (void) rou_alert(0,"%s <%s> is not an expected SPF Prefix (Bug?)", + OPEP,seq); + break; + } + phase=999; //no need to go further + } + break; + case 1 : //check directive + switch (tellmechanism(seq)) { + case mch_all : //usually last in sequence + spf=locspf; + break; + case mch_mx : //This is a MX refrence + if (checkmx(domain,afnnum,seq+1)==true) + spf=locspf; + break; + case mch_ip4 : //This is IPV4 number + case mch_ip6 : //This is IPV6 number + if (checkip(domain,afnnum,seq+1)==true) + spf=locspf; + (void) dbgspf(2,"checkip",domain,afnnum,seq+1,spf); + break; + case mch_include : //include sub domain + if (seq[0]==':') { + (*try)++; + spf=spf_getstatus(try,seq+1,afnnum); + } + else { + (void) rou_alert(0,"%s wrong SPF include seq <%s> (SPF format?)", + OPEP,seq); + spf=spf_permerr; + } + break; + default : //trouble + break; + case mch_unknown : //trouble + (void) rou_alert(0,"%s unknown mechanism <%s> (bug?, config?)", + OPEP,seq); + spf=spf_permerr; + break; + } + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return spf; + +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to return check if an IP is part of */ +/* spf allowed IP */ +/* */ +/********************************************************/ +static SPFENU is_peerip_ok(int *try,char *domain,AFNTYP *afnnum,char *spfrec) + +{ +#define OPEP "gesspf.c:is_peerip_ok" +SPFENU spf; +int phase; +_Bool proceed; + +spf=spf_neutral; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Converting the IP number + if (spfrec==(char *)0) { + (void) rou_alert(0,"%s SPF record is NULL (bug?)",OPEP); + phase=999; + } + break; + case 1 : //making sure spfrec is an SPF1 + if (strlen(spfrec)>0) { + char *seq; + char *ref; + + ref=spfrec; + while ((seq=getspfseq(spfrec))!=(char *)0) { + spfrec=strstr(spfrec,seq); + spfrec+=strlen(seq); + spf=checkseq(try,domain,seq,afnnum,spf); + seq=rou_freestr(seq); + if (spf!=spf_neutral) + break; //Found a pass status, breaking loop + } + (void) dbgspf(2,"is_peerip_ok",domain,afnnum,ref,spf); + } + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +return spf; + +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to return the SPF status string value */ +/* */ +/********************************************************/ +PUBLIC const char *dns_spfASCII(SPFENU spf) + +{ +#define OPEP "gesspf.c:dns_spfASCII" +static char *spfascii[]= + { + "spf_pass", + "spf_fail", + "spf_softfail", + "spf_neutral", + "spf_timeout", + "spf_missing", + "spf_permerr", + "spf_unknown" + }; + +const char *ascii; + +ascii="Unset (Bug?)"; +switch (spf) { + case spf_pass : + case spf_fail : + case spf_softfail : + case spf_neutral : + case spf_timeout : + case spf_missing : + case spf_permerr : + case spf_unknown : + ascii=spfascii[spf]; + break; + default : + (void) rou_alert(0,"%s, Unexpected '%d' SPF status (Bug!)",OPEP,spf); + break; + } +return ascii; + +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to get the SPF status according a */ +/* domain name and and an IP. */ +/* */ +/********************************************************/ +PUBLIC SPFENU spf_getstatus(int *try,char *domain,AFNTYP *afnnum) + +{ +#define OPEP "gesspf.c:dns_get_spf_status" + +SPFENU spf; +char *list; +int phase; +_Bool proceed; + +(*try)++; +spf=spf_permerr; +list=(char *)0; +phase=0; +proceed=true; +(void) printf("JMPDBG try='%02d' domain=<%s> peerip=<%s>\n", + *try,domain,afnnum->strnumip); +while (proceed==true) { + switch (phase) { + case 0 : //Are the parameters available + if ((domain==(char *)0)||(afnnum==(AFNTYP *)0)) { + (void) rou_alert(0,"%s missing one or both needed argument",OPEP); + phase=999; //trouble trouble + } + break; + case 1 : //check the number of DNS access + if ((*try)>MXDNS) { + (void) rou_alert(0,"%s SPF record scan is too deep (aborting)",OPEP); + phase=999; //trouble trouble + } + break; + case 2 : //get the spf LIST related to SPF + if ((list=dns_getspf(domain))==(char *)0) + phase=999; //trouble trouble + break; + case 3 : //check if we have only ONE SPF entry + if (rou_nbrlist((void **)list)>1) { + (void) rou_alert(0,"%s more than 1 SPF record for domain <%s>", + OPEP,domain); + phase=999; //trouble trouble + } + break; + case 4 : //gett the spf LIST related to SPF + spf=is_peerip_ok(try,domain,afnnum,list); + list=rou_freestr(list); + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return spf; + +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to "open/close" module and do */ +/* homework purpose */ +/* return zero if everything right */ +/* */ +/********************************************************/ +int spf_modegesspf(_Bool mode) + +{ +#define OPEP "unidoc.c:soc_modeunisoc" + +int status; + +status=0; +if (mode!=modopen) { + (void) rou_modesubrou(mode); + (void) afn_modesubafn(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/gesspf.h b/lib/gesspf.h new file mode 100644 index 0000000..f8093e0 --- /dev/null +++ b/lib/gesspf.h @@ -0,0 +1,33 @@ +// vim: smarttab tabstop=8 shiftwidth=2 expandtab +/********************************************************/ +/* */ +/* Define all procedure to manage SPF entry within */ +/* DNS record. */ +/* */ +/********************************************************/ +#ifndef GESTSPF +#define GESTSPF + +#include "subafn.h" + +typedef enum { + spf_pass, //OK if condition apply + spf_fail, //NOK if condition apply + spf_softfail, //Msg origin is dubious + spf_neutral, //same status as no SPF + spf_timeout, //no answer within time + spf_missing, //SPF not found + spf_permerr, //SPF permanent error + spf_unknown //Unknown SPF directive + }SPFENU; + +//procedure to return spf status as an ASCII string +extern const char *spf_spfASCII(SPFENU spf); + +//get the SPF status for a specific domain and a remote peer IP +extern SPFENU spf_getstatus(int *try,char *domain,AFNTYP *afnnum); + +//homework to be done before starting/stopping module. +extern int spf_modegesspf(_Bool mode); + +#endif diff --git a/lib/subrou.c b/lib/subrou.c index 2682e3a..0a44f0f 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -21,7 +21,7 @@ //version definition #define VERSION "0.4.2" -#define RELEASE "15" +#define RELEASE "16" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unidns.c b/lib/unidns.c index 3e99255..b5987fe 100644 --- a/lib/unidns.c +++ b/lib/unidns.c @@ -17,8 +17,6 @@ #include "subrou.h" #include "unidns.h" -#define MXDNS 10 //maximun number of DNS acess - //spf1 marker within DNS record #define SPF1 "v=spf1 " @@ -28,44 +26,12 @@ typedef union { u_char buf[B64K]; //according US Cert VU#738331 }RSPTYP; -typedef enum { //mechanism definition - mch_all, //"all" - mch_a, //'a' - mch_exists, //"existe" - mch_include, //"include" - mch_ip4, //"ip4" - mch_ip6, //"ip6" - mch_mx, //"mx" - mch_ptr, //"mx" - mch_redirect, //"redirect" - mch_unknown //unknown mechanism - }MCHTYP; - static _Bool modopen; //module open/close status /* */ /********************************************************/ /* */ -/* Procedure to display SPF debug information */ -/* */ -/********************************************************/ -static void dbgspf(int dbg,char *proc,char *domain,AFNTYP *afnnum,char *seq,SPFENU status) - -{ -if (debug>-dbg) { - (void) rou_alert(dbg,"Origin=\"%s\"\n" - "\tCurrent SPF Value <%s>\n" - "\tPeer IP=[%s]\n" - "\tdomain=<%s> SPF=<%s>", - proc,dns_spfASCII(status),afnnum->strnumip,domain,seq); - } -} -/* - -*/ -/********************************************************/ -/* */ /* Procedure to compare 2 MX and return */ /* a value according preference value */ /* */ @@ -85,290 +51,6 @@ return m1->preference-m2->preference; */ /********************************************************/ /* */ -/* Procedure to parse mechanisme string */ -/* */ -/********************************************************/ -static MCHTYP tellmechanism(char *seq) - -{ -//MUST be set in the MCHTYP order -static char *voc[]= - { - "all", //allways match - "a", //addresss - "exists", //allways match - "include", //include sub domain - "ip4", //IPV4 address format - "ip6", //IPV5 address format - "mx", //MX definition - "ptr", //PTR definition - "redirect", //PTR definition - (char *)0 - }; - -MCHTYP mch; - -mch=mch_unknown; -for (int i=0;voc[i]!=(char *)0;i++) { - register int taille; - - taille=strlen(voc[i]); - if (strncmp(voc[i],seq,taille)!=0) - continue; - (void) memmove(seq,seq+taille,strlen(seq+taille)+1); - mch=(MCHTYP)i; - break; - } -return mch; -} -/* - -*/ -/********************************************************/ -/* */ -/* Procedure to get the next SPF component */ -/* return a dynamic char pointer with the isolated */ -/* SPF sequence. */ -/* */ -/********************************************************/ -static char *getspfseq(char *fullspf) - -{ -char *seq; -int phase; -_Bool proceed; - -seq=(char *)0; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //Converting the IP number - if (fullspf==(char *)0) - phase=999; //no need to go further - break; - case 1 : //skipping blank - while ((*fullspf==' ')||(*fullspf=='\t')) - fullspf++; //scanning blank - if (strlen(fullspf)==0) - phase=999; //no need to go further - break; - case 2 : //detecting specific char - seq=strdup(fullspf); - if (strchr("?~-+",fullspf[0])!=(char *)0) { - seq[1]='\000'; //on char only - phase=999; //no need to go further - } - break; - case 3 : //cleaning sequence - if (seq!=(char *)0) { //always - char *ptr; - - if ((ptr=strchr(seq,' '))!=(char *)0) - *ptr='\000'; - if ((ptr=strchr(seq,'\t'))!=(char *)0) - *ptr='\000'; - } - break; - default : //SAFE Guard - proceed=false; - break; - } - phase++; - } -return seq; -} -/* - -*/ -/********************************************************/ -/* */ -/* Procedure to check the SPF MX values againt the */ -/* current afnnum. */ -/* return true if successful. */ -/* */ -/********************************************************/ -static _Bool checkmx(char *domain,AFNTYP *afnnum,char *seq) - -{ -_Bool found; - -found=false; -return found; -} -/* - -*/ -/********************************************************/ -/* */ -/* Procedure to check ip peerip is within an */ -/* spf sequence */ -/* */ -/********************************************************/ -static _Bool checkip(char *domain,AFNTYP *afnnum,char *seq) - -{ -#define OPEP "unidns.c:checkip" -_Bool found; -int cidr; -AFNTYP *target; -int phase; -_Bool proceed; - -found=false; -cidr=128; -target=(AFNTYP *)0; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //Converting the IP number - if (seq==(char *)0) { - (void) rou_alert(2,"%s Sequence missing from domain <%s> " - "(Wrong SPF sequence wrong)",OPEP,domain); - phase=999; - } - break; - case 1 : //calculating the local cidr - if (seq!=(char *)0) { //always - char *ptr; - - if ((ptr=strchr(seq,'/'))!=(char *)0) { - *ptr='\000'; - cidr=atoi(ptr+1); - } - } - break; - case 2 : //computing the target ipnumber - if ((target=afn_getipnum(seq))==(AFNTYP *)0) { - (void) rou_alert(0,"%s Unable to convert <%s> from " - "domain <%s> (SPF bug?)", - OPEP,seq,domain); - phase=999; //no need to go further - } - break; - case 3 : //calculating the local cidr - switch (afn_cmpipnum(afnnum,target,cidr)) { - case -1 : - (void) rou_alert(0,"%s Unable to compare IP [%s] from SPF " - "domain <%s> (errno=<%s>) (SPF?)", - OPEP,seq,domain); - break; - case 1 : - found=true; - break; - case 0 : - found=false; - break; - } - target=afn_freeipnum(target); - break; - default : //SAFE guard - proceed=false; - break; - } - phase++; - } -return found; - -#undef OPEP -} -/* - -*/ -/********************************************************/ -/* */ -/* Procedure to return an spf status according */ -/* sequence contents */ -/* */ -/********************************************************/ -static SPFENU checkseq(int *try,char *domain,char *seq,AFNTYP *afnnum,SPFENU spf) - -{ -#define OPEP "unidns.c:checkseq" -SPFENU locspf; -int phase; -_Bool proceed; - -spf=spf_neutral; -locspf=spf_pass; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //is the sequence an SPF Mechanisms - if (strlen(seq)==1) { - switch (seq[0]) { - case '?' : - locspf=spf_neutral; - break; - case '~' : - locspf=spf_softfail; - break; - case '+' : - locspf=spf_pass; - break; - case '-' : - locspf=spf_fail; - break; - default : - (void) rou_alert(0,"%s <%s> is not an expected SPF Prefix (Bug?)", - OPEP,seq); - break; - } - phase=999; //no need to go further - } - break; - case 1 : //check directive - switch (tellmechanism(seq)) { - case mch_all : //usually last in sequence - spf=locspf; - break; - case mch_mx : //This is a MX refrence - if (checkmx(domain,afnnum,seq+1)==true) - spf=locspf; - break; - case mch_ip4 : //This is IPV4 number - case mch_ip6 : //This is IPV6 number - if (checkip(domain,afnnum,seq+1)==true) - spf=locspf; - (void) dbgspf(2,"checkip",domain,afnnum,seq+1,spf); - break; - case mch_include : //include sub domain - if (seq[0]==':') { - (*try)++; - spf=dns_get_spf_status(try,seq+1,afnnum); - } - else { - (void) rou_alert(0,"%s wrong SPF include seq <%s> (SPF format?)", - OPEP,seq); - spf=spf_permerr; - } - break; - default : //trouble - break; - case mch_unknown : //trouble - (void) rou_alert(0,"%s unknown mechanism <%s> (bug?, config?)", - OPEP,seq); - spf=spf_permerr; - break; - } - break; - default : //SAFE guard - proceed=false; - break; - } - phase++; - } -return spf; - -#undef OPEP -} -/* - -*/ -/********************************************************/ -/* */ /* Procedure to query DNS information */ /* */ /********************************************************/ @@ -576,140 +258,29 @@ return inftxt; /* is returned. */ /* */ /********************************************************/ -static char **getspf(char *domain) +PUBLIC char *dns_getspf(char *domain) { -char **infspf; - -if ((infspf=gettxt(domain,T_SPF,"SPF"))==(char **)0) { - char **inftxt; - - inftxt=gettxt(domain,T_TXT,"TXT"); - if (inftxt!=(char **)0) { - char **ptr; - - ptr=inftxt; - while (*ptr!=(char *)0) { - if (strstr(*ptr,SPF1)==*ptr) { - char *dup; - - dup=strdup(*ptr); - infspf=(char **)rou_addlist((void **)infspf,(void *)dup); - } - ptr++; - } - inftxt=(char **)rou_freelist((void **)inftxt,(freehandler_t)rou_freestr); - } - } -return infspf; -} -/* -^L -*/ -/********************************************************/ -/* */ -/* Procedure to return check if an IP is part of */ -/* spf allowed IP */ -/* */ -/********************************************************/ -static SPFENU is_peerip_ok(int *try,char *domain,AFNTYP *afnnum,char *spfrec) - -{ -#define OPEP "unidns.c:is_peerip_ok" -SPFENU spf; -int phase; -_Bool proceed; +char *spfrec; +char **list; -spf=spf_neutral; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //Converting the IP number - if (spfrec==(char *)0) { - (void) rou_alert(0,"%s SPF record is NULL (bug?)",OPEP); - phase=999; - } - break; - case 1 : //making sure spfrec is an SPF1 - if (strstr(spfrec,SPF1)!=spfrec) { - (void) rou_alert(0,"%s DNS SPF <%s> not a valide one ",OPEP,spfrec); - phase=999; - } - break; - case 2 : //making sure spfrec is an SPF1 - spfrec+=strlen(SPF1); - if (strlen(spfrec)>0) { - char *seq; - char *ref; +spfrec=(char *)0; +if ((list=gettxt(domain,T_SPF,"SPF"))==(char **)0) + list=gettxt(domain,T_TXT,"TXT"); +if (list!=(char **)0) { + char **ptr; - ref=spfrec; - while ((seq=getspfseq(spfrec))!=(char *)0) { - spfrec=strstr(spfrec,seq); - spfrec+=strlen(seq); - spf=checkseq(try,domain,seq,afnnum,spf); - seq=rou_freestr(seq); - if (spf!=spf_neutral) - break; //Found a pass status, breaking loop - } - (void) dbgspf(2,"is_peerip_ok",domain,afnnum,ref,spf); - } - break; - default : //SAFE Guard - proceed=false; + ptr=list; + while (*ptr!=(char *)0) { + if (strstr(*ptr,SPF1)==*ptr) { + spfrec=strdup(*ptr+strlen(SPF1)); break; + } + ptr++; } - phase++; + list=(char **)rou_freelist((void **)list,(freehandler_t)rou_freestr); } -return spf; - -#undef OPEP -} -/* -^L -*/ -/********************************************************/ -/* */ -/* Procedure to return the SPF status string value */ -/* */ -/********************************************************/ -PUBLIC const char *dns_spfASCII(SPFENU spf) - -{ -#define OPEP "unidns.c:dns_spfASCII" -static char *spfascii[]= - { - "spf_pass", - "spf_fail", - "spf_softfail", - "spf_neutral", - "spf_timeout", - "spf_missing", - "spf_permerr", - "spf_unknown" - }; - -const char *ascii; - -ascii="Unset (Bug?)"; -switch (spf) { - case spf_pass : - case spf_fail : - case spf_softfail : - case spf_neutral : - case spf_timeout : - case spf_missing : - case spf_permerr : - case spf_unknown : - ascii=spfascii[spf]; - break; - default : - (void) rou_alert(0,"%s, Unexpected '%d' SPF status (Bug!)",OPEP,spf); - break; - } -return ascii; - -#undef OPEP +return spfrec; } /* ^L @@ -787,71 +358,6 @@ while (proceed==true) { } return mxlist; -#undef OPEP -} -/* -^L -*/ -/********************************************************/ -/* */ -/* Procedure to get the SPF status according a */ -/* domain name and and an IP. */ -/* */ -/********************************************************/ -PUBLIC SPFENU dns_get_spf_status(int *try,char *domain,AFNTYP *afnnum) - -{ -#define OPEP "unidns.c:dns_get_spf_status" - -SPFENU spf; -char **list; -int phase; -_Bool proceed; - -(*try)++; -spf=spf_permerr; -list=(char **)0; -phase=0; -proceed=true; -(void) printf("JMPDBG try='%02d' domain=<%s> peerip=<%s>\n", - *try,domain,afnnum->strnumip); -while (proceed==true) { - switch (phase) { - case 0 : //Are the parameters available - if ((domain==(char *)0)||(afnnum==(AFNTYP *)0)) { - (void) rou_alert(0,"%s missing one or both needed argument",OPEP); - phase=999; //trouble trouble - } - break; - case 1 : //check the number of DNS access - if ((*try)>MXDNS) { - (void) rou_alert(0,"%s SPF record scan is too deep (aborting)",OPEP); - phase=999; //trouble trouble - } - break; - case 2 : //get the spf LIST related to SPF - if ((list=getspf(domain))==(char **)0) - phase=999; //trouble trouble - break; - case 3 : //check if we have only ONE SPF entry - if (rou_nbrlist((void **)list)>1) { - (void) rou_alert(0,"%s more than 1 SPF record for domain <%s>", - OPEP,domain); - phase=999; //trouble trouble - } - break; - case 4 : //gett the spf LIST related to SPF - spf=is_peerip_ok(try,domain,afnnum,list[0]); - list=(char **)rou_freelist((void **)list,(freehandler_t)rou_freestr); - break; - default : //SAFE guard - proceed=false; - break; - } - phase++; - } -return spf; - #undef OPEP } /* @@ -874,7 +380,6 @@ int status; status=0; if (mode!=modopen) { (void) rou_modesubrou(mode); - (void) afn_modesubafn(mode); switch ((int)mode) { case true : break; diff --git a/lib/unidns.h b/lib/unidns.h index c83fcdc..83f63d8 100644 --- a/lib/unidns.h +++ b/lib/unidns.h @@ -8,35 +8,19 @@ #ifndef UNIDNS #define UNIDNS -#include "subafn.h" - -typedef enum { - spf_pass, //OK if condition apply - spf_fail, //NOK if condition apply - spf_softfail, //Msg origin is dubious - spf_neutral, //same status as no SPF - spf_timeout, //no answer within time - spf_missing, //SPF not found - spf_permerr, //SPF permanent error - spf_unknown //Unknown SPF directive - }SPFENU; - //defining an MX structure typedef struct { int preference; /*MX preference */ char *mxname; /*MX hostname */ }MXTYP; -//procedure to return spf status as an ASCII string -extern const char *dns_spfASCII(SPFENU spf); +//Procedure to get ONE SPF entry within domain dns +extern char *dns_getspf(char *domain); //procedure to get a list of MX IP releated to a specific //domain. extern MXTYP **dns_getmx(char *domain); -//get the SPF status for a specific domain and a remote peer IP -extern SPFENU dns_get_spf_status(int *try,char *domain,AFNTYP *afnnum); - //homework to be done before starting/stopping module. extern int dns_modeunidns(_Bool mode); -- 2.47.3