def test_result_cb_error(self): result = AsyncResult() DNSResolver._result_cb(result, 13, pycares.errno.ARES_ENOTFOUND) with self.assertRaises(DNSError) as cm: result.get() self.assertEqual('Domain name not found [ARES_ENOTFOUND]', str(cm.exception))
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
def test_check_dnsrbl(self): class TestSession(object): address = ('1.2.3.4', 56789) class TestValidators(object): def __init__(self): self.session = TestSession() @check_dnsbl('test.example.com') def validate_mail(self, reply, sender): assert False DNSResolver.query('4.3.2.1.test.example.com', 'A').AndRaise(DNSError(ARES_ENOTFOUND)) DNSResolver.query('4.3.2.1.test.example.com', 'A').AndReturn(FakeAsyncResult()) self.mox.ReplayAll() validators = TestValidators() reply = Reply('250', '2.0.0 Ok') self.assertRaises(AssertionError, validators.validate_mail, reply, 'asdf') self.assertEqual('250', reply.code) self.assertEqual('2.0.0 Ok', reply.message) validators.validate_mail(reply, 'asdf') self.assertEqual('550', reply.code) self.assertEqual('5.7.1 Access denied', reply.message)
def test_wait_channel(self): DNSResolver._channel = channel = self.mox.CreateMockAnything() poll = self.mox.CreateMockAnything() self.mox.StubOutWithMock(select, 'poll') select.poll().AndReturn(poll) channel.getsock().AndReturn(([1, 2], [2, 3])) channel.timeout().AndReturn(1.0) poll.register(1, select.POLLIN) poll.register(2, select.POLLIN | select.POLLOUT) poll.register(3, select.POLLOUT) poll.poll(1.0).AndReturn([(1, select.POLLIN), (3, select.POLLOUT)]) channel.process_fd(1, pycares.ARES_SOCKET_BAD) channel.process_fd(pycares.ARES_SOCKET_BAD, 3) channel.getsock().AndReturn(([1, 3], [4])) channel.timeout().AndReturn(1.0) poll.register(3, select.POLLIN) poll.register(4, select.POLLOUT) poll.unregister(2) poll.poll(1.0).AndReturn([]) channel.getsock().AndReturn(([1, 3], [4])) channel.timeout().AndReturn(None) channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD) channel.getsock().AndReturn(([], [])) poll.unregister(1) poll.unregister(3) poll.unregister(4) self.mox.ReplayAll() DNSResolver._wait_channel()
def test_dnsblocklist_get(self): DNSResolver.query('4.3.2.1.test.example.com', 'A').AndReturn(FakeAsyncResult()) DNSResolver.query('8.7.6.5.test.example.com', 'A').AndRaise(DNSError(ARES_ENOTFOUND)) self.mox.ReplayAll() self.assertTrue(self.dnsbl.get('1.2.3.4')) self.assertNotIn('5.6.7.8', self.dnsbl)
def test_query(self): channel = self.mox.CreateMock(pycares.Channel) self.mox.StubOutWithMock(pycares, 'Channel') self.mox.StubOutWithMock(gevent, 'spawn') pycares.Channel().AndReturn(channel) channel.query('example.com', 13, IgnoreArg()) gevent.spawn(IgnoreArg()) self.mox.ReplayAll() DNSResolver.query('example.com', 13)
def test_dnsblocklistgroup_get_reasons(self): group = DnsBlocklistGroup() group.add_dnsbl('test1.example.com') group.add_dnsbl('test2.example.com') group.add_dnsbl('test3.example.com') DNSResolver.query('4.3.2.1.test1.example.com', 'TXT').InAnyOrder().AndReturn(FakeAsyncResult(['reason one'])) DNSResolver.query('4.3.2.1.test3.example.com', 'TXT').InAnyOrder().AndReturn(FakeAsyncResult()) self.mox.ReplayAll() self.assertEqual({'test1.example.com': 'reason one', 'test3.example.com': None}, group.get_reasons(set(['test1.example.com', 'test3.example.com']), '1.2.3.4'))
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_wait_channel_error(self): DNSResolver._channel = channel = self.mox.CreateMockAnything() self.mox.StubOutWithMock(select, 'select') channel.getsock().AndReturn(('read', 'write')) channel.timeout().AndReturn(1.0) select.select('read', 'write', [], 1.0).AndRaise(ValueError(13)) channel.cancel() self.mox.ReplayAll() with self.assertRaises(ValueError): DNSResolver._wait_channel() self.assertIsNone(DNSResolver._channel)
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)
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_wait_channel_error(self): DNSResolver._channel = channel = self.mox.CreateMockAnything() poll = self.mox.CreateMockAnything() self.mox.StubOutWithMock(select, 'poll') select.poll().AndReturn(poll) channel.getsock().AndReturn(([1], [])) channel.timeout().AndReturn(1.0) poll.register(1, select.POLLIN).AndReturn(None) poll.poll(1.0).AndRaise(ValueError(13)) channel.cancel() self.mox.ReplayAll() with self.assertRaises(ValueError): DNSResolver._wait_channel() self.assertIsNone(DNSResolver._channel)
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_wait_channel(self): DNSResolver._channel = channel = self.mox.CreateMockAnything() self.mox.StubOutWithMock(select, 'select') channel.getsock().AndReturn(('read', 'write')) channel.timeout().AndReturn(1.0) select.select('read', 'write', [], 1.0).AndReturn( ([1, 2, 3], [4, 5, 6], None)) for fd in [1, 2, 3]: channel.process_fd(fd, pycares.ARES_SOCKET_BAD) for fd in [4, 5, 6]: channel.process_fd(pycares.ARES_SOCKET_BAD, fd) channel.getsock().AndReturn(('read', 'write')) channel.timeout().AndReturn(None) channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD) channel.getsock().AndReturn((None, None)) self.mox.ReplayAll() DNSResolver._wait_channel()
def _resolve_a(self): answer = DNSResolver.query(self.domain, 'A').get() expiration = 0 now = time.time() ret = [] for rdata in answer: ret.append((0, self.domain)) expiration = max(expiration, now + rdata.ttl) return ret, expiration
def test_dnsblocklistgroup_get_reasons(self): group = DnsBlocklistGroup() group.add_dnsbl('test1.example.com') group.add_dnsbl('test2.example.com') group.add_dnsbl('test3.example.com') DNSResolver.query('4.3.2.1.test1.example.com', 'TXT').InAnyOrder().AndReturn( FakeAsyncResult(['reason one'])) DNSResolver.query('4.3.2.1.test3.example.com', 'TXT').InAnyOrder().AndReturn(FakeAsyncResult()) self.mox.ReplayAll() self.assertEqual( { 'test1.example.com': 'reason one', 'test3.example.com': None }, group.get_reasons(set(['test1.example.com', 'test3.example.com']), '1.2.3.4'))
def _resolve_a(self): answer = DNSResolver.query(self.domain, 'A').get() expiration = 0 now = time.time() ret = [] for rdata in answer: ret.append((0, str(rdata.host))) expiration = max(expiration, now + rdata.ttl) return ret, expiration
def test_dnsblocklist_get_reason(self): DNSResolver.query('4.3.2.1.test.example.com', 'TXT').AndReturn(FakeAsyncResult()) DNSResolver.query('4.3.2.1.test.example.com', 'TXT').AndReturn(FakeAsyncResult(['good reason'])) DNSResolver.query('8.7.6.5.test.example.com', 'TXT').AndRaise(DNSError(ARES_ENOTFOUND)) self.mox.ReplayAll() self.assertEqual(None, self.dnsbl.get_reason('1.2.3.4')) self.assertEqual('good reason', self.dnsbl.get_reason('1.2.3.4')) self.assertEqual(None, self.dnsbl['5.6.7.8'])
def _resolve_mx(self): answer = DNSResolver.query(self.domain, 'MX').get() expiration = 0 now = time.time() ret = [] for rdata in answer: for i, rec in enumerate(ret): if rec[0] > rdata.priority: ret.insert(i, (rdata.priority, str(rdata.host))) break else: ret.append((rdata.priority, str(rdata.host))) expiration = max(expiration, now + rdata.ttl) return ret, expiration
def get_reason(self, ip, timeout=None): """Gets the TXT record for the IP address on this DNSBL. This is usually a reason for why the IP address matched. As such, this function should only be called after :meth:`.get()` returns ``True``. :param ip: The IP address to get a match reason for. :param timeout: A timeout in seconds before giving up. :returns: A string with the reason, or ``None``. """ with gevent.Timeout(timeout, None): query = self._build_query(ip) try: answers = DNSResolver.query(query, 'TXT').get() except DNSError: pass else: if answers: for rdata in answers: return rdata.text
def test_result_cb(self): result = AsyncResult() DNSResolver._result_cb(result, 13, None) self.assertEqual(13, result.get())
def test_get_query_type(self): self.assertEqual(pycares.QUERY_TYPE_MX, DNSResolver._get_query_type('MX')) self.assertEqual(13, DNSResolver._get_query_type(13))
def test_dnsblocklistgroup_get(self): group = DnsBlocklistGroup() group.add_dnsbl('test1.example.com') group.add_dnsbl('test2.example.com') group.add_dnsbl('test3.example.com') DNSResolver.query('4.3.2.1.test1.example.com', 'A').InAnyOrder('one').AndReturn(FakeAsyncResult()) DNSResolver.query('4.3.2.1.test2.example.com', 'A').InAnyOrder('one').AndRaise( DNSError(ARES_ENOTFOUND)) DNSResolver.query('4.3.2.1.test3.example.com', 'A').InAnyOrder('one').AndReturn(FakeAsyncResult()) DNSResolver.query('8.7.6.5.test1.example.com', 'A').InAnyOrder('two').AndRaise( DNSError(ARES_ENOTFOUND)) DNSResolver.query('8.7.6.5.test2.example.com', 'A').InAnyOrder('two').AndRaise( DNSError(ARES_ENOTFOUND)) DNSResolver.query('8.7.6.5.test3.example.com', 'A').InAnyOrder('two').AndRaise( DNSError(ARES_ENOTFOUND)) self.mox.ReplayAll() self.assertEqual(set(['test1.example.com', 'test3.example.com']), group.get('1.2.3.4')) self.assertNotIn('5.6.7.8', group)
def test_dnsblocklistgroup_get(self): group = DnsBlocklistGroup() group.add_dnsbl('test1.example.com') group.add_dnsbl('test2.example.com') group.add_dnsbl('test3.example.com') DNSResolver.query('4.3.2.1.test1.example.com', 'A').InAnyOrder('one').AndReturn(FakeAsyncResult()) DNSResolver.query('4.3.2.1.test2.example.com', 'A').InAnyOrder('one').AndRaise(DNSError(ARES_ENOTFOUND)) DNSResolver.query('4.3.2.1.test3.example.com', 'A').InAnyOrder('one').AndReturn(FakeAsyncResult()) DNSResolver.query('8.7.6.5.test1.example.com', 'A').InAnyOrder('two').AndRaise(DNSError(ARES_ENOTFOUND)) DNSResolver.query('8.7.6.5.test2.example.com', 'A').InAnyOrder('two').AndRaise(DNSError(ARES_ENOTFOUND)) DNSResolver.query('8.7.6.5.test3.example.com', 'A').InAnyOrder('two').AndRaise(DNSError(ARES_ENOTFOUND)) self.mox.ReplayAll() self.assertEqual(set(['test1.example.com', 'test3.example.com']), group.get('1.2.3.4')) self.assertNotIn('5.6.7.8', group)