Email from Google causes a crash and bounceback

Bug #1842250 reported by Colin Cogle
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dkimpy-milter
Fix Released
High
Scott Kitterman

Bug Description

I just switched from OpenDKIM to dkimpy-milter, and it's been working great until now. However, I've noticed email from Google crashes the milter and the message gets lost permanently. The only output I've gotten was from journalctl. I'll provide any help I can.

(Also, if anyone here knows how to stop the message from getting lost when the milter crashes, that'd be much appreciated!)

Sep 01 12:48:45 mymailserver.domain.tld postfix/smtpd[10680]: connect from mail-io1-xd2a.google.com[2607:f8b0:4864:20::d2a]
Sep 01 12:48:45 mymailserver.domain.tld postfix/smtpd[10680]: Anonymous TLS connection established from mail-io1-xd2a.google.com[2607:f8b0:4864:20::d2a]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)
Sep 01 12:48:45 mymailserver.domain.tld policyd-spf[10686]: prepend Authentication-Results: mymailserver.domain.tld; spf=pass (mailfrom) smtp.mailfrom=google.com (client-ip=2607:f8b0:4864:20::d2a; helo=mail-io1-xd2a.google.com; <email address hidden>; receiver=<UNKNOWN>)
Sep 01 12:48:45 mymailserver.domain.tld postfix/smtpd[10680]: C290C138BBF: client=mail-io1-xd2a.google.com[2607:f8b0:4864:20::d2a]
Sep 01 12:48:45 mymailserver.domain.tld postfix/cleanup[10687]: C290C138BBF: message-id=<email address hidden>
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: check_dkim: endswith first arg must be bytes or a tuple of bytes, not str
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: TypeError: a bytes-like object is required, not 'NoneType'
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]:
                                                          The above exception was the direct cause of the following exception:
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: Traceback (most recent call last):
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: File "/usr/local/lib/python3.6/dist-packages/Milter/__init__.py", line 772, in <lambda>
                                                              milter.set_eom_callback(lambda ctx: ctx.getpriv().eom())
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: File "/usr/local/lib/python3.6/dist-packages/dkimpy_milter/__init__.py", line 196, in eom
                                                              self.check_dkim(txt)
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: File "/usr/local/lib/python3.6/dist-packages/dkimpy_milter/__init__.py", line 292, in check_dkim
                                                              self.header_i = codecs.decode(d.signature_fields.get(b'i'), 'ascii')
Sep 01 12:48:45 mymailserver.domain.tld dkimpy-milter[21461]: TypeError: decoding with 'ascii' codec failed (TypeError: a bytes-like object is required, not 'NoneType')
Sep 01 12:48:45 mymailserver.domain.tld postfix/cleanup[10687]: C290C138BBF: milter-reject: END-OF-MESSAGE from mail-io1-xd2a.google.com[2607:f8b0:4864:20::d2a]: 4.3.0 pymilter: untrapped exception in dkimpy-filter; from=<email address hidden> to=<email address hidden> proto=ESMTP helo=<mail-io1-xd2a.google.com>

Revision history for this message
Scott Kitterman (kitterman) wrote :

In postfix you can use milter_default_action to control what happens if the milter fails. See postfix documentation for details.

Thanks.

Changed in dkimpy-milter:
importance: Undecided → High
status: New → Confirmed
Revision history for this message
Colin Cogle (signofzeta) wrote :

Thanks for the Postfix help, but that was already set in my main.cf. Apparently, if a milter throws an exception, then the result is always tempfail.

As far as dkimpy-milter goes, it seems like when the identity tag (i=) is missing from the DKIM-Signature header, it crashes. However, this is allowed. If the identity tag is missing and the domain (d=) field domain.com, the DKIM spec assumes <email address hidden>. I implemented a very quick and dirty check for it just to keep the milter from crashing. (Feel free to do this right; I don't speak Python.)

    self.header_a = codecs.decode(d.signature_fields.get(b'a'), 'ascii')
    self.header_d = codecs.decode(d.signature_fields.get(b'd'), 'ascii')
    if (d.signature_fields.get(b'i') is not None):
      self.header_i = codecs.decode(d.signature_fields.get(b'i'), 'ascii')
    else:
      self.header_i = "@{}".format(self.header_d)

However, DKIM validation will still fail. See this example email I received from eBay:

    Authentication-Results: mx.mymailserver.tld; dkim=fail (endswith first
       arg must be bytes or a tuple of bytes, not str) header.d=ebay.com
       <email address hidden> header.a=rsa-sha1; dkim=fail (endswith first arg
       must be bytes or a tuple of bytes, not str) header.d=ebay.com
       <email address hidden> header.a=rsa-sha1

Ignore that eBay is still using rsa-sha1, which "MUST NOT be used for signing or verifying" (RFC 8301). The same behavior happens with rsa-sha256 signatures, too.

Revision history for this message
Scott Kitterman (kitterman) wrote :

I used something very close to this. In the else clause I just set it to None and then it works (signature validates and produces an appropriate A-R header). I'll get a release done with this soon.

Changed in dkimpy-milter:
assignee: nobody → Scott Kitterman (kitterman)
status: Confirmed → Fix Committed
milestone: none → 1.2.0
milestone: 1.2.0 → 1.1.1
Revision history for this message
Scott Kitterman (kitterman) wrote :

1.1.1 2019-09-06
 - Fix startup logging so it provides information at a useful time
 - Fix verify processing so missing (optional) i= tag doesn't cause the milter
   to fail (LP: #1842250)
 - Fix message extraction so that signing in the same pass through the milter
   as verifying works correctly

Changed in dkimpy-milter:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.