Opened 8 years ago

Closed 8 years ago

Last modified 3 years ago

#27131 closed Bug (fixed)

send_mail() error on Python 2 if smtp server uses CRAM-MD5 auth method

Reported by: Slava Owned by: nobody
Component: Core (Mail) Version: dev
Severity: Normal Keywords: send_mail
Cc: slavugan@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

send_mail('title', 'message', from_email='test@mail.com', recipient_list=['test2@mail.com'])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    send_mail('hello slafffko', 'message is here', from_email='test@artel7.com',
 recipient_list=['slavugan@gmail.com'])
  File "/home/slav/venv/luxjango/local/lib/python2.7/site-packages/django/core/m
ail/__init__.py", line 62, in send_mail
    return mail.send()
  File "/home/slav/venv/luxjango/local/lib/python2.7/site-packages/django/core/m
ail/message.py", line 303, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/home/slav/venv/luxjango/local/lib/python2.7/site-packages/django/core/m
ail/backends/smtp.py", line 100, in send_messages
    new_conn_created = self.open()
  File "/home/slav/venv/luxjango/local/lib/python2.7/site-packages/django/core/m
ail/backends/smtp.py", line 67, in open
    self.connection.login(self.username, self.password)
  File "/usr/lib/python2.7/smtplib.py", line 607, in login
    (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
  File "/usr/lib/python2.7/smtplib.py", line 571, in encode_cram_md5
    response = user + " " + hmac.HMAC(password, challenge).hexdigest()
  File "/usr/lib/python2.7/hmac.py", line 75, in __init__
    self.outer.update(key.translate(trans_5C))
TypeError: character mapping must return integer, None or unicode

email backend should pass passwrord as string, not as unicode to smtplib to avoid this error

Change History (11)

comment:1 by Tim Graham, 8 years ago

I have no way to reproduce this -- can you submit a patch with a test?

comment:2 by Claude Paroz, 8 years ago

Would it be possible to test with Python 3?

comment:3 by Claude Paroz, 8 years ago

FYI, I'm currently working on a test for this in the Django test suite.

comment:4 by Slava, 8 years ago

I have checked for python3 everything is ok, because of with python3 Django passes password as string to smtplib, so this error is relevant only for python2.
For fix in django/core/mail/backends/smtp.py in EmailBackend.__init__ we should add something like this:

if self.password.__class__.__name__ == 'unicode':
    try:
        self.password = str(self.password)
    except UnicodeEncodeError:
        pass
Last edited 8 years ago by Slava (previous) (diff)

comment:5 by Claude Paroz, 8 years ago

Has patch: set
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug
Version: 1.8master

comment:6 by Tim Graham, 8 years ago

Summary: send_mail error if smtp server uses CRAM-MD5 auth methodsend_mail() error on Python 2 if smtp server uses CRAM-MD5 auth method
Triage Stage: AcceptedReady for checkin

comment:7 by Claude Paroz <claude@…>, 8 years ago

Resolution: fixed
Status: newclosed

In fe252c0a:

Fixed #27131 -- Passed proper string type to SMTP connection login

Passing an Unicode string on Python 2 was crashing the connection.
Thanks slavugan@… for the report, and Tim Graham for the review.

comment:8 by Claude Paroz, 8 years ago

As suggested by Tim on the pull request, a workaround on older Django could be to define email username and pasword as bytestrings.

comment:9 by GitHub <noreply@…>, 3 years ago

In cdad96e6:

Refs #27131 -- Removed SMTPBackendTests.test_server_login().

test_server_login() was a regression test for a crash when passing
Unicode strings to SMTP server using CRAM-MD5 method on Python 2.
Python 2 is no longer supported and test_server_login() passes even
without FakeSMTPChannel.smtp_AUTH() because
smtplib.SMTPAuthenticationError is raised when AUTH is not implemented.

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

In 8ab9536:

[4.0.x] Refs #27131 -- Removed SMTPBackendTests.test_server_login().

test_server_login() was a regression test for a crash when passing
Unicode strings to SMTP server using CRAM-MD5 method on Python 2.
Python 2 is no longer supported and test_server_login() passes even
without FakeSMTPChannel.smtp_AUTH() because
smtplib.SMTPAuthenticationError is raised when AUTH is not implemented.
Backport of cdad96e6330cd31185f7496aaf8eb316f2773d6d from main

comment:11 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

In 137a9899:

[3.2.x] Refs #27131 -- Removed SMTPBackendTests.test_server_login().

test_server_login() was a regression test for a crash when passing
Unicode strings to SMTP server using CRAM-MD5 method on Python 2.
Python 2 is no longer supported and test_server_login() passes even
without FakeSMTPChannel.smtp_AUTH() because
smtplib.SMTPAuthenticationError is raised when AUTH is not implemented.
Backport of cdad96e6330cd31185f7496aaf8eb316f2773d6d from main

Note: See TracTickets for help on using tickets.
Back to Top