DKIM: use string-allocate facilities for DNS lookup
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 21 Jan 2018 14:51:45 +0000 (14:51 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 21 Jan 2018 15:07:48 +0000 (15:07 +0000)
src/src/dkim.c
src/src/pdkim/pdkim.c
src/src/pdkim/pdkim.h

index 852ae17f3c5398642139b6f0c7372e2968798013..867d45647d0bedd94136e86fb717e0a5a7505a13 100644 (file)
@@ -36,19 +36,19 @@ static const uschar * dkim_collect_error = NULL;
 
 
 /*XXX the caller only uses the first record if we return multiple.
-Could we hand back an allocated string?
 */
 
-static int
-dkim_exim_query_dns_txt(char *name, char *answer)
+static uschar *
+dkim_exim_query_dns_txt(char * name)
 {
 dns_answer dnsa;
 dns_scan dnss;
 dns_record *rr;
+gstring * g = NULL;
 
 lookup_dnssec_authenticated = NULL;
 if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
-  return PDKIM_FAIL;   /*XXX better error detail?  logging? */
+  return NULL; /*XXX better error detail?  logging? */
 
 /* Search for TXT record */
 
@@ -65,22 +65,27 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     while (rr_offset < rr->size)
       {
       uschar len = rr->data[rr_offset++];
-      snprintf(answer + answer_offset,
-               PDKIM_DNS_TXT_MAX_RECLEN - answer_offset,
-               "%.*s", (int)len, CS  (rr->data + rr_offset));
+
+      g = string_catn(g, US(rr->data + rr_offset), len);
+      if (g->ptr >= PDKIM_DNS_TXT_MAX_RECLEN)
+       goto bad;
+
       rr_offset += len;
-      answer_offset += len;
-      if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN)
-       return PDKIM_FAIL;      /*XXX better error detail?  logging? */
       }
 
     /* check if this looks like a DKIM record */
-    if (strncmp(answer, "v=", 2) == 0 && strncasecmp(answer, "v=dkim", 6) != 0)
-      continue;
-    return PDKIM_OK;
+    if (strncmp(g->s, "v=", 2) != 0 || strncasecmp(g->s, "v=dkim", 6) == 0)
+      {
+      store_reset(g->s + g->ptr + 1);
+      return string_from_gstring(g);
+      }
+
+    if (g) g->ptr = 0;         /* overwrite previous record */
     }
 
-return PDKIM_FAIL;     /*XXX better error detail?  logging? */
+bad:
+if (g) store_reset(g);
+return NULL;   /*XXX better error detail?  logging? */
 }
 
 
index 186258a621334bc537b73be718d2f87eb3cedf18..679607dbd46d4abcf174023227ff8153bd4dd3a7 100644 (file)
@@ -1306,10 +1306,7 @@ pdkim_pubkey * p;
 
 dns_txt_name = string_sprintf("%s._domainkey.%s.", sig->selector, sig->domain);
 
-dns_txt_reply = store_get(PDKIM_DNS_TXT_MAX_RECLEN);
-memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
-
-if (  ctx->dns_txt_callback(CS dns_txt_name, CS dns_txt_reply) != PDKIM_OK 
+if (  !(dns_txt_reply = ctx->dns_txt_callback(CS dns_txt_name))
    || dns_txt_reply[0] == '\0'
    )
   {
@@ -1713,7 +1710,7 @@ return PDKIM_OK;
 /* -------------------------------------------------------------------------- */
 
 DLLEXPORT pdkim_ctx *
-pdkim_init_verify(int(*dns_txt_callback)(char *, char *), BOOL dot_stuffing)
+pdkim_init_verify(uschar * (*dns_txt_callback)(char *), BOOL dot_stuffing)
 {
 pdkim_ctx * ctx;
 
@@ -1817,7 +1814,7 @@ return;
 
 void
 pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed,
-  int(*dns_txt_callback)(char *, char *))
+  uschar * (*dns_txt_callback)(char *))
 {
 memset(ctx, 0, sizeof(pdkim_ctx));
 ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN;
index 067c574f2b0d67be307934400c970bb1210ffbd0..ece86cba5088dccea8c9212c61ab23d5704e8873 100644 (file)
@@ -265,7 +265,7 @@ typedef struct pdkim_ctx {
   pdkim_signature *sig;
 
   /* Callback for dns/txt query method (verification only) */
-  int(*dns_txt_callback)(char *, char *);
+  uschar * (*dns_txt_callback)(char *);
 
   /* Coder's little helpers */
   gstring   *cur_header;
@@ -287,7 +287,7 @@ extern "C" {
 
 void      pdkim_init         (void);
 
-void      pdkim_init_context (pdkim_ctx *, BOOL, int(*)(char *, char *));
+void      pdkim_init_context (pdkim_ctx *, BOOL, uschar * (*)(char *));
 
 DLLEXPORT
 pdkim_signature *pdkim_init_sign    (pdkim_ctx *,
@@ -295,7 +295,7 @@ pdkim_signature *pdkim_init_sign    (pdkim_ctx *,
                               const uschar **);
 
 DLLEXPORT
-pdkim_ctx *pdkim_init_verify  (int(*)(char *, char *), BOOL);
+pdkim_ctx *pdkim_init_verify  (uschar * (*)(char *), BOOL);
 
 DLLEXPORT
 void       pdkim_set_optional (pdkim_signature *, char *, char *,int, int,