def ssl(conf: Configuration, privkey, cert, chain): conf.certificate = FilePath(cert) conf.chain = FilePath(chain) conf.privateKey = FilePath(privkey) conf.sslFactory = makeContextFactory(conf) if conf.factory: conf.tlsFactory = tls.TLSMemoryBIOFactory(conf.sslFactory, False, conf.factory)
def sendmail(config, to, messageFile): """ Sends an email """ contextFactory = ClientContextFactory() # evilaliv3: # in order to understand and before change this settings please # read the comment inside tor2web.utils.tls contextFactory.method = SSL.SSLv23_METHOD resultDeferred = defer.Deferred() senderFactory = ESMTPSenderFactory( config.smtpuser.encode('utf-8'), config.smtppass.encode('utf-8'), config.smtpmail, to, messageFile, resultDeferred, contextFactory=contextFactory, requireAuthentication=True, requireTransportSecurity=(config.smtpsecurity != 'SSL'), retries=0, timeout=15) if config.security == "SSL": senderFactory = tls.TLSMemoryBIOFactory(contextFactory, True, senderFactory) reactor.connectTCP(config.smtpdomain, config.smtpport, senderFactory) return resultDeferred
def connect(self, factory): # further wrap the protocol if we're doing TLS. # "pray i do not wrap the protocol further". if self._tls: # XXX requires Twisted 14+ from twisted.internet.ssl import optionsForClientTLS if self._tls is True: context = optionsForClientTLS(self._host) else: context = self._tls tls_factory = tls.TLSMemoryBIOFactory(context, True, factory) socks_factory = _TorSocksFactory( self._host, self._port, 'CONNECT', tls_factory, ) else: socks_factory = _TorSocksFactory( self._host, self._port, 'CONNECT', factory, ) self._socks_factory = socks_factory # forward our address (when we get it) to any listeners self._socks_factory._get_address().addBoth(self._when_address.fire) # XXX isn't this just maybeDeferred() if isinstance(self._proxy_ep, Deferred): proxy_ep = yield self._proxy_ep else: proxy_ep = self._proxy_ep # socks_proto = yield proxy_ep.connect(socks_factory) proto = yield proxy_ep.connect(socks_factory) wrapped_proto = yield proto.when_done() if self._tls: returnValue(wrapped_proto.wrappedProtocol) else: returnValue(wrapped_proto)
def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None): tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, True, factory) return self.connectTCP(host, port, tlsFactory, timeout, bindAddress)
def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None): if tls is not None: tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, True, factory) return self.connectTCP(host, port, tlsFactory, timeout, bindAddress) elif ssl is not None: c = ssl.Connector( host, port, factory, contextFactory, timeout, bindAddress, self) c.connect() return c else: assert False, "SSL support is not present"
def listenSSL(self, port, factory, contextFactory, backlog=50, interface=''): if tls is not None: tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, False, factory) port = self.listenTCP(port, tlsFactory, backlog, interface) port._type = 'TLS' return port elif ssl is not None: p = ssl.Port( port, factory, contextFactory, backlog, interface, self) p.startListening() return p else: assert False, "SSL support is not present"
def connect(self, factory): tls_factory = tls.TLSMemoryBIOFactory(self._server_options, isClient=False, wrappedFactory=factory) try: wf = _WrappingFactory(tls_factory) self._reactor.connectTCP(self._host, self._port, wf, timeout=self._timeout, bindAddress=self._bindAddress) return wf._onConnection except: return defer.fail()
def connect(self, factory): # further wrap the protocol if we're doing TLS. # "pray i do not wrap the protocol further". if self._tls: # XXX requires Twisted 14+ from twisted.internet.ssl import optionsForClientTLS if self._tls is True: context = optionsForClientTLS(self._host) else: context = self._tls tls_factory = tls.TLSMemoryBIOFactory(context, True, factory) socks_factory = _TorSocksFactory( self._host, self._port, 'CONNECT', tls_factory, ) else: socks_factory = _TorSocksFactory( self._host, self._port, 'CONNECT', factory, ) self._socks_factory = socks_factory # forward our address (when we get it) to any listeners self._socks_factory._get_address().addBoth(self._when_address.fire) # XXX isn't this just maybeDeferred() if isinstance(self._proxy_ep, Deferred): proxy_ep = yield self._proxy_ep if not IStreamClientEndpoint.providedBy(proxy_ep): raise ValueError( "The Deferred provided as 'socks_endpoint' must " "resolve to an IStreamClientEndpoint provider (got " "{})".format(type(proxy_ep).__name__)) else: proxy_ep = self._proxy_ep # socks_proto = yield proxy_ep.connect(socks_factory) proto = yield proxy_ep.connect(socks_factory) wrapped_proto = yield proto.when_done() if self._tls: returnValue(wrapped_proto.wrappedProtocol) else: returnValue(wrapped_proto)
def sendmail(config, messageFile): """ Sends an email using SSLv3 over SMTP @param authenticationUsername: account username @param authenticationSecret: account password @param fromAddress: the from address field of the email @param toAddress: the to address field of the email @param messageFile: the message content @param smtpHost: the smtp host @param smtpPort: the smtp port """ contextFactory = ClientContextFactory() # evilaliv3: # in order to understand and before change this settings please # read the comment inside tor2web.utils.ssl contextFactory.method = SSL.SSLv23_METHOD resultDeferred = defer.Deferred() senderFactory = ESMTPSenderFactory( config.smtpuser.encode('utf-8'), config.smtppass.encode('utf-8'), config.smtpmail, config.smtpmailto_exceptions, messageFile, resultDeferred, contextFactory=contextFactory, requireAuthentication=True, requireTransportSecurity=(config.smtpsecurity != 'SSL'), retries=0, timeout=15) if config.security == "SSL": senderFactory = tls.TLSMemoryBIOFactory(contextFactory, True, senderFactory) reactor.connectTCP(config.smtpdomain, config.smtpport, senderFactory) return resultDeferred
def connect(self, fac): fac = tls.TLSMemoryBIOFactory(self.contextFactory, True, fac) return self.wrappedEndpoint.connect(fac)
def listenSSLonExistingFD(reactor, fd, factory, contextFactory): tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, False, factory) port = reactor.listenTCPonExistingFD(reactor, fd, tlsFactory) port._type = 'TLS' return port
def sendmail(to_address, subject, body): """ Sends an email using SMTPS/SMTP+TLS and torify the connection @param to_address: the to address field of the email @param subject: the mail subject @param body: the mail body @param event: the event description, needed to keep track of failure/success """ try: if GLSettings.disable_mail_notification: return defer.succeed(None) if to_address == "": return result_deferred = defer.Deferred() def errback(reason, *args, **kwargs): # TODO: here it should be written a complete debugging of the possible # errors by writing clear log lines in relation to all the stack: # e.g. it should debugged all errors related to: TCP/SOCKS/TLS/SSL/SMTP/SFIGA if isinstance(reason, Failure): log.err("SMTP connection failed (Exception: %s)" % reason.value) log.debug(reason) return result_deferred.errback(reason) authentication_username = GLSettings.memory_copy.notif_username authentication_password = GLSettings.memory_copy.notif_password from_address = GLSettings.memory_copy.notif_source_email smtp_host = GLSettings.memory_copy.notif_server smtp_port = GLSettings.memory_copy.notif_port security = GLSettings.memory_copy.notif_security message = MIME_mail_build(GLSettings.memory_copy.notif_source_name, GLSettings.memory_copy.notif_source_email, to_address, to_address, subject, body) log.debug('Sending email to %s using SMTP server [%s:%d] [%s]' % (to_address, smtp_host, smtp_port, security)) if security != "PLAIN": context_factory = GLClientContextFactory() else: context_factory = ClientContextFactory() esmtp_deferred = defer.Deferred() esmtp_deferred.addCallbacks(result_deferred.callback, errback) condition = True if authentication_username == "" or authentication_password == "": condition = False alter_condition = False if security == "TLS": alter_condition = True factory = ESMTPSenderFactory(authentication_username.encode('utf-8'), authentication_password.encode('utf-8'), from_address, to_address, message, esmtp_deferred, contextFactory=context_factory, requireAuthentication=condition, requireTransportSecurity=alter_condition, retries=0, timeout=GLSettings.mail_timeout) if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if GLSettings.testing: # Hooking the test down to here is a trick to be able to test all the above code :) return defer.succeed(None) if security != "PLAIN": if not GLSettings.disable_mail_torification: socksProxy = TCP4ClientEndpoint( reactor, GLSettings.socks_host, GLSettings.socks_port, timeout=GLSettings.mail_timeout) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host.encode('utf-8'), smtp_port, timeout=GLSettings.mail_timeout) d = endpoint.connect(factory) d.addErrback(errback) else: reactor.connectTCP(smtp_host, smtp_port, factory) return result_deferred except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("Unexpected exception in sendmail: %s" % str(excep)) return defer.fail()
def sendmail(authentication_username, authentication_password, from_address, to_address, message_file, smtp_host, smtp_port, security, event=None): """ Sends an email using SSLv3 over SMTP @param authentication_username: account username @param authentication_secret: account password @param from_address: the from address field of the email @param to_address: the to address field of the email @param message_file: the message content its a StringIO @param smtp_host: the smtp host @param smtp_port: the smtp port @param security: may need to be STRING, here is converted at start @param event: the event description, needed to keep track of failure/success """ def printError(reason, event): # XXX is catch a wrong TCP port, but not wrong SSL protocol, here if event: log.err("** failed notification within event %s" % event.type) # TODO Enhance with retry # TODO specify a ticket - make event an Obj instead of a namedtuple # TODO It's defined in plugin/base.py if isinstance(reason, Failure): log.err("Failed to contact %s:%d (Sock Error %s)" % (smtp_host, smtp_port, reason.type)) log.debug(reason) def handle_error(reason, *args, **kwargs): # XXX event is not an argument here ? printError(reason, event) return result_deferred.errback(reason) def protocolConnectionLost(self, reason=protocol.connectionDone): """We are no longer connected""" if isinstance(reason, Failure): if not isinstance(reason.value, error.ConnectionDone): log.err("Failed to contact %s:%d (ConnectionLost Error %s)" % (smtp_host, smtp_port, reason.type)) log.debug(reason) self.setTimeout(None) self.mailFile = None def sendError(self, exc): if exc.code and exc.resp: error = re.match(r'^([0-9\.]+) ', exc.resp) error_str = "" if error: error_str = error.group(1) key = str(exc.code) + " " + error.group(1) if key in smtp_errors: error_str += " " + smtp_errors[key] log.err("Failed to contact %s:%d (SMTP Error: %.3d %s)" % (smtp_host, smtp_port, exc.code, error_str)) log.debug("Failed to contact %s:%d (SMTP Error: %.3d %s)" % (smtp_host, smtp_port, exc.code, exc.resp)) SMTPClient.sendError(self, exc) try: security = str(security) result_deferred = Deferred() context_factory = ClientContextFactory() context_factory.method = SSL.SSLv3_METHOD if security != "SSL": requireTransportSecurity = True else: requireTransportSecurity = False esmtp_deferred = Deferred() esmtp_deferred.addErrback(handle_error, event) esmtp_deferred.addCallback(result_deferred.callback) factory = ESMTPSenderFactory( authentication_username, authentication_password, from_address, to_address, message_file, esmtp_deferred, contextFactory=context_factory, requireAuthentication=(authentication_username and authentication_password), requireTransportSecurity=requireTransportSecurity) factory.protocol.sendError = sendError factory.protocol.connectionLost = protocolConnectionLost if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if GLSetting.tor_socks_enable: socksProxy = TCP4ClientEndpoint(reactor, GLSetting.socks_host, GLSetting.socks_port) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host, smtp_port) d = endpoint.connect(factory) d.addErrback(handle_error, event) except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("unexpected exception in sendmail: %s" % str(excep)) return fail() return result_deferred
def sendmail(to_address, subject, body): """ Sends an email using SMTPS/SMTP+TLS and torify the connection @param to_address: the to address field of the email @param subject: the mail subject @param body: the mail body @param event: the event description, needed to keep track of failure/success """ try: if not to_address: return result_deferred = defer.Deferred() def errback(reason, *args, **kwargs): # TODO: here it should be written a complete debugging of the possible # errors by writing clear log lines in relation to all the stack: # e.g. it should debugged all errors related to: TCP/SOCKS/TLS/SSL/SMTP/SFIGA if isinstance(reason, Failure): log.err("SMTP connection failed (Exception: %s)", reason.value) log.debug(reason) return result_deferred.errback(reason) result_deferred.addErrback(errback) authentication_username = State.tenant_cache[1].notif.username authentication_password = State.tenant_cache[1].private.smtp_password from_address = State.tenant_cache[1].notif.source_email smtp_host = State.tenant_cache[1].notif.server smtp_port = State.tenant_cache[1].notif.port security = State.tenant_cache[1].notif.security message = MIME_mail_build(State.tenant_cache[1].notif.source_name, State.tenant_cache[1].notif.source_email, to_address, to_address, subject, body) log.debug('Sending email to %s using SMTP server [%s:%d] [%s]', to_address, smtp_host, smtp_port, security) context_factory = TLSClientContextFactory() factory = ESMTPSenderFactory( authentication_username.encode('utf-8'), authentication_password.encode('utf-8'), from_address, to_address, message, result_deferred, contextFactory=context_factory, requireAuthentication=True, requireTransportSecurity=(security != 'SSL'), retries=0, timeout=Settings.mail_timeout) if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if State.tenant_cache[1].anonymize_outgoing_connections: socksProxy = TCP4ClientEndpoint(reactor, Settings.socks_host, Settings.socks_port, timeout=Settings.mail_timeout) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host.encode('utf-8'), smtp_port, timeout=Settings.mail_timeout) if Settings.testing: # Hooking the test down to here is a trick to be able to test all the above code :) return defer.succeed(None) d = endpoint.connect(factory) d.addErrback(errback) return result_deferred except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("Unexpected exception in sendmail: %s", str(excep)) return defer.fail()
def launch(conf: Configuration, application: str): module, attribute = application.rsplit('.', 1) mod = importlib.import_module(module) conf.factory = getattr(mod, attribute) if conf.sslFactory: conf.tlsFactory = tls.TLSMemoryBIOFactory(conf.sslFactory, False, conf.factory)
def sendmail(to_address, subject, body): """ Send an email using SMTPS/SMTP+TLS and maybe torify the connection. @param to_address: the 'To:' field of the email @param subject: the mail subject @param body: the mail body @return: a {Deferred} that returns a success {bool} if the message was passed to the server. """ try: if not to_address: return authentication_username = State.tenant_cache[1].notif.username authentication_password = State.tenant_cache[1].private.smtp_password from_address = State.tenant_cache[1].notif.source_email smtp_host = State.tenant_cache[1].notif.server smtp_port = State.tenant_cache[1].notif.port security = State.tenant_cache[1].notif.security message = MIME_mail_build(State.tenant_cache[1].notif.source_name, State.tenant_cache[1].notif.source_email, to_address, to_address, subject, body) log.debug('Sending email to %s using SMTP server [%s:%d] [%s]', to_address, smtp_host, smtp_port, security) context_factory = TLSClientContextFactory() smtp_deferred = defer.Deferred() factory = ESMTPSenderFactory( authentication_username.encode('utf-8'), authentication_password.encode('utf-8'), from_address, to_address, message, smtp_deferred, contextFactory=context_factory, requireAuthentication=True, requireTransportSecurity=(security != 'SSL'), retries=0, timeout=Settings.mail_timeout) if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if State.tenant_cache[1].anonymize_outgoing_connections: socksProxy = TCP4ClientEndpoint(reactor, Settings.socks_host, Settings.socks_port, timeout=Settings.mail_timeout) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host.encode('utf-8'), smtp_port, timeout=Settings.mail_timeout) if Settings.testing: # during unit testing do not try to send the mail return defer.succeed(True) conn_deferred = endpoint.connect(factory) final = defer.DeferredList([conn_deferred, smtp_deferred], fireOnOneErrback=True, consumeErrors=True) def failure_cb(failure): """ @param failure {Failure {twisted.internet.FirstError {Failure}}} """ log.err("SMTP connection failed (Exception: %s)", failure.value.subFailure.value) log.debug(failure) return False def success_cb(results): """ @param results {list of (success, return_val) tuples} """ return True final.addCallback(success_cb) final.addErrback(failure_cb) return final except Exception as excep: # avoids raising an exception inside email logic to avoid chained errors log.err("Unexpected exception in sendmail: %s", str(excep)) return defer.succeed(False)
def sendmail(authentication_username, authentication_password, from_address, to_address, message_file, smtp_host, smtp_port, security, event=None): """ Sends an email using SMTPS/SMTP+TLS and torify the connection @param authentication_username: account username @param authentication_password: account password @param from_address: the from address field of the email @param to_address: the to address field of the email @param message_file: the message content its a StringIO @param smtp_host: the smtp host @param smtp_port: the smtp port @param security: may need to be STRING, here is converted at start @param event: the event description, needed to keep track of failure/success """ notif_retries = 2 notif_timeout = 10 def printError(method, reason, event): if event: log.err("** failed notification within event %s" % event.type) if isinstance(reason, Failure): log.err( "Failed to connect to %s:%d (Sock Error: %s) (Method: %s)" % (smtp_host, smtp_port, reason.value, method)) log.debug(reason) def esmtp_errback(reason, *args, **kwargs): printError("ESMTP", reason, event) return result_deferred.errback(reason) def socks_errback(reason, *args, **kwargs): printError("SOCKS5", reason, event) return result_deferred.errback(reason) def tcp4_errback(reason, *args, **kwargs): printError("TCP4", reason, event) return result_deferred.errback(reason) def result_errback(reason, *args, **kwargs): """To not report an error as unexpected in the log files""" return True def esmtp_sendError(self, exc): if exc.code and exc.resp: error_str = "" error = re.match(r'^([0-9\.]+) ', exc.resp) if error: key = str(exc.code) + " " + error.group(1) if key in smtp_errors: error_str += " " + smtp_errors[key] verb = '[unknown]' if 'authentication' in exc.resp: verb = 'autenticate' if 'not support secure' in exc.resp: verb = 'negotiate TLS' log.err("Failed to %s to %s:%d (SMTP Code: %.3d) (%s)" % (verb, smtp_host, smtp_port, exc.code, error_str)) SMTPClient.sendError(self, exc) def esmtp_connectionLost(self, reason=protocol.connectionDone): """We are no longer connected""" if isinstance(reason, Failure): if not isinstance(reason.value, error.ConnectionDone): verb = 'unknown_verb' if 'OpenSSL' in str(reason.type): verb = 'negotiate SSL' log.err("Failed to %s to %s:%d (%s)" % (verb, smtp_host, smtp_port, reason.type)) log.debug(reason) self.setTimeout(None) self.mailFile = None # TODO: validation? if from_address == '' or to_address == '': log.err( "Failed to init sendmail to %s:%s (Invalid from/to addresses)" % (from_address, to_address)) return if security != "SSL" and security != "disabled": requireTransportSecurity = True else: requireTransportSecurity = False try: security = str(security) result_deferred = Deferred() result_deferred.addErrback(result_errback, event) context_factory = ClientContextFactory() # evilaliv3: # this is the same solution I applied to tor2web: # as discussed on https://trac.torproject.org/projects/tor/ticket/11598 # there is no way of enabling all TLS methods excluding SSL. # the problem lies in the fact that SSL.TLSv1_METHOD | SSL.TLSv1_1_METHOD | SSL.TLSv1_2_METHOD # is denied by OpenSSL. # # As spotted by nickm the only good solution right now is to enable SSL.SSLv23_METHOD then explicitly # use options: SSL_OP_NO_SSLv2 and SSL_OP_NO_SSLv3 # # This trick make openssl consider valid all TLS methods. # context_factory.method = SSL.SSLv23_METHOD esmtp_deferred = Deferred() esmtp_deferred.addErrback(esmtp_errback, event) esmtp_deferred.addCallback(result_deferred.callback) except Exception as excep: log.err( "Error in Twisted objects init - unexpected exception in sendmail: %s" % str(excep)) return fail() try: factory = ESMTPSenderFactory( authentication_username, authentication_password, from_address, to_address, message_file, esmtp_deferred, contextFactory=context_factory, requireAuthentication=(authentication_username and authentication_password), requireTransportSecurity=requireTransportSecurity, retries=notif_retries, timeout=notif_timeout) factory.protocol.sendError = esmtp_sendError factory.protocol.connectionLost = esmtp_connectionLost if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) except Exception as excep: log.err( "Error in factory init - unexpected exception in sendmail: %s" % str(excep)) return fail() try: if not GLSettings.disable_mail_torification and GLSettings.memory_copy.notif_uses_tor: socksProxy = TCP4ClientEndpoint(reactor, GLSettings.socks_host, GLSettings.socks_port, timeout=notif_timeout) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) d = endpoint.connect(factory) d.addErrback(socks_errback, event) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host, smtp_port, timeout=notif_timeout) d = endpoint.connect(factory) d.addErrback(tcp4_errback, event) except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("unexpected exception in sendmail: %s" % str(excep)) return fail() return result_deferred
def sendmail(tid, smtp_host, smtp_port, security, authentication, username, password, from_name, from_address, to_address, subject, body, anonymize=True, socks_host='127.0.0.1', socks_port=9050): """ Send an email using SMTPS/SMTP+TLS and maybe torify the connection. :param tid: A tenant id :param smtp_host: A SMTP host :param smtp_port: A SMTP port :param security: A type of security to be applied (SMTPS/SMTP+TLS) :param authentication: A boolean to enable authentication :param username: A mail account username :param password: A mail account password :param from_name: A from name :param from_address: A from address :param to_address: The to address :param subject: A mail subject :param body: A mail body :param anonymize: A boolean to enable anonymous mail connection :param socks_host: A socks host to be used for the mail connection :param socks_port: A socks port to be used for the mail connection :return: A deferred resource resolving at the end of the connection """ try: timeout = 30 message = MIME_mail_build(from_name, from_address, to_address, to_address, subject, body) log.debug('Sending email to %s using SMTP server [%s:%d] [%s]', to_address, smtp_host, smtp_port, security, tid=tid) context_factory = TLSClientContextFactory() smtp_deferred = defer.Deferred() factory = ESMTPSenderFactory( username.encode() if authentication else None, password.encode() if authentication else None, from_address, to_address, message, smtp_deferred, contextFactory=context_factory, requireAuthentication=authentication, requireTransportSecurity=(security == 'TLS'), retries=0, timeout=timeout) if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if anonymize: socksProxy = TCP4ClientEndpoint(reactor, socks_host, socks_port, timeout=timeout) endpoint = SOCKS5ClientEndpoint(smtp_host, smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host, smtp_port, timeout=timeout) conn_deferred = endpoint.connect(factory) final = defer.DeferredList([conn_deferred, smtp_deferred], fireOnOneErrback=True, consumeErrors=True) def failure_cb(failure): """ :param failure {Failure {twisted.internet.FirstError {Failure}}} """ log.err("SMTP connection failed (Exception: %s)", failure.value.subFailure.value, tid=tid) return False def success_cb(results): """ :param results {list of (success, return_val) tuples} """ return True return final.addCallbacks(success_cb, failure_cb) except Exception as e: # avoids raising an exception inside email logic to avoid chained errors log.err("Unexpected exception in sendmail: %s", e, tid=tid) return defer.succeed(False)
def sendmail(tid, username, password, smtp_host, smtp_port, security, from_name, from_address, to_address, subject, body, anonymize=True, socks_host='127.0.0.1', socks_port=9050): """ Send an email using SMTPS/SMTP+TLS and maybe torify the connection. @param to_address: the 'To:' field of the email @param subject: the mail subject @param body: the mail body @return: a {Deferred} that returns a success {bool} if the message was passed to the server. """ try: timeout = 30 message = MIME_mail_build(from_name, from_address, to_address, to_address, subject, body) log.debug('Sending email to %s using SMTP server [%s:%d] [%s]', to_address, smtp_host, smtp_port, security, tid=tid) context_factory = TLSClientContextFactory() smtp_deferred = defer.Deferred() factory = ESMTPSenderFactory( username.encode('utf-8'), password.encode('utf-8'), from_address, to_address, message, smtp_deferred, contextFactory=context_factory, requireAuthentication=True, requireTransportSecurity=(security != 'SSL'), retries=0, timeout=timeout) if security == "SSL": factory = tls.TLSMemoryBIOFactory(context_factory, True, factory) if anonymize: socksProxy = TCP4ClientEndpoint(reactor, socks_host, socks_port, timeout=timeout) endpoint = SOCKS5ClientEndpoint(smtp_host.encode('utf-8'), smtp_port, socksProxy) else: endpoint = TCP4ClientEndpoint(reactor, smtp_host.encode('utf-8'), smtp_port, timeout=timeout) conn_deferred = endpoint.connect(factory) final = defer.DeferredList([conn_deferred, smtp_deferred], fireOnOneErrback=True, consumeErrors=True) def failure_cb(failure): """ @param failure {Failure {twisted.internet.FirstError {Failure}}} """ log.err("SMTP connection failed (Exception: %s)", failure.value.subFailure.value, tid=tid) log.debug(failure) return False def success_cb(results): """ @param results {list of (success, return_val) tuples} """ return True final.addCallback(success_cb) final.addErrback(failure_cb) return final except Exception as excep: # avoids raising an exception inside email logic to avoid chained errors log.err("Unexpected exception in sendmail: %s", str(excep), tid=tid) return defer.succeed(False)
def listen_tls_on_sock(reactor, fd, contextFactory, factory): tlsFactory = tls.TLSMemoryBIOFactory(contextFactory, False, factory) port = listen_tcp_on_sock(reactor, fd, tlsFactory) port._type = 'TLS' return port