From 4e76c7f793f7ea2e416bea99fa92fd36c3ddb490 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Thu, 15 Aug 2024 08:51:11 -0400 Subject: [PATCH] Improving subafn module --- app/chkdns.c | 1 + lib/subafn.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/subafn.h | 10 ++++ lib/subrou.c | 2 +- lib/unidns.c | 50 +++++++++++++++-- 5 files changed, 209 insertions(+), 4 deletions(-) diff --git a/app/chkdns.c b/app/chkdns.c index 19b7d01..c4b63df 100644 --- a/app/chkdns.c +++ b/app/chkdns.c @@ -43,6 +43,7 @@ while (proceed==true) { switch (phase) { case 0 : //checking parameters foreground=true; + debug=5; (void) rou_setappname(curname); if (argc<2) { (void) rou_alert(0,"%s need 2 arguments (domain,IP)",appname); diff --git a/lib/subafn.c b/lib/subafn.c index 67f75c7..f2892aa 100644 --- a/lib/subafn.c +++ b/lib/subafn.c @@ -4,8 +4,12 @@ /* Sub kevel procedure to manage IP number. */ /* */ /********************************************************/ +#include +#include +#include #include #include +#include #include "subafn.h" @@ -13,6 +17,152 @@ static _Bool modopen; //module open/close status /* + +*/ +/********************************************************/ +/* */ +/* Routine to fee memory used by an AFNTYP */ +/* */ +/********************************************************/ +PUBLIC AFNTYP *afn_freeipnum(AFNTYP *afnnum) + +{ +if (afnnum!=(AFNTYP *)0) { + (void) free(afnnum); + afnnum=(AFNTYP *)0; + } +return afnnum; +} +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to return a string with */ +/* ipnum address and MASK in clear format */ +/* Address need to freed. */ +/* */ +/********************************************************/ +PUBLIC char *afn_stripnum(AFNTYP *num) + +{ +#define OPEP "subafn.c:afn_stripnum" + +char *strip; +const char *markr; +char host[NI_MAXHOST]; +int phase; +_Bool proceed; + +strip=(char *)0; +markr=""; +(void) strcpy(host,""); +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Do we have an IP number + if (num==(AFNTYP *)0) { + (void) fprintf(stderr,"%s No ip provided (bug?)\n",OPEP); + (void) snprintf(host,sizeof(host),"[IP not defined] (Bug?)"); + phase=999; + } + break; + case 1 : //extracting IP + switch (num->afntype) { + case AF_INET6 : + markr=STRIPV6; + //NO break + case AF_INET : + if (inet_ntop(num->afntype,&(num->ip),host,sizeof(host))==(char *)0) + (void) snprintf(host,sizeof(host),"[afn_stripnum error=<%s>] (Bug?)", + strerror(errno)); + break; + default : + (void) snprintf(host,sizeof(host),"[ipvx:0.%d] (Bug?)",num->afntype); + break; + } + break; + default : //SAFE Guard + if (strlen(host)>0) { //always + int taille; + + taille=strlen(markr)+strlen(host)+10; + strip=(char *)calloc(taille,sizeof(char)); + (void) snprintf(strip,taille,"%s%s",markr,host); + } + proceed=false; + break; + } + phase++; + } +return strip; + +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ +/* Routine to convert clean string to be */ +/* IP number in AFNTYP structure. */ +/* */ +/********************************************************/ +PUBLIC AFNTYP *afn_getipnum(char *cleanipstr) + +{ +#define OPEP "subafn.c:afn_getipnum" +#define ZIPV4 "0.0.0.0" + +AFNTYP *afnnum; +int phase; +int proceed; + +afnnum=(AFNTYP *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Do we have an IP string + if (cleanipstr==(char *)0) { + (void) fprintf(stderr,"%s No ip provided (bug?)\n",OPEP); + phase=999; //No need to go further + } + break; + case 1 : /*lets say ip format ok */ + afnnum=(AFNTYP *)calloc(1,sizeof(AFNTYP)); + afnnum->afntype=AF_INET; + afnnum->afnmask=32; + if (strchr(cleanipstr,':')==(char *)0) + phase++; //This is an IPV4 number + break; + case 2 : //IP is an IPV6 format + if (strcasestr(cleanipstr,STRIPV6)==cleanipstr) + cleanipstr+=strlen(STRIPV6); + afnnum->afntype=AF_INET6; + afnnum->afnmask=128; + break; + case 3 : //checking '0' situation + if (strcmp(cleanipstr,"0")==0) + cleanipstr=ZIPV4; + break; + case 4 : //lets convert it + if (inet_pton(afnnum->afntype,cleanipstr,afnnum->ip)<=0) + afnnum=afn_freeipnum(afnnum); + break; + default : /*SAFE guard */ + proceed=false; + break; + } + phase++; + } +return afnnum; + +#undef ZIPV4 +#undef OPEP +} +/* ^L */ /********************************************************/ diff --git a/lib/subafn.h b/lib/subafn.h index d2e3460..f25f296 100644 --- a/lib/subafn.h +++ b/lib/subafn.h @@ -10,6 +10,9 @@ #include +//IPV6 ip number marker +#define STRIPV6 "ipv6:" + //space to store (at least) IPV6 number #define AFT sizeof(struct in6_addr) @@ -19,6 +22,13 @@ typedef struct { u_char ip[AFT]; /*IP number */ }AFNTYP; +//procedure to free memory used by an AFNTYP structure +extern AFNTYP *afn_freeipnum(AFNTYP *afnnum); + +//procedure to convert a AFNTYP structure to an standardised +//IP number +extern char *afn_stripnum(AFNTYP *afnnum); + //procedure to convert a IP as string to an AFNTYP structure extern AFNTYP *afn_getipnum(char *cleanipstr); diff --git a/lib/subrou.c b/lib/subrou.c index 3335e56..dd512b2 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -21,7 +21,7 @@ //version definition #define VERSION "0.4.2" -#define RELEASE "5" +#define RELEASE "6" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unidns.c b/lib/unidns.c index 7489fa5..7e1fc6b 100644 --- a/lib/unidns.c +++ b/lib/unidns.c @@ -17,6 +17,8 @@ #include "subrou.h" #include "unidns.h" +//spf1 marker within DNS record +#define SPF1 "v=spf1 " #define B64K 65536 /*according US Cert VU#738331 */ typedef union { @@ -30,6 +32,26 @@ static _Bool modopen; //module open/close status */ /********************************************************/ /* */ +/* Procedure to display SPF debug information */ +/* */ +/********************************************************/ +static void dbgspf(int dbg,char *spf,AFNTYP *afnnum,char *seq,SPFENU status) + +{ +if (debug>-dbg) { + char *strip; + + strip=afn_stripnum(afnnum); + (void) rou_alert(dbg,"Current SPF Value <%s>]\n\tSEQ=<%s>\n\tIP=[%s]\n\tSPF=<%s>", + dns_spfASCII(status),spf,strip,seq); + strip=rou_freestr(strip); + } +} +/* + +*/ +/********************************************************/ +/* */ /* Procedure to query DNS information */ /* */ /********************************************************/ @@ -250,7 +272,7 @@ if ((infspf=gettxt(domain,T_SPF,"SPF"))==(char **)0) { ptr=inftxt; while (*ptr!=(char *)0) { - if (strstr(*ptr,"v=spf1")==*ptr) { + if (strstr(*ptr,SPF1)==*ptr) { char *dup; dup=strdup(*ptr); @@ -275,17 +297,36 @@ return infspf; static SPFENU is_peerip_ok(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 - afnnum=afn_getipnum(peerip); + 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 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 + (void) dbgspf(2,spfrec,afnnum,spfrec,spf); break; default : //SAFE Guard proceed=false; @@ -295,6 +336,8 @@ while (proceed==true) { } spf=spf_neutral; return spf; + +#undef OPEP } /* ^L @@ -368,7 +411,7 @@ proceed=true; while (proceed==true) { switch (phase) { case 0 : //Are the parameters available - if ((domain==(char *)0)||(peerip=(char *)0)) { + if ((domain==(char *)0)||(peerip==(char *)0)) { (void) rou_alert(0,"%s missing one or both needed argument",OPEP); phase=999; //trouble trouble } @@ -385,6 +428,7 @@ while (proceed==true) { } break; case 3 : //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]); list=(char **)rou_freelist((void **)list,(freehandler_t)rou_freestr); break; -- 2.47.3