* 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
#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;
}
+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)
dkim_verify_ctx = pdkim_init_verify(&dkim_exim_query_dns_txt);
dkim_collect_input = !!dkim_verify_ctx;
+
+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;
}
int dkim_signers_ptr = 0;
dkim_signers = NULL;
+store_pool = POOL_PERM;
+
/* Delete eventual previous signature chain */
dkim_signatures = NULL;
"DKIM: Error while running this message through validation,"
" disabling signature verification.");
dkim_disable_verify = TRUE;
- return;
+ goto out;
}
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)
{
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->sigdata_len * 8
+ 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"",
"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]");
if (Ustrlen(dkim_signers) > 0)
dkim_signers[Ustrlen(dkim_signers) - 1] = '\0';
}
+
+out:
+store_pool = dkim_verify_oldpool;
}
dkim_signing_domain = US sig->domain;
dkim_signing_selector = US sig->selector;
- dkim_key_length = sig->sigdata_len * 8;
+ dkim_key_length = sig->sigdata.len * 8;
return;
}
}
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
{
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";
}