253 lines
12 KiB
Python
Executable File
253 lines
12 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright 2014-2015, Tresys Technology, LLC
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
|
|
import setools
|
|
import argparse
|
|
import sys
|
|
import logging
|
|
import signal
|
|
import warnings
|
|
|
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="SELinux policy rule search tool.",
|
|
epilog="TE/MLS rule searches cannot be mixed with RBAC rule searches.")
|
|
parser.add_argument("--version", action="version", version=setools.__version__)
|
|
parser.add_argument("policy", help="Path to the SELinux policy to search.", nargs="?")
|
|
parser.add_argument("-v", "--verbose", action="store_true",
|
|
help="Print extra informational messages")
|
|
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
|
|
|
|
rtypes = parser.add_argument_group("TE Rule Types")
|
|
rtypes.add_argument("-A", action="store_true", help="Search allow and allowxperm rules.")
|
|
rtypes.add_argument("--allow", action="append_const",
|
|
const=setools.TERuletype.allow, dest="tertypes",
|
|
help="Search allow rules.")
|
|
rtypes.add_argument("--allowxperm", action="append_const",
|
|
const=setools.TERuletype.allowxperm, dest="tertypes",
|
|
help="Search allowxperm rules.")
|
|
rtypes.add_argument("--auditallow", action="append_const",
|
|
const=setools.TERuletype.auditallow, dest="tertypes",
|
|
help="Search auditallow rules.")
|
|
rtypes.add_argument("--auditallowxperm", action="append_const",
|
|
const=setools.TERuletype.auditallowxperm, dest="tertypes",
|
|
help="Search auditallowxperm rules.")
|
|
rtypes.add_argument("--dontaudit", action="append_const",
|
|
const=setools.TERuletype.dontaudit, dest="tertypes",
|
|
help="Search dontaudit rules.")
|
|
rtypes.add_argument("--dontauditxperm", action="append_const",
|
|
const=setools.TERuletype.dontauditxperm, dest="tertypes",
|
|
help="Search dontauditxperm rules.")
|
|
# rtypes.add_argument("--neverallow", action="append_const",
|
|
# const=setools.TERuletype.neverallow, dest="tertypes",
|
|
# help="Search neverallow rules.")
|
|
# rtypes.add_argument("--neverallowxperm", action="append_const",
|
|
# const=setools.TERuletype.neverallowxperm, dest="tertypes",
|
|
# help="Search neverallowxperm rules.")
|
|
rtypes.add_argument("-T", "--type_transition", action="append_const",
|
|
const=setools.TERuletype.type_transition, dest="tertypes",
|
|
help="Search type_transition rules.")
|
|
rtypes.add_argument("--type_change", action="append_const",
|
|
const=setools.TERuletype.type_change, dest="tertypes",
|
|
help="Search type_change rules.")
|
|
rtypes.add_argument("--type_member", action="append_const",
|
|
const=setools.TERuletype.type_member, dest="tertypes",
|
|
help="Search type_member rules.")
|
|
rbacrtypes = parser.add_argument_group("RBAC Rule Types")
|
|
rbacrtypes.add_argument("--role_allow", action="append_const",
|
|
const=setools.RBACRuletype.allow, dest="rbacrtypes",
|
|
help="Search role allow rules.")
|
|
rbacrtypes.add_argument("--role_transition", action="append_const",
|
|
const=setools.RBACRuletype.role_transition, dest="rbacrtypes",
|
|
help="Search role_transition rules.")
|
|
|
|
mlsrtypes = parser.add_argument_group("MLS Rule Types")
|
|
mlsrtypes.add_argument("--range_transition", action="append_const",
|
|
const=setools.MLSRuletype.range_transition, dest="mlsrtypes",
|
|
help="Search range_transition rules.")
|
|
|
|
expr = parser.add_argument_group("Expressions")
|
|
expr.add_argument("-s", "--source",
|
|
help="Source type/role of the TE/RBAC rule.")
|
|
expr.add_argument("-t", "--target",
|
|
help="Target type/role of the TE/RBAC rule.")
|
|
expr.add_argument("-c", "--class", dest="tclass",
|
|
help="Comma separated list of object classes")
|
|
expr.add_argument("-p", "--perms", metavar="PERMS",
|
|
help="Comma separated list of permissions. (TE rule searches only.)")
|
|
expr.add_argument("-x", "--xperms", metavar="XPERMS",
|
|
help="Comma separated list of extended permissions. (TE rule searches only.)")
|
|
expr.add_argument("-D", "--default",
|
|
help="Default of the rule. (type/role/range transition rules)")
|
|
expr.add_argument("-b", "--bool", dest="boolean", metavar="BOOL",
|
|
help="Comma separated list of Booleans in the conditional expression. "
|
|
"(TE rule searches only.)")
|
|
|
|
opts = parser.add_argument_group("Search options")
|
|
opts.add_argument("-eb", action="store_true", dest="boolean_equal",
|
|
help="Match Boolean list exactly instead of matching any listed Boolean.")
|
|
opts.add_argument("-ep", action="store_true", dest="perms_equal",
|
|
help="Match permission set exactly instead of matching any listed permission.")
|
|
opts.add_argument("-ex", action="store_true", dest="xperms_equal",
|
|
help="Match extended permission set exactly instead of matching any listed "
|
|
"permission.")
|
|
opts.add_argument("-Sp", action="store_true", dest="perms_subset",
|
|
help="Match rules where the listed permissions are a subset of the rule "
|
|
"permissions.")
|
|
opts.add_argument("-ds", action="store_false", dest="source_indirect",
|
|
help="Match source attributes directly instead of matching member types/roles.")
|
|
opts.add_argument("-dt", action="store_false", dest="target_indirect",
|
|
help="Match target attributes directly instead of matching member types/roles.")
|
|
opts.add_argument("-rs", action="store_true", dest="source_regex",
|
|
help="Use regular expression matching for the source type/role.")
|
|
opts.add_argument("-rt", action="store_true", dest="target_regex",
|
|
help="Use regular expression matching for the target type/role.")
|
|
opts.add_argument("-rc", action="store_true", dest="tclass_regex",
|
|
help="Use regular expression matching for the object class.")
|
|
opts.add_argument("-rd", action="store_true", dest="default_regex",
|
|
help="Use regular expression matching for the default type/role.")
|
|
opts.add_argument("-rb", action="store_true", dest="boolean_regex",
|
|
help="Use regular expression matching for Booleans.")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.A:
|
|
try:
|
|
args.tertypes.extend([setools.TERuletype.allow, setools.TERuletype.allowxperm])
|
|
except AttributeError:
|
|
args.tertypes = [setools.TERuletype.allow, setools.TERuletype.allowxperm]
|
|
|
|
if not any((args.tertypes, args.mlsrtypes, args.rbacrtypes)):
|
|
parser.error("At least one rule type must be specified.")
|
|
|
|
if any((args.perms, args.xperms, args.boolean)) and any((args.rbacrtypes, args.mlsrtypes)):
|
|
parser.error("-p/--perms, -x/--xperms, and -b/--bool options are only supported "
|
|
"with TE rule searches.")
|
|
|
|
if args.debug:
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s|%(levelname)s|%(name)s|%(message)s')
|
|
if not sys.warnoptions:
|
|
warnings.simplefilter("default")
|
|
elif args.verbose:
|
|
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
|
if not sys.warnoptions:
|
|
warnings.simplefilter("default")
|
|
else:
|
|
logging.basicConfig(level=logging.WARNING, format='%(message)s')
|
|
if not sys.warnoptions:
|
|
warnings.simplefilter("ignore")
|
|
|
|
try:
|
|
p = setools.SELinuxPolicy(args.policy)
|
|
|
|
if args.tertypes:
|
|
terq = setools.TERuleQuery(p,
|
|
ruletype=args.tertypes,
|
|
source=args.source,
|
|
source_indirect=args.source_indirect,
|
|
source_regex=args.source_regex,
|
|
target=args.target,
|
|
target_indirect=args.target_indirect,
|
|
target_regex=args.target_regex,
|
|
tclass_regex=args.tclass_regex,
|
|
perms_equal=args.perms_equal,
|
|
perms_subset=args.perms_subset,
|
|
xperms_equal=args.xperms_equal,
|
|
default=args.default,
|
|
default_regex=args.default_regex,
|
|
boolean_regex=args.boolean_regex,
|
|
boolean_equal=args.boolean_equal)
|
|
|
|
# these are broken out from the above statement to prevent making a list
|
|
# with an empty string in it (split on empty string)
|
|
if args.tclass:
|
|
if args.tclass_regex:
|
|
terq.tclass = args.tclass
|
|
else:
|
|
terq.tclass = args.tclass.split(",")
|
|
|
|
if args.perms:
|
|
terq.perms = args.perms.split(",")
|
|
|
|
if args.xperms:
|
|
# https://github.com/python/mypy/issues/220
|
|
terq.xperms = setools.xperm_str_to_tuple_ranges(args.xperms) # type: ignore
|
|
|
|
if args.boolean:
|
|
if args.boolean_regex:
|
|
terq.boolean = args.boolean
|
|
else:
|
|
if args.policy:
|
|
terq.boolean = args.boolean.split(",")
|
|
else:
|
|
# try to find substitutions for old boolean names
|
|
terq.boolean = map(setools.policyrep.lookup_boolean_name_sub,
|
|
args.boolean.split(","))
|
|
|
|
for te_result in sorted(terq.results()):
|
|
print(te_result)
|
|
|
|
if args.rbacrtypes:
|
|
rbacrq = setools.RBACRuleQuery(p,
|
|
ruletype=args.rbacrtypes,
|
|
source=args.source,
|
|
source_indirect=args.source_indirect,
|
|
source_regex=args.source_regex,
|
|
target=args.target,
|
|
target_indirect=args.target_indirect,
|
|
target_regex=args.target_regex,
|
|
default=args.default,
|
|
default_regex=args.default_regex,
|
|
tclass_regex=args.tclass_regex)
|
|
|
|
# these are broken out from the above statement to prevent making a list
|
|
# with an empty string in it (split on empty string)
|
|
if args.tclass:
|
|
if args.tclass_regex:
|
|
rbacrq.tclass = args.tclass
|
|
else:
|
|
rbacrq.tclass = args.tclass.split(",")
|
|
|
|
for rbac_result in sorted(rbacrq.results()):
|
|
print(rbac_result)
|
|
|
|
if args.mlsrtypes:
|
|
mlsrq = setools.MLSRuleQuery(p,
|
|
ruletype=args.mlsrtypes,
|
|
source=args.source,
|
|
source_indirect=args.source_indirect,
|
|
source_regex=args.source_regex,
|
|
target=args.target,
|
|
target_indirect=args.target_indirect,
|
|
target_regex=args.target_regex,
|
|
tclass_regex=args.tclass_regex,
|
|
default=args.default)
|
|
|
|
# these are broken out from the above statement to prevent making a list
|
|
# with an empty string in it (split on empty string)
|
|
if args.tclass:
|
|
if args.tclass_regex:
|
|
mlsrq.tclass = args.tclass
|
|
else:
|
|
mlsrq.tclass = args.tclass.split(",")
|
|
|
|
for mls_result in sorted(mlsrq.results()):
|
|
print(mls_result)
|
|
|
|
except AssertionError:
|
|
# Always provide a traceback for assertion errors
|
|
raise
|
|
|
|
except Exception as err:
|
|
if args.debug:
|
|
raise
|
|
else:
|
|
print(err)
|
|
|
|
sys.exit(1)
|