X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/fc6fb551537b5af8988576071ff6e1240cff269f..286b9d5fa4344de72fe6575fa089237fd7dbb56f:/src/src/dkim.c diff --git a/src/src/dkim.c b/src/src/dkim.c index 852ae17f3..c7bf64152 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -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 */ @@ -58,29 +58,33 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); if (rr->type == T_TXT) { int rr_offset = 0; - int answer_offset = 0; /* Copy record content to the answer buffer */ 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 (Ustrncmp(g->s, "v=", 2) != 0 || strncasecmp(CS 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? */ } @@ -264,7 +268,7 @@ dkim_exim_verify_finish(void) pdkim_signature * sig; int rc; gstring * g = NULL; -const uschar * errstr; +const uschar * errstr = NULL; store_pool = POOL_PERM; @@ -287,12 +291,8 @@ dkim_collect_input = FALSE; /* Finish DKIM operation and fetch link to signatures chain */ rc = pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures, &errstr); -if (rc != PDKIM_OK) - { - log_write(0, LOG_MAIN, "DKIM: validation error: %.100s%s%s", pdkim_errstr(rc), - errstr ? ": " : "", errstr ? errstr : US""); - goto out; - } +if (rc != PDKIM_OK && errstr) + log_write(0, LOG_MAIN, "DKIM: validation error: %s", errstr); /* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */ @@ -706,6 +706,9 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0))) pdkim_canon, pdkim_canon, -1, 0, 0); + if (!pdkim_set_bodyhash(&ctx, sig)) + goto bad; + if (!ctx.sig) /* link sig to context chain */ ctx.sig = sig; else @@ -723,7 +726,7 @@ if (!ctx.sig) goto CLEANUP; } -if (prefix && (pdkim_feed(&ctx, prefix, Ustrlen(prefix))) != PDKIM_OK) +if (prefix && (pdkim_rc = pdkim_feed(&ctx, prefix, Ustrlen(prefix))) != PDKIM_OK) goto pk_bad; if (lseek(fd, off, SEEK_SET) < 0)