/*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 */
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? */
}
- return PDKIM_OK;
+
+ /* check if this looks like a DKIM record */
+ 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? */
}
if (!sig) return;
+if ( !dkim_verify_overall
+ && dkim_verify_status
+ ? Ustrcmp(dkim_verify_status, US"pass") == 0
+ : sig->verify_status == PDKIM_VERIFY_PASS
+ )
+ dkim_verify_overall = string_copy(sig->domain);
+
+if (!LOGGING(dkim_verbose)) return;
+
logmsg = string_catn(NULL, US"DKIM: ", 6);
if (!(s = sig->domain)) s = US"<UNSET>";
logmsg = string_append(logmsg, 2, "d=", s);
if (!(s = sig->selector)) s = US"<UNSET>";
logmsg = string_append(logmsg, 2, " s=", s);
-logmsg = string_append(logmsg, 7,
+logmsg = string_append(logmsg, 7,
" c=", sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
"/", sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
" a=", dkim_sig_to_a_tag(sig),
dkim_verify_status = dkim_exim_expand_query(DKIM_VERIFY_STATUS);
dkim_verify_reason = dkim_exim_expand_query(DKIM_VERIFY_REASON);
-
+
if ((rc = dkim_acl_call(id, res_ptr, user_msgptr, log_msgptr)) != OK)
return rc;
}
}
-/* Generate signatures for the given file, returning a string.
+/* Generate signatures for the given file.
If a prefix is given, prepend it to the file for the calculations.
+
+Return:
+ NULL: error; error string written
+ string: signature header(s), or a zero-length string (not an error)
*/
gstring *
pdkim_set_optional(sig,
CS dkim_sign_headers_expanded,
- dkim_identity_expanded,
+ CS dkim_identity_expanded,
pdkim_canon,
pdkim_canon, -1, 0, 0);
}
}
}
+if (!ctx.sig)
+ {
+ DEBUG(D_transport) debug_printf("DKIM: no viable signatures to use\n");
+ sigbuf = string_get(1); /* return a zero-len string */
+ goto CLEANUP;
+ }
-if (prefix)
- pdkim_feed(&ctx, prefix, Ustrlen(prefix));
+if (prefix && (pdkim_feed(&ctx, prefix, Ustrlen(prefix))) != PDKIM_OK)
+ goto pk_bad;
if (lseek(fd, off, SEEK_SET) < 0)
sread = -1;
for (sigbuf = NULL; sig; sig = sig->next)
sigbuf = string_append(sigbuf, 2, US sig->signature_header, US"\r\n");
-(void) string_from_gstring(sigbuf);
-
CLEANUP:
+ (void) string_from_gstring(sigbuf);
store_pool = old_pool;
errno = save_errno;
return sigbuf;