#include "subrou.h"
#include "unidns.h"
+#define MXDNS 10 //maximun number of DNS acess
+
//spf1 marker within DNS record
#define SPF1 "v=spf1 "
-#define B64K 65536 /*according US Cert VU#738331 */
+#define B64K 65536 //according US Cert VU#738331
typedef union {
- HEADER hdr; /*defined in resolv.h */
- u_char buf[B64K]; /*according US Cert VU#738331 */
+ HEADER hdr; //defined in resolv.h
+ 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
/*
\f
/* Procedure to display SPF debug information */
/* */
/********************************************************/
-static void dbgspf(int dbg,AFNTYP *afnnum,char *seq,SPFENU status)
+static void dbgspf(int dbg,char *peerip,char *seq,SPFENU status)
{
if (debug>-dbg) {
- char *strip;
-
- strip=afn_stripnum(afnnum);
(void) rou_alert(dbg,"Current SPF Value <%s>\n\tIP=[%s]\n\tSPF=<%s>",
- dns_spfASCII(status),strip,seq);
- strip=rou_freestr(strip);
+ dns_spfASCII(status),peerip,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;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to get the next SPF component */
/* return a dynamic char pointer with the isolated */
/* SPF sequence. */
/* sequence contents */
/* */
/********************************************************/
-static SPFENU checkseq(char *seq,AFNTYP *afnum,SPFENU spf)
+static SPFENU checkseq(int *try,char *seq,char *peerip,SPFENU spf)
{
#define OPEP "unidns.c:checkseq"
spf=spf_fail;
break;
default :
- (void) rou_alert(0,"%s <%s> is not an expected SPF Mechanisms (Bug?)",
+ (void) rou_alert(0,"%s <%s> is not an expected SPF Prefix (Bug?)",
OPEP,seq);
break;
}
}
break;
case 1 : //check directive
+ switch (tellmechanism(seq)) {
+ case mch_include : //include sub domain
+ (void) printf("JMPDBG should include <%s>\n",seq+1);
+ if (seq[0]==':') {
+ (*try)++;
+ spf=dns_get_spf_status(try,seq+1,peerip);
+ }
+ 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;
/* spf allowed IP */
/* */
/********************************************************/
-static SPFENU is_peerip_ok(char *peerip,char *spfrec)
+static SPFENU is_peerip_ok(int *try,char *peerip,char *spfrec)
{
#define OPEP "unidns.c:is_peerip_ok"
SPFENU spf;
-AFNTYP *afnnum;
int phase;
_Bool proceed;
spf=spf_permerr;
-afnnum=(AFNTYP *)0;
phase=0;
proceed=true;
while (proceed==true) {
switch (phase) {
case 0 : //Converting the IP number
- if ((afnnum=afn_getipnum(peerip))==(AFNTYP *)0) {
- (void) rou_alert(0,"%s Unable to convert ip <%s> (bug?)",OPEP,peerip);
- phase=999;
- }
if (spfrec==(char *)0) {
(void) rou_alert(0,"%s SPF record is NULL (bug?)",OPEP);
phase=999;
break;
case 2 : //making sure spfrec is an SPF1
spfrec+=strlen(SPF1);
- (void) dbgspf(2,afnnum,spfrec,spf);
+ (void) dbgspf(2,peerip,spfrec,spf);
if (strlen(spfrec)>0) {
char *seq;
while ((seq=getspfseq(spfrec))!=(char *)0) {
spfrec=strstr(spfrec,seq);
spfrec+=strlen(seq);
- spf=checkseq(seq,afnnum,spf);
+ spf=checkseq(try,seq,peerip,spf);
seq=rou_freestr(seq);
}
}
/* domain name and and an IP. */
/* */
/********************************************************/
-PUBLIC SPFENU dns_get_spf_status(char *domain,char *peerip)
+PUBLIC SPFENU dns_get_spf_status(int *try,char *domain,char *peerip)
{
#define OPEP "unidns.c:dns_get_spf_status"
int phase;
_Bool proceed;
+(*try)++;
spf=spf_permerr;
list=(char **)0;
phase=0;
phase=999; //trouble trouble
}
break;
- case 1 : //get the spf LIST related to SPF
+ 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 2 : //check if we have onlye ONE SPF entry
+ 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 3 : //gett the spf LIST related to SPF
+ case 4 : //gett the spf LIST related to SPF
(void) printf("JMPDBG peerip=<%s>, spf=<%s>\n",peerip,list[0]);
- spf=is_peerip_ok(peerip,list[0]);
+ spf=is_peerip_ok(try,peerip,list[0]);
list=(char **)rou_freelist((void **)list,(freehandler_t)rou_freestr);
break;
default : //SAFE guard