diff options
Diffstat (limited to 'contrib/sendmail/cf')
-rw-r--r-- | contrib/sendmail/cf/README | 79 | ||||
-rw-r--r-- | contrib/sendmail/cf/cf/Makefile | 29 | ||||
-rw-r--r-- | contrib/sendmail/cf/cf/submit.cf | 39 | ||||
-rw-r--r-- | contrib/sendmail/cf/cf/submit.mc | 3 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/check_cert_altnames.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/check_other.m4 | 46 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/delay_checks.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/dnsbl.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/enhdnsbl.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/nopercenthack.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/nouucp.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/feature/sts.m4 | 19 | ||||
-rw-r--r-- | contrib/sendmail/cf/m4/cfhead.m4 | 8 | ||||
-rw-r--r-- | contrib/sendmail/cf/m4/proto.m4 | 338 | ||||
-rw-r--r-- | contrib/sendmail/cf/m4/version.m4 | 2 | ||||
-rw-r--r-- | contrib/sendmail/cf/mailer/local.m4 | 2 |
16 files changed, 462 insertions, 115 deletions
diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README index 983aa2821a1a..cfabe5eefe45 100644 --- a/contrib/sendmail/cf/README +++ b/contrib/sendmail/cf/README @@ -1120,9 +1120,8 @@ local_procmail Use procmail or another delivery agent as the local mailer. setreuid() call, you may need to add -f $f to the procmail argument vector to pass the proper sender to procmail. - For example, this allows it to use the maildrop - (http://www.flounder.net/~mrsam/maildrop/) mailer instead - by specifying: + For example, this allows it to use the maildrop mailer + instead by specifying: FEATURE(`local_procmail', `/usr/local/bin/maildrop', `maildrop -d $u') @@ -1132,7 +1131,7 @@ local_procmail Use procmail or another delivery agent as the local mailer. FEATURE(`local_procmail', `/usr/local/bin/scanmails') WARNING: This feature sets LOCAL_MAILER_FLAGS unconditionally, - i.e., without respecting any definitions in an OSTYPE setting. + i.e., without respecting any definitions in an OSTYPE setting. bestmx_is_local Accept mail as though locally addressed for any host that lists us as the best possible MX record. This generates @@ -1267,6 +1266,12 @@ delay_checks The rulesets check_mail and check_relay will not be called section. Note: this feature is incompatible to the versions in 8.10 and 8.11. +check_other Enable a default check_other ruleset which terminates + an SMTP session when it encounters a command which matches + a regular expression given as argument. If no argument + is given, then the default (to match potential headers) is: + ^[[:print:]]+ *: + use_client_ptr If this feature is enabled then check_relay will override its first argument with $&{client_ptr}. This is useful for rejections based on the unverified hostname of client, @@ -1578,9 +1583,9 @@ require_rdns Reject mail from connecting SMTP clients without proper Entries such as Connect:1.2.3.4 OK - Connect:1.2 RELAY - will allowlist IP address 1.2.3.4, so that the rDNS - blocking does apply to that IP address + Connect:1.3 RELAY + will allowlist IP address 1.2.3.4 and IP net 1.3.* + so that the rDNS blocking does apply not to those IPs. Entries such as Connect:1.2.3.4 REJECT @@ -1603,6 +1608,14 @@ badmx Reject envelope sender addresses (MAIL) whose domain part has been compiled with the options MAP_REGEX and DNSMAP. +sts Experimental support for Strict Transport Security + (MTA-STS, see RFC 8461). It sets the option + StrictTransportSecurity and takes one optional + argument: the socket map specification to access + postfix-mta-sts-resolver (see feature/sts.m4 + for the default value). + For more information see doc/op/op.me. + +-------+ | HACKS | +-------+ @@ -2581,7 +2594,7 @@ top level domain TLD, 192.168.212.* network, and the IPv6 address 2002:c0a8:02c7::/48. Entries in the access map should be tagged according to their type. -Three tags are available: +These tags are applicable: Connect: connection information (${client_addr}, ${client_name}) From: envelope sender @@ -2818,7 +2831,7 @@ regex map: # check address against various regex checks R$* $: $>Parse0 $>3 $1 R$+ < @ bigisp.com. > $* $: $(allnumbers $1 $) - R@MATCH $#error $: 553 Header Error + R@MATCH $#error $: 553 Address Error These rules are called with the original arguments of the corresponding check_* ruleset. If the local ruleset returns $#OK, no further checking @@ -3081,8 +3094,8 @@ Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org (line breaks have been inserted for readability). -The macros which are subject to this encoding are ${cert_subject}, -${cert_issuer}, ${cn_subject}, and ${cn_issuer}. +The macros which are subject to this encoding are ${cert_subject}, +${cert_issuer}, ${cn_subject}, and ${cn_issuer}. Examples: @@ -3223,13 +3236,13 @@ options: - CertFile, KeyFile: {Server,Client}{Cert,Key}File - Flags: see doc/op/op.me for details. -If FEATURE(`tls_session_features') is used, then default rulesets -are activated which look up entries in the access map with the tags -TLS_Srv_features and TLS_Clt_features, respectively. -For example, these entries: +If FEATURE(`tls_session_features') and FEATURE(`access_db') are +used, then default rulesets are activated which look up entries in +the access map with the tags TLS_Srv_features and TLS_Clt_features, +respectively. For example, these entries: - TLS_Srv_features:10.0.2.4 CipherList=MEDIUM+aRSA; - TLS_Clt_features:10.1.0.1 Options=SSL_OP_NO_TLSv1_2; CipherList=ALL:-EXPORT +TLS_Srv_features:10.0.2.4 CipherList=MEDIUM+aRSA; +TLS_Clt_features:10.1.0.1 Options=SSL_OP_NO_TLSv1_2; CipherList=ALL:-EXPORT specify a cipherlist with MEDIUM strength ciphers that use RSA certificates only for the client with the IP address 10.0.2.4, @@ -3240,21 +3253,23 @@ their own rulesets which must return the appropriate data. If the rulesets are not defined or do not return a value, the default TLS options are not modified. -About 2): the ruleset try_tls (srv_features) can be used together -with the access map. Entries for the access map must be tagged -with Try_TLS (Srv_Features) and refer to the hostname or IP address -of the connecting system. A default case can be specified by using -just the tag. For example, the following entries in the access map: +About 2): the rulesets try_tls, srv_features, and clt_features can +be used together with the access map. Entries for the access map +must be tagged with Try_TLS, Srv_Features, Clt_Features and refer +to the hostname or IP address of the connecting system. A default +case can be specified by using just the tag. For example, the +following entries in the access map: Try_TLS:broken.server NO Srv_Features:my.domain v Srv_Features: V + Clt_Features:broken.sts M will turn off STARTTLS when sending to broken.server (or any host -in that domain), and request a client certificate during the TLS -handshake only for hosts in my.domain. The valid entries on the RHS -for Srv_Features are listed in the Sendmail Installation and -Operations Guide. +in that domain), request a client certificate during the TLS handshake +only for hosts in my.domain, and disable MTA-STS for broken.sts. +The valid entries on the RHS for Srv_Features and Clt_Features are +listed in the Sendmail Installation and Operations Guide. Received: Header @@ -3377,11 +3392,11 @@ LOCAL_RULESETS respectively. For example: Smyruleset ... -Local additions for the rulesets srv_features, try_tls, tls_rcpt, -tls_client, and tls_server can be made using LOCAL_SRV_FEATURES, -LOCAL_TRY_TLS, LOCAL_TLS_RCPT, LOCAL_TLS_CLIENT, and LOCAL_TLS_SERVER, -respectively. For example, to add a local ruleset that decides -whether to try STARTTLS in a sendmail client, use: +Local additions for the rulesets srv_features, clt_features, try_tls, +tls_rcpt, tls_client, and tls_server can be made using LOCAL_SRV_FEATURES, +LOCAL_CLT_FEATURES, LOCAL_TRY_TLS, LOCAL_TLS_RCPT, LOCAL_TLS_CLIENT, +and LOCAL_TLS_SERVER, respectively. For example, to add a local +ruleset that decides whether to try STARTTLS in a sendmail client, use: LOCAL_TRY_TLS R... @@ -4288,7 +4303,7 @@ confXF_BUFFER_SIZE XScriptFileBufferSize memory-buffered transcript (xf) file before a disk-based file is used. -confAUTH_MECHANISMS AuthMechanisms [GSSAPI KERBEROS_V4 DIGEST-MD5 +confAUTH_MECHANISMS AuthMechanisms [EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5] List of authentication mechanisms for AUTH (separated by spaces). The advertised list of diff --git a/contrib/sendmail/cf/cf/Makefile b/contrib/sendmail/cf/cf/Makefile index bf6f031b2f11..bdb9f9e9b426 100644 --- a/contrib/sendmail/cf/cf/Makefile +++ b/contrib/sendmail/cf/cf/Makefile @@ -100,23 +100,36 @@ M4FILES=\ ${CFDIR}/feature/access_db.m4 \ ${CFDIR}/feature/allmasquerade.m4 \ ${CFDIR}/feature/always_add_domain.m4 \ + ${CFDIR}/feature/authinfo.m4 \ + ${CFDIR}/feature/badmx.m4 \ ${CFDIR}/feature/bcc.m4 \ ${CFDIR}/feature/bestmx_is_local.m4 \ ${CFDIR}/feature/bitdomain.m4 \ + ${CFDIR}/feature/block_bad_helo.m4 \ ${CFDIR}/feature/blocklist_recipients.m4 \ + ${CFDIR}/feature/check_cert_altnames.m4 \ + ${CFDIR}/feature/check_other.m4 \ + ${CFDIR}/feature/compat_check.m4 \ ${CFDIR}/feature/conncontrol.m4 \ + ${CFDIR}/feature/delay_checks.m4 \ ${CFDIR}/feature/dnsbl.m4 \ ${CFDIR}/feature/domaintable.m4 \ + ${CFDIR}/feature/enhdnsbl.m4 \ ${CFDIR}/feature/generics_entire_domain.m4 \ ${CFDIR}/feature/genericstable.m4 \ + ${CFDIR}/feature/greet_pause.m4 \ ${CFDIR}/feature/ldap_routing.m4 \ ${CFDIR}/feature/limited_masquerade.m4 \ ${CFDIR}/feature/local_lmtp.m4 \ + ${CFDIR}/feature/local_no_masquerade.m4 \ ${CFDIR}/feature/local_procmail.m4 \ + ${CFDIR}/feature/lookupdotdomain.m4 \ ${CFDIR}/feature/loose_relay_check.m4 \ ${CFDIR}/feature/mailertable.m4 \ ${CFDIR}/feature/masquerade_entire_domain.m4 \ ${CFDIR}/feature/masquerade_envelope.m4 \ + ${CFDIR}/feature/msp.m4 \ + ${CFDIR}/feature/mtamark.m4 \ ${CFDIR}/feature/no_default_msa.m4 \ ${CFDIR}/feature/nocanonify.m4 \ ${CFDIR}/feature/nopercenthack.m4 \ @@ -124,17 +137,24 @@ M4FILES=\ ${CFDIR}/feature/nouucp.m4 \ ${CFDIR}/feature/nullclient.m4 \ ${CFDIR}/feature/prefixmod.m4 \ + ${CFDIR}/feature/preserve_local_plus_detail.m4 \ + ${CFDIR}/feature/preserve_luser_host.m4 \ ${CFDIR}/feature/promiscuous_relay.m4 \ - ${CFDIR}/feature/redirect.m4 \ + ${CFDIR}/feature/queuegroup.m4 \ ${CFDIR}/feature/ratecontrol.m4 \ + ${CFDIR}/feature/redirect.m4 \ ${CFDIR}/feature/relay_based_on_MX.m4 \ ${CFDIR}/feature/relay_entire_domain.m4 \ ${CFDIR}/feature/relay_hosts_only.m4 \ ${CFDIR}/feature/relay_local_from.m4 \ ${CFDIR}/feature/relay_mail_from.m4 \ + ${CFDIR}/feature/require_rdns.m4 \ ${CFDIR}/feature/smrsh.m4 \ ${CFDIR}/feature/stickyhost.m4 \ + ${CFDIR}/feature/sts.m4 \ + ${CFDIR}/feature/tls_failures.m4 \ ${CFDIR}/feature/tls_session_features.m4 \ + ${CFDIR}/feature/use_client_ptr.m4 \ ${CFDIR}/feature/use_ct_file.m4 \ ${CFDIR}/feature/use_cw_file.m4 \ ${CFDIR}/feature/uucpdomain.m4 \ @@ -147,6 +167,7 @@ M4FILES=\ ${CFDIR}/m4/proto.m4 \ ${CFDIR}/m4/version.m4 \ ${CFDIR}/mailer/cyrus.m4 \ + ${CFDIR}/mailer/cyrusv2.m4 \ ${CFDIR}/mailer/fax.m4 \ ${CFDIR}/mailer/local.m4 \ ${CFDIR}/mailer/mail11.m4 \ @@ -159,6 +180,7 @@ M4FILES=\ ${CFDIR}/mailer/uucp.m4 \ ${CFDIR}/ostype/aix3.m4 \ ${CFDIR}/ostype/aix4.m4 \ + ${CFDIR}/ostype/aix5.m4 \ ${CFDIR}/ostype/altos.m4 \ ${CFDIR}/ostype/amdahl-uts.m4 \ ${CFDIR}/ostype/a-ux.m4 \ @@ -167,6 +189,7 @@ M4FILES=\ ${CFDIR}/ostype/bsdi.m4 \ ${CFDIR}/ostype/bsdi1.0.m4 \ ${CFDIR}/ostype/bsdi2.0.m4 \ + ${CFDIR}/ostype/darwin.m4 \ ${CFDIR}/ostype/dgux.m4 \ ${CFDIR}/ostype/domainos.m4 \ ${CFDIR}/ostype/dragonfly.m4 \ @@ -200,10 +223,14 @@ M4FILES=\ ${CFDIR}/ostype/solaris2.ml.m4 \ ${CFDIR}/ostype/solaris2.pre5.m4 \ ${CFDIR}/ostype/solaris8.m4 \ + ${CFDIR}/ostype/solaris11.m4 \ ${CFDIR}/ostype/sunos3.5.m4 \ ${CFDIR}/ostype/sunos4.1.m4 \ ${CFDIR}/ostype/svr4.m4 \ ${CFDIR}/ostype/ultrix4.m4 \ + ${CFDIR}/ostype/unicos.m4 \ + ${CFDIR}/ostype/unicosmk.m4 \ + ${CFDIR}/ostype/unicosmp.m4 \ ${CFDIR}/ostype/unixware7.m4 \ ${CFDIR}/ostype/unknown.m4 \ ${CFDIR}/ostype/uxpds.m4 diff --git a/contrib/sendmail/cf/cf/submit.cf b/contrib/sendmail/cf/cf/submit.cf index 63d7cb720eb7..1faab23e9e39 100644 --- a/contrib/sendmail/cf/cf/submit.cf +++ b/contrib/sendmail/cf/cf/submit.cf @@ -16,8 +16,8 @@ ##### ##### SENDMAIL CONFIGURATION FILE ##### -##### built by ca@lab.smi.sendmail.com on Thu Jul 2 22:41:57 PDT 2020 -##### in /var/tmp/ca/sm8.git/sendmail/OpenSource/sendmail-8.16.1/cf/cf +##### built by ca@lab.smi.sendmail.com on Sun Aug 15 23:05:00 PDT 2021 +##### in /var/tmp/ca/sm8.head/sendmail/OpenSource/sendmail-8.17.1/cf/cf ##### using ../ as configuration include directory ##### ###################################################################### @@ -88,6 +88,7 @@ C{ResOk}OKR # Hosts for which relaying is permitted ($=R) FR-o /etc/mail/relay-domains + # arithmetic map Karith arith @@ -114,7 +115,7 @@ D{MTAHost}[127.0.0.1] # Configuration version number -DZ8.16.1/Submit +DZ8.17.1/Submit ############### @@ -362,7 +363,7 @@ O TimeZoneSpec= # maximum number of new connections per second #O ConnectionRateThrottle=0 -# Width of the window +# Width of the window #O ConnectionRateWindowSize=60s # work recipient factor @@ -536,7 +537,7 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid #O ClientCertFile # Client private key #O ClientKeyFile -# File containing certificate revocation lists +# File containing certificate revocation lists #O CRLFile # Directory containing hashes pointing to certificate revocation status files #O CRLPath @@ -802,7 +803,7 @@ R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ... R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here R< @ $+ > $#error $@ 5.1.3 $: "553 User address required" R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ... -R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" +R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" R< @ *LOCAL* > $#error $@ 5.1.3 $: "553 User address required" R$* $=O $* < @ *LOCAL* > $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... @@ -896,7 +897,7 @@ R< $+ > $+ $@ $>MailerToTriple < $1 > $2 < @ $1 > SMailerToTriple=95 R< > $* $@ $1 strip off null relay -R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 +R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2 R< error : $+ > $* $#error $: $1 R< local : $* > $* $>CanonLocal < $1 > $2 @@ -926,7 +927,7 @@ R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 > # handle local:user syntax R< $+ > $* <@ $* > $* $#local $@ $2@$3 $: $1 -R< $+ > $* $#local $@ $2 $: $1 +R< $+ > $* $#local $@ $2 $: $1 ################################################################### ### Ruleset 93 -- convert header names to masqueraded form ### @@ -1189,7 +1190,7 @@ R<FORGED> $#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $ R<FAIL> $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name} R$* $: <@> $&{client_name} # pass to name server to make hostname canonical -R<@> $* $=P $:<?> $1 $2 +R<@> $* $=P $:<?> $1 $2 R<@> $+ $:<?> $[ $1 $] R$* . $1 strip trailing dots R<?> $=w $@ RELAY @@ -1233,12 +1234,20 @@ Ssrv_features ###################################################################### +### clt_features: which features to use with a server? +### (done in client) +###################################################################### +Sclt_features + + +###################################################################### ### try_tls: try to use STARTTLS? ### (done in client) ###################################################################### Stry_tls + ###################################################################### ### tls_rcpt: is connection with server "good" enough? ### (done in client, per recipient) @@ -1278,8 +1287,12 @@ R$* $@ $>"TLS_connection" $1 ### Requirement: RHS from access map, may be ? for none. ###################################################################### STLS_connection -RSOFTWARE $#error $@ 4.7.0 $: "403 TLS handshake." -RDANE_FAIL $#error $@ 4.7.0 $: "403 DANE check failed." +RSOFTWARE $#error $@ 4.7.0 $: "454 TLS handshake failed." +RDANE_FAIL $#error $@ 4.7.0 $: "454 DANE check failed." +RPROTOCOL $#error $@ 4.7.0 $: "454 STARTTLS failed." +RCONFIG $#error $@ 4.7.0 $: "454 STARTTLS temporarily not possible." + + @@ -1478,6 +1491,7 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L= T=DNS/RFC822/SMTP, A=TCP $h + ### submit.mc ### # divert(-1) # # @@ -1505,3 +1519,6 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L= # dnl # dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] # FEATURE(`msp', `[127.0.0.1]')dnl +# dnl enable this for SMTPUTF8 support +# dnl LOCAL_CONFIG +# dnl O SMTPUTF8=true diff --git a/contrib/sendmail/cf/cf/submit.mc b/contrib/sendmail/cf/cf/submit.mc index fc3cceec6b8f..99e58ac2629c 100644 --- a/contrib/sendmail/cf/cf/submit.mc +++ b/contrib/sendmail/cf/cf/submit.mc @@ -24,3 +24,6 @@ define(`confDONT_INIT_GROUPS', `True')dnl dnl dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] FEATURE(`msp', `[127.0.0.1]')dnl +dnl enable this for SMTPUTF8 support +dnl LOCAL_CONFIG +dnl O SMTPUTF8=true diff --git a/contrib/sendmail/cf/feature/check_cert_altnames.m4 b/contrib/sendmail/cf/feature/check_cert_altnames.m4 index 9fae74ef0a3c..baa10697fd95 100644 --- a/contrib/sendmail/cf/feature/check_cert_altnames.m4 +++ b/contrib/sendmail/cf/feature/check_cert_altnames.m4 @@ -10,7 +10,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$Id: block_bad_helo.m4,v 1.2 2013-11-22 20:51:11 ca Exp $') +VERSIONID(`$Id: check_cert_altnames.m4 1.0 2019-01-01 01:01:01 ca Exp $') divert(-1) define(`_FFR_TLS_ALTNAMES', `1') divert(6)dnl diff --git a/contrib/sendmail/cf/feature/check_other.m4 b/contrib/sendmail/cf/feature/check_other.m4 new file mode 100644 index 000000000000..fa792243e137 --- /dev/null +++ b/contrib/sendmail/cf/feature/check_other.m4 @@ -0,0 +1,46 @@ +divert(-1) +# +# Copyright (c) 2021 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# +dnl bogus Id, just here to show up in the generated cf file +divert(0) +VERSIONID(`$Id: check_other.m4,v 1.0 2021-04-30 00:01:11 ca Exp $') +divert(-1) +dnl +dnl Options: +dnl first arg: +dnl empty: use default regex +dnl else: use as regex +dnl [not implemented: NOREGEX: do not use any regex] +dnl +dnl Possible enhancements: +dnl select which SMTP reply type(s) should be allowed to match? +dnl maybe add "exceptions": +dnl - via an "OK" regex? +dnl - access map lookup for clients to be "ok" (Connect:... {ok,relay}) +dnl more args? possible matches for rejections: +dnl does not seem to worth the effort: too inflexible. +dnl +dnl Note: sendmail removes whitespace before ':' ("tokenization") +ifelse( + defn(`_ARG_'), `', `define(`CHKORX', `^[[:print:]]+ *:')', + dnl defn(`_ARG_'), `NOREGEX', `define(`CHKORX', `')', + `define(`CHKORX', defn(`_ARG_'))') +LOCAL_CONFIG +ifelse(defn(`CHKORX'), `', `', `dnl +Kbadcmd regex -m -a<BADCMD> defn(`CHKORX')') +LOCAL_RULESETS +Scheck_other +dnl accept anything that will be accepted by the MTA +R$* $| 2 $@ ok +ifelse(defn(`CHKORX'), `', `', `dnl +R$+ $| 5 $: $(badcmd $1 $) +R$*<BADCMD> $#error $@ 4.7.0 $: 421 bad command') +dnl terminate on any bad command? +dnl R$* $| 5 $#error $@ 4.7.0 $: 421 bad command diff --git a/contrib/sendmail/cf/feature/delay_checks.m4 b/contrib/sendmail/cf/feature/delay_checks.m4 index 368057c991a8..630f94072922 100644 --- a/contrib/sendmail/cf/feature/delay_checks.m4 +++ b/contrib/sendmail/cf/feature/delay_checks.m4 @@ -21,5 +21,5 @@ ifelse(defn(`_ARG_'), `', `', ') ') -dnl be backward compatible by default +dnl be backward compatible by default ifelse(len(X`'_ARG2_), `1', `define(`_DELAY_COMPAT_8_10_', 1)', `') diff --git a/contrib/sendmail/cf/feature/dnsbl.m4 b/contrib/sendmail/cf/feature/dnsbl.m4 index dd8fd52583f9..4a6969687b0b 100644 --- a/contrib/sendmail/cf/feature/dnsbl.m4 +++ b/contrib/sendmail/cf/feature/dnsbl.m4 @@ -14,7 +14,7 @@ divert(0) ifdef(`_DNSBL_R_',`dnl',`dnl VERSIONID(`$Id: dnsbl.m4,v 8.34 2013-11-22 20:51:11 ca Exp $') define(`_DNSBL_R_',`') -ifelse(defn(`_ARG_'), `', +ifelse(defn(`_ARG_'), `', `errprint(`*** ERROR: missing argument for FEATURE(`dnsbl')')') LOCAL_CONFIG # map for DNS based blocklist lookups diff --git a/contrib/sendmail/cf/feature/enhdnsbl.m4 b/contrib/sendmail/cf/feature/enhdnsbl.m4 index f0ba5c50d482..a1f5f62a004b 100644 --- a/contrib/sendmail/cf/feature/enhdnsbl.m4 +++ b/contrib/sendmail/cf/feature/enhdnsbl.m4 @@ -9,7 +9,7 @@ divert(-1) # # -ifelse(defn(`_ARG_'), `', +ifelse(defn(`_ARG_'), `', `errprint(`*** ERROR: missing argument for FEATURE(`enhdnsbl')')') divert(0) ifdef(`_EDNSBL_R_',`dnl',`dnl diff --git a/contrib/sendmail/cf/feature/nopercenthack.m4 b/contrib/sendmail/cf/feature/nopercenthack.m4 index f6c9621c970d..7f5c7485fef0 100644 --- a/contrib/sendmail/cf/feature/nopercenthack.m4 +++ b/contrib/sendmail/cf/feature/nopercenthack.m4 @@ -16,7 +16,7 @@ divert(0) VERSIONID(`$Id: nopercenthack.m4,v 8.14 2013/01/31 15:07:00 ca Exp $') divert(-1) -ifelse(defn(`_ARG_'), `', +ifelse(defn(`_ARG_'), `', `errprint(`*** ERROR: missing argument for FEATURE(nopercenthack): use `reject' or `nospecial'. See cf/README. ')define(`_NO_PERCENTHACK_', `e')', diff --git a/contrib/sendmail/cf/feature/nouucp.m4 b/contrib/sendmail/cf/feature/nouucp.m4 index 5d1ee76f4dd7..98a9d69d2efb 100644 --- a/contrib/sendmail/cf/feature/nouucp.m4 +++ b/contrib/sendmail/cf/feature/nouucp.m4 @@ -16,7 +16,7 @@ divert(0) VERSIONID(`$Id: nouucp.m4,v 8.14 2013-11-22 20:51:11 ca Exp $') divert(-1) -ifelse(defn(`_ARG_'), `', +ifelse(defn(`_ARG_'), `', `errprint(`*** ERROR: missing argument for FEATURE(nouucp): use `reject' or `nospecial'. See cf/README. ')define(`_NO_UUCP_', `e')', diff --git a/contrib/sendmail/cf/feature/sts.m4 b/contrib/sendmail/cf/feature/sts.m4 new file mode 100644 index 000000000000..54ffb96a9b9c --- /dev/null +++ b/contrib/sendmail/cf/feature/sts.m4 @@ -0,0 +1,19 @@ +divert(-1) +# +# Copyright (c) 2020 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# + +divert(-1) +define(`_MTA_STS_', `') +define(`_NEED_MACRO_MAP_', `1') +ifelse(_ARG2_,`NO_SAN_TST',`',`define(`_STS_SAN', `1')') +LOCAL_CONFIG +O StrictTransportSecurity=true +ifelse(_ARG2_,`NO_SAN_TST',`',`O SetCertAltnames=true') +Ksts ifelse(defn(`_ARG_'), `', socket -d5 -T<TMPF> inet:5461@127.0.0.1, + defn(`_NARG_'), `', `_ARG_', `_NARG_') diff --git a/contrib/sendmail/cf/m4/cfhead.m4 b/contrib/sendmail/cf/m4/cfhead.m4 index 7e5fa99e0ef5..64981a94f867 100644 --- a/contrib/sendmail/cf/m4/cfhead.m4 +++ b/contrib/sendmail/cf/m4/cfhead.m4 @@ -171,6 +171,12 @@ ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCA ')') divert(9) SLocal_srv_features') +define(`LOCAL_CLT_FEATURES', +`define(`_LOCAL_CLT_FEATURES_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_CLT_FEATURES +')') +divert(9) +SLocal_clt_features') define(`LOCAL_TRY_TLS', `define(`_LOCAL_TRY_TLS_') ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TRY_TLS @@ -213,7 +219,7 @@ define(`SITE', `ifelse(CONCAT($'2`, $3), SU, sinclude(_CF_DIR_`'siteconfig/$1.m4)') define(`EXPOSED_USER', `PUSHDIVERT(5)C{E}$1 POPDIVERT`'dnl`'') -define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1 +define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1 POPDIVERT`'dnl`'') define(`LOCAL_USER', `PUSHDIVERT(5)C{L}$1 POPDIVERT`'dnl`'') diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4 index 618dde00e24a..cfd71b3f9cad 100644 --- a/contrib/sendmail/cf/m4/proto.m4 +++ b/contrib/sendmail/cf/m4/proto.m4 @@ -183,16 +183,20 @@ ifdef(`confCR_FILE', `dnl FR`'confCR_FILE', `dnl') +ifdef(`_ACCESS_TABLE_', `dnl +define(`_FULL_TLS_CONNECTION_CHECK_', `1')', `dnl +ifdef(`_MTA_STS_', `define(`_FULL_TLS_CONNECTION_CHECK_', `1')')') define(`TLS_SRV_TAG', `"TLS_Srv"')dnl define(`TLS_CLT_TAG', `"TLS_Clt"')dnl define(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl define(`TLS_TRY_TAG', `"Try_TLS"')dnl define(`SRV_FEAT_TAG', `"Srv_Features"')dnl +define(`CLT_FEAT_TAG', `"Clt_Features"')dnl dnl this may be useful in other contexts too ifdef(`_ARITH_MAP_', `', `# arithmetic map define(`_ARITH_MAP_', `1')dnl Karith arith') -ifdef(`_ACCESS_TABLE_', `dnl +ifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl ifdef(`_MACRO_MAP_', `', `# macro storage map define(`_MACRO_MAP_', `1')dnl Kmacro macro') @@ -206,6 +210,13 @@ KCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl') ifdef(`_CERT_REGEX_SUBJECT_', `dnl # extract relevant part from cert subject KCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl') +ifdef(`_MTA_STS_', `dnl +Kstsxsni regex -a: -s3 (.*)(servername=)(.*) +Kstsxsni2 regex -a: -s2 (.*)(servername=.*) +Kstsxmatch regex -a: -s2 (match=)(.*) +# flag d: turn off DANE +Kstsxnodaneflag regex -a@ -s3 (.*)(flags=)([^;]*d)(.*) +', `dnl') ifdef(`LOCAL_RELAY', `dnl # who I send unqualified names to if `FEATURE(stickyhost)' is used @@ -502,7 +513,7 @@ _OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0') # maximum number of new connections per second _OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0') -# Width of the window +# Width of the window _OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s') # work recipient factor @@ -688,7 +699,7 @@ _OPTION(ServerKeyFile, `confSERVER_KEY', `') _OPTION(ClientCertFile, `confCLIENT_CERT', `') # Client private key _OPTION(ClientKeyFile, `confCLIENT_KEY', `') -# File containing certificate revocation lists +# File containing certificate revocation lists _OPTION(CRLFile, `confCRL', `') # Directory containing hashes pointing to certificate revocation status files _OPTION(CRLPath, `confCRL_PATH', `') @@ -868,7 +879,7 @@ R$* < @@ $+ > $* $@ $1 < @ $2 > $3 canon IP addr ifdef(`_DOMAIN_TABLE_', `dnl # look up domains in the domain table -R$* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3', `dnl') +R$* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3', `dnl') undivert(2)dnl LOCAL_RULE_3 @@ -953,14 +964,14 @@ ifdef(`_MASQUERADE_ENTIRE_DOMAIN_', ifdef(`_VIRTUSER_TABLE_', `dnl dnl virtual hosts are also canonical ifdef(`_VIRTUSER_ENTIRE_DOMAIN_', -`R$* < @ $* $={VirtHost} > $* $: $1 < @ $2 $3 . > $4', -`R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3')', +`R$* < @ $* $={VirtHost} > $* $: $1 < @ $2 $3 . > $4', +`R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3')', `dnl') ifdef(`_GENERICS_TABLE_', `dnl dnl hosts for genericstable are also canonical ifdef(`_GENERICS_ENTIRE_DOMAIN_', -`R$* < @ $* $=G > $* $: $1 < @ $2 $3 . > $4', -`R$* < @ $=G > $* $: $1 < @ $2 . > $3')', +`R$* < @ $* $=G > $* $: $1 < @ $2 $3 . > $4', +`R$* < @ $=G > $* $: $1 < @ $2 . > $3')', `dnl') dnl remove superfluous dots (maybe repeatedly) which may have been added dnl by one of the rules before @@ -1062,7 +1073,7 @@ R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ... R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here R< @ $+ > $#error $@ 5.1.3 $: "_CODE553 User address required" R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ... -R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" +R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" R< @ *LOCAL* > $#error $@ 5.1.3 $: "_CODE553 User address required" R$* $=O $* < @ *LOCAL* > $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... @@ -1105,17 +1116,17 @@ dnl are identical, i.e., if address A is mapped to A. dnl it does not deal with multi-level recursion # handle full domains in RHS of virtusertable R$+ < @ $+ > $: $(macro {RecipientAddress} $) $1 < @ $2 > -R$+ < @ $+ > $: <?> $1 < @ $2 > $| $>final $1 < @ $2 > +R$+ < @ $+ > $: <?> $1 < @ $2 > $| $>final $1 < @ $2 > R<?> $+ $| $+ $: $1 $(macro {RecipientAddress} $@ $2 $) R<?> $+ $| $* $: $1', `dnl') R$+ $: <!> $1 Mark for lookup dnl input: <!> local<@domain> ifdef(`_VIRTUSER_ENTIRE_DOMAIN_', -`R<!> $+ < @ $* $={VirtHost} . > $: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >', -`R<!> $+ < @ $={VirtHost} . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >') +`R<!> $+ < @ $* $={VirtHost} . > $: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >', +`R<!> $+ < @ $={VirtHost} . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >') dnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain> -R<!> $+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . > +R<!> $+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . > dnl if <@> local<@domain>: no match but try lookup dnl user+detail: try user++@domain if detail not empty R<@> $+ + $+ < @ $* . > @@ -1140,14 +1151,14 @@ dnl no match R<@> $+ $: $1 dnl remove mark R<!> $+ $: $1 -R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 -R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2 +R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 +R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2 ifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl # check virtuser input address against output address, if same, skip recursion R< $+ > $+ < @ $+ > $: < $1 > $2 < @ $3 > $| $1 # it is the same: stop now R< $+ > $+ < @ $+ > $| $&{RecipientAddress} $: $>ParseLocal $>Parse0 $>canonify $1 -R< $+ > $+ < @ $+ > $| $* $: < $1 > $2 < @ $3 > +R< $+ > $+ < @ $+ > $| $* $: < $1 > $2 < @ $3 > dnl', `dnl') dnl this is not a documented option dnl it performs no looping at all for virtusertable @@ -1176,7 +1187,7 @@ R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name R< $+ . > $* $: < $1 > $2 strip trailing dot R< $+ > $* $: < $(mailertable $1 $) > $2 lookup dnl it is $~[ instead of $- to avoid matches on IPv6 addresses -R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 check -- resolved? +R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 check -- resolved? R< $+ > $* $: $>Mailertable <$1> $2 try domain', `dnl') undivert(4)dnl UUCP rules from `MAILER(uucp)' @@ -1285,7 +1296,7 @@ R< > $+ + $* $: < ? $L > <+ $2> $(user $1 $) look up user+ R< > $+ $: < ? $L > < > $(user $1 $) look up user R< ? $* > < $* > $+ <> $: < > $3 $2 found; strip $L R< ? $* > < $* > $+ $: < $1 > $3 $2 not found', ` -R< > $+ $: < $L > $(user $1 $) look up user +R< > $+ $: < $L > $(user $1 $) look up user R< $* > $+ <> $: < > $2 found; strip $L') ifdef(`_PRESERVE_LUSER_HOST_', `dnl R< $+ > $+ $: < $1 > $2 $&{Host}') @@ -1336,7 +1347,7 @@ R< $+ > $* $#_RELAY_ $@ $1 $: $2 not found, direct relay', `dnl') ################################################################### -### Ruleset 90 -- try domain part of mailertable entry ### +### Ruleset 90 -- try domain part of mailertable entry ### dnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress ################################################################### @@ -1346,7 +1357,7 @@ dnl %2 is not documented in cf/README R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4 dnl it is $~[ instead of $- to avoid matches on IPv6 addresses R$* <$~[ : $* > $* $>MailerToTriple < $2 : $3 > $4 check -- resolved? -R$* < . $+ > $* $@ $>Mailertable $1 . <$2> $3 no -- strip & try again +R$* < . $+ > $* $@ $>Mailertable $1 . <$2> $3 no -- strip & try again dnl is $2 always empty? R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "." R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 "." found? @@ -1369,7 +1380,7 @@ dnl <host> address -> relay host address SMailerToTriple=95 R< > $* $@ $1 strip off null relay -R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 +R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2 R< error : $+ > $* $#error $: $1 R< local : $* > $* $>CanonLocal < $1 > $2 @@ -1408,7 +1419,7 @@ R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 > # handle local:user syntax R< $+ > $* <@ $* > $* $#_LOCAL_ $@ $2@$3 $: $1 -R< $+ > $* $#_LOCAL_ $@ $2 $: $1 +R< $+ > $* $#_LOCAL_ $@ $2 $: $1 ################################################################### ### Ruleset 93 -- convert header names to masqueraded form ### @@ -1440,9 +1451,9 @@ dnl no match, try @domain for exceptions R< > $+ < @ $+ . > $: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . > dnl workspace: ... or <match> user <@domain> dnl no match, try local part -R< > $+ < @ $+ > $: < $(generics $1 $: $) > $1 < @ $2 > -R< > $+ + $* < @ $+ > $: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 > -R< > $+ + $* < @ $+ > $: < $(generics $1 $: $) > $1 + $2 < @ $3 > +R< > $+ < @ $+ > $: < $(generics $1 $: $) > $1 < @ $2 > +R< > $+ + $* < @ $+ > $: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 > +R< > $+ + $* < @ $+ > $: < $(generics $1 $: $) > $1 + $2 < @ $3 > R< $* @ $* > $* < $* > $@ $>canonify $1 @ $2 found qualified R< $+ > $* < $* > $: $>canonify $1 @ *LOCAL* found unqualified R< > $* $: $1 not found', @@ -1594,7 +1605,7 @@ dnl must not be empty ### + does lookup with and without tag ### <$4> -- passthru (additional data passed unchanged through) dnl returns: <default> <passthru> -dnl <result> <passthru> +dnl <result> <passthru> ###################################################################### SD @@ -2183,10 +2194,10 @@ R$* $| $* $: $1 dnl workspace: localpart<@domain> | localpart ifelse(defn(`_NO_UUCP_'), `r', `R$* ! $* < @ $* > $: <REMOTE> $2 < @ BANG_PATH > -R$* ! $* $: <REMOTE> $2 < @ BANG_PATH >', `dnl') +R$* ! $* $: <REMOTE> $2 < @ BANG_PATH >', `dnl') ifelse(defn(`_NO_PERCENTHACK_'), `r', `R$* % $* < @ $* > $: <REMOTE> $1 < @ PERCENT_HACK > -R$* % $* $: <REMOTE> $1 < @ PERCENT_HACK >', `dnl') +R$* % $* $: <REMOTE> $1 < @ PERCENT_HACK >', `dnl') # anything terminating locally is ok ifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl R$+ < @ $* $=m > $@ RELAY', `dnl') @@ -2273,13 +2284,13 @@ RIPv6:::1 $@ RELAY originated locally R$=R $* $@ RELAY relayable IP address ifdef(`_ACCESS_TABLE_', `dnl R$* $: $>A <$1> <?> <+ Connect> <$1> -R<RELAY> $* $@ RELAY relayable IP address +R<RELAY> $* $@ RELAY relayable IP address ifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl dnl this will cause rejections in cases like: dnl Connect:My.Host.Domain RELAY dnl Connect:My.Net REJECT dnl since in check_relay client_name is checked before client_addr -R<REJECT> $* $@ REJECT rejected IP address') +R<REJECT> $* $@ REJECT rejected IP address') ifdef(`_ATMPF_', `R<_ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl') R<$*> <$*> $: $2', `dnl') R$* $: [ $1 ] put brackets around it... @@ -2326,7 +2337,7 @@ dnl nevertheless, removing the rule doesn't hurt. dnl R<@> $@ RELAY dnl workspace: <@> ${client_name} (not empty) # pass to name server to make hostname canonical -R<@> $* $=P $:<?> $1 $2 +R<@> $* $=P $:<?> $1 $2 R<@> $+ $:<?> $[ $1 $] dnl workspace: <?> ${client_name} (canonified) R$* . $1 strip trailing dots @@ -2471,7 +2482,7 @@ dnl must not be empty ### + does lookup with and without tag ### <$4> -- passthru (additional data passed unchanged through) dnl returns: <default> <passthru> -dnl <result> <passthru> +dnl <result> <passthru> ###################################################################### SF @@ -2520,7 +2531,7 @@ dnl must not be empty ### + does lookup with and without tag ### <$4> -- passthru (additional data passed unchanged through) dnl returns: <default> <passthru> -dnl <result> <passthru> +dnl <result> <passthru> ###################################################################### SE @@ -2554,7 +2565,7 @@ dnl must not be empty ### + does lookup with and without tag ### <$4> -- passthru (additional data passed unchanged through) dnl returns: <default> <passthru> -dnl <result> <passthru> +dnl <result> <passthru> ###################################################################### SU @@ -2686,6 +2697,24 @@ R<$* _ATMPF_>$* $#temp', `dnl') R<$+>$* $# $1') ###################################################################### +### clt_features: which features to use with a server? +### (done in client) +###################################################################### +Sclt_features +ifdef(`_LOCAL_CLT_FEATURES_', `dnl +R$* $: $1 $| $>"Local_clt_features" $1 +R$* $| $#$* $#$2 +R$* $| $* $: $1', `dnl') +ifdef(`_ACCESS_TABLE_', `dnl +R$* $: $>D <$&{client_name}> <?> <! CLT_FEAT_TAG> <> +R<?>$* $: $>A <$&{client_addr}> <?> <! CLT_FEAT_TAG> <> +R<?>$* $: <$(access CLT_FEAT_TAG`'_TAG_DELIM_ $: ? $)> +R<?>$* $@ OK +ifdef(`_ATMPF_', `dnl tempfail? +R<$* _ATMPF_>$* $#temp', `dnl') +R<$+>$* $# $1') + +###################################################################### ### try_tls: try to use STARTTLS? ### (done in client) ###################################################################### @@ -2703,6 +2732,76 @@ ifdef(`_ATMPF_', `dnl tempfail? R<$* _ATMPF_>$* $#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl') R<NO>$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"') +ifdef(`_MTA_STS_', `dnl +STLS_NameInList +R$* :$&{TLS_Name}: $* $@ ok +R$* $@ $1 + +dnl check SAN for STS +SSTS_SAN +ifdef(`_STS_SAN', `dnl +R$* $: $&{server_name} +dnl exact match +R$={cert_altnames} $@ ok +# strip only one level (no recursion!) +R$-.$+ $: $2 +dnl wildcard: *. or just .? +R *.$={cert_altnames} $@ ok +dnl R .$={cert_altnames} $@ ok +dnl always temporary error? make it an option (of the feature)? +R$* $#error $@ 4.7.0 $: 450 $&{server_name} not listed in SANs', `dnl') + +dnl input: ${verify} +dnl output: $# error ... (from TLS_connection) +dnl everything else: ok +SSTS_secure +R$* $: $&{rcpt_addr} $| $1 +# no {rcpt_addr}, no STS check +R $| $* $@ ok +dnl canonify to extract domain part? +R$*@$+ $| $* $2 $| $3 +R$+. $| $* $1 $| $2 +R$+ $| $* $: $(sts $1 $: none $) $| $2 +R$* <TMPF> $| $* $#error $@ 4.7.0 $: 450 STS lookup temp fail +dnl check whether connection is "secure" +dnl always temporary error? make it an option (of the feature)? +R$* secure $* $| $* $@ $>"TLS_connection" $3 $| <TEMP+VERIFY:128> +R$* $| $* $: $2 + +dnl check STS policy: secure and match? if so, check list +SSTS_Check +R$* $: $&{rcpt_addr} $| $1 +# no {rcpt_addr}, no STS check +R $| $* $@ ok +# use the original argument for the test, not {rcpt_addr} +R$* $| $* $: $2 $| $2 +dnl canonify to extract domain part? +R$*@$+ $| $* $2 $| $3 +R$+. $| $* $1 $| $2 +R$* $| $* $: $(sts $1 $: none $) $| mark +R$* <TMPF> $| $* $#error $@ 4.7.0 $: 450 STS lookup temp fail +dnl STS check only for "secure" +dnl do this only if {sts_sni} is set? +dnl workspace: result of sts lookup $| mark +R$* secure $* $| mark $: $2 $| trmatch +dnl not "secure": no check +R$* $| mark $@ ok +dnl remove servername=hostname, keep match= +R$* servername=hostname $| trmatch $: $1 $| trmatch +dnl extra list of matches, i.e., remove match= +R$+ $| trmatch $: : $(stsxmatch $1 $: : $) +dnl no match= data +R$* $| trmatch $@ $>STS_SAN +dnl Remove trailing dots from each entry in the list; +dnl those should not be there, but better safe than sorry. +R$*:$+.:$* $1:$2:$3 +R:$+: $: $(macro {TLS_Name} $@ $&{server_name} $) $>TLS_NameInList :$1: +R$* ok $@ $>STS_SAN +R$* $: $1 $| $&{server_name} +R:$* $| $-.$+ $: $(macro {TLS_Name} $@ .$3 $) $>TLS_NameInList :$1 +R$* ok $@ $>STS_SAN +R:$*: $#error $@ 4.7.0 $: 450 $&{server_name} not found in " "$1', `dnl') + ###################################################################### ### tls_rcpt: is connection with server "good" enough? ### (done in client, per recipient) @@ -2716,6 +2815,10 @@ ifdef(`_LOCAL_TLS_RCPT_', `dnl R$* $: $1 $| $>"Local_tls_rcpt" $1 R$* $| $#$* $#$2 R$* $| $* $: $1', `dnl') +ifdef(`_MTA_STS_', `dnl +R$* $: $1 $| $>"STS_Check" $1 +R$* $| $#$* $#$2 +R$* $| $* $: $1', `dnl') ifdef(`_ACCESS_TABLE_', `dnl dnl store name of other side R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 @@ -2783,6 +2886,10 @@ R$* $| $#$* $#$2 R$* $| $* $: $1', `dnl') ifdef(`_TLS_FAILURES_',`dnl R$* $: $(macro {saved_verify} $@ $1 $) $1') +ifdef(`_MTA_STS_', `dnl +R$* $: $1 $| $>"STS_secure" $1 +R$* $| $#$* $#$2 +R$* $| $* $: $1', `dnl') ifdef(`_ACCESS_TABLE_', `dnl dnl store name of other side R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 @@ -2808,11 +2915,22 @@ dnl [(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions] dnl extensions: could be a list of further requirements dnl for now: CN:string {cn_subject} == string ###################################################################### +ifdef(`TLS_PERM_ERR', `dnl +define(`TLS_DSNCODE', `5.7.0')dnl +define(`TLS_ERRCODE', `554')',`dnl +define(`TLS_DSNCODE', `4.7.0')dnl +define(`TLS_ERRCODE', `454')')dnl +define(`SW_MSG', `TLS handshake failed.')dnl +define(`DANE_MSG', `DANE check failed.')dnl +define(`PROT_MSG', `STARTTLS failed.')dnl +define(`CNF_MSG', `STARTTLS temporarily not possible.')dnl STLS_connection -ifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error +ifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl', `dnl use default error dnl deal with TLS handshake failures: abort -RSOFTWARE $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake." -RDANE_FAIL $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed." +RSOFTWARE $#error $@ TLS_DSNCODE $: "TLS_ERRCODE SW_MSG" +RDANE_FAIL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG" +RPROTOCOL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE PROT_MSG" +RCONFIG $#error $@ TLS_DSNCODE $: "TLS_ERRCODE CNF_MSG" divert(-1)') dnl common ruleset for tls_{client|server} dnl input: ${verify} $| <ResultOfLookup> [<>] @@ -2824,23 +2942,21 @@ dnl permanent or temporary error? R$* $| <PERM + $={Tls} $*> $: $1 $| <503:5.7.0> <$2 $3> R$* $| <TEMP + $={Tls} $*> $: $1 $| <403:4.7.0> <$2 $3> dnl default case depends on TLS_PERM_ERR -R$* $| <$={Tls} $*> $: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3> +R$* $| <$={Tls} $*> $: $1 $| <TLS_ERRCODE:TLS_DSNCODE> <$2 $3> dnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup> -# deal with TLS handshake failures: abort -RSOFTWARE $| <$-:$+> $* $#error $@ $2 $: $1 " TLS handshake failed." +define(`TLS_ERRORS', `dnl +R`'$1 $| <$-:$+> $`'* $`'#error $`'@ $`'2 $: $`'1 " $2" dnl no <reply:dns> i.e. no requirements in the access map dnl use default error -RSOFTWARE $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed." +R`'$1 $| $`'* $`'#error $`'@ TLS_DSNCODE $: "TLS_ERRCODE $2"')dnl +# deal with TLS handshake failures: abort +TLS_ERRORS(SOFTWARE,SW_MSG) # deal with TLS protocol errors: abort -RPROTOCOL $| <$-:$+> $* $#error $@ $2 $: $1 " STARTTLS failed." -dnl no <reply:dns> i.e. no requirements in the access map -dnl use default error -RPROTOCOL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed." +TLS_ERRORS(PROTOCOL,PROT_MSG) # deal with DANE errors: abort -RDANE_FAIL $| <$-:$+> $* $#error $@ $2 $: $1 " DANE check failed." -dnl no <reply:dns> i.e. no requirements in the access map -dnl use default error -RDANE_FAIL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed." +TLS_ERRORS(DANE_FAIL,DANE_MSG) +# deal with CONFIG (tls_clt_features) errors: abort +TLS_ERRORS(CONFIG,CNF_MSG) R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1 dnl separate optional requirements R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1 @@ -2958,25 +3074,116 @@ R$-:$-:$- $: $2 dnl endif _ACCESS_TABLE_ divert(0) +dnl this must also be activated without _TLS_SESSION_FEATURES_ +ifdef(`_MTA_STS_', `dnl +dnl caller preserves workspace +SSet_SNI +R$* $: <$&{rcpt_addr}> +# no {rcpt_addr}, no STS check +R<> $@ "" +dnl canonify to extract domain part? +R<$*@$+> $2 +R$+. $1 +R$+ $: $(sts $1 $: none $) +R$* <TMPF> $#error $@ 4.7.0 $: 450 STS lookup temp fail +Rnone $@ "" +dnl get servername=sni and store it in {sts_sni} +dnl stsxsni extracts the value of servername= (sni) +dnl stsxsni2 extracts servername=sni so it can be returned to the caller +R$* secure $* $: $(stsxsni $2 $: : $) $| sts=secure; $(stsxsni2 $2 $: : $) +dnl store {server_addr} as sni if there was a match +dnl Note: this implies that only servername=hostname (literally!) +dnl is only ever returned. +R$+: $| $+ : $: $(macro {sts_sni} $@ $&{server_name} $) set $| $2 +R$* $| $* $@ $2 +R$* $@ "" +dnl', `dnl') + ifdef(`_TLS_SESSION_FEATURES_', `dnl +define(`_NEED_TLS_CLT_FEATURES') Stls_srv_features ifdef(`_ACCESS_TABLE_', `dnl R$* $| $* $: $>D <$1> <?> <! TLS_Srv_Features> <$2> -R<?> <$*> $: $>A <$1> <?> <! TLS_Srv_Features> <$1> -R<?> <$*> $@ "" -R<$+> <$*> $@ $1 +R<?> <$*> $: $>A <$1> <?> <! TLS_Srv_Features> <$1> +R<?> <$*> $@ "" +R<$+> <$*> $@ $1 +', `dnl +R$* $@ ""') ', `dnl -R$* $@ ""') +ifdef(`_MTA_STS_',`define(`_NEED_TLS_CLT_FEATURES')')dnl +')dnl -Stls_clt_features +ifdef(`_NEED_TLS_CLT_FEATURES', `dnl ifdef(`_ACCESS_TABLE_', `dnl +Stls_clt_feat_acc R$* $| $* $: $>D <$1> <?> <! TLS_Clt_Features> <$2> -R<?> <$*> $: $>A <$1> <?> <! TLS_Clt_Features> <$1> -R<?> <$*> $@ "" -R<$+> <$*> $@ $1 -', `dnl -R$* $@ ""') -') +R<?> <$*> $: $>A <$1> <?> <! TLS_Clt_Features> <$1> +R<?> <$*> $@ "" +R<$+> <$*> $@ $1') + +SDANE_disabled +dnl Note: most of this is handled in the binary. +dnl input: access map lookup for tls_clt_features +dnl output: +dnl <>: disabled +dnl <DANE>: enabled +R$+ $: < $(stsxnodaneflag $1 $: NOFLAGS $) > +R<$* @> $@ <> +R$* $: < $&{sts_sni} > +R<> $@ <> +# check this too? +# R$* $: $&{client_flags} +# R$* DD $* $@ <> +R$* $@ <DANE> + +SSTS_disabled +dnl input: ignored +dnl output: +dnl <>: disabled +dnl <STS>: enabled +R$* $: $&{client_flags} +R$* MM $* $@ <> +dnl +R$* $: $&{rcpt_addr} $| $1 +# no {rcpt_addr}, no STS check +R $| $* $@ <> +R$* $@ <STS> + +Stls_clt_features +dnl host $| ip +R$* $: $1 $| <> +ifdef(`_ACCESS_TABLE_', `dnl +R$* $| <> $: $1 $| $>"tls_clt_feat_acc" $1 +R$* $| $* $| $* $: $1 $| $2 $| <$3>', `dnl') +ifdef(`_MTA_STS_', `dnl +dnl host $| ip $| <acc result - might be empty> +R$* $| $* $| <$*> $: $1 $| $2 $| <$3> $| $>"STS_disabled" sts +dnl host $| ip $| <acc result - might be empty> $| STS_disabled result +dnl disable STS check? return access result +R$* $| $* $| <$*> $| <> $@ $3 +dnl host $| ip $| <acc result - might be empty> $| STS_disabled result +R$* $| $* $| <$*> $| $* $: $1 $| $2 $| <$3> $| $>"DANE_disabled" $3 +dnl DANE enabled: return access result; take care of empty return +R$* $| $* $| <$+> $| <DANE> $@ $3 +R$* $| $* $| <> $| <DANE> $@ "" +dnl host $| ip $| <acc result - might be empty> $| <DANE_disabled result> +R$* $| $* $| <$*> $| <$*> $: $1 $| $2 $| <$3> $| $>"Set_SNI" $1 +dnl host $| ip $| <acc result - might be empty> $| sni result +dnl return sni result if not empty but acc is +R$* $| $* $| <""> $| $+ $@ $3 +dnl return acc + sni result if not empty +R$* $| $* $| <$+;> $| $+ $@ $3 ; $4 +dnl return acc + sni result if not empty +R$* $| $* $| <$+> $| $+ $@ $3 ; $4 +dnl return sni result if not empty +R$* $| $* $| <> $| $+ $@ $3 +dnl remove sni result +R$* $| $* $| $* $| $* $: $1 $| $2 $| $3 +', `dnl') +dnl host $| ip $| <acc result - might be empty> +R$* $| $* $| <""> $@ "" +R$* $| $* $| <$+> $@ $3 +R$* $@ ""') ###################################################################### ### RelayTLS: allow relaying based on TLS authentication @@ -3046,7 +3253,7 @@ dnl', `dnl')') ifdef(`_RATE_CONTROL_',`dnl ###################################################################### -### RateControl: +### RateControl: ### Parameters: ignored ### return: $#error or OK ###################################################################### @@ -3068,7 +3275,7 @@ R<$+> $| TRUE $#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exce ifdef(`_CONN_CONTROL_',`dnl ###################################################################### -### ConnControl: +### ConnControl: ### Parameters: ignored ### return: $#error or OK ###################################################################### @@ -3108,3 +3315,10 @@ _MAIL_FILTERS_ ###################################################################### undivert(7)dnl MAILER_DEFINITIONS + +dnl Helper ruleset for -bt mode to invoke rulesets +dnl which take two arguments separated by $| +dnl For example: +dnl Start,check_relay host.name $| I.P.V.4 +dnl SStart +dnl R$* $$| $* $: $1 $| $2 diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4 index dadff627bb2e..3942ca1a0691 100644 --- a/contrib/sendmail/cf/m4/version.m4 +++ b/contrib/sendmail/cf/m4/version.m4 @@ -15,4 +15,4 @@ VERSIONID(`$Id: version.m4,v 8.237 2014-01-27 12:55:17 ca Exp $') # divert(0) # Configuration version number -DZ8.16.1`'ifdef(`confCF_VERSION', `/confCF_VERSION') +DZ8.17.1`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/contrib/sendmail/cf/mailer/local.m4 b/contrib/sendmail/cf/mailer/local.m4 index 85d24f32a2a6..1a9e4a3a1309 100644 --- a/contrib/sendmail/cf/mailer/local.m4 +++ b/contrib/sendmail/cf/mailer/local.m4 @@ -79,7 +79,7 @@ R$* $: $>MasqHdr $1 do all-masquerading')', # SAddDomain ifdef(`_ALWAYS_ADD_DOMAIN_', `dnl -R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified +R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified ifelse(len(X`'_ALWAYS_ADD_DOMAIN_),`1',` R$+ $@ $1 < @ *LOCAL* > add local qualification', `R$+ $@ $1 < @ _ALWAYS_ADD_DOMAIN_ > add qualification')', |