git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
DANE: Fix 2 messages from queue case
[exim.git]
/
src
/
src
/
dkim.c
diff --git
a/src/src/dkim.c
b/src/src/dkim.c
index a410ed55bbcbfe2734b12493c784bc0c67429f8f..92adb35897665f650653de3622c639f72800361f 100644
(file)
--- a/
src/src/dkim.c
+++ b/
src/src/dkim.c
@@
-3,6
+3,7
@@
*************************************************/
/* Copyright (c) University of Cambridge, 1995 - 2018 */
*************************************************/
/* Copyright (c) University of Cambridge, 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for DKIM support. Other DKIM relevant code is in
/* See the file NOTICE for conditions of use and distribution. */
/* Code for DKIM support. Other DKIM relevant code is in
@@
-21,6
+22,7
@@
void
params_dkim(void)
{
builtin_macro_create_var(US"_DKIM_SIGN_HEADERS", US PDKIM_DEFAULT_SIGN_HEADERS);
params_dkim(void)
{
builtin_macro_create_var(US"_DKIM_SIGN_HEADERS", US PDKIM_DEFAULT_SIGN_HEADERS);
+builtin_macro_create_var(US"_DKIM_OVERSIGN_HEADERS", US PDKIM_OVERSIGN_HEADERS);
}
# else /*!MACRO_PREDEF*/
}
# else /*!MACRO_PREDEF*/
@@
-37,29
+39,28
@@
static const uschar * dkim_collect_error = NULL;
-/*XXX the caller only uses the first record if we return multiple.
+/* Look up the DKIM record in DNS for the given hostname.
+Will use the first found if there are multiple.
+The return string is tainted, having come from off-site.
*/
uschar *
*/
uschar *
-dkim_exim_query_dns_txt(uschar * name)
+dkim_exim_query_dns_txt(
const
uschar * name)
{
{
-/*XXX need to always alloc the dnsa, from tainted mem.
-Then, we hope, the answers will be tainted */
-
-dns_answer dnsa;
+dns_answer * dnsa = store_get_dns_answer();
dns_scan dnss;
rmark reset_point = store_mark();
gstring * g = NULL;
lookup_dnssec_authenticated = NULL;
dns_scan dnss;
rmark reset_point = store_mark();
gstring * g = NULL;
lookup_dnssec_authenticated = NULL;
-if (dns_lookup(
&
dnsa, name, T_TXT, NULL) != DNS_SUCCEED)
+if (dns_lookup(dnsa, name, T_TXT, NULL) != DNS_SUCCEED)
return NULL; /*XXX better error detail? logging? */
/* Search for TXT record */
return NULL; /*XXX better error detail? logging? */
/* Search for TXT record */
-for (dns_record * rr = dns_next_rr(
&
dnsa, &dnss, RESET_ANSWERS);
+for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
rr;
rr;
- rr = dns_next_rr(
&
dnsa, &dnss, RESET_NEXT))
+ rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
if (rr->type == T_TXT)
{
int rr_offset = 0;
if (rr->type == T_TXT)
{
int rr_offset = 0;
@@
-96,6
+97,8
@@
return NULL; /*XXX better error detail? logging? */
void
dkim_exim_init(void)
{
void
dkim_exim_init(void)
{
+if (f.dkim_init_done) return;
+f.dkim_init_done = TRUE;
pdkim_init();
}
pdkim_init();
}
@@
-104,6
+107,8
@@
pdkim_init();
void
dkim_exim_verify_init(BOOL dot_stuffing)
{
void
dkim_exim_verify_init(BOOL dot_stuffing)
{
+dkim_exim_init();
+
/* 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. */
/* 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. */
@@
-264,6
+269,11
@@
else
"(headers probably modified in transit)]");
break;
"(headers probably modified in transit)]");
break;
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE:
+ logmsg = string_cat(logmsg,
+ US"signature invalid (key too short)]");
+ break;
+
default:
logmsg = string_cat(logmsg, US"unspecified reason]");
}
default:
logmsg = string_cat(logmsg, US"unspecified reason]");
}
@@
-402,7
+412,7
@@
for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
dkim_cur_sig = sig;
dkim_signing_domain = US sig->domain;
dkim_signing_selector = US sig->selector;
dkim_cur_sig = sig;
dkim_signing_domain = US sig->domain;
dkim_signing_selector = US sig->selector;
- dkim_key_length = sig->
sighash.len * 8
;
+ dkim_key_length = sig->
keybits
;
/* These two return static strings, so we can compare the addr
later to see if the ACL overwrote them. Check that when logging */
/* These two return static strings, so we can compare the addr
later to see if the ACL overwrote them. Check that when logging */
@@
-556,6
+566,7
@@
switch (what)
return US"pubkey_unavailable";
case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD:return US"pubkey_dns_syntax";
case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return US"pubkey_der_syntax";
return US"pubkey_unavailable";
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_INVALID_PUBKEY_KEYSIZE: return US"pubkey_too_short";
case PDKIM_VERIFY_FAIL_BODY: return US"bodyhash_mismatch";
case PDKIM_VERIFY_FAIL_MESSAGE: return US"signature_incorrect";
}
case PDKIM_VERIFY_FAIL_BODY: return US"bodyhash_mismatch";
case PDKIM_VERIFY_FAIL_MESSAGE: return US"signature_incorrect";
}
@@
-570,6
+581,8
@@
void
dkim_exim_sign_init(void)
{
int old_pool = store_pool;
dkim_exim_sign_init(void)
{
int old_pool = store_pool;
+
+dkim_exim_init();
store_pool = POOL_MAIN;
pdkim_init_context(&dkim_sign_ctx, FALSE, &dkim_exim_query_dns_txt);
store_pool = old_pool;
store_pool = POOL_MAIN;
pdkim_init_context(&dkim_sign_ctx, FALSE, &dkim_exim_query_dns_txt);
store_pool = old_pool;
@@
-784,14
+797,15
@@
CLEANUP:
pk_bad:
log_write(0, LOG_MAIN|LOG_PANIC,
pk_bad:
log_write(0, LOG_MAIN|LOG_PANIC,
- "DKIM: signing failed: %.100s", pdkim_errstr(pdkim_rc));
+ "DKIM: signing failed: %.100s", pdkim_errstr(pdkim_rc));
bad:
sigbuf = NULL;
goto CLEANUP;
expand_bad:
bad:
sigbuf = NULL;
goto CLEANUP;
expand_bad:
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand %s: %s",
- errwhen, expand_string_message);
+ *errstr = string_sprintf("failed to expand %s: %s",
+ errwhen, expand_string_message);
+ log_write(0, LOG_MAIN | LOG_PANIC, "%s", *errstr);
goto bad;
}
goto bad;
}
@@
-847,6
+861,9
@@
for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
g = string_cat(g,
US"fail (signature did not verify; headers probably modified in transit)\n\t\t");
break;
g = string_cat(g,
US"fail (signature did not verify; headers probably modified in transit)\n\t\t");
break;
+ case PDKIM_VERIFY_INVALID_PUBKEY_KEYSIZE: /* should this really be "polcy"? */
+ g = string_fmt_append(g, "fail (public key too short: %u bits)\n\t\t", sig->keybits);
+ break;
default:
g = string_cat(g, US"fail (unspecified reason)\n\t\t");
break;
default:
g = string_cat(g, US"fail (unspecified reason)\n\t\t");
break;