Mailing List Archive

Re: [exim] DKIM vs DomainKeys
On Friday 17 November 2006 11:39, Magnus Holmgren wrote:
> On Friday 17 November 2006 09:31, Tom Kistner wrote:
> > David Saez Padros wrote:
> > > Looks like DKIM will replace DomainKeys, maybe it's time to
> > > do the same in Exim ?
> >
> > I'd be interested in starting this (my current employer may be
> > interested as well, so there'd be an additional incentive).
> >
> > Or did anyone here already start an implementation?
>
> I've been trying to modify dk.c into a dkim.c using libdkim instead of
> libdomainkeys. I'm not quite there yet though.

I've come to the conclusion that it's not possible to simply adapt the
existing dk.c to use libdkim instead of libdomainkeys - the interfaces are
too different, especially for verification.

First, libdomainkeys gives a single result (was the signature OK, who signed,
etc), while libdkim gives a list of all signatures and their respective
status. There is a good reason for this: DomainKeys required the signing
identity to be the address in the Sender: field if it exists, otherwise the
address in the From: field. That has the advantage that it is the identity
shown by the MUAs that will be authenticated. It has the drawback that
mailing list managers that add footers (like this one) will have to re-sign
all mail and change the Sender field.

In DKIM, however, the signing identity is found only in the signature field.
This means that there can be any number of valid (and invalid) signatures.

A reasonable way of handling that could be to let the ACL conditions succeed
if any valid signature matches:

dkim_sender_domains = <domain list>: Succeeds if any valid signature is made
by a domain in the list.
dkim_senders = <address list>,
dkim_local_parts = <local part list>: Analogous, but note that the local
part may be empty if the signing server can't guarantee the exact
identity of the sender.

A dkim_local_parts probably isn't very useful if it can match against any
signature identity.

The expansion variables could represent the earliest valid signature. It's of
course possible to have a $dkim_senders containing a comma-delimited list of
all valid signature identities, but Exim has no good built-in mechanism for
looping over comma-delimited lists of addresses, except in filters
(foranyaddress). The best option probably is ${perl ...}. So, probably some
new expansion conditions might be needed.

--
Magnus Holmgren holmgren@lysator.liu.se
(No Cc of list mail needed, thanks)

"Exim is better at being younger, whereas sendmail is better for
Scrabble (50 point bonus for clearing your rack)" -- Dave Evans

--
## List details at http://www.exim.org/mailman/listinfo/exim-dev Exim details at http://www.exim.org/ ##
Re: [exim] DKIM vs DomainKeys [ In reply to ]
On Sat, 2007-01-20 at 16:29 +0100, Magnus Holmgren wrote:
> In DKIM, however, the signing identity is found only in the signature field.
> This means that there can be any number of valid (and invalid) signatures.
>
> A reasonable way of handling that could be to let the ACL conditions succeed
> if any valid signature matches:
>
> dkim_sender_domains = <domain list>: Succeeds if any valid signature is made
> by a domain in the list.
> dkim_senders = <address list>,

right, so we could write

dkim_senders = ${if def:h_Sender: {${address:$h_Sender:}} \
{${address:$h_From:}}}

to get DomainKeys-like behaviour. (this ignores the possibility of From
containing more than one address. see below.)

> dkim_local_parts = <local part list>: Analogous, but note that the local
> part may be empty if the signing server can't guarantee the exact
> identity of the sender.
>
> A dkim_local_parts probably isn't very useful if it can match against any
> signature identity.

I agree, and I don't think it should be added if no one has a use case
for it.

> The expansion variables could represent the earliest valid signature. It's of
> course possible to have a $dkim_senders containing a comma-delimited list of
> all valid signature identities, but Exim has no good built-in mechanism for
> looping over comma-delimited lists of addresses, except in filters
> (foranyaddress). The best option probably is ${perl ...}. So, probably some
> new expansion conditions might be needed.

${extract can use an arbitrary delimiter, but we lack the looping
construct. perhaps a new kind of require keyword, which takes an ACL
and a list?

as for the list: both comma and space can be used validly in an e-mail
address, so we need an operator which understands quoting and dequotes
each element. consider the following list of three addresses:

set acl_m0 = foo@bar : gazonk@zot : "<\"some::weirdo\"@quux>"

I used colon as the separator in the above to mimic the normal syntax
for lists in Exim. we can extend it like so:

set acl_m0 = $acl_m0 : ${quote:$sender_address}

to loop over it, I suggest this new ACL verb:

require_list = acl_check_element $acl_m0

the ACL named acl_check_element would be called four times, with the new
variable $list_element (or somesuch) set to the dequoted element value.
this function should be made available as a more advanced ${extract for
general use, e.g.:

${extract_quoted{4}{:}{$acl_m0}}

would return

<"some::weirdo"@quux>

finally, we now have the infrastructure to make an ${address operator
which returns a list when the header contains more than one address.
given:

To: foo@bar, Frank Zot <gazonk@zot>, <"some::weirdo"@quux>

${address_list:$h_To:} should now return:

foo@bar:gazonk@zot:"\"some::weirdo\"@quux"

does this make sense to anyone else?
--
Kjetil T.



--
## List details at http://www.exim.org/mailman/listinfo/exim-dev Exim details at http://www.exim.org/ ##
Re: [exim] DKIM vs DomainKeys [ In reply to ]
On Sunday 21 January 2007 15:40, Kjetil Torgrim Homme wrote:
> On Sat, 2007-01-20 at 16:29 +0100, Magnus Holmgren wrote:
> > In DKIM, however, the signing identity is found only in the signature
> > field. This means that there can be any number of valid (and invalid)
> > signatures.
> >
> > A reasonable way of handling that could be to let the ACL conditions
> > succeed if any valid signature matches:
> >
> > dkim_sender_domains = <domain list>: Succeeds if any valid signature is
> > made by a domain in the list.
> > dkim_senders = <address list>,
>
> right, so we could write
>
> dkim_senders = ${if def:h_Sender: {${address:$h_Sender:}} \
> {${address:$h_From:}}}
>
> to get DomainKeys-like behaviour. (this ignores the possibility of From
> containing more than one address. see below.)

Well, yes, *if* we want that. The fact that the Sender field has to be
clobbered by MLMs and other software that alters messages if they wish to
re-sign them is a problem with DK, and it should not be expected that the
signing identity be found in the Sender or From fields. However, it's still a
test that may be useful, as long as it isn't ground for rejection.

> > The expansion variables could represent the earliest valid signature.
> > It's of course possible to have a $dkim_senders containing a
> > comma-delimited list of all valid signature identities, but Exim has no
> > good built-in mechanism for looping over comma-delimited lists of
> > addresses, except in filters (foranyaddress). The best option probably is
> > ${perl ...}. So, probably some new expansion conditions might be needed.

> ${extract can use an arbitrary delimiter, but we lack the looping
> construct. perhaps a new kind of require keyword, which takes an ACL
> and a list?

There are now a number of looping constructs in progress, which should be
adequate, whether $dkim_senders is an addresslist (colon-separated) or an
address-list (comma-separated).

> as for the list: both comma and space can be used validly in an e-mail
> address, so we need an operator which understands quoting and dequotes
> each element. consider the following list of three addresses:
>
> set acl_m0 = foo@bar : gazonk@zot : "<\"some::weirdo\"@quux>"
>
> I used colon as the separator in the above to mimic the normal syntax
> for lists in Exim. we can extend it like so:
>
> set acl_m0 = $acl_m0 : ${quote:$sender_address}

Hmm, nah, quote doesn't work quite right here. It puts the whole string inside
quotes, not just the local part, does that when it's not necessary, and
doesn't double colons.

> to loop over it, I suggest this new ACL verb:
>
> require_list = acl_check_element $acl_m0
>
> the ACL named acl_check_element would be called four times, with the new
> variable $list_element (or somesuch) set to the dequoted element value.
> this function should be made available as a more advanced ${extract for
> general use, e.g.:
>
> ${extract_quoted{4}{:}{$acl_m0}}
>
> would return
>
> <"some::weirdo"@quux>

Shouldn't that be <"some:weirdo"@quux>? I thought the colon was doubled so as
not to confuse it for a list separator in the list further up.

Calling an ACL to evaluate a single variable doesn't quite make sense to me.
Calling an ACL once for each DKIM signature found, without explicitly
invoking it through that require_list condition, would make more sense. In
that case, dkim_senders, dkim_domains, and dkim_local_parts would all be
meaningful as they would only test one signature at a time.

Yes... it all becomes clear to me... then we don't have to come up with a
single overall result for all signatures, and all the ACL conditions and
expansion variables that exist for DK today will work with DKIM. This is
probably the way to go.

The alternative might be a big $dkim_signatures variable containing a list of
attr="value" pairs, to be used with forany/forall/map/reduce and extract.

> finally, we now have the infrastructure to make an ${address operator
> which returns a list when the header contains more than one address.
> given:
>
> To: foo@bar, Frank Zot <gazonk@zot>, <"some::weirdo"@quux>
>
> ${address_list:$h_To:} should now return:
>
> foo@bar:gazonk@zot:"\"some::weirdo\"@quux"

There is now a suggested patch that implements exactly this as the "addresses"
expansion operator.

--
Magnus Holmgren holmgren@lysator.liu.se
(No Cc of list mail needed, thanks)

"Exim is better at being younger, whereas sendmail is better for
Scrabble (50 point bonus for clearing your rack)" -- Dave Evans
Re: [exim] DKIM vs DomainKeys [ In reply to ]
I move this to -users now, hoping to attract more responses. Please keep
followups there.

On Saturday 20 January 2007 16:29, Magnus Holmgren wrote:
> I've come to the conclusion that it's not possible to simply adapt the
> existing dk.c to use libdkim instead of libdomainkeys - the interfaces are
> too different, especially for verification.
>
> First, libdomainkeys gives a single result (was the signature OK, who
> signed, etc), while libdkim gives a list of all signatures and their
> respective status. There is a good reason for this: DomainKeys required the
> signing identity to be the address in the Sender: field if it exists,
> otherwise the address in the From: field. That has the advantage that it is
> the identity shown by the MUAs that will be authenticated. It has the
> drawback that mailing list managers that add footers (like this one) will
> have to re-sign all mail and change the Sender field.
>
> In DKIM, however, the signing identity is found only in the signature
> field. This means that there can be any number of valid (and invalid)
> signatures.

However, SSP (Sender Signing Policy), which I didn't look very closely at
until now (it's a separate standard that isn't done yet), addresses this and
lets domains declare that they sign all their mail. Unlike DomainKeys, it's
always the (first) address in the From field that is the Originator Address,
but relays (MLMs etc.) that re-sign messages don't have to add or alter the
Sender field (but is recommended to do so anyway).

Considering this, as well as practical use cases, perhaps we can make DKIM
functionality rather similar to the existing DK functionality.

In a message header there can be one Originator Signature and any number of
Third-party Signatures (but in practice never more than one or maybe two).
third-party signatures are good for two things (*if you trust the signer*, of
course): 1) They can certify that the originator signature (or the previous
signature, or both; I'm not sure) was valid when it got to them: "A
DKIM-aware Mailing List Manager MUST NOT re-sign an improperly signed message
in such a way that would imply that the existing signature is acceptable."
and 2) they can certify that the message was indeed sent by the purported
originator, even if there is no originator signature, e.g. if the identity
has been established through some other means (it doesn't say this in the SSP
I-D, but you can see that it's a workable use case; an example would be the
Exim Bugzilla, which sends out notices on behalf of the person who adds
comments or changes bug fields (the mail-in interface lacks authentication
though, so we should be careful there).

This means that there *can* be DKIM features that work similarly to the
existing DK features: Exim would need a list of trusted third-party signers;
dkim_sender_domains, dkim_sender_local_parts, and dkim_senders would then
succeed if there is a matching, valid originator signature *or* there is an
originator signature that is signed by a trusted third-party signer.
dkim_status and dkim_policy could also refer to the originator signature.

But users could still want to do things with messages that are simply signed
by certain signers, even if there is no originator signature, so there are
still many things to take into account.

--
Magnus Holmgren holmgren@lysator.liu.se
(No Cc of list mail needed, thanks)

"Exim is better at being younger, whereas sendmail is better for
Scrabble (50 point bonus for clearing your rack)" -- Dave Evans