-/*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;
+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 (dns_record * 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;
/* 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);
}
}
bad:
-if (g) store_reset(g);
+store_reset(reset_point);
return NULL; /*XXX better error detail? logging? */
}
void
dkim_exim_init(void)
{
+if (f.dkim_init_done) return;
+f.dkim_init_done = TRUE;
pdkim_init();
}
void
dkim_exim_verify_init(BOOL dot_stuffing)
{
+dkim_exim_init();
+
/* There is a store-reset between header & body reception
so cannot use the main pool. Any allocs done by Exim
memory-handling must use the perm pool. */
dkim_exim_sign_init(void)
{
int old_pool = store_pool;
+
+dkim_exim_init();
store_pool = POOL_MAIN;
pdkim_init_context(&dkim_sign_ctx, FALSE, &dkim_exim_query_dns_txt);
store_pool = old_pool;
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;
}