Replace tabs with spaces
This commit is contained in:
parent
a5e831ec21
commit
8384311517
194
api/dnshelper.py
194
api/dnshelper.py
|
@ -11,121 +11,121 @@ import dns.resolver
|
|||
# FIXME: DNS timeouts
|
||||
|
||||
def compareRecords(rrset, expected):
|
||||
result = {
|
||||
"nameMissing": [],
|
||||
"rrMissing": [],
|
||||
"rrExtra": [],
|
||||
}
|
||||
result = {
|
||||
"nameMissing": [],
|
||||
"rrMissing": [],
|
||||
"rrExtra": [],
|
||||
}
|
||||
|
||||
for domain, rrtype, content in expected:
|
||||
for rrrec in rrset:
|
||||
if domain == rrrec.name.to_text() and dns.rdatatype.from_text(rrtype) == rrrec.rdtype:
|
||||
for name in content:
|
||||
if name not in map(lambda _x: _x.to_text(), rrrec.items):
|
||||
# record missing
|
||||
result["rrMissing"].append((domain, rrtype, name))
|
||||
for domain, rrtype, content in expected:
|
||||
for rrrec in rrset:
|
||||
if domain == rrrec.name.to_text() and dns.rdatatype.from_text(rrtype) == rrrec.rdtype:
|
||||
for name in content:
|
||||
if name not in map(lambda _x: _x.to_text(), rrrec.items):
|
||||
# record missing
|
||||
result["rrMissing"].append((domain, rrtype, name))
|
||||
|
||||
for item in rrrec.items:
|
||||
if item.to_text() not in content:
|
||||
# superfluous record
|
||||
result["rrExtra"].append((domain, rrtype, item.to_text()))
|
||||
for item in rrrec.items:
|
||||
if item.to_text() not in content:
|
||||
# superfluous record
|
||||
result["rrExtra"].append((domain, rrtype, item.to_text()))
|
||||
|
||||
break
|
||||
else:
|
||||
# domain + rr nicht in nameserver
|
||||
result["nameMissing"].append((domain, rrtype))
|
||||
break
|
||||
else:
|
||||
# domain + rr nicht in nameserver
|
||||
result["nameMissing"].append((domain, rrtype))
|
||||
|
||||
success = not any(len(_x) > 0 for _x in result.values())
|
||||
success = not any(len(_x) > 0 for _x in result.values())
|
||||
|
||||
return success, result
|
||||
return success, result
|
||||
|
||||
|
||||
def dnsQuery(domain, rrType, nameserverIp):
|
||||
dname = dns.name.from_text(domain)
|
||||
req = dns.message.make_query(dname, dns.rdatatype.from_text(rrType))
|
||||
resp = dns.query.udp(req, nameserverIp, timeout=2.0)
|
||||
dname = dns.name.from_text(domain)
|
||||
req = dns.message.make_query(dname, dns.rdatatype.from_text(rrType))
|
||||
resp = dns.query.udp(req, nameserverIp, timeout=2.0)
|
||||
|
||||
if resp.rcode() != dns.rcode.NXDOMAIN:
|
||||
rrset = resp.answer + resp.authority + resp.additional
|
||||
return True, rrset
|
||||
else:
|
||||
return False, []
|
||||
if resp.rcode() != dns.rcode.NXDOMAIN:
|
||||
rrset = resp.answer + resp.authority + resp.additional
|
||||
return True, rrset
|
||||
else:
|
||||
return False, []
|
||||
|
||||
|
||||
def checkDomain(domain, tldNameserver, nameservers):
|
||||
result = []
|
||||
result = []
|
||||
|
||||
if nameservers.count() == 0:
|
||||
return [("err", "Domain %s has no nameservers attached to it, nothing to check" % domain)]
|
||||
if nameservers.count() == 0:
|
||||
return [("err", "Domain %s has no nameservers attached to it, nothing to check" % domain)]
|
||||
|
||||
# build record set
|
||||
nsRecords = [(domain, "NS", list(ns.name for ns in nameservers))]
|
||||
glueRecords = []
|
||||
for ns in nameservers:
|
||||
if ns.name.endswith("." + domain):
|
||||
if ns.glueIPv4 or ns.glueIPv6:
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s is under domain %s, but has no glue entries." % (ns.name, domain)))
|
||||
# build record set
|
||||
nsRecords = [(domain, "NS", list(ns.name for ns in nameservers))]
|
||||
glueRecords = []
|
||||
for ns in nameservers:
|
||||
if ns.name.endswith("." + domain):
|
||||
if ns.glueIPv4 or ns.glueIPv6:
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s is under domain %s, but has no glue entries." % (ns.name, domain)))
|
||||
|
||||
# 1. TLD nameserver
|
||||
try:
|
||||
found, rrset = dnsQuery(domain, "ANY", tldNameserver)
|
||||
if found:
|
||||
success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
if success:
|
||||
result.append(("succ", "All records present in TLD nameserver"))
|
||||
else:
|
||||
result.append(("err", "Record mismatch between TLD nameserver and WHOIS database", errors))
|
||||
else:
|
||||
result.append(("err", "Domain %s not found in TLD nameserver" % (domain,)))
|
||||
except (dns.exception.Timeout, OSError):
|
||||
result.append(("err", "TLD nameserver is currently not reachable"))
|
||||
# 1. TLD nameserver
|
||||
try:
|
||||
found, rrset = dnsQuery(domain, "ANY", tldNameserver)
|
||||
if found:
|
||||
success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
if success:
|
||||
result.append(("succ", "All records present in TLD nameserver"))
|
||||
else:
|
||||
result.append(("err", "Record mismatch between TLD nameserver and WHOIS database", errors))
|
||||
else:
|
||||
result.append(("err", "Domain %s not found in TLD nameserver" % (domain,)))
|
||||
except (dns.exception.Timeout, OSError):
|
||||
result.append(("err", "TLD nameserver is currently not reachable"))
|
||||
|
||||
# find other records...
|
||||
# find other records...
|
||||
|
||||
# 2. your nameservers
|
||||
for ns in nameservers:
|
||||
addr = None
|
||||
if ns.glueIPv4:
|
||||
addr = ns.glueIPv4
|
||||
elif ns.glueIPv6:
|
||||
addr = ns.glueIPv6
|
||||
else:
|
||||
for rrType in ("A", "AAAA"):
|
||||
try:
|
||||
r = dns.resolver.Resolver()
|
||||
r.timeout = 2.0
|
||||
q = r.query(ns.name, rdtype=dns.rdatatype.from_text(rrType))
|
||||
addr = q.response.answer[0].items[0].address
|
||||
except (dns.exception.DNSException, OSError):
|
||||
pass
|
||||
# 2. your nameservers
|
||||
for ns in nameservers:
|
||||
addr = None
|
||||
if ns.glueIPv4:
|
||||
addr = ns.glueIPv4
|
||||
elif ns.glueIPv6:
|
||||
addr = ns.glueIPv6
|
||||
else:
|
||||
for rrType in ("A", "AAAA"):
|
||||
try:
|
||||
r = dns.resolver.Resolver()
|
||||
r.timeout = 2.0
|
||||
q = r.query(ns.name, rdtype=dns.rdatatype.from_text(rrType))
|
||||
addr = q.response.answer[0].items[0].address
|
||||
except (dns.exception.DNSException, OSError):
|
||||
pass
|
||||
|
||||
if addr:
|
||||
err = False
|
||||
errDict = {"nameMissing": [], "rrMissing": [], "rrExtra": []}
|
||||
try:
|
||||
for rec in (nsRecords + glueRecords):
|
||||
found, rrset = dnsQuery(rec[0], rec[1], addr)
|
||||
if addr:
|
||||
err = False
|
||||
errDict = {"nameMissing": [], "rrMissing": [], "rrExtra": []}
|
||||
try:
|
||||
for rec in (nsRecords + glueRecords):
|
||||
found, rrset = dnsQuery(rec[0], rec[1], addr)
|
||||
|
||||
#success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
success, errors = compareRecords(rrset, [rec])
|
||||
if not success:
|
||||
err = True
|
||||
for k in errors.keys():
|
||||
errDict[k].extend(errors[k])
|
||||
#success, errors = compareRecords(rrset, nsRecords + glueRecords)
|
||||
success, errors = compareRecords(rrset, [rec])
|
||||
if not success:
|
||||
err = True
|
||||
for k in errors.keys():
|
||||
errDict[k].extend(errors[k])
|
||||
|
||||
if not err:
|
||||
result.append(("succ", "Nameserver %s is configured correctly" % ns.name))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s (via %s) recordset does not match the database" % (ns.name, addr), errDict))
|
||||
except (dns.exception.DNSException, OSError):
|
||||
result.append(("err", "Nameserver %s is not reachable (via %s)" % (ns.name, addr)))
|
||||
|
||||
else:
|
||||
result.append(("err", "Can't resolv an ip address for nameserver %s" % ns.name))
|
||||
if not err:
|
||||
result.append(("succ", "Nameserver %s is configured correctly" % ns.name))
|
||||
else:
|
||||
result.append(("err", "Nameserver %s (via %s) recordset does not match the database" % (ns.name, addr), errDict))
|
||||
except (dns.exception.DNSException, OSError):
|
||||
result.append(("err", "Nameserver %s is not reachable (via %s)" % (ns.name, addr)))
|
||||
|
||||
else:
|
||||
result.append(("err", "Can't resolv an ip address for nameserver %s" % ns.name))
|
||||
|
||||
return result
|
||||
return result
|
||||
|
|
12
api/urls.py
12
api/urls.py
|
@ -7,13 +7,13 @@ from django.conf.urls import url
|
|||
from . import views as api_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'asblock/free-as/$', api_views.asblockFreeAS, name='asblock-free-as'),
|
||||
url(r'asblock/free-subnet/$', api_views.freeSubnet, name='inetnum-free-subnet'),
|
||||
url(r'inetnum/get-subnet/$', api_views.getSubnet, name='inetnum-get-subnet'),
|
||||
url(r'asblock/free-as/$', api_views.asblockFreeAS, name='asblock-free-as'),
|
||||
url(r'asblock/free-subnet/$', api_views.freeSubnet, name='inetnum-free-subnet'),
|
||||
url(r'inetnum/get-subnet/$', api_views.getSubnet, name='inetnum-get-subnet'),
|
||||
|
||||
url(r'domain/check/$', api_views.checkDomain, name='domain-check'),
|
||||
url(r'rzone/check/$', api_views.checkRzone, name='reversezone-check'),
|
||||
url(r'domain/check/$', api_views.checkDomain, name='domain-check'),
|
||||
url(r'rzone/check/$', api_views.checkRzone, name='reversezone-check'),
|
||||
|
||||
url(r'roa/$', api_views.getROA, name='get-roa'),
|
||||
url(r'roa/$', api_views.getROA, name='get-roa'),
|
||||
|
||||
]
|
||||
|
|
336
api/views.py
336
api/views.py
|
@ -19,219 +19,219 @@ import ipaddress
|
|||
@login_required
|
||||
def asblockFreeAS(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"number": -1,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"number": -1,
|
||||
}
|
||||
|
||||
try:
|
||||
blockName = request.GET.get('block', None)
|
||||
if not blockName:
|
||||
raise ValidationError("No block given")
|
||||
try:
|
||||
blockName = request.GET.get('block', None)
|
||||
if not blockName:
|
||||
raise ValidationError("No block given")
|
||||
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
block = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=blockName)
|
||||
if block.asblock_set.count() > 0:
|
||||
raise ValidationError("AS Block already has sub AS Blocks")
|
||||
if block.asnumber_set.count() > 0:
|
||||
num = block.asnumber_set.order_by("-number")[0].number + 1
|
||||
if num > block.asEnd:
|
||||
num = None
|
||||
for n in range(block.asBegin, block.asEnd + 1):
|
||||
try:
|
||||
ASNumber.objects.get(number=n)
|
||||
except ASNumber.DoesNotExist:
|
||||
num = n
|
||||
break
|
||||
if not num:
|
||||
raise ValidationError("No free AS Number in block")
|
||||
ret["number"] = num
|
||||
else:
|
||||
ret["number"] = block.asBegin
|
||||
except ASBlock.DoesNotExist:
|
||||
raise ValidationError("Could not get AS Block")
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
block = ASBlock.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=blockName)
|
||||
if block.asblock_set.count() > 0:
|
||||
raise ValidationError("AS Block already has sub AS Blocks")
|
||||
if block.asnumber_set.count() > 0:
|
||||
num = block.asnumber_set.order_by("-number")[0].number + 1
|
||||
if num > block.asEnd:
|
||||
num = None
|
||||
for n in range(block.asBegin, block.asEnd + 1):
|
||||
try:
|
||||
ASNumber.objects.get(number=n)
|
||||
except ASNumber.DoesNotExist:
|
||||
num = n
|
||||
break
|
||||
if not num:
|
||||
raise ValidationError("No free AS Number in block")
|
||||
ret["number"] = num
|
||||
else:
|
||||
ret["number"] = block.asBegin
|
||||
except ASBlock.DoesNotExist:
|
||||
raise ValidationError("Could not get AS Block")
|
||||
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
return JsonResponse(ret)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def freeSubnet(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
|
||||
try:
|
||||
parentRangeName = request.GET.get('parentRange', None)
|
||||
if not parentRangeName:
|
||||
raise ValidationError("No subnet given")
|
||||
try:
|
||||
parentRangeName = request.GET.get('parentRange', None)
|
||||
if not parentRangeName:
|
||||
raise ValidationError("No subnet given")
|
||||
|
||||
parentRange = None
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
parentRange = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=parentRangeName)
|
||||
except InetNum.DoesNotExist:
|
||||
raise ValidationError("Parent range does not exist / is not maintained by you")
|
||||
parentRange = None
|
||||
try:
|
||||
mnts = request.user.maintainer_set.all()
|
||||
parentRange = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct().get(handle=parentRangeName)
|
||||
except InetNum.DoesNotExist:
|
||||
raise ValidationError("Parent range does not exist / is not maintained by you")
|
||||
|
||||
prefixLen = 0
|
||||
try:
|
||||
prefixLen = request.GET.get("prefixLen", None)
|
||||
if not prefixLen:
|
||||
if parentRange.protocol == InetNum.IPv4:
|
||||
prefixLen = 27
|
||||
else:
|
||||
prefixLen = 60
|
||||
prefixLen = int(prefixLen)
|
||||
prefixLen = 0
|
||||
try:
|
||||
prefixLen = request.GET.get("prefixLen", None)
|
||||
if not prefixLen:
|
||||
if parentRange.protocol == InetNum.IPv4:
|
||||
prefixLen = 27
|
||||
else:
|
||||
prefixLen = 60
|
||||
prefixLen = int(prefixLen)
|
||||
|
||||
if prefixLen < 8 or \
|
||||
(parentRange.protocol == InetNum.IPv4 and prefixLen > 32) or \
|
||||
(parentRange.protocol == InetNum.IPv6 and prefixLen > 128):
|
||||
raise ValidationError("Given prefix length is out of range")
|
||||
except ValueError:
|
||||
raise ValidationError("PrefixLen is not a number")
|
||||
if prefixLen < 8 or \
|
||||
(parentRange.protocol == InetNum.IPv4 and prefixLen > 32) or \
|
||||
(parentRange.protocol == InetNum.IPv6 and prefixLen > 128):
|
||||
raise ValidationError("Given prefix length is out of range")
|
||||
except ValueError:
|
||||
raise ValidationError("PrefixLen is not a number")
|
||||
|
||||
usableNet = None
|
||||
# FIXME: use first biggest usable netblock...
|
||||
#biggestNet = parentRange.inetnum_set.order_by("-address")
|
||||
#if biggestNet
|
||||
# candidateNet =
|
||||
# and (biggestNet.getNetwork().broadcast_address.:
|
||||
usableNet = None
|
||||
# FIXME: use first biggest usable netblock...
|
||||
#biggestNet = parentRange.inetnum_set.order_by("-address")
|
||||
#if biggestNet
|
||||
# candidateNet =
|
||||
# and (biggestNet.getNetwork().broadcast_address.:
|
||||
|
||||
# try using next network in range
|
||||
# ordering does not work, as order_by sorts alphabetically
|
||||
# ==> the set is short, we can iterate through all. no sense in unpacking the SQL magic
|
||||
#biggestNets = parentRange.inetnum_set.order_by("-address")
|
||||
biggestNet = None
|
||||
for ipRange in parentRange.inetnum_set.all():
|
||||
if not biggestNet or ipRange.getNetwork() > biggestNet:
|
||||
biggestNet = ipRange.getNetwork()
|
||||
# try using next network in range
|
||||
# ordering does not work, as order_by sorts alphabetically
|
||||
# ==> the set is short, we can iterate through all. no sense in unpacking the SQL magic
|
||||
#biggestNets = parentRange.inetnum_set.order_by("-address")
|
||||
biggestNet = None
|
||||
for ipRange in parentRange.inetnum_set.all():
|
||||
if not biggestNet or ipRange.getNetwork() > biggestNet:
|
||||
biggestNet = ipRange.getNetwork()
|
||||
|
||||
if biggestNet:
|
||||
candidateNet = ipaddress.ip_network("%s/%s" % (biggestNet.broadcast_address + 1, biggestNet.prefixlen))
|
||||
print("biggest net", biggestNet, "candidate", candidateNet)
|
||||
if candidateNet.network_address in parentRange.getNetwork():
|
||||
usableNet = candidateNet
|
||||
if biggestNet:
|
||||
candidateNet = ipaddress.ip_network("%s/%s" % (biggestNet.broadcast_address + 1, biggestNet.prefixlen))
|
||||
print("biggest net", biggestNet, "candidate", candidateNet)
|
||||
if candidateNet.network_address in parentRange.getNetwork():
|
||||
usableNet = candidateNet
|
||||
|
||||
# check if there are still networks left in range
|
||||
if not usableNet:
|
||||
# search for free network
|
||||
nets = list(parentRange.getNetwork().subnets())
|
||||
for subRange in parentRange.inetnum_set.all():
|
||||
newNet = None
|
||||
for net in nets:
|
||||
if subRange.getNetwork().network_address in net:
|
||||
newNet = net
|
||||
if not newNet:
|
||||
# critical error, we want a 500 here
|
||||
raise ValueError("Subnet not in range")
|
||||
# check if there are still networks left in range
|
||||
if not usableNet:
|
||||
# search for free network
|
||||
nets = list(parentRange.getNetwork().subnets())
|
||||
for subRange in parentRange.inetnum_set.all():
|
||||
newNet = None
|
||||
for net in nets:
|
||||
if subRange.getNetwork().network_address in net:
|
||||
newNet = net
|
||||
if not newNet:
|
||||
# critical error, we want a 500 here
|
||||
raise ValueError("Subnet not in range")
|
||||
|
||||
nets.remove(newNet)
|
||||
nets.extend(newNet.address_exclude(subRange.getNetwork()))
|
||||
nets.remove(newNet)
|
||||
nets.extend(newNet.address_exclude(subRange.getNetwork()))
|
||||
|
||||
nets = sorted(nets)
|
||||
for net in nets:
|
||||
if net.prefixlen <= prefixLen:
|
||||
usableNet = net
|
||||
break
|
||||
nets = sorted(nets)
|
||||
for net in nets:
|
||||
if net.prefixlen <= prefixLen:
|
||||
usableNet = net
|
||||
break
|
||||
|
||||
if not usableNet:
|
||||
raise ValidationError("No space left in given range")
|
||||
if not usableNet:
|
||||
raise ValidationError("No space left in given range")
|
||||
|
||||
ret["network"] = "%s/%s" % (usableNet.network_address, prefixLen)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
ret["network"] = "%s/%s" % (usableNet.network_address, prefixLen)
|
||||
ret["success"] = True
|
||||
except ValidationError as e:
|
||||
ret["errorMsg"] = e.message
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def getSubnet(request):
|
||||
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"network": None,
|
||||
}
|
||||
|
||||
try:
|
||||
netName = request.GET.get('net', None)
|
||||
mnts = request.user.maintainer_set.all()
|
||||
nets = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
net = nets.get(handle=netName)
|
||||
try:
|
||||
netName = request.GET.get('net', None)
|
||||
mnts = request.user.maintainer_set.all()
|
||||
nets = InetNum.objects.filter(Q(mnt_by__in=mnts) | Q(mnt_lower__in=mnts)).distinct()
|
||||
net = nets.get(handle=netName)
|
||||
|
||||
ret["success"] = True
|
||||
ret["network"] = net.prefix()
|
||||
except InetNum.DoesNotExist:
|
||||
ret["errorMsg"] = "Chosen network does not exist"
|
||||
ret["success"] = True
|
||||
ret["network"] = net.prefix()
|
||||
except InetNum.DoesNotExist:
|
||||
ret["errorMsg"] = "Chosen network does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def checkDomain(request):
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
|
||||
try:
|
||||
domainName = Domain.fixName(request.GET.get('domain', ''))
|
||||
domain = Domain.objects.get(name=domainName)
|
||||
#if not domain.canEdit(request.user):
|
||||
# raise Domain.DoesNotExist()
|
||||
try:
|
||||
domainName = Domain.fixName(request.GET.get('domain', ''))
|
||||
domain = Domain.objects.get(name=domainName)
|
||||
#if not domain.canEdit(request.user):
|
||||
# raise Domain.DoesNotExist()
|
||||
|
||||
ret["success"] = True
|
||||
ret["domain"] = domain.name
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(domain.name, TLD_NAMESERVERS[0], domain.nameservers.all())
|
||||
except Domain.DoesNotExist:
|
||||
ret["errorMsg"] = "Domain does not exist"
|
||||
ret["success"] = True
|
||||
ret["domain"] = domain.name
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(domain.name, TLD_NAMESERVERS[0], domain.nameservers.all())
|
||||
except Domain.DoesNotExist:
|
||||
ret["errorMsg"] = "Domain does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
@login_required
|
||||
def checkRzone(request):
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
ret = {
|
||||
"success": False,
|
||||
"errorMsg": None,
|
||||
"domain": None,
|
||||
"result": None,
|
||||
}
|
||||
|
||||
try:
|
||||
rzonePk = int(request.GET.get('domain', ''))
|
||||
rzone = ReverseZone.objects.get(pk=rzonePk)
|
||||
#if not rzone.canEdit(request.user):
|
||||
# raise ReverseZone.DoesNotExist()
|
||||
try:
|
||||
rzonePk = int(request.GET.get('domain', ''))
|
||||
rzone = ReverseZone.objects.get(pk=rzonePk)
|
||||
#if not rzone.canEdit(request.user):
|
||||
# raise ReverseZone.DoesNotExist()
|
||||
|
||||
ret["success"] = True
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(rzone.getZone(), TLD_NAMESERVERS[0], rzone.nameservers.all())
|
||||
except (ReverseZone.DoesNotExist, ValueError):
|
||||
ret["errorMsg"] = "ReverseZone does not exist"
|
||||
ret["success"] = True
|
||||
# FIXME: change this if we ever have more than one...
|
||||
ret["result"] = helperCheckDomain(rzone.getZone(), TLD_NAMESERVERS[0], rzone.nameservers.all())
|
||||
except (ReverseZone.DoesNotExist, ValueError):
|
||||
ret["errorMsg"] = "ReverseZone does not exist"
|
||||
|
||||
return JsonResponse(ret)
|
||||
return JsonResponse(ret)
|
||||
|
||||
|
||||
def getROA(request):
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
|
||||
return JsonResponse(roa)
|
||||
return JsonResponse(roa)
|
||||
|
|
265
bin/dns-sync
265
bin/dns-sync
|
@ -25,179 +25,178 @@ __VERSION__ = '0.1'
|
|||
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
||||
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
||||
parser.add_argument("-c", "--config", default=None, type=argparse.FileType("r"), help="Path to config file (default path: ./dns-sync.conf, /etc/dns-sync.conf)")
|
||||
parser.add_argument("--api-key", default=None, help="PDNS API key")
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
||||
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
||||
parser.add_argument("-c", "--config", default=None, type=argparse.FileType("r"), help="Path to config file (default path: ./dns-sync.conf, /etc/dns-sync.conf)")
|
||||
parser.add_argument("--api-key", default=None, help="PDNS API key")
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
|
||||
return parser
|
||||
|
||||
def mergeDomains(zoneData, pdnsData):
|
||||
rrAdd = []
|
||||
rrData = pdnsData['rrsets']
|
||||
rrAdd = []
|
||||
rrData = pdnsData['rrsets']
|
||||
|
||||
for domain, rrType, records in zoneData:
|
||||
found = False
|
||||
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
||||
if len(pdnsDom) > 0:
|
||||
rrSet = set(_x['content'] for _x in pdnsDom[0]['records'])
|
||||
if rrSet == set(records):
|
||||
found = True
|
||||
for domain, rrType, records in zoneData:
|
||||
found = False
|
||||
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
||||
if len(pdnsDom) > 0:
|
||||
rrSet = set(_x['content'] for _x in pdnsDom[0]['records'])
|
||||
if rrSet == set(records):
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
# new domain!
|
||||
rrAdd.append({
|
||||
"name": domain,
|
||||
"type": rrType,
|
||||
"ttl": 60*60,
|
||||
"changetype": "REPLACE",
|
||||
"records": [{"content": record, "disabled": False} for record in records],
|
||||
})
|
||||
if not found:
|
||||
# new domain!
|
||||
rrAdd.append({
|
||||
"name": domain,
|
||||
"type": rrType,
|
||||
"ttl": 60*60,
|
||||
"changetype": "REPLACE",
|
||||
"records": [{"content": record, "disabled": False} for record in records],
|
||||
})
|
||||
|
||||
return rrAdd
|
||||
return rrAdd
|
||||
|
||||
|
||||
def removeOldDomains(zoneData, pdnsData):
|
||||
rrDel = []
|
||||
rrDel = []
|
||||
|
||||
#print("zone data", zoneData)
|
||||
#print("pdnsData", pdnsData)
|
||||
for entry in pdnsData['rrsets']:
|
||||
# search for name/type in domain dict. if non-existtant mark for deletion
|
||||
# this could be much more efficient with a dict! name: [rrset...]
|
||||
if not any(entry['name'] == _x[0] and entry['type'] == _x[1] for _x in zoneData):
|
||||
rrDel.append({
|
||||
"changetype": "DELETE",
|
||||
"name": entry["name"],
|
||||
"type": entry["type"],
|
||||
})
|
||||
#print("zone data", zoneData)
|
||||
#print("pdnsData", pdnsData)
|
||||
for entry in pdnsData['rrsets']:
|
||||
# search for name/type in domain dict. if non-existtant mark for deletion
|
||||
# this could be much more efficient with a dict! name: [rrset...]
|
||||
if not any(entry['name'] == _x[0] and entry['type'] == _x[1] for _x in zoneData):
|
||||
rrDel.append({
|
||||
"changetype": "DELETE",
|
||||
"name": entry["name"],
|
||||
"type": entry["type"],
|
||||
})
|
||||
|
||||
return rrDel
|
||||
|
||||
return rrDel
|
||||
|
||||
def handleNameserver(ns, servers, usedNameservers, domains):
|
||||
servers.append(ns.name)
|
||||
servers.append(ns.name)
|
||||
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
domains.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
domains.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
domains.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
domains.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
|
||||
|
||||
def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers, v4reverse=False):
|
||||
for domain in qs:
|
||||
servers = []
|
||||
for ns in domain.nameservers.all():
|
||||
servers.append(ns.name)
|
||||
for domain in qs:
|
||||
servers = []
|
||||
for ns in domain.nameservers.all():
|
||||
servers.append(ns.name)
|
||||
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
if ns.name not in usedNameservers and (ns.glueIPv4 or ns.glueIPv6):
|
||||
usedNameservers.append(ns.name)
|
||||
if ns.glueIPv4:
|
||||
glueRecords.append((ns.name, "A", [ns.glueIPv4]))
|
||||
if ns.glueIPv6:
|
||||
glueRecords.append((ns.name, "AAAA", [ns.glueIPv6]))
|
||||
|
||||
zone.append((domain.getZone(), "NS", servers))
|
||||
zone.append((domain.getZone(), "NS", servers))
|
||||
|
||||
if v4reverse:
|
||||
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
||||
# see RFC2317
|
||||
net = domain.parentNet.getNetwork()
|
||||
if net.prefixlen % 8 != 0:
|
||||
revZone = domain.getZone()
|
||||
parts = str(net.network_address).split(".")
|
||||
baseZone = ".".join(reversed(parts[:net.prefixlen // 8])) + ".in-addr.arpa."
|
||||
startNo = int(parts[net.prefixlen // 8])
|
||||
lenExp = 8 - (net.prefixlen % 8)
|
||||
if v4reverse:
|
||||
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
||||
# see RFC2317
|
||||
net = domain.parentNet.getNetwork()
|
||||
if net.prefixlen % 8 != 0:
|
||||
revZone = domain.getZone()
|
||||
parts = str(net.network_address).split(".")
|
||||
baseZone = ".".join(reversed(parts[:net.prefixlen // 8])) + ".in-addr.arpa."
|
||||
startNo = int(parts[net.prefixlen // 8])
|
||||
lenExp = 8 - (net.prefixlen % 8)
|
||||
|
||||
for i in range(2 ** lenExp):
|
||||
no = startNo + i
|
||||
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
||||
|
||||
for i in range(2 ** lenExp):
|
||||
no = startNo + i
|
||||
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
||||
|
||||
def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
|
||||
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
||||
pdnsData = s.get(url).json()
|
||||
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
||||
pdnsData = s.get(url).json()
|
||||
|
||||
baseProtectedRecords = [
|
||||
(zone, "NS", []),
|
||||
(zone, "SOA", []),
|
||||
]
|
||||
baseProtectedRecords = [
|
||||
(zone, "NS", []),
|
||||
(zone, "SOA", []),
|
||||
]
|
||||
|
||||
# add dn. (NS + glue Nameservers)
|
||||
newDomains = mergeDomains(zoneData, pdnsData)
|
||||
print("Add/replace", newDomains)
|
||||
# add dn. (NS + glue Nameservers)
|
||||
newDomains = mergeDomains(zoneData, pdnsData)
|
||||
print("Add/replace", newDomains)
|
||||
|
||||
if len(newDomains) > 0:
|
||||
r = s.patch(url, data=json.dumps({'rrsets': newDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
if len(newDomains) > 0:
|
||||
r = s.patch(url, data=json.dumps({'rrsets': newDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
|
||||
delDomains = removeOldDomains(zoneData + protectedRecords + baseProtectedRecords, pdnsData)
|
||||
print("Del", delDomains)
|
||||
r = s.patch(url, data=json.dumps({'rrsets': delDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
delDomains = removeOldDomains(zoneData + protectedRecords + baseProtectedRecords, pdnsData)
|
||||
print("Del", delDomains)
|
||||
r = s.patch(url, data=json.dumps({'rrsets': delDomains}))
|
||||
if r.status_code != 204:
|
||||
raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
|
||||
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
if args.config:
|
||||
config.read_file(args.config)
|
||||
else:
|
||||
config.read([os.path.join(os.path.abspath(__file__), "dns-sync.conf"), "/etc/dns-sync.conf"])
|
||||
#print(config)
|
||||
#print(config.get("DEFAULT", "api-key"))
|
||||
#print(config.has_section("DEFAULT"), config.has_option("DEFAULT", "api-key"))
|
||||
config = configparser.ConfigParser()
|
||||
if args.config:
|
||||
config.read_file(args.config)
|
||||
else:
|
||||
config.read([os.path.join(os.path.abspath(__file__), "dns-sync.conf"), "/etc/dns-sync.conf"])
|
||||
#print(config)
|
||||
#print(config.get("DEFAULT", "api-key"))
|
||||
#print(config.has_section("DEFAULT"), config.has_option("DEFAULT", "api-key"))
|
||||
|
||||
if args.api_key:
|
||||
config["DEFAULT"]["api-key"] = args.api_key
|
||||
if args.api_key:
|
||||
config["DEFAULT"]["api-key"] = args.api_key
|
||||
|
||||
if not config.has_option("DEFAULT", "api-key"):
|
||||
print("Error: Could not find api-key (not present in config under [DEFAULT]; not given via command line)", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
if not config.has_option("DEFAULT", "api-key"):
|
||||
print("Error: Could not find api-key (not present in config under [DEFAULT]; not given via command line)", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
s = requests.Session()
|
||||
s.headers = {
|
||||
'X-API-Key': config.get("DEFAULT", "api-key"),
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
s = requests.Session()
|
||||
s.headers = {
|
||||
'X-API-Key': config.get("DEFAULT", "api-key"),
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
domains = []
|
||||
rzone4 = []
|
||||
rzone6 = []
|
||||
usedNameservers = []
|
||||
domains = []
|
||||
rzone4 = []
|
||||
rzone6 = []
|
||||
usedNameservers = []
|
||||
|
||||
# assenble domain data
|
||||
# dn.
|
||||
qs = Domain.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("name")
|
||||
getDomainsFromQueryset(qs, domains, domains, usedNameservers)
|
||||
# assenble domain data
|
||||
# dn.
|
||||
qs = Domain.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("name")
|
||||
getDomainsFromQueryset(qs, domains, domains, usedNameservers)
|
||||
|
||||
# reverse zones
|
||||
qs = ReverseZone.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("parentNet__address")
|
||||
qs4 = filter(lambda _revz: _revz.getNetwork().version == 4, qs)
|
||||
qs6 = filter(lambda _revz: _revz.getNetwork().version == 6, qs)
|
||||
getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers, v4reverse=True)
|
||||
getDomainsFromQueryset(qs6, rzone6, domains, usedNameservers)
|
||||
# reverse zones
|
||||
qs = ReverseZone.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("parentNet__address")
|
||||
qs4 = filter(lambda _revz: _revz.getNetwork().version == 4, qs)
|
||||
qs6 = filter(lambda _revz: _revz.getNetwork().version == 6, qs)
|
||||
getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers, v4reverse=True)
|
||||
getDomainsFromQueryset(qs6, rzone6, domains, usedNameservers)
|
||||
|
||||
#print("dn.", domains)
|
||||
#print("v4", rzone4)
|
||||
#print("v6", rzone6)
|
||||
|
||||
mergeDomainsWithPdns(s, args, "dn.", domains)
|
||||
mergeDomainsWithPdns(s, args, "10.in-addr.arpa.", rzone4)
|
||||
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
||||
#print("dn.", domains)
|
||||
#print("v4", rzone4)
|
||||
#print("v6", rzone6)
|
||||
|
||||
mergeDomainsWithPdns(s, args, "dn.", domains)
|
||||
mergeDomainsWithPdns(s, args, "10.in-addr.arpa.", rzone4)
|
||||
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
170
bin/import-data
170
bin/import-data
|
@ -24,107 +24,107 @@ from whoisdb.models import ASBlock, ASNumber, Contact, Maintainer, InetNum
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
|
||||
#parser.add_argument("-p", "--port", default=2323, type=int, help="Your port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-j", "--json", type=argparse.FileType('r'), required=True, help="Path to json file")
|
||||
#parser.add_argument("-p", "--port", default=2323, type=int, help="Your port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-j", "--json", type=argparse.FileType('r'), required=True, help="Path to json file")
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
defContact = Contact.objects.get(handle="UNKNOWN-DN")
|
||||
defMnt = Maintainer.objects.get(handle="DARKNET-MNT")
|
||||
blocks = [
|
||||
ASBlock.objects.get(handle="TRA1-ASB"),
|
||||
ASBlock.objects.get(handle="UAB1-ASB")
|
||||
]
|
||||
ranges = [
|
||||
InetNum.objects.get(handle="TRA1-NET"),
|
||||
InetNum.objects.get(handle="DEF4-NET"),
|
||||
InetNum.objects.get(handle="DEF6-NET"),
|
||||
InetNum.objects.get(handle="MISC6-NET"),
|
||||
InetNum.objects.get(handle="LTRA1-NET"),
|
||||
InetNum.objects.get(handle="MAIN4-NET"),
|
||||
]
|
||||
defContact = Contact.objects.get(handle="UNKNOWN-DN")
|
||||
defMnt = Maintainer.objects.get(handle="DARKNET-MNT")
|
||||
blocks = [
|
||||
ASBlock.objects.get(handle="TRA1-ASB"),
|
||||
ASBlock.objects.get(handle="UAB1-ASB")
|
||||
]
|
||||
ranges = [
|
||||
InetNum.objects.get(handle="TRA1-NET"),
|
||||
InetNum.objects.get(handle="DEF4-NET"),
|
||||
InetNum.objects.get(handle="DEF6-NET"),
|
||||
InetNum.objects.get(handle="MISC6-NET"),
|
||||
InetNum.objects.get(handle="LTRA1-NET"),
|
||||
InetNum.objects.get(handle="MAIN4-NET"),
|
||||
]
|
||||
|
||||
|
||||
data = json.load(args.json)
|
||||
print(data.keys())
|
||||
for k, v in data["handles"].items():
|
||||
print(k, v["person"])
|
||||
for asn in data["as"]:
|
||||
print(asn)
|
||||
if ASNumber.objects.filter(number=asn["number"]).count() > 0:
|
||||
continue
|
||||
data = json.load(args.json)
|
||||
print(data.keys())
|
||||
for k, v in data["handles"].items():
|
||||
print(k, v["person"])
|
||||
for asn in data["as"]:
|
||||
print(asn)
|
||||
if ASNumber.objects.filter(number=asn["number"]).count() > 0:
|
||||
continue
|
||||
|
||||
obj = ASNumber(number=asn["number"])
|
||||
block = None
|
||||
for block in blocks:
|
||||
if obj.number >= block.asBegin and obj.number <= block.asEnd:
|
||||
obj.asblock = block
|
||||
break
|
||||
else:
|
||||
raise ValueError("AS %d does not fit a block" % asn["number"])
|
||||
obj = ASNumber(number=asn["number"])
|
||||
block = None
|
||||
for block in blocks:
|
||||
if obj.number >= block.asBegin and obj.number <= block.asEnd:
|
||||
obj.asblock = block
|
||||
break
|
||||
else:
|
||||
raise ValueError("AS %d does not fit a block" % asn["number"])
|
||||
|
||||
if len(asn['admin_c']) >= 1:
|
||||
name = data["handles"][asn["admin_c"][0]]["person"]
|
||||
obj.name = "Imported AS of %s" % name
|
||||
obj.handle = ASNumber.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported AS without admin info"
|
||||
obj.handle = ASNumber.genGenericHandle("Unknown Imported AS")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
obj.save()
|
||||
if len(asn['admin_c']) >= 1:
|
||||
name = data["handles"][asn["admin_c"][0]]["person"]
|
||||
obj.name = "Imported AS of %s" % name
|
||||
obj.handle = ASNumber.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported AS without admin info"
|
||||
obj.handle = ASNumber.genGenericHandle("Unknown Imported AS")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
obj.save()
|
||||
|
||||
for net in data["network"]:
|
||||
print(net)
|
||||
network = ipaddress.ip_network(net["prefix"])
|
||||
for net in data["network"]:
|
||||
print(net)
|
||||
network = ipaddress.ip_network(net["prefix"])
|
||||
|
||||
if InetNum.objects.filter(address=str(network.network_address), netmask=network.prefixlen).count() > 0:
|
||||
continue
|
||||
if InetNum.objects.filter(address=str(network.network_address), netmask=network.prefixlen).count() > 0:
|
||||
continue
|
||||
|
||||
origin = None
|
||||
if net["origin"]:
|
||||
origin = ASNumber.objects.get(number=net["origin"])
|
||||
obj = InetNum(address=str(network.network_address), netmask=network.prefixlen)
|
||||
obj.protocol = InetNum.IPv4 if network.version == 4 else InetNum.IPv6
|
||||
origin = None
|
||||
if net["origin"]:
|
||||
origin = ASNumber.objects.get(number=net["origin"])
|
||||
obj = InetNum(address=str(network.network_address), netmask=network.prefixlen)
|
||||
obj.protocol = InetNum.IPv4 if network.version == 4 else InetNum.IPv6
|
||||
|
||||
x = list(filter(lambda _x: _x['number'] == net["origin"], data["as"]))
|
||||
if len(x) > 0 and x[0]["admin_c"]:
|
||||
name = data["handles"][x[0]["admin_c"][0]]["person"]
|
||||
obj.name = "Imported Network of %s" % name
|
||||
obj.handle = InetNum.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported Network without admin info"
|
||||
obj.handle = InetNum.genGenericHandle("Unknown Imported Network")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
x = list(filter(lambda _x: _x['number'] == net["origin"], data["as"]))
|
||||
if len(x) > 0 and x[0]["admin_c"]:
|
||||
name = data["handles"][x[0]["admin_c"][0]]["person"]
|
||||
obj.name = "Imported Network of %s" % name
|
||||
obj.handle = InetNum.genGenericHandle(re.sub("[^a-zA-Z0-9 ]", "", name))
|
||||
else:
|
||||
obj.name = "Imported Network without admin info"
|
||||
obj.handle = InetNum.genGenericHandle("Unknown Imported Network")
|
||||
obj.description = "Object has been imported from old DB and has not yet been edited"
|
||||
|
||||
for r in ranges:
|
||||
if network.network_address in r.getNetwork():
|
||||
obj.parent_range = r
|
||||
break
|
||||
else:
|
||||
raise ValueError("%s did not fit in any netblock" % network)
|
||||
for r in ranges:
|
||||
if network.network_address in r.getNetwork():
|
||||
obj.parent_range = r
|
||||
break
|
||||
else:
|
||||
raise ValueError("%s did not fit in any netblock" % network)
|
||||
|
||||
obj.save()
|
||||
obj.save()
|
||||
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
if origin:
|
||||
obj.origin_as.add(origin)
|
||||
obj.save()
|
||||
obj.mnt_by.add(defMnt)
|
||||
obj.admin_c.add(defContact)
|
||||
if origin:
|
||||
obj.origin_as.add(origin)
|
||||
obj.save()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -12,11 +12,11 @@ import os
|
|||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
files = [
|
||||
("templates/help/faq.md", "templates/help/faq.html"),
|
||||
("templates/help/faq.md", "templates/help/faq.html"),
|
||||
]
|
||||
|
||||
for srcFile, dstFile in files:
|
||||
srcFile = os.path.join(BASE_DIR, srcFile)
|
||||
dstFile = os.path.join(BASE_DIR, dstFile)
|
||||
markdown.markdownFromFile(open(srcFile, "rb"), open(dstFile, "wb"), extensions=[TocExtension(baselevel=1, permalink=True)])
|
||||
srcFile = os.path.join(BASE_DIR, srcFile)
|
||||
dstFile = os.path.join(BASE_DIR, dstFile)
|
||||
markdown.markdownFromFile(open(srcFile, "rb"), open(dstFile, "wb"), extensions=[TocExtension(baselevel=1, permalink=True)])
|
||||
|
||||
|
|
|
@ -22,26 +22,26 @@ from whoisdb.models import ASNumber
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
parser.parse_args()
|
||||
parser = _parser()
|
||||
parser.parse_args()
|
||||
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
roa = {}
|
||||
for asn in ASNumber.objects.all():
|
||||
nets = []
|
||||
for net in asn.inetnum_set.all():
|
||||
nets.append(net.prefix())
|
||||
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
if nets:
|
||||
roa[asn.number] = nets
|
||||
|
||||
print(json.dumps(roa))
|
||||
print(json.dumps(roa))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
118
bin/whoisd
118
bin/whoisd
|
@ -24,84 +24,84 @@ log = logging.getLogger("whoisd")
|
|||
__VERSION__ = '0.1'
|
||||
|
||||
class WhoisHandler(socketserver.BaseRequestHandler):
|
||||
header = "% This is the DARKNET database query service.\n" \
|
||||
"% The objects should be in something like RPSL format.\n" \
|
||||
"%\n" \
|
||||
"% The DARKNET database is subject to terms and conditions.\n" \
|
||||
"% Mostly these are \"be nice\" and \"don't knowingly break things\".\n" \
|
||||
"\n"
|
||||
header = "% This is the DARKNET database query service.\n" \
|
||||
"% The objects should be in something like RPSL format.\n" \
|
||||
"%\n" \
|
||||
"% The DARKNET database is subject to terms and conditions.\n" \
|
||||
"% Mostly these are \"be nice\" and \"don't knowingly break things\".\n" \
|
||||
"\n"
|
||||
|
||||
def handle(self):
|
||||
self.request.sendall(self.header.encode())
|
||||
line = self.request.recv(1024)
|
||||
line = line.split(b"\n", 2)[0].strip()
|
||||
print("Request object is %s" % line)
|
||||
log.info("Request by %s for %s" % (self.request.getpeername()[0], line))
|
||||
self.request.send(b"\n")
|
||||
def handle(self):
|
||||
self.request.sendall(self.header.encode())
|
||||
line = self.request.recv(1024)
|
||||
line = line.split(b"\n", 2)[0].strip()
|
||||
print("Request object is %s" % line)
|
||||
log.info("Request by %s for %s" % (self.request.getpeername()[0], line))
|
||||
self.request.send(b"\n")
|
||||
|
||||
objs = findInDatabase(line.decode())
|
||||
if len(objs) > 0:
|
||||
self.request.sendall(("%% %d result%s\n" % (len(objs), "" if len(objs)==1 else "s")).encode())
|
||||
for obj in objs:
|
||||
self.sendObject(obj)
|
||||
else:
|
||||
self.request.sendall(b"%% NOT FOUND\n\n")
|
||||
objs = findInDatabase(line.decode())
|
||||
if len(objs) > 0:
|
||||
self.request.sendall(("%% %d result%s\n" % (len(objs), "" if len(objs)==1 else "s")).encode())
|
||||
for obj in objs:
|
||||
self.sendObject(obj)
|
||||
else:
|
||||
self.request.sendall(b"%% NOT FOUND\n\n")
|
||||
|
||||
def sendObject(self, obj):
|
||||
result = [
|
||||
"",
|
||||
"%% Object %s (%s)" % (obj, obj.getClassName()),
|
||||
""
|
||||
]
|
||||
def sendObject(self, obj):
|
||||
result = [
|
||||
"",
|
||||
"%% Object %s (%s)" % (obj, obj.getClassName()),
|
||||
""
|
||||
]
|
||||
|
||||
for field, value in getWhoisObjectFields(obj, False):
|
||||
fieldName = field.lower().replace(" ", "-") + ":"
|
||||
if not value:
|
||||
value = ""
|
||||
for field, value in getWhoisObjectFields(obj, False):
|
||||
fieldName = field.lower().replace(" ", "-") + ":"
|
||||
if not value:
|
||||
value = ""
|
||||
|
||||
if hasattr(value, "through"):
|
||||
for v in value.all():
|
||||
result.append("%-16s %s" % (fieldName, v))
|
||||
else:
|
||||
result.append("%-16s %s" % (fieldName, value))
|
||||
result.extend(["", ""])
|
||||
if hasattr(value, "through"):
|
||||
for v in value.all():
|
||||
result.append("%-16s %s" % (fieldName, v))
|
||||
else:
|
||||
result.append("%-16s %s" % (fieldName, value))
|
||||
result.extend(["", ""])
|
||||
|
||||
self.request.sendall("\n".join(result).encode())
|
||||
self.request.sendall("\n".join(result).encode())
|
||||
|
||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
allow_reuse_address = True
|
||||
|
||||
|
||||
def _parser():
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
parser = argparse.ArgumentParser(
|
||||
#prog='foo',
|
||||
#description='do some awesome foo',
|
||||
)
|
||||
|
||||
parser.add_argument("-p", "--port", default=43, type=int, help="whoisd port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
parser.add_argument("-p", "--port", default=43, type=int, help="whoisd port")
|
||||
#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
|
||||
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
|
||||
|
||||
return parser
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
parser = _parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
server = ThreadedTCPServer(('', args.port), WhoisHandler)
|
||||
server = ThreadedTCPServer(('', args.port), WhoisHandler)
|
||||
|
||||
while True:
|
||||
try:
|
||||
server.serve_forever()
|
||||
except select.error as e:
|
||||
log.exception(e)
|
||||
except KeyboardInterrupt:
|
||||
log.info("^c hit, quitting.")
|
||||
break
|
||||
while True:
|
||||
try:
|
||||
server.serve_forever()
|
||||
except select.error as e:
|
||||
log.exception(e)
|
||||
except KeyboardInterrupt:
|
||||
log.info("^c hit, quitting.")
|
||||
break
|
||||
|
||||
server.server_close()
|
||||
server.server_close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -7,6 +7,6 @@ from .models import User
|
|||
|
||||
|
||||
class CustomUserCreationForm(UserCreationForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username",)
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username",)
|
||||
|
|
|
@ -7,4 +7,4 @@ from django.db import models
|
|||
from django.contrib.auth.models import AbstractUser
|
||||
|
||||
class User(AbstractUser):
|
||||
pass
|
||||
pass
|
||||
|
|
|
@ -8,10 +8,10 @@ from django.contrib.auth import views as auth_views
|
|||
from . import views as dncore_views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', dncore_views.dashboard, name='dashboard'),
|
||||
url(r'^$', dncore_views.dashboard, name='dashboard'),
|
||||
|
||||
url(r'^login/$', auth_views.login, name='login'),
|
||||
url(r'^register/$', dncore_views.RegisterUser.as_view(), name='register'),
|
||||
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
|
||||
url(r'^profile/$', dncore_views.profile, name='profile'),
|
||||
url(r'^login/$', auth_views.login, name='login'),
|
||||
url(r'^register/$', dncore_views.RegisterUser.as_view(), name='register'),
|
||||
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
|
||||
url(r'^profile/$', dncore_views.profile, name='profile'),
|
||||
]
|
||||
|
|
|
@ -22,54 +22,54 @@ from .forms import CustomUserCreationForm
|
|||
|
||||
@login_required
|
||||
def profile(request):
|
||||
pwForm = None
|
||||
pwForm = None
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST.get("submit", None) == "pwchange":
|
||||
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
||||
if pwForm.is_valid():
|
||||
pwForm.save()
|
||||
auth_login(request, pwForm.user)
|
||||
messages.success(request, "Password changed")
|
||||
if request.method == "POST":
|
||||
if request.POST.get("submit", None) == "pwchange":
|
||||
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
||||
if pwForm.is_valid():
|
||||
pwForm.save()
|
||||
auth_login(request, pwForm.user)
|
||||
messages.success(request, "Password changed")
|
||||
|
||||
return HttpResponseRedirect(reverse("user:profile"))
|
||||
return HttpResponseRedirect(reverse("user:profile"))
|
||||
|
||||
if not pwForm:
|
||||
pwForm = PasswordChangeForm(user=request.user)
|
||||
if not pwForm:
|
||||
pwForm = PasswordChangeForm(user=request.user)
|
||||
|
||||
return render(request, "registration/profile.html", {'pwForm': pwForm})
|
||||
return render(request, "registration/profile.html", {'pwForm': pwForm})
|
||||
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
mnts = request.user.maintainer_set.all()
|
||||
ownMnts = request.user.maintainer_set.filter(rir=False, lir=False).all().distinct()
|
||||
# if account only has rir/lir objects, show them
|
||||
if ownMnts.count() == 0:
|
||||
ownMnts = mnts
|
||||
mnts = request.user.maintainer_set.all()
|
||||
ownMnts = request.user.maintainer_set.filter(rir=False, lir=False).all().distinct()
|
||||
# if account only has rir/lir objects, show them
|
||||
if ownMnts.count() == 0:
|
||||
ownMnts = mnts
|
||||
|
||||
asns = ASNumber.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
inetnums = InetNum.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
rrequests = Request.objects.filter((Q(provider__in=mnts) | Q(applicant__in=mnts)) & Q(status=Request.STATE_OPEN)).distinct()
|
||||
asns = ASNumber.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
inetnums = InetNum.objects.filter(Q(mnt_by__in=ownMnts) | Q(mnt_lower__in=ownMnts)).distinct()
|
||||
domains = Domain.objects.filter(mnt_by__in=mnts).distinct()
|
||||
rrequests = Request.objects.filter((Q(provider__in=mnts) | Q(applicant__in=mnts)) & Q(status=Request.STATE_OPEN)).distinct()
|
||||
|
||||
return render(request, "dncore/dashboard.html", {"asns": asns, "inetnums": inetnums, "domains": domains, 'rrequests': rrequests})
|
||||
return render(request, "dncore/dashboard.html", {"asns": asns, "inetnums": inetnums, "domains": domains, 'rrequests': rrequests})
|
||||
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect(reverse("dashboard"))
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect(reverse("dashboard"))
|
||||
|
||||
return render(request, "index.html", {})
|
||||
return render(request, "index.html", {})
|
||||
|
||||
|
||||
class RegisterUser(CreateView):
|
||||
template_name = "dncore/registration.html"
|
||||
form_class = CustomUserCreationForm
|
||||
success_url = reverse_lazy("user:login")
|
||||
template_name = "dncore/registration.html"
|
||||
form_class = CustomUserCreationForm
|
||||
success_url = reverse_lazy("user:login")
|
||||
|
||||
def form_valid(self, form):
|
||||