From b895f4b20b25f81cd6f94be75881d3328df03892 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 21 Jan 2017 18:54:56 +0000 Subject: [PATCH] Fix DKIM verify operation in -bh test mode. Bug 2017 --- doc/doc-txt/ChangeLog | 3 ++ src/src/pdkim/pdkim.c | 69 ++++++++++++++++++++++-------------- src/src/pdkim/pdkim.h | 5 +-- test/confs/4507 | 1 + test/scripts/0000-Basic/0021 | 1 + test/scripts/0000-Basic/0022 | 11 ++++++ test/scripts/0000-Basic/0303 | 2 ++ test/scripts/0000-Basic/0371 | 1 + test/scripts/0000-Basic/0386 | 2 ++ test/scripts/0000-Basic/0575 | 1 + test/scripts/4500-DKIM/4507 | 30 ++++++++++++++++ test/stderr/0021 | 1 - test/stderr/0022 | 3 -- test/stderr/0386 | 2 -- test/stderr/0575 | 1 - test/stderr/4507 | 22 ++++++++++++ test/stdout/0022 | 4 +++ test/stdout/0904 | 4 +-- 18 files changed, 125 insertions(+), 38 deletions(-) create mode 120000 test/confs/4507 create mode 100644 test/scripts/4500-DKIM/4507 create mode 100644 test/stderr/4507 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 67a1bf476..f501eb433 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -28,6 +28,9 @@ PP/02 GitHub PR 52: many spelling fixes, which include fixing parsing of no_require_dnssec option and creation of _HAVE_TRANSPORT_APPEND_MAILDIR macro. Patches provided by Josh Soref. +JH/05 Bug 2017: Fix DKIM verification in -bh test mode. The data feed into + the dkim code may be unix-mode line endings rather than smtp wire-format + CRLF, so prepend a CR to any bare LF. Exim version 4.88 ----------------- diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 58838c2ef..1953c4bd6 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -876,7 +876,7 @@ ctx->linebuf[ctx->linebuf_offset] = '\0'; /* Terminate on EOD marker */ if (ctx->flags & PDKIM_DOT_TERM) { - if ( memcmp(p, ".\r\n", 3) == 0) + if (memcmp(p, ".\r\n", 3) == 0) return pdkim_body_complete(ctx); /* Unstuff dots */ @@ -1017,45 +1017,60 @@ else for (p = 0; pflags & PDKIM_PAST_HDRS) { + if (c == '\n' && !(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */ + { + ctx->linebuf[ctx->linebuf_offset++] = '\r'; + if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1) + return PDKIM_ERR_LONG_LINE; + } + /* Processing body byte */ ctx->linebuf[ctx->linebuf_offset++] = c; - if (c == '\n') + if (c == '\r') + ctx->flags |= PDKIM_SEEN_CR; + else if (c == '\n') { - int rc = pdkim_bodyline_complete(ctx); /* End of line */ - if (rc != PDKIM_OK) return rc; + int rc; + ctx->flags &= ~PDKIM_SEEN_CR; + if ((rc = pdkim_bodyline_complete(ctx)) != PDKIM_OK) + return rc; } - if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1)) + + if (ctx->linebuf_offset == PDKIM_MAX_BODY_LINE_LEN-1) return PDKIM_ERR_LONG_LINE; } else { /* Processing header byte */ - if (c != '\r') + if (c == '\r') + ctx->flags |= PDKIM_SEEN_CR; + else if (c == '\n') { - if (c == '\n') - { - if (ctx->flags & PDKIM_SEEN_LF) - { - int rc = pdkim_header_complete(ctx); /* Seen last header line */ - if (rc != PDKIM_OK) return rc; + if (!(ctx->flags & PDKIM_SEEN_CR)) /* emulate the CR */ + ctx->cur_header = string_catn(ctx->cur_header, &ctx->cur_header_size, + &ctx->cur_header_len, CUS "\r", 1); - ctx->flags = ctx->flags & ~PDKIM_SEEN_LF | PDKIM_PAST_HDRS; - DEBUG(D_acl) debug_printf( - "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n"); - continue; - } - else - ctx->flags |= PDKIM_SEEN_LF; + if (ctx->flags & PDKIM_SEEN_LF) + { + int rc = pdkim_header_complete(ctx); /* Seen last header line */ + if (rc != PDKIM_OK) return rc; + + ctx->flags = ctx->flags & ~(PDKIM_SEEN_LF|PDKIM_SEEN_CR) | PDKIM_PAST_HDRS; + DEBUG(D_acl) debug_printf( + "PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>>\n"); + continue; } - else if (ctx->flags & PDKIM_SEEN_LF) - { - if (!(c == '\t' || c == ' ')) - { - int rc = pdkim_header_complete(ctx); /* End of header */ - if (rc != PDKIM_OK) return rc; - } - ctx->flags &= ~PDKIM_SEEN_LF; + else + ctx->flags = ctx->flags & ~PDKIM_SEEN_CR | PDKIM_SEEN_LF; + } + else if (ctx->flags & PDKIM_SEEN_LF) + { + if (!(c == '\t' || c == ' ')) + { + int rc = pdkim_header_complete(ctx); /* End of header */ + if (rc != PDKIM_OK) return rc; } + ctx->flags &= ~PDKIM_SEEN_LF; } if (ctx->cur_header_len < PDKIM_MAX_HEADER_LEN) diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index c1c8c262e..65138b00b 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -250,9 +250,10 @@ typedef struct pdkim_ctx { #define PDKIM_MODE_SIGN BIT(0) /* if unset, mode==verify */ #define PDKIM_DOT_TERM BIT(1) /* dot termination and unstuffing */ -#define PDKIM_SEEN_LF BIT(2) -#define PDKIM_SEEN_EOD BIT(3) +#define PDKIM_SEEN_CR BIT(2) +#define PDKIM_SEEN_LF BIT(3) #define PDKIM_PAST_HDRS BIT(4) +#define PDKIM_SEEN_EOD BIT(5) unsigned flags; /* One (signing) or several chained (verification) signatures */ diff --git a/test/confs/4507 b/test/confs/4507 new file mode 120000 index 000000000..c4f73bacd --- /dev/null +++ b/test/confs/4507 @@ -0,0 +1 @@ +4500 \ No newline at end of file diff --git a/test/scripts/0000-Basic/0021 b/test/scripts/0000-Basic/0021 index 16c5c3b80..0df1f0ae6 100644 --- a/test/scripts/0000-Basic/0021 +++ b/test/scripts/0000-Basic/0021 @@ -46,6 +46,7 @@ exim -d-all+acl+lists -odi -bs -oMa 10.9.8.8 mail from: rcpt to: data + Some message . quit diff --git a/test/scripts/0000-Basic/0022 b/test/scripts/0000-Basic/0022 index 92d955171..dd11aa236 100644 --- a/test/scripts/0000-Basic/0022 +++ b/test/scripts/0000-Basic/0022 @@ -3,6 +3,7 @@ exim -d -bh V4NET.9.8.7 mail from: rcpt to: data + Testing . quit @@ -11,6 +12,7 @@ exim -d -bh V4NET.9.8.7 mail from: rcpt to: data + Testing . quit @@ -19,6 +21,7 @@ exim -d -bh V4NET.9.8.7 mail from: rcpt to: data + Testing . quit @@ -55,22 +58,26 @@ mail from: rcpt to: rcpt to: data + Testing . mail from: rcpt to: data + Testing 2 . mail from: rcpt to: rcpt to: data + Testing 3 . mail from: rcpt to: data + Testing 4 . quit @@ -101,6 +108,7 @@ rcpt to: ??? 250 data ??? 354 + Testing . ??? 250 @@ -110,6 +118,7 @@ rcpt to: ??? 250 data ??? 354 + Testing 2 . ??? 250 @@ -121,6 +130,7 @@ rcpt to: ??? 250 data ??? 354 + Testing 3 . ??? 250 @@ -130,6 +140,7 @@ rcpt to: ??? 250 data ??? 354 + Testing 4 . ??? 250 diff --git a/test/scripts/0000-Basic/0303 b/test/scripts/0000-Basic/0303 index 854206e4a..16e80c866 100644 --- a/test/scripts/0000-Basic/0303 +++ b/test/scripts/0000-Basic/0303 @@ -16,6 +16,7 @@ EHLO [V4NET.2.3.4] mail from:<> rcpt to: data + . quit **** @@ -24,6 +25,7 @@ EHLO [V4NET.2.3.4] mail from:<> rcpt to: data + . quit **** diff --git a/test/scripts/0000-Basic/0371 b/test/scripts/0000-Basic/0371 index 2850fc12f..6dc0bca77 100644 --- a/test/scripts/0000-Basic/0371 +++ b/test/scripts/0000-Basic/0371 @@ -4,6 +4,7 @@ ehlo something mail from: rcpt to: data + . vrfy x@y mail from: diff --git a/test/scripts/0000-Basic/0386 b/test/scripts/0000-Basic/0386 index 172c8b79a..7adc4fbeb 100644 --- a/test/scripts/0000-Basic/0386 +++ b/test/scripts/0000-Basic/0386 @@ -11,12 +11,14 @@ exim -d -odi -bs -oMa V4NET.11.12.13 userx mail from: rcpt to:<2@b> data + Message 1 . rset mail from: rcpt to:<2@b> data + Message 2 . quit diff --git a/test/scripts/0000-Basic/0575 b/test/scripts/0000-Basic/0575 index e4534af9b..302b67f4f 100644 --- a/test/scripts/0000-Basic/0575 +++ b/test/scripts/0000-Basic/0575 @@ -4,6 +4,7 @@ exim -d -bh V4NET.0.0.0 mail from: rcpt to: data + Message. . quit diff --git a/test/scripts/4500-DKIM/4507 b/test/scripts/4500-DKIM/4507 new file mode 100644 index 000000000..6a4121fe1 --- /dev/null +++ b/test/scripts/4500-DKIM/4507 @@ -0,0 +1,30 @@ +# DKIM verify, -bh test mode +# +# +# This should pass. +# - sha1, 1024b +# Mail original in aux-fixed/4500.msg1.txt +# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt +exim -DSERVER=server -DNOTDAEMON -bh 127.0.0.1 +HELO xxx +MAIL FROM: +RCPT TO: +DATA +DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to + :date:message-id:subject; s=sel; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b= + PeUA8iBGfStWv+9/BBKkvCEYj/AVMl4e9k+AqWOXKyuEUfHxqAnV+sPnOejpmvT8 + 41kuM4u0bICvK371YvB/yO61vtliRhyqU76Y2e55p2uvMADb3UyDhLyzpco4+yBo + 1w0AuIxu0VU4TK8UmOLyCw/1hxrh1DcEInbEMEKJ7kI= +From: mrgus@text.ex +To: bakawolf@yahoo.com +Date: Thu, 19 Nov 2015 17:00:07 -0700 +Message-ID: +Subject: simple test + +This is a simple test. +. +QUIT +**** +# +no_stdout_check +no_msglog_check diff --git a/test/stderr/0021 b/test/stderr/0021 index 43331d4aa..7c5a79ee9 100644 --- a/test/stderr/0021 +++ b/test/stderr/0021 @@ -178,7 +178,6 @@ LOG: PANIC rcpt accepted accept: condition test succeeded in ACL "rcpt" end of ACL "rcpt": ACCEPT -host in ignore_fromline_hosts? no (option unset) >>Headers added by MAIL or RCPT ACL: X-ACL-Warn: added header line >> diff --git a/test/stderr/0022 b/test/stderr/0022 index 75c282029..bcafb8589 100644 --- a/test/stderr/0022 +++ b/test/stderr/0022 @@ -41,7 +41,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called @@ -113,7 +112,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called @@ -183,7 +181,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called diff --git a/test/stderr/0386 b/test/stderr/0386 index 00094863b..44e856da2 100644 --- a/test/stderr/0386 +++ b/test/stderr/0386 @@ -191,7 +191,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called @@ -373,7 +372,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called diff --git a/test/stderr/0575 b/test/stderr/0575 index 86620a896..210f868ad 100644 --- a/test/stderr/0575 +++ b/test/stderr/0575 @@ -35,7 +35,6 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called -host in ignore_fromline_hosts? no (option unset) >>Headers received: search_tidyup called diff --git a/test/stderr/4507 b/test/stderr/4507 new file mode 100644 index 000000000..1df9537ea --- /dev/null +++ b/test/stderr/4507 @@ -0,0 +1,22 @@ + +******** SERVER ******** +>>> host in hosts_connection_nolog? no (option unset) +>>> host in host_lookup? no (option unset) +>>> host in host_reject_connection? no (option unset) +>>> host in sender_unqualified_hosts? no (option unset) +>>> host in recipient_unqualified_hosts? no (option unset) +>>> host in helo_verify_hosts? no (option unset) +>>> host in helo_try_verify_hosts? no (option unset) +>>> host in helo_accept_junk_hosts? no (option unset) +>>> xxx in helo_lookup_domains? no (end of list) +>>> processing "accept" +>>> accept: condition test succeeded in inline ACL +>>> end of inline ACL: ACCEPT +>>> host in ignore_fromline_hosts? no (option unset) +LOG: 10HmaX-0005vi-00 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded] +>>> processing "accept" +>>> check logwrite = signer: test.ex bits: 1024 +LOG: 10HmaX-0005vi-00 signer: test.ex bits: 1024 +>>> accept: condition test succeeded in inline ACL +>>> end of inline ACL: ACCEPT +LOG: 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net diff --git a/test/stdout/0022 b/test/stdout/0022 index 5a8c879dd..6dba84034 100644 --- a/test/stdout/0022 +++ b/test/stdout/0022 @@ -140,6 +140,7 @@ Connecting to 127.0.0.1 port 1225 ... connected >>> data ??? 354 <<< 354 Enter message, ending with "." on a line by itself +>>> >>> Testing >>> . ??? 250 @@ -153,6 +154,7 @@ Connecting to 127.0.0.1 port 1225 ... connected >>> data ??? 354 <<< 354 Enter message, ending with "." on a line by itself +>>> >>> Testing 2 >>> . ??? 250 @@ -169,6 +171,7 @@ Connecting to 127.0.0.1 port 1225 ... connected >>> data ??? 354 <<< 354 Enter message, ending with "." on a line by itself +>>> >>> Testing 3 >>> . ??? 250 @@ -182,6 +185,7 @@ Connecting to 127.0.0.1 port 1225 ... connected >>> data ??? 354 <<< 354 Enter message, ending with "." on a line by itself +>>> >>> Testing 4 >>> . ??? 250 diff --git a/test/stdout/0904 b/test/stdout/0904 index a19787d12..dc6209432 100644 --- a/test/stdout/0904 +++ b/test/stdout/0904 @@ -27,7 +27,7 @@ MAIL FROM:<> RCPT TO: 250 acceptable rcpt cmd BDAT 329 LAST -Unxpected EOF read from client +Unexpected EOF read from client Listening on port 1224 ... Connection request from [127.0.0.1] 220 Greetings @@ -100,7 +100,7 @@ EHLO testhost.test.ex MAIL FROM:<> RCPT TO: BDAT 329 LAST -Unxpected EOF read from client +Unexpected EOF read from client Listening on port 1224 ... Connection request from [127.0.0.1] 220 Greetings -- 2.30.2