diff --git a/setools/diff/difference.py b/setools/diff/difference.py index fabec63c..c67477a0 100644 --- a/setools/diff/difference.py +++ b/setools/diff/difference.py @@ -7,7 +7,6 @@ from abc import ABC, abstractmethod from typing import Generic, Iterable, TypeVar -from ..mixins import TupleCompat from ..policyrep import PolicyObject, PolicySymbol, SELinuxPolicy @@ -118,7 +117,7 @@ def _set_diff(left, right, key=None, unwrap=True): return added_items, removed_items, matched_items -class DifferenceResult(TupleCompat): +class DifferenceResult: """Base class for difference results""" diff --git a/setools/dta.py b/setools/dta.py index 5ce50f44..3fa6c0d9 100644 --- a/setools/dta.py +++ b/setools/dta.py @@ -11,7 +11,6 @@ from contextlib import suppress from dataclasses import dataclass, InitVar import typing -import warnings try: import networkx as nx @@ -355,151 +354,6 @@ def graphical_results(self) -> nx.DiGraph: raise exception.AnalysisException( f"Unable to generate graphical results: {ex}") from ex - def shortest_path(self, source: Type | str, target: Type | str) -> DTAPath: - """ - Generator which yields one shortest domain transition path - between the source and target types (there may be more). - - Parameters: - source The source type. - target The target type. - - Yield: generator(steps) - - steps A generator that returns the tuple of - source, target, and rules for each - domain transition. - """ - warnings.warn("DomainTransitionAnalysis.shortest_path() is deprecated. " - "It will be removed in SETools 4.6.") - s: Type = self.policy.lookup_type(source) - t: Type = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info(f"Generating one domain transition path from {s} to {t}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. excluded - # NetworkXNoPath: no paths or the target type is - # not in the graph - # pylint: disable=unexpected-keyword-arg, no-value-for-parameter - yield from self._generate_steps(nx.shortest_path(self.subG, source=s, target=t)) - - def all_paths(self, source: Type | str, target: Type | str, maxlen: int = 2) \ - -> Iterable[DTAPath]: - """ - Generator which yields all domain transition paths between - the source and target up to the specified maximum path - length. - - Parameters: - source The source type. - target The target type. - maxlen Maximum length of paths. - - Yield: generator(steps) - - steps A generator that returns the tuple of - source, target, and rules for each - domain transition. - """ - warnings.warn("DomainTransitionAnalysis.all_paths() is deprecated. " - "It will be removed in SETools 4.6.") - if maxlen < 1: - raise ValueError("Maximum path length must be positive.") - - s: Type = self.policy.lookup_type(source) - t: Type = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info( - f"Generating all domain transition paths from {s} to {t}, max length {maxlen}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. excluded - # NetworkXNoPath: no paths or the target type is - # not in the graph - for path in nx.all_simple_paths(self.subG, s, t, maxlen): - yield self._generate_steps(path) - - def all_shortest_paths(self, source: Type | str, target: Type | str) -> Iterable[DTAPath]: - """ - Generator which yields all shortest domain transition paths - between the source and target types. - - Parameters: - source The source type. - target The target type. - - Yield: generator(steps) - - steps A generator that returns the tuple of - source, target, and rules for each - domain transition. - """ - warnings.warn("DomainTransitionAnalysis.all_shortest_paths() is deprecated. " - "It will be removed in SETools 4.6.") - s: Type = self.policy.lookup_type(source) - t: Type = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info(f"Generating all shortest domain transition paths from {s} to {t}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. excluded - # NetworkXNoPath: no paths or the target type is - # not in the graph - for path in nx.all_shortest_paths(self.subG, s, t): - yield self._generate_steps(path) - - def transitions(self, type_: Type | str) -> DTAPath: - """ - Generator which yields all domain transitions out of a - specified source type. - - Parameters: - type_ The starting type. - - Yield: generator(steps) - - steps A generator that returns the tuple of - source, target, and rules for each - domain transition. - """ - warnings.warn("DomainTransitionAnalysis.transitions() is deprecated. " - "It will be removed in SETools 4.6.") - s: Type = self.policy.lookup_type(type_) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info( - f"Generating all domain transitions {'in to' if self.reverse else 'out from'} {s}") - - with suppress(NetworkXError): - # NetworkXError: the type is valid but not in graph, e.g. excluded - for source, target in self.subG.out_edges(s): - edge = Edge(self.subG, source, target) - - if self.reverse: - real_source, real_target = target, source - else: - real_source, real_target = source, target - - yield DomainTransition(real_source, - real_target, - edge.transition, - self._generate_entrypoints(edge), - edge.setexec, - edge.dyntransition, - edge.setcurrent) - def get_stats(self) -> str: # pragma: no cover """ Get the domain transition graph statistics. diff --git a/setools/infoflow.py b/setools/infoflow.py index 0d48bbed..ab00a6e4 100644 --- a/setools/infoflow.py +++ b/setools/infoflow.py @@ -9,7 +9,6 @@ from contextlib import suppress from dataclasses import dataclass, InitVar import typing -import warnings try: import networkx as nx @@ -283,159 +282,6 @@ def graphical_results(self) -> nx.DiGraph: raise exception.AnalysisException( f"Unable to generate graphical results: {ex}") from ex - def shortest_path(self, source: Type | str, target: Type | str) -> InfoFlowPath: - """ - Generator which yields one shortest path between the source - and target types (there may be more). - - Parameters: - source The source type. - target The target type. - - Yield: generator(steps) - - steps Yield: tuple(source, target, rules) - - source The source type for this step of the information flow. - target The target type for this step of the information flow. - rules The list of rules creating this information flow step. - """ - warnings.warn("InfoFlowAnalysis.shortest_path() is deprecated. " - "It will be removed in SETools 4.6.") - s = self.policy.lookup_type(source) - t = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info(f"Generating one shortest information flow path from {s} to {t}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. - # excluded or disconnected due to min weight - # NetworkXNoPath: no paths or the target type is - # not in the graph - # pylint: disable=unexpected-keyword-arg, no-value-for-parameter - yield from self._generate_steps(nx.shortest_path(self.subG, source=s, target=t)) - - def all_paths(self, source: Type | str, target: Type | str, maxlen: int = 2) \ - -> Iterable[InfoFlowPath]: - """ - Generator which yields all paths between the source and target - up to the specified maximum path length. This algorithm - tends to get very expensive above 3-5 steps, depending - on the policy complexity. - - Parameters: - source The source type. - target The target type. - maxlen Maximum length of paths. - - Yield: generator(steps) - - steps Yield: tuple(source, target, rules) - - source The source type for this step of the information flow. - target The target type for this step of the information flow. - rules The list of rules creating this information flow step. - """ - warnings.warn("InfoFlowAnalysis.all_paths() is deprecated, replaced with the results() " - "method. It will be removed in SETools 4.6.") - if maxlen < 1: - raise ValueError("Maximum path length must be positive.") - - s = self.policy.lookup_type(source) - t = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info( - f"Generating all information flow paths from {s} to {t}, max length {maxlen}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. - # excluded or disconnected due to min weight - # NetworkXNoPath: no paths or the target type is - # not in the graph - for path in nx.all_simple_paths(self.subG, s, t, maxlen): - yield self._generate_steps(path) - - def all_shortest_paths(self, source: Type | str, target: Type | str) -> Iterable[InfoFlowPath]: - """ - Generator which yields all shortest paths between the source - and target types. - - Parameters: - source The source type. - target The target type. - - Yield: generator(steps) - - steps Yield: tuple(source, target, rules) - - source The source type for this step of the information flow. - target The target type for this step of the information flow. - rules The list of rules creating this information flow step. - """ - warnings.warn("InfoFlowAnalysis.all_shorted_paths() is deprecated, replaced with the " - "results() method. It will be removed in SETools 4.6.") - s = self.policy.lookup_type(source) - t = self.policy.lookup_type(target) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info(f"Generating all shortest information flow paths from {s} to {t}...") - - with suppress(NetworkXNoPath, NodeNotFound): - # NodeNotFound: the type is valid but not in graph, e.g. - # excluded or disconnected due to min weight - # NetworkXNoPath: no paths or the target type is - # not in the graph - for path in nx.all_shortest_paths(self.subG, s, t): - yield self._generate_steps(path) - - def infoflows(self, type_: Type | str, out: bool = True) -> Iterable['InfoFlowStep']: - """ - Generator which yields all information flows in/out of a - specified source type. - - Parameters: - source The starting type. - - Keyword Parameters: - out If true, information flows out of the type will - be returned. If false, information flows in to the - type will be returned. Default is true. - - Yield: generator(steps) - - steps A generator that returns the tuple of - source, target, and rules for each - information flow. - """ - warnings.warn("InfoFlowAnalysis.infoflows() is deprecated, replaced with the results() " - "method. It will be removed in SETools 4.6.") - s = self.policy.lookup_type(type_) - - if self.rebuildsubgraph: - self._build_subgraph() - - self.log.info(f"Generating all information flows {'out of' if out else 'into'} {s}") - - with suppress(NetworkXError): - # NetworkXError: the type is valid but not in graph, e.g. - # excluded or disconnected due to min weight - - if out: - flows = self.subG.out_edges(s) - else: - flows = self.subG.in_edges(s) - - for source, target in flows: - yield InfoFlowStep(self.subG, source, target) - def get_stats(self) -> str: # pragma: no cover """ Get the information flow graph statistics. diff --git a/setools/mixins.py b/setools/mixins.py index 57fe15bd..013008d9 100644 --- a/setools/mixins.py +++ b/setools/mixins.py @@ -234,23 +234,3 @@ def _index_to_item(self, index: int): return self.target else: raise IndexError(f"Invalid index (NetworkXGraphEdge only has 2 items): {index}") - - -class TupleCompat: - - """Mixin for named tuple backwards compatibility for dataclasses.""" - - def __getitem__(self, key): - warnings.warn("Named tuple returns are deprecated, replaced with dataclasses.", - DeprecationWarning) - return astuple(self)[key] - - def __iter__(self): - warnings.warn("Named tuple returns are deprecated, replaced with dataclasses.", - DeprecationWarning) - return iter(astuple(self)) - - def __len__(self): - warnings.warn("Named tuple returns are deprecated, replaced with dataclasses.", - DeprecationWarning) - return len(astuple(self)) diff --git a/setools/permmap.py b/setools/permmap.py index f44145f0..c42be04c 100644 --- a/setools/permmap.py +++ b/setools/permmap.py @@ -13,7 +13,6 @@ from . import exception from .descriptors import PermissionMapDescriptor -from .mixins import TupleCompat from .policyrep import AVRule, SELinuxPolicy, TERuletype # This is the filename in the Python package @@ -25,7 +24,7 @@ @dataclass -class RuleWeight(TupleCompat): +class RuleWeight: """The read and write weights for a rule, given all of its permissions."""