summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh@wizmail.org>2016-12-16 20:36:39 +0000
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2016-12-23 11:51:30 +0100
commit46672dc8be913fb02f0aa822d79c590fac276182 (patch)
tree6a3eca10660459f631c233e0514cbb3f5e992fdd
parent05b66bc5fbe44e744c3a56a8fada6841a2143976 (diff)
downloadexim4-46672dc8be913fb02f0aa822d79c590fac276182.tar.gz
Fix DKIM information leakage
(Cherry picked from exim-4_84_2..exim-4_84_2+CVE-2016-9963)
-rw-r--r--doc/doc-txt/cve-2016-966386
-rw-r--r--src/src/dkim.c1
-rw-r--r--src/src/transports/smtp.c4
-rw-r--r--test/confs/451071
-rw-r--r--test/log/451020
-rw-r--r--test/mail/4510.store58
-rwxr-xr-xtest/runtest16
-rw-r--r--test/scripts/4510-DKIM-Bounces/451015
-rw-r--r--test/scripts/4510-DKIM-Bounces/REQUIRES2
9 files changed, 272 insertions, 1 deletions
diff --git a/doc/doc-txt/cve-2016-9663 b/doc/doc-txt/cve-2016-9663
new file mode 100644
index 000000000..ae85a73cb
--- /dev/null
+++ b/doc/doc-txt/cve-2016-9663
@@ -0,0 +1,86 @@
+CVE ID: CVE-2016-9963
+Date: 2016-12-15
+Credits: Bjoern Jacke <bjoern@j3e.de>
+Version(s): 4.69 -> 4.87
+Issue: If several conditions are met, Exim leaks private information
+ to a remote attacker.
+
+Conditions
+==========
+
+If *all* of the following conditions are met
+
+ Build options
+ -------------
+
+ * Exim is built with DKIM enabled (default for newer versions)
+ exim -bV | grep 'Support.*DKIM'
+
+ Runtime options
+ ---------------
+
+ * Exim uses DKIM signing (transport options dkim_private_key,
+ dkim_domain, and other)
+
+ * The dkim_private_key option names a file containing the key.
+
+ exim -bP transports | grep 'dkim_private_key = .'
+
+ * Exim uses PRDR (transport option hosts_try_prdr) (default
+ since 4.86)
+
+ exim -bP transports | grep 'hosts_try_prdr = .'
+
+ *OR*
+
+ Exim uses the LMTP protocol variant for SMTP transport.
+
+ exim -bP transports | grep 'protocol = lmtp'
+
+ Operation
+ ---------
+
+ * Exim transports a multi-recipient message
+
+ * The destination host supports PRDR
+ OR
+ the message transport uses LMTP
+
+ * One or more recipients are rejected after the DATA phase
+
+Impact
+======
+
+Exim leaks the private DKIM signing key to the log files. Additionally,
+if the build option EXPERIMENTAL_DSN_INFO=yes is used, the key material
+is included in the bounce message.
+
+Fix
+===
+
+Install a fixed Exim version:
+
+ 4.88 (available soon)
+ 4.87.1 (available soon)
+
+If you can't install one of the above versions, ask your package
+maintainer for a version containing the backported fix. On request and
+depending on our resources we will support you in backporting the fix.
+(Please note, that Exim project officially doesn't support versions
+prior the current stable version.)
+
+Workaround
+==========
+
+Disable PRDR in your outgoing transport(s): set hosts_try_prdr to an
+empty string.
+
+AND do not use the LMTP protocol variant of the SMTP driver.
+
+Indication
+==========
+
+You can check if you where affected already. The mainlog entries look like this:
+
+2016-12-17 09:44:33 10HmaX-0005vi-00 ** baduser@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: PRDR error after -----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd\n+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+Y\ndhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB\nAoGAZPokJKQQmRK6a0zn5f8lWemy0airG66KhzDF0Pafb/nWKgDCB02gpJgdw5rJ\nbO7/HI3IeqsfRdYTP7tjfmZtPiPo1mnF7D1rSRspZjOF2yXY/ky7t7c5xChRcSxf\n+69CknwjrfteY9Aj0j6o7N+2w2uvHO+AAq8BHDgXKmPo0SECQQDzQ/glyhNH9tlO\nx+3TTMwwyZUf2mYYosN3Q9NIl3Umz/3+13K5b6Ed6fZvS/XwU55Qf5IBUVj2Fujk\nRv2lbGPpAkEA4okpnzYz5nm1X5WjpJPQPyo8nGEU1A5QfoDbkAvWYvVoYrpWPOx5\nHFpOAHkvSk1Y1vhCUa+zHwiQRBC8OMp6LwJBAOAUK/AjQ792UpWO9DM++pe2F/dP\nZdwrkYG6qFSlrvQhgwXLz5GgkfjMGoRKpDDL1XixCfzMwfVtBPnBqsNGJIECQGYX\nSIGu7L7edMXJ60C9OKluwHf9LGTQuqf4LHsDSq+4Rz3PGhREwePsMqD1/EDxEKt4\noHKtyvyeYF28aQbzARMCQQCRtJlR6vlKhxYL8+xoPrCu3MijKgVruRUcNstXkDZK\nfKQax6vhiMq+0qIiEwLA1wavyLVKZ7Mfag+/4NTcDUVC\n-----END RSA PRIVATE KEY-----\n: 550 PRDR R=<baduser@test.ex> refusal
+
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 05b5fec56..834ae84b8 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -514,6 +514,7 @@ uschar *dkim_exim_sign(int dkim_fd,
(char *)dkim_signing_selector,
(char *)dkim_private_key_expanded
);
+ dkim_private_key_expanded[0] = '\0';
pdkim_set_debug_stream(ctx,debug_file);
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index f9f225fca..01f17ca30 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -215,6 +215,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
static uschar *smtp_command; /* Points to last cmd for error messages */
static uschar *mail_command; /* Points to MAIL cmd for error messages */
static BOOL update_waiting; /* TRUE to update the "wait" database */
+static uschar *data_command = US""; /* Points to DATA cmd for error messages */
/*************************************************
@@ -1610,6 +1611,7 @@ if (ok || (smtp_use_pipelining && !mua_wrapper))
case -1: goto END_OFF; /* Timeout on RCPT */
default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */
}
+ data_command = string_copy(big_buffer); /* Save for later error message */
}
/* Save the first address of the next batch. */
@@ -1758,7 +1760,7 @@ if (!ok) ok = TRUE; else
{
if (errno != 0 || buffer[0] == 0) goto RESPONSE_FAILED;
addr->message = string_sprintf("LMTP error after %s: %s",
- big_buffer, string_printing(buffer));
+ data_command, string_printing(buffer));
setflag(addr, af_pass_message); /* Allow message to go to user */
if (buffer[0] == '5')
addr->transport_return = FAIL;
diff --git a/test/confs/4510 b/test/confs/4510
new file mode 100644
index 000000000..feab4c0b6
--- /dev/null
+++ b/test/confs/4510
@@ -0,0 +1,71 @@
+# Exim test configuration 4510
+
+SERVER=
+OPT=
+
+exim_path = EXIM_PATH
+keep_environment =
+host_lookup_order = bydns
+spool_directory = DIR/spool
+
+.ifdef SERVER
+log_file_path = DIR/spool/log/SERVER%slog
+.else
+log_file_path = DIR/spool/log/%slog
+.endif
+
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+
+primary_hostname = myhost.test.ex
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_dkim = accept logwrite = signer: $dkim_cur_signer bits: $dkim_key_length h=$dkim_headernames
+acl_smtp_data_prdr = accept local_parts = okuser
+
+prdr_enable
+
+# ----- Routers
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ transport = send_to_server
+
+server_dump:
+ driver = redirect
+ senders = ! :
+ data = :blackhole:
+
+server_store:
+ driver = accept
+ transport = store
+
+# ----- Transports
+
+begin transports
+
+store:
+ driver = appendfile
+ file = DIR/test-mail/store
+ return_path_add
+ user = CALLER
+
+send_to_server:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+
+ dkim_domain = ${if def:sender_address_local_part {test.ex}}
+ dkim_selector = sel
+ dkim_private_key = DIR/aux-fixed/dkim/dkim.private
+ dkim_sign_headers = From
+
+# End
diff --git a/test/log/4510 b/test/log/4510
new file mode 100644
index 000000000..0d826ab32
--- /dev/null
+++ b/test/log/4510
@@ -0,0 +1,20 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 ** baduser@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: PRDR error after DATA: 550 PRDR R=<baduser@test.ex> refusal
+1999-03-02 09:44:33 10HmaX-0005vi-00 => okuser@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] PRDR C="250 PRDR R=<okuser@test.ex> acceptance"
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER@myhost.test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmaZ-0005vi-00"
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmbA-0005vi-00 signer: test.ex bits: 1024 h=From
+1999-03-02 09:44:33 10HmbA-0005vi-00 PRDR R=<baduser@test.ex> refusal
+1999-03-02 09:44:33 10HmbA-0005vi-00 PRDR R=<okuser@test.ex> acceptance
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp PRDR S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <okuser@test.ex> R=server_dump
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => CALLER <CALLER@myhost.test.ex> R=server_store T=store
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
diff --git a/test/mail/4510.store b/test/mail/4510.store
new file mode 100644
index 000000000..d75e40906
--- /dev/null
+++ b/test/mail/4510.store
@@ -0,0 +1,58 @@
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Return-path: <>
+Received: from the.local.host.name ([ip4.ip4.ip4.ip4] helo=myhost.test.ex)
+ by myhost.test.ex with esmtp (Exim x.yz)
+ id 10HmaZ-0005vi-00
+ for CALLER@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+ id 10HmaY-0005vi-00
+ for CALLER@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: baduser@test.ex
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@myhost.test.ex>
+To: CALLER@myhost.test.ex
+Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+ baduser@test.ex
+ host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
+ PRDR error after DATA: 550 PRDR R=<baduser@test.ex> refusal
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/delivery-status
+
+Reporting-MTA: dns; myhost.test.ex
+
+Action: failed
+Final-Recipient: rfc822;baduser@test.ex
+Status: 5.0.0
+Diagnostic-Code: smtp; 550 PRDR R=<baduser@test.ex> refusal
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/rfc822
+
+Return-path: <CALLER@myhost.test.ex>
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmaX-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+From: nobody@example.com
+From: second@example.com
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+content
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM--
+
diff --git a/test/runtest b/test/runtest
index aa242d589..7a35e9587 100755
--- a/test/runtest
+++ b/test/runtest
@@ -321,6 +321,7 @@ open(IN, "$file") || tests_exit(-1, "Failed to open $file: $!");
my($is_log) = $file =~ /log/;
my($is_stdout) = $file =~ /stdout/;
my($is_stderr) = $file =~ /stderr/;
+my($is_mail) = $file =~ /mail/;
# Date pattern
@@ -980,6 +981,21 @@ RESET_AFTER_EXTRA_LINE_READ:
next;
}
+ # ======== log ========
+
+ elsif ($is_log)
+ {
+ # Berkeley DB version differences
+ next if / Berkeley DB error: /;
+ }
+
+ elsif ($is_mail)
+ {
+ # Experimental_DSN info in bounces
+ next if /^Remote-MTA: /;
+ next if /^X-Exim-Diagnostic: /;
+ }
+
# ======== All files other than stderr ========
print MUNGED;
diff --git a/test/scripts/4510-DKIM-Bounces/4510 b/test/scripts/4510-DKIM-Bounces/4510
new file mode 100644
index 000000000..531dbdafd
--- /dev/null
+++ b/test/scripts/4510-DKIM-Bounces/4510
@@ -0,0 +1,15 @@
+# DKIM signing and bounces
+#
+exim -bd -DSERVER=server -oX PORT_D
+****
+#
+# single header signed
+# one rcpt accept, one reject - should get a DSN
+exim -odf baduser@test.ex okuser@test.ex
+From: nobody@example.com
+From: second@example.com
+
+content
+****
+millisleep 500
+killdaemon
diff --git a/test/scripts/4510-DKIM-Bounces/REQUIRES b/test/scripts/4510-DKIM-Bounces/REQUIRES
new file mode 100644
index 000000000..a75b81c54
--- /dev/null
+++ b/test/scripts/4510-DKIM-Bounces/REQUIRES
@@ -0,0 +1,2 @@
+support DKIM
+support PRDR