From 79ef03d4cc07a7e75eba2ca0f9231d841ecf7b8e Mon Sep 17 00:00:00 2001 From: Paul Morelle Date: Tue, 2 Jul 2019 09:20:32 +0000 Subject: [PATCH] [FIX] base: always send HELO when connecting SMTP smtplib.SMTP API calls such as .sendmail() or .login() make sure on their first line that this command is sent, by calling .ehlo_or_helo_if_needed(). However, test_smtp_connection() does not use SMTP.sendmail() to simulate sending email, or the email would really be sent. Instead it uses the low-level API SMTP.mail() which does not make sure that HELO was sent. The connection test could be fixed by ensuring that this command was sent to the server in the test method. However, this could lead to inconsistent cases where the connection test passes whereas another usage in the code fails because the command was not sent. For example, someone could use the low-level API for some reason. EHLO could have already been sent because if authentication is enabled smtplib.SMTP.login() calls ehlo_or_helo_if_needed(). Therefore it is correct to call it ourselves at the end of our connect() method. STARTTLS sends a first EHLO, negociates the encryption, and leaves the state without the second EHLO, which should still be sent to the server, as stated by RFC 3207, in section "4.2 Result of the STARTTLS Command". https://www.ietf.org/rfc/rfc3207.txt closes odoo/odoo#34550 Signed-off-by: Julien Legros (jle) --- odoo/addons/base/models/ir_mail_server.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/odoo/addons/base/models/ir_mail_server.py b/odoo/addons/base/models/ir_mail_server.py index 8102d2e65e7..57e856d8e66 100644 --- a/odoo/addons/base/models/ir_mail_server.py +++ b/odoo/addons/base/models/ir_mail_server.py @@ -277,6 +277,11 @@ class IrMailServer(models.Model): smtp_user = pycompat.to_native(ustr(smtp_user)) smtp_password = pycompat.to_native(ustr(smtp_password)) connection.login(smtp_user, smtp_password) + + # Some methods of SMTP don't check whether EHLO/HELO was sent. + # Anyway, as it may have been sent by login(), all subsequent usages should consider this command as sent. + connection.ehlo_or_helo_if_needed() + return connection def build_email(self, email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False,