Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Salmon breaks DKIM signatures #72

Open
talwrii opened this issue May 24, 2018 · 3 comments
Open

Salmon breaks DKIM signatures #72

talwrii opened this issue May 24, 2018 · 3 comments
Labels

Comments

@talwrii
Copy link

talwrii commented May 24, 2018

DKIM is a standard for signing emails that uses DNS as a certificate store.
DKIM's related standard DMARC may result in your mail server silently refusing to accept email messages that have been modified if an email has been in any way modified, assuming that your mail server is adopting the standard (which, for example, gmail does).

This is somewhat problematic for forwarders like salmon, since they must be careful in some circumstances not to modify email messages.

By default salmon aggressively normalizes messages, potentially breaking DKIM forwarding. This normalization can be avoided by setting

Examples of problems this causes: Airbnb/stackoverlay/yahoo mail have a DKIM policy that result in Gmail dropping mail.

An alternative approach might be to remove DKIM header changed the from address and use ReplyTo for this purpose.

@talwrii
Copy link
Author

talwrii commented May 24, 2018

This branch https://github.com/talwrii/salmon/tree/talwrii--2018-05-17--dkim fixes this issue by letting one switch off salmon's mail normalisation.

The approach used here is quite aggressive - but it seemed a bit perverse to try and get the mail canonicalisation code to do nothing.

@moggers87
Copy link
Owner

If you're only wanting to forward a message as-is, the original message is preserved in message.Data:

@route(r"(local)@(domain)", local=r".+", domain=r".+")
def FORWARD(message, local=None, domain=None):
    Relay().deliver(message.Data, To="someone@example.com", From="me@example.com")

If you've added some headers of your own before forwarding, but still want to avoid Salmon's sanitization, replace message.Data with message.base.mime_part.

As for your branch, we should parse the DKIM header and work out which headers need to be preserved. This should not be the default, but I could see it being useful.

@moggers87 moggers87 changed the title Forwarding seems to (silently) break DKIM/DMARC/SPF Salmon breaks DKIM signatures May 24, 2018
@talwrii
Copy link
Author

talwrii commented Jun 5, 2018

Thanks for that. It looks like there is no need for this feature. I got tripped up by the existence of two mail classes (salmon.mail.MailRequest and salmon.encoding.MailBase) and didn't realise the deliver accepts strings.

A couple of points for other users.

The From argument to deliver must be provided if message.Data is used as the message object.

    [user@XXXXXXXXXXX] out: Traceback (most recent call last):
    [user@XXXXXXXXXXX] out:   File "/home/user/pymail/app/handlers/sample.py", line 41, in receive
    [user@XXXXXXXXXXX] out:     config.settings.tatw_relay.deliver(message.Data, To="tat.wright@googlemail.com")
    [user@XXXXXXXXXXX] out:   File "/home/user/.local/lib/python2.7/site-packages/salmon/server.py", line 126, in deliver
    [user@XXXXXXXXXXX] out:     sender = From or getattr(message, 'From', None) or message['From']
    [user@XXXXXXXXXXX] out: TypeError: string indices must be integers, not unicode

Also, I imagine the From header will be part of the DMARC signed headers (h=From:Subject:Date:To:MIME-Version:Content-Type * and I believe is used to verify the signature.

So the sample one wants is:

@route(r"(local)@(domain)", local=r".+", domain=r".+")
def FORWARD(message, local=None, domain=None):
    Relay().deliver(message.Data, To="someone@example.com", From=message.From)

If one wants to change From on might prefer to use the ReplyTo heading - there is an edge case where the DKIM header prevents you from changing this. Though to do this one must de-encoding and re-encoding the message. I had success doing this email itself. Although, if you are changing From you can just get rid of the DKIM signature itself (assuming you don't have your own DNS DKIM message)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants