Подключиться к SMTP (SSL или TLS) с помощью Python

Я пытаюсь подключиться к почтовому серверу gmail smtp и выполнять задачи, указанные в коде скелета, предоставленном мне. Допускается использование сокетов. Мне нужно: отправить команду HELO, Mail FROM, RCPT TO и DATA.

Существует много случаев подобных проблем, но они не получили надлежащего ответа. Пример: Реализация безопасности транспортного уровня в Python - Простой почтовый клиент

Программа должна подключаться к smtp.gmail.com через порт 587. Я применил два разных подхода:

Использование STARTTLS:

mailserver = 'smtp.gmail.com'
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((mailserver, 587))
recv = clientSocket.recv(1024)
print recv
if recv[:3] != '220':
print '220 reply not received from server.'

#Send HELO command and print server response
 heloCommand = 'HELO Alice\r\n'
 clientSocket.send(heloCommand)
 recv1 = clientSocket.recv(1024)
 print recv1
 if recv1[:3] != '250':
print '250 reply not received from server.'

#Send MAIL FROM command and print server response.
#Start, end
command = "STARTTLS\r\n"
clientSocket.send(command)
recvdiscard = clientSocket.recv(1024)
print recvdiscard
clientSocket.send("MAIL From: email\r\n")
recv2 = clientSocket.recv(1024)
print recv2
if recv2[:3] != '250':
print '250 reply not received from server.'

Использование SSL:

clientSocketSSL = ssl.wrap_socket(clientSocket)

Затем clientSocketSSL заменяет все экземпляры clientSocket. Строки STARTTLS также удаляются и import ssl добавляется вверх.

При использовании первого метода команда MAIL FROM: ничего не возвращает. Я получаю следующий вывод:

250 mx.google.com at your service

220 2.0.0 Ready to start TLS


250 reply not received from server.

При использовании SSL я получаю то же самое, что и связанный пост:

ssl.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

Я что-то упустил? Я думаю, мой лучший вариант - использовать TLS, но я не знаю, как это сделать... есть ли что-то не так с моей командой MAIL FROM?

Ответ 1

При использовании SSL вам необходимо подключиться к порту 465 вместо порта 587. Если вы используете STARTTLS, вам все равно нужно использовать ssl.wrap_socket, вы просто это сделаете позже - в частности, после получения ответа 220 на STARTTLS. После выполнения STARTTLS вы должны снова сделать HELO, так как сервер должен забыть все, что произошло до STARTTLS.

В любом случае серверы портов smtp.google.com 465 и 587 все равно не возвратят ответ 250 на команду MAIL, так как они требуют, чтобы вы были аутентифицированы перед отправкой почты. Вместо этого вы получите ответ 530. Вам нужно будет использовать команду AUTH с вашими учетными данными gmail.com для аутентификации, прежде чем вы сможете успешно использовать MAIL на этих серверах.

Если вы не хотите аутентифицироваться, и в зависимости от того, что вам нужно сделать, вы можете попробовать использовать порт 25 сервера, найденный в записи gmail.com MX. На данный момент сервер - gmail-smtp-in.l.google.com и поддерживает STARTTLS.