mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-11 03:51:26 +00:00
Found by codespell(1) and typos[1]. [1]: https://github.com/crate-ci/typos Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
1507 lines
71 KiB
Python
Executable File
1507 lines
71 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright 2015-2016, Tresys Technology, LLC
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
|
|
import setools
|
|
import argparse
|
|
import sys
|
|
import logging
|
|
import signal
|
|
import warnings
|
|
from itertools import chain
|
|
from contextlib import suppress
|
|
|
|
|
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="SELinux policy semantic difference tool.",
|
|
epilog="If no differences are selected, all differences will be printed.")
|
|
parser.add_argument("POLICY1", help="Path to the first SELinux policy to diff.", nargs=1)
|
|
parser.add_argument("POLICY2", help="Path to the second SELinux policy to diff.", nargs=1)
|
|
parser.add_argument("--version", action="version", version=setools.__version__)
|
|
parser.add_argument("--stats", action="store_true", help="Display only statistics.")
|
|
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.")
|
|
|
|
comp = parser.add_argument_group("component differences")
|
|
comp.add_argument("--common", action="store_true", help="Print common differences")
|
|
comp.add_argument("-c", "--class", action="store_true", help="Print class differences",
|
|
dest="class_")
|
|
comp.add_argument("-t", "--type", action="store_true", help="Print type differences",
|
|
dest="type_")
|
|
comp.add_argument("-a", "--attribute", action="store_true", help="Print type attribute differences")
|
|
comp.add_argument("-r", "--role", action="store_true", help="Print role differences")
|
|
comp.add_argument("-u", "--user", action="store_true", help="Print user differences")
|
|
comp.add_argument("-b", "--bool", action="store_true", help="Print Boolean differences",
|
|
dest="bool_")
|
|
comp.add_argument("--sensitivity", action="store_true", help="Print MLS sensitivity differences")
|
|
comp.add_argument("--category", action="store_true", help="Print MLS category differences")
|
|
comp.add_argument("--level", action="store_true", help="Print MLS level definition differences")
|
|
|
|
terule = parser.add_argument_group("type enforcement rule differences")
|
|
terule.add_argument("-A", action="store_true", help="Print allow and allowxperm rule differences")
|
|
terule.add_argument("--allow", action="store_true", help="Print allow rule differences")
|
|
# terule.add_argument("--neverallow", action="store_true", help="Print neverallow rule differences")
|
|
terule.add_argument("--auditallow", action="store_true", help="Print auditallow rule differences")
|
|
terule.add_argument("--dontaudit", action="store_true", help="Print dontaudit rule differences")
|
|
terule.add_argument("--allowxperm", action="store_true", help="Print allowxperm rule differences")
|
|
# terule.add_argument("--neverallowxperm", action="store_true",
|
|
# help="Print neverallowxperm rule differences")
|
|
terule.add_argument("--auditallowxperm", action="store_true",
|
|
help="Print auditallowxperm rule differences")
|
|
terule.add_argument("--dontauditxperm", action="store_true",
|
|
help="Print dontauditxperm rule differences")
|
|
terule.add_argument("-T", "--type_trans", action="store_true",
|
|
help="Print type_transition rule differences")
|
|
terule.add_argument("--type_change", action="store_true", help="Print type_change rule differences")
|
|
terule.add_argument("--type_member", action="store_true",
|
|
help="Print type_member rule differences")
|
|
|
|
rbacrule = parser.add_argument_group("RBAC rule differences")
|
|
rbacrule.add_argument("--role_allow", action="store_true", help="Print role allow rule differences")
|
|
rbacrule.add_argument("--role_trans", action="store_true",
|
|
help="Print role_transition rule differences")
|
|
|
|
mlsrule = parser.add_argument_group("MLS rule differences")
|
|
mlsrule.add_argument("--range_trans", action="store_true",
|
|
help="Print range_transition rule differences")
|
|
|
|
constrain = parser.add_argument_group("Constraint differences")
|
|
constrain.add_argument("--constrain", action="store_true", help="Print constrain differences")
|
|
constrain.add_argument("--mlsconstrain", action="store_true", help="Print mlsconstrain differences")
|
|
constrain.add_argument("--validatetrans", action="store_true",
|
|
help="Print validatetrans differences")
|
|
constrain.add_argument("--mlsvalidatetrans", action="store_true",
|
|
help="Print mlsvalidatetrans differences")
|
|
|
|
labeling = parser.add_argument_group("labeling statement differences")
|
|
labeling.add_argument("--ibendportcon", action="store_true", help="Print ibendportcon differences")
|
|
labeling.add_argument("--ibpkeycon", action="store_true", help="Print ibkeycon differences")
|
|
labeling.add_argument("--initialsid", action="store_true", help="Print initial SID differences")
|
|
labeling.add_argument("--fs_use", action="store_true", help="Print fs_use_* differences")
|
|
labeling.add_argument("--genfscon", action="store_true", help="Print genfscon differences")
|
|
labeling.add_argument("--netifcon", action="store_true", help="Print netifcon differences")
|
|
labeling.add_argument("--nodecon", action="store_true", help="Print nodecon differences")
|
|
labeling.add_argument("--portcon", action="store_true", help="Print portcon differences")
|
|
|
|
other = parser.add_argument_group("other differences")
|
|
other.add_argument("--default", action="store_true", help="Print default_* differences")
|
|
other.add_argument("--property", action="store_true",
|
|
help="Print policy property differences (handle_unknown, version, MLS)")
|
|
other.add_argument("--polcap", action="store_true", help="Print policy capability differences")
|
|
other.add_argument("--typebounds", action="store_true", help="Print typebounds differences")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# neverallow and neverallowxperm options are disabled
|
|
args.neverallow = False
|
|
args.neverallowxperm = False
|
|
|
|
if args.A:
|
|
args.allow = True
|
|
args.allowxperm = True
|
|
|
|
all_differences = not any((args.class_, args.common, args.type_, args.attribute, args.role,
|
|
args.user, args.bool_, args.sensitivity, args.category, args.level,
|
|
args.allow, args.neverallow, args.auditallow, args.dontaudit,
|
|
args.type_trans, args.type_change, args.type_member, args.role_allow,
|
|
args.role_trans, args.range_trans, args.initialsid, args.genfscon,
|
|
args.netifcon, args.nodecon, args.portcon, args.fs_use, args.polcap,
|
|
args.property, args.default, args.constrain, args.mlsconstrain,
|
|
args.validatetrans, args.mlsvalidatetrans, args.typebounds,
|
|
args.allowxperm, args.neverallowxperm, args.auditallowxperm,
|
|
args.dontauditxperm, args.ibendportcon, args.ibpkeycon))
|
|
|
|
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:
|
|
p1 = setools.SELinuxPolicy(args.POLICY1[0])
|
|
p2 = setools.SELinuxPolicy(args.POLICY2[0])
|
|
diff = setools.PolicyDifference(p1, p2)
|
|
|
|
perms: list[str]
|
|
|
|
if all_differences or args.property:
|
|
if diff.modified_properties or args.property:
|
|
print(f"Policy Properties ({len(diff.modified_properties)} Modified)")
|
|
if not args.stats:
|
|
for prop in sorted(diff.modified_properties):
|
|
print(f" * {prop.property} +{prop.added} -{prop.removed}")
|
|
print()
|
|
del diff.modified_properties
|
|
|
|
if all_differences or args.polcap:
|
|
if diff.added_polcaps or diff.removed_polcaps or args.polcap:
|
|
na = len(diff.added_polcaps)
|
|
nr = len(diff.removed_polcaps)
|
|
print(f"Policy Capabilities ({na} Added, {nr} Removed)")
|
|
if diff.added_polcaps and not args.stats:
|
|
print(f" Added Policy Capabilities: {na}")
|
|
for cap in sorted(diff.added_polcaps):
|
|
print(f" + {cap}")
|
|
if diff.removed_polcaps and not args.stats:
|
|
print(f" Removed Policy Capabilities: {nr}")
|
|
for cap in sorted(diff.removed_polcaps):
|
|
print(f" - {cap}")
|
|
|
|
print()
|
|
del diff.added_polcaps
|
|
del diff.removed_polcaps
|
|
|
|
if all_differences or args.common:
|
|
if diff.added_commons or diff.removed_commons or diff.modified_commons or args.common:
|
|
na = len(diff.added_commons)
|
|
nr = len(diff.removed_commons)
|
|
nm = len(diff.modified_commons)
|
|
print(f"Commons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_commons and not args.stats:
|
|
print(f" Added Commons: {na}")
|
|
for c in sorted(diff.added_commons):
|
|
print(f" + {c}")
|
|
if diff.removed_commons and not args.stats:
|
|
print(f" Removed Commons: {nr}")
|
|
for c in sorted(diff.removed_commons):
|
|
print(f" - {c}")
|
|
if diff.modified_commons and not args.stats:
|
|
print(f" Modified Commons: {nm}")
|
|
for com in sorted(diff.modified_commons):
|
|
change = []
|
|
if com.added_perms:
|
|
change.append(f"{len(com.added_perms)} Added permissions")
|
|
if com.removed_perms:
|
|
change.append(f"{len(com.removed_perms)} Removed permissions")
|
|
|
|
print(f" * {com.common.name} ({', '.join(change)})")
|
|
for p in sorted(com.added_perms):
|
|
print(f" + {p}")
|
|
for p in sorted(com.removed_perms):
|
|
print(f" - {p}")
|
|
print()
|
|
del diff.added_commons
|
|
del diff.removed_commons
|
|
del diff.modified_commons
|
|
|
|
if all_differences or args.class_:
|
|
if diff.added_classes or diff.removed_classes or diff.modified_classes or args.class_:
|
|
na = len(diff.added_classes)
|
|
nr = len(diff.removed_classes)
|
|
nm = len(diff.modified_classes)
|
|
print(f"Classes ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_classes and not args.stats:
|
|
print(f" Added Classes: {na}")
|
|
for cls in sorted(diff.added_classes):
|
|
print(f" + {cls}")
|
|
if diff.removed_classes and not args.stats:
|
|
print(f" Removed Classes: {nr}")
|
|
for cls in sorted(diff.removed_classes):
|
|
print(f" - {cls}")
|
|
if diff.modified_classes and not args.stats:
|
|
print(f" Modified Classes: {nm}")
|
|
for mcls in sorted(diff.modified_classes):
|
|
change = []
|
|
if mcls.added_perms:
|
|
change.append(f"{len(mcls.added_perms)} Added permissions")
|
|
if mcls.removed_perms:
|
|
change.append(f"{len(mcls.removed_perms)} Removed permissions")
|
|
|
|
print(f" * {mcls.class_.name} ({', '.join(change)})")
|
|
for p in sorted(mcls.added_perms):
|
|
print(f" + {p}")
|
|
for p in sorted(mcls.removed_perms):
|
|
print(f" - {p}")
|
|
print()
|
|
del diff.added_classes
|
|
del diff.removed_classes
|
|
del diff.modified_classes
|
|
|
|
if all_differences or args.default:
|
|
if diff.added_defaults or diff.removed_defaults or diff.modified_defaults or args.default:
|
|
na = len(diff.added_defaults)
|
|
nr = len(diff.removed_defaults)
|
|
nm = len(diff.modified_defaults)
|
|
print(f"Defaults ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_defaults and not args.stats:
|
|
print(f" Added Defaults: {na}")
|
|
for dflt in sorted(diff.added_defaults):
|
|
print(f" + {dflt}")
|
|
if diff.removed_defaults and not args.stats:
|
|
print(f" Removed Defaults: {nr}")
|
|
for dflt in sorted(diff.removed_defaults):
|
|
print(f" - {dflt}")
|
|
if diff.modified_defaults and not args.stats:
|
|
print(f" Modified Defaults: {nm}")
|
|
for mdflt in sorted(diff.modified_defaults):
|
|
line = f" * {mdflt.rule.ruletype} {mdflt.rule.tclass} "
|
|
if mdflt.removed_default:
|
|
line += f"+{mdflt.added_default} -{mdflt.removed_default}"
|
|
else:
|
|
line += mdflt.rule.default.name
|
|
|
|
if mdflt.removed_default_range:
|
|
line += f" +{mdflt.added_default_range} -{mdflt.removed_default_range};"
|
|
else:
|
|
try:
|
|
line += f" {mdflt.rule.default_range};" # type: ignore
|
|
except AttributeError:
|
|
line += ";"
|
|
print(line)
|
|
|
|
print()
|
|
del diff.added_defaults
|
|
del diff.removed_defaults
|
|
del diff.modified_defaults
|
|
|
|
if all_differences or args.bool_:
|
|
if diff.added_booleans or diff.removed_booleans or \
|
|
diff.modified_booleans or args.bool_:
|
|
na = len(diff.added_booleans)
|
|
nr = len(diff.removed_booleans)
|
|
nm = len(diff.modified_booleans)
|
|
print(f"Booleans ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_booleans and not args.stats:
|
|
print(f" Added Booleans: {na}")
|
|
for a in sorted(diff.added_booleans):
|
|
print(f" + {a}")
|
|
if diff.removed_booleans and not args.stats:
|
|
print(f" Removed Booleans: {nr}")
|
|
for a in sorted(diff.removed_booleans):
|
|
print(f" - {a}")
|
|
if diff.modified_booleans and not args.stats:
|
|
print(f" Modified Booleans: {nm}")
|
|
for bool_ in sorted(diff.modified_booleans):
|
|
print(f" * {bool_.boolean.name} (Modified default state)")
|
|
print(f" + {bool_.added_state}")
|
|
print(f" - {bool_.removed_state}")
|
|
|
|
print()
|
|
del diff.added_booleans
|
|
del diff.removed_booleans
|
|
del diff.modified_booleans
|
|
|
|
if all_differences or args.role:
|
|
if diff.added_roles or diff.removed_roles or diff.modified_roles or args.role:
|
|
na = len(diff.added_roles)
|
|
nr = len(diff.removed_roles)
|
|
nm = len(diff.modified_roles)
|
|
print(f"Roles ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_roles and not args.stats:
|
|
print(f" Added Roles: {na}")
|
|
for role in sorted(diff.added_roles):
|
|
print(f" + {role}")
|
|
if diff.removed_roles and not args.stats:
|
|
print(f" Removed Roles: {nr}")
|
|
for role in sorted(diff.removed_roles):
|
|
print(f" - {role}")
|
|
if diff.modified_roles and not args.stats:
|
|
print(f" Modified Roles: {nm}")
|
|
for mrole in sorted(diff.modified_roles):
|
|
change = []
|
|
if mrole.added_types:
|
|
change.append(f"{len(mrole.added_types)} Added types")
|
|
if mrole.removed_types:
|
|
change.append(f"{len(mrole.removed_types)} Removed types")
|
|
|
|
print(f" * {mrole.role.name} ({', '.join(change)})")
|
|
for type_ in sorted(mrole.added_types):
|
|
print(f" + {type_}")
|
|
for type_ in sorted(mrole.removed_types):
|
|
print(f" - {type_}")
|
|
print()
|
|
del diff.added_roles
|
|
del diff.removed_roles
|
|
del diff.modified_roles
|
|
|
|
if all_differences or args.type_:
|
|
if diff.added_types or diff.removed_types or diff.modified_types or args.type_:
|
|
na = len(diff.added_types)
|
|
nr = len(diff.removed_types)
|
|
nm = len(diff.modified_types)
|
|
print(f"Types ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_types and not args.stats:
|
|
print(f" Added Types: {na}")
|
|
for type_ in sorted(diff.added_types):
|
|
print(f" + {type_}")
|
|
if diff.removed_types and not args.stats:
|
|
print(f" Removed Types: {nr}")
|
|
for type_ in sorted(diff.removed_types):
|
|
print(f" - {type_}")
|
|
if diff.modified_types and not args.stats:
|
|
print(f" Modified Types: {nm}")
|
|
for mtype in sorted(diff.modified_types):
|
|
change = []
|
|
if mtype.added_attributes:
|
|
change.append(f"{len(mtype.added_attributes)} Added attributes")
|
|
if mtype.removed_attributes:
|
|
change.append(f"{len(mtype.removed_attributes)} Removed attributes")
|
|
if mtype.added_aliases:
|
|
change.append(f"{len(mtype.added_aliases)} Added aliases")
|
|
if mtype.removed_aliases:
|
|
change.append(f"{len(mtype.removed_aliases)} Removed aliases")
|
|
if mtype.modified_permissive:
|
|
if mtype.permissive:
|
|
change.append("Removed permissive")
|
|
else:
|
|
change.append("Added permissive")
|
|
|
|
print(f" * {mtype.type_.name} ({','.join(change)})")
|
|
if mtype.added_attributes or mtype.removed_attributes:
|
|
print(" Attributes:")
|
|
for attr in sorted(mtype.added_attributes):
|
|
print(f" + {attr}")
|
|
for attr in sorted(mtype.removed_attributes):
|
|
print(f" - {attr}")
|
|
|
|
if mtype.added_aliases or mtype.removed_aliases:
|
|
print(" Aliases:")
|
|
for alias in sorted(mtype.added_aliases):
|
|
print(f" + {alias}")
|
|
for alias in sorted(mtype.removed_aliases):
|
|
print(f" - {alias}")
|
|
|
|
print()
|
|
del diff.added_types
|
|
del diff.removed_types
|
|
del diff.modified_types
|
|
|
|
if all_differences or args.typebounds:
|
|
if diff.added_typebounds or diff.removed_typebounds or diff.modified_typebounds \
|
|
or args.typebounds:
|
|
na = len(diff.added_typebounds)
|
|
nr = len(diff.removed_typebounds)
|
|
nm = len(diff.modified_typebounds)
|
|
print(f"Typebounds ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_typebounds and not args.stats:
|
|
print(f" Added Typebounds: {na}")
|
|
for tb in sorted(diff.added_typebounds):
|
|
print(f" + {tb}")
|
|
if diff.removed_typebounds and not args.stats:
|
|
print(f" Removed Typebounds: {nr}")
|
|
for tb in sorted(diff.removed_typebounds):
|
|
print(f" - {tb}")
|
|
if diff.modified_typebounds and not args.stats:
|
|
print(f" Modified Typebounds: {nm}")
|
|
for mtb in sorted(diff.modified_typebounds):
|
|
print(
|
|
f" * {mtb.rule.ruletype} +{mtb.added_bound} -{mtb.removed_bound} "
|
|
f"{mtb.rule.child};")
|
|
|
|
print()
|
|
del diff.added_typebounds
|
|
del diff.removed_typebounds
|
|
|
|
if all_differences or args.attribute:
|
|
if diff.added_type_attributes or diff.removed_type_attributes or \
|
|
diff.modified_type_attributes or args.attribute:
|
|
na = len(diff.added_type_attributes)
|
|
nr = len(diff.removed_type_attributes)
|
|
nm = len(diff.modified_type_attributes)
|
|
print(f"Type Attributes ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_type_attributes and not args.stats:
|
|
print(f" Added Type Attributes: {na}")
|
|
for attr in sorted(diff.added_type_attributes):
|
|
print(f" + {attr}")
|
|
if diff.removed_type_attributes and not args.stats:
|
|
print(f" Removed Type Attributes: {nr}")
|
|
for attr in sorted(diff.removed_type_attributes):
|
|
print(f" - {attr}")
|
|
if diff.modified_type_attributes and not args.stats:
|
|
print(f" Modified Type Attributes: {nm}")
|
|
for mattr in sorted(diff.modified_type_attributes):
|
|
change = []
|
|
if mattr.added_types:
|
|
change.append(f"{len(mattr.added_types)} Added types")
|
|
if mattr.removed_types:
|
|
change.append(f"{len(mattr.removed_types)} Removed types")
|
|
|
|
print(f" * {mattr.attr.name} ({', '.join(change)})")
|
|
for type_ in sorted(mattr.added_types):
|
|
print(f" + {type_}")
|
|
for type_ in sorted(mattr.removed_types):
|
|
print(f" - {type_}")
|
|
print()
|
|
del diff.added_type_attributes
|
|
del diff.removed_type_attributes
|
|
del diff.modified_type_attributes
|
|
|
|
if all_differences or args.user:
|
|
if diff.added_users or diff.removed_users or diff.modified_users or args.user:
|
|
na = len(diff.added_users)
|
|
nr = len(diff.removed_users)
|
|
nm = len(diff.modified_users)
|
|
print(f"Users ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_users and not args.stats:
|
|
print(f" Added Users: {na}")
|
|
for user in sorted(diff.added_users):
|
|
print(f" + {user}")
|
|
if diff.removed_users and not args.stats:
|
|
print(f" Removed Users: {nr}")
|
|
for user in sorted(diff.removed_users):
|
|
print(f" - {user}")
|
|
if diff.modified_users and not args.stats:
|
|
print(f" Modified Users: {nm}")
|
|
for muser in sorted(diff.modified_users):
|
|
change = []
|
|
if muser.added_roles:
|
|
change.append(f"{len(muser.added_roles)} Added roles")
|
|
if muser.removed_roles:
|
|
change.append(f"{len(muser.removed_roles)} Removed roles")
|
|
if muser.removed_level:
|
|
change.append("Modified default level")
|
|
if muser.removed_range:
|
|
change.append("Modified range")
|
|
|
|
print(f" * {muser.user.name} ({', '.join(change)})")
|
|
if muser.added_roles or muser.removed_roles:
|
|
print(" Roles:")
|
|
for role in sorted(muser.added_roles):
|
|
print(f" + {role}")
|
|
for role in sorted(muser.removed_roles):
|
|
print(f" - {role}")
|
|
|
|
if muser.removed_level:
|
|
print(" Default level:")
|
|
print(f" + {muser.added_level}")
|
|
print(f" - {muser.removed_level}")
|
|
|
|
if muser.removed_range:
|
|
print(" Range:")
|
|
print(f" + {muser.added_range}")
|
|
print(f" - {muser.removed_range}")
|
|
print()
|
|
del diff.added_users
|
|
del diff.removed_users
|
|
del diff.modified_users
|
|
|
|
if all_differences or args.category:
|
|
if diff.added_categories or diff.removed_categories or diff.modified_categories \
|
|
or args.category:
|
|
na = len(diff.added_categories)
|
|
nr = len(diff.removed_categories)
|
|
nm = len(diff.modified_categories)
|
|
print(f"Categories ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_categories and not args.stats:
|
|
print(f" Added Categories: {na}")
|
|
for cat in sorted(diff.added_categories):
|
|
print(f" + {cat}")
|
|
if diff.removed_categories and not args.stats:
|
|
print(f" Removed Categories: {nr}")
|
|
for cat in sorted(diff.removed_categories):
|
|
print(f" - {cat}")
|
|
if diff.modified_categories and not args.stats:
|
|
print(f" Modified Categories: {nm}")
|
|
for mcat in sorted(diff.modified_categories):
|
|
change = []
|
|
if mcat.added_aliases:
|
|
change.append(f"{len(mcat.added_aliases)} Added Aliases")
|
|
if mcat.removed_aliases:
|
|
change.append(f"{len(mcat.removed_aliases)} Removed Aliases")
|
|
|
|
print(f" * {mcat.category.name} ({', '.join(change)})")
|
|
print(" Aliases:")
|
|
for alias in sorted(mcat.added_aliases):
|
|
print(f" + {alias}")
|
|
for alias in sorted(mcat.removed_aliases):
|
|
print(f" - {alias}")
|
|
|
|
print()
|
|
del diff.added_categories
|
|
del diff.removed_categories
|
|
del diff.modified_categories
|
|
|
|
if all_differences or args.sensitivity:
|
|
if diff.added_sensitivities or diff.removed_sensitivities or diff.modified_sensitivities \
|
|
or args.sensitivity:
|
|
na = len(diff.added_sensitivities)
|
|
nr = len(diff.removed_sensitivities)
|
|
nm = len(diff.modified_sensitivities)
|
|
print(f"Sensitivities ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_sensitivities and not args.stats:
|
|
print(f" Added Sensitivities: {na}")
|
|
for sens in sorted(diff.added_sensitivities):
|
|
print(f" + {sens}")
|
|
if diff.removed_sensitivities and not args.stats:
|
|
print(f" Removed Sensitivities: {nr}")
|
|
for sens in sorted(diff.removed_sensitivities):
|
|
print(f" - {sens}")
|
|
if diff.modified_sensitivities and not args.stats:
|
|
print(f" Modified Sensitivities: {nm}")
|
|
for msens in sorted(diff.modified_sensitivities):
|
|
change = []
|
|
if msens.added_aliases:
|
|
change.append(f"{len(msens.added_aliases)} Added Aliases")
|
|
if msens.removed_aliases:
|
|
change.append(f"{len(msens.removed_aliases)} Removed Aliases")
|
|
|
|
print(f" * {msens.sensitivity.name} ({', '.join(change)})")
|
|
print(" Aliases:")
|
|
for alias in sorted(msens.added_aliases):
|
|
print(f" + {alias}")
|
|
for alias in sorted(msens.removed_aliases):
|
|
print(f" - {alias}")
|
|
|
|
print()
|
|
del diff.added_sensitivities
|
|
del diff.removed_sensitivities
|
|
del diff.modified_sensitivities
|
|
|
|
if all_differences or args.level:
|
|
if diff.added_levels or diff.removed_levels or \
|
|
diff.modified_levels or args.level:
|
|
na = len(diff.added_levels)
|
|
nr = len(diff.removed_levels)
|
|
nm = len(diff.modified_levels)
|
|
print(f"Levels ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_levels and not args.stats:
|
|
print(f" Added Levels: {na}")
|
|
for level in sorted(diff.added_levels):
|
|
print(f" + {level}")
|
|
if diff.removed_levels and not args.stats:
|
|
print(f" Removed Levels: {len(diff.removed_levels)}")
|
|
for level in sorted(diff.removed_levels):
|
|
print(f" - {level}")
|
|
if diff.modified_levels and not args.stats:
|
|
print(f" Modified Levels: {len(diff.modified_levels)}")
|
|
for mlevel in sorted(diff.modified_levels):
|
|
change = []
|
|
if mlevel.added_categories:
|
|
change.append(f"{len(mlevel.added_categories)} Added Categories")
|
|
if mlevel.removed_categories:
|
|
change.append(f"{len(mlevel.removed_categories)} Removed Categories")
|
|
|
|
print(f" * level {mlevel.level.sensitivity} ({', '.join(change)})")
|
|
for cat in sorted(mlevel.added_categories):
|
|
print(f" + {cat}")
|
|
for cat in sorted(mlevel.removed_categories):
|
|
print(f" - {cat}")
|
|
print()
|
|
del diff.added_levels
|
|
del diff.removed_levels
|
|
del diff.modified_levels
|
|
|
|
if all_differences or args.allow:
|
|
if diff.added_allows or diff.removed_allows or diff.modified_allows or args.allow:
|
|
na = len(diff.added_allows)
|
|
nr = len(diff.removed_allows)
|
|
nm = len(diff.modified_allows)
|
|
print(f"Allow Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_allows and not args.stats:
|
|
print(f" Added Allow Rules: {na}")
|
|
for avr in sorted(diff.added_allows):
|
|
print(f" + {avr}")
|
|
|
|
if diff.removed_allows and not args.stats:
|
|
print(f" Removed Allow Rules: {nr}")
|
|
for avr in sorted(diff.removed_allows):
|
|
print(f" - {avr}")
|
|
|
|
if diff.modified_allows and not args.stats:
|
|
print(f" Modified Allow Rules: {nm}")
|
|
|
|
for mavr in sorted(diff.modified_allows):
|
|
perm_str = " ".join(chain((p for p in mavr.matched_perms),
|
|
(f"+{p}" for p in mavr.added_perms),
|
|
(f"-{p}" for p in mavr.removed_perms)))
|
|
rule_string = f"{mavr.rule.ruletype} {mavr.rule.source} " \
|
|
f"{mavr.rule.target}:{mavr.rule.tclass} {{ {perm_str} }};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mavr.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_allows
|
|
del diff.removed_allows
|
|
del diff.modified_allows
|
|
|
|
if all_differences or args.allowxperm:
|
|
if diff.added_allowxperms or diff.removed_allowxperms or diff.modified_allowxperms \
|
|
or args.allowxperm:
|
|
na = len(diff.added_allowxperms)
|
|
nr = len(diff.removed_allowxperms)
|
|
nm = len(diff.modified_allowxperms)
|
|
print(f"Allowxperm Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_allowxperms and not args.stats:
|
|
print(f" Added Allowxperm Rules: {na}")
|
|
for avxr in sorted(diff.added_allowxperms):
|
|
print(f" + {avxr}")
|
|
|
|
if diff.removed_allowxperms and not args.stats:
|
|
print(f" Removed Allowxperm Rules: {nr}")
|
|
for avxr in sorted(diff.removed_allowxperms):
|
|
print(f" - {avxr}")
|
|
|
|
if diff.modified_allowxperms and not args.stats:
|
|
print(f" Modified Allowxperm Rules: {nm}")
|
|
|
|
for mavxr in sorted(diff.modified_allowxperms):
|
|
# Process the string representation of the sets
|
|
# so hex representation and ranges are preserved.
|
|
# Check if the perm sets have contents, otherwise
|
|
# split on empty string will be an empty string.
|
|
# Add brackets to added and removed permissions
|
|
# in case there is a range of permissions.
|
|
perms = []
|
|
if mavxr.matched_perms:
|
|
for p in str(mavxr.matched_perms).split(" "):
|
|
perms.append(p)
|
|
if mavxr.added_perms:
|
|
for p in str(mavxr.added_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"+[{p}]")
|
|
else:
|
|
perms.append(f"+{p}")
|
|
if mavxr.removed_perms:
|
|
for p in str(mavxr.removed_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"-[{p}]")
|
|
else:
|
|
perms.append(f"-{p}")
|
|
|
|
print(f" * {mavxr.rule.ruletype} {mavxr.rule.source} "
|
|
f"{mavxr.rule.target}:{mavxr.rule.tclass} {mavxr.rule.xperm_type} "
|
|
f"{{ {' '.join(perms)} }};")
|
|
|
|
print()
|
|
del diff.added_allowxperms
|
|
del diff.removed_allowxperms
|
|
del diff.modified_allowxperms
|
|
|
|
if all_differences or args.neverallow:
|
|
if diff.added_neverallows or diff.removed_neverallows or diff.modified_neverallows or \
|
|
args.neverallow:
|
|
na = len(diff.added_neverallows)
|
|
nr = len(diff.removed_neverallows)
|
|
nm = len(diff.modified_neverallows)
|
|
print(f"Neverallow Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_neverallows and not args.stats:
|
|
print(f" Added Neverallow Rules: {na}")
|
|
for avr in sorted(diff.added_neverallows):
|
|
print(f" + {avr}")
|
|
|
|
if diff.removed_neverallows and not args.stats:
|
|
print(f" Removed Neverallow Rules: {nr}")
|
|
for avr in sorted(diff.removed_neverallows):
|
|
print(f" - {avr}")
|
|
|
|
if diff.modified_neverallows and not args.stats:
|
|
print(f" Modified Neverallow Rules: {nm}")
|
|
|
|
for mavr in sorted(diff.modified_neverallows):
|
|
perm_str = " ".join(chain((p for p in mavr.matched_perms),
|
|
("+" + p for p in mavr.added_perms),
|
|
("-" + p for p in mavr.removed_perms)))
|
|
rule_string = f"{mavr.rule.ruletype} {mavr.rule.source} " \
|
|
f"{mavr.rule.target}:{mavr.rule.tclass} {{ {perm_str} }};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mavr.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_neverallows
|
|
del diff.removed_neverallows
|
|
del diff.modified_neverallows
|
|
|
|
if all_differences or args.neverallowxperm:
|
|
if diff.added_neverallowxperms or diff.removed_neverallowxperms or \
|
|
diff.modified_neverallowxperms or args.neverallowxperm:
|
|
na = len(diff.added_neverallowxperms)
|
|
nr = len(diff.removed_neverallowxperms)
|
|
nm = len(diff.modified_neverallowxperms)
|
|
print(f"Neverallowxperm Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_neverallowxperms and not args.stats:
|
|
print(f" Added Neverallowxperm Rules: {na}")
|
|
for avxr in sorted(diff.added_neverallowxperms):
|
|
print(f" + {avxr}")
|
|
|
|
if diff.removed_neverallowxperms and not args.stats:
|
|
print(f" Removed Neverallowxperm Rules: {nr}")
|
|
for avxr in sorted(diff.removed_neverallowxperms):
|
|
print(f" - {avxr}")
|
|
|
|
if diff.modified_neverallowxperms and not args.stats:
|
|
print(f" Modified Neverallowxperm Rules: {nm}")
|
|
|
|
for mavxr in sorted(diff.modified_neverallowxperms):
|
|
|
|
# Process the string representation of the sets
|
|
# so hex representation and ranges are preserved.
|
|
# Check if the perm sets have contents, otherwise
|
|
# split on empty string will be an empty string.
|
|
# Add brackets to added and removed permissions
|
|
# in case there is a range of permissions.
|
|
perms = []
|
|
if mavxr.matched_perms:
|
|
for p in str(mavxr.matched_perms).split(" "):
|
|
perms.append(p)
|
|
if mavxr.added_perms:
|
|
for p in str(mavxr.added_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"+[{p}]")
|
|
else:
|
|
perms.append(f"+{p}")
|
|
if mavxr.removed_perms:
|
|
for p in str(mavxr.removed_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"-[{p}]")
|
|
else:
|
|
perms.append(f"-{p}")
|
|
|
|
print(f" * {mavxr.rule.ruletype} {mavxr.rule.source} "
|
|
f"{mavxr.rule.target}:{mavxr.rule.tclass} "
|
|
f"{mavxr.rule.xperm_type} {{ {' '.join(perms)} }};")
|
|
|
|
print()
|
|
del diff.added_neverallowxperms
|
|
del diff.removed_neverallowxperms
|
|
del diff.modified_neverallowxperms
|
|
|
|
if all_differences or args.auditallow:
|
|
if diff.added_auditallows or diff.removed_auditallows or diff.modified_auditallows or \
|
|
args.auditallow:
|
|
na = len(diff.added_auditallows)
|
|
nr = len(diff.removed_auditallows)
|
|
nm = len(diff.modified_auditallows)
|
|
print(f"Auditallow Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_auditallows and not args.stats:
|
|
print(f" Added Auditallow Rules: {na}")
|
|
for avr in sorted(diff.added_auditallows):
|
|
print(f" + {avr}")
|
|
|
|
if diff.removed_auditallows and not args.stats:
|
|
print(f" Removed Auditallow Rules: {nr}")
|
|
for avr in sorted(diff.removed_auditallows):
|
|
print(f" - {avr}")
|
|
|
|
if diff.modified_auditallows and not args.stats:
|
|
print(f" Modified Auditallow Rules: {nm}")
|
|
|
|
for mavr in sorted(diff.modified_auditallows):
|
|
perm_str = " ".join(chain((p for p in mavr.matched_perms),
|
|
("+" + p for p in mavr.added_perms),
|
|
("-" + p for p in mavr.removed_perms)))
|
|
rule_string = f"{mavr.rule.ruletype} {mavr.rule.source} " \
|
|
f"{mavr.rule.target}:{mavr.rule.tclass} {{ {perm_str} }};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mavr.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_auditallows
|
|
del diff.removed_auditallows
|
|
del diff.modified_auditallows
|
|
|
|
if all_differences or args.auditallowxperm:
|
|
if diff.added_auditallowxperms or diff.removed_auditallowxperms or \
|
|
diff.modified_auditallowxperms or args.auditallowxperm:
|
|
|
|
na = len(diff.added_auditallowxperms)
|
|
nr = len(diff.removed_auditallowxperms)
|
|
nm = len(diff.modified_auditallowxperms)
|
|
print(f"Auditallowxperm Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_auditallowxperms and not args.stats:
|
|
print(f" Added Auditallowxperm Rules: {na}")
|
|
for avxr in sorted(diff.added_auditallowxperms):
|
|
print(f" + {avxr}")
|
|
|
|
if diff.removed_auditallowxperms and not args.stats:
|
|
print(f" Removed Auditallowxperm Rules: {nr}")
|
|
for avxr in sorted(diff.removed_auditallowxperms):
|
|
print(f" - {avxr}")
|
|
|
|
if diff.modified_auditallowxperms and not args.stats:
|
|
print(f" Modified Auditallowxperm Rules: {nm}")
|
|
|
|
for mavxr in sorted(diff.modified_auditallowxperms):
|
|
|
|
# Process the string representation of the sets
|
|
# so hex representation and ranges are preserved.
|
|
# Check if the perm sets have contents, otherwise
|
|
# split on empty string will be an empty string.
|
|
# Add brackets to added and removed permissions
|
|
# in case there is a range of permissions.
|
|
perms = []
|
|
if mavxr.matched_perms:
|
|
for p in str(mavxr.matched_perms).split(" "):
|
|
perms.append(p)
|
|
if mavxr.added_perms:
|
|
for p in str(mavxr.added_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"+[{p}]")
|
|
else:
|
|
perms.append(f"+{p}")
|
|
if mavxr.removed_perms:
|
|
for p in str(mavxr.removed_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"-[{p}]")
|
|
else:
|
|
perms.append(f"-{p}")
|
|
|
|
print(f" * {mavxr.rule.ruletype} {mavxr.rule.source} "
|
|
f"{mavxr.rule.target}:{mavxr.rule.tclass} "
|
|
f"{mavxr.rule.xperm_type} {{ {' '.join(perms)} }};")
|
|
|
|
print()
|
|
del diff.added_auditallowxperms
|
|
del diff.removed_auditallowxperms
|
|
del diff.modified_auditallowxperms
|
|
|
|
if all_differences or args.dontaudit:
|
|
if diff.added_dontaudits or diff.removed_dontaudits or diff.modified_dontaudits or \
|
|
args.dontaudit:
|
|
|
|
na = len(diff.added_dontaudits)
|
|
nr = len(diff.removed_dontaudits)
|
|
nm = len(diff.modified_dontaudits)
|
|
print(f"Dontaudit Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_dontaudits and not args.stats:
|
|
print(f" Added Dontaudit Rules: {na}")
|
|
for avr in sorted(diff.added_dontaudits):
|
|
print(f" + {avr}")
|
|
|
|
if diff.removed_dontaudits and not args.stats:
|
|
print(f" Removed Dontaudit Rules: {nr}")
|
|
for avr in sorted(diff.removed_dontaudits):
|
|
print(f" - {avr}")
|
|
|
|
if diff.modified_dontaudits and not args.stats:
|
|
print(f" Modified Dontaudit Rules: {nm}")
|
|
|
|
for mavr in sorted(diff.modified_dontaudits):
|
|
perm_str = " ".join(chain((p for p in mavr.matched_perms),
|
|
("+" + p for p in mavr.added_perms),
|
|
("-" + p for p in mavr.removed_perms)))
|
|
rule_string = f"{mavr.rule.ruletype} {mavr.rule.source} " \
|
|
f"{mavr.rule.target}:{mavr.rule.tclass} {{ {perm_str} }};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mavr.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_dontaudits
|
|
del diff.removed_dontaudits
|
|
del diff.modified_dontaudits
|
|
|
|
if all_differences or args.dontauditxperm:
|
|
if diff.added_dontauditxperms or diff.removed_dontauditxperms or \
|
|
diff.modified_dontauditxperms or args.dontauditxperm:
|
|
|
|
na = len(diff.added_dontauditxperms)
|
|
nr = len(diff.removed_dontauditxperms)
|
|
nm = len(diff.modified_dontauditxperms)
|
|
print(f"Dontauditxperm Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_dontauditxperms and not args.stats:
|
|
print(f" Added Dontauditxperm Rules: {na}")
|
|
for avxr in sorted(diff.added_dontauditxperms):
|
|
print(f" + {avxr}")
|
|
|
|
if diff.removed_dontauditxperms and not args.stats:
|
|
print(f" Removed Dontauditxperm Rules: {nr}")
|
|
for avxr in sorted(diff.removed_dontauditxperms):
|
|
print(f" - {avxr}")
|
|
|
|
if diff.modified_dontauditxperms and not args.stats:
|
|
print(f" Modified Dontauditxperm Rules: {nm}")
|
|
|
|
for mavxr in sorted(diff.modified_dontauditxperms):
|
|
|
|
# Process the string representation of the sets
|
|
# so hex representation and ranges are preserved.
|
|
# Check if the perm sets have contents, otherwise
|
|
# split on empty string will be an empty string.
|
|
# Add brackets to added and removed permissions
|
|
# in case there is a range of permissions.
|
|
perms = []
|
|
if mavxr.matched_perms:
|
|
for p in str(mavxr.matched_perms).split(" "):
|
|
perms.append(p)
|
|
if mavxr.added_perms:
|
|
for p in str(mavxr.added_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"+[{p}]")
|
|
else:
|
|
perms.append(f"+{p}")
|
|
if mavxr.removed_perms:
|
|
for p in str(mavxr.removed_perms).split(" "):
|
|
if '-' in p:
|
|
perms.append(f"-[{p}]")
|
|
else:
|
|
perms.append(f"-{p}")
|
|
|
|
print(f" * {mavxr.rule.ruletype} {mavxr.rule.source} "
|
|
f"{mavxr.rule.target}:{mavxr.rule.tclass} "
|
|
f"{mavxr.rule.xperm_type} {{ {' '.join(perms)} }};")
|
|
|
|
print()
|
|
del diff.added_dontauditxperms
|
|
del diff.removed_dontauditxperms
|
|
del diff.modified_dontauditxperms
|
|
|
|
if all_differences or args.type_trans:
|
|
if diff.added_type_transitions or diff.removed_type_transitions or \
|
|
diff.modified_type_transitions or args.type_trans:
|
|
|
|
na = len(diff.added_type_transitions)
|
|
nr = len(diff.removed_type_transitions)
|
|
nm = len(diff.modified_type_transitions)
|
|
print(f"Type_transition Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_type_transitions and not args.stats:
|
|
print(f" Added Type_transition Rules: {na}")
|
|
for ter in sorted(diff.added_type_transitions):
|
|
print(f" + {ter}")
|
|
|
|
if diff.removed_type_transitions and not args.stats:
|
|
print(f" Removed Type_transition Rules: {nr}")
|
|
for ter in sorted(diff.removed_type_transitions):
|
|
print(f" - {ter}")
|
|
|
|
if diff.modified_type_transitions and not args.stats:
|
|
print(f" Modified Type_transition Rules: {nm}")
|
|
|
|
for mter in sorted(diff.modified_type_transitions):
|
|
rule_string = \
|
|
f"{mter.rule.ruletype} {mter.rule.source} " \
|
|
f"{mter.rule.target}:{mter.rule.tclass} " \
|
|
f"+{mter.added_default} -{mter.removed_default}"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" {mter.rule.filename}"
|
|
|
|
rule_string += ";"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mter.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_type_transitions
|
|
del diff.removed_type_transitions
|
|
del diff.modified_type_transitions
|
|
|
|
if all_differences or args.type_change:
|
|
if diff.added_type_changes or diff.removed_type_changes or \
|
|
diff.modified_type_changes or args.type_change:
|
|
|
|
na = len(diff.added_type_changes)
|
|
nr = len(diff.removed_type_changes)
|
|
nm = len(diff.modified_type_changes)
|
|
print(f"Type_change Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_type_changes and not args.stats:
|
|
print(f" Added Type_change Rules: {na}")
|
|
for ter in sorted(diff.added_type_changes):
|
|
print(f" + {ter}")
|
|
|
|
if diff.removed_type_changes and not args.stats:
|
|
print(f" Removed Type_change Rules: {nr}")
|
|
for ter in sorted(diff.removed_type_changes):
|
|
print(f" - {ter}")
|
|
|
|
if diff.modified_type_changes and not args.stats:
|
|
print(f" Modified Type_change Rules: {nm}")
|
|
|
|
for mter in sorted(diff.modified_type_changes):
|
|
rule_string = \
|
|
f"{mter.rule.ruletype} {mter.rule.source} " \
|
|
f"{mter.rule.target}:{mter.rule.tclass} " \
|
|
f"+{mter.added_default} -{mter.removed_default};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mter.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_type_changes
|
|
del diff.removed_type_changes
|
|
del diff.modified_type_changes
|
|
|
|
if all_differences or args.type_member:
|
|
if diff.added_type_members or diff.removed_type_members or \
|
|
diff.modified_type_members or args.type_member:
|
|
|
|
na = len(diff.added_type_members)
|
|
nr = len(diff.removed_type_members)
|
|
nm = len(diff.modified_type_members)
|
|
print(f"Type_member Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_type_members and not args.stats:
|
|
print(f" Added Type_member Rules: {na}")
|
|
for ter in sorted(diff.added_type_members):
|
|
print(f" + {ter}")
|
|
|
|
if diff.removed_type_members and not args.stats:
|
|
print(f" Removed Type_member Rules: {nr}")
|
|
for ter in sorted(diff.removed_type_members):
|
|
print(f" - {ter}")
|
|
|
|
if diff.modified_type_members and not args.stats:
|
|
print(f" Modified Type_member Rules: {nm}")
|
|
|
|
for mter in sorted(diff.modified_type_members):
|
|
rule_string = \
|
|
f"{mter.rule.ruletype} {mter.rule.source} " \
|
|
f"{mter.rule.target}:{mter.rule.tclass} " \
|
|
f"+{mter.added_default} -{mter.removed_default};"
|
|
|
|
with suppress(AttributeError):
|
|
rule_string += f" [ {mter.rule.conditional} ]"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_type_members
|
|
del diff.removed_type_members
|
|
del diff.modified_type_members
|
|
|
|
if all_differences or args.role_allow:
|
|
if diff.added_role_allows or diff.removed_role_allows or args.role_allow:
|
|
|
|
na = len(diff.added_role_allows)
|
|
nr = len(diff.removed_role_allows)
|
|
print(f"Role allow Rules ({na} Added, {nr} Removed)")
|
|
|
|
if diff.added_role_allows and not args.stats:
|
|
print(f" Added Role Allow Rules: {na}")
|
|
for ra in sorted(diff.added_role_allows):
|
|
print(f" + {ra}")
|
|
|
|
if diff.removed_role_allows and not args.stats:
|
|
print(f" Removed Role Allow Rules: {nr}")
|
|
for ra in sorted(diff.removed_role_allows):
|
|
print(f" - {ra}")
|
|
|
|
print()
|
|
del diff.added_role_allows
|
|
del diff.removed_role_allows
|
|
|
|
if all_differences or args.role_trans:
|
|
if diff.added_role_transitions or diff.removed_role_transitions or \
|
|
diff.modified_role_transitions or args.role_trans:
|
|
|
|
na = len(diff.added_role_transitions)
|
|
nr = len(diff.removed_role_transitions)
|
|
nm = len(diff.modified_role_transitions)
|
|
print(f"Role_transition Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_role_transitions and not args.stats:
|
|
print(f" Added Role_transition Rules: {na}")
|
|
for rotr in sorted(diff.added_role_transitions):
|
|
print(f" + {rotr}")
|
|
|
|
if diff.removed_role_transitions and not args.stats:
|
|
print(f" Removed Role_transition Rules: {nr}")
|
|
for rotr in sorted(diff.removed_role_transitions):
|
|
print(f" - {rotr}")
|
|
|
|
if diff.modified_role_transitions and not args.stats:
|
|
print(f" Modified Role_transition Rules: {nm}")
|
|
|
|
for mrotr in sorted(diff.modified_role_transitions):
|
|
rule_string = \
|
|
f"{mrotr.rule.ruletype} {mrotr.rule.source} " \
|
|
f"{mrotr.rule.target}:{mrotr.rule.tclass} " \
|
|
f"+{mrotr.added_default} -{mrotr.removed_default};"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_role_transitions
|
|
del diff.removed_role_transitions
|
|
del diff.modified_role_transitions
|
|
|
|
if all_differences or args.range_trans:
|
|
if diff.added_range_transitions or diff.removed_range_transitions or \
|
|
diff.modified_range_transitions or args.range_trans:
|
|
|
|
na = len(diff.added_range_transitions)
|
|
nr = len(diff.removed_range_transitions)
|
|
nm = len(diff.modified_range_transitions)
|
|
print(f"Range_transition Rules ({na} Added, {nr} Removed, {nm} Modified)")
|
|
|
|
if diff.added_range_transitions and not args.stats:
|
|
print(f" Added Range_transition Rules: {na}")
|
|
for ratr in sorted(diff.added_range_transitions):
|
|
print(f" + {ratr}")
|
|
|
|
if diff.removed_range_transitions and not args.stats:
|
|
print(f" Removed Range_transition Rules: {nr}")
|
|
for ratr in sorted(diff.removed_range_transitions):
|
|
print(f" - {ratr}")
|
|
|
|
if diff.modified_range_transitions and not args.stats:
|
|
print(f" Modified Range_transition Rules: {nm}")
|
|
|
|
for mratr in sorted(diff.modified_range_transitions):
|
|
# added brackets around range change for clarity since ranges
|
|
# can have '-' and spaces.
|
|
rule_string = \
|
|
f"{mratr.rule.ruletype} {mratr.rule.source} " \
|
|
f"{mratr.rule.target}:{mratr.rule.tclass} " \
|
|
f"+[{mratr.added_default}] -[{mratr.removed_default}];"
|
|
|
|
print(f" * {rule_string}")
|
|
|
|
print()
|
|
del diff.added_range_transitions
|
|
del diff.removed_range_transitions
|
|
del diff.modified_range_transitions
|
|
|
|
if all_differences or args.constrain:
|
|
if diff.added_constrains or diff.removed_constrains or args.constrain:
|
|
na = len(diff.added_constrains)
|
|
nr = len(diff.removed_constrains)
|
|
print(f"Constraints ({na} Added, {nr} Removed)")
|
|
|
|
if diff.added_constrains and not args.stats:
|
|
print(f" Added Constraints: {na}")
|
|
for constraint in sorted(diff.added_constrains):
|
|
print(f" + {constraint}")
|
|
|
|
if diff.removed_constrains and not args.stats:
|
|
print(f" Removed Constraints: {nr}")
|
|
for constraint in sorted(diff.removed_constrains):
|
|
print(f" - {constraint}")
|
|
|
|
print()
|
|
del diff.added_constrains
|
|
del diff.removed_constrains
|
|
|
|
if all_differences or args.mlsconstrain:
|
|
if diff.added_mlsconstrains or diff.removed_mlsconstrains or args.mlsconstrain:
|
|
na = len(diff.added_mlsconstrains)
|
|
nr = len(diff.removed_mlsconstrains)
|
|
print(f"MLS Constraints ({na} Added, {nr} Removed)")
|
|
|
|
if diff.added_mlsconstrains and not args.stats:
|
|
print(f" Added MLS Constraints: {na}")
|
|
for constraint in sorted(diff.added_mlsconstrains):
|
|
print(f" + {constraint}")
|
|
|
|
if diff.removed_mlsconstrains and not args.stats:
|
|
print(f" Removed MLS Constraints: {nr}")
|
|
for constraint in sorted(diff.removed_mlsconstrains):
|
|
print(f" - {constraint}")
|
|
|
|
print()
|
|
del diff.added_mlsconstrains
|
|
del diff.removed_mlsconstrains
|
|
|
|
if all_differences or args.validatetrans:
|
|
if diff.added_validatetrans or diff.removed_validatetrans or args.validatetrans:
|
|
na = len(diff.added_validatetrans)
|
|
nr = len(diff.removed_validatetrans)
|
|
print(f"Validatetrans ({na} Added, {nr} Removed)")
|
|
|
|
if diff.added_validatetrans and not args.stats:
|
|
print(f" Added Validatetrans: {na}")
|
|
for validatetrans in sorted(diff.added_validatetrans):
|
|
print(f" + {validatetrans}")
|
|
|
|
if diff.removed_validatetrans and not args.stats:
|
|
print(f" Removed Validatetrans: {nr}")
|
|
for validatetrans in sorted(diff.removed_validatetrans):
|
|
print(f" - {validatetrans}")
|
|
|
|
print()
|
|
del diff.added_validatetrans
|
|
del diff.removed_validatetrans
|
|
|
|
if all_differences or args.mlsvalidatetrans:
|
|
if diff.added_mlsvalidatetrans or diff.removed_mlsvalidatetrans or args.mlsvalidatetrans:
|
|
na = len(diff.added_mlsvalidatetrans)
|
|
nr = len(diff.removed_mlsvalidatetrans)
|
|
print(f"MLS Validatetrans ({na} Added, {nr} Removed)")
|
|
|
|
if diff.added_mlsvalidatetrans and not args.stats:
|
|
print(f" Added MLS Validatetrans: {na}")
|
|
for validatetrans in sorted(diff.added_mlsvalidatetrans):
|
|
print(f" + {validatetrans}")
|
|
|
|
if diff.removed_mlsvalidatetrans and not args.stats:
|
|
print(f" Removed MLS Validatetrans: {nr}")
|
|
for validatetrans in sorted(diff.removed_mlsvalidatetrans):
|
|
print(f" - {validatetrans}")
|
|
|
|
print()
|
|
del diff.added_mlsvalidatetrans
|
|
del diff.removed_mlsvalidatetrans
|
|
|
|
if all_differences or args.initialsid:
|
|
if diff.added_initialsids or diff.removed_initialsids or diff.modified_initialsids \
|
|
or args.initialsid:
|
|
na = len(diff.added_initialsids)
|
|
nr = len(diff.removed_initialsids)
|
|
nm = len(diff.modified_initialsids)
|
|
print(f"Initial SIDs ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_initialsids and not args.stats:
|
|
print(f" Added Initial SIDs: {na}")
|
|
for isid in sorted(diff.added_initialsids):
|
|
print(f" + {isid.statement()}")
|
|
if diff.removed_initialsids and not args.stats:
|
|
print(f" Removed Initial SIDs: {nr}")
|
|
for isid in sorted(diff.removed_initialsids):
|
|
print(f" - {isid.statement()}")
|
|
if diff.modified_initialsids and not args.stats:
|
|
print(f" Modified Initial SIDs: {nm}")
|
|
for misid in sorted(diff.modified_initialsids):
|
|
print(f" * sid {misid.isid.name} +[{misid.added_context}] "
|
|
f"-[{misid.removed_context}];")
|
|
|
|
print()
|
|
del diff.added_initialsids
|
|
del diff.removed_initialsids
|
|
del diff.modified_initialsids
|
|
|
|
if all_differences or args.ibendportcon:
|
|
if diff.added_ibendportcons or diff.removed_ibendportcons or diff.modified_ibendportcons \
|
|
or args.ibendportcon:
|
|
na = len(diff.added_ibendportcons)
|
|
nr = len(diff.removed_ibendportcons)
|
|
nm = len(diff.modified_ibendportcons)
|
|
print(f"Ibendportcons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_ibendportcons and not args.stats:
|
|
print(f" Added Ibendportcons: {na}")
|
|
for ibp in sorted(diff.added_ibendportcons):
|
|
print(f" + {ibp}")
|
|
if diff.removed_ibendportcons and not args.stats:
|
|
print(f" Removed Ibendportcons: {nr}")
|
|
for ibp in sorted(diff.removed_ibendportcons):
|
|
print(f" - {ibp}")
|
|
if diff.modified_ibendportcons and not args.stats:
|
|
print(f" Modified Ibendportcons: {nm}")
|
|
for mibp in sorted(diff.modified_ibendportcons):
|
|
print(f" * ibendportcon {mibp.rule.name} {mibp.rule.port} "
|
|
f"+[{mibp.added_context}] -[{mibp.removed_context}]")
|
|
|
|
print()
|
|
del diff.added_ibendportcons
|
|
del diff.removed_ibendportcons
|
|
del diff.modified_ibendportcons
|
|
|
|
if all_differences or args.ibpkeycon:
|
|
if diff.added_ibpkeycons or diff.removed_ibpkeycons or diff.modified_ibpkeycons \
|
|
or args.ibpkeycon:
|
|
na = len(diff.added_ibpkeycons)
|
|
nr = len(diff.removed_ibpkeycons)
|
|
nm = len(diff.modified_ibpkeycons)
|
|
print(f"Ibpkeycons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_ibpkeycons and not args.stats:
|
|
print(f" Added Ibpkeycons: {na}")
|
|
for ibpk in sorted(diff.added_ibpkeycons):
|
|
print(f" + {ibpk}")
|
|
if diff.removed_ibpkeycons and not args.stats:
|
|
print(f" Removed Ibpkeycons: {nr}")
|
|
for ibpk in sorted(diff.removed_ibpkeycons):
|
|
print(f" - {ibpk}")
|
|
if diff.modified_ibpkeycons and not args.stats:
|
|
print(f" Modified Ibpkeycons: {nm}")
|
|
for mibpk in sorted(diff.modified_ibpkeycons):
|
|
if mibpk.rule.pkeys.low == mibpk.rule.pkeys.high:
|
|
print(f" * ibpkeycon {mibpk.rule.subnet_prefix} "
|
|
f"{mibpk.rule.pkeys.low:#x} +[{mibpk.added_context}] "
|
|
f"-[{mibpk.removed_context}]")
|
|
else:
|
|
print(f" * ibpkeycon {mibpk.rule.subnet_prefix} "
|
|
f"{mibpk.rule.pkeys.low:#x}-{mibpk.rule.pkeys.high:#x} "
|
|
f"+[{mibpk.added_context}] -[{mibpk.removed_context}]")
|
|
|
|
print()
|
|
del diff.added_ibpkeycons
|
|
del diff.removed_ibpkeycons
|
|
del diff.modified_ibpkeycons
|
|
|
|
if all_differences or args.fs_use:
|
|
if diff.added_fs_uses or diff.removed_fs_uses or diff.modified_fs_uses \
|
|
or args.fs_use:
|
|
na = len(diff.added_fs_uses)
|
|
nr = len(diff.removed_fs_uses)
|
|
nm = len(diff.modified_fs_uses)
|
|
print(f"Fs_use ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_fs_uses and not args.stats:
|
|
print(f" Added Fs_use: {na}")
|
|
for fsu in sorted(diff.added_fs_uses):
|
|
print(f" + {fsu}")
|
|
if diff.removed_fs_uses and not args.stats:
|
|
print(f" Removed Fs_use: {nr}")
|
|
for fsu in sorted(diff.removed_fs_uses):
|
|
print(f" - {fsu}")
|
|
if diff.modified_fs_uses and not args.stats:
|
|
print(f" Modified Fs_use: {nm}")
|
|
for mfsu in sorted(diff.modified_fs_uses):
|
|
print(f" * {mfsu.rule.ruletype} {mfsu.rule.fs} "
|
|
f"+[{mfsu.added_context}] -[{mfsu.removed_context}];")
|
|
|
|
print()
|
|
del diff.added_fs_uses
|
|
del diff.removed_fs_uses
|
|
del diff.modified_fs_uses
|
|
|
|
if all_differences or args.genfscon:
|
|
if diff.added_genfscons or diff.removed_genfscons or diff.modified_genfscons \
|
|
or args.genfscon:
|
|
na = len(diff.added_genfscons)
|
|
nr = len(diff.removed_genfscons)
|
|
nm = len(diff.modified_genfscons)
|
|
print(f"Genfscons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_genfscons and not args.stats:
|
|
print(f" Added Genfscons: {na}")
|
|
for genfs in sorted(diff.added_genfscons):
|
|
print(f" + {genfs}")
|
|
if diff.removed_genfscons and not args.stats:
|
|
print(f" Removed Genfscons: {nr}")
|
|
for genfs in sorted(diff.removed_genfscons):
|
|
print(f" - {genfs}")
|
|
if diff.modified_genfscons and not args.stats:
|
|
print(f" Modified Genfscons: {nm}")
|
|
for mgenfs in sorted(diff.modified_genfscons):
|
|
print(f" * genfscon {mgenfs.rule.fs} {mgenfs.rule.path} "
|
|
f"{mgenfs.rule.filetype} +[{mgenfs.added_context}] "
|
|
f"-[{mgenfs.removed_context}];")
|
|
|
|
print()
|
|
del diff.added_genfscons
|
|
del diff.removed_genfscons
|
|
del diff.modified_genfscons
|
|
|
|
if all_differences or args.netifcon:
|
|
if diff.added_netifcons or diff.removed_netifcons or \
|
|
diff.modified_netifcons or args.netifcon:
|
|
na = len(diff.added_netifcons)
|
|
nr = len(diff.removed_netifcons)
|
|
nm = len(diff.modified_netifcons)
|
|
print(f"Netifcons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_netifcons and not args.stats:
|
|
print(f" Added Netifcons: {na}")
|
|
for netif in sorted(diff.added_netifcons):
|
|
print(f" + {netif}")
|
|
if diff.removed_netifcons and not args.stats:
|
|
print(f" Removed Netifcons: {nr}")
|
|
for netif in sorted(diff.removed_netifcons):
|
|
print(f" - {netif}")
|
|
if diff.modified_netifcons and not args.stats:
|
|
print(f" Modified Netifcons: {nm}")
|
|
for mnetif in sorted(diff.modified_netifcons):
|
|
# This output is different than other statements because
|
|
# it becomes difficult to read if this was condensed
|
|
# into a single line, especially if both contexts
|
|
# are modified.
|
|
change = []
|
|
if mnetif.removed_context:
|
|
change.append("Modified Context")
|
|
if mnetif.removed_packet:
|
|
change.append("Modified Packet Context")
|
|
|
|
print(f" * netif {mnetif.rule.netif} ({', '.join(change)})")
|
|
|
|
if mnetif.removed_context:
|
|
print(" Context:")
|
|
print(f" + {mnetif.added_context}")
|
|
print(f" - {mnetif.removed_context}")
|
|
if mnetif.removed_packet:
|
|
print(" Packet Context:")
|
|
print(f" + {mnetif.added_packet}")
|
|
print(f" - {mnetif.removed_packet}")
|
|
|
|
print()
|
|
del diff.added_netifcons
|
|
del diff.removed_netifcons
|
|
del diff.modified_netifcons
|
|
|
|
if all_differences or args.nodecon:
|
|
if diff.added_nodecons or diff.removed_nodecons or diff.modified_nodecons \
|
|
or args.nodecon:
|
|
na = len(diff.added_nodecons)
|
|
nr = len(diff.removed_nodecons)
|
|
nm = len(diff.modified_nodecons)
|
|
print(f"Nodecons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_nodecons and not args.stats:
|
|
print(f" Added Nodecons: {na}")
|
|
for node in sorted(diff.added_nodecons):
|
|
print(f" + {node}")
|
|
if diff.removed_nodecons and not args.stats:
|
|
print(f" Removed Nodecons: {nr}")
|
|
for node in sorted(diff.removed_nodecons):
|
|
print(f" - {node}")
|
|
if diff.modified_nodecons and not args.stats:
|
|
print(f" Modified Nodecons: {nm}")
|
|
for mnode in sorted(diff.modified_nodecons):
|
|
print(f" * nodecon {mnode.rule.network.with_netmask.replace('/', ' ')} "
|
|
f"+[{mnode.added_context}] -[{mnode.removed_context}];")
|
|
|
|
print()
|
|
del diff.added_nodecons
|
|
del diff.removed_nodecons
|
|
del diff.modified_nodecons
|
|
|
|
if all_differences or args.portcon:
|
|
if diff.added_portcons or diff.removed_portcons or diff.modified_portcons \
|
|
or args.portcon:
|
|
na = len(diff.added_portcons)
|
|
nr = len(diff.removed_portcons)
|
|
nm = len(diff.modified_portcons)
|
|
print(f"Portcons ({na} Added, {nr} Removed, {nm} Modified)")
|
|
if diff.added_portcons and not args.stats:
|
|
print(f" Added Portcons: {na}")
|
|
for port in sorted(diff.added_portcons):
|
|
print(f" + {port}")
|
|
if diff.removed_portcons and not args.stats:
|
|
print(f" Removed Portcons: {nr}")
|
|
for port in sorted(diff.removed_portcons):
|
|
print(f" - {port}")
|
|
if diff.modified_portcons and not args.stats:
|
|
print(f" Modified Portcons: {nm}")
|
|
for mport in sorted(diff.modified_portcons):
|
|
low, high = mport.rule.ports.low, mport.rule.ports.high
|
|
if low == high:
|
|
print(f" * portcon {mport.rule.protocol} {low} "
|
|
f"+[{mport.added_context}] -[{mport.removed_context}];")
|
|
else:
|
|
print(f" * portcon {mport.rule.protocol} {low}-{high} "
|
|
f"+[{mport.added_context}] -[{mport.removed_context}];")
|
|
|
|
print()
|
|
del diff.added_portcons
|
|
del diff.removed_portcons
|
|
del diff.modified_portcons
|
|
|
|
except AssertionError:
|
|
# Always provide a traceback for assertion errors
|
|
raise
|
|
|
|
except Exception as err:
|
|
if args.debug:
|
|
raise
|
|
else:
|
|
print(err)
|
|
|
|
sys.exit(1)
|