13.1.2 认证加密
SMTP类还会处理认证和传输层安全(Transport Layer Sercurity,TLS)加密(如果服务器提供了支持)。要确定服务器是否支持TLS,可以直接调用ehlo()为服务器标识客户,询问可以得到哪些扩展。然后调用has_extn()来检查结果。启动TLS之后,在认证用户之前必须再次调用ehlo()。很多邮件托管提供商现在只支持基于TLS的连接。要与这些服务器通信,可以使用SMTP_SSL来启动一个加密连接。
import smtplib
import email.utils
from email.mime.text import MIMEText
import getpass
# Prompt the user for connection info.
to_email = input('Recipient: ')
servername = input('Mail server name: ')
serverport = input('Server prot: ')
if serverport:
serverport = int(serverport)
else:
serverport = 25
use_tls = input('Use TLS? (yes/no): ').lower()
username = input('Mail username: ')
password = getpass.getpass("%s's password: " % username)
# Create the message.
msg = MIMEText('Test message from PyMOTW.')
msg.set_unixfrom('author')
msg['To'] = email.utils.formataddr(('Recipient',to_email))
msg['From'] = email.utils.formataddr(('Author','邮箱'))
msg['Subject'] = 'Test from PyMOTW'
if use_tls == 'yes':
print('starting with a secure connection')
server = smtplib.SMTP_SSL(servername,serverport)
else:
print('starting with a insecure connection')
server = smtplib.SMTP(servername,serverport)
try:
server.set_debuglevel(True)
# Identify ourselves, prompting server for supported features.
server.ehlo()
# If we can encrypt this session, do it.
if server.has_extn('STARTTLS'):
print('(starting TLS)')
server.starttls()
server.ehlo() # Reidentify ourselves over TLS connection.
else:
print('(no STARTTLS)')
if server.has_extn('AUTH'):
print('(logging in)')
server.login(username,password)
else:
print('(no AUTH)')
server.sendmail('发件人',
[to_email],
msg.as_string())
finally:
server.quit()
启用TLS之后,STARTTLS扩展不会出现在对EHLO的应答中。