diff --git a/setools/dta.py b/setools/dta.py index f9f3c58..7e5811c 100644 --- a/setools/dta.py +++ b/setools/dta.py @@ -20,6 +20,7 @@ except ImportError: from .descriptors import EdgeAttrDict, EdgeAttrList from .mixins import NetworkXGraphEdge from .policyrep import AnyTERule, SELinuxPolicy, TERuletype, Type +from .query import DirectedGraphAnalysis __all__ = ['DomainTransitionAnalysis', 'DomainTransition', 'DomainEntrypoint', 'DTAPath'] @@ -56,7 +57,7 @@ DTAPath = Iterable[DomainTransition] RuleHash = DefaultDict[Type, List[AnyTERule]] -class DomainTransitionAnalysis: +class DomainTransitionAnalysis(DirectedGraphAnalysis): """Domain transition analysis.""" diff --git a/setools/infoflow.py b/setools/infoflow.py index 6fadba5..b358597 100644 --- a/setools/infoflow.py +++ b/setools/infoflow.py @@ -18,13 +18,14 @@ from .descriptors import EdgeAttrIntMax, EdgeAttrList from .mixins import NetworkXGraphEdge from .permmap import PermissionMap from .policyrep import AVRule, SELinuxPolicy, TERuletype, Type +from .query import DirectedGraphAnalysis __all__ = ['InfoFlowAnalysis'] InfoFlowPath = Iterable['InfoFlowStep'] -class InfoFlowAnalysis: +class InfoFlowAnalysis(DirectedGraphAnalysis): """Information flow analysis.""" diff --git a/setools/query.py b/setools/query.py index bed4653..f7da641 100644 --- a/setools/query.py +++ b/setools/query.py @@ -4,21 +4,24 @@ # SPDX-License-Identifier: LGPL-2.1-only # from abc import ABC, abstractmethod -from logging import Logger -from typing import Iterable +from typing import TYPE_CHECKING -from .policyrep import SELinuxPolicy +if TYPE_CHECKING: + from logging import Logger + from typing import Iterable + from networkx import DiGraph + from .policyrep import SELinuxPolicy class PolicyQuery(ABC): - """Abstract base class for SELinux policy queries.""" + """Abstract base class for all SELinux policy analyses.""" - log: Logger - policy: SELinuxPolicy + log: "Logger" + policy: "SELinuxPolicy" - def __init__(self, policy: SELinuxPolicy, **kwargs) -> None: - self.policy = policy + def __init__(self, policy: "SELinuxPolicy", **kwargs) -> None: + self.policy: "SELinuxPolicy" = policy # keys are sorted in reverse order so regex settings # are set before the criteria, e.g. name_regex @@ -33,9 +36,16 @@ class PolicyQuery(ABC): setattr(self, name, kwargs[name]) @abstractmethod - def results(self) -> Iterable: + def results(self) -> "Iterable": """ Generator which returns the matches for the query. This method should be overridden by subclasses. """ pass + + +class DirectedGraphAnalysis(PolicyQuery): + + """Abstract base class for graph-basded SELinux policy analysis.""" + + G: "DiGraph"