Skip to content
17 changes: 4 additions & 13 deletions lib/dnsServer/namecoindns.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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, []
Expand All @@ -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("."))
Expand All @@ -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
Expand Down
84 changes: 3 additions & 81 deletions plugin/pluginDns.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#import DNS
#import json, base64, types, random, traceback
import re, json
import random


class dnsResult(dict):

Expand Down Expand Up @@ -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'],
Expand All @@ -59,7 +58,6 @@ class pluginDns(plugin.PluginThread):
'getFreenet': [1, 1, '<domain>', 'Get the freenet config for the domain'],
'getFingerprint': [1, 1, '<domain>', 'Get the sha1 of the certificate for the domain (deprecated)'],
'getTlsFingerprint': [1, 3, '<domain> <protocol> <port>', 'Get the TLS information for the domain'],
'getNS': [1, 1, '<domain>', 'Get a list of NS for the domain'],
'verifyFingerprint': [1, 2, '<domain> <fingerprint>',
'Verify if the fingerprint is'
' acceptable for the domain'],
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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('.')):
Expand Down
163 changes: 75 additions & 88 deletions plugin/pluginNamespaceDomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -123,31 +121,19 @@ 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)
#def _cleanBadRecords(self, data):
# pass

def _fetchSubTree(self, subData, subKeys):

for sub in subKeys:
if sub == '' and len(sub) == 0:
return subData
Expand Down Expand Up @@ -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]

Loading