diff options
author | Casey Deccio <casey@deccio.net> | 2019-02-05 07:31:49 +0300 |
---|---|---|
committer | Casey Deccio <casey@deccio.net> | 2019-02-07 02:28:21 +0300 |
commit | 6d7d9ba9a86e7c049895a6cd6f177a97104dc342 (patch) | |
tree | 78105bbd87e08f8a89374b1ee0fd6e45941e116d | |
parent | 7782fe4e4660d0e1f8bb9ac58c03468b71fb0b61 (diff) |
Avoid infinite loops when graphing CNAME chains
Fix CNAME loop
-rw-r--r-- | dnsviz/analysis/offline.py | 12 | ||||
-rw-r--r-- | dnsviz/viz/dnssec.py | 13 |
2 files changed, 19 insertions, 6 deletions
diff --git a/dnsviz/analysis/offline.py b/dnsviz/analysis/offline.py index b90d33b..9937066 100644 --- a/dnsviz/analysis/offline.py +++ b/dnsviz/analysis/offline.py @@ -230,12 +230,20 @@ class OfflineDomainNameAnalysis(OnlineDomainNameAnalysis): return active_ksks return self.ksks.difference(self.revoked_keys) - def _create_response_info_recursive(self, name, rdtype, name_to_info_mapping, rrset_to_cname_mapping): + def _create_response_info_recursive(self, name, rdtype, name_to_info_mapping, rrset_to_cname_mapping, trace=None): zone_obj = self.get_name(name).zone info_obj = AggregateResponseInfo(name, rdtype, self, zone_obj) + + if trace is None: + trace = [name] + for info in name_to_info_mapping[name]: if info in rrset_to_cname_mapping: - cname_info = self._create_response_info_recursive(rrset_to_cname_mapping[info], rdtype, name_to_info_mapping, rrset_to_cname_mapping) + target = info.rrset[0].target + if target not in trace: + cname_info = self._create_response_info_recursive(rrset_to_cname_mapping[info], rdtype, name_to_info_mapping, rrset_to_cname_mapping, trace=trace + [target]) + else: + cname_info = None else: cname_info = None info_obj.add_response_info(info, cname_info) diff --git a/dnsviz/viz/dnssec.py b/dnsviz/viz/dnssec.py index 73fb532..022dbe3 100644 --- a/dnsviz/viz/dnssec.py +++ b/dnsviz/viz/dnssec.py @@ -1071,7 +1071,7 @@ class DNSAuthGraph: rrsig_status = name_obj.rrsig_status[rrset_info][rrsig][dnskey] self.add_rrsig(rrsig_status, name_obj, signer_obj, signed_node, port=port) - def graph_rrset_auth(self, name_obj, name, rdtype): + def graph_rrset_auth(self, name_obj, name, rdtype, trace=None): if (name, rdtype) not in self.processed_rrsets: self.processed_rrsets[(name, rdtype)] = [] @@ -1100,14 +1100,19 @@ class DNSAuthGraph: if name_obj.is_zone() and rdtype in (dns.rdatatype.DNSKEY, dns.rdatatype.DS): return [] + # trace is used just for CNAME chains + if trace is None: + trace = [name] + cname_nodes = [] - # if this name is a alias, then graph the CNAME, unless this is a - # recursive analysis + # if this name is an alias, then graph its target, i.e., the canonical + # name, unless this is a recursive analysis. if name_obj.analysis_type != ANALYSIS_TYPE_RECURSIVE: if name in name_obj.cname_targets: for target, cname_obj in name_obj.cname_targets[name].items(): if cname_obj is not None: - cname_nodes.extend(self.graph_rrset_auth(cname_obj, target, rdtype)) + if target not in trace: + cname_nodes.extend(self.graph_rrset_auth(cname_obj, target, rdtype, trace + [target])) query = name_obj.queries[(name, rdtype)] node_to_cname_mapping = set() |