+
+
+
+.section "SPF (Sender Policy Framework)" SECSPF
+.cindex SPF verification
+
+SPF is a mechanism whereby a domain may assert which IP addresses may transmit
+messages with its domain in the envelope from, documented by RFC 7208.
+For more information on SPF see &url(http://www.openspf.org).
+. --- 2018-09-07: still not https
+
+Messages sent by a system not authorised will fail checking of such assertions.
+This includes retransmissions done by traditional forwarders.
+
+SPF verification support is built into Exim if SUPPORT_SPF=yes is set in
+&_Local/Makefile_&. The support uses the &_libspf2_& library
+&url(https://www.libspf2.org/).
+There is no Exim involvement in the transmission of messages;
+publishing certain DNS records is all that is required.
+
+For verification, an ACL condition and an expansion lookup are provided.
+.cindex authentication "expansion item"
+Performing verification sets up information used by the
+&$authresults$& expansion item.
+
+
+.cindex SPF "ACL condition"
+.cindex ACL "spf condition"
+The ACL condition "spf" can be used at or after the MAIL ACL.
+It takes as an argument a list of strings giving the outcome of the SPF check,
+and will succeed for any matching outcome.
+Valid strings are:
+.vlist
+.vitem &%pass%&
+The SPF check passed, the sending host is positively verified by SPF.
+
+.vitem &%fail%&
+The SPF check failed, the sending host is NOT allowed to send mail for the
+domain in the envelope-from address.
+
+.vitem &%softfail%&
+The SPF check failed, but the queried domain can't absolutely confirm that this
+is a forgery.
+
+.vitem &%none%&
+The queried domain does not publish SPF records.
+
+.vitem &%neutral%&
+The SPF check returned a "neutral" state. This means the queried domain has
+published a SPF record, but wants to allow outside servers to send mail under
+its domain as well. This should be treated like "none".
+
+.vitem &%permerror%&
+This indicates a syntax error in the SPF record of the queried domain.
+You may deny messages when this occurs.
+
+.vitem &%temperror%&
+This indicates a temporary error during all processing, including Exim's
+SPF processing. You may defer messages when this occurs.
+.endlist
+
+You can prefix each string with an exclamation mark to invert
+its meaning, for example "!fail" will match all results but
+"fail". The string list is evaluated left-to-right, in a
+short-circuit fashion.
+
+Example:
+.code
+deny spf = fail
+ message = $sender_host_address is not allowed to send mail from \
+ ${if def:sender_address_domain \
+ {$sender_address_domain}{$sender_helo_name}}. \
+ Please see http://www.openspf.org/Why?scope=\
+ ${if def:sender_address_domain {mfrom}{helo}};\
+ identity=${if def:sender_address_domain \
+ {$sender_address}{$sender_helo_name}};\
+ ip=$sender_host_address
+.endd
+
+When the spf condition has run, it sets up several expansion
+variables:
+
+.cindex SPF "verification variables"
+.vlist
+.vitem &$spf_header_comment$&
+.vindex &$spf_header_comment$&
+ This contains a human-readable string describing the outcome
+ of the SPF check. You can add it to a custom header or use
+ it for logging purposes.
+
+.vitem &$spf_received$&
+.vindex &$spf_received$&
+ This contains a complete Received-SPF: header that can be
+ added to the message. Please note that according to the SPF
+ draft, this header must be added at the top of the header
+ list. Please see section 10 on how you can do this.
+
+ Note: in case of "Best-guess" (see below), the convention is
+ to put this string in a header called X-SPF-Guess: instead.
+
+.vitem &$spf_result$&
+.vindex &$spf_result$&
+ This contains the outcome of the SPF check in string form,
+ one of pass, fail, softfail, none, neutral, permerror or
+ temperror.
+
+.vitem &$spf_result_guessed$&
+.vindex &$spf_result_guessed$&
+ This boolean is true only if a best-guess operation was used
+ and required in order to obtain a result.
+
+.vitem &$spf_smtp_comment$&
+.vindex &$spf_smtp_comment$&
+ This contains a string that can be used in a SMTP response
+ to the calling party. Useful for "fail".
+.endlist
+
+
+.cindex SPF "ACL condition"
+.cindex ACL "spf_guess condition"
+.cindex SPF "best guess"
+In addition to SPF, you can also perform checks for so-called
+"Best-guess". Strictly speaking, "Best-guess" is not standard
+SPF, but it is supported by the same framework that enables SPF
+capability.
+Refer to &url(http://www.openspf.org/FAQ/Best_guess_record)
+for a description of what it means.
+. --- 2018-09-07: still not https:
+
+To access this feature, simply use the spf_guess condition in place
+of the spf one. For example:
+
+.code
+deny spf_guess = fail
+ message = $sender_host_address doesn't look trustworthy to me
+.endd
+
+In case you decide to reject messages based on this check, you
+should note that although it uses the same framework, "Best-guess"
+is not SPF, and therefore you should not mention SPF at all in your
+reject message.
+
+When the spf_guess condition has run, it sets up the same expansion
+variables as when spf condition is run, described above.
+
+Additionally, since Best-guess is not standardized, you may redefine
+what "Best-guess" means to you by redefining the main configuration
+&%spf_guess%& option.
+For example, the following:
+
+.code
+spf_guess = v=spf1 a/16 mx/16 ptr ?all
+.endd
+
+would relax host matching rules to a broader network range.
+
+
+.cindex SPF "lookup expansion"
+.cindex lookup spf
+A lookup expansion is also available. It takes an email
+address as the key and an IP address as the database:
+
+.code
+ ${lookup {username@domain} spf {ip.ip.ip.ip}}
+.endd
+
+The lookup will return the same result strings as can appear in
+&$spf_result$& (pass,fail,softfail,neutral,none,err_perm,err_temp).
+Currently, only IPv4 addresses are supported.
+
+
+
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "Proxies" "CHAPproxies" &&&
+ "Proxy support"
+.cindex "proxy support"
+.cindex "proxy" "access via"
+
+A proxy is an intermediate system through which communication is passed.
+Proxies may provide a security, availability or load-distribution function.
+
+
+.section "Inbound proxies" SECTproxyInbound
+.cindex proxy inbound
+.cindex proxy "server side"
+.cindex proxy "Proxy protocol"
+.cindex "Proxy protocol" proxy
+
+Exim has support for receiving inbound SMTP connections via a proxy
+that uses &"Proxy Protocol"& to speak to it.
+To include this support, include &"SUPPORT_PROXY=yes"&
+in Local/Makefile.
+
+It was built on the HAProxy specification, found at
+&url(https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
+
+The purpose of this facility is so that an application load balancer,
+such as HAProxy, can sit in front of several Exim servers
+to distribute load.
+Exim uses the local protocol communication with the proxy to obtain
+the remote SMTP system IP address and port information.
+There is no logging if a host passes or
+fails Proxy Protocol negotiation, but it can easily be determined and
+recorded in an ACL (example is below).
+
+Use of a proxy is enabled by setting the &%hosts_proxy%&
+main configuration option to a hostlist; connections from these
+hosts will use Proxy Protocol.
+Exim supports both version 1 and version 2 of the Proxy Protocol and
+automatically determines which version is in use.
+
+The Proxy Protocol header is the first data received on a TCP connection
+and is inserted before any TLS-on-connect handshake from the client; Exim
+negotiates TLS between Exim-as-server and the remote client, not between
+Exim and the proxy server.
+
+The following expansion variables are usable
+(&"internal"& and &"external"& here refer to the interfaces
+of the proxy):
+.display
+&'proxy_external_address '& IP of host being proxied or IP of remote interface of proxy
+&'proxy_external_port '& Port of host being proxied or Port on remote interface of proxy
+&'proxy_local_address '& IP of proxy server inbound or IP of local interface of proxy
+&'proxy_local_port '& Port of proxy server inbound or Port on local interface of proxy
+&'proxy_session '& boolean: SMTP connection via proxy
+.endd
+If &$proxy_session$& is set but &$proxy_external_address$& is empty
+there was a protocol error.
+
+Since the real connections are all coming from the proxy, and the
+per host connection tracking is done before Proxy Protocol is
+evaluated, &%smtp_accept_max_per_host%& must be set high enough to
+handle all of the parallel volume you expect per inbound proxy.
+With the option set so high, you lose the ability
+to protect your server from many connections from one IP.
+In order to prevent your server from overload, you
+need to add a per connection ratelimit to your connect ACL.
+A possible solution is:
+.display
+ # Set max number of connections per host
+ LIMIT = 5
+ # Or do some kind of IP lookup in a flat file or database
+ # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}}
+
+ defer message = Too many connections from this IP right now
+ ratelimit = LIMIT / 5s / per_conn / strict
+.endd
+
+
+
+.section "Outbound proxies" SECTproxySOCKS
+.cindex proxy outbound
+.cindex proxy "client side"
+.cindex proxy SOCKS
+.cindex SOCKS proxy
+Exim has support for sending outbound SMTP via a proxy
+using a protocol called SOCKS5 (defined by RFC1928).
+The support can be optionally included by defining SUPPORT_SOCKS=yes in
+Local/Makefile.
+
+Use of a proxy is enabled by setting the &%socks_proxy%& option
+on an smtp transport.
+The option value is expanded and should then be a list
+(colon-separated by default) of proxy specifiers.
+Each proxy specifier is a list
+(space-separated by default) where the initial element
+is an IP address and any subsequent elements are options.
+
+Options are a string <name>=<value>.
+The list of options is in the following table:
+.display
+&'auth '& authentication method
+&'name '& authentication username
+&'pass '& authentication password
+&'port '& tcp port
+&'tmo '& connection timeout
+&'pri '& priority
+&'weight '& selection bias
+.endd
+
+More details on each of these options follows:
+
+.ilist
+.cindex authentication "to proxy"
+.cindex proxy authentication
+&%auth%&: Either &"none"& (default) or &"name"&.
+Using &"name"& selects username/password authentication per RFC 1929
+for access to the proxy.
+Default is &"none"&.
+.next
+&%name%&: sets the username for the &"name"& authentication method.
+Default is empty.
+.next
+&%pass%&: sets the password for the &"name"& authentication method.
+Default is empty.
+.next
+&%port%&: the TCP port number to use for the connection to the proxy.
+Default is 1080.
+.next
+&%tmo%&: sets a connection timeout in seconds for this proxy.
+Default is 5.
+.next
+&%pri%&: specifies a priority for the proxy within the list,
+higher values being tried first.
+The default priority is 1.
+.next
+&%weight%&: specifies a selection bias.
+Within a priority set servers are queried in a random fashion,
+weighted by this value.
+The default value for selection bias is 1.
+.endlist
+
+Proxies from the list are tried according to their priority
+and weight settings until one responds. The timeout for the
+overall connection applies to the set of proxied attempts.
+
+.section Logging SECTproxyLog
+To log the (local) IP of a proxy in the incoming or delivery logline,
+add &"+proxy"& to the &%log_selector%& option.
+This will add a component tagged with &"PRX="& to the line.
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "Internationalisation" "CHAPi18n" &&&
+ "Internationalisation""
+.cindex internationalisation "email address"
+.cindex EAI
+.cindex i18n
+.cindex utf8 "mail name handling"
+
+Exim has support for Internationalised mail names.
+To include this it must be built with SUPPORT_I18N and the libidn library.
+Standards supported are RFCs 2060, 5890, 6530 and 6533.
+
+If Exim is built with SUPPORT_I18N_2008 (in addition to SUPPORT_I18N, not
+instead of it) then IDNA2008 is supported; this adds an extra library
+requirement, upon libidn2.
+
+.section "MTA operations" SECTi18nMTA
+.cindex SMTPUTF8 "ESMTP option"
+The main configuration option &%smtputf8_advertise_hosts%& specifies
+a host list. If this matches the sending host and
+accept_8bitmime is true (the default) then the ESMTP option
+SMTPUTF8 will be advertised.
+
+If the sender specifies the SMTPUTF8 option on a MAIL command
+international handling for the message is enabled and
+the expansion variable &$message_smtputf8$& will have value TRUE.
+
+The option &%allow_utf8_domains%& is set to true for this
+message. All DNS lookups are converted to a-label form
+whatever the setting of &%allow_utf8_domains%&
+when Exim is built with SUPPORT_I18N.
+
+Both localparts and domain are maintained as the original
+UTF-8 form internally; any comparison or regular-expression use will
+require appropriate care. Filenames created, eg. by
+the appendfile transport, will have UTF-8 names.
+
+HELO names sent by the smtp transport will have any UTF-8
+components expanded to a-label form,
+and any certificate name checks will be done using the a-label
+form of the name.
+
+.cindex log protocol
+.cindex SMTPUTF8 logging
+.cindex i18n logging
+Log lines and Received-by: header lines will acquire a "utf8"
+prefix on the protocol element, eg. utf8esmtp.
+
+The following expansion operators can be used:
+.code
+${utf8_domain_to_alabel:str}
+${utf8_domain_from_alabel:str}
+${utf8_localpart_to_alabel:str}
+${utf8_localpart_from_alabel:str}
+.endd
+
+.cindex utf8 "address downconversion"
+.cindex i18n "utf8 address downconversion"
+The RCPT ACL
+may use the following modifier:
+.display
+control = utf8_downconvert
+control = utf8_downconvert/<value>
+.endd
+This sets a flag requiring that addresses are converted to
+a-label form before smtp delivery, for use in a
+Message Submission Agent context.
+If a value is appended it may be:
+.display
+&`1 `& (default) mandatory downconversion
+&`0 `& no downconversion
+&`-1 `& if SMTPUTF8 not supported by destination host
+.endd
+
+If mua_wrapper is set, the utf8_downconvert control
+is initially set to -1.
+
+.new
+The smtp transport has an option &%utf8_downconvert%&.
+If set it must expand to one of the three values described above,
+and it overrides any previously set value.
+.wen
+
+
+There is no explicit support for VRFY and EXPN.
+Configurations supporting these should inspect
+&$smtp_command_argument$& for an SMTPUTF8 argument.
+
+There is no support for LMTP on Unix sockets.
+Using the "lmtp" protocol option on an smtp transport,
+for LMTP over TCP, should work as expected.
+
+There is no support for DSN unitext handling,
+and no provision for converting logging from or to UTF-8.
+
+
+
+.section "MDA operations" SECTi18nMDA
+To aid in constructing names suitable for IMAP folders
+the following expansion operator can be used:
+.code
+${imapfolder {<string>} {<sep>} {<specials>}}
+.endd
+
+The string is converted from the charset specified by
+the "headers charset" command (in a filter file)
+or &%headers_charset%& main configuration option (otherwise),
+to the
+modified UTF-7 encoding specified by RFC 2060,
+with the following exception: All occurrences of <sep>
+(which has to be a single character)
+are replaced with periods ("."), and all periods and slashes that are not
+<sep> and are not in the <specials> string are BASE64 encoded.
+
+The third argument can be omitted, defaulting to an empty string.
+The second argument can be omitted, defaulting to "/".
+
+This is the encoding used by Courier for Maildir names on disk, and followed
+by many other IMAP servers.
+
+Examples:
+.display
+&`${imapfolder {Foo/Bar}} `& yields &`Foo.Bar`&
+&`${imapfolder {Foo/Bar}{.}{/}} `& yields &`Foo&&AC8-Bar`&
+&`${imapfolder {Räksmörgås}} `& yields &`R&&AOQ-ksm&&APY-rg&&AOU-s`&
+.endd
+
+Note that the source charset setting is vital, and also that characters
+must be representable in UTF-16.
+
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "Events" "CHAPevents" &&&
+ "Events"
+.cindex events
+
+The events mechanism in Exim can be used to intercept processing at a number
+of points. It was originally invented to give a way to do customised logging
+actions (for example, to a database) but can also be used to modify some
+processing actions.
+
+Most installations will never need to use Events.
+The support can be left out of a build by defining DISABLE_EVENT=yes
+in &_Local/Makefile_&.
+
+There are two major classes of events: main and transport.
+The main configuration option &%event_action%& controls reception events;
+a transport option &%event_action%& controls delivery events.
+
+Both options are a string which is expanded when the event fires.
+An example might look like:
+.cindex logging custom
+.code
+event_action = ${if eq {msg:delivery}{$event_name} \
+{${lookup pgsql {SELECT * FROM record_Delivery( \
+ '${quote_pgsql:$sender_address_domain}',\
+ '${quote_pgsql:${lc:$sender_address_local_part}}', \
+ '${quote_pgsql:$domain}', \
+ '${quote_pgsql:${lc:$local_part}}', \
+ '${quote_pgsql:$host_address}', \
+ '${quote_pgsql:${lc:$host}}', \
+ '${quote_pgsql:$message_exim_id}')}} \
+} {}}
+.endd
+
+Events have names which correspond to the point in process at which they fire.
+The name is placed in the variable &$event_name$& and the event action
+expansion must check this, as it will be called for every possible event type.
+
+The current list of events is:
+.display
+&`dane:fail after transport `& per connection
+&`msg:complete after main `& per message
+&`msg:delivery after transport `& per recipient
+&`msg:rcpt:host:defer after transport `& per recipient per host
+&`msg:rcpt:defer after transport `& per recipient
+&`msg:host:defer after transport `& per attempt
+&`msg:fail:delivery after transport `& per recipient
+&`msg:fail:internal after main `& per recipient
+&`tcp:connect before transport `& per connection
+&`tcp:close after transport `& per connection
+&`tls:cert before both `& per certificate in verification chain
+&`smtp:connect after transport `& per connection
+.endd
+New event types may be added in future.
+
+The event name is a colon-separated list, defining the type of
+event in a tree of possibilities. It may be used as a list
+or just matched on as a whole. There will be no spaces in the name.
+
+The second column in the table above describes whether the event fires
+before or after the action is associates with. Those which fire before
+can be used to affect that action (more on this below).
+
+The third column in the table above says what section of the configuration
+should define the event action.
+
+An additional variable, &$event_data$&, is filled with information varying
+with the event type:
+.display
+&`dane:fail `& failure reason
+&`msg:delivery `& smtp confirmation message
+&`msg:fail:internal `& failure reason
+&`msg:fail:delivery `& smtp error message
+&`msg:rcpt:host:defer `& error string
+&`msg:rcpt:defer `& error string
+&`msg:host:defer `& error string
+&`tls:cert `& verification chain depth
+&`smtp:connect `& smtp banner
+.endd
+
+The :defer events populate one extra variable: &$event_defer_errno$&.
+
+For complex operations an ACL expansion can be used in &%event_action%&
+however due to the multiple contexts that Exim operates in during
+the course of its processing:
+.ilist
+variables set in transport events will not be visible outside that
+transport call
+.next
+acl_m variables in a server context are lost on a new connection,
+and after smtp helo/ehlo/mail/starttls/rset commands
+.endlist
+Using an ACL expansion with the logwrite modifier can be
+a useful way of writing to the main log.
+
+The expansion of the event_action option should normally
+return an empty string. Should it return anything else the
+following will be forced:
+.display
+&`tcp:connect `& do not connect
+&`tls:cert `& refuse verification
+&`smtp:connect `& close connection
+.endd
+All other message types ignore the result string, and
+no other use is made of it.
+
+For a tcp:connect event, if the connection is being made to a proxy
+then the address and port variables will be that of the proxy and not
+the target system.
+
+For tls:cert events, if GnuTLS is in use this will trigger only per
+chain element received on the connection.
+For OpenSSL it will trigger for every chain element including those
+loaded locally.
+