JSON lookup
[users/jgh/exim.git] / doc / doc-txt / experimental-spec.txt
index 839200c6cd0923d63bfbb92bfd55431ea21b6a2b..d5a75f5b3154306fab232e318ef0ff317315e447 100644 (file)
@@ -430,14 +430,13 @@ package controlled locations (/usr/include and /usr/lib).
 
 2. Use the following global settings to configure DMARC:
 
-Optional:
+Required:
 dmarc_tld_file      Defines the location of a text file of valid
                     top level domains the opendmarc library uses
                     during domain parsing. Maintained by Mozilla,
                     the most current version can be downloaded
                     from a link at http://publicsuffix.org/list/.
-                    If unset, "/etc/exim/opendmarc.tlds" (hardcoded)
-                    is used.
+                    See also util/renew-opendmarc-tlds.sh script.
 
 Optional:
 dmarc_history_file  Defines the location of a file to log results
@@ -448,11 +447,19 @@ dmarc_history_file  Defines the location of a file to log results
                     directory of this file is writable by the user
                     exim runs as.
 
-dmarc_forensic_sender The email address to use when sending a
+dmarc_forensic_sender Alternate email address to use when sending a
                     forensic report detailing alignment failures
                     if a sender domain's dmarc record specifies it
                     and you have configured Exim to send them.
-                    Default: do-not-reply@$default_hostname
+
+                   If set, this is expanded and used for the
+                   From: header line; the address is extracted
+                   from it and used for the envelope from.
+                   If not set, the From: header is expanded from
+                   the dsn_from option, and <> is used for the
+                   envelope from.
+
+                    Default: unset.
 
 
 3. By default, the DMARC processing will run for any remote,
@@ -525,6 +532,9 @@ Of course, you can also use any other lookup method that Exim
 supports, including LDAP, Postgres, MySQL, etc, as long as the
 result is a list of colon-separated strings.
 
+Performing the check sets up information used by the
+${authresults } expansion item.
+
 Several expansion variables are set before the DATA ACL is
 processed, and you can use them in this ACL.  The following
 expansion variables are available:
@@ -548,9 +558,8 @@ expansion variables are available:
     are "none", "reject" and "quarantine".  It is blank when there
     is any error, including no DMARC record.
 
-  o $dmarc_ar_header
-    This is the entire Authentication-Results header which you can
-    add using an add_header modifier.
+A now-redundant variable $dmarc_ar_header has now been withdrawn.
+Use the ${authresults } expansion instead.
 
 
 5. How to enable DMARC advanced operation:
@@ -590,7 +599,6 @@ b. Configure, somewhere before the DATA ACL, the control option to
   warn    dmarc_status   = accept : none : off
           !authenticated = *
           log_message    = DMARC DEBUG: $dmarc_status $dmarc_used_domain
-          add_header     = $dmarc_ar_header
 
   warn    dmarc_status   = !accept
           !authenticated = *
@@ -609,6 +617,8 @@ b. Configure, somewhere before the DATA ACL, the control option to
           !authenticated = *
           message        = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
 
+  warn    add_header     = :at_start:${authresults {$primary_hostname}}
+
 
 
 DSN extra information
@@ -707,6 +717,8 @@ an external directory retaining the exim spool format.
 
 The spool files can then be processed by external processes and then
 requeued into exim spool directories for final delivery.
+However, note carefully the warnings in the main documentation on
+qpool file formats.
 
 The motivation/inspiration for the transport is to allow external
 processes to access email queued by exim and have access to all the
@@ -723,7 +735,7 @@ the queuefile driver.
 The transport only takes one option:
 
 * directory - This is used to specify the directory messages should be
-copied to
+copied to.  Expanded.
 
 The generic transport options (body_only, current_directory, disable_logging,
 debug_print, delivery_date_add, envelope_to_add, event_action, group,
@@ -791,17 +803,184 @@ standard header.
        Note that it would be wise to strip incoming messages of A-R headers
        that claim to be from our own <admd-identifier>.
 
-There are two new variables: $arc_state and $arc_state_reason.
+There are four new variables:
+
+  $arc_state           One of pass, fail, none
+  $arc_state_reason    (if fail, why)
+  $arc_domains         colon-sep list of ARC chain domains, in chain order.
+                       problematic elements may have empty list elements
+  $arc_oldest_pass     lowest passing instance number of chain
+
+Example:
+  logwrite = oldest-p-ams: <${reduce {$lh_ARC-Authentication-Results:} \
+                               {} \
+                               {${if = {$arc_oldest_pass} \
+                                       {${extract {i}{${extract {1}{;}{$item}}}}} \
+                                       {$item} {$value}}} \
+                           }>
 
 Receive log lines for an ARC pass will be tagged "ARC".
 
 
 Signing
 --
-arc_sign = <admd-identifier> : <selector> : <privkey>
+arc_sign = <admd-identifier> : <selector> : <privkey> [ : <options> ]
 An option on the smtp transport, which constructs and prepends to the message
 an ARC set of headers.  The textually-first Authentication-Results: header
 is used as a basis (you must have added one on entry to the ADMD).
+Expanded as a whole; if unset, empty or forced-failure then no signing is done.
+If it is set, all of the first three elements must be non-empty.
+
+The fourth element is optional, and if present consists of a comma-separated list
+of options.  The options implemented are
+
+  timestamps           Add a t= tag to the generated AMS and AS headers, with the
+                       current time.
+  expire[=<val>]       Add an x= tag to the generated AMS header, with an expiry time.
+                       If the value <val> is an plain number it is used unchanged.
+                       If it starts with a '+' then the following number is added
+                       to the current time, as an offset in seconds.
+                       If a value is not given it defaults to a one month offset.
+
+[As of writing, gmail insist that a t= tag on the AS is mandatory]
+
+Caveats:
+ * There must be an Authentication-Results header, presumably added by an ACL
+   while receiving the message, for the same ADMD, for arc_sign to succeed.
+   This requires careful coordination between inbound and outbound logic.
+
+   Only one A-R header is taken account of.  This is a limitation versus
+   the ARC spec (which says that all A-R headers from within the ADMD must
+   be used).
+
+ * If passing a message to another system, such as a mailing-list manager
+   (MLM), between receipt and sending, be wary of manipulations to headers made
+   by the MLM.
+   + For instance, Mailman with REMOVE_DKIM_HEADERS==3 might improve
+     deliverability in a pre-ARC world, but that option also renames the
+     Authentication-Results header, which breaks signing.
+
+ * Even if you use multiple DKIM keys for different domains, the ARC concept
+   should try to stick to one ADMD, so pick a primary domain and use that for
+   AR headers and outbound signing.
+
+Signing is not compatible with cutthrough delivery; any (before expansion)
+value set for the option will result in cutthrough delivery not being
+used via the transport in question.
+
+
+
+
+REQUIRETLS support
+------------------
+Ref: https://tools.ietf.org/html/draft-ietf-uta-smtp-require-tls-03
+
+If compiled with EXPERIMENTAL_REQUIRETLS support is included for this
+feature, where a REQUIRETLS option is added to the MAIL command.
+The client may not retry in clear if the MAIL+REQUIRETLS fails (or was never
+offered), and the server accepts an obligation that any onward transmission
+by SMTP of the messages accepted will also use REQUIRETLS - or generate a
+fail DSN.
+
+The Exim implementation includes
+- a main-part option tls_advertise_requiretls; host list, default "*"
+- an observability variable $requiretls returning yes/no
+- an ACL "control = requiretls" modifier for setting the requirement
+- Log lines and Received: headers capitalise the S in the protocol
+  element: "P=esmtpS"
+
+Differences from spec:
+- we support upgrading the requirement for REQUIRETLS, including adding
+  it from cold, within an MTA.  The spec only define the sourcing MUA
+  as being able to source the requirement, and makes no mention of upgrade.
+- No support is coded for the RequireTLS header (which can be used
+  to annul DANE and/or STS policiy). [this can _almost_ be done in
+  transport option expansions, but not quite: it requires tha DANE-present
+  but STARTTLS-failing targets fallback to cleartext, which current DANE
+  coding specifically blocks]
+
+Note that REQUIRETLS is only advertised once a TLS connection is achieved
+(in contrast to STARTTLS).  If you want to check the advertising, do something
+like "swaks -s 127.0.0.1 -tls -q HELO".
+
+
+
+
+Early pipelining support
+------------------------
+Ref: https://datatracker.ietf.org/doc/draft-harris-early-pipe/
+
+If compiled with EXPERIMENTAL_PIPE_CONNECT support is included for this feature.
+The server advertises the feature in its EHLO response, currently using the name
+"X_PIPE_CONNECT" (this will change, some time in the future).
+A client may cache this information, along with the rest of the EHLO response,
+and use it for later connections.  Those later ones can send esmtp commands before
+a banner is received.
+
+Up to 1.5 roundtrip times can be taken out of cleartext connections, 2.5 on
+STARTTLS connections.
+
+In combination with the traditional PIPELINING feature the following example
+sequences are possible (among others):
+
+(client)                (server)
+
+EHLO,MAIL,RCPT,DATA ->
+                     <- banner,EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+message-data        ->
+------
+
+EHLO,MAIL,RCPT,BDAT              ->
+                                  <- banner,EHLO-resp,MAIL-ack,RCPT-ack
+message-data                     ->
+------
+
+EHLO,STARTTLS                     ->
+                                   <- banner,EHLO-resp,TLS-goahead
+TLS1.2-client-hello               ->
+                                   <- TLS-server-hello,cert,hello-done
+client-Kex,change-cipher,finished ->
+                                   <- change-cipher,finshed
+EHLO,MAIL,RCPT,DATA               ->
+                                   <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+
+------
+(tls-on-connect)
+TLS1.2-client-hello               ->
+                                   <- TLS-server-hello,cert,hello-done
+client-Kex,change-cipher,finished ->
+                                   <- change-cipher,finshed
+                                   <- banner
+EHLO,MAIL,RCPT,DATA               ->
+                                   <- EHLO-resp,MAIL-ack,RCPT-ack,DATA-goahead
+
+Where the initial client packet is SMTP, it can combine with the TCP Fast Open
+feature and be sent in the TCP SYN.
+
+
+A main-section option "pipelining_connect_advertise_hosts" (default: *)
+and an smtp transport option "hosts_pipe_connect" (default: unset)
+control the feature.
+
+If the "pipelining" log_selector is enabled, the "L" field in server <=
+log lines has a period appended if the feature was advertised but not used;
+or has an asterisk appended if the feature was used.  In client => lines
+the "L" field has an asterisk appended if the feature was used.
+
+The "retry_data_expire" option controls cache invalidation.
+Entries are also rewritten (or cleared) if the adverised features
+change.
+
+
+NOTE: since the EHLO command must be constructed before the connection is
+made it cannot depend on the interface IP address that will be used.
+Transport configurations should be checked for this.  An example avoidance:
+
+ helo_data =   ${if def:sending_ip_address \
+                  {${lookup dnsdb{>! ptr=$sending_ip_address} \
+                       {${sg{$value} {^([^!]*).*\$} {\$1}}} fail}} \
+                  {$primary_hostname}}
+