Skip to content

Commit

Permalink
Merge pull request #123 from pebenito/deep-clean
Browse files Browse the repository at this point in the history
Clean up technical debt
  • Loading branch information
pebenito authored Apr 2, 2024
2 parents 6ca6ab7 + 8cb28fc commit 4c205e4
Show file tree
Hide file tree
Showing 105 changed files with 2,851 additions and 2,790 deletions.
2 changes: 1 addition & 1 deletion sechecker
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ try:
c = setools.PolicyChecker(p, args.config)

if args.output_file:
with open(args.output_file, "w") as fd:
with open(args.output_file, "w", encoding="utf-8") as fd:
failures = c.run(output=fd)

else:
Expand Down
1,513 changes: 754 additions & 759 deletions sediff

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions seinfo
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def expand_attr(attr):
"""Render type and role attributes."""
items = "\n\t".join(sorted(str(i) for i in attr.expand()))
contents = items if items else "<empty attribute>"
return "{0}\n\t{1}".format(attr.statement(), contents)
return f"{attr.statement()}\n\t{contents}"


signal.signal(signal.SIGPIPE, signal.SIG_DFL)
Expand Down Expand Up @@ -332,10 +332,11 @@ try:
if (not components or args.all) and not args.flat:
mls = "enabled" if p.mls else "disabled"

print("Statistics for policy file: {0}".format(p))
print("Policy Version: {0} (MLS {1})".format(p.version, mls))
print("Target Policy: {0}".format(p.target_platform))
print("Handle unknown classes: {0}".format(p.handle_unknown))
print(f"Statistics for policy file: {p}")
print(f"Policy Version: {p.version} (MLS {mls})")
print(f"Target Policy: {p.target_platform}")
print(f"Handle unknown classes: {p.handle_unknown}")
# keeping str.format below to ease alignment
print(" Classes: {0:7} Permissions: {1:7}".format(
p.class_count, p.permission_count))
print(" Sensitivities: {0:7} Categories: {1:7}".format(
Expand Down Expand Up @@ -389,7 +390,7 @@ try:
for desc, component, expander in components:
results = sorted(component.results())
if not args.flat:
print("\n{0}: {1}".format(desc, len(results)))
print(f"\n{desc}: {len(results)}")
for item in results:
result = expander(item) if args.expand else item
strfmt = " {0}" if not args.flat else "{0}"
Expand Down
21 changes: 11 additions & 10 deletions setools/boolquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
#
# SPDX-License-Identifier: LGPL-2.1-only
#
from typing import Iterable, Optional
from collections.abc import Iterable
import typing

from .mixins import MatchName
from .policyrep import Boolean
from .query import PolicyQuery
from . import mixins, policyrep, query

__all__: typing.Final[tuple[str, ...]] = ("BoolQuery",)

class BoolQuery(MatchName, PolicyQuery):

class BoolQuery(mixins.MatchName, query.PolicyQuery):

"""Query SELinux policy Booleans.
Expand All @@ -24,10 +25,10 @@ class BoolQuery(MatchName, PolicyQuery):
is None, the default state not be matched.
"""

_default: Optional[bool] = None
_default: bool | None = None

@property
def default(self) -> Optional[bool]:
def default(self) -> bool | None:
return self._default

@default.setter
Expand All @@ -37,11 +38,11 @@ def default(self, value) -> None:
else:
self._default = bool(value)

def results(self) -> Iterable[Boolean]:
def results(self) -> Iterable[policyrep.Boolean]:
"""Generator which yields all Booleans matching the criteria."""
self.log.info("Generating Boolean results from {0.policy}".format(self))
self.log.info(f"Generating Boolean results from {self.policy}")
self._match_name_debug(self.log)
self.log.debug("Default: {0.default}".format(self))
self.log.debug(f"{self.default=}")

for boolean in self.policy.bools():
if not self._match_name(boolean):
Expand Down
31 changes: 16 additions & 15 deletions setools/boundsquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
#
# SPDX-License-Identifier: LGPL-2.1-only
#
from typing import Iterable
from collections.abc import Iterable
import typing

from . import policyrep, query, util
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep import Bounds, BoundsRuletype
from .query import PolicyQuery
from .util import match_regex

__all__: typing.Final[tuple[str, ...]] = ("BoundsQuery",)

class BoundsQuery(PolicyQuery):

class BoundsQuery(query.PolicyQuery):

"""
Query *bounds statements.
Expand All @@ -22,30 +23,30 @@ class BoundsQuery(PolicyQuery):
ruletype The rule type(s) to match.
"""

ruletype = CriteriaSetDescriptor(enum_class=BoundsRuletype)
parent = CriteriaDescriptor("parent_regex")
ruletype = CriteriaSetDescriptor[policyrep.BoundsRuletype](enum_class=policyrep.BoundsRuletype)
parent = CriteriaDescriptor[policyrep.Type]("parent_regex")
parent_regex: bool = False
child = CriteriaDescriptor("child_regex")
child = CriteriaDescriptor[policyrep.Type]("child_regex")
child_regex: bool = False

def results(self) -> Iterable[Bounds]:
def results(self) -> Iterable[policyrep.Bounds]:
"""Generator which yields all matching *bounds statements."""
self.log.info("Generating bounds results from {0.policy}".format(self))
self.log.debug("Ruletypes: {0.ruletype}".format(self))
self.log.debug("Parent: {0.parent!r}, regex: {0.parent_regex}".format(self))
self.log.debug("Child: {0.child!r}, regex: {0.child_regex}".format(self))
self.log.info(f"Generating bounds results from {self.policy}")
self.log.debug(f"{self.ruletype=}")
self.log.debug(f"{self.parent=}, {self.parent_regex=}")
self.log.debug(f"{self.child=}, {self.child_regex=}")

for b in self.policy.bounds():
if self.ruletype and b.ruletype not in self.ruletype:
continue

if self.parent and not match_regex(
if self.parent and not util.match_regex(
b.parent,
self.parent,
self.parent_regex):
continue

if self.child and not match_regex(
if self.child and not util.match_regex(
b.child,
self.child,
self.child_regex):
Expand Down
15 changes: 8 additions & 7 deletions setools/categoryquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
#
# SPDX-License-Identifier: LGPL-2.1-only
#
from typing import Iterable
from collections.abc import Iterable
import typing

from .mixins import MatchAlias, MatchName
from .policyrep import Category
from .query import PolicyQuery
from . import mixins, policyrep, query

__all__: typing.Final[tuple[str, ...]] = ("CategoryQuery",)

class CategoryQuery(MatchAlias, MatchName, PolicyQuery):

class CategoryQuery(mixins.MatchAlias, mixins.MatchName, query.PolicyQuery):

"""
Query MLS Categories
Expand All @@ -26,9 +27,9 @@ class CategoryQuery(MatchAlias, MatchName, PolicyQuery):
will be used on the alias names.
"""

def results(self) -> Iterable[Category]:
def results(self) -> Iterable[policyrep.Category]:
"""Generator which yields all matching categories."""
self.log.info("Generating category results from {0.policy}".format(self))
self.log.info(f"Generating category results from {self.policy}")
self._match_name_debug(self.log)
self._match_alias_debug(self.log)

Expand Down
58 changes: 29 additions & 29 deletions setools/checker/assertrbac.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
# SPDX-License-Identifier: LGPL-2.1-only
#

import logging
from typing import List, Union
import typing

from ..exception import InvalidCheckValue
from ..policyrep import AnyRBACRule
from .. import exception, policyrep
from ..rbacrulequery import RBACRuleQuery
from .checkermodule import CheckerModule
from .descriptors import ConfigDescriptor, ConfigSetDescriptor

SOURCE_OPT = "source"
TARGET_OPT = "target"
EXEMPT_SRC_OPT = "exempt_source"
EXEMPT_TGT_OPT = "exempt_target"
EXPECT_SRC_OPT = "expect_source"
EXPECT_TGT_OPT = "expect_target"
SOURCE_OPT: typing.Final[str] = "source"
TARGET_OPT: typing.Final[str] = "target"
EXEMPT_SRC_OPT: typing.Final[str] = "exempt_source"
EXEMPT_TGT_OPT: typing.Final[str] = "exempt_target"
EXPECT_SRC_OPT: typing.Final[str] = "expect_source"
EXPECT_TGT_OPT: typing.Final[str] = "expect_target"

__all__: typing.Final[tuple[str, ...]] = ("AssertRBAC",)


class AssertRBAC(CheckerModule):
Expand All @@ -29,18 +29,18 @@ class AssertRBAC(CheckerModule):
check_config = frozenset((SOURCE_OPT, TARGET_OPT, EXEMPT_SRC_OPT, EXEMPT_TGT_OPT,
EXPECT_SRC_OPT, EXPECT_TGT_OPT))

source = ConfigDescriptor("lookup_role")
target = ConfigDescriptor("lookup_role")
source = ConfigDescriptor[policyrep.Role]("lookup_role")
target = ConfigDescriptor[policyrep.Role]("lookup_role")

exempt_source = ConfigSetDescriptor("lookup_role", strict=False, expand=True)
exempt_target = ConfigSetDescriptor("lookup_role", strict=False, expand=True)
expect_source = ConfigSetDescriptor("lookup_role", strict=True, expand=True)
expect_target = ConfigSetDescriptor("lookup_role", strict=True, expand=True)
exempt_source = ConfigSetDescriptor[policyrep.Role]("lookup_role", strict=False, expand=True)
exempt_target = ConfigSetDescriptor[policyrep.Role]("lookup_role", strict=False, expand=True)
expect_source = ConfigSetDescriptor[policyrep.Role]("lookup_role", strict=True, expand=True)
expect_target = ConfigSetDescriptor[policyrep.Role]("lookup_role", strict=True, expand=True)

def __init__(self, policy, checkname, config) -> None:
super().__init__(policy, checkname, config)
self.log = logging.getLogger(__name__)
def __init__(self, policy: policyrep.SELinuxPolicy, checkname: str,
config: dict[str, str]) -> None:

super().__init__(policy, checkname, config)
self.source = config.get(SOURCE_OPT)
self.target = config.get(TARGET_OPT)

Expand All @@ -50,20 +50,20 @@ def __init__(self, policy, checkname, config) -> None:
self.expect_target = config.get(EXPECT_TGT_OPT)

if not any((self.source, self.target)):
raise InvalidCheckValue(
raise exception.InvalidCheckValue(
"At least one of source or target options must be set.")

source_exempt_expect_overlap = self.exempt_source & self.expect_source
if source_exempt_expect_overlap:
self.log.info("Overlap in expect_source and exempt_source: {}".
format(", ".join(i.name for i in source_exempt_expect_overlap)))
self.log.info("Overlap in expect_source and exempt_source: "
f"{', '.join(i.name for i in source_exempt_expect_overlap)}")

target_exempt_expect_overlap = self.exempt_target & self.expect_target
if target_exempt_expect_overlap:
self.log.info("Overlap in expect_target and exempt_target: {}".
format(", ".join(i.name for i in target_exempt_expect_overlap)))
self.log.info("Overlap in expect_target and exempt_target: "
f"{', '.join(i.name for i in target_exempt_expect_overlap)}")

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

self.log.info("Checking RBAC allow rule assertion.")
Expand All @@ -75,7 +75,7 @@ def run(self) -> List:

unseen_sources = set(self.expect_source)
unseen_targets = set(self.expect_target)
failures: List[Union[AnyRBACRule, str]] = []
failures: list[policyrep.AnyRBACRule | str] = []
for rule in sorted(query.results()):
srcs = set(rule.source.expand())
tgts = set(rule.target.expand())
Expand All @@ -91,14 +91,14 @@ def run(self) -> List:
self.log_ok(str(rule))

for item in unseen_sources:
failure = "Expected rule with source \"{}\" not found.".format(item)
failure = f"Expected rule with source \"{item}\" not found."
self.log_fail(failure)
failures.append(failure)

for item in unseen_targets:
failure = "Expected rule with target \"{}\" not found.".format(item)
failure = f"Expected rule with target \"{item}\" not found."
self.log_fail(failure)
failures.append(failure)

self.log.debug("{} failure(s)".format(failures))
self.log.debug(f"{failures} failure(s)")
return failures
Loading

0 comments on commit 4c205e4

Please sign in to comment.