Fix DKIM verify operation in -bh test mode. Bug 2017
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 21 Jan 2017 18:54:56 +0000 (18:54 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 21 Jan 2017 20:11:58 +0000 (20:11 +0000)
18 files changed:
doc/doc-txt/ChangeLog
src/src/pdkim/pdkim.c
src/src/pdkim/pdkim.h
test/confs/4507 [new symlink]
test/scripts/0000-Basic/0021
test/scripts/0000-Basic/0022
test/scripts/0000-Basic/0303
test/scripts/0000-Basic/0371
test/scripts/0000-Basic/0386
test/scripts/0000-Basic/0575
test/scripts/4500-DKIM/4507 [new file with mode: 0644]
test/stderr/0021
test/stderr/0022
test/stderr/0386
test/stderr/0575
test/stderr/4507 [new file with mode: 0644]
test/stdout/0022
test/stdout/0904

index 67a1bf476a68304acb0fdea4ccf9c8a0befc44d8..f501eb433cf6e749039c947d15e4498cca87b3ac 100644 (file)
@@ -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
 -----------------
index 58838c2ef0b5ac994c6a31ce936f20e3eca0a6d9..1953c4bd68f4437511e1d3393d0cccb22486409d 100644 (file)
@@ -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; p<len; p++)
 
   if (ctx->flags & 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)
index c1c8c262e6e89c73a3cc35a70abe00e7f179623a..65138b00b855842c3e71b781361ce50ecaa59334 100644 (file)
@@ -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 (symlink)
index 0000000..c4f73ba
--- /dev/null
@@ -0,0 +1 @@
+4500
\ No newline at end of file
index 16c5c3b80d270612b81a5d4dd8910cfba7c1b241..0df1f0ae6a80a7fa8965aac18ad7a17582e09aef 100644 (file)
@@ -46,6 +46,7 @@ exim -d-all+acl+lists -odi -bs -oMa 10.9.8.8
 mail from:<ok@test3>
 rcpt to:<x@y>
 data
+
 Some message
 .
 quit
index 92d95517116fef48f4f9ed7943d44368e3cc34ef..dd11aa23687b37abe24eb9c03f4fc50baeff465a 100644 (file)
@@ -3,6 +3,7 @@ exim -d -bh V4NET.9.8.7
 mail from:<x@y>
 rcpt to:<warn_empty@test.ex>
 data
+
 Testing
 .
 quit
@@ -11,6 +12,7 @@ exim -d -bh V4NET.9.8.7
 mail from:<x@y>
 rcpt to:<warn_log@test.ex>
 data
+
 Testing
 .
 quit
@@ -19,6 +21,7 @@ exim -d -bh V4NET.9.8.7
 mail from:<x@y>
 rcpt to:<warn_user@test.ex>
 data
+
 Testing
 .
 quit
@@ -55,22 +58,26 @@ mail from:<x@y>
 rcpt to:<accept@y>
 rcpt to:<freeze@y>
 data
+
 Testing
 .
 mail from:<x@y>
 rcpt to:<accept@y>
 data
+
 Testing 2
 .
 mail from:<x@y>
 rcpt to:<queue_only@y>
 rcpt to:<accept@y>
 data
+
 Testing 3
 .
 mail from:<x@y>
 rcpt to:<accept@y>
 data
+
 Testing 4
 .
 quit
@@ -101,6 +108,7 @@ rcpt to:<freeze@y>
 ??? 250
 data
 ??? 354
+
 Testing
 .
 ??? 250
@@ -110,6 +118,7 @@ rcpt to:<accept@y>
 ??? 250
 data
 ??? 354
+
 Testing 2
 .
 ??? 250
@@ -121,6 +130,7 @@ rcpt to:<accept@y>
 ??? 250
 data
 ??? 354
+
 Testing 3
 .
 ??? 250
@@ -130,6 +140,7 @@ rcpt to:<accept@y>
 ??? 250
 data
 ??? 354
+
 Testing 4
 .
 ??? 250
index 854206e4ad02d63c30607aefa1adb0b386448874..16e80c86673bfbd3575b482fe1571438e7a55272 100644 (file)
@@ -16,6 +16,7 @@ EHLO [V4NET.2.3.4]
 mail from:<>
 rcpt to:<x@y>
 data
+
 .
 quit
 ****
@@ -24,6 +25,7 @@ EHLO [V4NET.2.3.4]
 mail from:<>
 rcpt to:<x@y>
 data
+
 .
 quit
 ****
index 2850fc12f9cffb7692f1539a1d30521f1d6d630d..6dc0bca77e7d2092e5bae003dbabed7cb6063c4f 100644 (file)
@@ -4,6 +4,7 @@ ehlo something
 mail from:<x@y>
 rcpt to:<x@y>
 data
+
 .
 vrfy x@y
 mail from:<x@y>
index 172c8b79ac40718918083c48d72b486b0f1515c1..7adc4fbebe1a95cd048b3de28c4308a625fee729 100644 (file)
@@ -11,12 +11,14 @@ exim -d -odi -bs -oMa V4NET.11.12.13 userx
 mail from:<x@y>
 rcpt to:<2@b>
 data
+
 Message 1
 .
 rset
 mail from:<x@y>
 rcpt to:<2@b>
 data
+
 Message 2
 .
 quit
index e4534af9b25b424e417fb03ac0901ad70b7f8efb..302b67f4fd690a9dd956c6a1949acef613c5a61c 100644 (file)
@@ -4,6 +4,7 @@ exim -d -bh V4NET.0.0.0
 mail from:<x@y>
 rcpt to:<x@y>
 data
+
 Message.
 .
 quit
diff --git a/test/scripts/4500-DKIM/4507 b/test/scripts/4500-DKIM/4507
new file mode 100644 (file)
index 0000000..6a4121f
--- /dev/null
@@ -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:<CALLER@bloggs.com>
+RCPT TO:<a@test.ex>
+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: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
+This is a simple test.
+.
+QUIT
+****
+#
+no_stdout_check
+no_msglog_check
index 43331d4aa116c9d6aaecf902cd0e9fb5794204e0..7c5a79ee947a6dabf98781813d13da29ec36fda0 100644 (file)
@@ -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
 >>
index 75c28202963363feebcc19bcfa05b9df8c3adfd1..bcafb85894ecda3b646f25162ed5a3bf46093d1b 100644 (file)
@@ -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
index 00094863b2368ae780ee0679b9ce25dca166b34a..44e856da20ac6c5ec18f815c1f7ea3c37a5b703e 100644 (file)
@@ -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
index 86620a896a753e0ef3759cf34efdff4e8c8310de..210f868ad90e083e703e7a30ab9dda468663d93b 100644 (file)
@@ -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 (file)
index 0000000..1df9537
--- /dev/null
@@ -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
index 5a8c879ddd48dbecb6350dccfe7a439bd808022e..6dba84034b8e13f963386dd99f5b8d4758423fc8 100644 (file)
@@ -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
index a19787d120f0caa620691a5d5864e5c7799cff72..dc6209432ddd87ed6972759e76d667e69bc37375 100644 (file)
@@ -27,7 +27,7 @@ MAIL FROM:<>
 RCPT TO:<b@test.ex>
 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:<q@test.ex>
 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