From: Jeremy Harris Date: Fri, 16 Dec 2016 20:45:44 +0000 (+0000) Subject: Fix DKIM information leakage X-Git-Tag: exim-4_88~1 X-Git-Url: https://git.exim.org/users/jgh/exim.git/commitdiff_plain/87cb4a166c47b57df48c2918e47801d77639fbb0 Fix DKIM information leakage --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 0598eccc8..5324be398 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -38273,6 +38273,7 @@ These options take (expandable) strings as arguments. MANDATORY: The domain you want to sign with. The result of this expanded option is put into the &%$dkim_domain%& expansion variable. +If it is empty after expansion, DKIM signing is not done. .option dkim_selector smtp string&!! unset MANDATORY: diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 156413fcd..926a36dc1 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -143,6 +143,10 @@ HS/02 Bug 1802: Do not half-close the connection after sending a request HS/03 Use "auto" as the default EC curve parameter. For OpenSSL < 1.0.2 fallback to "prime256v1". +JH/34 SECURITY: Use proper copy of DATA command in error message. + Could leak key material. Remotely explaoitable. CVE-2016-9963. + + Exim version 4.87 ----------------- JH/01 Bug 1664: Disable OCSP for GnuTLS library versions at/before 3.3.16 diff --git a/src/src/dkim.c b/src/src/dkim.c index 3fa11c800..70c9547ec 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -612,6 +612,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, CS dkim_private_key_expanded, PDKIM_ALGO_RSA_SHA256, dkim->dot_stuffed); + dkim_private_key_expanded[0] = '\0'; pdkim_set_optional(ctx, CS dkim_sign_headers_expanded, NULL, diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index d6ef34eff..a19e85ffb 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -285,10 +285,11 @@ static uschar *rf_names[] = { US"NEVER", US"SUCCESS", US"FAILURE", US"DELAY" }; /* Local statics */ -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 BOOL pipelining_active; /* current transaction is in pipe mode */ +static uschar *smtp_command; /* Points to last cmd for error messages */ +static uschar *mail_command; /* Points to MAIL cmd for error messages */ +static uschar *data_command = US""; /* Points to DATA cmd for error messages */ +static BOOL update_waiting; /* TRUE to update the "wait" database */ +static BOOL pipelining_active; /* current transaction is in pipe mode */ /************************************************* @@ -1390,10 +1391,14 @@ uschar * buffer = tctx->buffer; /* Write SMTP chunk header command */ if (chunk_size > 0) + { if((cmd_count = smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n", chunk_size, flags & tc_chunk_last ? " LAST" : "") ) < 0) return ERROR; + if (flags & tc_chunk_last) + data_command = string_copy(big_buffer); /* Save for later error message */ + } prev_cmd_count = cmd_count += tctx->cmd_count; @@ -2512,6 +2517,7 @@ if ( !(peer_offered & PEER_OFFERED_CHUNKING) default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */ } pipelining_active = FALSE; + data_command = string_copy(big_buffer); /* Save for later error message */ } /* If there were no good recipients (but otherwise there have been no @@ -2735,7 +2741,7 @@ else #else "LMTP error after %s: %s", #endif - 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..42c58aac5 --- /dev/null +++ b/test/confs/4510 @@ -0,0 +1,57 @@ +# Exim test configuration 4510 + +SERVER= +OPT= + +.include DIR/aux-var/std_conf_prefix + +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= 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= 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= refusal +1999-03-02 09:44:33 10HmbA-0005vi-00 PRDR R= 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: 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 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 +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: +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= 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= refusal + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM +Content-type: message/rfc822 + +Return-path: +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000 +From: nobody@example.com +From: second@example.com +Message-Id: +Sender: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +content + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM-- + diff --git a/test/runtest b/test/runtest index c656cc50b..6b5a3e9d9 100755 --- a/test/runtest +++ b/test/runtest @@ -358,6 +358,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 @@ -1140,6 +1141,13 @@ RESET_AFTER_EXTRA_LINE_READ: 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