libvirt_cloud/roles/toxcore/overlay/Linux/usr/local/src/stem_examples/smtp_proxy.py

90 lines
3.7 KiB
Python

# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
# https://stackoverflow.com/questions/5239797/python-smtplib-proxy-support
# https://stackoverflow.com/questions/19642726/testing-python-smtp-email-service
import socket
import smtplib
import socks
class ProxySMTP(smtplib.SMTP):
def __init__(self, host='', port=0, local_hostname=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, proxy_addr=None, proxy_port=None):
"""Initialize a new instance.
If specified, `host' is the name of the remote host to which to
connect. If specified, `port' specifies the port to which to connect.
By default, smtplib.SMTP_PORT is used. If a host is specified the
connect method is called, and if it returns anything other than a
success code an SMTPConnectError is raised. If specified,
`local_hostname` is used as the FQDN of the local host in the HELO/EHLO
command. Otherwise, the local hostname is found using
socket.getfqdn(). The `source_address` parameter takes a 2-tuple (host,
port) for the socket to bind to as its source address before
connecting. If the host is '' and port is 0, the OS default behavior
will be used.
"""
self._host = host
self.timeout = timeout
self.esmtp_features = {}
self.command_encoding = 'ascii'
self.source_address = source_address
self.proxy_addr = proxy_addr
self.proxy_port = proxy_port
if host:
(code, msg) = self.connect(host, port)
if code != 220:
self.close()
raise smtplib.SMTPConnectError(code, msg)
if local_hostname is not None:
self.local_hostname = local_hostname
else:
# RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
# if that can't be calculated, that we should use a domain literal
# instead (essentially an encoded IP address like [A.B.C.D]).
fqdn = socket.getfqdn()
if '.' in fqdn:
self.local_hostname = fqdn
else:
# We can't find an fqdn hostname, so use a domain literal
addr = '127.0.0.1'
try:
addr = socket.gethostbyname(socket.gethostname())
except socket.gaierror:
pass
self.local_hostname = '[%s]' % addr
def _get_socket(self, host, port, timeout):
# This makes it simpler for SMTP_SSL to use the SMTP connect code
# and just alter the socket connection bit.
if self.debuglevel > 0:
self._print_debug('connect: to', (host, port), self.source_address)
return socks.create_connection((host, port),
proxy_type=socks.PROXY_TYPE_SOCKS5,
timeout=timeout,
proxy_addr=self.proxy_addr,
proxy_port=self.proxy_port)
# And to use:
if __name__ == '__main__':
user_email, user_pass = 'foo', 'bar'
email_server = ProxySMTP('smtp.gmail.com', 587,
proxy_addr='127.0.0.1',
proxy_port=9050,
timeout=20)
email_server.starttls()
try:
email_server.login(user_email, user_pass)
except smtplib.SMTPAuthenticationError as e:
if len(e.args) > 1:
code = e.args[0]
if code = 535:
# 5.7.8 Username and Password not accepted
pass
raise
email_server.sendmail(user_email, recipient_list, msg.as_string())
email_server.quit()