From c2ef5d7e9fc09693770d5d89a6913b47b9d6dbe7 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 1 Jun 2022 11:19:05 +0100 Subject: [PATCH] SRS: fix encode operation for empty sender addresses. --- doc/doc-docbook/spec.xfpt | 3 ++ doc/doc-txt/ChangeLog | 3 ++ src/src/expand.c | 103 +++++++++++++++++++------------------ src/src/parse.c | 2 +- test/scripts/4620-SRS/4620 | 5 ++ test/stdout/4620 | 2 + 6 files changed, 68 insertions(+), 50 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index e2111554c..7b92a2f21 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -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 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index ff35328a1..72cd3c667 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 ----------------- diff --git a/src/src/expand.c b/src/src/expand.c index e59625858..06dc58cb1 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -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; diff --git a/src/src/parse.c b/src/src/parse.c index f156865c8..bdba3ecd0 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -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; diff --git a/test/scripts/4620-SRS/4620 b/test/scripts/4620-SRS/4620 index f180142a6..8119c295f 100644 --- a/test/scripts/4620-SRS/4620 +++ b/test/scripts/4620-SRS/4620 @@ -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 diff --git a/test/stdout/4620 b/test/stdout/4620 index 7883638a6..c1fcaf1d1 100644 --- a/test/stdout/4620 +++ b/test/stdout/4620 @@ -1,3 +1,5 @@ > SRS0=ZZZZ=YY=the.local.host.name=CALLER@test.ex > "SRS0=ZZZZ=YY=the.local.host.name=CALLER"@test.ex > +> >< +> -- 2.30.2