예제 #1
0
 def _handle(self, socket, address):
     log.accept(self.server.socket, socket, address)
     try:
         self.handle(socket, address)
     except Exception:
         logging.log_exception(__name__)
         raise
예제 #2
0
 def load(self):
     for id in self.ops.get_ids():
         try:
             meta = self.ops.read_meta(id)
             yield (meta['timestamp'], id)
         except OSError:
             logging.log_exception(__name__, queue_id=id)
예제 #3
0
파일: dnsbl.py 프로젝트: sk1p/python-slimta
    def get(self, ip, timeout=None, strict=False):
        """Checks this DNSBL for the given IP address. This method does not
        check the answer, only that the response was not ``NXDOMAIN``.

        :param ip: The IP address string to check.
        :param timeout: A timeout in seconds before ``False`` is returned.
        :param strict: If ``True``, DNS exceptions that are not ``NXDOMAIN``
                       (including timeouts) will also  result in a ``True``
                       return value.
        :returns: ``True`` if the DNSBL had an entry for the given IP address,
                  ``False`` otherwise.

        """
        with gevent.Timeout(timeout, None):
            query = self._build_query(ip)
            try:
                answers = dns_resolver.query(query, 'A')
            except NXDOMAIN:
                return False
            except DNSException:
                logging.log_exception(__name__, query=query)
                return not strict
            else:
                return True
        return strict
예제 #4
0
    def get(self, ip, timeout=None, strict=False):
        """Checks this DNSBL for the given IP address. This method does not
        check the answer, only that the response was not ``NXDOMAIN``.

        :param ip: The IP address string to check.
        :param timeout: A timeout in seconds before ``False`` is returned.
        :param strict: If ``True``, DNS exceptions that are not ``NXDOMAIN``
                       (including timeouts) will also  result in a ``True``
                       return value.
        :returns: ``True`` if the DNSBL had an entry for the given IP address,
                  ``False`` otherwise.

        """
        with gevent.Timeout(timeout, None):
            query = self._build_query(ip)
            try:
                DNSResolver.query(query, 'A').get()
            except DNSError as exc:
                if exc.errno == ARES_ENOTFOUND:
                    return False
                logging.log_exception(__name__, query=query)
                return not strict
            else:
                return True
        return strict
예제 #5
0
 def _wait_channel(cls):
     poll = select.poll()
     fds_map = OrderedDict()
     try:
         while True:
             fds_map = cls._register_fds(poll, fds_map)
             if not fds_map:
                 break
             timeout = cls._channel.timeout()
             if not timeout:
                 cls._channel.process_fd(pycares.ARES_SOCKET_BAD,
                                         pycares.ARES_SOCKET_BAD)
                 continue
             for fd, event in poll.poll(timeout):
                 if event & (select.POLLIN | select.POLLPRI):
                     cls._channel.process_fd(fd, pycares.ARES_SOCKET_BAD)
                 if event & select.POLLOUT:
                     cls._channel.process_fd(pycares.ARES_SOCKET_BAD, fd)
     except Exception:
         logging.log_exception(__name__)
         cls._channel.cancel()
         cls._channel = None
         raise
     finally:
         cls._thread = None
예제 #6
0
 def load(self):
     for id in self.ops.get_ids():
         try:
             meta = self.ops.read_meta(id)
             yield (meta['timestamp'], id)
         except OSError:
             logging.log_exception(__name__, queue_id=id)
예제 #7
0
 def _handle(self, socket, address):
     log.accept(self.server.socket, socket, address)
     try:
         self.handle(socket, address)
     except Exception:
         logging.log_exception(__name__)
         raise
예제 #8
0
 def _run(self):
     try:
         hostname, _, _ = socket.gethostbyaddr(self.ip)
     except (socket.herror, socket.gaierror, gevent.GreenletExit):
         pass
     except Exception:
         logging.log_exception(__name__, query=self.ip)
     else:
         return hostname
예제 #9
0
 def _run(self):
     try:
         hostname, _, _ = socket.gethostbyaddr(self.ip)
     except (socket.herror, socket.gaierror, gevent.GreenletExit):
         pass
     except Exception:
         logging.log_exception(__name__, query=self.ip)
     else:
         return hostname
예제 #10
0
 def write(self, envelope, timestamp):
     storage_id = self.obj_store.write_message(envelope, timestamp)
     if self.msg_queue:
         try:
             self.msg_queue.queue_message(storage_id, timestamp)
         except Exception:
             logging.log_exception(__name__)
     log.write(storage_id, envelope)
     return storage_id
예제 #11
0
 def write(self, envelope, timestamp):
     storage_id = self.obj_store.write_message(envelope, timestamp)
     if self.msg_queue:
         try:
             self.msg_queue.queue_message(storage_id, timestamp)
         except Exception:
             logging.log_exception(__name__)
     log.write(storage_id, envelope)
     return storage_id
 def attempt_delivery(self, envelope, attempts):
     try:
         self.relay.attempt(envelope, attempts)
     except TransientRelayError as exc:
         self._handle_transient_failure(envelope, attempts, exc.reply)
     except PermanentRelayError as exc:
         self.enqueue_bounce(envelope, exc.reply)
     except Exception as exc:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: ' + str(exc))
         self._handle_transient_failure(envelope, attempts, reply)
         raise
 def attempt_delivery(self, envelope, attempts):
     try:
         self.relay.attempt(envelope, attempts)
     except TransientRelayError as exc:
         self._handle_transient_failure(envelope, attempts, exc.reply)
     except PermanentRelayError as exc:
         self.enqueue_bounce(envelope, exc.reply)
     except Exception as exc:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: '+str(exc))
         self._handle_transient_failure(envelope, attempts, reply)
         raise
예제 #14
0
 def _attempt(self, id, envelope, attempts):
     try:
         self.relay._attempt(envelope, attempts)
     except TransientRelayError as e:
         self._pool_spawn('store', self._retry_later, id, envelope, e.reply)
     except PermanentRelayError as e:
         self._perm_fail(id, envelope, e.reply)
     except Exception as e:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: '+str(e))
         self._pool_spawn('store', self._retry_later, id, envelope, reply)
         raise
     else:
         self._pool_spawn('store', self.store.remove, id)
예제 #15
0
 def _ptr_lookup(self):
     try:
         ptraddr = reversename.from_address(self.address[0])
         try:
             answers = resolver.query(ptraddr, 'PTR')
         except resolver.NXDOMAIN:
             answers = []
         try:
             self.reverse_address = str(answers[0])
         except IndexError:
             pass
     except Exception:
         logging.log_exception(__name__, query=self.address[0])
         raise
예제 #16
0
 def _ptr_lookup(self, environ):
     ip = environ.get('REMOTE_ADDR', '0.0.0.0')
     try:
         ptraddr = reversename.from_address(ip)
         try:
             answers = dns_resolver.query(ptraddr, 'PTR')
         except NXDOMAIN:
             answers = []
         try:
             environ['slimta.reverse_address'] = str(answers[0])
         except IndexError:
             pass
     except Exception:
         log_exception(__name__, query=ip)
예제 #17
0
 def _run(self):
     # StreamServer can return an ipv4 address with an ipv6 prefix "::ffff:"
     # which is not handled correctly by gethostbyaddr and throws an error
     ip = str(self.ip)
     if ip.find("::ffff:") == 0:
         ip = ip.replace("::ffff:", "")
     try:
         hostname, _, _ = socket.gethostbyaddr(ip)
     except (socket.herror, socket.gaierror, gevent.GreenletExit):
         pass
     except Exception:
         logging.log_exception(__name__, query=ip)
     else:
         return hostname
예제 #18
0
파일: wsgi.py 프로젝트: sk1p/python-slimta
 def _ptr_lookup(self, environ):
     ip = environ.get('REMOTE_ADDR', '0.0.0.0')
     try:
         ptraddr = reversename.from_address(ip)
         try:
             answers = dns_resolver.query(ptraddr, 'PTR')
         except NXDOMAIN:
             answers = []
         try:
             environ['slimta.reverse_address'] = str(answers[0])
         except IndexError:
             pass
     except Exception:
         log_exception(__name__, query=ip)
예제 #19
0
 def _attempt(self, id, envelope, attempts):
     try:
         self.relay._attempt(envelope, attempts)
     except TransientRelayError as e:
         self._pool_spawn('store', self._retry_later, id, envelope, e.reply)
     except PermanentRelayError as e:
         self._perm_fail(id, envelope, e.reply)
     except Exception as e:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: ' + str(e))
         self._pool_spawn('store', self._retry_later, id, envelope, reply)
         raise
     else:
         self._pool_spawn('store', self.store.remove, id)
예제 #20
0
 def _run(self):
     try:
         ptraddr = reversename.from_address(self.ip)
         try:
             answers = dns_resolver.query(ptraddr, 'PTR')
         except NXDOMAIN:
             answers = []
         try:
             return str(answers[0])
         except IndexError:
             pass
     except (DnsSyntaxError, gevent.GreenletExit):
         pass
     except Exception:
         logging.log_exception(__name__, query=self.ip)
예제 #21
0
 def _run(self):
     try:
         ptraddr = reversename.from_address(self.ip)
         try:
             answers = dns_resolver.query(ptraddr, 'PTR')
         except NXDOMAIN:
             answers = []
         try:
             return str(answers[0])
         except IndexError:
             pass
     except (DnsSyntaxError, gevent.GreenletExit):
         pass
     except Exception:
         logging.log_exception(__name__, query=self.ip)
예제 #22
0
 def _attempt(self, id, envelope, attempts):
     try:
         results = self.relay._attempt(envelope, attempts)
     except TransientRelayError as e:
         self._pool_spawn('store', self._retry_later, id, envelope, e.reply)
     except PermanentRelayError as e:
         self._perm_fail(id, envelope, e.reply)
     except Exception as e:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: '+str(e))
         self._pool_spawn('store', self._retry_later, id, envelope, reply)
         raise
     else:
         if isinstance(results, collections.Sequence):
             self._handle_partial_relay(id, envelope, attempts, results)
         else:
             self._remove(id)
예제 #23
0
 def _attempt(self, id, envelope, attempts):
     try:
         results = self.relay._attempt(envelope, attempts)
     except TransientRelayError as e:
         self._pool_spawn('store', self._retry_later, id, envelope, e.reply)
     except PermanentRelayError as e:
         self._perm_fail(id, envelope, e.reply)
     except Exception as e:
         log_exception(__name__)
         reply = Reply('450', '4.0.0 Unhandled delivery error: ' + str(e))
         self._pool_spawn('store', self._retry_later, id, envelope, reply)
         raise
     else:
         if isinstance(results, collections.Sequence):
             self._handle_partial_relay(id, envelope, attempts, results)
         else:
             self._remove(id)
예제 #24
0
 def test_log_exception(self, l):
     log_exception('test', extra='not logged')
     try:
         raise ValueError('testing stuff')
     except Exception:
         log_exception('test', extra='more stuff')
     self.assertEqual(1, len(l.records))
     rec = l.records[0]
     self.assertEqual('test', rec.name)
     self.assertEqual('ERROR', rec.levelname)
     type, id, op, data = parseline(rec.msg)
     self.assertEqual('exception', type)
     self.assertEqual('ValueError', id)
     self.assertEqual('unhandled', op)
     self.assertEqual('more stuff', data['extra'])
     self.assertEqual(('testing stuff', ), data['args'])
     self.assertEqual('testing stuff', data['message'])
     self.assertTrue(data['traceback'])
예제 #25
0
 def __call__(self, environ, start_response):
     self._trigger_ptr_lookup(environ)
     try:
         self._validate_request(environ)
         env = self._get_envelope(environ)
         self._add_envelope_extras(environ, env)
         self._enqueue_envelope(env)
     except WsgiResponse as res:
         start_response(res.status, res.headers)
         return res.data
     except Exception as exc:
         log_exception(__name__)
         msg = "{0!s}\n".format(exc)
         headers = [("Content-Length", len(msg)), ("Content-Type", "text/plain")]
         start_response("500 Internal Server Error", headers)
         return [msg]
     finally:
         environ["slimta.ptr_lookup_thread"].kill(block=False)
예제 #26
0
 def __call__(self, environ, start_response):
     self._trigger_ptr_lookup(environ)
     try:
         self._validate_request(environ)
         env = self._get_envelope(environ)
         self._add_envelope_extras(environ, env)
         self._enqueue_envelope(env)
     except WsgiResponse as res:
         start_response(res.status, res.headers)
         return res.data
     except Exception as exc:
         log_exception(__name__)
         msg = '{0!s}\n'.format(exc)
         headers = [('Content-Length', len(msg)),
                    ('Content-Type', 'text/plain')]
         start_response('500 Internal Server Error', headers)
         return [msg]
     finally:
         environ['slimta.ptr_lookup_thread'].kill(block=False)
예제 #27
0
파일: wsgi.py 프로젝트: sk1p/python-slimta
 def __call__(self, environ, start_response):
     self._trigger_ptr_lookup(environ)
     try:
         self._validate_request(environ)
         env = self._get_envelope(environ)
         self._add_envelope_extras(environ, env)
         self._enqueue_envelope(env)
     except WsgiResponse as res:
         start_response(res.status, res.headers)
         return res.data
     except Exception as exc:
         log_exception(__name__)
         msg = '{0!s}\n'.format(exc)
         content_length = str(len(msg))
         headers = [('Content-Length', content_length),
                    ('Content-Type', 'text/plain')]
         start_response('500 Internal Server Error', headers)
         return [msg]
     finally:
         environ['slimta.ptr_lookup_thread'].kill(block=False)
예제 #28
0
 def __call__(self, environ, start_response):
     ptr_lookup = PtrLookup(environ.get('REMOTE_ADDR', '0.0.0.0'))
     ptr_lookup.start()
     try:
         self._validate_request(environ)
         env = self._get_envelope(environ)
         self._add_envelope_extras(environ, env, ptr_lookup)
         self._enqueue_envelope(env)
     except WsgiResponse as res:
         start_response(res.status, res.headers)
         return res.data
     except Exception as exc:
         logging.log_exception(__name__)
         msg = '{0!s}\n'.format(exc)
         content_length = str(len(msg))
         headers = [('Content-Length', content_length),
                    ('Content-Type', 'text/plain')]
         start_response('500 Internal Server Error', headers)
         return [msg]
     finally:
         ptr_lookup.kill(block=False)
예제 #29
0
 def __call__(self, environ, start_response):
     ptr_lookup = PtrLookup(environ.get('REMOTE_ADDR', '0.0.0.0'))
     ptr_lookup.start()
     try:
         self._validate_request(environ)
         env = self._get_envelope(environ)
         self._add_envelope_extras(environ, env, ptr_lookup)
         self._enqueue_envelope(env)
     except WsgiResponse as res:
         start_response(res.status, res.headers)
         return res.data
     except Exception as exc:
         logging.log_exception(__name__)
         msg = '{0!s}\n'.format(exc)
         content_length = str(len(msg))
         headers = [('Content-Length', content_length),
                    ('Content-Type', 'text/plain')]
         start_response('500 Internal Server Error', headers)
         return [msg]
     finally:
         ptr_lookup.kill(block=False)
예제 #30
0
    def handoff(self, envelope):
        """This method may be called manually or by whatever mechanism a
        sub-class uses to receive new |Envelope| messages from a client.
        Because a |QueuePolicy| may generate new |Envelope| objects, this
        method returns a list of tuples, ``(envelope, result)`` where
        ``result`` is either an ID string or a
        :class:`~slimta.queue.QueueError`. The edge service can then use this
        information to report back success or failure to the client.

        :param envelope: |Envelope| containing the received message.
        :returns: List of tuples containing each |Envelope| and its
                  corresponding ID string or :class:`~slimta.queue.QueueError`.

        """
        envelope.receiver = self.hostname
        envelope.timestamp = time.time()

        try:
            return self.queue.enqueue(envelope)
        except Exception:
            logging.log_exception(__name__)
            raise
예제 #31
0
    def handoff(self, envelope):
        """This method may be called manually or by whatever mechanism a
        sub-class uses to receive new |Envelope| messages from a client.
        Because a |QueuePolicy| may generate new |Envelope| objects, this
        method returns a list of tuples, ``(envelope, result)`` where
        ``result`` is either an ID string or a
        :class:`~slimta.queue.QueueError`. The edge service can then use this
        information to report back success or failure to the client.

        :param envelope: |Envelope| containing the received message.
        :returns: List of tuples containing each |Envelope| and its
                  corresponding ID string or :class:`~slimta.queue.QueueError`.

        """
        envelope.receiver = self.hostname
        envelope.timestamp = time.time()

        try:
            return self.queue.enqueue(envelope)
        except Exception:
            logging.log_exception(__name__)
            raise
예제 #32
0
파일: dns.py 프로젝트: slimta/python-slimta
 def _wait_channel(cls):
     try:
         while True:
             read_fds, write_fds = cls._channel.getsock()
             if not read_fds and not write_fds:
                 break
             timeout = cls._channel.timeout()
             if not timeout:
                 cls._channel.process_fd(pycares.ARES_SOCKET_BAD,
                                         pycares.ARES_SOCKET_BAD)
                 continue
             rlist, wlist, xlist = select.select(
                 read_fds, write_fds, [], timeout)
             for fd in rlist:
                 cls._channel.process_fd(fd, pycares.ARES_SOCKET_BAD)
             for fd in wlist:
                 cls._channel.process_fd(pycares.ARES_SOCKET_BAD, fd)
     except Exception:
         logging.log_exception(__name__)
         cls._channel.cancel()
         cls._channel = None
         raise
     finally:
         cls._thread = None
예제 #33
0
 def attempt(self, envelope, attempts):
     domain = self._get_rcpt_domain(envelope)
     if domain in self._force_mx:
         dest, port = self._force_mx[domain]
     else:
         record = self._mx_records.setdefault(domain, MxRecord(domain))
         try:
             dest = self.choose_mx(record.get(), attempts)
         except ValueError as exc:
             msg = str(exc)
             reply = Reply('550', '5.1.2 '+msg)
             raise PermanentRelayError(msg, reply)
         except DNSError:
             log_exception(__name__)
             msg = 'DNS lookup failed'
             reply = Reply('451', '4.4.3 '+msg)
             raise TransientRelayError(msg, reply)
         port = 25
     try:
         relayer = self._relayers[(dest, port)]
     except KeyError:
         relayer = self.new_static_relay(dest, port)
         self._relayers[(dest, port)] = relayer
     return relayer.attempt(envelope, attempts)
예제 #34
0
 def attempt(self, envelope, attempts):
     domain = self._get_rcpt_domain(envelope)
     if domain in self._force_mx:
         dest, port = self._force_mx[domain]
     else:
         record = self._mx_records.setdefault(domain, MxRecord(domain))
         try:
             dest = self.choose_mx(record.get(), attempts)
         except ValueError as exc:
             msg = str(exc)
             reply = Reply('550', '5.1.2 ' + msg)
             raise PermanentRelayError(msg, reply)
         except DNSException:
             log_exception(__name__)
             msg = 'DNS lookup failed'
             reply = Reply('451', '4.4.3 ' + msg)
             raise TransientRelayError(msg, reply)
         port = 25
     try:
         relayer = self._relayers[(dest, port)]
     except KeyError:
         relayer = self.new_static_relay(dest, port)
         self._relayers[(dest, port)] = relayer
     return relayer.attempt(envelope, attempts)
예제 #35
0
 def _wait_channel(cls):
     try:
         while True:
             read_fds, write_fds = cls._channel.getsock()
             if not read_fds and not write_fds:
                 break
             timeout = cls._channel.timeout()
             if not timeout:
                 cls._channel.process_fd(pycares.ARES_SOCKET_BAD,
                                         pycares.ARES_SOCKET_BAD)
                 continue
             rlist, wlist, xlist = select.select(read_fds, write_fds, [],
                                                 timeout)
             for fd in rlist:
                 cls._channel.process_fd(fd, pycares.ARES_SOCKET_BAD)
             for fd in wlist:
                 cls._channel.process_fd(pycares.ARES_SOCKET_BAD, fd)
     except Exception:
         logging.log_exception(__name__)
         cls._channel.cancel()
         cls._channel = None
         raise
     finally:
         cls._thread = None