diff --git a/lib/dnsServer/namecoindns.py b/lib/dnsServer/namecoindns.py index f702938..09c9482 100644 --- a/lib/dnsServer/namecoindns.py +++ b/lib/dnsServer/namecoindns.py @@ -1,4 +1,4 @@ -#name_scan "d/yourdomain" 1 +#namponse_scan "d/yourdomain" 1 import sys, os #sys.path.append('/home/khal/sources/nmcontrol/lib/') import DNS @@ -93,8 +93,6 @@ def get_response(self, query, domain, qtype, qclass, src_addr): elif qtype == 28: #answer = struct.pack("!I", ipstr2int(value)) reqtype = "AAAA" - elif qtype == 52: - reqtype = "TLSA" else : reqtype = None answers = app['services']['dns'].lookup({"query":query, "domain":domain, "qtype":qtype, "qclass":qclass, "src_addr":src_addr}) #print 'domain:', domain @@ -113,22 +111,17 @@ def get_response(self, query, domain, qtype, qclass, src_addr): elif response["type"] == 2 or response["type"] == 5: tempresults["rdata"] = labels2str(response["data"].split(".")) elif response["type"] == 16 : - tempresults["rdata"] = labels2str(response["data"]) + tempresults["rdata"] = label2str(response["data"]) elif response["type"] == 15 : tempresult = struct.pack("!H", response["data"][0]) tempresult += labels2str(response["data"][1].split(".")) tempresults["rdata"] = tempresult elif response["type"] == 28 : tempresults["rdata"] = response["data"] - elif response["type"] == 52 : - tempresult = '\x03\x00' - tempresult += chr(int(response["data"][0][0])) - tempresult += bytearray.fromhex(response["data"][0][1]) - tempresults["rdata"] = tempresult #else : return 3, [] results.append(tempresults) return 0, results - if type(response) == types.StringType : + if type(response) == types.StringType : if self.isIP(response) : return 0, [{"qtype":1, "qclass":qclass, "ttl":300, "rdata":struct.pack("!I", ipstr2int(response))}] return 3, [] @@ -154,7 +147,7 @@ def get_response(self, query, domain, qtype, qclass, src_addr): elif response["type"] == 2 or response["type"] == 5: tempresults["rdata"] = labels2str(response["data"].split(".")) elif response["type"] == 16 : - tempresults["rdata"] = labels2str(response["data"]) + tempresults["rdata"] = label2str(response["data"]) elif response["type"] == 15 : tempresult = struct.pack("!H", response["data"][0]) tempresult += labels2str(response["data"][1].split(".")) @@ -164,8 +157,6 @@ def get_response(self, query, domain, qtype, qclass, src_addr): return self.get_response(query, domain, 5, qclass, src_addr) #tempresults["rdata"] = struct.pack("!I", ipstr2int(response["data"])) tempresults["rdata"] = response["data"] - elif response["type"] == 52 : - tempresults["rdata"] = response["data"] #else : return 3, [] results.append(tempresults) return 0, results diff --git a/plugin/pluginDns.py b/plugin/pluginDns.py index 814a5cf..41b29cd 100644 --- a/plugin/pluginDns.py +++ b/plugin/pluginDns.py @@ -3,7 +3,7 @@ #import DNS #import json, base64, types, random, traceback import re, json -import random + class dnsResult(dict): @@ -45,7 +45,6 @@ class pluginDns(plugin.PluginThread): name = 'dns' options = { 'start': ['Launch at startup', 1], - 'disable_ns_lookups': ['Disable remote lookups for NS records','0'], #'host': ['Listen on ip', '127.0.0.1'], #'port': ['Listen on port', 53], #'resolver': ['Forward standard requests to', '8.8.8.8,8.8.4.4'], @@ -59,7 +58,6 @@ class pluginDns(plugin.PluginThread): 'getFreenet': [1, 1, '', 'Get the freenet config for the domain'], 'getFingerprint': [1, 1, '', 'Get the sha1 of the certificate for the domain (deprecated)'], 'getTlsFingerprint': [1, 3, ' ', 'Get the TLS information for the domain'], - 'getNS': [1, 1, '', 'Get a list of NS for the domain'], 'verifyFingerprint': [1, 2, ' ', 'Verify if the fingerprint is' ' acceptable for the domain'], @@ -126,34 +124,10 @@ def _getRecordForRPC(self, domain, recType): return result.toJsonForRPC() def getIp4(self, domain): - result = self._getRecordForRPC(domain, 'getIp4') - # if we got an NS record because there is no IP we need to ask the NS server for the IP - if self.conf['disable_ns_lookups'] != '1': - if "ns" in result: - - if(domain.endswith('_ip4.bit')): - domain = domain[:-8] + 'bit' - if(domain.endswith('_ip.bit')): - domain = domain[:-7] + 'bit' - - result = '["'+self._getIPv4FromNS(domain)+'"]' - - return result + return self._getRecordForRPC(domain, 'getIp4') def getIp6(self, domain): - result = self._getRecordForRPC(domain, 'getIp6') - # if we got an NS record because there is no IP we need to ask the NS server for the IP - if self.conf['disable_ns_lookups'] != '1': - if "ns" in result: - - if(domain.endswith('_ip6.bit')): - domain = domain[:-8] + 'bit' - if(domain.endswith('_ip.bit')): - domain = domain[:-7] + 'bit' - - result = '["'+self._getIPv6FromNS(domain)+'"]' - - return result + return self._getRecordForRPC(domain, 'getIp6') def getOnion(self, domain): return self._getRecordForRPC(domain, 'getOnion') @@ -215,61 +189,9 @@ def getTlsFingerprint(self, domain, protocol, port): result.add(domain, 'getTlsFingerprint' , answer) return result.toJsonForRPC() - def getNS(self, domain): - return self._getRecordForRPC(domain, 'getNS') - - def getTranslate(self, domain): - return self._getRecordForRPC(domain, 'getTranslate') - def _getTls(self, domain): return self._getRecordForRPC(domain, 'getTls') - def _getNSServer(self,domain): - item = self.getNS(domain) - - try: - servers = json.loads(item) - except: - if app['debug']: traceback.print_exc() - return - - server = servers[random.randrange(0, len(servers))] - return server - - def _getIPv4FromNS(self,domain): - #1 is the A record - server = self._getNSServer(domain) - - translate = self.getTranslate(domain) - - if translate != '[]': - try: - translate = json.loads(translate) - except: - if app['debug']: traceback.print_exc() - return - - domain = translate[0].rstrip('.') - - return app['services']['dns']._lookup(domain, 1 , server)[0]['data'] - - def _getIPv6FromNS(self,domain): - #28 is the AAAA record - server = self._getNSServer(domain) - - translate = self.getTranslate(domain) - - if translate != '[]': - try: - translate = json.loads(translate) - except: - if app['debug']: traceback.print_exc() - return - - domain = translate[0].rstrip('.') - - return app['services']['dns']._lookup(domain, 28 , server)[0]['data'] - def _getSubDomainTlsFingerprint(self,domain,protocol,port): #Get the first subdomain tls fingerprint that has the includeSubdomain flag turned on for i in xrange(0,domain.count('.')): diff --git a/plugin/pluginNamespaceDomain.py b/plugin/pluginNamespaceDomain.py index f3a0010..d55fc84 100644 --- a/plugin/pluginNamespaceDomain.py +++ b/plugin/pluginNamespaceDomain.py @@ -9,8 +9,8 @@ class pluginNamespaceDomain(plugin.PluginThread): 'start': ['Launch at startup', 1], #'resolver': ['Forward standard requests to', '8.8.8.8,8.8.4.4'], } - depends = {'plugins': ['data', 'dns'],'services': ['dns']} - filters = {'dns': '.bit$|.tor$'} + depends = {'plugins': ['data', 'dns']} + filters = {'dns': '.bit$'} handle = ['dns'] maxNestedCalls = 10 @@ -20,11 +20,9 @@ class pluginNamespaceDomain(plugin.PluginThread): 'getOnion' : 'tor', 'getI2p' : 'i2p', 'getI2p_b32' : 'i2p_b32', - 'getFreenet' : 'freenet', + 'getFreenet': 'freenet', 'getFingerprint': 'fingerprint', 'getTls': 'tls', - 'getNS' : 'ns', - 'getTranslate' : 'translate', } def pLoadconfig(self): @@ -123,24 +121,11 @@ def _fetchNamecoinData(self, domain, recType, subdoms, data, result): result.add(domain, recType, data) return True - if recType == 'ns' and ( type(data) == str or type(data) is unicode ): - result.add(domain, recType, data) - return True - - # ns record in a dictionary, potentially with the translate option - if recType == 'ip' and 'ns' in data: - result.add(domain, recType, data) - return True - # legacy compatibility with "" in map instead of root if recType == 'ip' and 'map' in data and '' in data['map']: result.add(domain, recType, data['map']['']) return True - if recType == 'ns' and 'map' in data and '' in data['map']: - result.add(domain, recType, data['map']['']['ns']) - return True - return False # remove incompatible records (ns with ip, etc) @@ -148,6 +133,7 @@ def _fetchNamecoinData(self, domain, recType, subdoms, data, result): # pass def _fetchSubTree(self, subData, subKeys): + for sub in subKeys: if sub == '' and len(sub) == 0: return subData @@ -189,76 +175,77 @@ def _expandSelectedRecord(self, nameData, subDoms, limit = maxNestedCalls): #print "* nameData:", nameData return nameData - + + def domainToNamespace(self, domain): + if domain.count(".") >= 2 : + host = ".".join(domain.split(".")[-2:-1]) + subdomain = ".".join(domain.split(".")[:-2]) + else : + host = domain.split(".")[0] + subdomain = "" + return 'd/'+host, host, subdomain + + def namespaceToDomain(self, name): + pass + def lookup(self, qdict) : - if qdict["domain"].endswith(".bit"): - return self._bitLookup(qdict) - - if qdict["domain"].endswith(".tor"): - return self._torLookup(qdict) - - - def _bitLookup(self,qdict): - qtype = qdict['qtype'] - if qtype == 1: - reqtype = "A" - if qtype == 2: - reqtype = "NS" - elif qtype == 5: - reqtype = "CNAME" - elif qtype == 16: - reqtype = "TXT" - elif qtype == 15: - reqtype = "MX" - elif qtype == 28: - reqtype = "AAAA" - elif qtype == 52: - reqtype = "TLSA" - - - #try the new API first, then fall back to map if it fails - if reqtype == "A": - #new style A request - answers = app['plugins']['dns'].getIp4(qdict["domain"]) - if answers != '[]': - nameData = json.loads(answers) - answers = str(nameData[0]) - #did we get an IP address or nothing? - if answers: - return answers - return - elif reqtype == "AAAA": - #new style AAAA request - answers = app['plugins']['dns'].getIp6(qdict["domain"]) - if answers != '[]': - nameData = json.loads(answers) - answers = str(nameData[0]) - #did we get an IP address or nothing? - if answers: - return answers + #dns = app['services']['dns'].lookup() + # + print 'inside lookup' + print qdict + name, host, subdomain = self.domainToNamespace(qdict["domain"]) + item = app['plugins']['data'].getData(['data', ['getData', name]]) + #rawlist = json.dumps(rawjson) + try: + item = json.loads(item) + except: + if app['debug']: traceback.print_exc() return - elif reqtype == "TLSA": - port = qdict["domain"].split(".")[0][1:] - protocol = qdict["domain"].split(".")[1][1:] - answers = app['plugins']['dns'].getTlsFingerprint(qdict["domain"], protocol, port) - answers = json.loads(answers) - return {"type":52, "class":1, "ttl":300, "data":answers} - return - - def _torLookup(self,qdict): - - answers = app['plugins']['dns'].getOnion(qdict["domain"]) - if answers != '[]': - nameData = json.loads(answers) - answers = str(nameData[0]) - #did we get an IP address or nothing? - if answers: - #if TXT record - if qdict['qtype'] == 16: - return {"type":16, "class":1, "ttl":300, "data":answers} - #if A record return a CNAME - elif qdict['qtype'] == 1: - return {"type":5, "class":1, "ttl":300, "data":answers} - - return + + if str(item[u"name"]) == "d/" + host : + try : + value = json.loads(item[u"value"]) + if value.has_key(u"map") : + if type(value[u"map"]) is types.DictType : + hasdefault = False + for key in value[u"map"].keys()[:] : + if key == u"" : + hasdefault = True + if str(key) == subdomain : + if type(value[u"map"][key]) == types.DictType : + #return dnslookup(value, key, qdict) + if value[u"map"][key].has_key(u"ns") : + server = value[u"map"][key][u"ns"][random.randrange(0, len(value[u"map"][key][u"ns"])-1)] + #return app['services']['dns']._lookup(qdict, server) + return app['services']['dns']._lookup(qdict, server)[0]['data'] + #return [{"qtype":1, "qclass":qclass, "ttl":300, "rdata":struct.pack("!I", ipstr2int(response))}] + #return [{'name': 'ssl.bit', 'data': '178.32.31.42', 'typename': 'A', 'classstr': 'IN', 'ttl': 86400, 'type': 1, 'class': 1, 'rdlength': 4}] + return str(value[u"map"][u""]) + #else : + #if type(value[u"map"][key]) == types.DictType : + #return dnslookup(domain, qt) + #return 1, str(value[u"map"][key]) + if hasdefault : + if type(value[u"map"][u""]) == types.DictType : + return self.dnslookup(value, u"", qdict) + return str(value[u"map"][u""]) + except : + if app['debug']: traceback.print_exc() + return + + #app['services']['dns'].lookup() + + def dnslookup(self, value, key, qdict) : + print 'dnslookup:', value, key, qdict + if value[u"map"][key].has_key(u"ns") : + server = self.servers[random.randrange(0, len(self.servers)-1)] + self.reqobj = DNS.Request(server=server) + + x = DnsClient.Request(server="8.8.8.8") + if type(value[u"map"][key][u"ns"]) == types.UnicodeType : + y = x.req(str(value[u"map"][key][u"ns"])).answers[0]["data"] + else : + y = x.req(str(value[u"map"][key][u"ns"][0])).answers[0]["data"] + ns = DNS.Request(server=y) + return ns.req(name=qdict["domain"], qtype=qdict["qtype"]).answers[0] diff --git a/service/serviceDNS.py b/service/serviceDNS.py index c96bbe4..f3b3b66 100644 --- a/service/serviceDNS.py +++ b/service/serviceDNS.py @@ -11,7 +11,6 @@ class serviceDNS(plugin.PluginThread): 'host': ['Listen on ip', '127.0.0.1'], 'port': ['Listen on port', 53], 'resolver': ['Forward standard requests to', '8.8.8.8,8.8.4.4'], - 'disable_standard_lookups': ['Disable lookups for standard domains','0'] } srv = None @@ -32,28 +31,15 @@ def pStop(self): def lookup(self, qdict) : if app['debug']: print 'Lookup:', qdict - #for service, value in self.services.iteritems(): - # if re.search(value['filter'], qdict["domain"]): - # return app['plugins'][service].lookup(qdict) - if qdict["domain"].endswith(".bit") or qdict["domain"].endswith(".tor"): - return app['plugins']['domain'].lookup(qdict) - if self.conf['disable_standard_lookups'] == '1': - return [] - return self._lookup(qdict["domain"],qdict["qtype"]) - - def _lookup(self, domain, qtype=1, server = ''): - #make sure the server string is a string and not unicode, otherwise the DNS library fails to resolve it - server = str(server) + for service, value in self.services.iteritems(): + if re.search(value['filter'], qdict["domain"]): + return app['plugins'][service].lookup(qdict) + return self._lookup(qdict) + def _lookup(self, qdict, server = ''): if server == '': server = self.servers[random.randrange(0, len(self.servers)-1)] - if app['debug']: print "Fetching IP Address for: ", domain, "with NS Server:", server - x = DNS.Request(server=server) - result = x.req(name=domain, qtype=qtype).answers - - if app['debug']: print "* result: ", result - - return result + return x.req(name=qdict["domain"], qtype=qdict["qtype"]).answers