/* Sub kevel procedure to manage IP number. */
/* */
/********************************************************/
+#include <arpa/inet.h>
+#include <errno.h>
+#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
+#include <string.h>
#include "subafn.h"
static _Bool modopen; //module open/close status
/*
+\f
+*/
+/********************************************************/
+/* */
+/* 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;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* 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
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* 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
*/
/********************************************************/
#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 {
*/
/********************************************************/
/* */
+/* 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);
+ }
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to query DNS information */
/* */
/********************************************************/
ptr=inftxt;
while (*ptr!=(char *)0) {
- if (strstr(*ptr,"v=spf1")==*ptr) {
+ if (strstr(*ptr,SPF1)==*ptr) {
char *dup;
dup=strdup(*ptr);
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;
}
spf=spf_neutral;
return spf;
+
+#undef OPEP
}
/*
^L
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
}
}
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;