]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Starting to extract SPF record
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 14 Aug 2024 14:52:00 +0000 (10:52 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 14 Aug 2024 14:52:00 +0000 (10:52 -0400)
lib/subrou.c
lib/unidns.c

index 1b537844072805bf27be085ae49de4c9478950ea..9fa3673758dddaa1432a48a6c5b984522c3b7fac 100644 (file)
@@ -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
index 13ad64d5bdd5dbfb20362ae75b7eff4c07bf0b45..dc0715872ae6945b66112278ddcdff2b730e20f4 100644 (file)
@@ -5,6 +5,9 @@
 /*     exchange.                                       */
 /*                                                     */
 /********************************************************/
+#include        <errno.h>
+#include        <malloc.h>
+#include        <resolv.h>
 #include        <stdbool.h>
 #include        <stdio.h>
 #include        <string.h>
 #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
+/*
+\f
+*/
+/************************************************/
+/*                                             */
+/*     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
+}
+/*
+\f
+*/
+/************************************************/
+/*                                             */
+/*     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)&&(cp<eom)) {
+  if ((rc=dn_expand(msg,eom,cp,(char *)buf,sizeof(buf)-1))<0)
+    break;
+  cp +=rc+QFIXEDSZ;
+  }
+while((answer-->0)&&(cp<eom)) {
+  if ((rc=dn_expand(msg,eom,cp,(char *)buf,sizeof(buf)-1))<0) {
+    break;
+    }
+  if (rc>0) {
+    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 (collected<dlen) {
+          u_int taille;
+         char *newdynbuf;
+
+         (void) memset(buf,'\000',sizeof(buf));
+          taille=((u_int)(txtptr[0]))&0X0FF; 
+         txtptr++;
+          (void) snprintf(buf,sizeof(buf),"%.*s ",taille,txtptr);
+         if ((newdynbuf=(char *)realloc(dynbuf,strlen(dynbuf)+strlen(buf)+5))!=(char *)0) {
+            dynbuf=newdynbuf;
+           (void) strcat(dynbuf,buf);
+            }
+         collected+=taille+1;
+         txtptr+=taille;
+          }
+        list=(char **)rou_addlist((void **)list,(void *)dynbuf);
+       break;
+      case T_A         :       {
+        u_int32_t *addr;
+
+        addr=(u_int32_t *)calloc(1,sizeof(u_int32_t));
+        *addr=ntohl(*((u_int32_t *)cp));
+        list=(char **)rou_addlist((void **)list,(void *)addr);
+       }
+       break;
+      case T_AAAA      :       
+       (void) rou_alert(0,"%s Unexpected T_AAAA field",OPEP);
+       break;
+      case T_PTR       :
+        if ((rc=dn_expand(msg,eom,cp,(char *)buf,sizeof(buf)-1))>0) {
+          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