コード例 #1
0
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
コード例 #2
0
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):
            if recipient not in deliverable_addresses:
                reply.code = '550'
                reply.message = '5.7.1 Recipient <{0}> Not allowed'.format(recipient)
                return

    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
コード例 #3
0
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
コード例 #4
0
ファイル: slimta-mail.py プロジェクト: madhugb/python-slimta
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)

    tls = _get_tls_args(args)

    edge = SmtpEdge(('', args.outbound_port), queue, tls=tls,
                    validator_class=EdgeValidators,
                    auth=[b'PLAIN', b'LOGIN'],
                    command_timeout=20.0, data_timeout=30.0)
    edge.start()

    return edge
コード例 #5
0
ファイル: state.py プロジェクト: servotim/slimta
 def _start_edge(self, name, options=None):
     if name in self.edges:
         return self.edges[name]
     if not options:
         options = getattr(self.cfg.edge, name)
     new_edge = None
     if options.type == 'smtp':
         from slimta.edge.smtp import SmtpEdge
         from .helpers import build_smtpedge_validators, build_smtpedge_auth
         from .helpers import fill_hostname_template
         ip = options.listener.get('interface', '127.0.0.1')
         port = int(options.listener.get('port', 25))
         queue_name = options.queue
         queue = self._start_queue(queue_name)
         kwargs = {}
         if options.get('tls'):
             kwargs['tls'] = dict(options.tls)
         kwargs['tls_immediately'] = options.get('tls_immediately', False)
         kwargs['validator_class'] = build_smtpedge_validators(options)
         kwargs['auth_class'] = build_smtpedge_auth(options)
         kwargs['command_timeout'] = 20.0
         kwargs['data_timeout'] = 30.0
         kwargs['max_size'] = options.get('max_size', 10485760)
         kwargs['hostname'] = fill_hostname_template(options.get('hostname'))
         new_edge = SmtpEdge((ip, port), queue, **kwargs)
         new_edge.start()
     else:
         raise ConfigError('edge type does not exist: '+options.type)
     self.edges[name] = new_edge
     return new_edge
コード例 #6
0
 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()
コード例 #7
0
 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()
コード例 #8
0
class MDA(MTA):
    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()
コード例 #9
0
 def _start_edge(self, name, options=None):
     if name in self.edges:
         return self.edges[name]
     if not options:
         options = getattr(self.cfg.edge, name)
     new_edge = None
     queue_name = options.queue
     queue = self._start_queue(queue_name)
     ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
     if options.type == 'smtp':
         from slimta.edge.smtp import SmtpEdge
         from .helpers import build_smtpedge_validators
         from .helpers import fill_hostname_template
         hostname = fill_hostname_template(options.get('hostname'))
         listener_defaults = {'interface': '127.0.0.1', 'port': 25}
         listener = self._get_listener(options.listener, listener_defaults)
         kwargs = {}
         kwargs['context'] = self._get_ssl_context(ctx, options.get('tls'))
         kwargs['tls_immediately'] = options.get('tls_immediately', False)
         kwargs['validator_class'] = build_smtpedge_validators(options)
         kwargs['auth'] = ['PLAIN', 'LOGIN']
         kwargs['command_timeout'] = 20.0
         kwargs['data_timeout'] = 30.0
         kwargs['max_size'] = int(options.get('max_size', 10485760))
         kwargs['hostname'] = hostname
         new_edge = SmtpEdge(listener, queue, **kwargs)
         new_edge.start()
     elif options.type == 'http':
         from slimta.edge.wsgi import WsgiEdge
         from .helpers import build_wsgiedge_validators
         from .helpers import fill_hostname_template
         hostname = fill_hostname_template(options.get('hostname'))
         uri_pattern = options.get('uri')
         validator_class = build_wsgiedge_validators(options)
         new_edge = WsgiEdge(queue, hostname, validator_class, uri_pattern)
         listener_defaults = {'interface': '127.0.0.1', 'port': 8025}
         listener = self._get_listener(options.listener, listener_defaults)
         server = new_edge.build_server(listener, tls=options.get('tls'))
         server.start()
     elif options.type == 'custom':
         new_edge = self._load_from_custom(options, queue)
     else:
         msg = 'edge type does not exist: '+options.type
         raise ConfigValidationError(msg)
     self.edges[name] = new_edge
     return new_edge
コード例 #10
0
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
コード例 #11
0
class MSA(MTA):
    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()
コード例 #12
0
ファイル: slimta-mail.py プロジェクト: you4you4/python-slimta
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)

    context = _get_ssl_context_server(args)

    edge = SmtpEdge(('', args.inbound_port), queue, max_size=10240,
                    validator_class=EdgeValidators, context=context,
                    command_timeout=20.0,
                    data_timeout=30.0)
    edge.start()

    ssl_edge = SmtpEdge(('', args.inbound_ssl_port), queue,
                        validator_class=EdgeValidators,
                        auth=[b'PLAIN', b'LOGIN'],
                        context=context, tls_immediately=True,
                        command_timeout=20.0, data_timeout=30.0)
    ssl_edge.start()

    return edge, ssl_edge
コード例 #13
0
 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)
コード例 #14
0
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
コード例 #15
0
from slimta.queue.dict import DictStorage
from slimta.relay import RelayError
from slimta.relay.smtp.static import StaticSmtpRelay

def backoff(envelope, attempts):
    if attempts <= 5:
        return 5.0 * attempts

relay = StaticSmtpRelay('mail.example.com', 25, pool_size=2)

env_db = shelve.open('envelope.db')
meta_db = shelve.open('meta.db')
queue_storage = DictStorage(env_db, meta_db)
queue = Queue(queue_storage, relay, backoff)

edge = SmtpEdge(('127.0.0.1', 1337), queue)
edge.start()
queue.start()
try:
    edge.get()
except KeyboardInterrupt:
    print
finally:
    for key in env_db.keys():
        print 'env', key
    for key in meta_db.keys():
        print 'meta', key
    env_db.close()
    meta_db.close()

# vim:et:fdm=marker:sts=4:sw=4:ts=4