X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/d7978c0f8af20ff4c3f770589b1bb81568aecff3..a841a6eca79ff08b36f2225dcf89c1c162bb8777:/src/src/pdkim/pdkim.c diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index d056402e1..0d2674f50 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -26,8 +26,8 @@ #ifndef DISABLE_DKIM /* entire file */ -#ifndef SUPPORT_TLS -# error Need SUPPORT_TLS for DKIM +#ifdef DISABLE_TLS +# error Must not DISABLE_TLS, for DKIM #endif #include "crypt_ver.h" @@ -121,6 +121,14 @@ return string_sprintf("%s-%s", } +static int +pdkim_keyname_to_keytype(const uschar * s) +{ +for (int i = 0; i < nelem(pdkim_keytypes); i++) + if (Ustrcmp(s, pdkim_keytypes[i]) == 0) return i; +return -1; +} + int pdkim_hashname_to_hashtype(const uschar * s, unsigned len) { @@ -238,7 +246,7 @@ debug_printf("\n"); static pdkim_stringlist * pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str) { -pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist)); +pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist), FALSE); memset(new_entry, 0, sizeof(pdkim_stringlist)); new_entry->value = string_copy(str); @@ -328,7 +336,7 @@ pdkim_relax_header_n(const uschar * header, int len, BOOL append_crlf) { BOOL past_field_name = FALSE; BOOL seen_wsp = FALSE; -uschar * relaxed = store_get(len+3); +uschar * relaxed = store_get(len+3, TRUE); /* tainted */ uschar * q = relaxed; for (const uschar * p = header; p - header < len; p++) @@ -408,7 +416,7 @@ pdkim_decode_qp(const uschar * str) int nchar = 0; uschar * q; const uschar * p = str; -uschar * n = store_get(Ustrlen(str)+1); +uschar * n = store_get(Ustrlen(str)+1, TRUE); *n = '\0'; q = n; @@ -445,7 +453,7 @@ b->len = dlen; uschar * pdkim_encode_base64(blob * b) { -return b64encode(b->data, b->len); +return b64encode(CUS b->data, b->len); } @@ -465,7 +473,7 @@ BOOL past_hname = FALSE; BOOL in_b_val = FALSE; int where = PDKIM_HDR_LIMBO; -sig = store_get(sizeof(pdkim_signature)); +sig = store_get(sizeof(pdkim_signature), FALSE); memset(sig, 0, sizeof(pdkim_signature)); sig->bodylength = -1; @@ -474,7 +482,7 @@ sig->version = 0; sig->keytype = -1; sig->hashtype = -1; -q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1); +q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1, TRUE); /* tainted */ for (uschar * p = raw_hdr; ; p++) { @@ -561,9 +569,7 @@ for (uschar * p = raw_hdr; ; p++) uschar * elem; if ((elem = string_nextinlist(&list, &sep, NULL, 0))) - for (int i = 0; i < nelem(pdkim_keytypes); i++) - if (Ustrcmp(elem, pdkim_keytypes[i]) == 0) - { sig->keytype = i; break; } + sig->keytype = pdkim_keyname_to_keytype(elem); if ((elem = string_nextinlist(&list, &sep, NULL, 0))) for (int i = 0; i < nelem(pdkim_hashes); i++) if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0) @@ -632,12 +638,12 @@ while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n')) DEBUG(D_acl) { debug_printf( - "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + "DKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); pdkim_quoteprint(US sig->rawsig_no_b_val, Ustrlen(sig->rawsig_no_b_val)); debug_printf( - "PDKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8); + "DKIM >> Sig size: %4u bits\n", (unsigned) sig->sighash.len*8); debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } if (!pdkim_set_sig_bodyhash(ctx, sig)) @@ -656,7 +662,7 @@ const uschar * ele; int sep = ';'; pdkim_pubkey * pub; -pub = store_get(sizeof(pdkim_pubkey)); +pub = store_get(sizeof(pdkim_pubkey), TRUE); /* tainted */ memset(pub, 0, sizeof(pdkim_pubkey)); while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0))) @@ -783,7 +789,7 @@ pdkim_finish_bodyhash(pdkim_ctx * ctx) { for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */ { - DEBUG(D_acl) debug_printf("PDKIM: finish bodyhash %d/%d/%ld len %ld\n", + DEBUG(D_acl) debug_printf("DKIM: finish bodyhash %d/%d/%ld len %ld\n", b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes); exim_sha_finish(&b->body_hash_ctx, &b->bh); } @@ -795,8 +801,8 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { - debug_printf("PDKIM [%s] Body bytes (%s) hashed: %lu\n" - "PDKIM [%s] Body %s computed: ", + debug_printf("DKIM [%s] Body bytes (%s) hashed: %lu\n" + "DKIM [%s] Body %s computed: ", sig->domain, pdkim_canons[b->canon_method], b->signed_body_bytes, sig->domain, pdkim_hashes[b->hashtype].dkim_hashname); pdkim_hexprint(CUS b->bh.data, b->bh.len); @@ -818,15 +824,15 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) if ( sig->bodyhash.data && memcmp(b->bh.data, sig->bodyhash.data, b->bh.len) == 0) { - DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash compared OK\n", sig->domain); + DEBUG(D_acl) debug_printf("DKIM [%s] Body hash compared OK\n", sig->domain); } else { DEBUG(D_acl) { - debug_printf("PDKIM [%s] Body hash signature from headers: ", sig->domain); + debug_printf("DKIM [%s] Body hash signature from headers: ", sig->domain); pdkim_hexprint(sig->bodyhash.data, sig->bodyhash.len); - debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain); + debug_printf("DKIM [%s] Body hash did NOT verify\n", sig->domain); } sig->verify_status = PDKIM_VERIFY_FAIL; sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY; @@ -970,7 +976,7 @@ else #ifdef notdef DEBUG(D_acl) { - debug_printf("PDKIM >> raw hdr: "); + debug_printf("DKIM >> raw hdr: "); pdkim_quoteprint(CUS ctx->cur_header->s, ctx->cur_header->ptr); } #endif @@ -984,7 +990,7 @@ else fail verification of it later. */ DEBUG(D_acl) debug_printf( - "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + "DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s); @@ -1069,7 +1075,7 @@ else for (int p = 0; p < len; p++) ctx->flags = (ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR)) | PDKIM_PAST_HDRS; DEBUG(D_acl) debug_printf( - "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + "DKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); continue; } else @@ -1345,7 +1351,7 @@ check_bare_ed25519_pubkey(pdkim_pubkey * p) int excess = p->key.len - 32; if (excess > 0) { - DEBUG(D_acl) debug_printf("PDKIM: unexpected pubkey len %lu\n", p->key.len); + DEBUG(D_acl) debug_printf("DKIM: unexpected pubkey len %lu\n", p->key.len); p->key.data += excess; p->key.len = 32; } } @@ -1374,7 +1380,7 @@ if ( !(dns_txt_reply = ctx->dns_txt_callback(dns_txt_name)) DEBUG(D_acl) { debug_printf( - "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" + "DKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" " %s\n" " Raw record: ", dns_txt_name); @@ -1395,13 +1401,13 @@ if ( !(p = pdkim_parse_pubkey_record(CUS dns_txt_reply)) else debug_printf(" Error while parsing public key record\n"); debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } return NULL; } DEBUG(D_acl) debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); /* Import public key */ @@ -1411,23 +1417,20 @@ time we do not have a signature so we must interpret the pubkey k= tag instead. Assume writing on the sig is ok in that case. */ if (sig->keytype < 0) - { - for(int i = 0; i < nelem(pdkim_keytypes); i++) - if (Ustrcmp(p->keytype, pdkim_keytypes[i]) == 0) - { sig->keytype = i; goto k_ok; } - DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype); - sig->verify_status = PDKIM_VERIFY_INVALID; - sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT; - return NULL; - } -k_ok: + if ((sig->keytype = pdkim_keyname_to_keytype(p->keytype)) < 0) + { + DEBUG(D_acl) debug_printf("verify_init: unhandled keytype %s\n", p->keytype); + sig->verify_status = PDKIM_VERIFY_INVALID; + sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_IMPORT; + return NULL; + } if (sig->keytype == KEYTYPE_ED25519) check_bare_ed25519_pubkey(p); if ((*errstr = exim_dkim_verify_init(&p->key, sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER, - vctx))) + vctx, &sig->keybits))) { DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr); sig->verify_status = PDKIM_VERIFY_INVALID; @@ -1440,6 +1443,61 @@ return p; } +/* -------------------------------------------------------------------------- */ +/* Sort and filter the sigs developed from the message */ + +static pdkim_signature * +sort_sig_methods(pdkim_signature * siglist) +{ +pdkim_signature * yield, ** ss; +const uschar * prefs; +uschar * ele; +int sep; + +if (!siglist) return NULL; + +/* first select in order of hashtypes */ +DEBUG(D_acl) debug_printf("DKIM: dkim_verify_hashes '%s'\n", dkim_verify_hashes); +for (prefs = dkim_verify_hashes, sep = 0, yield = NULL, ss = &yield; + ele = string_nextinlist(&prefs, &sep, NULL, 0); ) + { + int i = pdkim_hashname_to_hashtype(CUS ele, 0); + for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s; + s = next) + { + next = s->next; + if (s->hashtype == i) + { *prev = next; s->next = NULL; *ss = s; ss = &s->next; } + else + prev = &s->next; + } + } + +/* then in order of keytypes */ +siglist = yield; +DEBUG(D_acl) debug_printf("DKIM: dkim_verify_keytypes '%s'\n", dkim_verify_keytypes); +for (prefs = dkim_verify_keytypes, sep = 0, yield = NULL, ss = &yield; + ele = string_nextinlist(&prefs, &sep, NULL, 0); ) + { + int i = pdkim_keyname_to_keytype(CUS ele); + for (pdkim_signature * s = siglist, * next, ** prev = &siglist; s; + s = next) + { + next = s->next; + if (s->keytype == i) + { *prev = next; s->next = NULL; *ss = s; ss = &s->next; } + else + prev = &s->next; + } + } + +DEBUG(D_acl) for (pdkim_signature * s = yield; s; s = s->next) + debug_printf(" retain d=%s s=%s a=%s\n", + s->domain, s->selector, dkim_sig_to_a_tag(s)); +return yield; +} + + /* -------------------------------------------------------------------------- */ DLLEXPORT int @@ -1465,16 +1523,21 @@ if (ctx->cur_header && ctx->cur_header->ptr > 0) } else DEBUG(D_acl) debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); /* Build (and/or evaluate) body hash. Do this even if no DKIM sigs, in case we have a hash to do for ARC. */ pdkim_finish_bodyhash(ctx); +/* Sort and filter the recived signatures */ + +if (!(ctx->flags & PDKIM_MODE_SIGN)) + ctx->sig = sort_sig_methods(ctx->sig); + if (!ctx->sig) { - DEBUG(D_acl) debug_printf("PDKIM: no signatures\n"); + DEBUG(D_acl) debug_printf("DKIM: no signatures\n"); *return_signatures = NULL; return PDKIM_OK; } @@ -1491,12 +1554,12 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) && sig->verify_status == PDKIM_VERIFY_FAIL) { DEBUG(D_acl) - debug_printf("PDKIM: [%s] abandoning this signature\n", sig->domain); + debug_printf("DKIM: [%s] abandoning this signature\n", sig->domain); continue; } /*XXX The hash of the headers is needed for GCrypt (for which we can do RSA - suging only, as it happens) and for either GnuTLS and OpenSSL when we are + signing only, as it happens) and for either GnuTLS and OpenSSL when we are signing with EC (specifically, Ed25519). The former is because the GCrypt signing operation is pure (does not do its own hash) so we must hash. The latter is because we (stupidly, but this is what the IETF draft is saying) @@ -1506,7 +1569,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) do this hash incrementally. We don't need the hash we're calculating here for the GnuTLS and OpenSSL cases of RSA signing, since those library routines can do hash-and-sign. - + Some time in the future we could easily avoid doing the hash here for those cases (which will be common for a long while. We could also change from the current copy-all-the-headers-into-one-block, then call the hash-and-sign @@ -1519,18 +1582,18 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) if (!exim_sha_init(&hhash_ctx, pdkim_hashes[sig->hashtype].exim_hashmethod)) { log_write(0, LOG_MAIN|LOG_PANIC, - "PDKIM: hash setup error, possibly nonhandled hashtype"); + "DKIM: hash setup error, possibly nonhandled hashtype"); break; } if (ctx->flags & PDKIM_MODE_SIGN) DEBUG(D_acl) debug_printf( - "PDKIM >> Headers to be signed: >>>>>>>>>>>>\n" + "DKIM >> Headers to be signed: >>>>>>>>>>>>\n" " %s\n", sig->sign_headers); DEBUG(D_acl) debug_printf( - "PDKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n", + "DKIM >> Header data for hash, canonicalized (%-7s), in sequence >>\n", pdkim_canons[sig->canon_headers]); @@ -1550,7 +1613,6 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Import private key, including the keytype which we need for building the signature header */ -/*XXX extend for non-RSA algos */ if ((*err = exim_dkim_signing_init(CUS sig->privkey, &sctx))) { log_write(0, LOG_MAIN|LOG_PANIC, "signing_init: %s", *err); @@ -1649,15 +1711,15 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) } DEBUG(D_acl) debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); DEBUG(D_acl) { debug_printf( - "PDKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n"); + "DKIM >> Signed DKIM-Signature header, pre-canonicalized >>>>>>>>>>>>>\n"); pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr)); debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } /* Relax header if necessary */ @@ -1666,11 +1728,11 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { - debug_printf("PDKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n", + debug_printf("DKIM >> Signed DKIM-Signature header, canonicalized (%-7s) >>>>>>>\n", pdkim_canons[sig->canon_headers]); pdkim_quoteprint(CUS sig_hdr, Ustrlen(sig_hdr)); debug_printf( - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } /* Finalize header hash */ @@ -1679,7 +1741,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { - debug_printf("PDKIM [%s] Header %s computed: ", + debug_printf("DKIM [%s] Header %s computed: ", sig->domain, pdkim_hashes[sig->hashtype].dkim_hashname); pdkim_hexprint(hhash.data, hhash.len); } @@ -1719,7 +1781,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) { - debug_printf( "PDKIM [%s] b computed: ", sig->domain); + debug_printf( "DKIM [%s] b computed: ", sig->domain); pdkim_hexprint(sig->sighash.data, sig->sighash.len); } @@ -1748,7 +1810,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) debug_printf( " Error in DKIM-Signature header: tags missing or invalid (%s)\n" - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", !(sig->domain && *sig->domain) ? "d=" : !(sig->selector && *sig->selector) ? "s=" : !(sig->headernames && *sig->headernames) ? "h=" @@ -1759,7 +1821,7 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) ); goto NEXT_VERIFY; } - + /* Make sure sig uses supported DKIM version (only v1) */ if (sig->version != 1) { @@ -1768,19 +1830,19 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) DEBUG(D_acl) debug_printf( " Error in DKIM-Signature header: unsupported DKIM version\n" - "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + "DKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); goto NEXT_VERIFY; } DEBUG(D_acl) { - debug_printf( "PDKIM [%s] b from mail: ", sig->domain); + debug_printf( "DKIM [%s] b from mail: ", sig->domain); pdkim_hexprint(sig->sighash.data, sig->sighash.len); } if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err))) { - log_write(0, LOG_MAIN, "PDKIM: %s%s %s%s [failed key import]", + log_write(0, LOG_MAIN, "DKIM: %s%s %s%s [failed key import]", sig->domain ? "d=" : "", sig->domain ? sig->domain : US"", sig->selector ? "s=" : "", sig->selector ? sig->selector : US""); goto NEXT_VERIFY; @@ -1831,13 +1893,14 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) { sig->verify_status = PDKIM_VERIFY_PASS; verify_pass = TRUE; + if (dkim_verify_minimal) break; } NEXT_VERIFY: DEBUG(D_acl) { - debug_printf("PDKIM [%s] %s signature status: %s", + debug_printf("DKIM [%s] %s signature status: %s", sig->domain, dkim_sig_to_a_tag(sig), pdkim_verify_status_str(sig->verify_status)); if (sig->verify_ext_status > 0) @@ -1861,15 +1924,16 @@ return ctx->flags & PDKIM_MODE_SIGN || verify_pass /* -------------------------------------------------------------------------- */ DLLEXPORT pdkim_ctx * -pdkim_init_verify(uschar * (*dns_txt_callback)(uschar *), BOOL dot_stuffing) +pdkim_init_verify(uschar * (*dns_txt_callback)(const uschar *), BOOL dot_stuffing) { pdkim_ctx * ctx; -ctx = store_get(sizeof(pdkim_ctx)); +ctx = store_get(sizeof(pdkim_ctx), FALSE); memset(ctx, 0, sizeof(pdkim_ctx)); if (dot_stuffing) ctx->flags = PDKIM_DOT_TERM; -ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN); +/* The line-buffer is for message data, hence tainted */ +ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE); ctx->dns_txt_callback = dns_txt_callback; return ctx; @@ -1891,7 +1955,7 @@ if (!domain || !selector || !privkey) /* Allocate & init one signature struct */ -sig = store_get(sizeof(pdkim_signature)); +sig = store_get(sizeof(pdkim_signature), FALSE); memset(sig, 0, sizeof(pdkim_signature)); sig->bodylength = -1; @@ -1907,7 +1971,7 @@ for (hashtype = 0; hashtype < nelem(pdkim_hashes); hashtype++) if (hashtype >= nelem(pdkim_hashes)) { log_write(0, LOG_MAIN|LOG_PANIC, - "PDKIM: unrecognised hashname '%s'", hashname); + "DKIM: unrecognised hashname '%s'", hashname); return NULL; } @@ -1916,10 +1980,10 @@ DEBUG(D_acl) pdkim_signature s = *sig; ev_ctx vctx; - debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + debug_printf("DKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr)) debug_printf("WARNING: bad dkim key in dns\n"); - debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + debug_printf("DKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } return sig; } @@ -1965,19 +2029,21 @@ pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method, { pdkim_bodyhash * b; +if (hashtype == -1 || canon_method == -1) return NULL; + for (b = ctx->bodyhash; b; b = b->next) if ( hashtype == b->hashtype && canon_method == b->canon_method && bodylength == b->bodylength) { - DEBUG(D_receive) debug_printf("PDKIM: using existing bodyhash %d/%d/%ld\n", + DEBUG(D_receive) debug_printf("DKIM: using existing bodyhash %d/%d/%ld\n", hashtype, canon_method, bodylength); return b; } -DEBUG(D_receive) debug_printf("PDKIM: new bodyhash %d/%d/%ld\n", +DEBUG(D_receive) debug_printf("DKIM: new bodyhash %d/%d/%ld\n", hashtype, canon_method, bodylength); -b = store_get(sizeof(pdkim_bodyhash)); +b = store_get(sizeof(pdkim_bodyhash), FALSE); b->next = ctx->bodyhash; b->hashtype = hashtype; b->canon_method = canon_method; @@ -1986,7 +2052,7 @@ if (!exim_sha_init(&b->body_hash_ctx, /*XXX hash method: extend for sha512 */ pdkim_hashes[hashtype].exim_hashmethod)) { DEBUG(D_acl) - debug_printf("PDKIM: hash init error, possibly nonhandled hashtype\n"); + debug_printf("DKIM: hash init error, possibly nonhandled hashtype\n"); return NULL; } b->signed_body_bytes = 0; @@ -2017,11 +2083,12 @@ return b; void pdkim_init_context(pdkim_ctx * ctx, BOOL dot_stuffed, - uschar * (*dns_txt_callback)(uschar *)) + uschar * (*dns_txt_callback)(const uschar *)) { memset(ctx, 0, sizeof(pdkim_ctx)); ctx->flags = dot_stuffed ? PDKIM_MODE_SIGN | PDKIM_DOT_TERM : PDKIM_MODE_SIGN; -ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN); +/* The line buffer is for message data, hence tainted */ +ctx->linebuf = store_get(PDKIM_MAX_BODY_LINE_LEN, TRUE); DEBUG(D_acl) ctx->dns_txt_callback = dns_txt_callback; }