OpenSSL: support OCSP stapling on multi-cert servers
[exim.git] / src / src / dkim.c
index 5209cd983ceb27d16a8e4c097fcc7ba8d2428083..065170444bb8494a19b5a5c88f25eb8305ab9622 100644 (file)
@@ -37,26 +37,28 @@ static const uschar * dkim_collect_error = NULL;
 
 
 
-/*XXX the caller only uses the first record if we return multiple.
+/* Look up the DKIM record in DNS for the given hostname.
+Will use the first found if there are multiple.
+The return string is tainted, having come from off-site.
 */
 
 uschar *
-dkim_exim_query_dns_txt(uschar * name)
+dkim_exim_query_dns_txt(const uschar * name)
 {
-dns_answer dnsa;
+dns_answer * dnsa = store_get_dns_answer();
 dns_scan dnss;
-dns_record *rr;
+rmark reset_point = store_mark();
 gstring * g = NULL;
 
 lookup_dnssec_authenticated = NULL;
-if (dns_lookup(&dnsa, name, T_TXT, NULL) != DNS_SUCCEED)
+if (dns_lookup(dnsa, name, T_TXT, NULL) != DNS_SUCCEED)
   return NULL; /*XXX better error detail?  logging? */
 
 /* Search for TXT record */
 
-for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
      rr;
-     rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+     rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
   if (rr->type == T_TXT)
     {
     int rr_offset = 0;
@@ -77,7 +79,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     /* check if this looks like a DKIM record */
     if (Ustrncmp(g->s, "v=", 2) != 0 || strncasecmp(CS g->s, "v=dkim", 6) == 0)
       {
-      gstring_reset_unused(g);
+      gstring_release_unused(g);
       return string_from_gstring(g);
       }
 
@@ -85,7 +87,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     }
 
 bad:
-if (g) store_reset(g);
+store_reset(reset_point);
 return NULL;   /*XXX better error detail?  logging? */
 }
 
@@ -280,15 +282,14 @@ return;
 void
 dkim_exim_verify_log_all(void)
 {
-pdkim_signature * sig;
-for (sig = dkim_signatures; sig; sig = sig->next) dkim_exim_verify_log_sig(sig);
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
+  dkim_exim_verify_log_sig(sig);
 }
 
 
 void
 dkim_exim_verify_finish(void)
 {
-pdkim_signature * sig;
 int rc;
 gstring * g = NULL;
 const uschar * errstr = NULL;
@@ -320,7 +321,7 @@ if (rc != PDKIM_OK && errstr)
 
 /* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
 
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
   {
   if (sig->domain)   g = string_append_listele(g, ':', sig->domain);
   if (sig->identity) g = string_append_listele(g, ':', sig->identity);
@@ -372,7 +373,6 @@ int
 dkim_exim_acl_run(uschar * id, gstring ** res_ptr,
   uschar ** user_msgptr, uschar ** log_msgptr)
 {
-pdkim_signature * sig;
 uschar * cmp_val;
 int rc = -1;
 
@@ -385,7 +385,7 @@ if (f.dkim_disable_verify || !id || !dkim_verify_ctx)
 
 /* Find signatures to run ACL on */
 
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
   if (  (cmp_val = Ustrchr(id, '@') != NULL ? US sig->identity : US sig->domain)
      && strcmpic(cmp_val, id) == 0
      )
@@ -623,6 +623,7 @@ if (dkim_domain)
   /* Only sign once for each domain, no matter how often it
   appears in the expanded list. */
 
+  dkim_signing_domain = string_copylc(dkim_signing_domain);
   if (match_isinlist(dkim_signing_domain, CUSS &seen_doms,
       0, NULL, NULL, MCL_STRING, TRUE, NULL) == OK)
     continue;
@@ -782,14 +783,15 @@ CLEANUP:
 
 pk_bad:
   log_write(0, LOG_MAIN|LOG_PANIC,
-               "DKIM: signing failed: %.100s", pdkim_errstr(pdkim_rc));
+               "DKIM: signing failed: %.100s", pdkim_errstr(pdkim_rc));
 bad:
   sigbuf = NULL;
   goto CLEANUP;
 
 expand_bad:
-  log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand %s: %s",
-             errwhen, expand_string_message);
+  *errstr = string_sprintf("failed to expand %s: %s",
+              errwhen, expand_string_message);
+  log_write(0, LOG_MAIN | LOG_PANIC, "%s", *errstr);
   goto bad;
 }
 
@@ -799,12 +801,11 @@ expand_bad:
 gstring *
 authres_dkim(gstring * g)
 {
-pdkim_signature * sig;
 int start = 0;         /* compiler quietening */
 
 DEBUG(D_acl) start = g->ptr;
 
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
   {
   g = string_catn(g, US";\n\tdkim=", 8);