Skip to content

send() sends mail where lines are separated by LF, not CRLF, violating RFC5322 #49

@amfleurke

Description

@amfleurke

When sending a mail using repoze.sendmail.mailer.SMTPMailer.send( fromaddr, toaddrs, message), the message will be encoded (message = encode_message(message)) and then sent (connection.sendmail(fromaddr, toaddrs, message)).
the encode_message function calls message.as_string(), which concatenates all headers and body using LF, the default line separator of the email policy. https://docs.python.org/3/library/email.message.html states:

"If policy is specified use the rules it specifies to update and serialize the representation of the message. If policy is not set, use the default policy, which follows the rules of the email RFCs except for line endings (instead of the RFC mandated \r\n, it uses the Python standard \n line endings). For more information see the policy documentation."

https://www.rfc-editor.org/rfc/rfc5322#section-2.1

So, using this without extra handling causes the mail to be sent not conforming to RFC5322.

https://docs.python.org/3/library/email.policy.html#module-email.policy gives a hint how to solve it.

I guess instead of

encoding.py encode_message() line 103:
return message.as_string().encode('ascii')

we need something like

        from email.generator import BytesGenerator
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=False, message.policy.clone(linesep='\r\n'))
        g.flatten(message, unixfrom=unixfrom)
        return fp.getvalue().encode('ascii')

(I copied the contents of the as_string method, adding message.policy.clone(linesep='\r\n') and replacing self with message)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions