def _start_outbound_edge(args, queue): from slimta.edge.smtp import SmtpEdge, SmtpValidators from slimta.util.dnsbl import check_dnsbl from slimta.smtp.auth import Auth, CredentialsInvalidError from site_data import credentials, outbound_banner class EdgeAuth(Auth): def verify_secret(self, username, password, identity=None): try: assert credentials[username] == password except (KeyError, AssertionError): raise CredentialsInvalidError() return username def get_secret(self, username, identity=None): try: return credentials[username], username except KeyError: raise CredentialsInvalidError() class EdgeValidators(SmtpValidators): @check_dnsbl('zen.spamhaus.org') def handle_banner(self, reply, address): reply.message = outbound_banner def handle_mail(self, reply, sender): print self.session.auth_result if not self.session.auth_result: reply.code = '550' reply.message = '5.7.1 Sender <{0}> Not allowed'.format(sender) tls = _get_tls_args(args) edge = SmtpEdge(('', args.outbound_port), queue, tls=tls, validator_class=EdgeValidators, auth_class=EdgeAuth, command_timeout=20.0, data_timeout=30.0) edge.start() ssl_edge = SmtpEdge(('', args.outbound_ssl_port), queue, validator_class=EdgeValidators, auth_class=EdgeAuth, tls=tls, tls_immediately=True, command_timeout=20.0, data_timeout=30.0) ssl_edge.start() return edge, ssl_edge
def _start_outbound_edge(args, queue): from slimta.edge.smtp import SmtpEdge, SmtpValidators from slimta.util.dnsbl import check_dnsbl from site_data import credentials, outbound_banner class EdgeValidators(SmtpValidators): @check_dnsbl('zen.spamhaus.org') def handle_banner(self, reply, address): reply.message = outbound_banner def handle_auth(self, reply, creds): try: password = credentials[creds.authcid] assert creds.check_secret(password) except (KeyError, AssertionError): reply.code = '535' reply.message = '5.7.8 Authentication credentials invalid' def handle_mail(self, reply, sender, params): if not self.session.auth: reply.code = '550' reply.message = '5.7.1 Sender <{0}> Not allowed'.format(sender) context = _get_ssl_context_server(args) edge = SmtpEdge(('', args.outbound_port), queue, context=context, validator_class=EdgeValidators, auth=[b'PLAIN', b'LOGIN'], command_timeout=20.0, data_timeout=30.0) edge.start() return edge
def _start_inbound_edge(args, queue): from slimta.edge.smtp import SmtpEdge, SmtpValidators from slimta.util.dnsbl import check_dnsbl from site_data import inbound_banner, deliverable_addresses class EdgeValidators(SmtpValidators): @check_dnsbl('zen.spamhaus.org', match_code='520') def handle_banner(self, reply, address): reply.message = inbound_banner def handle_rcpt(self, reply, recipient, params): if recipient not in deliverable_addresses: reply.code = '550' reply.message = \ '5.7.1 Recipient <{0}> Not allowed'.format(recipient) tls = _get_tls_args(args) edge = SmtpEdge(('', args.inbound_port), queue, max_size=10240, validator_class=EdgeValidators, tls=tls, command_timeout=20.0, data_timeout=30.0) edge.start() return edge
def _start_edge(self, name, options=None): if not options: options = getattr(self.cfg.edge, name) new_edges = [] queue_name = options.queue queue = self._start_queue(queue_name) if options.type == 'smtp': from slimta.edge.smtp import SmtpEdge from .helpers import build_smtpedge_validators from .helpers import fill_hostname_template kwargs = {} kwargs['context'] = self._get_server_ssl_context(options.tls) kwargs['tls_immediately'] = options.tls_immediately kwargs['validator_class'] = build_smtpedge_validators(options) kwargs['auth'] = [b'PLAIN', b'LOGIN'] kwargs['command_timeout'] = 20.0 kwargs['data_timeout'] = 30.0 kwargs['max_size'] = int(options.get('max_size', 10485760)) kwargs['hostname'] = fill_hostname_template(options.hostname) for listener in Listeners(options, 25): new_edge = SmtpEdge(listener, queue, **kwargs) if options.proxyprotocol: ProxyProtocol.mixin(new_edge) new_edge.start() self.edges.append(new_edge) elif options.type == 'http': from slimta.edge.wsgi import WsgiEdge from .helpers import build_wsgiedge_validators from .helpers import fill_hostname_template kwargs = {} kwargs['hostname'] = fill_hostname_template(options.hostname) kwargs['validator_class'] = build_wsgiedge_validators(options) kwargs['uri_pattern'] = options.uri kwargs['context'] = self._get_server_ssl_context(options.tls) listener = self._get_listener(options, 8025) for listener in Listeners(options, 8025): new_edge = WsgiEdge(queue, listener=listener, **kwargs) if options.proxyprotocol: ProxyProtocol.mixin(new_edge) new_edge.start() self.edges.append(new_edge) elif options.type == 'custom': new_edge = custom_factory(options, queue) self.edges.append(new_edge) else: msg = 'edge type does not exist: '+options.type raise ConfigValidationError(msg)
def test_smtp_edge(self): queue = self.mox.CreateMockAnything() queue.enqueue(IsA(Envelope)).AndReturn([(Envelope(), 'testid')]) self.mox.ReplayAll() server = SmtpEdge(('127.0.0.1', 0), queue) server.start() gevent.sleep(0) client_sock = create_connection(server.server.address) client = Client(client_sock) client.get_banner() client.ehlo('there') client.mailfrom('*****@*****.**') client.rcptto('*****@*****.**') client.data() client.send_empty_data() client.quit() client_sock.close()
def __init__(self, msa, mail_list_url, mda_domain, list_subject_prefix=None): self.msa = msa # Relay: relay = DovecotLdaRelay(config['LDA']['dovecot_path'], timeout=10.0) # Queue: #env_db = shelve.open('envelope') #meta_db = shelve.open('meta') #storage = DictStorage(env_db, meta_db) # !!! replace with DiskStorage! (installed via pip install python-slimta-diskstorage) storage = DiskStorage(config['MDA']['ds_env'], config['MDA']['ds_meta']) self.queue = Queue( storage, relay) # no backoff - just fail local delivery immediately self.queue.start() # Headers: self.queue.add_policy(AddDateHeader()) self.queue.add_policy(AddMessageIdHeader()) self.queue.add_policy(AddReceivedHeader()) # Mailing List: self.queue.add_policy( MailingListDistribution(self.msa, mail_list_url, mda_domain, list_subject_prefix)) # SpamAssassin: #self.queue.add_policy(SpamAssassin()) # Edge: #tls_args = {'keyfile': '/home/jmcaine/dev/temp/slimta/tls/key.pem', 'certfile': '/home/jmcaine/dev/temp/slimta/tls/certificate.pem'} -- gone, see https://docs.slimta.org/en/latest/blog/2016-11-14.html ssl = SSLContext(PROTOCOL_SSLv23) ssl.load_cert_chain(config['SSL']['certificate_path'], config['SSL']['key_path']) self.edge = SmtpEdge(('0.0.0.0', 25), self.queue, validator_class=MDA_Validators, hostname=mda_domain, context=ssl) self.edge.start()
def __init__(self): # Relay: ssl = SSLContext(PROTOCOL_SSLv23) ssl.load_cert_chain(config['SSL']['certificate_path'], config['SSL']['key_path']) self.relay = MxSmtpRelay(context=ssl, connect_timeout=20, command_timeout=10, data_timeout=20, idle_timeout=30) # Queue: #env_db = shelve.open('msa_envelope') #meta_db = shelve.open('msa_meta') #storage = DictStorage(env_db, meta_db) # !!! replace with DiskStorage! (installed via pip install python-slimta-diskstorage) storage = DiskStorage(config['MSA']['ds_env'], config['MSA']['ds_meta']) def retry_backoff(envelope, attempts): if attempts < 10: return 60 * attempts * attempts # try again at increasingly long intervals; give up after 10 tries (100 minutes) return None self.queue = Queue(storage, self.relay, backoff=retry_backoff) self.queue.start() # Headers: self.queue.add_policy(AddDateHeader()) self.queue.add_policy(AddMessageIdHeader()) self.queue.add_policy(AddReceivedHeader()) self.queue.add_policy(RecipientDomainSplit()) # !!! Add Forward policy here, to manage general forwarding (but not list distribution - do that in mda!) # Edge: self.edge = SmtpEdge( ('localhost', 587), self.queue, auth=False ) #, auth=True, validator_class=MSA_Validators) # ?!!! context=ssl, tls_immediately=True, self.edge.start()