예제 #1
0
 def setUp(self):
     self.stream = StringIO()
     handler = Debugging(self.stream)
     controller = Controller(handler)
     controller.start()
     self.addCleanup(controller.stop)
     self.address = (controller.hostname, controller.port)
예제 #2
0
    def setUp(self):
        # There are two controllers and two SMTPd's running here.  The
        # "upstream" one listens on port 9025 and is connected to a "data
        # handler" which captures the messages it receives.  The second -and
        # the one under test here- listens on port 9024 and proxies to the one
        # on port 9025.  Because we need to set the decode_data flag
        # differently for each different test, the controller of the proxy is
        # created in the individual tests, not in the setup.
        self.upstream = DataHandler()
        upstream_controller = Controller(self.upstream, port=9025)
        upstream_controller.start()
        self.addCleanup(upstream_controller.stop)
        self.proxy = Proxy(upstream_controller.hostname, 9025)
        self.source = """\
From: Anne Person <*****@*****.**>
To: Bart Person <*****@*****.**>
Subject: A test

Testing
"""
        # The upstream SMTPd will always receive the content as bytes
        # delimited with CRLF.
        self.expected = CRLF.join([
            'From: Anne Person <*****@*****.**>',
            'To: Bart Person <*****@*****.**>',
            'Subject: A test',
            'X-Peer: ::1',
            '',
            'Testing']).encode('ascii')
예제 #3
0
 def test_mail_with_compatible_smtputf8(self):
     handler = ReceivingHandler()
     controller = Controller(handler)
     controller.start()
     self.addCleanup(controller.stop)
     recipient = 'bart\[email protected]'
     sender = 'anne\[email protected]'
     with SMTP(controller.hostname, controller.port) as client:
         client.ehlo('example.com')
         client.send(bytes(
             'MAIL FROM: <' + sender + '> SMTPUTF8\r\n',
             encoding='utf-8'))
         code, response = client.getreply()
         self.assertEqual(code, 250)
         self.assertEqual(response, b'OK')
         client.send(bytes(
             'RCPT TO: <' + recipient + '>\r\n',
             encoding='utf-8'))
         code, response = client.getreply()
         self.assertEqual(code, 250)
         self.assertEqual(response, b'OK')
         code, response = client.data('')
         self.assertEqual(code, 250)
         self.assertEqual(response, b'OK')
     self.assertEqual(handler.box[0].rcpt_tos[0], recipient)
     self.assertEqual(handler.box[0].mail_from, sender)
예제 #4
0
    def test_real_mail_aiosmtpd(self):
        """ Test sending messages with a real-world SMTPD server """
        if aiosmtpd is None:
            self.skipTest('aiosmtpd not available')

        # Start an smtp server
        mail_handler = StashingHandler()
        controller = Controller(mail_handler, loop=None,
                                hostname='localhost', port=self.smtpd_port)
        controller.start()

        # Give it time to settle
        sleep(0.5)

        # Initialize a Postman
        postman = Postman('*****@*****.**',
                          NoLoginSMTP('localhost', self.smtpd_port, None, None))

        # Send messages
        with postman.connect() as c:
            # Send plaintext message
            msg = Message(['*****@*****.**'], 'Subject', 'HTML message')
            c.sendmail(msg)

            # Send unicode message
            msg = Message(['*****@*****.**'], u'Håkon', u'Håkon')
            c.sendmail(msg)

        # Done
        controller.stop()

        # Test
        self.assertEqual(len(mail_handler.mail), 2)
예제 #5
0
 def test_socket_error(self):
     # Testing starting a server with a port already in use
     s1 = Controller(Sink(), port=8025)
     s2 = Controller(Sink(), port=8025)
     self.addCleanup(s1.stop)
     self.addCleanup(s2.stop)
     s1.start()
     self.assertRaises(socket.error, s2.start)
예제 #6
0
 def test_helo_hook(self):
     controller = Controller(HELOHandler())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         code, response = client.helo('me')
     self.assertEqual(code, 250)
     self.assertEqual(response, b'geddy.example.com')
예제 #7
0
 def test_smtp_utf8(self):
     controller = Controller(Sink())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         code, response = client.ehlo('example.com')
     self.assertEqual(code, 250)
     self.assertIn(b'SMTPUTF8', response.splitlines())
예제 #8
0
 def test_server_attribute(self):
     controller = Controller(Sink())
     self.assertIsNone(controller.server)
     try:
         controller.start()
         self.assertIsNotNone(controller.server)
     finally:
         controller.stop()
         self.assertIsNone(controller.server)
예제 #9
0
 def test_default_greeting(self):
     controller = Controller(Sink())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP() as client:
         code, msg = client.connect(controller.hostname, controller.port)
         self.assertEqual(code, 220)
         # The hostname prefix is unpredictable.
         self.assertEqual(msg[-len(GREETING):], bytes(GREETING, 'utf-8'))
예제 #10
0
 def setUp(self):
     self.tempdir = TemporaryDirectory()
     self.addCleanup(self.tempdir.cleanup)
     self.maildir_path = os.path.join(self.tempdir.name, 'maildir')
     self.handler = handler = Mailbox(self.maildir_path)
     controller = Controller(handler)
     controller.start()
     self.addCleanup(controller.stop)
     self.address = (controller.hostname, controller.port)
예제 #11
0
 def test_ehlo_hook(self):
     controller = Controller(EHLOHandler())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         code, response = client.ehlo('me')
     self.assertEqual(code, 250)
     lines = response.decode('utf-8').splitlines()
     self.assertEqual(lines[-1], 'alex.example.com')
예제 #12
0
 def test_mail_hook(self):
     controller = Controller(MAILHandler())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         client.helo('me')
         code, response = client.mail('*****@*****.**')
     self.assertEqual(code, 250)
     self.assertEqual(response, b'Yeah, sure')
예제 #13
0
 def test_mail_with_unrequited_smtputf8(self):
     controller = Controller(Sink())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         client.ehlo('example.com')
         code, response = client.docmd('MAIL FROM: <*****@*****.**>')
         self.assertEqual(code, 250)
         self.assertEqual(response, b'OK')
예제 #14
0
 def test_mail_with_incompatible_smtputf8(self):
     controller = Controller(Sink())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         client.ehlo('example.com')
         code, response = client.docmd(
             'MAIL FROM: <*****@*****.**> SMTPUTF8=YES')
         self.assertEqual(code, 501)
         self.assertEqual(response, b'Error: SMTPUTF8 takes no arguments')
예제 #15
0
 def test_mail_invalid_body(self):
     controller = Controller(Sink())
     controller.start()
     self.addCleanup(controller.stop)
     with SMTP(controller.hostname, controller.port) as client:
         client.ehlo('example.com')
         code, response = client.docmd(
             'MAIL FROM: <*****@*****.**> BODY 9BIT')
         self.assertEqual(code, 501)
         self.assertEqual(response,
                          b'Error: BODY can only be one of 7BIT, 8BITMIME')
예제 #16
0
 def test_deliver_bytes(self):
     with ExitStack() as resources:
         controller = Controller(self.proxy, port=9024)
         controller.start()
         resources.callback(controller.stop)
         client = resources.enter_context(
             SMTP(*(controller.hostname, controller.port)))
         client.sendmail(
             '*****@*****.**', ['*****@*****.**'], self.source)
         client.quit()
     self.assertEqual(self.upstream.content, self.expected)
     self.assertEqual(self.upstream.original_content, self.expected)
예제 #17
0
class CapturingAiosmtpdServer:
    """An async SMTP server / context manager for testing RPC effects."""

    def __init__(self):
        self.messages = []
        self.handler = CapturingAiosmtpdHandler(context=self)
        self.controller = Controller(
            handler=self.handler, hostname="localhost", port=10025)

    def __enter__(self):
        self.controller.start()
        return self

    def __exit__(self, *exc):
        self.controller.stop()
예제 #18
0
    def test_no_hooks(self):
        controller = Controller(NoHooksHandler())
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            client.helo('me')
            client.mail('*****@*****.**')
            client.rcpt(['*****@*****.**'])
            code, response = client.data("""\
From: [email protected]
To: [email protected]
Subject: Test

""")
            self.assertEqual(code, 250)
예제 #19
0
    def test_rcpt_hook(self):
        controller = Controller(RCPTHandler())
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            with self.assertRaises(SMTPRecipientsRefused) as cm:
                client.sendmail('*****@*****.**', ['*****@*****.**'], """\
From: [email protected]
To: [email protected]
Subject: Test

""")
            self.assertEqual(cm.exception.recipients, {
                '*****@*****.**': (550, b'Rejected'),
                })
예제 #20
0
    def test_data_hook(self):
        controller = Controller(DATAHandler())
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            with self.assertRaises(SMTPDataError) as cm:
                client.sendmail('*****@*****.**', ['*****@*****.**'], """\
From: [email protected]
To: [email protected]
Subject: Test

Yikes
""")
            self.assertEqual(cm.exception.smtp_code, 599)
            self.assertEqual(cm.exception.smtp_error, b'Not today')
예제 #21
0
    def test_process_message_error(self):
        controller = Controller(ErroringHandler())
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            code, response = client.ehlo('example.com')
            self.assertEqual(code, 250)
            with self.assertRaises(SMTPDataError) as cm:
                client.sendmail('*****@*****.**', ['*****@*****.**'], """\
From: [email protected]
To: [email protected]
Subject: A test

Testing
""")
            self.assertEqual(cm.exception.smtp_code, 499)
            self.assertEqual(cm.exception.smtp_error,
                             b'Could not accept the message')
예제 #22
0
    def test_message(self):
        # In this test, the message content comes in as a bytes.
        handler = DataHandler()
        controller = Controller(handler)
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            client.sendmail('*****@*****.**', ['*****@*****.**'], """\
From: Anne Person <*****@*****.**>
To: Bart Person <*****@*****.**>
Subject: A test
Message-ID: <ant>

Testing
""")
        # The content is not converted, so it's bytes.
        self.assertEqual(handler.content, handler.original_content)
        self.assertIsInstance(handler.content, bytes)
        self.assertIsInstance(handler.original_content, bytes)
예제 #23
0
    def test_message(self):
        # In this test, the message data comes in as bytes.
        controller = Controller(self.handler)
        controller.start()
        self.addCleanup(controller.stop)
        with SMTP(controller.hostname, controller.port) as client:
            client.sendmail('*****@*****.**', ['*****@*****.**'], """\
From: Anne Person <*****@*****.**>
To: Bart Person <*****@*****.**>
Subject: A test
Message-ID: <ant>

Testing
""")
        self.assertEqual(self.handled_message['subject'], 'A test')
        self.assertEqual(self.handled_message['message-id'], '<ant>')
        self.assertIsNotNone(self.handled_message['X-Peer'])
        self.assertEqual(
            self.handled_message['X-MailFrom'], '*****@*****.**')
        self.assertEqual(self.handled_message['X-RcptTo'], '*****@*****.**')
예제 #24
0
 def __init__(self):
     self.messages = []
     self.handler = CapturingAiosmtpdHandler(context=self)
     self.controller = Controller(
         handler=self.handler, hostname="localhost", port=10025)
예제 #25
0
 def setUp(self):
     controller = Controller(Sink)
     controller.start()
     self.addCleanup(controller.stop)
     self.address = (controller.hostname, controller.port)
예제 #26
0
 async def smtpd_main(self, hostname, port):
     cont = Controller(self, hostname=hostname, port=port)
     cont.start()
예제 #27
0
 def __init__(self, port=settings.SMTP_INBOUND_PORT) -> None:
     self.controller = Controller(self, hostname="0.0.0.0", port=port)
     super().__init__()
예제 #28
0
        database.update_state(database.open_db(), 23, job_id)
        
        print('waiting for payment')
        
        hashtx, _ = ensicoin.wait_for_pubkey(pk1)

        print('hashtx: ', hashtx)

        ensicoin.send_to(10,
                         hashtx,
                         0,
                         sk1,
                         42,
                         pk2,
                         [job_id,
                          "'" + json.dumps(split.generate_id_tuple(cut_segments)) + "'"], job_id)

        print('payment sent')

        database.update_state(database.open_db(), 24, job_id)

        return '250 Message accepted for delivery'


if __name__ == "__main__":
    controller = Controller(Handler(), hostname="0.0.0.0")
    controller.start()

    while True:
        time.sleep(1)
예제 #29
0
        data = json.dumps({
            "subject": message["subject"],
            "from": message["from"],
            "message": message_content,
            "attachments": attachments
        })
        self.mqtt.publish("printer/print", data)

        return '250 Message accepted for delivery'


if __name__ == "__main__":
    client = mqtt.Client()
    client.on_connect = on_connect

    client.connect(os.getenv("MQTT_SERVER", "172.30.2.3"), 1883, 60)

    controller = Controller(TelegraphHandler(client),
                            hostname='0.0.0.0',
                            port=25)
    controller.start()
    print("SMTP server started", flush=True)
    while True:
        try:
            client.loop()
        except (KeyboardInterrupt, SystemExit):
            print("Bye!", flush=True)
            break
    controller.stop()
예제 #30
0
async def amain(handler):
    cont = Controller(handler, hostname="localhost", port=10025)
    cont.start()
    return cont
예제 #31
0
                break
        else:
            _logger.debug('no match found')
            return '500 Could not process your message'
        headers = {'User-Agent': 'EmailPing from ' + mail_from}
        url = f'{self.ping_url}{match.group(1)}'
        _logger.info('Calling Ping url: %s for address: %s', url, mail_from)
        requests.get(url, headers=headers)
        return '250 OK'


async def health_check():
    ping_url = os.getenv('PING_URL', 'https://healthcheck.io/ping/')
    ping_id = os.getenv('PING_ID', '101fcaa8-32c5-4281-936f-330412b7afa4')
    ping_timeout = int(os.getenv('PING_TIMEOUT', '60'))
    _logger.info('Reporting own health to: %s', f'{ping_url}{ping_id}')
    while True:
        requests.get(f'{ping_url}{ping_id}')
        await asyncio.sleep(ping_timeout)


if __name__ == '__main__':
    handler = CustomHandler()
    controller = Controller(handler, hostname='0.0.0.0', port=10025)
    # Run the event loop in a separate thread.
    controller.start()
    # Wait for the user to press Return.
    loop = asyncio.get_event_loop()
    loop.create_task(health_check())
    loop.run_forever()
예제 #32
0
    async def start(self):
        from aiosmtpd.controller import Controller

        _LOGGER.info("Setting up mailserver " + self._server + ":" + str(self._port))
        controller = Controller(self, hostname=self._server, port=self._port)
        controller.start()
예제 #33
0
 def setUp(self):
     controller = Controller(Sink)
     controller.start()
     self.addCleanup(controller.stop)
     self.address = (controller.hostname, controller.port)
예제 #34
0
class MailQueueServer(object):
    def __init__(self, queue_host, queue_port, mail_host, mail_port):

        # message queue variables
        self._queue_host = queue_host
        self._queue_port = queue_port
        self.context = None
        self.publisher = None

        # mail server variables
        self._mail_host = mail_host
        self._mail_port = mail_port
        self.handler = None
        self.controller = None

        # store emails for debugging
        self._store_emails = False
        self.queue = None

    @property
    def store_emails(self):

        return self._store_emails

    @store_emails.setter
    def store_emails(self, value):

        if type(value) is not bool:
            raise Exception("bad value: should be bool")

        self._store_emails = value

    def start(self):

        # Prepare our message queue context and publisher
        self.context = zmq.asyncio.Context()
        self.publisher = self.context.socket(zmq.PUB)
        self.publisher.bind("tcp://{0}:{1}".format(self._queue_host,
                                                   self._queue_port))

        # setup the debug queue
        if self.store_emails is True and self.queue is None:
            self.queue = asyncio.Queue()

        # Prepare the mail server handler and controller
        self.handler = ZeroMQHandler(self.publisher, self.queue)
        self.controller = Controller(self.handler,
                                     hostname=self._mail_host,
                                     port=self._mail_port)

        self.controller.start()

    def stop(self):

        # stop/reset the mail server
        self.controller.stop()
        self.controller = None
        self.handler = None

        # tear down the debug queue
        self.queue = None

        # tear down the message queue
        self.publisher.close()
        self.publisher = None
        self.context.term()
        self.context = None

    def __enter__(self):

        logging.debug('Entering context')

        self.start()

        return self

    def __exit__(self, exc_type, exc_value, traceback):

        logging.debug('Exiting context')

        self.stop()
예제 #35
0
class MailerTest(AsyncTestCase):
    async def setUpAsync(self) -> None:
        await super().setUpAsync()
        self.smtp_handler = DummySMTPHandler()
        self.smtp = Controller(self.smtp_handler)
        self.smtp.start()

        config = TEST_CONFIG.copy()
        config.update({
            "email": {
                "host": self.smtp.hostname,
                "port": self.smtp.port,
                "address": "*****@*****.**",
            }
        })
        self.mailer_config = Config.from_dict(config)
        self.mailer = Mailer(config=self.mailer_config)

        self.mailer_task = asyncio.create_task(self.mailer.run())

        self.user_service = UserService(db_pool=self.db_pool,
                                        config=self.mailer_config)

    async def tearDownAsync(self) -> None:
        await super().tearDownAsync()
        self.mailer_task.cancel()
        self.smtp.stop()

    async def test_registration_mail_delivery(self):
        user_email = "*****@*****.**"
        await self.user_service.register_user("user1", user_email, "password")
        await asyncio.sleep(0.5)

        mail: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait()
        self.assertIsNotNone(mail)
        self.assertIn(user_email, mail.rcpt_tos)
        self.assertIn("[Test Abrechnung] Confirm user account",
                      mail.content.decode("utf-8"))

    async def test_email_change_mail_delivery(self):
        user_email = "*****@*****.**"
        new_email = "*****@*****.**"
        user_id, password = await self._create_test_user(username="******",
                                                         email=user_email)
        await self.user_service.request_email_change(user_id=user_id,
                                                     password=password,
                                                     email=new_email)

        await asyncio.sleep(0.5)
        mail1: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait()
        self.assertIsNotNone(mail1)
        mail2: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait()
        self.assertIsNotNone(mail2)
        self.assertTrue(user_email in mail1.rcpt_tos or mail2.rcpt_tos)
        self.assertTrue(new_email in mail1.rcpt_tos or mail2.rcpt_tos)
        self.assertIn("[Test Abrechnung] Change email",
                      mail1.content.decode("utf-8"))
        self.assertIn("[Test Abrechnung] Change email",
                      mail2.content.decode("utf-8"))

    async def test_password_reset_mail_delivery(self):
        user_email = "*****@*****.**"
        await self._create_test_user(username="******", email=user_email)
        await self.user_service.request_password_recovery(email=user_email)

        await asyncio.sleep(0.5)
        mail: smtp.Envelope = self.smtp_handler.mail_queue.get_nowait()
        self.assertIsNotNone(mail)
        self.assertIn(user_email, mail.rcpt_tos)
        self.assertIn("[Test Abrechnung] Reset password",
                      mail.content.decode("utf-8"))
예제 #36
0
async def amain(loop):
    cont = Controller(Sink(), hostname='', port=8025)
    cont.start()
예제 #37
0
from smtpx import CrazySrvHandler
from web import web_start

from aiosmtpd.controller import Controller
from aiosmtpd.smtp import SMTP
import configparser

if __name__ == "__main__":
    cf = configparser.ConfigParser()
    cf.read("cfg.ini")

    smtpd_host = cf.get("smtpd", "host")
    smtpd_port = cf.getint("smtpd", "port")

    rest_host = smtpd_host
    rest_port = cf.getint("rest", "port")

    handler = CrazySrvHandler()
    controller = Controller(handler, hostname=smtpd_host, port=smtpd_port)
    controller.factory = lambda: SMTP(handler, enable_SMTPUTF8=True)

    try:
        controller.start()
        web_start(rest_host, rest_port)
    except KeyboardInterrupt:
        print("Shutting down")
    finally:
        controller.stop()
예제 #38
0
 def test_socket_error_default(self):
     contr1 = Controller(Sink())
     contr2 = Controller(Sink())
     expectedre = r"error while attempting to bind on address"
     try:
         with pytest.raises(socket.error, match=expectedre):
             contr1.start()
             contr2.start()
     finally:
         contr2.stop()
         contr1.stop()
예제 #39
0
 async def smtpd_main(self, hostname, port):
     cont = Controller(self, hostname=hostname, port=port)
     cont.start()
예제 #40
0
def threaded_smtpd_server(request, hostname, port, smtpd_handler):
    controller = Controller(smtpd_handler, hostname=hostname, port=port)
    controller.start()
    request.addfinalizer(controller.stop)

    return controller.server
예제 #41
0
 async def startService(loop):
     controller = Controller(smtpHandler(), hostname='127.0.0.1', port=25)
     controller.start()
예제 #42
0
 def test_stop_noassert(self):
     controller = Controller(Sink())
     controller.stop(no_assert=True)
예제 #43
0
 def test_stop_assert(self):
     controller = Controller(Sink())
     with pytest.raises(AssertionError, match="SMTP daemon not running"):
         controller.stop(no_assert=False)
    config = configparser.ConfigParser()
    config.read(config_path)

    use_auth = config.getboolean('remote', 'smtp_auth', fallback=False)
    if use_auth:
        auth = {
            'user': config.get('remote', 'smtp_auth_user'),
            'password': config.get('remote', 'smtp_auth_password')
        }
    else:
        auth = None

    controller = Controller(
        MailProxyHandler(
            host=config.get('remote', 'host', fallback='0.0.0.0'),
            port=config.getint('remote', 'port', fallback=25),
            auth=auth,
            #use_ssl=config.getboolean('remote', 'use_ssl',fallback=False),
            starttls=config.getboolean('remote', 'starttls', fallback=False),
            local_hostname=config.get('remote',
                                      'local_hostname',
                                      fallback='mail.foo.com'),
            debug_level=config.getint('remote', 'debug_level', fallback=0)),
        hostname=config.get('local',
                            'host',
                            fallback='email-smtp.us-west-2.amazonaws.com'),
        port=config.getint('local', 'port', fallback=587))
    controller.start()
    while controller.loop.is_running():
        sleep(0.2)
예제 #45
0
import asyncio
from aiosmtpd.controller import Controller


class CustomHandler:
    async def handle_DATA(self, server, session, envelope):
        peer = session.peer
        mail_from = envelope.mail_from
        rcpt_tos = envelope.rcpt_tos
        data = envelope.content         # type: bytes
        print('peer:', peer)
        print('mail_from:', mail_from)
        print('rcpt_tos:', rcpt_tos)
        print('data:', data)
        # Process message data...
        # if error_occurred:
        #     return '500 Could not process your message'
        return '250 OK'


if __name__ == '__main__':
    handler = CustomHandler()
    controller = Controller(handler, hostname='127.0.0.1', port=10025)
    print('SMTP server:', controller.hostname, controller.port)
    # Run the event loop in a separate thread.
    controller.start()
    # Wait for the user to press Return.
    input('SMTP server running. Press Return to stop server and exit.')
    controller.stop()
예제 #46
0
class SmtpServer:
    def __init__(self, port=settings.SMTP_INBOUND_PORT) -> None:
        self.controller = Controller(self, hostname="0.0.0.0", port=port)
        super().__init__()

    def parse_message_id(self, raw_message_id):
        parts = raw_message_id.split("@")
        if len(parts) > 1:
            try:
                return UUID(parts[0].replace("<", ""))
            except:
                return None

        return None

    def get_ticket(self, message):
        if "Message-ID" not in message:
            return None, None

        message_id = self.parse_message_id(message["Message-ID"])
        if not message_id:
            return None, None

        return Ticket.objects.filter(
            Q(reply_message_id=message_id)
            | Q(comment_message_id=message_id)).first(), message_id

    @sync_to_async
    def handle_RCPT(self, server, session, envelope, address, rcpt_options):
        if not Inbox.objects.filter(email=address).exists():
            return '550 not relaying to that domain'

        envelope.rcpt_tos.append(address)

        return '250 OK'

    @sync_to_async
    def handle_DATA(self, server, session, envelope):
        mail_from = envelope.mail_from

        message = BytesParser(policy=policy.default).parsebytes(
            envelope.content)
        body = message.get_body(preferencelist=('plain', ))
        if body:
            content = body.get_content()
            reply = EmailReplyParser.parse_reply(content)
            author, _ = User.objects.get_or_create(email=mail_from)
            ticket, message_id = self.get_ticket(message)

            if ticket:
                if not ticket.inbox.enable_reply_by_email:
                    return '450 Reply by email is disabled for the inbox'

                Comment.objects.create(
                    ticket=ticket,
                    author=author,
                    is_reply=ticket.reply_message_id == message_id,
                    content=reply)
                UserInbox.objects.get_or_create(user=author,
                                                inbox=ticket.inbox)

            else:
                inbox = Inbox.objects.get(email__in=envelope.rcpt_tos, )
                if not inbox.enable_create_new_ticket_by_email:
                    return '450 Creation of ticket by email is disabled for the inbox'

                Ticket.objects.create(author=author,
                                      inbox=inbox,
                                      title=message["Subject"],
                                      content=reply)
                UserInbox.objects.get_or_create(user=author, inbox=inbox)

        return '250 OK'

    def start(self):
        try:
            self.controller.stop()
        except:
            pass

        try:
            self.controller.start()
            print("SMTP server started on port {}".format(
                settings.SMTP_INBOUND_PORT))
        except:
            pass

    def stop(self):
        self.controller.stop()
예제 #47
0
async def main():
    controller = Controller(MessageHandler(), port=25)
    controller.start()
예제 #48
0
파일: smtp_server.py 프로젝트: ICRAR/ngas
 def __init__(self, port):
     handler = InMemorySMTPServer.ReceivingHandler(self)
     InMemorySMTPServerBase.__init__(self, port)
     Controller.__init__(self, handler, hostname='127.0.0.1', port=port, enable_SMTPUTF8=False)
     self.start()
예제 #49
0
        else:
            smtp = SMTP(POSTFIX_SERVER, 25)

        msg = Parser(policy=SMTPUTF8).parsestr(message_data)

        for rcpt_to in envelope.rcpt_tos:
            # Reply case
            # recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix
            if rcpt_to.startswith("reply+") or rcpt_to.startswith("ra+"):
                LOG.debug("Reply phase")
                app = new_app()

                with app.app_context():
                    return handle_reply(envelope, smtp, msg, rcpt_to)
            else:  # Forward case
                LOG.debug("Forward phase")
                app = new_app()

                with app.app_context():
                    return handle_forward(envelope, smtp, msg, rcpt_to)


if __name__ == "__main__":
    controller = Controller(MailHandler(), hostname="0.0.0.0", port=20381)

    controller.start()
    LOG.d("Start mail controller %s %s", controller.hostname, controller.port)

    while True:
        time.sleep(2)
예제 #50
0
 def __init__(self):
     self.messages = []
     self.handler = CapturingAiosmtpdHandler(context=self)
     self.controller = Controller(handler=self.handler,
                                  hostname="localhost",
                                  port=10025)
예제 #51
0
 def test_hostname_none(self):
     cont = Controller(Sink())
     try:
         cont.start()
     finally:
         cont.stop()
예제 #52
0
async def amain(loop):
    handler = FixerHandler()
    controller = Controller(handler, hostname="0.0.0.0", port=8025)
    controller.start()
예제 #53
0
application = tornado.web.Application(
    [
        # Health Checks
        (r'/healthcheck', HealthCheckHandler),
    ],
    debug=(os.environ.get('DEBUG_MODE') == 'devel'),
    **APP_SETTINGS)

#===============================================================================
#===============================================================================

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--port', help='Server Port')
    parser.add_argument('--smtpport', help='SMTP Port')
    args = parser.parse_args()

    # Begin SMTP server
    smtp_server = Controller(SMTPHandler(),
                             hostname='0.0.0.0',
                             port=int(args.smtpport))
    smtp_server.start()

    # Begin Web server
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(int(args.port))

    IOLoop.instance().start()

#===============================================================================
#===============================================================================
예제 #54
0
    def init_db(self):
        print(f"use db {self.db}")
        conn = sqlite3.connect(self.db)
        cur = conn.cursor()
        sql = f"""
            create table  if not exists  {self.table_name}(
            id INTEGER  PRIMARY KEY autoincrement,
            email_from   VARCHAR(255),
            email_to  VARCHAR(255),
            email_title VARCHAR(512),
            dt TEXT,
            email_raw TEXT,
            has_attach INTEGER not null
            )
        """
        cur.execute(sql)
        conn.commit()
        cur.close()
        conn.close()


if __name__=='__main__':

    try:
        controller = Controller(DataHandler("~/mailbox", 'fake_mail.db', "fake_mail"), hostname='0.0.0.0', port=25)
        controller.start()

        start_web("0.0.0.0", "9080")
    except KeyboardInterrupt:
        print("smtpd quit!")
예제 #55
0
                        'body': message.body,
                        'data': content,
                        'timestamp': datetime.utcnow().isoformat()
                    }, open_file)
            return '250 OK'
        except Exception:
            return '500 Could not process your message'


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('host', type=str)
    parser.add_argument('port', type=int)
    args = parser.parse_args()
    handler = Handler()
    controller = Controller(handler, hostname=args.host, port=args.port)
    # noinspection PyBroadException
    try:
        controller.start()
        pid = str(os.getpid())
        pidfile = "/run/postoffice/postoffice.pid"
        open(pidfile, 'w').write(pid)
        print("Running smtpd server on {}:{}\n".format(args.host, args.port))
        while True:
            time.sleep(3)
    except Exception as exc:
        print(exc, file=sys.stderr)
        controller.stop()
    finally:
        os.unlink(pidfile)
예제 #56
0
async def amain(loop):
    cont = Controller(Sink(), hostname='::0', port=8025)
    cont.start()
예제 #57
0
        config_path = os.path.join(sys.path[0], 'config.ini')
    if not os.path.exists(config_path):
        raise Exception("Config file not found: {}".format(config_path))

    config = configparser.ConfigParser()
    config.read(config_path)

    use_auth = config.getboolean('remote', 'smtp_auth', fallback=False)
    if use_auth:
        auth = {
            'user': config.get('remote', 'smtp_auth_user'),
            'password': config.get('remote', 'smtp_auth_password')
        }
    else:
        auth = None

    controller = Controller(MailProxyHandler(
        host=config.get('remote', 'host'),
        port=config.getint('remote', 'port', fallback=25),
        auth=auth,
        use_ssl=config.getboolean('remote', 'use_ssl', fallback=False),
        starttls=config.getboolean('remote', 'starttls', fallback=False),
    ),
                            hostname=config.get('local',
                                                'host',
                                                fallback='127.0.0.1'),
                            port=config.getint('local', 'port', fallback=25))
    controller.start()
    while controller.loop.is_running():
        sleep(0.2)