[exim] Exim Snapshot - DomainKeys support - Testers wanted

Top Page

Reply to this message
Author: Tom Kistner
To: exim-users, exiscanusers
Subject: [exim] Exim Snapshot - DomainKeys support - Testers wanted
Hello everyone,

As promised last week, here is a CVS snapshot of Exim containing
DomainKeys support:


The snapshot carries a version number of 4.47. It represents the current
state of Exim CVS (includes exiscan-acl support) plus the DomainKeys code.

Please find the spec of the DK additions below. This is the first
release of that code, so you should treat it with some amount of
suspicion (run it under surveillance for a while ...).

DK support will NOT be in 4.50, but maybe in 4.51 or 4.52.

Experimental Exim DomainKeys Support
Tom Kistner <tom@???>


DomainKeys (DK) support is built into Exim using the "libdomainkeys"
reference library implementation. It is available at


You must build this library on your system and compile Exim against it.

To build Exim with DK support, add these lines to your Local/Makefile:

CFLAGS += -I/home/tom/exim-cvs/extra/libdomainkeys
LDFLAGS += -ldomainkeys -L/home/tom/exim-cvs/extra/libdomainkeys

Remember to tweak the CFLAGS and LDFLAGS lines to match the location of
the libdomainkeys includes and lib on your system.

The current experimental implementation supports two independent

o Validate incoming DK-signed email.
o Sign outgoing email with DK.

The former is implemented in the ACLs for SMTP, the latter as an
extension to the SMTP transport. That means both facilities are limited
to SMTP I/O.

Validate incoming DK-signed email

Incoming messages are fed to the DK validation process as they are
received "on the wire". This happens synchronously to Exim's buffering
of the message in the spool. You must set "control = dk_verify" in
one of the ACLs preceding DATA (you will typically use acl_smtp_rcpt).


warn log_message = Feeding message to DK validator.
      control = dk_verify

You can check for the outcome of the DK check in the ACL after data
(acl_smtp_data), using these expansion variables:

   $dk_status    This variable contains a lowercase string, describing
                 the outcome of the messages' DK validation. Typically,
                 it will contain the following strings:

                 o good          Message signature verifies against
                                 domainkey published in DNS. We have a

                 o bad           Message signature does not verify
                                 against domainkey published in DNS.

                 o no_signature  The message does not carry a DK

                 o no_key        The message had a signature, but the DNS
                                 of the sending domain does not carry a
                                 public key.

                 o revoked_key   The key used to sign this message has
                                 been revoked by the sending domain.

                 In addition, these following strings are also possible.
                 They describe error conditions.

                 o cannot_verify Both signature and key are available,
                                 but verification processing failed (e.g.
                                 signature was created using an
                                 unsupported hashing algorithm).

                 o bad_key       The domainkey published in DNS has a
                                 format error.

                 o bad_syntax    The domainkey record published in DNS
                                 has a syntax error.

                 Finally, the following describe internal errors in the
                 local DK processing:

                 o error         Internal disaster.

                 o no_resources  Out of memory. This will be the least of
                                 your problems.

                 o bad_argument  Yours truly has screwed up. Please
                                 report a bug.

                 If $dk_status is empty, the message has not been
                 processed by the DK engine.

$dk_signs_all   This variable is "1" when the sending domain signs all
                 outgoing email, "0" otherwise.

$dk_is_testing  This variable is "1" when the sending domain is
                 currently testing DomainKeys, "0" otherwise.

Using these variables, you COULD reject mail in the DATA ACL:

deny message = This message is unsigned. "$sender_address_domain" \
                policy is to sign all outgoing email. Go away.
      !condition = ${if eq{$dk_status}{}{1}{0}}
      !condition = $dk_is_testing
      condition = $dk_signs_all
      condition = ${if eq{$dk_status}{no_signature}{1}{0}}

deny message = DomainKeys signature did not verify.
      !condition = ${if eq{$dk_status}{}{1}{0}}
      !condition = $dk_is_testing
      condition = $dk_signs_all
      condition = ${if eq{$dk_status}{bad}{1}{0}}

The author does NOT RECOMMEND to use this code snippet. Consider it to
be for educational purposes. DK interoperability is not very good at the
moment and signatures may not evaluate to "good" for bona fide email.

What is recommended, however, is to add a DomainKey-Status: header that
informs end users about the result:

warn message = DomainKey-Status: $dk_status
      !condition = ${if eq{$dk_status}{}{1}{0}}

Sign outgoing email with DK

Outgoing messages are signed just before exim puts them "on the wire".
The only thing that happens after DK signing is eventual TLS encryption.

Signing is implemented by setting private options on the SMTP transport.
This simple example shows all the options (not all of them are needed,
check the explanations below):

driver = smtp
dk_private_key = /etc/exim/dk/foobar
dk_selector = foobar
dk_domain = duncanthrax.net
dk_canon = nofws

dk_private_key (MANTADORY)
This option MUST be present, otherwise the message will not be signed.
Its value is expanded before being used, and must result in:

     o the absolute filename (including path starting with a slash) of
       the private key, in which case the message will be signed using
       this key.
     o "0" or the empty string, in which case the message will not be

This option sets the key selector string. DK supports having multiple
keys in your DNS zone in order to be able to switch keys. Each key has
a "name", which is the selector. This option defaults to the filename
part of the dk_private_key setting (starting after the last slash), so
if your private key filenames are the same as your selector strings,
you can omit this option. Otherwise, you MUST set this option.

dk_domain (OPTIONAL)
This option can override the domain (d=) field of the
DomainKey-Signature header. You should normally not set this option
since the domain will be automatically selected by fishing it out of
the address headers.

dk_canon (OPTIONAL)
This option sets the canonicalization method used when signing a
message. The DK draft currently supports two methods: "simple" and
"nofws". The option defaults to "simple" when unset.


The implementation is currently "work-in-progress". The author plans the
following additions:

o Have a "dk_status" ACL condition instead of just an expansion
o Support the "h=" parameter (include only selected headers when
o Write $dk_status to the spool file, so it is available in routers and
transports later.