Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions setools/boolquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def default(self, value) -> None:
else:
self._default = bool(value)

def _build_repr_args(self) -> list[str]:
return [f"default={self.default!r}"] + self._build_name_repr_args()

def results(self) -> Iterable[policyrep.Boolean]:
"""Generator which yields all Booleans matching the criteria."""
self.log.info(f"Generating Boolean results from {self.policy}")
Expand Down
5 changes: 5 additions & 0 deletions setools/boundsquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class BoundsQuery(query.PolicyQuery):
child = CriteriaDescriptor[policyrep.Type]("child_regex")
child_regex: bool = False

def _build_repr_args(self) -> list[str]:
return [f"ruletype={self.ruletype!r}", f"parent={self.parent!r}",
f"parent_regex={self.parent_regex!r}", f"child={self.child!r}",
f"child_regex={self.child_regex!r}"]

def results(self) -> Iterable[policyrep.Bounds]:
"""Generator which yields all matching *bounds statements."""
self.log.info(f"Generating bounds results from {self.policy}")
Expand Down
3 changes: 3 additions & 0 deletions setools/categoryquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class CategoryQuery(mixins.MatchAlias, mixins.MatchName, query.PolicyQuery):
will be used on the alias names.
"""

def _build_repr_args(self) -> list[str]:
return self._build_name_repr_args() + self._build_alias_repr_args()

def results(self) -> Iterable[policyrep.Category]:
"""Generator which yields all matching categories."""
self.log.info(f"Generating category results from {self.policy}")
Expand Down
5 changes: 5 additions & 0 deletions setools/checker/assertrbac.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ def __init__(self, policy: policyrep.SELinuxPolicy, checkname: str,
self.log.info("Overlap in expect_target and exempt_target: "
f"{', '.join(i.name for i in target_exempt_expect_overlap)}")

def __repr__(self) -> str:
return (f"{self.__class__.__name__}(source={self.source}, target={self.target}, "
f"exempt_source={self.exempt_source}, exempt_target={self.exempt_target}, "
f"expect_source={self.expect_source}, expect_target={self.expect_target})")

def run(self) -> list[policyrep.AnyRBACRule | str]:
assert any((self.source, self.target)), "AssertRBAC no options set, this is a bug."

Expand Down
6 changes: 6 additions & 0 deletions setools/checker/assertte.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ def __init__(self, policy: policyrep.SELinuxPolicy, checkname: str,
self.log.info("Overlap in expect_target and exempt_target: "
f"{', '.join(i.name for i in target_exempt_expect_overlap)}")

def __repr__(self) -> str:
return (f"{self.__class__.__name__}(source={self.source}, target={self.target}, "
f"tclass={self.tclass}, perms={self.perms}, "
f"exempt_source={self.exempt_source}, exempt_target={self.exempt_target}, "
f"expect_source={self.expect_source}, expect_target={self.expect_target})")

def run(self) -> list[policyrep.AnyTERule | str]:
assert any((self.source, self.target, self.tclass, self.perms)), \
"AssertTe no options set, this is a bug."
Expand Down
3 changes: 3 additions & 0 deletions setools/checker/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ def config(self, configpath: str) -> None:
self.checks = checks
self._config = config

def __repr__(self) -> str:
return f"<{self.__class__.__name__}({self.policy!r}, {self.config!r})>"

def run(self, output: typing.TextIO = sys.stdout) -> int:
"""Run all configured checks and print report to the file-like output."""
failures = 0
Expand Down
3 changes: 3 additions & 0 deletions setools/checker/emptyattr.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def missing_ok(self, value) -> None:
else:
self._pass_by_missing = False

def __repr__(self) -> str:
return (f"{self.__class__.__name__}(attr={self.attr}, missing_ok={self.missing_ok})")

def run(self) -> list[policyrep.Type]:
self.log.info(f"Checking type attribute {self.attr} is empty.")

Expand Down
4 changes: 4 additions & 0 deletions setools/checker/roexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __init__(self, policy: policyrep.SELinuxPolicy, checkname: str,
self.exempt_file = config.get(EXEMPT_FILE)
self.exempt_exec_domain = config.get(EXEMPT_EXEC)

def __repr__(self) -> str:
return (f"{self.__class__.__name__}(exempt_write_domain={self.exempt_write_domain}, "
f"exempt_exec_domain={self.exempt_exec_domain}, exempt_file={self.exempt_file})")

def _collect_executables(self) -> defaultdict[policyrep.Type, set[policyrep.AVRule]]:
self.log.debug("Collecting list of executable file types.")
self.log.debug(f"{self.exempt_exec_domain=}")
Expand Down
4 changes: 4 additions & 0 deletions setools/checker/rokmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __init__(self, policy: policyrep.SELinuxPolicy, checkname: str,
self.exempt_file = config.get(EXEMPT_FILE)
self.exempt_load_domain = config.get(EXEMPT_LOAD)

def __repr__(self) -> str:
return (f"{self.__class__.__name__}(exempt_write_domain={self.exempt_write_domain}, "
f"exempt_load_domain={self.exempt_load_domain}, exempt_file={self.exempt_file})")

def _collect_kernel_mods(self) -> defaultdict[policyrep.Type, set[policyrep.AVRule]]:
self.log.debug("Collecting list of kernel module types.")
self.log.debug(f"{self.exempt_load_domain=}")
Expand Down
3 changes: 3 additions & 0 deletions setools/commonquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class CommonQuery(mixins.MatchPermission, mixins.MatchName, query.PolicyQuery):
on the permission names instead of set logic.
"""

def _build_repr_args(self) -> list[str]:
return self._build_name_repr_args() + self._build_perms_repr_args()

def results(self) -> Iterable[policyrep.Common]:
"""Generator which yields all matching commons."""
self.log.info(f"Generating common results from {self.policy}")
Expand Down
8 changes: 8 additions & 0 deletions setools/constraintquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, query.Policy
type_regex: bool = False
type_indirect: bool = True

def _build_repr_args(self) -> list[str]:
return [f"user={self.user!r}", f"user_regex={self.user_regex!r}", f"role={self.role!r}",
f"role_regex={self.role_regex!r}", f"role_indirect={self.role_indirect!r}",
f"type_={self.type_!r}", f"type_regex={self.type_regex!r}",
f"type_indirect={self.type_indirect!r}"] \
+ self._build_object_class_repr_args() \
+ self._build_perms_repr_args()

def _match_expr(self, expr: frozenset[policyrep.User] | frozenset[policyrep.Role] |
frozenset[policyrep.Type], criteria, indirect: bool, regex: bool) -> bool:
"""
Expand Down
5 changes: 5 additions & 0 deletions setools/defaultquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class DefaultQuery(mixins.MatchObjClass, query.PolicyQuery):
default_range = CriteriaDescriptor[policyrep.DefaultRangeValue](
enum_class=policyrep.DefaultRangeValue)

def _build_repr_args(self) -> list[str]:
return [f"ruletype={self.ruletype!r}", f"default={self.default!r}",
f"default_range={self.default_range!r}"] \
+ self._build_object_class_repr_args()

def results(self) -> Iterable[policyrep.AnyDefault]:
"""Generator which yields all matching default_* statements."""
self.log.info(f"Generating default_* results from {self.policy}")
Expand Down
3 changes: 3 additions & 0 deletions setools/devicetreeconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class DevicetreeconQuery(mixins.MatchContext, query.PolicyQuery):

path: str | None = None

def _build_repr_args(self) -> list[str]:
return [f"path={self.path!r}"] + self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Devicetreecon]:
"""Generator which yields all matching devicetreecons."""
self.log.info(f"Generating results from {self.policy}")
Expand Down
3 changes: 3 additions & 0 deletions setools/diff/difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def right_policy(self, policy):
#
# Internal functions
#
def __repr__(self) -> str:
return f"<{self.__class__.__name__}({self.left_policy!r}, {self.right_policy!r})>"

def _reset_diff(self) -> None:
"""Reset diff results on policy changes."""
raise NotImplementedError
Expand Down
5 changes: 5 additions & 0 deletions setools/dta.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ def exclude(self, types: Iterable[policyrep.Type | str] | None) -> None:

self.rebuildsubgraph = True

def _build_repr_args(self) -> list[str]:
return [f"source={self.source!r}", f"target={self.target!r}",
f"mode={self.mode!r}", f"depth_limit={self.depth_limit!r}",
f"exclude={self.exclude!r}", f"reverse={self.reverse!r}"]

def results(self) -> Iterable[DTAPath] | Iterable[DomainTransition]:
if self.rebuildsubgraph:
self._build_subgraph()
Expand Down
4 changes: 4 additions & 0 deletions setools/fsusequery.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class FSUseQuery(mixins.MatchContext, query.PolicyQuery):
fs = CriteriaDescriptor[str]("fs_regex")
fs_regex: bool = False

def _build_repr_args(self) -> list[str]:
return [f"ruletype={self.ruletype!r}", f"fs={self.fs!r}", f"fs_regex={self.fs_regex!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.FSUse]:
"""Generator which yields all matching fs_use_* statements."""
self.log.info(f"Generating fs_use_* results from {self.policy}")
Expand Down
5 changes: 5 additions & 0 deletions setools/genfsconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class GenfsconQuery(mixins.MatchContext, query.PolicyQuery):
path = CriteriaDescriptor[str]("path_regex")
path_regex: bool = False

def _build_repr_args(self) -> list[str]:
return [f"fs={self.fs!r}", f"fs_regex={self.fs_regex!r}", f"path={self.path!r}",
f"path_regex={self.path_regex!r}", f"filetype={self.filetype!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Genfscon]:
"""Generator which yields all matching genfscons."""
self.log.info(f"Generating genfscon results from {self.policy}")
Expand Down
4 changes: 4 additions & 0 deletions setools/ibendportconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def port(self, value: int | None) -> None:
else:
self._port = None

def _build_repr_args(self) -> list[str]:
return [f"port={self.port!r}"] + self._build_name_repr_args() \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Ibendportcon]:
"""Generator which yields all matching ibendportcons."""
self.log.info(f"Generating ibendportcon results from {self.policy}")
Expand Down
6 changes: 6 additions & 0 deletions setools/ibpkeyconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ def subnet_prefix(self, value: str | IPv6Address | None) -> None:
else:
self._subnet_prefix = None

def _build_repr_args(self) -> list[str]:
return [f"subnet_prefix={self.subnet_prefix!r}", f"pkeys={self.pkeys!r}",
f"pkeys_subset={self.pkeys_subset!r}", f"pkeys_overlap={self.pkeys_overlap!r}",
f"pkeys_superset={self.pkeys_superset!r}", f"pkeys_proper={self.pkeys_proper!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Ibpkeycon]:
"""Generator which yields all matching ibpkeycons."""
self.log.info(f"Generating ibpkeycon results from {self.policy}")
Expand Down
6 changes: 6 additions & 0 deletions setools/infoflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ def exclude(self, types: Iterable[policyrep.Type | str] | None) -> None:

self.rebuildsubgraph = True

def _build_repr_args(self) -> list[str]:
return [repr(self.perm_map),
f"source={self.source!r}", f"target={self.target!r}", f"mode={self.mode!r}",
f"min_weight={self.min_weight!r}", f"exclude={self.exclude!r}",
f"booleans={self.booleans!r}", f"depth_limit={self.depth_limit!r}"]

def results(self) -> Iterable[InfoFlowPath] | Iterable["InfoFlowStep"]:
if self.rebuildsubgraph:
self._build_subgraph()
Expand Down
3 changes: 3 additions & 0 deletions setools/initsidquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class InitialSIDQuery(mixins.MatchName, mixins.MatchContext, query.PolicyQuery):

required_platform = policyrep.PolicyTarget.selinux

def _build_repr_args(self) -> list[str]:
return self._build_name_repr_args() + self._build_context_repr_args()

def results(self) -> Iterable[policyrep.InitialSID]:
"""Generator which yields all matching initial SIDs."""
self.log.info(f"Generating initial SID results from {self.policy}")
Expand Down
6 changes: 6 additions & 0 deletions setools/iomemconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def addr(self, value: policyrep.IomemconRange | tuple[int, int] | None) -> None:
else:
self._addr = policyrep.IomemconRange(*value) if value else None

def _build_repr_args(self) -> list[str]:
return [f"addr={self.addr!r}", f"addr_subset={self.addr_subset!r}",
f"addr_overlap={self.addr_overlap!r}", f"addr_superset={self.addr_superset!r}",
f"addr_proper={self.addr_proper!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Iomemcon]:
"""Generator which yields all matching iomemcons."""
self.log.info(f"Generating results from {self.policy}")
Expand Down
6 changes: 6 additions & 0 deletions setools/ioportconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def ports(self, value: policyrep.IoportconRange | tuple[int, int] | None) -> Non
else:
self._ports = policyrep.IoportconRange(*value) if value else None

def _build_repr_args(self) -> list[str]:
return [f"ports={self.ports!r}", f"ports_subset={self.ports_subset!r}",
f"ports_overlap={self.ports_overlap!r}", f"ports_superset={self.ports_superset!r}",
f"ports_proper={self.ports_proper!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Ioportcon]:
"""Generator which yields all matching ioportcons."""
self.log.info(f"Generating results from {self.policy}")
Expand Down
24 changes: 24 additions & 0 deletions setools/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
# pylint: disable=attribute-defined-outside-init,no-member
from logging import Logger
import re
from typing import Any

from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, CriteriaPermissionSetDescriptor
Expand All @@ -18,6 +19,9 @@ class MatchAlias:
alias = CriteriaDescriptor[str]("alias_regex")
alias_regex: bool = False

def _build_alias_repr_args(self) -> list[str]:
return [f"alias={self.alias!r}", f"alias_regex={self.alias_regex!r}"]

def _match_alias_debug(self, log: Logger) -> None:
"""Emit log debugging info for alias matching."""
log.debug(f"{self.alias=}, {self.alias_regex=}")
Expand Down Expand Up @@ -76,6 +80,14 @@ class MatchContext:
range_superset: bool = False
range_proper: bool = False

def _build_context_repr_args(self) -> list[str]:
return [f"user={self.user!r}", f"user_regex={self.user_regex!r}",
f"role={self.role!r}", f"role_regex={self.role_regex!r}",
f"type_={self.type_!r}", f"type_regex={self.type_regex!r}",
f"range_={self.range_!r}", f"range_subset={self.range_subset!r}",
f"range_overlap={self.range_overlap!r}", f"range_superset={self.range_superset!r}",
f"range_proper={self.range_proper!r}"]

def _match_context_debug(self, log: Logger):
"""Emit log debugging info for context matching."""
log.debug(f"{self.user=}, {self.user_regex=}")
Expand Down Expand Up @@ -131,6 +143,10 @@ class MatchName:
name_regex: bool = False
alias_deref: bool = False

def _build_name_repr_args(self) -> list[str]:
return [f"name={self.name!r}", f"name_regex={self.name_regex!r}",
f"alias_deref={self.alias_deref!r}"]

def _match_name_debug(self, log: Logger) -> None:
"""Log debugging messages for name matching."""
log.debug(f"{self.name=}, {self.name_regex=}, {self.alias_deref=}")
Expand All @@ -155,6 +171,9 @@ class MatchObjClass:
tclass = CriteriaSetDescriptor[policyrep.ObjClass]("tclass_regex", "lookup_class")
tclass_regex: bool = False

def _build_object_class_repr_args(self) -> list[str]:
return [f"tclass={self.tclass!r}", f"tclass_regex={self.tclass_regex!r}"]

def _match_object_class_debug(self, log: Logger) -> None:
"""Emit log debugging info for permission matching."""
log.debug(f"{self.tclass=}, {self.tclass_regex=}")
Expand All @@ -171,6 +190,7 @@ def _match_object_class(self, obj):
# if there is no criteria, everything matches.
return True
elif self.tclass_regex:
assert isinstance(self.tclass, re.Pattern)
return bool(self.tclass.search(str(obj.tclass)))
else:
return obj.tclass in self.tclass
Expand All @@ -185,6 +205,10 @@ class MatchPermission:
perms_regex: bool = False
perms_subset: bool = False

def _build_perms_repr_args(self) -> list[str]:
return [f"perms={self.perms!r}", f"perms_equal={self.perms_equal!r}",
f"perms_regex={self.perms_regex!r}", f"perms_subset={self.perms_subset!r}"]

def _match_perms_debug(self, log: Logger):
"""Emit log debugging info for permission matching."""
log.debug(f"{self.perms=}, {self.perms_regex=}, {self.perms_equal=}, "
Expand Down
11 changes: 11 additions & 0 deletions setools/mlsrulequery.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
default_superset: bool = False
default_proper: bool = False

def _build_repr_args(self) -> list[str]:
return [f"ruletype={self.ruletype!r}", f"source={self.source!r}",
f"source_regex={self.source_regex!r}", f"source_indirect={self.source_indirect!r}",
f"target={self.target!r}", f"target_regex={self.target_regex!r}",
f"target_indirect={self.target_indirect!r}", f"default={self.default!r}",
f"default_overlap={self.default_overlap!r}",
f"default_subset={self.default_subset!r}",
f"default_superset={self.default_superset!r}",
f"default_proper={self.default_proper!r}"] \
+ self._build_object_class_repr_args()

def results(self) -> Iterable[policyrep.MLSRule]:
"""Generator which yields all matching MLS rules."""
self.log.info(f"Generating MLS rule results from {self.policy}")
Expand Down
3 changes: 3 additions & 0 deletions setools/netifconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class NetifconQuery(mixins.MatchContext, mixins.MatchName, query.PolicyQuery):

required_platform = policyrep.PolicyTarget.selinux

def _build_repr_args(self) -> list[str]:
return self._build_name_repr_args() + self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Netifcon]:
"""Generator which yields all matching netifcons."""
self.log.info(f"Generating netifcon results from {self.policy}")
Expand Down
5 changes: 5 additions & 0 deletions setools/nodeconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ def network(self, value: AnyIPNetwork | str | None) -> None:
else:
self._network = None

def _build_repr_args(self) -> list[str]:
return [f"network={self.network!r}", f"network_overlap={self.network_overlap!r}",
f"ip_version={self.ip_version!r}"] \
+ self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Nodecon]:
"""Generator which yields all matching nodecons."""
self.log.info(f"Generating nodecon results from {self.policy}")
Expand Down
5 changes: 5 additions & 0 deletions setools/objclassquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class ObjClassQuery(mixins.MatchName, query.PolicyQuery):
perms_indirect: bool = True
perms_regex: bool = False

def _build_repr_args(self) -> list[str]:
return [f"{self.common=}", f"{self.common_regex=}", f"{self.perms=}",
f"{self.perms_equal=}", f"{self.perms_indirect=}", f"{self.perms_regex=}"] \
+ self._build_name_repr_args()

def results(self) -> Iterable[policyrep.ObjClass]:
"""Generator which yields all matching object classes."""
self.log.info(f"Generating object class results from {self.policy}")
Expand Down
3 changes: 3 additions & 0 deletions setools/pcideviceconquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def device(self, value: int | None) -> None:
else:
self._device = None

def _build_repr_args(self) -> list[str]:
return [f"device={self.device!r}"] + self._build_context_repr_args()

def results(self) -> Iterable[policyrep.Pcidevicecon]:
"""Generator which yields all matching pcidevicecons."""
self.log.info(f"Generating results from {self.policy}")
Expand Down
Loading