From 2ec7d837ea2be672fc41858cab86b35b649993f5 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Wed, 14 Aug 2024 10:52:00 -0400 Subject: [PATCH] Starting to extract SPF record --- lib/subrou.c | 2 +- lib/unidns.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+), 1 deletion(-) diff --git a/lib/subrou.c b/lib/subrou.c index 1b53784..9fa3673 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -21,7 +21,7 @@ //version definition #define VERSION "0.4.2" -#define RELEASE "2" +#define RELEASE "3" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unidns.c b/lib/unidns.c index 13ad64d..dc07158 100644 --- a/lib/unidns.c +++ b/lib/unidns.c @@ -5,6 +5,9 @@ /* exchange. */ /* */ /********************************************************/ +#include +#include +#include #include #include #include @@ -13,8 +16,247 @@ #include "subrou.h" #include "unidns.h" + +#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 */ + }RSPTYP; + static _Bool modopen; //module open/close status +/* + +*/ +/************************************************/ +/* */ +/* Procedure to query DNS information */ +/* */ +/************************************************/ +static int myquery(const char *dname,int class,int type, + unsigned char *answer, int anslen) + +{ +#define OPEP "unidns.c:myquery," + +int got; + +if ((got=res_query(dname,class,type,answer,anslen))<0) { + got=-1; /*trouble trouble*/ + switch (errno) { + case 0 : /* do not care */ + got=0; /*NO answer! */ + break; + case ETIMEDOUT : /*rqst timed out*/ + (void) rou_alert(0,"%s Timeout on domain <%s>!",OPEP,dname); + break; + default : + (void) rou_alert(0,"%s query error for domain <%s> type='%d' " + "(error=<%d/%s>)",OPEP,dname,type,errno,strerror(errno)); + } + } +else { + if (got>anslen) { + (void) rou_alert(0,"%s query too by for domain <%s> type='%d' (got=%d)", + OPEP,dname,type,got); + got=anslen; + } + } +return got; + +#undef OPEP +} +/* + +*/ +/************************************************/ +/* */ +/* Procedure to extract text information */ +/* from DNS record. */ +/* SMTP client status. */ +/* */ +/************************************************/ +static char **extracting(RSPTYP *rsp,int rsplen,char *request,char *field) + +{ +#define OPEP "unidns.c:extracting," + +char **list; +int question; +int answer; +const unsigned char *msg; +const unsigned char *eom; +const unsigned char *cp; +int rc; +char buf[NS_PACKETSZ+1]; + +list=(char **)0; +question=ntohs(rsp->hdr.qdcount); +answer=ntohs(rsp->hdr.ancount); +msg=(unsigned char *)rsp; +eom=(unsigned char *)rsp+rsplen; +cp=(unsigned char *)rsp+sizeof(HEADER); +while ((question-->0)&&(cp0)&&(cp0) { + int type; + int class; + long ttl; + int dlen; + int collected; + const unsigned char *txtptr; + char *dynbuf; + + cp+=rc; + GETSHORT(type,cp); + GETSHORT(class,cp); + GETLONG(ttl,cp); + GETSHORT(dlen,cp); + if (class!=1) { + (void) rou_alert(0,"%s unexpected class='%d' on request <%s> field=<%s> (ttl='%d')", + OPEP,class,request,field,ttl); + cp+=dlen; + break; /*no need to go further */ + } + collected=0; + dynbuf=(char *)0; + switch (type) { + case T_MX : + if ((rc=dn_expand(msg,eom,cp+2,(char *)buf,sizeof(buf)-1))>0) { + int pref; + char info[30]; + + pref=(((unsigned int)cp[0])<<8)|((unsigned int)cp[1]); + (void) snprintf(info,sizeof(info),"%d",pref); + list=(char **)rou_addlist((void **)list,(void *)strdup(info)); + list=(char **)rou_addlist((void **)list,(void *)strdup(buf)); + } + break; + case T_CNAME : + #ifdef GETCNAME_2011 + /*we are not interested to collect CNAME for now (JMP Feb 2011) */ + if ((rc=dn_expand(msg,eom,cp,(char *)buf,sizeof(buf)))>0) { + list=(char **)rou_addlist((void **)list,(void *)strdup("100")); + list=(char **)rou_addlist((void **)list,(void *)strdup(buf)); + } + #endif + break; + case T_SPF : + case T_TXT : + txtptr=cp; + dynbuf=(char *)calloc(10,sizeof(char)); + while (collected0) { + list=(char **)rou_addlist((void **)list,(void *)strdup(buf)); + } + break; + default : + (void) rou_alert(0,"%s Unexpected '%d' field",OPEP,type); + break; + } + cp+=dlen; + } + } +return list; +#undef OPEP +} +/* +^L +*/ +/************************************************/ +/* */ +/* Procedure to extract a domain TXT */ +/* If the domain doesn't exist or domain */ +/* do not have a TXT, a void pointer is */ +/* returned. */ +/* */ +/* */ +/************************************************/ +static char **gettxt(char *domain,int ttype,char *field) + +{ +char **inftxt; +int answer; +RSPTYP rsp; + +inftxt=(char **)0; +(void) memset(rsp.buf,'\000',sizeof(rsp.buf)); +switch (answer=myquery(domain,C_IN,ttype,rsp.buf,sizeof(rsp.buf))) { + case -1 : /*timeout */ + break; + case 0 : /*no data available */ + break; + default : /*data */ + inftxt=extracting(&rsp,answer,domain,field); + break; + } +return inftxt; +} +/* +^L +*/ +/************************************************/ +/* */ +/* Procedure to extract a hostname SPF */ +/* Search first for an SPF record, if not */ +/* implemented search for a TXT record */ +/* If the domain doesn't exist or domain */ +/* do not have a TXT or SPF, a void pointer*/ +/* is returned. */ +/* */ +/* */ +/************************************************/ +static char **getspf(char *domain) + +{ +char **inftxt; + +if ((inftxt=gettxt(domain,T_SPF,"SPF"))==(char **)0) + inftxt=gettxt(domain,T_TXT,"TXT"); +return inftxt; +} +/* +^L +*/ +/************************************************/ +/* */ +/* Procedure to extract a hostname TXT */ +/* If the domain doesn't exist or domain */ /* ^L */ @@ -67,10 +309,50 @@ return ascii; PUBLIC SPFENU dns_get_spf_status(char *domain,char *peerip) { +#define OPEP "unidns.c:dns_get_spf_status" + SPFENU spf; +char **list; +int phase; +_Bool proceed; spf=spf_unknown; +list=(char **)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Are the parameters available + if ((domain==(char *)0)||(peerip=(char *)0)) { + (void) rou_alert(0,"%s missing one or both needed argument",OPEP); + phase=999; //trouble trouble + } + break; + case 1 : //get the spf LIST related to SPF + if ((list=getspf(domain))==(char **)0) { + phase=999; + } + break; + case 2 : //gett the spf LIST related to SPF + if (list!=(char **)0) { + char **ptr; + + ptr=list; + while (*ptr!=(char *)0) { + (void) printf("JMPDBG <%s>\n",*ptr); + ptr++; + } + } + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } return spf; + +#undef OPEP } /* ^L -- 2.47.3