def test_choose_mx(self):
     records = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
     mx = MxSmtpRelay()
     self.assertEqual(1, mx.choose_mx(records, 0))
     self.assertEqual(5, mx.choose_mx(records, 4))
     self.assertEqual(1, mx.choose_mx(records, 5))
     self.assertEqual(3, mx.choose_mx(records, 7))
     self.assertEqual(2, mx.choose_mx(records, 1821))
 def test_choose_mx(self):
     records = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
     mx = MxSmtpRelay()
     self.assertEqual(1, mx.choose_mx(records, 0))
     self.assertEqual(5, mx.choose_mx(records, 4))
     self.assertEqual(1, mx.choose_mx(records, 5))
     self.assertEqual(3, mx.choose_mx(records, 7))
     self.assertEqual(2, mx.choose_mx(records, 1821))
 def test_attempt_no_answer(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns_resolver, 'query')
     dns_resolver.query('example.com', 'MX').AndRaise(DNSTimeout)
     self.mox.ReplayAll()
     with assert_raises(TransientRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_answer(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns_resolver, 'query')
     dns_resolver.query('example.com', 'MX').AndRaise(DNSTimeout)
     self.mox.ReplayAll()
     with self.assertRaises(TransientRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_answer(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     mx = MxSmtpRelay()
     self.mox.StubOutWithMock(mx, "new_static_relay")
     self.mox.StubOutWithMock(dns_resolver, "query")
     dns_resolver.query("example.com", "MX").AndRaise(DNSTimeout)
     self.mox.ReplayAll()
     with assert_raises(TransientRelayError):
         mx.attempt(env, 0)
Example #6
0
 def test_attempt_no_records(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(DNSResolver, 'query')
     DNSResolver.query('example.com', 'MX').AndRaise(DNSError(ARES_ENOTFOUND))
     DNSResolver.query('example.com', 'A').AndRaise(DNSError(ARES_ENOTFOUND))
     self.mox.ReplayAll()
     with self.assertRaises(PermanentRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_answer(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(DNSResolver, 'query')
     DNSResolver.query('example.com', 'MX').AndRaise(DNSError(ARES_ENODATA))
     DNSResolver.query('example.com', 'A').AndRaise(DNSError(ARES_ENODATA))
     self.mox.ReplayAll()
     with self.assertRaises(PermanentRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_records(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns.resolver, 'query')
     dns.resolver.query('example.com', 'MX').AndRaise(dns.resolver.NXDOMAIN)
     dns.resolver.query('example.com', 'A').AndRaise(dns.resolver.NXDOMAIN)
     self.mox.ReplayAll()
     with self.assertRaises(PermanentRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_records(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns_resolver, 'query')
     dns_resolver.query('example.com', 'MX').AndRaise(dns.resolver.NXDOMAIN)
     dns_resolver.query('example.com', 'A').AndRaise(dns.resolver.NXDOMAIN)
     self.mox.ReplayAll()
     with assert_raises(PermanentRelayError):
         mx.attempt(env, 0)
 def test_attempt_no_records(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, "new_static_relay")
     self.mox.StubOutWithMock(dns_resolver, "query")
     dns_resolver.query("example.com", "MX").AndRaise(dns.resolver.NXDOMAIN)
     dns_resolver.query("example.com", "A").AndRaise(dns.resolver.NXDOMAIN)
     self.mox.ReplayAll()
     with assert_raises(PermanentRelayError):
         mx.attempt(env, 0)
Example #11
0
 def test_attempt_no_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     a_ret = FakeAAnswer(False, [('1.2.3.4', )])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(DNSResolver, 'query')
     DNSResolver.query('example.com', 'MX').AndRaise(DNSError(ARES_ENOTFOUND))
     DNSResolver.query('example.com', 'A').AndReturn(FakeAsyncResult(a_ret))
     mx.new_static_relay('example.com', 25).AndReturn(static)
     static.attempt(env, 0)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
 def test_attempt_no_mx(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     a_ret = FakeAAnswer(False, [("1.2.3.4",)])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, "new_static_relay")
     self.mox.StubOutWithMock(dns_resolver, "query")
     dns_resolver.query("example.com", "MX").AndRaise(dns.resolver.NXDOMAIN)
     dns_resolver.query("example.com", "A").AndReturn(a_ret)
     mx.new_static_relay("1.2.3.4", 25).AndReturn(static)
     static.attempt(env, 0)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
 def test_attempt_no_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     a_ret = FakeAAnswer(False, [('1.2.3.4', )])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns.resolver, 'query')
     dns.resolver.query('example.com', 'MX').AndRaise(dns.resolver.NXDOMAIN)
     dns.resolver.query('example.com', 'A').AndReturn(a_ret)
     mx.new_static_relay('1.2.3.4', 25).AndReturn(static)
     static.attempt(env, 0)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
 def test_attempt_force_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     mx.new_static_relay('mail.example.com', 25).AndReturn(static)
     static.attempt(env, 0)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.force_mx('example.com', 'mail.example.com')
     mx.attempt(env, 0)
     mx.attempt(env, 1)
Example #15
0
def _start_outbound_relay(args):
    from slimta.relay.smtp.mx import MxSmtpRelay

    tls = _get_tls_args(args)

    relay = MxSmtpRelay(tls=tls,
                        connect_timeout=20.0,
                        command_timeout=10.0,
                        data_timeout=20.0,
                        idle_timeout=10.0)
    return relay
Example #16
0
def _start_outbound_relay(args):
    from slimta.relay.smtp.mx import MxSmtpRelay

    context = _get_ssl_context_client(args)

    relay = MxSmtpRelay(connect_timeout=20.0,
                        command_timeout=10.0,
                        data_timeout=20.0,
                        idle_timeout=10.0,
                        context=context)
    return relay
 def test_attempt_force_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     mx.new_static_relay('mail.example.com', 25).AndReturn(static)
     static.attempt(env, 0)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.force_mx('example.com', 'mail.example.com')
     mx.attempt(env, 0)
     mx.attempt(env, 1)
 def test_attempt_force_mx(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, "new_static_relay")
     mx.new_static_relay("mail.example.com", 25).AndReturn(static)
     static.attempt(env, 0)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.force_mx("example.com", "mail.example.com")
     mx.attempt(env, 0)
     mx.attempt(env, 1)
Example #19
0
 def test_attempt(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx_ret = FakeMxAnswer(False, [(5, 'mx1.example.com'),
                                   (10, 'mx2.example.com')])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(DNSResolver, 'query')
     DNSResolver.query('example.com', 'MX').AndReturn(FakeAsyncResult(mx_ret))
     mx.new_static_relay('mx1.example.com', 25).AndReturn(static)
     static.attempt(env, 0)
     mx.new_static_relay('mx2.example.com', 25).AndReturn(static)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
     mx.attempt(env, 1)
 def test_attempt(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     mx_ret = FakeMxAnswer(False, [(5, "mx1.example.com"), (10, "mx2.example.com")])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, "new_static_relay")
     self.mox.StubOutWithMock(dns_resolver, "query")
     dns_resolver.query("example.com", "MX").AndReturn(mx_ret)
     mx.new_static_relay("mx1.example.com", 25).AndReturn(static)
     static.attempt(env, 0)
     mx.new_static_relay("mx2.example.com", 25).AndReturn(static)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
     mx.attempt(env, 1)
 def test_attempt(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx_ret = FakeMxAnswer(False, [(5, 'mx1.example.com'),
                                   (10, 'mx2.example.com')])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns.resolver, 'query')
     dns.resolver.query('example.com', 'MX').AndReturn(mx_ret)
     mx.new_static_relay('mx1.example.com', 25).AndReturn(static)
     static.attempt(env, 0)
     mx.new_static_relay('mx2.example.com', 25).AndReturn(static)
     static.attempt(env, 1)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
     mx.attempt(env, 1)
 def test_attempt_no_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     a_ret = FakeAAnswer(False, [('1.2.3.4', )])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(dns_resolver, 'query')
     dns_resolver.query('example.com', 'MX').AndRaise(dns.resolver.NXDOMAIN)
     dns_resolver.query('example.com', 'A').AndReturn(a_ret)
     mx.new_static_relay('1.2.3.4', 25).AndReturn(static)
     static.attempt(env, 0)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
Example #23
0
 def test_attempt_no_mx(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     a_ret = FakeAAnswer(False, [('1.2.3.4', )])
     mx = MxSmtpRelay()
     static = self.mox.CreateMock(StaticSmtpRelay)
     self.mox.StubOutWithMock(mx, 'new_static_relay')
     self.mox.StubOutWithMock(DNSResolver, 'query')
     DNSResolver.query('example.com', 'MX').AndRaise(DNSError(ARES_ENOTFOUND))
     DNSResolver.query('example.com', 'A').AndReturn(FakeAsyncResult(a_ret))
     mx.new_static_relay('1.2.3.4', 25).AndReturn(static)
     static.attempt(env, 0)
     self.mox.ReplayAll()
     mx.attempt(env, 0)
Example #24
0
    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()
Example #25
0
 def _start_relay(self, name, options=None):
     if name in self.relays:
         return self.relays[name]
     if not options:
         options = getattr(self.cfg.relay, name)
     new_relay = None
     if options.type == 'mx':
         from slimta.relay.smtp.mx import MxSmtpRelay
         from .helpers import fill_hostname_template
         kwargs = {}
         kwargs['connect_timeout'] = options.get('connect_timeout', 30)
         kwargs['command_timeout'] = options.get('command_timeout', 30)
         kwargs['data_timeout'] = options.get('data_timeout', 60)
         kwargs['idle_timeout'] = options.get('idle_timeout', 10)
         kwargs['pool_size'] = options.get('concurrent_connections', 5)
         kwargs['ehlo_as'] = fill_hostname_template(options.ehlo_as)
         kwargs['context'] = self._get_client_ssl_context(options.tls)
         if options.ipv4_only:
             kwargs['socket_creator'] = build_ipv4_socket_creator([25])
         new_relay = MxSmtpRelay(**kwargs)
         if 'force_mx' in options:
             for domain, dest in options.force_mx:
                 new_relay.force_mx(domain, dest)
     elif options.type == 'static':
         from slimta.relay.smtp.static import StaticSmtpRelay
         from .helpers import fill_hostname_template, get_relay_credentials
         kwargs = {}
         kwargs['host'] = options.host
         kwargs['port'] = options.get('port', 25)
         kwargs['connect_timeout'] = options.get('connect_timeout', 30)
         kwargs['command_timeout'] = options.get('command_timeout', 30)
         kwargs['data_timeout'] = options.get('data_timeout', 60)
         kwargs['idle_timeout'] = options.get('idle_timeout', 10)
         kwargs['pool_size'] = options.get('concurrent_connections', 5)
         kwargs['ehlo_as'] = fill_hostname_template(options.ehlo_as)
         kwargs['context'] = self._get_client_ssl_context(options.tls)
         if 'credentials' in options:
             credentials = get_relay_credentials(options.credentials)
             kwargs['credentials'] = credentials
         if options.ipv4_only:
             kwargs['socket_creator'] = \
                 build_ipv4_socket_creator([kwargs['port']])
         new_relay = StaticSmtpRelay(**kwargs)
     elif options.type == 'lmtp':
         from slimta.relay.smtp.static import StaticLmtpRelay
         from .helpers import fill_hostname_template, get_relay_credentials
         kwargs = {}
         kwargs['host'] = options.get('host', 'localhost')
         kwargs['port'] = options.get('port', 24)
         kwargs['connect_timeout'] = options.get('connect_timeout', 30)
         kwargs['command_timeout'] = options.get('command_timeout', 30)
         kwargs['data_timeout'] = options.get('data_timeout', 60)
         kwargs['idle_timeout'] = options.get('idle_timeout', 10)
         kwargs['pool_size'] = options.get('concurrent_connections', 5)
         kwargs['ehlo_as'] = fill_hostname_template(options.ehlo_as)
         kwargs['context'] = self._get_client_ssl_context(options.tls)
         if 'credentials' in options:
             credentials = get_relay_credentials(options.credentials)
             kwargs['credentials'] = credentials
         if options.ipv4_only:
             kwargs['socket_creator'] = \
                 build_ipv4_socket_creator([kwargs['port']])
         new_relay = StaticLmtpRelay(**kwargs)
     elif options.type == 'http':
         from slimta.relay.http import HttpRelay
         from .helpers import fill_hostname_template
         kwargs = {}
         kwargs['ehlo_as'] = fill_hostname_template(options.ehlo_as)
         kwargs['timeout'] = options.get('timeout', 60)
         kwargs['idle_timeout'] = options.get('idle_timeout', 10)
         kwargs['context'] = self._get_client_ssl_context(options.tls)
         new_relay = HttpRelay(options.url, **kwargs)
     elif options.type == 'blackhole':
         from slimta.relay.blackhole import BlackholeRelay
         new_relay = BlackholeRelay()
     elif options.type == 'pipe':
         from slimta.relay.pipe import PipeRelay
         new_relay = PipeRelay(options.args)
     elif options.type == 'maildrop':
         from slimta.relay.pipe import MaildropRelay
         path = options.path
         new_relay = MaildropRelay(path)
     elif options.type == 'dovecot':
         from slimta.relay.pipe import DovecotLdaRelay
         path = options.path
         new_relay = DovecotLdaRelay(path)
     elif options.type == 'custom':
         new_relay = custom_factory(options)
     else:
         msg = 'relay type does not exist: '+options.type
         raise ConfigValidationError(msg)
     self.relays[name] = new_relay
     return new_relay
 def test_get_rcpt_domain(self):
     env = Envelope("*****@*****.**", ["*****@*****.**"])
     mx = MxSmtpRelay()
     assert_equal("example.com", mx._get_rcpt_domain(env))
 def test_get_rcpt_domain(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.assertEqual('example.com', mx._get_rcpt_domain(env))
 def test_get_rcpt_domain(self):
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     mx = MxSmtpRelay()
     self.assertEqual('example.com', mx._get_rcpt_domain(env))
 def test_get_rcpt_domain_error(self):
     env = Envelope('*****@*****.**', ['badrcpt'])
     mx = MxSmtpRelay()
     self.assertRaises(NoDomainError, mx._get_rcpt_domain, env)