Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dnsviz/dnsviz.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCasey Deccio <casey@deccio.net>2020-12-17 03:06:14 +0300
committerCasey Deccio <casey@deccio.net>2020-12-17 03:06:55 +0300
commit69d4a44c6fb2b966733e5621f610e7cae41d0251 (patch)
tree1bd6906777ceb6333ff172d94ba30f91e236ae61
parent33da7ca6b60fa7ef8c29b6f4f0d18f0aeaf3cbd9 (diff)
Display NSID values
Fixes #50.
-rw-r--r--dnsviz/analysis/offline.py42
-rw-r--r--dnsviz/analysis/status.py120
-rw-r--r--dnsviz/response.py52
-rw-r--r--dnsviz/viz/dnssec.py30
-rw-r--r--share/js/dnsviz.js4
5 files changed, 217 insertions, 31 deletions
diff --git a/dnsviz/analysis/offline.py b/dnsviz/analysis/offline.py
index 72c18d0..a9ff6cf 100644
--- a/dnsviz/analysis/offline.py
+++ b/dnsviz/analysis/offline.py
@@ -2642,14 +2642,14 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
dnskeys.sort()
for dnskey in dnskeys:
rrsig_status = self.rrsig_status[rrset_info][rrsig][dnskey]
- rrsig_serialized = rrsig_status.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ rrsig_serialized = rrsig_status.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if rrsig_serialized:
rrsig_list.append(rrsig_serialized)
dname_list = []
if rrset_info in self.dname_status:
for dname_status in self.dname_status[rrset_info]:
- dname_serialized = dname_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ dname_serialized = dname_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if dname_serialized:
dname_list.append(dname_serialized)
@@ -2661,7 +2661,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
wildcard_name_str = lb2s(wildcard_name.canonicalize().to_text())
wildcard_proof_list[wildcard_name_str] = []
for nsec_status in self.wildcard_status[rrset_info.wildcard_info[wildcard_name]]:
- nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if nsec_serialized:
wildcard_proof_list[wildcard_name_str].append(nsec_serialized)
if not wildcard_proof_list[wildcard_name_str]:
@@ -2680,7 +2680,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
if loglevel <= logging.DEBUG:
d['description'] = str(rrset_info)
- d.update(rrset_info.serialize(consolidate_clients=consolidate_clients, show_servers=False, html_format=html_format))
+ d.update(rrset_info.serialize(consolidate_clients=consolidate_clients, show_servers=False, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip))
if rrsig_list:
d['rrsig'] = rrsig_list
@@ -2702,16 +2702,29 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
servers = server_list
d['servers'] = servers
+ ns_names = list(set([lb2s(self.zone.get_ns_name_for_ip(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
if show_server_meta:
tags = set()
+ nsids = set()
cookie_tags = {}
for server,client in rrset_info.servers_clients:
for response in rrset_info.servers_clients[(server,client)]:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
cookie_tags[server] = OrderedDict((
('request', response.request_cookie_tag()),
('response', response.response_cookie_tag()),
))
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -2733,7 +2746,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
proof_list = []
for nsec_status in neg_status[neg_response_info]:
- nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if nsec_serialized:
proof_list.append(nsec_serialized)
@@ -2768,15 +2781,28 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
servers = server_list
d['servers'] = servers
+ ns_names = list(set([lb2s(self.zone.get_ns_name_for_ip(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
cookie_tags = {}
for server,client in neg_response_info.servers_clients:
for response in neg_response_info.servers_clients[(server,client)]:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
cookie_tags[server] = OrderedDict((
('request', response.request_cookie_tag()),
('response', response.response_cookie_tag()),
))
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -2848,7 +2874,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
d = []
for dnskey in self.get_dnskeys():
- dnskey_serialized = dnskey.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ dnskey_serialized = dnskey.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if dnskey_serialized:
if loglevel <= logging.INFO and self.response_component_status is not None:
dnskey_serialized['status'] = Status.rrset_status_mapping[self.response_component_status[dnskey]]
@@ -2867,7 +2893,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
dnskeys.sort()
for dnskey in dnskeys:
ds_status = self.ds_status_by_ds[rdtype][ds][dnskey]
- ds_serialized = ds_status.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ ds_serialized = ds_status.serialize(consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if ds_serialized:
d['ds'].append(ds_serialized)
if not d['ds']:
@@ -2886,7 +2912,7 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis):
if neg_response_info is not None:
d['insecurity_proof'] = []
for nsec_status in status[neg_response_info]:
- nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ nsec_serialized = nsec_status.serialize(self._serialize_rrset_info, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=self.zone.get_ns_name_for_ip)
if nsec_serialized:
d['insecurity_proof'].append(nsec_serialized)
if not d['insecurity_proof']:
diff --git a/dnsviz/analysis/status.py b/dnsviz/analysis/status.py
index 621c438..a2197a8 100644
--- a/dnsviz/analysis/status.py
+++ b/dnsviz/analysis/status.py
@@ -253,7 +253,7 @@ class RRSIGStatus(object):
def __str__(self):
return 'RRSIG covering %s/%s' % (fmt.humanize_name(self.rrset.rrset.name), dns.rdatatype.to_text(self.rrset.rrset.rdtype))
- def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
erroneous_status = self.validation_status not in (RRSIG_STATUS_VALID, RRSIG_STATUS_INDETERMINATE_NO_DNSKEY, RRSIG_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM)
@@ -306,11 +306,25 @@ class RRSIGStatus(object):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.rrset.rrsig_info[self.rrsig].servers_clients:
for response in self.rrset.rrsig_info[self.rrsig].servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -397,7 +411,7 @@ class DSStatus(object):
def __str__(self):
return '%s record(s) corresponding to DNSKEY for %s (algorithm %d (%s), key tag %d)' % (dns.rdatatype.to_text(self.ds_meta.rrset.rdtype), fmt.humanize_name(self.ds_meta.rrset.name), self.ds.algorithm, fmt.DNSKEY_ALGORITHMS.get(self.ds.algorithm, self.ds.algorithm), self.ds.key_tag)
- def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=True):
d = OrderedDict()
erroneous_status = self.validation_status not in (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM)
@@ -442,11 +456,25 @@ class DSStatus(object):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.ds_meta.servers_clients:
for response in self.ds_meta.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -543,7 +571,7 @@ class NSECStatusNXDOMAIN(NSECStatus):
def __str__(self):
return 'NSEC record(s) proving the non-existence (NXDOMAIN) of %s' % (fmt.humanize_name(self.qname))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
nsec_list = []
@@ -606,11 +634,25 @@ class NSECStatusNXDOMAIN(NSECStatus):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.nsec_set_info.servers_clients:
for response in self.nsec_set_info.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -669,8 +711,8 @@ class NSECStatusWildcard(NSECStatusNXDOMAIN):
else:
self.nsec_set_info = nsec_set_info.project(*list(nsec_set_info.rrsets))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
- d = super(NSECStatusWildcard, self).serialize(rrset_info_serializer, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
+ d = super(NSECStatusWildcard, self).serialize(rrset_info_serializer, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=map_ip_to_ns_name)
try:
del d['wildcard']
except KeyError:
@@ -797,7 +839,7 @@ class NSECStatusNODATA(NSECStatus):
else:
self.nsec_set_info = nsec_set_info.project(*list(nsec_set_info.rrsets))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
nsec_list = []
@@ -857,11 +899,25 @@ class NSECStatusNODATA(NSECStatus):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.nsec_set_info.servers_clients:
for response in self.nsec_set_info.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -1010,7 +1066,7 @@ class NSEC3StatusNXDOMAIN(NSEC3Status):
for name in self.nsec_set_info.invalid_nsec3_hash:
self.errors.append(Errors.InvalidNSEC3Hash(name=fmt.format_nsec3_name(name), nsec3_hash=lb2s(base32.b32encode(self.nsec_set_info.rrsets[name].rrset[0].next))))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
nsec3_list = []
@@ -1107,11 +1163,25 @@ class NSEC3StatusNXDOMAIN(NSEC3Status):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.nsec_set_info.servers_clients:
for response in self.nsec_set_info.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -1178,8 +1248,8 @@ class NSEC3StatusWildcard(NSEC3StatusNXDOMAIN):
for name in self.nsec_set_info.invalid_nsec3_hash:
self.errors.append(Errors.InvalidNSEC3Hash(name=fmt.format_nsec3_name(name), nsec3_hash=lb2s(base32.b32encode(self.nsec_set_info.rrsets[name].rrset[0].next))))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
- d = super(NSEC3StatusWildcard, self).serialize(rrset_info_serializer, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format)
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
+ d = super(NSEC3StatusWildcard, self).serialize(rrset_info_serializer, consolidate_clients=consolidate_clients, loglevel=loglevel, html_format=html_format, map_ip_to_ns_name=map_ip_to_ns_name)
try:
del d['wildcard']
except KeyError:
@@ -1361,7 +1431,7 @@ class NSEC3StatusNODATA(NSEC3Status):
for name in self.nsec_set_info.invalid_nsec3_hash:
self.errors.append(Errors.InvalidNSEC3Hash(name=fmt.format_nsec3_name(name), nsec3_hash=lb2s(base32.b32encode(self.nsec_set_info.rrsets[name].rrset[0].next))))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
nsec3_list = []
@@ -1457,11 +1527,25 @@ class NSEC3StatusNODATA(NSEC3Status):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.nsec_set_info.servers_clients:
for response in self.nsec_set_info.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -1497,7 +1581,7 @@ class CNAMEFromDNAMEStatus(object):
def __str__(self):
return 'CNAME synthesis for %s from %s/%s' % (fmt.humanize_name(self.synthesized_cname.rrset.name), fmt.humanize_name(self.synthesized_cname.dname_info.rrset.name), dns.rdatatype.to_text(self.synthesized_cname.dname_info.rrset.rdtype))
- def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, rrset_info_serializer=None, consolidate_clients=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
values = []
d = OrderedDict()
@@ -1543,11 +1627,25 @@ class CNAMEFromDNAMEStatus(object):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.synthesized_cname.dname_info.servers_clients:
for response in self.synthesized_cname.dname_info.servers_clients[(server, client)]:
if response is not None:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
diff --git a/dnsviz/response.py b/dnsviz/response.py
index b6c3308..4f456c5 100644
--- a/dnsviz/response.py
+++ b/dnsviz/response.py
@@ -52,7 +52,7 @@ try:
except ImportError:
from cgi import escape
-import dns.flags, dns.message, dns.rcode, dns.rdataclass, dns.rdatatype, dns.rrset
+import dns.edns, dns.flags, dns.message, dns.rcode, dns.rdataclass, dns.rdatatype, dns.rrset
from . import base32
from . import crypto
@@ -209,6 +209,24 @@ class DNSResponse:
s += '_0x20'
return s
+ def nsid_val(self):
+ if self.message is None:
+ return None
+
+ if self.message.edns < 0:
+ return None
+
+ try:
+ nsid_opt = [o for o in self.message.options if o.otype == dns.edns.NSID][0]
+ except IndexError:
+ return None
+
+ try:
+ nsid_val = nsid_opt.data.decode('ascii')
+ except UnicodeDecodeError:
+ nsid_val = '0x' + lb2s(binascii.hexlify(nsid_opt.data))
+ return nsid_val
+
def request_cookie_tag(self):
from . import query as Q
@@ -914,7 +932,7 @@ class DNSKEYMeta(DNSResponseComponent):
return name_wire + rdata_wire + self.rdata.key
- def serialize(self, consolidate_clients=True, show_servers=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, consolidate_clients=True, show_servers=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
from .analysis import status as Status
show_id = loglevel <= logging.INFO or \
@@ -962,10 +980,24 @@ class DNSKEYMeta(DNSResponseComponent):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.servers_clients:
for response in self.servers_clients[(server,client)]:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -1100,7 +1132,7 @@ class RRsetInfo(DNSResponseComponent):
return rrsig_canonicalized_wire + rrset_canonicalized_wire
- def serialize(self, consolidate_clients=True, show_servers=True, loglevel=logging.DEBUG, html_format=False):
+ def serialize(self, consolidate_clients=True, show_servers=True, loglevel=logging.DEBUG, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
if html_format:
@@ -1135,10 +1167,24 @@ class RRsetInfo(DNSResponseComponent):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = set()
for server,client in self.servers_clients:
for response in self.servers_clients[(server,client)]:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.add(nsid)
+
+ if nsids:
+ d['nsid_values'] = list(nsids)
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
diff --git a/dnsviz/viz/dnssec.py b/dnsviz/viz/dnssec.py
index e628c5d..b71cc2f 100644
--- a/dnsviz/viz/dnssec.py
+++ b/dnsviz/viz/dnssec.py
@@ -110,7 +110,7 @@ class RRsetNonExistent(object):
self.nxdomain = nxdomain
self.servers_clients = servers_clients
- def serialize(self, consolidate_clients, html_format=False):
+ def serialize(self, consolidate_clients, html_format=False, map_ip_to_ns_name=None):
d = OrderedDict()
if html_format:
@@ -135,10 +135,24 @@ class RRsetNonExistent(object):
servers.sort()
d['servers'] = servers
+ if map_ip_to_ns_name is not None:
+ ns_names = list(set([lb2s(map_ip_to_ns_name(s)[0][0].canonicalize().to_text()) for s in servers]))
+ ns_names.sort()
+ d['ns_names'] = ns_names
+
tags = set()
+ nsids = []
for server,client in self.servers_clients:
for response in self.servers_clients[(server,client)]:
tags.add(response.effective_query_tag())
+ nsid = response.nsid_val()
+ if nsid is not None:
+ nsids.append(nsid)
+
+ if nsids:
+ d['nsid_values'] = nsids
+ d['nsid_values'].sort()
+
d['query_options'] = list(tags)
d['query_options'].sort()
@@ -385,7 +399,7 @@ class DNSAuthGraph:
self.node_subgraph_name[node_str] = zone_top_name
consolidate_clients = name_obj.single_client()
- dnskey_serialized = dnskey.serialize(consolidate_clients=consolidate_clients, html_format=True)
+ dnskey_serialized = dnskey.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)
all_warnings = []
if rrset_info_with_warnings:
@@ -484,7 +498,7 @@ class DNSAuthGraph:
self.node_subgraph_name[node_str] = parent_top_name
consolidate_clients = zone_obj.single_client()
- ds_serialized = [d.serialize(consolidate_clients=consolidate_clients, html_format=True) for d in ds_statuses]
+ ds_serialized = [d.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=zone_obj.get_ns_name_for_ip) for d in ds_statuses]
digest_algs = []
digests = []
@@ -668,7 +682,7 @@ class DNSAuthGraph:
self.G.add_edge(signed_node, dnskey_node, label=edge_label, id=edge_id, color=line_color, style=line_style, dir='back', **attrs)
consolidate_clients = name_obj.single_client()
- rrsig_serialized = rrsig_status.serialize(consolidate_clients=consolidate_clients, html_format=True)
+ rrsig_serialized = rrsig_status.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)
if edge_id not in self.node_info:
self.node_info[edge_id] = []
@@ -732,7 +746,7 @@ class DNSAuthGraph:
self.node_subgraph_name[node_str] = zone_top_name
consolidate_clients = name_obj.single_client()
- rrset_serialized = rrset_info.serialize(consolidate_clients=consolidate_clients, html_format=True)
+ rrset_serialized = rrset_info.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)
if name_obj.rrset_warnings[rrset_info]:
if 'warnings' not in rrset_serialized:
@@ -804,7 +818,7 @@ class DNSAuthGraph:
rrset_info = RRsetNonExistent(neg_response_info.qname, neg_response_info.rdtype, nxdomain, neg_response_info.servers_clients)
consolidate_clients = name_obj.single_client()
- rrset_serialized = rrset_info.serialize(consolidate_clients=consolidate_clients, html_format=True)
+ rrset_serialized = rrset_info.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)
if warnings_list:
if 'warnings' not in rrset_serialized:
@@ -900,7 +914,7 @@ class DNSAuthGraph:
edge_label = '<<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="%s"/></TD></TR></TABLE>>' % WARNING_ICON
self.G.add_edge(cname_node, dname_node, label=edge_label, id=edge_id, color=line_color, style=line_style, dir='back')
- self.node_info[edge_id] = [dname_status.serialize(html_format=True)]
+ self.node_info[edge_id] = [dname_status.serialize(html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)]
if edge_id not in self.node_mapping:
self.node_mapping[edge_id] = set()
@@ -974,7 +988,7 @@ class DNSAuthGraph:
consolidate_clients = name_obj.single_client()
- nsec_serialized = nsec_status.serialize(consolidate_clients=consolidate_clients, html_format=True)
+ nsec_serialized = nsec_status.serialize(consolidate_clients=consolidate_clients, html_format=True, map_ip_to_ns_name=name_obj.zone.get_ns_name_for_ip)
nsec_serialized_edge = nsec_serialized.copy()
nsec_serialized_edge['description'] = 'Non-existence proof provided by %s' % (nsec_serialized['description'])
diff --git a/share/js/dnsviz.js b/share/js/dnsviz.js
index f5bb6b4..76539fb 100644
--- a/share/js/dnsviz.js
+++ b/share/js/dnsviz.js
@@ -43,6 +43,8 @@ function AuthGraph(anchorElement, maxPaperWidth, imageScale) {
'ttl': 'TTL',
'rrset': 'RRset',
'rdata': 'Record data',
+ 'nsid': 'NSID',
+ 'ns': 'NS',
}
this._dnssec_algorithms = {
1: 'RSA/MD5',
@@ -114,7 +116,7 @@ AuthGraph.prototype.infoToHtmlTableComponents = function (obj) {
}
s += '</ul>';
} else if (typeof val[0] in {'string':null,'number':null}) {
- if (key.toLowerCase() in {'servers':null,'digest_type':null}) {
+ if (key.toLowerCase() in {'servers':null,'nsid_values':null,'ns_names':null,'digest_type':null}) {
s += val.join(", ");
} else {
s += val.join("<br />");