Version 4.33
------------

 1. The special domain-matching patterns @mx_any, @mx_primary, and
    @mx_secondary can now be followed by "/ignore=<ip list>", where <ip list>
    is a list of IP addresses. Such addresses are ignored when processing the
    pattern (compare ignore_target_hosts on a router). For example:

      domains = @mx_any/ignore=127.0.0.1

    This example matches any domain that has an MX record pointing to one of
    the local host's IP addresses other than 127.0.0.1.

    Because the list is a sublist within the "domains" list, you have to be
    careful about delimiters if there is more than one address. Like any other
    list, the default delimiter can be changed. Thus, you might have

      domains = @mx_any/ignore=<;127.0.0.1;0.0.0.0 : an.other.domain : ...

    so that the sublist uses semicolons for delimiters. When IPv6 addresses are
    involved, it is easiest to change the delimiter for the main list as well:

      domains = <+ @mx_any/ignore=<;127.0.0.1;::1 + an.other.domain + ...

 2. There are three new expansion conditions: match_domain, match_address, and
    match_local_part. They make it possible to use domain, address, and local
    part lists within expansions. Each requires two arguments: an item and a
    list to match. A trivial example is:

      ${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}

    However, the second argument can contain any of the allowable items for a
    list of the appropriate type.

    Because the second argument (after expansion) is a list, it is possible to
    use a named list. Thus, you can have things like this:

      ${if match_domain{$domain}{+local_domains}{...

    For address lists, the matching starts off caselessly, but the +caseful
    item can be used, as in all address lists, to cause subsequent items to
    have their local parts matched casefully. Domains are always matched
    caselessly.

    Note that hosts lists are *not* supported in this way. This is because
    hosts have two identities: a name and an IP address, and it is not clear
    how to specify how such a test would work cleanly. At least, I haven't come
    up with anything yet.

 3. To assist configurations for multi-homed hosts that want to pretend that
    they are several different hosts, there is a new option called
    smtp_active_hostname. At the start of an SMTP connection, its value is
    expanded and used instead of the value of primary_hostname in SMTP
    responses. For example, it is used as domain name in the response to an
    incoming HELO or EHLO command. If this option is unset, or if its expansion
    is forced to fail, or if the expansion results in an empty string, the
    value of primary_hostname is used. Other expansion failures cause a message
    to be written to the main and panic logs, and the SMTP command receives a
    temporary error. Typically, the value of smtp_active_hostname will depend
    on the incoming interface address. For example:

      smtp_active_hostname = ${if eq{$interface_address}{10.0.0.1}\
        {cox.mydomain}{box.mydomain}}

 4. There is a new lookup type called "iplsearch". It is another linear search
    lookup. The keys in the file must be IP addresses, or IP addresses with
    CIDR masks. Keys that involve IPv6 addresses must be enclosed in quotes to
    prevent the first internal colon being interpreted as a key terminator. An
    asterisk key is also permitted for use with iplsearch*. For example:

      *:                 data for *
      1.2.3.4:           data for 1.2.3.4
      192.168.0.0/16     data for 192.168.0.0/16
      "abcd::cdab":      data for abcd::cdab
      "abcd:abcd::/32"   data for abcd:abcd::/32

    The key for an iplsearch lookup must be an IP address. The file is searched
    linearly, until a matching key is found. The first key that matches is
    used; there is no attempt to find a "best" match.

 5. There's a new log selector called ident_timeout, which does what its name
    suggests - it writes a log line when an attempt to connect to a client's
    ident port times out.

 6. There's a new log selector called tls_certificate_verified which adds an
    extra item to <= and => log lines when TLS is in use. The item is "CV=yes"
    if the peer's certificate was verified, and "CV=no" if not.

 7. There is a new global option called tls_require_ciphers, which controls
    which ciphers can be used for incoming connections, in a similar way to the
    option of the same name in the smtp transport. The option is expanded for
    each connection, so can be varied for different clients if required.

 8. The way tls_require_ciphers works for GNUtls in the client has been
    changed, and this is now how it works for the server also. The only way I
    could figure out before was to check for a disallowed cipher after the TLS
    session had been set up, and then abort the session. This was not very
    useful. Now it works more like the way it works in OpenSSL. Below are the
    details for both libraries. Note that OpenSSL uses hyphens to separate the
    components of cipher suite names, whereas GNUtls uses underscores. Exim
    recognizes either in both cases, and translates as appropriate.

    OpenSSL
    -------

    There is a function in the OpenSSL library that can be passed a list of
    cipher suites before the cipher negotiation takes place. This specifies
    which ciphers are acceptable. The list is colon separated and may contain
    names like DES-CBC3-SHA. Exim passes the expanded value of tls_require_
    ciphers directly to this function call. The following paragraphs, which are
    quoted from the OpenSSL documentation, specify what forms of item are
    allowed in the list:

      The actual cipher string can take several different forms.

      It can consist of a single cipher suite such as RC4-SHA.

      It can represent a list of cipher suites containing a certain algorithm,
      or cipher suites of a certain type. For example SHA1 represents all
      ciphers suites using the digest algorithm SHA1 and SSLv3 represents all
      SSL v3 algorithms.

      Lists of cipher suites can be combined in a single cipher string using
      the + character. This is used as a logical and operation. For example
      SHA1+DES represents all cipher suites containing the SHA1 and the DES
      algorithms.

      Each cipher string can be optionally preceded by the characters !, - or
      +.

      If ! is used then the ciphers are permanently deleted from the list. The
      ciphers deleted can never reappear in the list even if they are
      explicitly stated.

      If - is used then the ciphers are deleted from the list, but some or all
      of the ciphers can be added again by later options.

      If + is used then the ciphers are moved to the end of the list. This
      option doesn't add any new ciphers it just moves matching existing ones.

      If none of these characters is present then the string is just
      interpreted as a list of ciphers to be appended to the current preference
      list. If the list includes any ciphers already present they will be
      ignored: that is they will not moved to the end of the list.

    GNUtls
    ------

    The GNUtls library does not have a combined function like OpenSSL. Instead,
    it allows the caller to specify separate lists of key-exchange methods,
    main cipher algorithms, and MAC algorithms. Unfortunately, these lists are
    numerical, and the library does not have a function for turning names into
    numbers. Consequently, the list of recognized names has to be built into
    the application.

    At present, Exim permits only the list of main cipher algorithms to be
    changed. The tls_require_ciphers option is in the same format as for
    OpenSSL. Exim searches each item for the name of available algorithm. For
    example, if the list contains RSA_ARCFOUR_SHA then ARCFOUR is recognized.

    The cipher algorithms list starts out with a default set of algorithms. If
    the first item in tls_require_ciphers does NOT start with an exclamation
    mark, all the default items are deleted. Thus, only those specified can be
    used. If the first item in tls_require_ciphers DOES start with an
    exclamation mark, the defaults are left on the list.

    Then, any item that starts with an exclamation mark causes the relevent
    algorithms to be removed from the list, and any item that does not start
    with an exclamation mark causes the relevant algorithms to be added to the
    list. Thus,

      tls_require_ciphers = !RSA_ARCFOUR_SHA

    allows all the defaults except those that use ARCFOUR, whereas

      tls_require_ciphers = AES : 3DES

    allows only cipher suites that use AES and 3DES. The currently recognized
    algorithms are: ARCFOUR_128, ARCFOUR_40, ARCFOUR (both of the preceding),
    AES_256, AES_128, AES (both of the preceding), and 3DES.

    Unrecognized algorithms are ignored. In a client, the order of the list
    specifies a preference order for the algorithms.

****
