Exemple #1
0
 def lookup_dns(self, domain):
     if not self.discoverNS:
         DNS.DiscoverNameServers()
         self.discoverNS = True
     name = '_dmarc.' + domain
     try:
         req = DNS.DnsRequest(name=name,
                              qtype=DNS.Type.TXT,
                              timeout=self.dnstimeout)
         res = req.req()
         if res.header['tc'] == True:
             try:
                 req = DNS.DnsRequest(name,
                                      qtype='TXT',
                                      protocol='tcp',
                                      timeout=self.dnstimeout)
                 res = req.req()
             except DNS.DNSError as x:
                 print('DNS: TCP fallback error:', str(x))
             if res.header['rcode'] != 0 and res.header['rcode'] != 3:
                 print('DNS Error:', res.header['status'],
                       ' RCODE ({})'.format(res.header['rcode']))
         return [((a['name'], a['typename']), a['data'])
                 for a in res.answers] \
                     + [((a['name'], a['typename']), a['data'])
                        for a in res.additional]
     except AttributeError as x:
         print('DNS attribute:' + str(x))
     except IOError as x:
         print('DNS IOE:' + str(x))
     except DNS.DNSError as x:
         'DNS ' + str(x)
Exemple #2
0
def DNSLookup(name, qtype, strict=True, timeout=30):
    try:
        req = DNS.DnsRequest(name, qtype=qtype, timeout=timeout)
        resp = req.req()
        # resp.show()
        # key k: ('wayforward.net', 'A'), value v
        # FIXME: pydns returns AAAA RR as 16 byte binary string, but
        # A RR as dotted quad.  For consistency, this driver should
        # return both as binary string.
        #
        if resp.header['tc'] == True:
            if strict > 1:
                raise spf.AmbiguityWarning(
                    'DNS: Truncated UDP Reply, SPF records should fit in a UDP packet, retrying TCP'
                )
            try:
                req = DNS.DnsRequest(name,
                                     qtype=qtype,
                                     protocol='tcp',
                                     timeout=timeout)
                resp = req.req()
            except DNS.DNSError as x:
                raise spf.TempError('DNS: TCP Fallback error: ' + str(x))
        return [((a['name'], a['typename']), a['data']) for a in resp.answers]
    except IOError as x:
        raise spf.TempError('DNS ' + str(x))
    except DNS.DNSError as x:
        raise spf.TempError('DNS ' + str(x))
Exemple #3
0
 def testIDND(self):
     """Can we lookup an internationalized domain name?"""
     dnsob = DNS.DnsRequest('xn--bb-eka.at')
     unidnsob = DNS.DnsRequest('öbb.at')
     a_resp = dnsob.req(qtype='A', resulttype='text')
     ua_resp = unidnsob.req(qtype='A', resulttype='text')
     self.assertTrue(a_resp.answers)
     self.assertTrue(ua_resp.answers)
     self.assertEqual(ua_resp.answers[0]['data'], a_resp.answers[0]['data'])
Exemple #4
0
    def __init__(self, dnsServer=None, cachefile=""):
        # These attributes intended for user setting
        self.printStatsAtEnd = False

        # As far as I can tell from the standards,
        # it's legal to have more than one PTR record
        # for an address. That is, it's legal to get
        # more than one name back when you do a
        # reverse lookup on an IP address. I don't
        # know of a use for that and I've never seen
        # it done. And I don't think that most
        # people would expect it. So forward ("A")
        # lookups always return a list. Reverse
        # ("PTR") lookups return a single name unless
        # this attribute is set to False.
        self.returnSinglePTR = True

        # How long to cache an error as no data
        self.cacheErrorSecs = 5 * 60

        # How long to wait for the server
        self.dnsTimeout = 10

        # end of user-settable attributes

        self.cachefile = os.path.expanduser(cachefile)
        self.caches = None

        if self.cachefile and os.path.exists(self.cachefile):
            try:
                self.caches = pickle_read(self.cachefile)
            except:
                os.unlink(self.cachefile)

        if self.caches is None:
            self.caches = {"A": {}, "PTR": {}}

        if options["globals", "verbose"]:
            if self.caches["A"] or self.caches["PTR"]:
                print >> sys.stderr, "opened existing cache with",
                print >> sys.stderr, len(self.caches["A"]), "A records",
                print >> sys.stderr, "and", len(self.caches["PTR"]),
                print >> sys.stderr, "PTR records"
            else:
                print >> sys.stderr, "opened new cache"

        self.hits = 0  # These two for statistics
        self.misses = 0
        self.pruneTicker = 0

        if dnsServer == None:
            DNS.DiscoverNameServers()
            self.queryObj = DNS.DnsRequest()
        else:
            self.queryObj = DNS.DnsRequest(server=dnsServer)
        return None
Exemple #5
0
    def testDNSRequestTXTD(self):
        dnsob = DNS.DnsRequest('fail.kitterman.org')

        respdef = dnsob.req(qtype='TXT')
        self.assertTrue(respdef.answers)
        data = respdef.answers[0]['data']
        self.assertEqual(data, [b'v=spf1 -all'])
Exemple #6
0
def is_gooddomain(host):
    a = DNS.DnsRequest(host, qtype='a').req().answers
    for record in a:
        if record['typename'] == "A":
            return record['data']

    return
Exemple #7
0
 def lookup(self, record="A"):
     if globalvars.verbose:
         mydns = ", ".join(self.dns_servers)
         self.equeue.put("Looking up %s with %s\n" % (self.hostname, mydns))
     try:
         ipaddress = None
         for svr in self.dns_servers:
             # We set a short timeout because life moves too fast...so does the game!
             r = DNS.DnsRequest(self.hostname,
                                qtype="A",
                                server=[svr],
                                protocol='udp',
                                timeout=60)
             res = r.req()
             for answer in res.answers:
                 if answer["data"]:
                     ipaddress = answer["data"]
                     break
                 else:
                     self.equeue.put("Failed to get DNS!")
         if ipaddress:
             if ctfnet_re.search(ipaddress):
                 if globalvars.verbose:
                     self.equeue.put("got %s\n" % self.ipaddress)
                 self.ipaddress = ipaddress
                 return True
             else:
                 self.equeue.put("Got non RFC1918: %s\n" % ipaddress)
                 return False
         else:
             return False
     except:
         traceback.print_exc(file=self.equeue)
         self.ipaddress = None
         return False
Exemple #8
0
 def lookup(self, IP=None, name=None):
     import DNS
     now = time.time()
     if (not IP) and (not name):
         return None
     if IP:
         if type(IP) != type(''):
             return None
         a = string.split(IP, '.')
         a.reverse()
         name = string.join(a, '.') + '.in-addr.arpa'
         cache = self.revCache
         qt = 'ptr'
     else:
         if type(name) != type(''):
             return None
         cache = self.forCache
         qt = 'a'
     if name in cache:
         # Check if it's timed out or not
         if cache[name][1] < now:
             del (cache[name])
         else:
             return (cache[name][0])
     x = DNS.DnsRequest(name, qtype=qt)
     try:
         x.req()
     except:
         return 'Timeout'
     if len(x.response.answers) > 0:
         cache[name] = (x.response.answers[0]['data'],
                        x.time_finish + x.response.answers[0]['ttl'])
     else:
         cache[name] = (None, now + self.negCache)
     return cache[name][0]
Exemple #9
0
 def __get_remote_current_version(self):
     """
     Retrieve last info about database 
     return dictionary that contains engine, main and daily current version, else None
     """
     # automatically load nameserver(s) from /etc/resolv.conf
     # (works on unix - not on windows
     conf = self.__resolv_conf_for_win()
     DNS.ParseResolvConf(conf)
     self.__del_file(conf)
     
     dns_request = DNS.DnsRequest(name='current.cvd.clamav.net', qtype='TXT')
     dns_answer = dns_request.req()
     if not dns_answer:
         return CL_Py_DNS_Error
         
     all_info = dns_answer.answers[0]
     
     raw = str(all_info["data"][0])
     
     raw_split = raw.split(':')
     
     current_version = dict()
     current_version["engine"] = raw_split[0]
     current_version["main"] = atoi(raw_split[1])
     current_version["daily"] = atoi(raw_split[2])
     
     return current_version
Exemple #10
0
    def testDnsRequestAAAA(self):
        import ipaddress
        dnsobj = DNS.DnsRequest('example.org')

        aaaa_response = dnsobj.qry(qtype='AAAA', resulttype='text')
        self.assertTrue(aaaa_response.answers)
        # does the result look like an ipv6 address?
        self.assertTrue(':' in aaaa_response.answers[0]['data'])
        self.assertEqual(aaaa_response.answers[0]['data'],
                         '2606:2800:220:6d:26bf:1447:1097:aa7')

        # default is returning ipaddress object
        aaaad_response = dnsobj.qry(qtype='AAAA')
        self.assertTrue(aaaad_response.answers)
        self.assertEqual(
            aaaad_response.answers[0]['data'],
            ipaddress.IPv6Address('2606:2800:220:6d:26bf:1447:1097:aa7'))

        aaaab_response = dnsobj.qry(qtype='AAAA', resulttype='binary')
        self.assertTrue(aaaab_response.answers)
        # is it ipv6 looking?
        self.assertEqual(len(aaaab_response.answers[0]['data']), 16)
        for b in aaaab_response.answers[0]['data']:
            assertIsByte(b)
        self.assertEqual(aaaab_response.answers[0]['data'],
                         b'&\x06(\x00\x02 \x00m&\xbf\x14G\x10\x97\n\xa7')
        # IPv6 decimal
        aaaai_response = dnsobj.qry(qtype='AAAA', resulttype='integer')
        self.assertTrue(aaaai_response.answers)
        self.assertEqual(aaaai_response.answers[0]['data'],
                         50542628918019815862290244053507705511)
Exemple #11
0
def main():
    import DNS, timing, socket, time
    res = {}
    for server in servers:
        res[server] = [100000, 0, 0, 0]  # min,max,tot,failed
    for what, querytype in lookups:
        for count in range(rpts):
            for server in servers:
                d = DNS.DnsRequest(server=server, timeout=1)
                fail = 0
                timing.start()
                try:
                    r = d.req(name=what, qtype=querytype)
                except DNS.Error:
                    fail = 1
                timing.finish()
                if fail:
                    res[server][3] = res[server][3] + 1
                    print "(failed)", res[server][3]
                if 0:
                    if r.header['ancount'] == 0:
                        print "WARNING: Server",server,"got no answers for", \
                         what, querytype
                t = timing.milli()
                print server, "took", t, "ms for", what, querytype
                res[server][0] = min(t, res[server][0])
                res[server][1] = max(t, res[server][1])
                res[server][2] = res[server][2] + t
    for server in servers:
        queries = rpts * len(lookups)
        r = res[server]
        print "%-30s %2d/%2d(%3.2f%%) %dms/%dms/%dms min/avg/max" % (
            socket.gethostbyaddr(server)[0], queries - r[3], queries,
            ((queries - r[3]) * 100.0) / queries, r[0], r[2] / queries, r[1])
Exemple #12
0
    def testDnsRequestA(self):
        # try with asking for strings, and asking for bytes
        dnsobj = DNS.DnsRequest('example.org')

        a_response = dnsobj.qry(qtype='A', resulttype='text')
        self.assertTrue(a_response.answers)
        # is the result vaguely ipv4 like?
        self.assertEqual(a_response.answers[0]['data'].count('.'), 3)
        self.assertEqual(a_response.answers[0]['data'], '93.184.216.119')

        # Default result type for .qry object is an ipaddress object
        ad_response = dnsobj.qry(qtype='A')
        self.assertTrue(ad_response.answers)
        self.assertEqual(ad_response.answers[0]['data'],
                         ipaddress.IPv4Address('93.184.216.119'))

        ab_response = dnsobj.qry(qtype='A', resulttype='binary')
        self.assertTrue(ab_response.answers)
        # is the result ipv4 binary like?
        self.assertEqual(len(ab_response.answers[0]['data']), 4)
        for b in ab_response.answers[0]['data']:
            assertIsByte(b)
        self.assertEqual(ab_response.answers[0]['data'], b']\xb8\xd8w')

        ai_response = dnsobj.qry(qtype='A', resulttype='integer')
        self.assertTrue(ai_response.answers)
        self.assertEqual(ai_response.answers[0]['data'], 1572395127)
def DNSResolve(s):
    if DNS:
        DNS.ParseResolvConf()  # Windows?
        r = DNS.DnsRequest(name=s, qtype='A')
        a = r.req()
        return a.answers[0]['data']
    else:
        return socket.gethostbyname(s)
Exemple #14
0
def wan_ip():
    """
    Return the WAN IP of the host running this script.
    """
    DNS.defaults['server'] = ('resolver1.opendns.com', 'resolver2.opendns.com',
                              'resolver3.opendns.com', 'resolver4.opendns.com')
    res = DNS.DnsRequest('myip.opendns.com').qry()
    return res.answers[0]['data']
Exemple #15
0
 def test_email_converter(value, state=None):
     if value is None:
         return value, None
     if state is None:
         state = states.default_state
     username, domain = value.split('@', 1)
     try:
         # For an email domain to be considered valid, either A or MX request should work (both are not needed).
         answers = DNS.DnsRequest(domain, qtype='a',
                                  timeout=10).req().answers
         if not answers:
             answers = DNS.DnsRequest(domain, qtype='mx',
                                      timeout=10).req().answers
     except (socket.error, DNS.DNSError), e:
         return value, state._(
             u'An error occured when trying to connect to the email server: {0}'
         ).format(e)
Exemple #16
0
    def testDnsRequestAD(self):
        # try with asking for strings, and asking for bytes
        dnsob = DNS.DnsRequest('example.org')

        ad_response = dnsob.req(qtype='A')
        self.assertTrue(ad_response.answers)
        # is the result vaguely ipv4 like?
        self.assertEqual(ad_response.answers[0]['data'].count('.'), 3)
        self.assertEqual(ad_response.answers[0]['data'], '93.184.216.119')
Exemple #17
0
    def testDnsRequestMX(self):
        dnsobj = DNS.DnsRequest('ietf.org')
        mx_response = dnsobj.qry(qtype='MX')
        self.assertTrue(mx_response.answers[0])
        # is hard coding a remote address a good idea?
        # I think it's unavoidable. - sk
        self.assertEqual(mx_response.answers[0]['data'], (0, 'mail.ietf.org'))

        m = DNS.mxlookup('ietf.org')
        self.assertEqual(mx_response.answers[0]['data'], m[0])
Exemple #18
0
def lookup(query, type='a'):
    """
	Lookup DNS entries of specified type.

	>>> lookup('localhost')
	['127.0.0.1']
	"""
    rr = DNS.DnsRequest(query, qtype=type).req().answers
    result = map(lambda x: x['data'], rr)
    return result
Exemple #19
0
def DNSLookup(name, qtype):
    try:
        req = DNS.DnsRequest(name, qtype=qtype)
        resp = req.req()
        #resp.show()
        # key k: ('wayforward.net', 'A'), value v
        return [((a['name'], a['typename']), a['data']) for a in resp.answers]
    except IOError:
        raise TempError, 'DNS ' + str(x)
    except DNS.DNSError, x:
        raise TempError, 'DNS ' + str(x)
Exemple #20
0
 def testNSD(self):
     """Lookup NS record from SOA"""
     dnsob = DNS.DnsRequest('kitterman.com')
     resp = dnsob.req(qtype='SOA')
     self.assertTrue(resp.answers)
     primary = resp.answers[0]['data'][0]
     self.assertEqual(primary, 'ns1.pairnic.com')
     resp = dnsob.req(qtype='NS', server=primary, aa=1)
     nslist = [x['data'].lower() for x in resp.answers]
     nslist.sort()
     self.assertEqual(nslist, ['ns1.pairnic.com', 'ns2.pairnic.com'])
Exemple #21
0
def get_dbservername(domainname):
	'''Datenbankserver ermitteln'''
	log('get dbservername for ' + domainname)
	DNS.DiscoverNameServers()
	dbsrvname = None
	try:
		dbsrvname = map(lambda x: x['data'], DNS.DnsRequest('_pkgdb._tcp.' + domainname, qtype='srv').req().answers)[0][3]
	except:
		log('Cannot find service-record of _pkgdb._tcp.')
		print('Cannot find service-record of _pkgdb._tcp.')
	return dbsrvname
    def dns_resolver(self, domain):
        """
        dns resolver
        """

        try:
            import DNS
            req = DNS.DnsRequest(domain, qtype='A').req().answers
            return [r['data'] for r in req if r['typename'] == 'A']
        except:
            self.logger.error(grac_format_exc())
            return []
Exemple #23
0
    def testDnsRequestAAAAD(self):
        dnsob = DNS.DnsRequest('example.org')

        # default is returning binary instead of text
        aaaad_response = dnsob.req(qtype='AAAA')
        self.assertTrue(aaaad_response.answers)
        # does the result look like a binary ipv6 address?
        self.assertEqual(len(aaaad_response.answers[0]['data']), 16)
        for b in aaaad_response.answers[0]['data']:
            assertIsByte(b)
        self.assertEqual(aaaad_response.answers[0]['data'],
                         b'&\x06(\x00\x02 \x00m&\xbf\x14G\x10\x97\n\xa7')
Exemple #24
0
 def f(value):
     try:
         username, domain = value.split('@', 1)
     except ValueError:
         raise Invalid(_msg(f.msg, 'email.format', 'invalid format'))
     if not _usernameRE.match(username):
         raise Invalid(_msg(f.msg, 'email.username', 'invalid username'))
     if not _domainRE.match(domain):
         raise Invalid(_msg(f.msg, 'email.domain', 'invalid domain'))
     if f.check_dns:
         try:
             a = DNS.DnsRequest(domain, qtype='mx').req().answers
             if not a:
                 a = DNS.DnsRequest(domain, qtype='a').req().answers
             dnsdomains = [x['data'] for x in a]
         except (socket.error, DNS.DNSError), e:
             raise Invalid(_msg(f.msg, 'email.socket_error',
                                'socket error'))
         if not dnsdomains:
             raise Invalid(
                 _msg(f.msg, 'email.domain_error', 'no such domain'))
Exemple #25
0
def getQtypeAnswers(name, type, server, protocol='udp', times=1):
    success = 0
    try:
        r = DNS.DnsRequest(name=name, qtype=type, server=server, protocol=protocol, timeout=1)
        answerslist = r.req()
        # while answerslist.header['ancount'] == 0 :
        # times = times + 1
    # answerslist = getQtypeAnswers(name,type,server,protocol,times)
        return answerslist
    except:
        # print "Timeout",name,type,server
        # logging.error(("Timeout 5 times",name,type,server))
        return 0
Exemple #26
0
def is_using_tor(client_ip, el_port='80'):
    '''
    Find out if clientIp is a tor exit node following query type one.
    Inspired by https://svn.torproject.org/svn/check/trunk/cgi-bin/TorCheck.py
    Query Specification under https://gitweb.torproject.org/tordnsel.git/blob/HEAD:/doc/torel-design.txt
    See also https://check.torproject.org/
    '''

    DNS.DiscoverNameServers()

    # Put user ip in right format
    split_ip = client_ip.split('.')
    split_ip.reverse()
    el_exit_node = '.'.join(split_ip)

    # get beam's current ip address
    name = settings.ENV_SITE_MAPPING[settings.ENV][settings.SITE_USER]
    el_target = DNS.dnslookup(name, 'A')

    # ExitList DNS server we want to query
    el_host = 'ip-port.exitlist.torproject.org'

    # Prepare the question as an A record (i.e. a 32-bit IPv4 address) request
    el_question = el_exit_node + "." + el_port + "." + el_target[
        1] + "." + el_host
    request = DNS.DnsRequest(name=el_question,
                             qtype='A',
                             timeout=settings.TOR_TIMEOUT)

    # Ask the question and load the data into our answer
    try:
        answer = request.req()
    except DNS.DNSError as e:
        log_error('ERROR Tor - Failed to query ip address: {}'.format(e[0]))
        return False

    # Parse the answer and decide if it's allowing exits
    # 127.0.0.2 is an exit and NXDOMAIN is not
    if answer.header['status'] == 'NXDOMAIN':
        return False
    else:
        # unexpected response
        if not answer.answers:
            log_error('ERROR Tor - Query returned unexpected response')
            return False
        for a in answer.answers:
            if a['data'] != '127.0.0.2':
                return False
        return True
Exemple #27
0
def dns_reverse_lookup(dns_server, timeout_in_sec, ip, logger):
    '''Tries to return a hostname doing a DNS rev lookup'''
    dns_answered = False
    try:
        reversed_ip = '.'.join(ip.split('.')[::-1])
    except Exception as e:
        logger.critical('not a valid IP')
        logger.critical(e)
        sys.exit(FAILURE_CONSTANT)
    try:
        dns_obj = DNS.DnsRequest(server=dns_server, timeout=timeout_in_sec)
    except Exception, error:
        logger.critical('failed to talk to DNS NS')
        logger.critical(e)
        sys.exit(FAILURE_CONSTANT)
Exemple #28
0
def DNSLookup(name, qtype):
    try:
        # To be thread safe, we create a fresh DnsRequest with
        # each call.  It would be more efficient to reuse
        # a req object stored in a Session.
        req = DNS.DnsRequest(name, qtype=qtype)
        resp = req.req()
        #resp.show()
        # key k: ('wayforward.net', 'A'), value v
        # FIXME: pydns returns AAAA RR as 16 byte binary string, but
        # A RR as dotted quad.  For consistency, this driver should
        # return both as binary string.
        return [((a['name'], a['typename']), a['data']) for a in resp.answers]
    except IOError as x:
        raise DNSError(str(x))
Exemple #29
0
    def testDNSRequestTXT(self):
        dnsobj = DNS.DnsRequest('fail.kitterman.org')

        respdef = dnsobj.qry(qtype='TXT')
        self.assertTrue(respdef.answers)
        data = respdef.answers[0]['data']
        self.assertEqual(data, [b'v=spf1 -all'])

        resptext = dnsobj.qry(qtype='TXT', resulttype='text')
        self.assertTrue(resptext.answers)
        data = resptext.answers[0]['data']
        self.assertEqual(data, ['v=spf1 -all'])

        respbin = dnsobj.qry(qtype='TXT', resulttype='binary')
        self.assertTrue(respbin.answers)
        data = respbin.answers[0]['data']
        self.assertEqual(data, [b'\x0bv=spf1 -all'])
Exemple #30
0
    def _get_mx1(self, domain):
        if domain in ('localhost', ):
            return None

        import DNS
        # FIXME: This bypasses the connection broker and is not secured or
        #        anonymized.
        DNS.DiscoverNameServers()
        try:
            timeout = (self.deadline - time.time()) // 2
            mxlist = DNS.DnsRequest(name=domain,
                                    qtype=DNS.Type.MX,
                                    timeout=timeout).req()
            mxs = sorted([m['data'] for m in mxlist.answers if 'data' in m])
            return mxs[0][1] if mxs else None
        except socket.error:
            return None