SRS: fix encode operation for empty sender addresses.
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 1 Jun 2022 10:19:05 +0000 (11:19 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 1 Jun 2022 10:19:05 +0000 (11:19 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/expand.c
src/src/parse.c
test/scripts/4620-SRS/4620
test/stdout/4620

index e2111554c12f78f77f42c0801f1103d5a93c9782..7b92a2f21cd8294e79ef19767b749efd94c187c2 100644 (file)
@@ -42171,6 +42171,9 @@ There is no need to periodically change this key; a timestamp is also
 encoded.
 The second argument should be given as the envelope sender address before this
 encoding operation.
+.new
+If this value is empty the the expansion result will be empty.
+.wen
 The third argument should be the recipient domain of the message when
 it arrived at this system.
 .endlist
index ff35328a1643cc2daea9261a1b19879af785b387..72cd3c667414ea99a7dc2171b2ed7c3da3f838d8 100644 (file)
@@ -145,6 +145,9 @@ JH/32 Fix CHUNKING for a second message on a connection when the first was
       erroneously rejected the BDAT command.  Investigation help from
       Jesse Hathaway.
 
+JH/33 Fis ${srs_encode ...} to handle an empty sender address, now returning
+      an empty address.  Previously the expansion returned an error.
+
 
 Exim version 4.95
 -----------------
index e59625858c21e8913da2c17aa872fb98c10fa0c7..06dc58cb1c8c03f04867c2454f2e18b9c2d51ecd 100644 (file)
@@ -6943,68 +6943,73 @@ while (*s)
         case 3: goto EXPAND_FAILED;
         }
 
-      g = string_catn(g, US"SRS0=", 5);
-
-      /* ${l_4:${hmac{md5}{SRS_SECRET}{${lc:$return_path}}}}= */
-      hmac_md5(sub[0], string_copylc(sub[1]), cksum, sizeof(cksum));
-      g = string_catn(g, cksum, sizeof(cksum));
-      g = string_catn(g, US"=", 1);
-
-      /* ${base32:${eval:$tod_epoch/86400&0x3ff}}= */
+      if (sub[1] && *(sub[1]))
        {
-       struct timeval now;
-       unsigned long i;
-       gstring * h = NULL;
-
-       gettimeofday(&now, NULL);
-       for (unsigned long i = (now.tv_sec / 86400) & 0x3ff; i; i >>= 5)
-         h = string_catn(h, &base32_chars[i & 0x1f], 1);
-       if (h) while (h->ptr > 0)
-         g = string_catn(g, &h->s[--h->ptr], 1);
-       }
-      g = string_catn(g, US"=", 1);
+       g = string_catn(g, US"SRS0=", 5);
 
-      /* ${domain:$return_path}=${local_part:$return_path} */
-       {
-        int start, end, domain;
-        uschar * t = parse_extract_address(sub[1], &expand_string_message,
-                                         &start, &end, &domain, FALSE);
-       uschar * s;
+       /* ${l_4:${hmac{md5}{SRS_SECRET}{${lc:$return_path}}}}= */
+       hmac_md5(sub[0], string_copylc(sub[1]), cksum, sizeof(cksum));
+       g = string_catn(g, cksum, sizeof(cksum));
+       g = string_catn(g, US"=", 1);
 
-        if (!t)
-         goto EXPAND_FAILED;
+       /* ${base32:${eval:$tod_epoch/86400&0x3ff}}= */
+         {
+         struct timeval now;
+         unsigned long i;
+         gstring * h = NULL;
 
-       if (domain > 0) g = string_cat(g, t + domain);
+         gettimeofday(&now, NULL);
+         for (unsigned long i = (now.tv_sec / 86400) & 0x3ff; i; i >>= 5)
+           h = string_catn(h, &base32_chars[i & 0x1f], 1);
+         if (h) while (h->ptr > 0)
+           g = string_catn(g, &h->s[--h->ptr], 1);
+         }
        g = string_catn(g, US"=", 1);
 
-       s = domain > 0 ? string_copyn(t, domain - 1) : t;
-       if ((quoted = Ustrchr(s, '"') != NULL))
+       /* ${domain:$return_path}=${local_part:$return_path} */
          {
-         gstring * h = NULL;
-         DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n");
-         while (*s)            /* de-quote */
+         int start, end, domain;
+         uschar * t = parse_extract_address(sub[1], &expand_string_message,
+                                           &start, &end, &domain, FALSE);
+         uschar * s;
+
+         if (!t)
+           goto EXPAND_FAILED;
+
+         if (domain > 0) g = string_cat(g, t + domain);
+         g = string_catn(g, US"=", 1);
+
+         s = domain > 0 ? string_copyn(t, domain - 1) : t;
+         if ((quoted = Ustrchr(s, '"') != NULL))
            {
-           while (*s && *s != '"') h = string_catn(h, s++, 1);
-           if (*s) s++;
-           while (*s && *s != '"') h = string_catn(h, s++, 1);
-           if (*s) s++;
+           gstring * h = NULL;
+           DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n");
+           while (*s)          /* de-quote */
+             {
+             while (*s && *s != '"') h = string_catn(h, s++, 1);
+             if (*s) s++;
+             while (*s && *s != '"') h = string_catn(h, s++, 1);
+             if (*s) s++;
+             }
+           gstring_release_unused(h);
+           s = string_from_gstring(h);
            }
-         gstring_release_unused(h);
-         s = string_from_gstring(h);
+         g = string_cat(g, s);
          }
-       g = string_cat(g, s);
-        }
 
-      /* Assume that if the original local_part had quotes
-      it was for good reason */
+       /* Assume that if the original local_part had quotes
+       it was for good reason */
 
-      if (quoted) yield = string_catn(yield, US"\"", 1);
-      yield = string_catn(yield, g->s, g->ptr);
-      if (quoted) yield = string_catn(yield, US"\"", 1);
+       if (quoted) yield = string_catn(yield, US"\"", 1);
+       yield = string_catn(yield, g->s, g->ptr);
+       if (quoted) yield = string_catn(yield, US"\"", 1);
 
-      /* @$original_domain */
-      yield = string_catn(yield, US"@", 1);
-      yield = string_cat(yield, sub[2]);
+       /* @$original_domain */
+       yield = string_catn(yield, US"@", 1);
+       yield = string_cat(yield, sub[2]);
+       }
+      else
+       DEBUG(D_expand) debug_printf_indent("null return_path for srs-encode\n");
 
       if (skipping) continue;
       break;
index f156865c833a811034bc884be82157434177a93f..bdba3ecd0cb0be2185485f2099de9184359d05dd 100644 (file)
@@ -658,7 +658,7 @@ followed by a route-addr (more words must follow). */
 
 if (*s != '@' && *s != '<')
   {
-  if (*s == 0 || *s == ';')
+  if (!*s || *s == ';')
     {
     if (!*t) FAILED(US"empty address");
     endptr = last_comment_position;
index f180142a677a2dcaa696531b8e14c6b285da817b..8119c295f425ff2d766fe236edea58654ef4c06d 100644 (file)
@@ -40,4 +40,9 @@ exim -DCONTROL=remote -q
 exim -q
 ****
 #
+# Sender which is empty (already a bounce)
+exim -be
+>${srs_encode {mysecret} {} {test.ex}}<
+****
+#
 killdaemon
index 7883638a681c8811d64f76cb1b50025dfff10b05..c1fcaf1d1ba2294008ab55ce00c0fa47afa9536a 100644 (file)
@@ -1,3 +1,5 @@
 > SRS0=ZZZZ=YY=the.local.host.name=CALLER@test.ex
 > "SRS0=ZZZZ=YY=the.local.host.name=CALLER"@test.ex
 > 
+> ><
+>