summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt117
-rw-r--r--doc/doc-txt/NewStuff3
-rw-r--r--doc/doc-txt/experimental-spec.txt78
-rw-r--r--src/src/EDITME8
-rw-r--r--src/src/config.h.defaults2
-rw-r--r--src/src/exim.c5
-rw-r--r--src/src/expand.c22
-rw-r--r--src/src/globals.c2
-rw-r--r--src/src/globals.h2
-rw-r--r--src/src/macro_predef.c8
-rw-r--r--test/scripts/4620-SRS/REQUIRES2
11 files changed, 153 insertions, 96 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index f1940bb1e..748f81cc0 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -10597,6 +10597,14 @@ ${sort {${lookup dnsdb{>:,,mx=example.com}}} {<} {${listextract{1}{<,$item}}}}
will sort an MX lookup into priority order.
+
+.new
+.vitem &*${srs_encode&~{*&<&'secret'&>&*}{*&<&'return&~path'&>&*}{*&<&'original&~domain'&>&*}}*&
+SRS encoding. See SECT &<<SECTSRS>>& for details.
+.wen
+
+
+
.vitem &*${substr{*&<&'string1'&>&*}{*&<&'string2'&>&*}{*&<&'string3'&>&*}}*&
.cindex "&%substr%& expansion item"
.cindex "substring extraction"
@@ -11659,6 +11667,13 @@ includes the case of letters, whereas for &%gti%& the comparison is
case-independent.
Case and collation order are defined per the system C locale.
+
+.new
+.vitem &*inbound_srs&~{*&<&'local&~part'&>&*}{*&<&'secret'&>&*}*&
+SRS decode. See SECT &<<SECTSRS>>& for details.
+.wen
+
+
.vitem &*inlist&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*& &&&
&*inlisti&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*&
.cindex "string" "comparison"
@@ -41078,6 +41093,108 @@ The lookup will return the same result strings as can appear in
+.section "SRS (Sender Rewriting Scheme)" SECTSRS
+.cindex SRS "sender rewriting scheme"
+
+.new
+SRS can be used to modify sender addresses when forwarding so that
+SPF verification does not object to them.
+It operates by encoding the original envelope sender in a new
+sender local part and using a domain run by the forwarding site
+as the new domain for the sender. Any DSN message should be returned
+to this new sender at the forwarding site, which can extract the
+original sender from the coded local part and forward the DSN to
+the originator.
+
+This is a way of avoiding the breakage that SPF does to forwarding.
+The constructed local-part will be longer than the original,
+leading to possible problems with very long addresses.
+The changing of the sender address also hinders the tracing of mail
+problems.
+
+Exim can be built to include native SRS support. To do this
+SUPPORT_SRS=yes must be defined in &_Local/Makefile_&.
+If this has been done, the macros _HAVE_SRS and _HAVE_NATIVE_SRS
+will be defined.
+The support is limited to SRS0-encoding; SRS1 is not supported.
+
+.cindex SRS excoding
+To encode an address use this expansion item:
+.vlist
+.vitem &*${srs_encode&~{*&<&'secret'&>&*}{*&<&'return&~path'&>&*}{*&<&'original&~domain'&>&*}}*&
+.cindex "&%srs_encode%& expansion item"
+.cindex SRS "expansion item"
+The first argument should be a secret known and used by all systems
+handling the recipient domain for the original message.
+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.
+The third argument should be the recipient domain of the message when
+it arrived at this system.
+.endlist
+
+.cindex SRS decoding
+To decode an address use this expansion condition:
+.vlist
+.vitem &*inbound_srs&~{*&<&'local&~part'&>&*}{*&<&'secret'&>&*}*&
+The first argument should be the recipient local prt as is was received.
+The second argument is the site secret.
+
+If the messages is not for an SRS-encoded recipient the condition will
+return false. If it is, the condition will return true and the variable
+&$srs_recipient$& will be set to the decoded (original) value.
+.endlist
+
+Example usage:
+.code
+ #macro
+ SRS_SECRET = <pick something unique for your site for this. Use on all MXs.>
+
+ #routers
+
+ outbound:
+ driver = dnslookup
+ # if outbound, and forwarding has been done, use an alternate transport
+ domains = ! +my_domains
+ transport = ${if eq {$local_part@$domain} \
+ {$original_local_part@$original_domain} \
+ {remote_smtp} {remote_forwarded_smtp}}
+
+ inbound_srs:
+ driver = redirect
+ senders = :
+ domains = +my_domains
+ # detect inbound bounces which are SRS'd, and decode them
+ condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
+ data = $srs_recipient
+
+ inbound_srs_failure:
+ driver = redirect
+ senders = :
+ domains = +my_domains
+ # detect inbound bounces which look SRS'd but are invalid
+ condition = ${if inbound_srs {$local_part} {}}
+ allow_fail
+ data = :fail: Invalid SRS recipient address
+
+ #... further routers here
+
+
+ # transport; should look like the non-forward outbound
+ # one, plus the max_rcpt and return_path options
+ remote_forwarded_smtp:
+ driver = smtp
+ # modify the envelope from, for mails that we forward
+ max_rcpt = 1
+ return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
+.endd
+
+
+.wen
+
+
+
.section DMARC SECDMARC
.cindex DMARC verification
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 7f8f628f9..53d7b5c9a 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -12,6 +12,9 @@ Version 4.95
1. The fast-ramp two phase queue run support, previously experimental, is
now supported by default.
+ 2. The native SRS support, previously experimental, is now supported. It is
+ not built unless specified in the Local/Makefile.
+
Version 4.94
------------
diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 68d04cce7..2b6d01f33 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -292,81 +292,11 @@ These four steps are explained in more details below.
-SRS (Sender Rewriting Scheme) Support (native)
---------------------------------------------------------------
-This is less full-featured than the libsrs_alt version below.
-
-The Exim build needs to be done with this in Local/Makefile:
-EXPERIMENTAL_SRS_NATIVE=yes
-
-The following are provided:
-- an expansion item "srs_encode"
- This takes three arguments:
- - a site SRS secret
- - the return_path
- - the pre-forwarding domain
-
-- an expansion condition "inbound_srs"
- This takes two arguments: the local_part to check, and a site SRS secret.
- If the secret is zero-length, only the pattern of the local_part is checked.
- The $srs_recipient variable is set as a side-effect.
-
-- an expansion variable $srs_recipient
- This gets the original return_path encoded in the SRS'd local_part
-
-- predefined macros _HAVE_SRS and _HAVE_NATIVE_SRS
-
-Sample usage:
-
- #macro
- SRS_SECRET = <pick something unique for your site for this. Use on all MXs.>
-
- #routers
-
- outbound:
- driver = dnslookup
- # if outbound, and forwarding has been done, use an alternate transport
- domains = ! +my_domains
- transport = ${if eq {$local_part@$domain} \
- {$original_local_part@$original_domain} \
- {remote_smtp} {remote_forwarded_smtp}}
-
- inbound_srs:
- driver = redirect
- senders = :
- domains = +my_domains
- # detect inbound bounces which are SRS'd, and decode them
- condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
- data = $srs_recipient
-
- inbound_srs_failure:
- driver = redirect
- senders = :
- domains = +my_domains
- # detect inbound bounces which look SRS'd but are invalid
- condition = ${if inbound_srs {$local_part} {}}
- allow_fail
- data = :fail: Invalid SRS recipient address
-
- #... further routers here
-
-
- # transport; should look like the non-forward outbound
- # one, plus the max_rcpt and return_path options
- remote_forwarded_smtp:
- driver = smtp
- # modify the envelope from, for mails that we forward
- max_rcpt = 1
- return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
-
-
-
-
SRS (Sender Rewriting Scheme) Support (using libsrs_alt)
--------------------------------------------------------------
-See also above, for an alternative native support implementation.
+See also the main docs, for an alternative native support implementation.
-Exim currently includes SRS support via Miles Wilton's
+Exim can be built with SRS support using Miles Wilton's
libsrs_alt library. The current version of the supported
library is 0.5, there are reports of 1.0 working.
@@ -383,6 +313,10 @@ EXPERIMENTAL_SRS_ALT=yes
in your Local/Makefile.
+The built-in support, included by SUPPORT_SRS,
+shuold *not* be enabled if you wish to use the libsrs_alt
+version.
+
The following main-section options become available:
srs_config string
srs_hashlength int
diff --git a/src/src/EDITME b/src/src/EDITME
index 340d30d76..cf671afd1 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -572,6 +572,10 @@ DISABLE_MAL_MKS=yes
# Uncomment the following to remove the fast-ramp two-phase-queue-run support
# DISABLE_QUEUE_RAMP=yes
+# Uncomment the following lines to add SRS (Sender Rewriting Scheme) support
+# using only native facilities. See EXPERIMENTAL_SRS_ALT for an alternative.
+# SUPPORT_SRS=yes
+
#------------------------------------------------------------------------------
# Compiling Exim with experimental features. These are documented in
@@ -585,10 +589,6 @@ DISABLE_MAL_MKS=yes
# EXPERIMENTAL_DCC=yes
# Uncomment the following lines to add SRS (Sender rewriting scheme) support
-# using only native facilities.
-# EXPERIMENTAL_SRS_NATIVE=yes
-
-# Uncomment the following lines to add SRS (Sender rewriting scheme) support
# using the implementation in linbsrs_alt.
# You need to have libsrs_alt installed on your system (srs.mirtol.com).
# Depending on where it is installed you may have to edit the CFLAGS and
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 5347f7a8e..a91c3c3aa 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -157,6 +157,7 @@ Do not put spaces between # and the 'define'.
#define SUPPORT_PROXY
#define SUPPORT_SOCKS
#define SUPPORT_SPF
+#define SUPPORT_SRS
#define SUPPORT_TRANSLATE_IP_ADDRESS
#define SYSLOG_LOG_PID
@@ -205,7 +206,6 @@ Do not put spaces between # and the 'define'.
#define EXPERIMENTAL_LMDB
#define EXPERIMENTAL_QUEUEFILE
#define EXPERIMENTAL_SRS_ALT
-#define EXPERIMENTAL_SRS_NATIVE
#define EXPERIMENTAL_TLS_RESUME
diff --git a/src/src/exim.c b/src/src/exim.c
index cd6d25323..ab2d673dd 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -979,6 +979,9 @@ g = string_cat(NULL, US"Support for:");
#ifdef SUPPORT_SPF
g = string_cat(g, US" SPF");
#endif
+#if defined(SUPPORT_SRS)
+ g = string_cat(g, US" SRS");
+#endif
#ifdef TCP_FASTOPEN
tcp_init();
if (f.tcp_fastopen_ok) g = string_cat(g, US" TCP_Fast_Open");
@@ -1001,7 +1004,7 @@ g = string_cat(NULL, US"Support for:");
#ifdef EXPERIMENTAL_QUEUEFILE
g = string_cat(g, US" Experimental_QUEUEFILE");
#endif
-#if defined(EXPERIMENTAL_SRS_ALT) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT)
g = string_cat(g, US" Experimental_SRS");
#endif
#ifdef EXPERIMENTAL_TLS_RESUME
diff --git a/src/src/expand.c b/src/src/expand.c
index 95b5d02e1..4abde0af6 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -131,7 +131,7 @@ static uschar *item_table[] = {
US"run",
US"sg",
US"sort",
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
US"srs_encode",
#endif
US"substr",
@@ -166,7 +166,7 @@ enum {
EITEM_RUN,
EITEM_SG,
EITEM_SORT,
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
EITEM_SRS_ENCODE,
#endif
EITEM_SUBSTR,
@@ -334,7 +334,7 @@ static uschar *cond_table[] = {
US"gei",
US"gt",
US"gti",
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
US"inbound_srs",
#endif
US"inlist",
@@ -387,7 +387,7 @@ enum {
ECOND_STR_GEI,
ECOND_STR_GT,
ECOND_STR_GTI,
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
ECOND_INBOUND_SRS,
#endif
ECOND_INLIST,
@@ -758,7 +758,7 @@ static var_entry var_table[] = {
{ "srs_orig_recipient", vtype_stringptr, &srs_orig_recipient },
{ "srs_orig_sender", vtype_stringptr, &srs_orig_sender },
#endif
-#if defined(EXPERIMENTAL_SRS_ALT) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT) || defined(SUPPORT_SRS)
{ "srs_recipient", vtype_stringptr, &srs_recipient },
#endif
#ifdef EXPERIMENTAL_SRS_ALT
@@ -2438,7 +2438,7 @@ else
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
/* Do an hmac_md5. The result is _not_ nul-terminated, and is sized as
the smaller of a full hmac_md5 result (16 bytes) or the supplied output buffer.
@@ -2513,7 +2513,7 @@ for (int i = 0, j = len; i < MD5_HASHLEN; i++)
}
return;
}
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
/*************************************************
@@ -3443,7 +3443,7 @@ switch(cond_type = identify_operator(&s, &opname))
return s;
}
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
case ECOND_INBOUND_SRS:
/* ${if inbound_srs {local_part}{secret} {yes}{no}} */
{
@@ -3535,7 +3535,7 @@ srs_result:
if (yield) *yield = (boolvalue == testfor);
return s;
}
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
/* Unknown condition */
@@ -6783,7 +6783,7 @@ while (*s != 0)
continue;
}
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
case EITEM_SRS_ENCODE:
/* ${srs_encode {secret} {return_path} {orig_domain}} */
{
@@ -6837,7 +6837,7 @@ while (*s != 0)
yield = string_cat(yield, sub[2]);
continue;
}
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
} /* EITEM_* switch */
/* Control reaches here if the name is not recognized as one of the more
diff --git a/src/src/globals.c b/src/src/globals.c
index 880db98f4..561054981 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1517,7 +1517,7 @@ uschar *srs_recipient = NULL;
uschar *srs_secrets = NULL;
uschar *srs_status = NULL;
#endif
-#ifdef EXPERIMENTAL_SRS_ALT
+#ifdef SUPPORT_SRS
uschar *srs_recipient = NULL;
#endif
int string_datestamp_offset= -1;
diff --git a/src/src/globals.h b/src/src/globals.h
index 3b9e6fb40..fffe74441 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -1002,7 +1002,7 @@ extern uschar *srs_status; /* SRS staus */
extern BOOL srs_usehash; /* SRS use hash flag */
extern BOOL srs_usetimestamp; /* SRS use timestamp flag */
#endif
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
extern uschar *srs_recipient; /* SRS recipient */
#endif
extern BOOL strict_acl_vars; /* ACL variables have to be set before being used */
diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c
index 17aad2e4b..f6cfcb14c 100644
--- a/src/src/macro_predef.c
+++ b/src/src/macro_predef.c
@@ -174,6 +174,9 @@ due to conflicts with other common macros. */
#ifdef SUPPORT_SOCKS
builtin_macro_create(US"_HAVE_SOCKS");
#endif
+#if defined(SUPPORT_SRS)
+ builtin_macro_create(US"_HAVE_NATIVE_SRS"); /* beware clash with _HAVE_SRS */
+#endif
#ifdef TCP_FASTOPEN
builtin_macro_create(US"_HAVE_TCP_FASTOPEN");
#endif
@@ -183,12 +186,9 @@ due to conflicts with other common macros. */
#ifdef SUPPORT_SPF
builtin_macro_create(US"_HAVE_SPF");
#endif
-#if defined(EXPERIMENTAL_SRS_ALT) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT) || defined(SUPPORT_SRS)
builtin_macro_create(US"_HAVE_SRS");
#endif
-#if defined(EXPERIMENTAL_SRS_NATIVE)
- builtin_macro_create(US"_HAVE_NATIVE_SRS"); /* beware clash with _HAVE_SRS */
-#endif
#ifdef EXPERIMENTAL_ARC
builtin_macro_create(US"_HAVE_ARC");
#endif
diff --git a/test/scripts/4620-SRS/REQUIRES b/test/scripts/4620-SRS/REQUIRES
index 7286713d6..a32fd44f6 100644
--- a/test/scripts/4620-SRS/REQUIRES
+++ b/test/scripts/4620-SRS/REQUIRES
@@ -1,2 +1,2 @@
-support Experimental_SRS
+support SRS
feature _HAVE_NATIVE_SRS