X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/1cfe5c1c3f79de51039d47efd88620c3c325d2a6..584e96c65f12aca9414450b656504af6e3f7a399:/src/src/dkim.c diff --git a/src/src/dkim.c b/src/src/dkim.c index db2eb4948..a09ec7eca 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge, 1995 - 2015 */ +/* Copyright (c) University of Cambridge, 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Code for DKIM support. Other DKIM relevant code is in @@ -14,6 +14,7 @@ #include "pdkim/pdkim.h" +int dkim_verify_oldpool; pdkim_ctx *dkim_verify_ctx = NULL; pdkim_signature *dkim_signatures = NULL; pdkim_signature *dkim_cur_sig = NULL; @@ -59,9 +60,24 @@ return PDKIM_FAIL; } +void +dkim_exim_init(void) +{ +pdkim_init(); +} + + + void dkim_exim_verify_init(void) { +/* 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_verify_oldpool = store_pool; +store_pool = POOL_PERM; + /* Free previous context if there is one */ if (dkim_verify_ctx) @@ -69,19 +85,24 @@ if (dkim_verify_ctx) /* Create new context */ -dkim_verify_ctx = pdkim_init_verify(PDKIM_INPUT_SMTP, &dkim_exim_query_dns_txt); +dkim_verify_ctx = pdkim_init_verify(&dkim_exim_query_dns_txt); +dkim_collect_input = !!dkim_verify_ctx; -if ((dkim_collect_input = !!dkim_verify_ctx)) - pdkim_set_debug_stream(dkim_verify_ctx, debug_file); +/* Start feed up with any cached data */ +receive_get_cache(); + +store_pool = dkim_verify_oldpool; } void dkim_exim_verify_feed(uschar * data, int len) { +store_pool = POOL_PERM; if ( dkim_collect_input && pdkim_feed(dkim_verify_ctx, (char *)data, len) != PDKIM_OK) dkim_collect_input = FALSE; +store_pool = dkim_verify_oldpool; } @@ -93,6 +114,8 @@ int dkim_signers_size = 0; int dkim_signers_ptr = 0; dkim_signers = NULL; +store_pool = POOL_PERM; + /* Delete eventual previous signature chain */ dkim_signatures = NULL; @@ -107,7 +130,7 @@ if (!dkim_collect_input) "DKIM: Error while running this message through validation," " disabling signature verification."); dkim_disable_verify = TRUE; - return; + goto out; } dkim_collect_input = FALSE; @@ -115,7 +138,7 @@ dkim_collect_input = FALSE; /* Finish DKIM operation and fetch link to signatures chain */ if (pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures) != PDKIM_OK) - return; + goto out; for (sig = dkim_signatures; sig; sig = sig->next) { @@ -125,12 +148,16 @@ for (sig = dkim_signatures; sig; sig = sig->next) /* Log a line for each signature */ uschar *logmsg = string_append(NULL, &size, &ptr, 5, - string_sprintf("d=%s s=%s c=%s/%s a=%s ", + string_sprintf("d=%s s=%s c=%s/%s a=%s b=%d ", sig->domain, sig->selector, - sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", - sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", - sig->algo == PDKIM_ALGO_RSA_SHA256 ? "rsa-sha256" : "rsa-sha1"), + sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", + sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed", + sig->algo == PDKIM_ALGO_RSA_SHA256 + ? "rsa-sha256" + : sig->algo == PDKIM_ALGO_RSA_SHA1 ? "rsa-sha1" : "err", + (int)sig->sigdata.len > -1 ? sig->sigdata.len * 8 : 0 + ), sig->identity ? string_sprintf("i=%s ", sig->identity) : US"", sig->created > 0 ? string_sprintf("t=%lu ", sig->created) : US"", @@ -158,11 +185,22 @@ for (sig = dkim_signatures; sig; sig = sig->next) "overlong public key record]"); break; - case PDKIM_VERIFY_INVALID_PUBKEY_PARSING: + case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: + case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: logmsg = string_append(logmsg, &size, &ptr, 1, "syntax error in public key record]"); break; + case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: + logmsg = string_append(logmsg, &size, &ptr, 1, + "signature tag missing or invalid]"); + break; + + case PDKIM_VERIFY_INVALID_DKIM_VERSION: + logmsg = string_append(logmsg, &size, &ptr, 1, + "unsupported DKIM version]"); + break; + default: logmsg = string_append(logmsg, &size, &ptr, 1, "unspecified problem]"); @@ -220,6 +258,9 @@ if (dkim_signers) if (Ustrlen(dkim_signers) > 0) dkim_signers[Ustrlen(dkim_signers) - 1] = '\0'; } + +out: +store_pool = dkim_verify_oldpool; } @@ -229,7 +270,6 @@ dkim_exim_acl_setup(uschar * id) pdkim_signature * sig; uschar * cmp_val; - dkim_cur_sig = NULL; dkim_cur_signer = id; @@ -255,6 +295,7 @@ for (sig = dkim_signatures; sig; sig = sig->next) dkim_signing_domain = US sig->domain; dkim_signing_selector = US sig->selector; + dkim_key_length = sig->sigdata.len * 8; return; } } @@ -339,7 +380,7 @@ switch (what) case DKIM_HEADERNAMES: return dkim_cur_sig->headernames - ? US dkim_cur_sig->headernames : dkim_exim_expand_defaults(what); + ? dkim_cur_sig->headernames : dkim_exim_expand_defaults(what); case DKIM_IDENTITY: return dkim_cur_sig->identity @@ -395,7 +436,8 @@ switch (what) { case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return US"pubkey_unavailable"; - case PDKIM_VERIFY_INVALID_PUBKEY_PARSING: return US"pubkey_syntax"; + case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD:return US"pubkey_dns_syntax"; + case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return US"pubkey_der_syntax"; case PDKIM_VERIFY_FAIL_BODY: return US"bodyhash_mismatch"; case PDKIM_VERIFY_FAIL_MESSAGE: return US"signature_incorrect"; } @@ -561,16 +603,15 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, dkim_private_key_expanded = big_buffer; } - ctx = pdkim_init_sign(PDKIM_INPUT_SMTP, - (char *) dkim_signing_domain, + ctx = pdkim_init_sign( (char *) dkim_signing_domain, (char *) dkim_signing_selector, - (char *) dkim_private_key_expanded); - pdkim_set_debug_stream(ctx, debug_file); + (char *) dkim_private_key_expanded, + PDKIM_ALGO_RSA_SHA256); pdkim_set_optional(ctx, (char *) dkim_sign_headers_expanded, NULL, pdkim_canon, - pdkim_canon, -1, PDKIM_ALGO_RSA_SHA256, 0, 0); + pdkim_canon, -1, 0, 0); lseek(dkim_fd, 0, SEEK_SET);