mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
setools-V4: Add updates for testing V30 xen and xperms
Add updates to seinfo and sesearch to test libqpol updates added via [1]. Also include extra tests for Xen and xperms. Note, xperms cannot yet test the extended perms as needs more work on libqpol. [1] 0001-setools-V4-libqpol-policy-V30-updates-xen-xperm-stat.patch Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
This commit is contained in:
parent
dd29dc9c43
commit
3532ed2fff
89
seinfo
89
seinfo
@ -85,6 +85,18 @@ queries.add_argument("--typebounds", help="Print typebounds statements.", dest="
|
||||
nargs='?', const=True, metavar="BOUND_TYPE")
|
||||
queries.add_argument("--validatetrans", help="Print validatetrans.", dest="validatetransquery",
|
||||
nargs='?', const=True, metavar="CLASS")
|
||||
#### Xen statements
|
||||
queries.add_argument("--ioportcon", help="Print all ioportcon statements.", dest="ioportconquery",
|
||||
default=False, action="store_true")
|
||||
queries.add_argument("--iomemcon", help="Print all iomemcon statements.", dest="iomemconquery",
|
||||
default=False, action="store_true")
|
||||
queries.add_argument("--pcidevicecon", help="Print all pcidevicecon statements.",
|
||||
dest="pcideviceconquery", default=False, action="store_true")
|
||||
queries.add_argument("--pirqcon", help="Print all pirqcon statements.", dest="pirqconquery",
|
||||
default=False, action="store_true")
|
||||
queries.add_argument("--devicetreecon", help="Print all devicetreecon statements.", dest="devicetreeconquery",
|
||||
default=False, action="store_true")
|
||||
####
|
||||
queries.add_argument("--all", help="Print all of the above.",
|
||||
dest="all", default=False, action="store_true")
|
||||
|
||||
@ -259,47 +271,82 @@ try:
|
||||
|
||||
components.append(("Validatetrans", q, lambda x: x.statement()))
|
||||
|
||||
if p.target_platform == "xen":
|
||||
if args.ioportconquery or args.all:
|
||||
q = setools.IoportconQuery(p)
|
||||
components.append(("Ioportcon", q, lambda x: x.statement()))
|
||||
|
||||
if args.iomemconquery or args.all:
|
||||
q = setools.IomemconQuery(p)
|
||||
components.append(("Iomemcon", q, lambda x: x.statement()))
|
||||
|
||||
if args.pcideviceconquery or args.all:
|
||||
q = setools.PcideviceconQuery(p)
|
||||
components.append(("Pcidevicecon", q, lambda x: x.statement()))
|
||||
|
||||
if args.pirqconquery or args.all:
|
||||
q = setools.PirqconQuery(p)
|
||||
components.append(("Pirqcon", q, lambda x: x.statement()))
|
||||
|
||||
if args.devicetreeconquery or args.all:
|
||||
q = setools.DevicetreeconQuery(p)
|
||||
components.append(("Devicetreecon", q, lambda x: x.statement()))
|
||||
|
||||
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}, {2} unknown permissions)".format(
|
||||
p.version, mls, p.handle_unknown))
|
||||
print(" Classes: {0:7} Permissions: {1:7}".format(
|
||||
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(" Classes: {0:7} Permissions: {1:7}".format(
|
||||
p.class_count, p.permission_count))
|
||||
print(" Sensitivities: {0:7} Categories: {1:7}".format(
|
||||
print(" Sensitivities: {0:7} Categories: {1:7}".format(
|
||||
p.level_count, p.category_count))
|
||||
print(" Types: {0:7} Attributes: {1:7}".format(
|
||||
print(" Types: {0:7} Attributes: {1:7}".format(
|
||||
p.type_count, p.type_attribute_count))
|
||||
print(" Users: {0:7} Roles: {1:7}".format(
|
||||
print(" Users: {0:7} Roles: {1:7}".format(
|
||||
p.user_count, p.role_count))
|
||||
print(" Booleans: {0:7} Cond. Expr.: {1:7}".format(
|
||||
print(" Booleans: {0:7} Cond. Expr.: {1:7}".format(
|
||||
p.boolean_count, p.conditional_count))
|
||||
print(" Allow: {0:7} Neverallow: {1:7}".format(
|
||||
print(" Allow: {0:7} Neverallow: {1:7}".format(
|
||||
p.allow_count, p.neverallow_count))
|
||||
print(" Auditallow: {0:7} Dontaudit: {1:7}".format(
|
||||
print(" Auditallow: {0:7} Dontaudit: {1:7}".format(
|
||||
p.auditallow_count, p.dontaudit_count))
|
||||
print(" Type_trans: {0:7} Type_change: {1:7}".format(
|
||||
print(" Type_trans: {0:7} Type_change: {1:7}".format(
|
||||
p.type_transition_count, p.type_change_count))
|
||||
print(" Type_member: {0:7} Range_trans: {1:7}".format(
|
||||
print(" Type_member: {0:7} Range_trans: {1:7}".format(
|
||||
p.type_member_count, p.range_transition_count))
|
||||
print(" Role allow: {0:7} Role_trans: {1:7}".format(
|
||||
print(" Role allow: {0:7} Role_trans: {1:7}".format(
|
||||
p.role_allow_count, p.role_transition_count))
|
||||
print(" Constraints: {0:7} Validatetrans: {1:7}".format(
|
||||
print(" Constraints: {0:7} Validatetrans: {1:7}".format(
|
||||
p.constraint_count, p.validatetrans_count))
|
||||
print(" MLS Constrain: {0:7} MLS Val. Tran: {1:7}".format(
|
||||
print(" MLS Constrain: {0:7} MLS Val. Tran: {1:7}".format(
|
||||
p.mlsconstraint_count, p.mlsvalidatetrans_count))
|
||||
print(" Initial SIDs: {0:7} Fs_use: {1:7}".format(
|
||||
p.initialsids_count, p.fs_use_count))
|
||||
print(" Genfscon: {0:7} Portcon: {1:7}".format(
|
||||
p.genfscon_count, p.portcon_count))
|
||||
print(" Netifcon: {0:7} Nodecon: {1:7}".format(
|
||||
p.netifcon_count, p.nodecon_count))
|
||||
print(" Permissives: {0:7} Polcap: {1:7}".format(
|
||||
print(" Permissives: {0:7} Polcap: {1:7}".format(
|
||||
p.permissives_count, p.polcap_count))
|
||||
print(" Defaults: {0:7} Typebounds: {1:7}".format(
|
||||
p.default_count, p.typebounds_count))
|
||||
|
||||
if p.target_platform == "selinux":
|
||||
print(" Allowxperm: {0:7} Neverallowxperm: {1:7}".format(
|
||||
p.xprule_allow_count, p.xprule_neverallow_count))
|
||||
print(" Auditallowxperm: {0:7} Dontauditxperm: {1:7}".format(
|
||||
p.xprule_auditallow_count, p.xprule_dontaudit_count))
|
||||
print(" Initial SIDs: {0:7} Fs_use: {1:7}".format(
|
||||
p.initialsids_count, p.fs_use_count))
|
||||
print(" Genfscon: {0:7} Portcon: {1:7}".format(
|
||||
p.genfscon_count, p.portcon_count))
|
||||
print(" Netifcon: {0:7} Nodecon: {1:7}".format(
|
||||
p.netifcon_count, p.nodecon_count))
|
||||
elif p.target_platform == "xen":
|
||||
print(" Initial SIDs: {0:7} Devicetreecon {1:7}".format(
|
||||
p.initialsids_count, p.devicetreecon_count))
|
||||
print(" Iomemcon: {0:7} Ioportcon: {1:7}".format(
|
||||
p.iomemcon_count, p.ioportcon_count))
|
||||
print(" Pcidevicecon: {0:7} Pirqcon: {1:7}".format(
|
||||
p.pcidevicecon_count, p.pirqcon_count))
|
||||
|
||||
for desc, component, expander in components:
|
||||
results = sorted(component.results())
|
||||
if not args.flat:
|
||||
|
41
sesearch
41
sesearch
@ -42,6 +42,9 @@ rtypes.add_argument("--auditallow", action="append_const",
|
||||
rtypes.add_argument("--dontaudit", action="append_const",
|
||||
const="dontaudit", dest="tertypes",
|
||||
help="Search dontaudit rules.")
|
||||
rtypes.add_argument("--neverallow", action="append_const",
|
||||
const="neverallow", dest="tertypes",
|
||||
help="Search neverallow rules.")
|
||||
rtypes.add_argument("-T", "--type_trans", action="append_const",
|
||||
const="type_transition", dest="tertypes",
|
||||
help="Search type_transition rules.")
|
||||
@ -51,7 +54,19 @@ rtypes.add_argument("--type_change", action="append_const",
|
||||
rtypes.add_argument("--type_member", action="append_const",
|
||||
const="type_member", dest="tertypes",
|
||||
help="Search type_member rules.")
|
||||
|
||||
xperms = parser.add_argument_group("XPERM Rule Types")
|
||||
xperms.add_argument( "--allowxperm", action="append_const",
|
||||
const="allowxperm", dest="xpermrule",
|
||||
help="Search allowxperm rules.")
|
||||
xperms.add_argument("--auditallowxperm", action="append_const",
|
||||
const="auditallowxperm", dest="xpermrule",
|
||||
help="Search auditallowxperm rules.")
|
||||
xperms.add_argument("--dontauditxperm", action="append_const",
|
||||
const="dontauditxperm", dest="xpermrule",
|
||||
help="Search dontauditxperm rules.")
|
||||
xperms.add_argument("--neverallowxperm", action="append_const",
|
||||
const="neverallowxperm", dest="xpermrule",
|
||||
help="Search neverallowxperm rules.")
|
||||
rbacrtypes = parser.add_argument_group("RBAC Rule Types")
|
||||
rbacrtypes.add_argument("--role_allow", action="append_const",
|
||||
const="allow", dest="rbacrtypes",
|
||||
@ -101,7 +116,7 @@ opts.add_argument("-rb", action="store_true", dest="boolean_regex",
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes:
|
||||
if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes and not args.xpermrule:
|
||||
parser.error("At least one rule type must be specified.")
|
||||
|
||||
if args.debug:
|
||||
@ -151,6 +166,28 @@ try:
|
||||
for r in sorted(q.results()):
|
||||
print(r)
|
||||
|
||||
if args.xpermrule:
|
||||
q = setools.XpermRuleQuery(p,
|
||||
ruletype=args.xpermrule,
|
||||
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)
|
||||
|
||||
# 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:
|
||||
q.tclass = args.tclass
|
||||
else:
|
||||
q.tclass = args.tclass.split(",")
|
||||
|
||||
for r in sorted(q.results()):
|
||||
print(r)
|
||||
|
||||
if args.rbacrtypes:
|
||||
q = setools.RBACRuleQuery(p,
|
||||
ruletype=args.rbacrtypes,
|
||||
|
@ -49,6 +49,7 @@ from .userquery import UserQuery
|
||||
from .mlsrulequery import MLSRuleQuery
|
||||
from .rbacrulequery import RBACRuleQuery
|
||||
from .terulequery import TERuleQuery
|
||||
from .xpermrulequery import XpermRuleQuery
|
||||
|
||||
# Constraint queries
|
||||
from .constraintquery import ConstraintQuery
|
||||
@ -64,6 +65,11 @@ from .initsidquery import InitialSIDQuery
|
||||
from .netifconquery import NetifconQuery
|
||||
from .nodeconquery import NodeconQuery
|
||||
from .portconquery import PortconQuery
|
||||
from .ioportconquery import IoportconQuery
|
||||
from .iomemconquery import IomemconQuery
|
||||
from .pirqconquery import PirqconQuery
|
||||
from .pcideviceconquery import PcideviceconQuery
|
||||
from .devicetreeconquery import DevicetreeconQuery
|
||||
|
||||
# Information Flow Analysis
|
||||
from .infoflow import InfoFlowAnalysis
|
||||
|
95
setools/devicetreeconquery.py
Normal file
95
setools/devicetreeconquery.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Derived from portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import contextquery
|
||||
from .policyrep.xencontext import dev_path
|
||||
|
||||
class DevicetreeconQuery(contextquery.ContextQuery):
|
||||
|
||||
"""
|
||||
Devicetreecon context query.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
path A single devicetree path.
|
||||
|
||||
user The criteria to match the context's user.
|
||||
user_regex If true, regular expression matching
|
||||
will be used on the user.
|
||||
|
||||
role The criteria to match the context's role.
|
||||
role_regex If true, regular expression matching
|
||||
will be used on the role.
|
||||
|
||||
type_ The criteria to match the context's type.
|
||||
type_regex If true, regular expression matching
|
||||
will be used on the type.
|
||||
|
||||
range_ The criteria to match the context's range.
|
||||
range_subset If true, the criteria will match if it is a subset
|
||||
of the context's range.
|
||||
range_overlap If true, the criteria will match if it overlaps
|
||||
any of the context's range.
|
||||
range_superset If true, the criteria will match if it is a superset
|
||||
of the context's range.
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
|
||||
_path = None
|
||||
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
@path.setter
|
||||
def path(self, value):
|
||||
pending_path = dev_path(*value)
|
||||
|
||||
if all(pending_path):
|
||||
if type(pending_path.path) != str:
|
||||
raise ValueError("The path must a string: {0}".format(pending_path))
|
||||
|
||||
self._path = pending_path
|
||||
else:
|
||||
self._path = None
|
||||
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching devicetreecons."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("path: {0.path}".format(self))
|
||||
self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
|
||||
self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
|
||||
self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
|
||||
self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for devicetreecon in self.policy.devicetreecons():
|
||||
|
||||
if self.path and self.path != devicetreecon.path:
|
||||
continue
|
||||
|
||||
if not self._match_context(devicetreecon.context):
|
||||
continue
|
||||
yield devicetreecon
|
121
setools/iomemconquery.py
Normal file
121
setools/iomemconquery.py
Normal file
@ -0,0 +1,121 @@
|
||||
# Derived from portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import contextquery
|
||||
from .policyrep.xencontext import addr_range
|
||||
|
||||
|
||||
class IomemconQuery(contextquery.ContextQuery):
|
||||
|
||||
"""
|
||||
Iomemcon context query.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
mem_addr A 2-tuple of the memory addr range to match. (Set both to
|
||||
the same value for a single mem addr)
|
||||
mem_addr_subset If true, the criteria will match if it is a subset
|
||||
of the iomemcon's range.
|
||||
mem_addr_overlap If true, the criteria will match if it overlaps
|
||||
any of the iomemcon's range.
|
||||
mem_addr_superset If true, the criteria will match if it is a superset
|
||||
of the iomemcon's range.
|
||||
mem_addr_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
|
||||
user The criteria to match the context's user.
|
||||
user_regex If true, regular expression matching
|
||||
will be used on the user.
|
||||
|
||||
role The criteria to match the context's role.
|
||||
role_regex If true, regular expression matching
|
||||
will be used on the role.
|
||||
|
||||
type_ The criteria to match the context's type.
|
||||
type_regex If true, regular expression matching
|
||||
will be used on the type.
|
||||
|
||||
range_ The criteria to match the context's range.
|
||||
range_subset If true, the criteria will match if it is a subset
|
||||
of the context's range.
|
||||
range_overlap If true, the criteria will match if it overlaps
|
||||
any of the context's range.
|
||||
range_superset If true, the criteria will match if it is a superset
|
||||
of the context's range.
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
|
||||
_mem_addr = None
|
||||
mem_addr_subset = False
|
||||
mem_addr_overlap = False
|
||||
mem_addr_superset = False
|
||||
mem_addr_proper = False
|
||||
|
||||
@property
|
||||
def mem_addr(self):
|
||||
return self._mem_addr
|
||||
|
||||
@mem_addr.setter
|
||||
def mem_addr(self, value):
|
||||
pending_mem_addr = addr_range(*value)
|
||||
|
||||
if all(pending_mem_addr):
|
||||
if pending_mem_addr.low < 1 or pending_mem_addr.high < 1:
|
||||
raise ValueError("Memory address must be positive: {0.low}-{0.high}".
|
||||
format(pending_mem_addr))
|
||||
|
||||
if pending_mem_addr.low > pending_mem_addr.high:
|
||||
raise ValueError(
|
||||
"The low mem addr must be smaller than the high mem addr: {0.low}-{0.high}".
|
||||
format(pending_mem_addr))
|
||||
|
||||
self._mem_addr = pending_mem_addr
|
||||
else:
|
||||
self._mem_addr = None
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching iomemcons."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("mem_addr: {0.mem_addr}, overlap: {0.mem_addr_overlap}, "
|
||||
"subset: {0.mem_addr_subset}, superset: {0.mem_addr_superset}, "
|
||||
"proper: {0.mem_addr_proper}".format(self))
|
||||
self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
|
||||
self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
|
||||
self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
|
||||
self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for iomemcon in self.policy.iomemcons():
|
||||
|
||||
if self.mem_addr and not self._match_range(
|
||||
iomemcon.mem_addr,
|
||||
self.mem_addr,
|
||||
self.mem_addr_subset,
|
||||
self.mem_addr_overlap,
|
||||
self.mem_addr_superset,
|
||||
self.mem_addr_proper):
|
||||
continue
|
||||
|
||||
if not self._match_context(iomemcon.context):
|
||||
continue
|
||||
yield iomemcon
|
120
setools/ioportconquery.py
Normal file
120
setools/ioportconquery.py
Normal file
@ -0,0 +1,120 @@
|
||||
# Derived from portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import contextquery
|
||||
from .policyrep.xencontext import port_range
|
||||
|
||||
|
||||
class IoportconQuery(contextquery.ContextQuery):
|
||||
|
||||
"""
|
||||
Ioportcon context query.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
ports A 2-tuple of the port range to match. (Set both to
|
||||
the same value for a single port)
|
||||
ports_subset If true, the criteria will match if it is a subset
|
||||
of the ioportcon's range.
|
||||
ports_overlap If true, the criteria will match if it overlaps
|
||||
any of the ioportcon's range.
|
||||
ports_superset If true, the criteria will match if it is a superset
|
||||
of the ioportcon's range.
|
||||
ports_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
|
||||
user The criteria to match the context's user.
|
||||
user_regex If true, regular expression matching
|
||||
will be used on the user.
|
||||
|
||||
role The criteria to match the context's role.
|
||||
role_regex If true, regular expression matching
|
||||
will be used on the role.
|
||||
|
||||
type_ The criteria to match the context's type.
|
||||
type_regex If true, regular expression matching
|
||||
will be used on the type.
|
||||
|
||||
range_ The criteria to match the context's range.
|
||||
range_subset If true, the criteria will match if it is a subset
|
||||
of the context's range.
|
||||
range_overlap If true, the criteria will match if it overlaps
|
||||
any of the context's range.
|
||||
range_superset If true, the criteria will match if it is a superset
|
||||
of the context's range.
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
|
||||
_ports = None
|
||||
ports_subset = False
|
||||
ports_overlap = False
|
||||
ports_superset = False
|
||||
ports_proper = False
|
||||
|
||||
@property
|
||||
def ports(self):
|
||||
return self._ports
|
||||
|
||||
@ports.setter
|
||||
def ports(self, value):
|
||||
pending_ports = port_range(*value)
|
||||
|
||||
if all(pending_ports):
|
||||
if pending_ports.low < 1 or pending_ports.high < 1:
|
||||
raise ValueError("Port numbers must be positive: {0.low}-{0.high}".
|
||||
format(pending_ports))
|
||||
|
||||
if pending_ports.low > pending_ports.high:
|
||||
raise ValueError(
|
||||
"The low port must be smaller than the high port: {0.low}-{0.high}".
|
||||
format(pending_ports))
|
||||
|
||||
self._ports = pending_ports
|
||||
else:
|
||||
self._ports = None
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching ioportcons."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("Ports: {0.ports}, overlap: {0.ports_overlap}, "
|
||||
"subset: {0.ports_subset}, superset: {0.ports_superset}, "
|
||||
"proper: {0.ports_proper}".format(self))
|
||||
self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
|
||||
self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
|
||||
self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
|
||||
self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for ioportcon in self.policy.ioportcons():
|
||||
|
||||
if self.ports and not self._match_range(
|
||||
ioportcon.ports,
|
||||
self.ports,
|
||||
self.ports_subset,
|
||||
self.ports_overlap,
|
||||
self.ports_superset,
|
||||
self.ports_proper):
|
||||
continue
|
||||
if not self._match_context(ioportcon.context):
|
||||
continue
|
||||
yield ioportcon
|
94
setools/pcideviceconquery.py
Normal file
94
setools/pcideviceconquery.py
Normal file
@ -0,0 +1,94 @@
|
||||
# Derived from portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import contextquery
|
||||
from .policyrep.xencontext import device_id
|
||||
|
||||
class PcideviceconQuery(contextquery.ContextQuery):
|
||||
|
||||
"""
|
||||
Pcidevicecon context query.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
device A single PCI device ID.
|
||||
|
||||
user The criteria to match the context's user.
|
||||
user_regex If true, regular expression matching
|
||||
will be used on the user.
|
||||
|
||||
role The criteria to match the context's role.
|
||||
role_regex If true, regular expression matching
|
||||
will be used on the role.
|
||||
|
||||
type_ The criteria to match the context's type.
|
||||
type_regex If true, regular expression matching
|
||||
will be used on the type.
|
||||
|
||||
range_ The criteria to match the context's range.
|
||||
range_subset If true, the criteria will match if it is a subset
|
||||
of the context's range.
|
||||
range_overlap If true, the criteria will match if it overlaps
|
||||
any of the context's range.
|
||||
range_superset If true, the criteria will match if it is a superset
|
||||
of the context's range.
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
|
||||
_device = None
|
||||
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
return self._device
|
||||
|
||||
@device.setter
|
||||
def device(self, value):
|
||||
pending_device = device_id(*value)
|
||||
|
||||
if all(pending_device):
|
||||
if pending_device.low < 1:
|
||||
raise ValueError("PCI device ID must be positive: {0}".format(pending_device))
|
||||
|
||||
self._device = pending_device
|
||||
else:
|
||||
self._device = None
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching pcidevicecons."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("device id: {0.device}".format(self))
|
||||
self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
|
||||
self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
|
||||
self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
|
||||
self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for pcidevicecon in self.policy.pcidevicecons():
|
||||
|
||||
if self.device and self.device != pcidevicecon.device:
|
||||
continue
|
||||
|
||||
if not self._match_context(pcidevicecon.context):
|
||||
continue
|
||||
yield pcidevicecon
|
95
setools/pirqconquery.py
Normal file
95
setools/pirqconquery.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Derived from portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import contextquery
|
||||
from .policyrep.xencontext import pirq
|
||||
|
||||
class PirqconQuery(contextquery.ContextQuery):
|
||||
|
||||
"""
|
||||
Pirqcon context query.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
irq A single IRQ value.
|
||||
|
||||
user The criteria to match the context's user.
|
||||
user_regex If true, regular expression matching
|
||||
will be used on the user.
|
||||
|
||||
role The criteria to match the context's role.
|
||||
role_regex If true, regular expression matching
|
||||
will be used on the role.
|
||||
|
||||
type_ The criteria to match the context's type.
|
||||
type_regex If true, regular expression matching
|
||||
will be used on the type.
|
||||
|
||||
range_ The criteria to match the context's range.
|
||||
range_subset If true, the criteria will match if it is a subset
|
||||
of the context's range.
|
||||
range_overlap If true, the criteria will match if it overlaps
|
||||
any of the context's range.
|
||||
range_superset If true, the criteria will match if it is a superset
|
||||
of the context's range.
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
|
||||
_irq = None
|
||||
|
||||
|
||||
@property
|
||||
def irq(self):
|
||||
return self._irq
|
||||
|
||||
@irq.setter
|
||||
def irq(self, value):
|
||||
pending_irq = pirq(*value)
|
||||
|
||||
if all(pending_irq):
|
||||
if pending_irq.low < 1:
|
||||
raise ValueError("The IRQ must be positive: {0}".format(pending_irq))
|
||||
|
||||
self._irq = pending_irq
|
||||
else:
|
||||
self._irq = None
|
||||
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching pirqcons."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("irq: {0.irq}".format(self))
|
||||
self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
|
||||
self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
|
||||
self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
|
||||
self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for pirqcon in self.policy.pirqcons():
|
||||
|
||||
if self.irq and self.irq != pirqcon.irq:
|
||||
continue
|
||||
|
||||
if not self._match_context(pirqcon.context):
|
||||
continue
|
||||
yield pirqcon
|
@ -56,6 +56,7 @@ from . import user
|
||||
from . import mlsrule
|
||||
from . import rbacrule
|
||||
from . import terule
|
||||
from . import xpermrule
|
||||
|
||||
# Constraints
|
||||
from . import constraint
|
||||
@ -168,6 +169,11 @@ class SELinuxPolicy(object):
|
||||
"""The policy database version (e.g. v29)"""
|
||||
return self.policy.version()
|
||||
|
||||
@property
|
||||
def target_platform(self):
|
||||
"""The policy platform (selinux or xen)"""
|
||||
return self.policy.target_platform()
|
||||
|
||||
#
|
||||
# Policy statistics
|
||||
#
|
||||
@ -347,6 +353,51 @@ class SELinuxPolicy(object):
|
||||
"""The number of validatetrans."""
|
||||
return sum(1 for v in self.constraints() if v.ruletype == "validatetrans")
|
||||
|
||||
@property
|
||||
def iomemcon_count(self):
|
||||
"""The number of iomemcon statements."""
|
||||
return self.policy.iomemcon_count()
|
||||
|
||||
@property
|
||||
def ioportcon_count(self):
|
||||
"""The number of ioportcon statements."""
|
||||
return self.policy.ioportcon_count()
|
||||
|
||||
@property
|
||||
def pcidevicecon_count(self):
|
||||
"""The number of pcidevicecon statements."""
|
||||
return self.policy.pcidevicecon_count()
|
||||
|
||||
@property
|
||||
def pirqcon_count(self):
|
||||
"""The number of pirqcon statements."""
|
||||
return self.policy.pirqcon_count()
|
||||
|
||||
@property
|
||||
def devicetreecon_count(self):
|
||||
"""The number of devicetreecon statements."""
|
||||
return self.policy.devicetreecon_count()
|
||||
|
||||
@property
|
||||
def xprule_allow_count(self):
|
||||
"""The number of allowxperm rules."""
|
||||
return self.policy.xprule_allow_count()
|
||||
|
||||
@property
|
||||
def xprule_auditallow_count(self):
|
||||
"""The number of auditallowxperm rules."""
|
||||
return self.policy.xprule_auditallow_count()
|
||||
|
||||
@property
|
||||
def xprule_dontaudit_count(self):
|
||||
"""The number of dontauditxperm rules."""
|
||||
return self.policy.xprule_dontaudit_count()
|
||||
|
||||
@property
|
||||
def xprule_neverallow_count(self):
|
||||
"""The number of neverallowxperm rules."""
|
||||
return self.policy.xprule_neverallow_count()
|
||||
|
||||
#
|
||||
# Policy components lookup functions
|
||||
#
|
||||
@ -516,6 +567,11 @@ class SELinuxPolicy(object):
|
||||
self.policy.filename_trans_iter()):
|
||||
yield terule.te_rule_factory(self.policy, rule)
|
||||
|
||||
def xpermrules(self):
|
||||
"""Generator which yields all XPERM rules."""
|
||||
for rule in self.policy.xprule_iter():
|
||||
yield xpermrule.xperm_rule_factory(self.policy, rule)
|
||||
|
||||
#
|
||||
# Policy rule type validators
|
||||
#
|
||||
@ -564,6 +620,11 @@ class SELinuxPolicy(object):
|
||||
"""Validate type enforcement rule types."""
|
||||
return terule.validate_ruletype(types)
|
||||
|
||||
@staticmethod
|
||||
def validate_xperm_ruletype(types):
|
||||
"""Validate XPERM rule types."""
|
||||
xpermrule.validate_ruletype(types)
|
||||
|
||||
#
|
||||
# Constraints generators
|
||||
#
|
||||
@ -607,3 +668,30 @@ class SELinuxPolicy(object):
|
||||
"""Generator which yields all portcon statements."""
|
||||
for port in self.policy.portcon_iter():
|
||||
yield netcontext.portcon_factory(self.policy, port)
|
||||
|
||||
### Start XEN statements
|
||||
def iomemcons(self):
|
||||
"""Generator which yields all iomemcon statements."""
|
||||
for mem_addr in self.policy.iomemcon_iter():
|
||||
yield xencontext.iomemcon_factory(self.policy, mem_addr)
|
||||
|
||||
def ioportcons(self):
|
||||
"""Generator which yields all ioportcon statements."""
|
||||
for port in self.policy.ioportcon_iter():
|
||||
yield xencontext.ioportcon_factory(self.policy, port)
|
||||
|
||||
def pcidevicecons(self):
|
||||
"""Generator which yields all pcidevicecon statements."""
|
||||
for device in self.policy.pcidevicecon_iter():
|
||||
yield xencontext.pcidevicecon_factory(self.policy, device)
|
||||
|
||||
def pirqcons(self):
|
||||
"""Generator which yields all pirqcon statements."""
|
||||
for irq in self.policy.pirqcon_iter():
|
||||
yield xencontext.pirqcon_factory(self.policy, irq)
|
||||
|
||||
def devicetreecons(self):
|
||||
"""Generator which yields all devicetreecon statements."""
|
||||
for path in self.policy.devicetreecon_iter():
|
||||
yield xencontext.devicetreecon_factory(self.policy, path)
|
||||
### End XEN statements
|
||||
|
201
setools/policyrep/xencontext.py
Normal file
201
setools/policyrep/xencontext.py
Normal file
@ -0,0 +1,201 @@
|
||||
# Derived from netcontext.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections import namedtuple
|
||||
|
||||
from . import qpol
|
||||
from . import symbol
|
||||
from . import context
|
||||
|
||||
addr_range = namedtuple("memory_range", ["low", "high"])
|
||||
port_range = namedtuple("port_range", ["low", "high"])
|
||||
device_id = namedtuple("device_id", ["low"])
|
||||
pirq = namedtuple("irq", ["low"])
|
||||
dev_path = namedtuple("dev_path", ["path"])
|
||||
|
||||
def iomemcon_factory(policy, name):
|
||||
"""Factory function for creating iomemcon objects."""
|
||||
|
||||
if not isinstance(name, qpol.qpol_iomemcon_t):
|
||||
raise NotImplementedError
|
||||
|
||||
return Iomemcon(policy, name)
|
||||
|
||||
|
||||
def ioportcon_factory(policy, name):
|
||||
"""Factory function for creating ioportcon objects."""
|
||||
|
||||
if not isinstance(name, qpol.qpol_ioportcon_t):
|
||||
raise NotImplementedError
|
||||
|
||||
return Ioportcon(policy, name)
|
||||
|
||||
|
||||
def pirqcon_factory(policy, name):
|
||||
"""Factory function for creating pirqcon objects."""
|
||||
|
||||
if not isinstance(name, qpol.qpol_pirqcon_t):
|
||||
raise NotImplementedError
|
||||
|
||||
return Pirqcon(policy, name)
|
||||
|
||||
|
||||
def pcidevicecon_factory(policy, name):
|
||||
"""Factory function for creating pcidevicecon objects."""
|
||||
|
||||
if not isinstance(name, qpol.qpol_pcidevicecon_t):
|
||||
raise NotImplementedError
|
||||
|
||||
return Pcidevicecon(policy, name)
|
||||
|
||||
|
||||
def devicetreecon_factory(policy, name):
|
||||
"""Factory function for creating devicetreecon objects."""
|
||||
|
||||
if not isinstance(name, qpol.qpol_devicetreecon_t):
|
||||
raise NotImplementedError
|
||||
|
||||
return Devicetreecon(policy, name)
|
||||
|
||||
|
||||
class XenContext(symbol.PolicySymbol):
|
||||
|
||||
"""Base class for in-policy xen labeling rules."""
|
||||
|
||||
def __str__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
"""The context for this statement."""
|
||||
return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
|
||||
|
||||
def statement(self):
|
||||
return str(self)
|
||||
|
||||
|
||||
class Iomemcon(XenContext):
|
||||
|
||||
"""A iomemcon statement."""
|
||||
|
||||
def __str__(self):
|
||||
low, high = self.mem_addr
|
||||
|
||||
if low == high:
|
||||
return "iomemcon {0} {1}".format(low, self.context)
|
||||
else:
|
||||
return "iomemcon {0}-{1} {2}".format(low, high, self.context)
|
||||
|
||||
@property
|
||||
def mem_addr(self):
|
||||
"""
|
||||
The memory range for this iomemcon.
|
||||
|
||||
Return: Tuple(low, high)
|
||||
low The low memory of the range.
|
||||
high The high memory of the range.
|
||||
"""
|
||||
low = self.qpol_symbol.low_addr(self.policy)
|
||||
high = self.qpol_symbol.high_addr(self.policy)
|
||||
return addr_range(low, high)
|
||||
|
||||
class Ioportcon(XenContext):
|
||||
|
||||
"""A ioportcon statement."""
|
||||
|
||||
def __str__(self):
|
||||
low, high = self.ports
|
||||
|
||||
if low == high:
|
||||
return "ioportcon {0} {1}".format(low, self.context)
|
||||
else:
|
||||
return "ioportcon {0}-{1} {2}".format(low, high, self.context)
|
||||
|
||||
@property
|
||||
def ports(self):
|
||||
"""
|
||||
The port range for this ioportcon.
|
||||
|
||||
Return: Tuple(low, high)
|
||||
low The low port of the range.
|
||||
high The high port of the range.
|
||||
"""
|
||||
|
||||
low = self.qpol_symbol.low_port(self.policy)
|
||||
high = self.qpol_symbol.high_port(self.policy)
|
||||
return port_range(low, high)
|
||||
|
||||
class Pcidevicecon(XenContext):
|
||||
|
||||
"""A pcidevicecon statement."""
|
||||
|
||||
def __str__(self):
|
||||
device_id = self.device
|
||||
|
||||
return "pcidevicecon {0} {1}".format(device_id, self.context)
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""
|
||||
The device for this pcidevicecon.
|
||||
|
||||
Return: Tuple(low)
|
||||
low The PCI device ID.
|
||||
"""
|
||||
device_id = self.qpol_symbol.device(self.policy)
|
||||
return device_id
|
||||
|
||||
class Pirqcon(XenContext):
|
||||
|
||||
"""A pirqcon statement."""
|
||||
|
||||
def __str__(self):
|
||||
pirq = self.irq
|
||||
|
||||
return "pirqcon {0} {1}".format(pirq, self.context)
|
||||
|
||||
@property
|
||||
def irq(self):
|
||||
"""
|
||||
The irq for this pirqcon.
|
||||
|
||||
Return: Tuple(low)
|
||||
low The irq.
|
||||
"""
|
||||
pirq = self.qpol_symbol.irq(self.policy)
|
||||
return pirq
|
||||
|
||||
class Devicetreecon(XenContext):
|
||||
|
||||
"""A devicetreecon statement."""
|
||||
|
||||
def __str__(self):
|
||||
dev_path = self.path
|
||||
|
||||
return "devicetreecon {0} {1}".format(dev_path, self.context)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""
|
||||
The path for this devicetreecon.
|
||||
|
||||
Return: Tuple(path)
|
||||
path The device path name.
|
||||
"""
|
||||
dev_path = self.qpol_symbol.path(self.policy)
|
||||
return dev_path
|
58
setools/policyrep/xpermrule.py
Normal file
58
setools/policyrep/xpermrule.py
Normal file
@ -0,0 +1,58 @@
|
||||
# Derived from terule.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from . import exception
|
||||
from . import qpol
|
||||
from . import rule
|
||||
from . import typeattr
|
||||
|
||||
|
||||
def xperm_rule_factory(policy, symbol):
|
||||
"""Factory function for creating XPERM rule objects."""
|
||||
|
||||
if isinstance(symbol, qpol.qpol_xprule_t):
|
||||
return XpermRule(policy, symbol)
|
||||
else:
|
||||
raise TypeError("XPERM rules cannot be looked-up.")
|
||||
|
||||
|
||||
def validate_ruletype(types):
|
||||
"""Validate XPERM rule types."""
|
||||
for t in types:
|
||||
if t not in ["allowxperm", "auditallowxperm", "dontauditxperm", "neverallowxperm"]:
|
||||
raise exception.InvalidXpermRuleType("{0} is not a valid XPERM rule type.".format(t))
|
||||
|
||||
|
||||
class XpermRule(rule.PolicyRule):
|
||||
|
||||
"""An XPERM rule."""
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
"""The rule's source type/attribute."""
|
||||
return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.source_type(self.policy))
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
"""The rule's target type/attribute."""
|
||||
return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy))
|
||||
|
||||
def __str__(self):
|
||||
rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} {1};".format(
|
||||
self, self.qpol_symbol.xprule_xperm_string(self.policy))
|
||||
return rule_string
|
112
setools/xpermrulequery.py
Normal file
112
setools/xpermrulequery.py
Normal file
@ -0,0 +1,112 @@
|
||||
# Derived from terulequery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 2.1 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
import re
|
||||
|
||||
from . import mixins, query
|
||||
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor
|
||||
from .policyrep.exception import RuleUseError
|
||||
|
||||
|
||||
class XpermRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
|
||||
|
||||
"""
|
||||
Query the xperm rules.
|
||||
|
||||
Parameter:
|
||||
policy The policy to query.
|
||||
|
||||
Keyword Parameters/Class attributes:
|
||||
ruletype The list of rule type(s) to match.
|
||||
source The name of the source type/attribute to match.
|
||||
source_indirect If true, members of an attribute will be
|
||||
matched rather than the attribute itself.
|
||||
Default is true.
|
||||
source_regex If true, regular expression matching will
|
||||
be used on the source type/attribute.
|
||||
Obeys the source_indirect option.
|
||||
Default is false.
|
||||
target The name of the target type/attribute to match.
|
||||
target_indirect If true, members of an attribute will be
|
||||
matched rather than the attribute itself.
|
||||
Default is true.
|
||||
target_regex If true, regular expression matching will
|
||||
be used on the target type/attribute.
|
||||
Obeys target_indirect option.
|
||||
Default is false.
|
||||
tclass The object class(es) to match.
|
||||
tclass_regex If true, use a regular expression for
|
||||
matching the rule's object class.
|
||||
Default is false.
|
||||
"""
|
||||
|
||||
ruletype = RuletypeDescriptor("validate_xperm_ruletype")
|
||||
source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
|
||||
source_regex = False
|
||||
source_indirect = True
|
||||
target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
|
||||
target_regex = False
|
||||
target_indirect = True
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching Xperm rules."""
|
||||
self.log.info("Generating results from {0.policy}".format(self))
|
||||
self.log.debug("Ruletypes: {0.ruletype}".format(self))
|
||||
self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, "
|
||||
"regex: {0.source_regex}".format(self))
|
||||
self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, "
|
||||
"regex: {0.target_regex}".format(self))
|
||||
self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
|
||||
|
||||
for rule in self.policy.xpermrules():
|
||||
#
|
||||
# Matching on rule type
|
||||
#
|
||||
if self.ruletype:
|
||||
if rule.ruletype not in self.ruletype:
|
||||
continue
|
||||
|
||||
#
|
||||
# Matching on source type
|
||||
#
|
||||
if self.source and not self._match_indirect_regex(
|
||||
rule.source,
|
||||
self.source,
|
||||
self.source_indirect,
|
||||
self.source_regex):
|
||||
continue
|
||||
|
||||
#
|
||||
# Matching on target type
|
||||
#
|
||||
if self.target and not self._match_indirect_regex(
|
||||
rule.target,
|
||||
self.target,
|
||||
self.target_indirect,
|
||||
self.target_regex):
|
||||
continue
|
||||
|
||||
#
|
||||
# Matching on object class
|
||||
#
|
||||
if not self._match_object_class(rule):
|
||||
continue
|
||||
|
||||
# if we get here, we have matched all available criteria
|
||||
yield rule
|
231
tests/devicetreeconquery.conf
Normal file
231
tests/devicetreeconquery.conf
Normal file
@ -0,0 +1,231 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity s0;
|
||||
sensitivity s1;
|
||||
sensitivity s2;
|
||||
sensitivity s3;
|
||||
sensitivity s4;
|
||||
sensitivity s5;
|
||||
sensitivity s6;
|
||||
|
||||
dominance { s0 s1 s2 s3 s4 s5 s6 }
|
||||
|
||||
category c0;
|
||||
category c1;
|
||||
category c2;
|
||||
category c3;
|
||||
category c4;
|
||||
|
||||
#level decl
|
||||
level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s4:c0.c4;
|
||||
level s5:c0.c4;
|
||||
level s6:c0.c4;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
role role20_r;
|
||||
role role21a_r;
|
||||
role role21b_r;
|
||||
role role21c_r;
|
||||
|
||||
role role20_r types system;
|
||||
role role21a_r types system;
|
||||
role role21b_r types system;
|
||||
role role21c_r types system;
|
||||
|
||||
type type30;
|
||||
type type31a;
|
||||
type type31b;
|
||||
type type31c;
|
||||
role system types { type30 type31a type31b type31c };
|
||||
|
||||
allow system self:infoflow hi_w;
|
||||
|
||||
#users
|
||||
user system roles { system role20_r role21a_r role21b_r role21c_r } level s0 range s0 - s6:c0.c4;
|
||||
user user10 roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11a roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11b roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11c roles system level s0 range s0 - s2:c0.c4;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:s0
|
||||
sid security system:system:system:s0
|
||||
|
||||
# test 1:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree1" system:system:system:s0:c0.c1
|
||||
|
||||
# test 10:
|
||||
# irq: unset
|
||||
# user: user10, exact
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree10" user10:system:system:s0:c0.c1
|
||||
|
||||
# test 11:
|
||||
# irq: unset
|
||||
# user: user11(a|b), regex
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree11" user11a:system:system:s0:c0.c1
|
||||
devicetreecon "/dev/tree11000" user11b:system:system:s0:c0.c1
|
||||
devicetreecon "/dev/tree11001" user11c:system:system:s0:c0.c1
|
||||
|
||||
# test 20:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: role20_r, exact
|
||||
# type: unset
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree20" system:role20_r:system:s0:c0.c1
|
||||
|
||||
# test 21:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: role20(a|c)_r, regex
|
||||
# type: unset
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree21" system:role21a_r:system:s0:c0.c1
|
||||
devicetreecon "/dev/tree21000" system:role21b_r:system:s0:c0.c1
|
||||
devicetreecon "/dev/tree21001" system:role21c_r:system:s0:c0.c1
|
||||
|
||||
# test 30:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type30
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree30" system:system:type30:s0:c0.c1
|
||||
|
||||
# test 31:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type31(b|c)
|
||||
# range: unset
|
||||
devicetreecon "/dev/tree31" system:system:type31a:s0:c0.c1
|
||||
devicetreecon "/dev/tree31000" system:system:type31b:s0:c0.c1
|
||||
devicetreecon "/dev/tree31001" system:system:type31c:s0:c0.c1
|
||||
|
||||
# test 40:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: equal
|
||||
devicetreecon "/dev/tree40" system:system:system:s0:c1 - s0:c0.c4
|
||||
|
||||
# test 41:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: overlap
|
||||
devicetreecon "/dev/tree41" system:system:system:s1:c1 - s1:c1.c3
|
||||
|
||||
# test 42:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: subset
|
||||
devicetreecon "/dev/tree42" system:system:system:s2:c1 - s2:c1.c3
|
||||
|
||||
# test 43:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: superset
|
||||
devicetreecon "/dev/tree43" system:system:system:s3:c1 - s3:c1.c3
|
||||
|
||||
# test 44:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper subset
|
||||
devicetreecon "/dev/tree44" system:system:system:s4:c1 - s4:c1.c3
|
||||
|
||||
# test 45:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper superset
|
||||
devicetreecon "/dev/tree45" system:system:system:s5:c1 - s5:c1.c3
|
||||
|
206
tests/devicetreeconquery.py
Normal file
206
tests/devicetreeconquery.py
Normal file
@ -0,0 +1,206 @@
|
||||
# Derived from tests/portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, DevicetreeconQuery
|
||||
|
||||
|
||||
class DevicetreeconQueryTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/devicetreeconquery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""Devicetreecon query with no criteria"""
|
||||
# query with no parameters gets all PCI paths.
|
||||
rules = sorted(self.p.devicetreecons())
|
||||
|
||||
q = DevicetreeconQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_010_user_exact(self):
|
||||
"""Devicetreecon query with context user exact match"""
|
||||
q = DevicetreeconQuery(self.p, user="user10", user_regex=False)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree10")], path)
|
||||
|
||||
def test_011_user_regex(self):
|
||||
"""Devicetreecon query with context user regex match"""
|
||||
q = DevicetreeconQuery(self.p, user="user11(a|b)", user_regex=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree11"), ("/dev/tree11000")], path)
|
||||
|
||||
def test_020_role_exact(self):
|
||||
"""Devicetreecon query with context role exact match"""
|
||||
q = DevicetreeconQuery(self.p, role="role20_r", role_regex=False)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree20")], path)
|
||||
|
||||
def test_021_role_regex(self):
|
||||
"""Devicetreecon query with context role regex match"""
|
||||
q = DevicetreeconQuery(self.p, role="role21(a|c)_r", role_regex=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree21"), ("/dev/tree21001")], path)
|
||||
|
||||
def test_030_type_exact(self):
|
||||
"""Devicetreecon query with context type exact match"""
|
||||
q = DevicetreeconQuery(self.p, type_="type30", type_regex=False)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree30")], path)
|
||||
|
||||
def test_031_type_regex(self):
|
||||
"""Devicetreecon query with context type regex match"""
|
||||
q = DevicetreeconQuery(self.p, type_="type31(b|c)", type_regex=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree31000"), ("/dev/tree31001")], path)
|
||||
|
||||
def test_040_range_exact(self):
|
||||
"""Devicetreecon query with context range exact match"""
|
||||
q = DevicetreeconQuery(self.p, range_="s0:c1 - s0:c0.c4")
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree40")], path)
|
||||
|
||||
def test_041_range_overlap1(self):
|
||||
"""Devicetreecon query with context range overlap match (equal)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree41")], path)
|
||||
|
||||
def test_041_range_overlap2(self):
|
||||
"""Devicetreecon query with context range overlap match (subset)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree41")], path)
|
||||
|
||||
def test_041_range_overlap3(self):
|
||||
"""Devicetreecon query with context range overlap match (superset)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree41")], path)
|
||||
|
||||
def test_041_range_overlap4(self):
|
||||
"""Devicetreecon query with context range overlap match (overlap low level)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree41")], path)
|
||||
|
||||
def test_041_range_overlap5(self):
|
||||
"""Devicetreecon query with context range overlap match (overlap high level)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree41")], path)
|
||||
|
||||
def test_042_range_subset1(self):
|
||||
"""Devicetreecon query with context range subset match"""
|
||||
q = DevicetreeconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree42")], path)
|
||||
|
||||
def test_042_range_subset2(self):
|
||||
"""Devicetreecon query with context range subset match (equal)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree42")], path)
|
||||
|
||||
def test_043_range_superset1(self):
|
||||
"""Devicetreecon query with context range superset match"""
|
||||
q = DevicetreeconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree43")], path)
|
||||
|
||||
def test_043_range_superset2(self):
|
||||
"""Devicetreecon query with context range superset match (equal)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree43")], path)
|
||||
|
||||
def test_044_range_proper_subset1(self):
|
||||
"""Devicetreecon query with context range proper subset match"""
|
||||
q = DevicetreeconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree44")], path)
|
||||
|
||||
def test_044_range_proper_subset2(self):
|
||||
"""Devicetreecon query with context range proper subset match (equal)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([], path)
|
||||
|
||||
def test_044_range_proper_subset3(self):
|
||||
"""Devicetreecon query with context range proper subset match (equal low only)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree44")], path)
|
||||
|
||||
def test_044_range_proper_subset4(self):
|
||||
"""Devicetreecon query with context range proper subset match (equal high only)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree44")], path)
|
||||
|
||||
def test_045_range_proper_superset1(self):
|
||||
"""Devicetreecon query with context range proper superset match"""
|
||||
q = DevicetreeconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree45")], path)
|
||||
|
||||
def test_045_range_proper_superset2(self):
|
||||
"""Devicetreecon query with context range proper superset match (equal)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([], path)
|
||||
|
||||
def test_045_range_proper_superset3(self):
|
||||
"""Devicetreecon query with context range proper superset match (equal low)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree45")], path)
|
||||
|
||||
def test_045_range_proper_superset4(self):
|
||||
"""Devicetreecon query with context range proper superset match (equal high)"""
|
||||
q = DevicetreeconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
path = sorted(p.path for p in q.results())
|
||||
self.assertListEqual([("/dev/tree45")], path)
|
||||
|
359
tests/iomemconquery.conf
Normal file
359
tests/iomemconquery.conf
Normal file
@ -0,0 +1,359 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity s0;
|
||||
sensitivity s1;
|
||||
sensitivity s2;
|
||||
sensitivity s3;
|
||||
sensitivity s4;
|
||||
sensitivity s5;
|
||||
sensitivity s6;
|
||||
|
||||
dominance { s0 s1 s2 s3 s4 s5 s6 }
|
||||
|
||||
category c0;
|
||||
category c1;
|
||||
category c2;
|
||||
category c3;
|
||||
category c4;
|
||||
|
||||
#level decl
|
||||
level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s4:c0.c4;
|
||||
level s5:c0.c4;
|
||||
level s6:c0.c4;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
role role20_r;
|
||||
role role21a_r;
|
||||
role role21b_r;
|
||||
role role21c_r;
|
||||
|
||||
role role20_r types system;
|
||||
role role21a_r types system;
|
||||
role role21b_r types system;
|
||||
role role21c_r types system;
|
||||
|
||||
type type30;
|
||||
type type31a;
|
||||
type type31b;
|
||||
type type31c;
|
||||
role system types { type30 type31a type31b type31c };
|
||||
|
||||
allow system self:infoflow hi_w;
|
||||
|
||||
#users
|
||||
user system roles { system role20_r role21a_r role21b_r role21c_r } level s0 range s0 - s6:c0.c4;
|
||||
user user10 roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11a roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11b roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11c roles system level s0 range s0 - s2:c0.c4;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:s0
|
||||
sid security system:system:system:s0
|
||||
|
||||
# test 1:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 1 system:system:system:s0:c0.c1
|
||||
|
||||
# test 10:
|
||||
# mem addr: unset
|
||||
# user: user10, exact
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 10 user10:system:system:s0:c0.c1
|
||||
|
||||
# test 11:
|
||||
# mem addr: unset
|
||||
# user: user11(a|b), regex
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 11 user11a:system:system:s0:c0.c1
|
||||
iomemcon 11000 user11b:system:system:s0:c0.c1
|
||||
iomemcon 11001 user11c:system:system:s0:c0.c1
|
||||
|
||||
# test 20:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: role20_r, exact
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 20 system:role20_r:system:s0:c0.c1
|
||||
|
||||
# test 21:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: role20(a|c)_r, regex
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 21 system:role21a_r:system:s0:c0.c1
|
||||
iomemcon 21000 system:role21b_r:system:s0:c0.c1
|
||||
iomemcon 21001 system:role21c_r:system:s0:c0.c1
|
||||
|
||||
# test 30:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type30
|
||||
# range: unset
|
||||
iomemcon 30 system:system:type30:s0:c0.c1
|
||||
|
||||
# test 31:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type31(b|c)
|
||||
# range: unset
|
||||
iomemcon 31 system:system:type31a:s0:c0.c1
|
||||
iomemcon 31000 system:system:type31b:s0:c0.c1
|
||||
iomemcon 31001 system:system:type31c:s0:c0.c1
|
||||
|
||||
# test 40:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: equal
|
||||
iomemcon 40 system:system:system:s0:c1 - s0:c0.c4
|
||||
|
||||
# test 41:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: overlap
|
||||
iomemcon 41 system:system:system:s1:c1 - s1:c1.c3
|
||||
|
||||
# test 42:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: subset
|
||||
iomemcon 42 system:system:system:s2:c1 - s2:c1.c3
|
||||
|
||||
# test 43:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: superset
|
||||
iomemcon 43 system:system:system:s3:c1 - s3:c1.c3
|
||||
|
||||
# test 44:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper subset
|
||||
iomemcon 44 system:system:system:s4:c1 - s4:c1.c3
|
||||
|
||||
# test 45:
|
||||
# mem addr: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper superset
|
||||
iomemcon 45 system:system:system:s5:c1 - s5:c1.c3
|
||||
|
||||
# test 50:
|
||||
# mem addr: (50, 50)
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50 system:system:system:s0:c0.c1
|
||||
|
||||
# test 51:
|
||||
# mem addr: (50100, 50110)
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50100-50110 system:system:system:s0:c0.c1
|
||||
|
||||
# test 52:
|
||||
# mem addr: (50200, 50200), subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50200 system:system:system:s0:c0.c1
|
||||
|
||||
# test 53:
|
||||
# mem addr: (50301, 50309), subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50300-50310 system:system:system:s0:c0.c1
|
||||
|
||||
# test 54:
|
||||
# mem addr: (50400, 50400), proper subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50400 system:system:system:s0:c0.c1
|
||||
|
||||
# test 55:
|
||||
# mem addr: (50501, 50509), proper subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50500-50510 system:system:system:s0:c0.c1
|
||||
|
||||
# test 56:
|
||||
# mem addr: (50600, 50602), superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50601 system:system:system:s0:c0.c1
|
||||
|
||||
# test 57:
|
||||
# mem addr: (50700, 50711), superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50700-50710 system:system:system:s0:c0.c1
|
||||
|
||||
# test 58:
|
||||
# mem addr: (50600, 50602), proper superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50801 system:system:system:s0:c0.c1
|
||||
|
||||
# test 59:
|
||||
# mem addr: (50900, 50911), proper superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 50901-50910 system:system:system:s0:c0.c1
|
||||
|
||||
# test 60:
|
||||
# mem addr: (60001, 60001), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60001 system:system:system:s0:c0.c1
|
||||
|
||||
# test 61:
|
||||
# mem addr: (60100, 60105), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60101-60110 system:system:system:s0:c0.c1
|
||||
|
||||
# test 62:
|
||||
# mem addr: (60205, 60211), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60200-60210 system:system:system:s0:c0.c1
|
||||
|
||||
# test 63:
|
||||
# mem addr: (60305, 60308), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60300-60310 system:system:system:s0:c0.c1
|
||||
|
||||
# test 64:
|
||||
# mem addr: (60400, 60410), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60400-60410 system:system:system:s0:c0.c1
|
||||
|
||||
# test 65:
|
||||
# mem addr: (60500, 60510), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
iomemcon 60501-60509 system:system:system:s0:c0.c1
|
||||
|
435
tests/iomemconquery.py
Normal file
435
tests/iomemconquery.py
Normal file
@ -0,0 +1,435 @@
|
||||
# Derived from tests/portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, IomemconQuery
|
||||
|
||||
|
||||
class IomemconQueryTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/iomemconquery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""Iomemcon query with no criteria"""
|
||||
# query with no parameters gets all mem_addr.
|
||||
rules = sorted(self.p.iomemcons())
|
||||
|
||||
q = IomemconQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_010_user_exact(self):
|
||||
"""Iomemcon query with context user exact match"""
|
||||
q = IomemconQuery(self.p, user="user10", user_regex=False)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(10, 10)], mem_addr)
|
||||
|
||||
def test_011_user_regex(self):
|
||||
"""Iomemcon query with context user regex match"""
|
||||
q = IomemconQuery(self.p, user="user11(a|b)", user_regex=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(11, 11), (11000, 11000)], mem_addr)
|
||||
|
||||
def test_020_role_exact(self):
|
||||
"""Iomemcon query with context role exact match"""
|
||||
q = IomemconQuery(self.p, role="role20_r", role_regex=False)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(20, 20)], mem_addr)
|
||||
|
||||
def test_021_role_regex(self):
|
||||
"""Iomemcon query with context role regex match"""
|
||||
q = IomemconQuery(self.p, role="role21(a|c)_r", role_regex=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(21, 21), (21001, 21001)], mem_addr)
|
||||
|
||||
def test_030_type_exact(self):
|
||||
"""Iomemcon query with context type exact match"""
|
||||
q = IomemconQuery(self.p, type_="type30", type_regex=False)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(30, 30)], mem_addr)
|
||||
|
||||
def test_031_type_regex(self):
|
||||
"""Iomemcon query with context type regex match"""
|
||||
q = IomemconQuery(self.p, type_="type31(b|c)", type_regex=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(31000, 31000), (31001, 31001)], mem_addr)
|
||||
|
||||
def test_040_range_exact(self):
|
||||
"""Iomemcon query with context range exact match"""
|
||||
q = IomemconQuery(self.p, range_="s0:c1 - s0:c0.c4")
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(40, 40)], mem_addr)
|
||||
|
||||
def test_041_range_overlap1(self):
|
||||
"""Iomemcon query with context range overlap match (equal)"""
|
||||
q = IomemconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(41, 41)], mem_addr)
|
||||
|
||||
def test_041_range_overlap2(self):
|
||||
"""Iomemcon query with context range overlap match (subset)"""
|
||||
q = IomemconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(41, 41)], mem_addr)
|
||||
|
||||
def test_041_range_overlap3(self):
|
||||
"""Iomemcon query with context range overlap match (superset)"""
|
||||
q = IomemconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(41, 41)], mem_addr)
|
||||
|
||||
def test_041_range_overlap4(self):
|
||||
"""Iomemcon query with context range overlap match (overlap low level)"""
|
||||
q = IomemconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(41, 41)], mem_addr)
|
||||
|
||||
def test_041_range_overlap5(self):
|
||||
"""Iomemcon query with context range overlap match (overlap high level)"""
|
||||
q = IomemconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(41, 41)], mem_addr)
|
||||
|
||||
def test_042_range_subset1(self):
|
||||
"""Iomemcon query with context range subset match"""
|
||||
q = IomemconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(42, 42)], mem_addr)
|
||||
|
||||
def test_042_range_subset2(self):
|
||||
"""Iomemcon query with context range subset match (equal)"""
|
||||
q = IomemconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(42, 42)], mem_addr)
|
||||
|
||||
def test_043_range_superset1(self):
|
||||
"""Iomemcon query with context range superset match"""
|
||||
q = IomemconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(43, 43)], mem_addr)
|
||||
|
||||
def test_043_range_superset2(self):
|
||||
"""Iomemcon query with context range superset match (equal)"""
|
||||
q = IomemconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(43, 43)], mem_addr)
|
||||
|
||||
def test_044_range_proper_subset1(self):
|
||||
"""Iomemcon query with context range proper subset match"""
|
||||
q = IomemconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(44, 44)], mem_addr)
|
||||
|
||||
def test_044_range_proper_subset2(self):
|
||||
"""Iomemcon query with context range proper subset match (equal)"""
|
||||
q = IomemconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_044_range_proper_subset3(self):
|
||||
"""Iomemcon query with context range proper subset match (equal low only)"""
|
||||
q = IomemconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(44, 44)], mem_addr)
|
||||
|
||||
def test_044_range_proper_subset4(self):
|
||||
"""Iomemcon query with context range proper subset match (equal high only)"""
|
||||
q = IomemconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(44, 44)], mem_addr)
|
||||
|
||||
def test_045_range_proper_superset1(self):
|
||||
"""Iomemcon query with context range proper superset match"""
|
||||
q = IomemconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(45, 45)], mem_addr)
|
||||
|
||||
def test_045_range_proper_superset2(self):
|
||||
"""Iomemcon query with context range proper superset match (equal)"""
|
||||
q = IomemconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_045_range_proper_superset3(self):
|
||||
"""Iomemcon query with context range proper superset match (equal low)"""
|
||||
q = IomemconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(45, 45)], mem_addr)
|
||||
|
||||
def test_045_range_proper_superset4(self):
|
||||
"""Iomemcon query with context range proper superset match (equal high)"""
|
||||
q = IomemconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(45, 45)], mem_addr)
|
||||
|
||||
def test_050_single_equal(self):
|
||||
"""Iomemcon query with single mem addr exact match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50, 50))
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50, 50)], mem_addr)
|
||||
|
||||
def test_051_range_equal(self):
|
||||
"""Iomemcon query with mem addr range exact match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50100, 50110))
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50100, 50110)], mem_addr)
|
||||
|
||||
def test_052_single_subset(self):
|
||||
"""Iomemcon query with single mem addr subset"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50200, 50200), mem_addr_subset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50200, 50200)], mem_addr)
|
||||
|
||||
def test_053_range_subset(self):
|
||||
"""Iomemcon query with range subset"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50301, 50309), mem_addr_subset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50300, 50310)], mem_addr)
|
||||
|
||||
def test_053_range_subset_edge1(self):
|
||||
"""Iomemcon query with range subset, equal edge case"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50300, 50310), mem_addr_subset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50300, 50310)], mem_addr)
|
||||
|
||||
def test_054_single_proper_subset(self):
|
||||
"""Iomemcon query with single mem addr proper subset"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50400, 50400), mem_addr_subset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_055_range_proper_subset(self):
|
||||
"""Iomemcon query with range proper subset"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50501, 50509), mem_addr_subset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], mem_addr)
|
||||
|
||||
def test_055_range_proper_subset_edge1(self):
|
||||
"""Iomemcon query with range proper subset, equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50500, 50510), mem_addr_subset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_055_range_proper_subset_edge2(self):
|
||||
"""Iomemcon query with range proper subset, low equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50500, 50509), mem_addr_subset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], mem_addr)
|
||||
|
||||
def test_055_range_proper_subset_edge3(self):
|
||||
"""Iomemcon query with range proper subset, high equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50501, 50510), mem_addr_subset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], mem_addr)
|
||||
|
||||
def test_056_single_superset(self):
|
||||
"""Iomemcon query with single mem addr superset"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50600, 50602), mem_addr_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50601, 50601)], mem_addr)
|
||||
|
||||
def test_056_single_superset_edge1(self):
|
||||
"""Iomemcon query with single mem addr superset, equal edge case"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50601, 50601), mem_addr_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50601, 50601)], mem_addr)
|
||||
|
||||
def test_057_range_superset(self):
|
||||
"""Iomemcon query with range superset"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50700, 50711), mem_addr_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50700, 50710)], mem_addr)
|
||||
|
||||
def test_057_range_superset_edge1(self):
|
||||
"""Iomemcon query with range superset, equal edge case"""
|
||||
q = IomemconQuery(self.p, mem_addr=(50700, 50710), mem_addr_superset=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50700, 50710)], mem_addr)
|
||||
|
||||
def test_058_single_proper_superset(self):
|
||||
"""Iomemcon query with single mem addr proper superset"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50800, 50802), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], mem_addr)
|
||||
|
||||
def test_058_single_proper_superset_edge1(self):
|
||||
"""Iomemcon query with single mem addr proper superset, equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50801, 50801), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_058_single_proper_superset_edge2(self):
|
||||
"""Iomemcon query with single mem addr proper superset, low equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50801, 50802), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], mem_addr)
|
||||
|
||||
def test_058_single_proper_superset_edge3(self):
|
||||
"""Iomemcon query with single mem addr proper superset, high equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50800, 50801), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], mem_addr)
|
||||
|
||||
def test_059_range_proper_superset(self):
|
||||
"""Iomemcon query with range proper superset"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50900, 50911), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], mem_addr)
|
||||
|
||||
def test_059_range_proper_superset_edge1(self):
|
||||
"""Iomemcon query with range proper superset, equal edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50901, 50910), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([], mem_addr)
|
||||
|
||||
def test_059_range_proper_superset_edge2(self):
|
||||
"""Iomemcon query with range proper superset, equal high mem addr edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50900, 50910), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], mem_addr)
|
||||
|
||||
def test_059_range_proper_superset_edge3(self):
|
||||
"""Iomemcon query with range proper superset, equal low mem addr edge case"""
|
||||
q = IomemconQuery(
|
||||
self.p, mem_addr=(50901, 50911), mem_addr_superset=True, mem_addr_proper=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], mem_addr)
|
||||
|
||||
def test_060_single_overlap(self):
|
||||
"""Iomemcon query with single overlap"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60001, 60001), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], mem_addr)
|
||||
|
||||
def test_060_single_overlap_edge1(self):
|
||||
"""Iomemcon query with single overlap, range match low"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60001, 60002), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], mem_addr)
|
||||
|
||||
def test_060_single_overlap_edge2(self):
|
||||
"""Iomemcon query with single overlap, range match high"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60000, 60001), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], mem_addr)
|
||||
|
||||
def test_060_single_overlap_edge3(self):
|
||||
"""Iomemcon query with single overlap, range match proper superset"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60000, 60002), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], mem_addr)
|
||||
|
||||
def test_061_range_overlap_low_half(self):
|
||||
"""Iomemcon query with range overlap, low half match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60100, 60105), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60101, 60110)], mem_addr)
|
||||
|
||||
def test_062_range_overlap_high_half(self):
|
||||
"""Iomemcon query with range overlap, high half match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60205, 60211), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60200, 60210)], mem_addr)
|
||||
|
||||
def test_063_range_overlap_middle(self):
|
||||
"""Iomemcon query with range overlap, middle match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60305, 60308), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60300, 60310)], mem_addr)
|
||||
|
||||
def test_064_range_overlap_equal(self):
|
||||
"""Iomemcon query with range overlap, equal match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60400, 60410), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60400, 60410)], mem_addr)
|
||||
|
||||
def test_065_range_overlap_superset(self):
|
||||
"""Iomemcon query with range overlap, superset match"""
|
||||
q = IomemconQuery(self.p, mem_addr=(60500, 60510), mem_addr_overlap=True)
|
||||
|
||||
mem_addr = sorted(p.mem_addr for p in q.results())
|
||||
self.assertListEqual([(60501, 60509)], mem_addr)
|
359
tests/ioportconquery.conf
Normal file
359
tests/ioportconquery.conf
Normal file
@ -0,0 +1,359 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity s0;
|
||||
sensitivity s1;
|
||||
sensitivity s2;
|
||||
sensitivity s3;
|
||||
sensitivity s4;
|
||||
sensitivity s5;
|
||||
sensitivity s6;
|
||||
|
||||
dominance { s0 s1 s2 s3 s4 s5 s6 }
|
||||
|
||||
category c0;
|
||||
category c1;
|
||||
category c2;
|
||||
category c3;
|
||||
category c4;
|
||||
|
||||
#level decl
|
||||
level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s4:c0.c4;
|
||||
level s5:c0.c4;
|
||||
level s6:c0.c4;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
role role20_r;
|
||||
role role21a_r;
|
||||
role role21b_r;
|
||||
role role21c_r;
|
||||
|
||||
role role20_r types system;
|
||||
role role21a_r types system;
|
||||
role role21b_r types system;
|
||||
role role21c_r types system;
|
||||
|
||||
type type30;
|
||||
type type31a;
|
||||
type type31b;
|
||||
type type31c;
|
||||
role system types { type30 type31a type31b type31c };
|
||||
|
||||
allow system self:infoflow hi_w;
|
||||
|
||||
#users
|
||||
user system roles { system role20_r role21a_r role21b_r role21c_r } level s0 range s0 - s6:c0.c4;
|
||||
user user10 roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11a roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11b roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11c roles system level s0 range s0 - s2:c0.c4;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:s0
|
||||
sid security system:system:system:s0
|
||||
|
||||
# test 1:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 1 system:system:system:s0:c0.c1
|
||||
|
||||
# test 10:
|
||||
# ports: unset
|
||||
# user: user10, exact
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 10 user10:system:system:s0:c0.c1
|
||||
|
||||
# test 11:
|
||||
# ports: unset
|
||||
# user: user11(a|b), regex
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 11 user11a:system:system:s0:c0.c1
|
||||
ioportcon 11000 user11b:system:system:s0:c0.c1
|
||||
ioportcon 11001 user11c:system:system:s0:c0.c1
|
||||
|
||||
# test 20:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: role20_r, exact
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 20 system:role20_r:system:s0:c0.c1
|
||||
|
||||
# test 21:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: role20(a|c)_r, regex
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 21 system:role21a_r:system:s0:c0.c1
|
||||
ioportcon 21000 system:role21b_r:system:s0:c0.c1
|
||||
ioportcon 21001 system:role21c_r:system:s0:c0.c1
|
||||
|
||||
# test 30:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type30
|
||||
# range: unset
|
||||
ioportcon 30 system:system:type30:s0:c0.c1
|
||||
|
||||
# test 31:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type31(b|c)
|
||||
# range: unset
|
||||
ioportcon 31 system:system:type31a:s0:c0.c1
|
||||
ioportcon 31000 system:system:type31b:s0:c0.c1
|
||||
ioportcon 31001 system:system:type31c:s0:c0.c1
|
||||
|
||||
# test 40:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: equal
|
||||
ioportcon 40 system:system:system:s0:c1 - s0:c0.c4
|
||||
|
||||
# test 41:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: overlap
|
||||
ioportcon 41 system:system:system:s1:c1 - s1:c1.c3
|
||||
|
||||
# test 42:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: subset
|
||||
ioportcon 42 system:system:system:s2:c1 - s2:c1.c3
|
||||
|
||||
# test 43:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: superset
|
||||
ioportcon 43 system:system:system:s3:c1 - s3:c1.c3
|
||||
|
||||
# test 44:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper subset
|
||||
ioportcon 44 system:system:system:s4:c1 - s4:c1.c3
|
||||
|
||||
# test 45:
|
||||
# ports: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper superset
|
||||
ioportcon 45 system:system:system:s5:c1 - s5:c1.c3
|
||||
|
||||
# test 50:
|
||||
# ports: (50, 50)
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50 system:system:system:s0:c0.c1
|
||||
|
||||
# test 51:
|
||||
# ports: (50100, 50110)
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50100-50110 system:system:system:s0:c0.c1
|
||||
|
||||
# test 52:
|
||||
# ports: (50200, 50200), subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50200 system:system:system:s0:c0.c1
|
||||
|
||||
# test 53:
|
||||
# ports: (50301, 50309), subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50300-50310 system:system:system:s0:c0.c1
|
||||
|
||||
# test 54:
|
||||
# ports: (50400, 50400), proper subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50400 system:system:system:s0:c0.c1
|
||||
|
||||
# test 55:
|
||||
# ports: (50501, 50509), proper subset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50500-50510 system:system:system:s0:c0.c1
|
||||
|
||||
# test 56:
|
||||
# ports: (50600, 50602), superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50601 system:system:system:s0:c0.c1
|
||||
|
||||
# test 57:
|
||||
# ports: (50700, 50711), superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50700-50710 system:system:system:s0:c0.c1
|
||||
|
||||
# test 58:
|
||||
# ports: (50600, 50602), proper superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50801 system:system:system:s0:c0.c1
|
||||
|
||||
# test 59:
|
||||
# ports: (50900, 50911), proper superset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 50901-50910 system:system:system:s0:c0.c1
|
||||
|
||||
# test 60:
|
||||
# ports: (60001, 60001), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60001 system:system:system:s0:c0.c1
|
||||
|
||||
# test 61:
|
||||
# ports: (60100, 60105), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60101-60110 system:system:system:s0:c0.c1
|
||||
|
||||
# test 62:
|
||||
# ports: (60205, 60211), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60200-60210 system:system:system:s0:c0.c1
|
||||
|
||||
# test 63:
|
||||
# ports: (60305, 60308), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60300-60310 system:system:system:s0:c0.c1
|
||||
|
||||
# test 64:
|
||||
# ports: (60400, 60410), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60400-60410 system:system:system:s0:c0.c1
|
||||
|
||||
# test 65:
|
||||
# ports: (60500, 60510), overlap
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
ioportcon 60501-60509 system:system:system:s0:c0.c1
|
||||
|
435
tests/ioportconquery.py
Normal file
435
tests/ioportconquery.py
Normal file
@ -0,0 +1,435 @@
|
||||
# Derived from tests/portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, IoportconQuery
|
||||
|
||||
|
||||
class IoportconQueryTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/ioportconquery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""Ioportcon query with no criteria"""
|
||||
# query with no parameters gets all ports.
|
||||
rules = sorted(self.p.ioportcons())
|
||||
|
||||
q = IoportconQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_010_user_exact(self):
|
||||
"""Portcon query with context user exact match"""
|
||||
q = IoportconQuery(self.p, user="user10", user_regex=False)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(10, 10)], ports)
|
||||
|
||||
def test_011_user_regex(self):
|
||||
"""Portcon query with context user regex match"""
|
||||
q = IoportconQuery(self.p, user="user11(a|b)", user_regex=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(11, 11), (11000, 11000)], ports)
|
||||
|
||||
def test_020_role_exact(self):
|
||||
"""Portcon query with context role exact match"""
|
||||
q = IoportconQuery(self.p, role="role20_r", role_regex=False)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(20, 20)], ports)
|
||||
|
||||
def test_021_role_regex(self):
|
||||
"""Portcon query with context role regex match"""
|
||||
q = IoportconQuery(self.p, role="role21(a|c)_r", role_regex=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(21, 21), (21001, 21001)], ports)
|
||||
|
||||
def test_030_type_exact(self):
|
||||
"""Portcon query with context type exact match"""
|
||||
q = IoportconQuery(self.p, type_="type30", type_regex=False)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(30, 30)], ports)
|
||||
|
||||
def test_031_type_regex(self):
|
||||
"""Portcon query with context type regex match"""
|
||||
q = IoportconQuery(self.p, type_="type31(b|c)", type_regex=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(31000, 31000), (31001, 31001)], ports)
|
||||
|
||||
def test_040_range_exact(self):
|
||||
"""Portcon query with context range exact match"""
|
||||
q = IoportconQuery(self.p, range_="s0:c1 - s0:c0.c4")
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(40, 40)], ports)
|
||||
|
||||
def test_041_range_overlap1(self):
|
||||
"""Portcon query with context range overlap match (equal)"""
|
||||
q = IoportconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(41, 41)], ports)
|
||||
|
||||
def test_041_range_overlap2(self):
|
||||
"""Portcon query with context range overlap match (subset)"""
|
||||
q = IoportconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(41, 41)], ports)
|
||||
|
||||
def test_041_range_overlap3(self):
|
||||
"""Portcon query with context range overlap match (superset)"""
|
||||
q = IoportconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(41, 41)], ports)
|
||||
|
||||
def test_041_range_overlap4(self):
|
||||
"""Portcon query with context range overlap match (overlap low level)"""
|
||||
q = IoportconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(41, 41)], ports)
|
||||
|
||||
def test_041_range_overlap5(self):
|
||||
"""Portcon query with context range overlap match (overlap high level)"""
|
||||
q = IoportconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(41, 41)], ports)
|
||||
|
||||
def test_042_range_subset1(self):
|
||||
"""Portcon query with context range subset match"""
|
||||
q = IoportconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(42, 42)], ports)
|
||||
|
||||
def test_042_range_subset2(self):
|
||||
"""Portcon query with context range subset match (equal)"""
|
||||
q = IoportconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(42, 42)], ports)
|
||||
|
||||
def test_043_range_superset1(self):
|
||||
"""Portcon query with context range superset match"""
|
||||
q = IoportconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(43, 43)], ports)
|
||||
|
||||
def test_043_range_superset2(self):
|
||||
"""Portcon query with context range superset match (equal)"""
|
||||
q = IoportconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(43, 43)], ports)
|
||||
|
||||
def test_044_range_proper_subset1(self):
|
||||
"""Portcon query with context range proper subset match"""
|
||||
q = IoportconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(44, 44)], ports)
|
||||
|
||||
def test_044_range_proper_subset2(self):
|
||||
"""Portcon query with context range proper subset match (equal)"""
|
||||
q = IoportconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_044_range_proper_subset3(self):
|
||||
"""Portcon query with context range proper subset match (equal low only)"""
|
||||
q = IoportconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(44, 44)], ports)
|
||||
|
||||
def test_044_range_proper_subset4(self):
|
||||
"""Portcon query with context range proper subset match (equal high only)"""
|
||||
q = IoportconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(44, 44)], ports)
|
||||
|
||||
def test_045_range_proper_superset1(self):
|
||||
"""Portcon query with context range proper superset match"""
|
||||
q = IoportconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(45, 45)], ports)
|
||||
|
||||
def test_045_range_proper_superset2(self):
|
||||
"""Portcon query with context range proper superset match (equal)"""
|
||||
q = IoportconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_045_range_proper_superset3(self):
|
||||
"""Portcon query with context range proper superset match (equal low)"""
|
||||
q = IoportconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(45, 45)], ports)
|
||||
|
||||
def test_045_range_proper_superset4(self):
|
||||
"""Portcon query with context range proper superset match (equal high)"""
|
||||
q = IoportconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(45, 45)], ports)
|
||||
|
||||
def test_050_single_equal(self):
|
||||
"""Portcon query with single port exact match"""
|
||||
q = IoportconQuery(self.p, ports=(50, 50))
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50, 50)], ports)
|
||||
|
||||
def test_051_range_equal(self):
|
||||
"""Portcon query with port range exact match"""
|
||||
q = IoportconQuery(self.p, ports=(50100, 50110))
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50100, 50110)], ports)
|
||||
|
||||
def test_052_single_subset(self):
|
||||
"""Portcon query with single port subset"""
|
||||
q = IoportconQuery(self.p, ports=(50200, 50200), ports_subset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50200, 50200)], ports)
|
||||
|
||||
def test_053_range_subset(self):
|
||||
"""Portcon query with range subset"""
|
||||
q = IoportconQuery(self.p, ports=(50301, 50309), ports_subset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50300, 50310)], ports)
|
||||
|
||||
def test_053_range_subset_edge1(self):
|
||||
"""Portcon query with range subset, equal edge case"""
|
||||
q = IoportconQuery(self.p, ports=(50300, 50310), ports_subset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50300, 50310)], ports)
|
||||
|
||||
def test_054_single_proper_subset(self):
|
||||
"""Portcon query with single port proper subset"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50400, 50400), ports_subset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_055_range_proper_subset(self):
|
||||
"""Portcon query with range proper subset"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50501, 50509), ports_subset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], ports)
|
||||
|
||||
def test_055_range_proper_subset_edge1(self):
|
||||
"""Portcon query with range proper subset, equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50500, 50510), ports_subset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_055_range_proper_subset_edge2(self):
|
||||
"""Portcon query with range proper subset, low equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50500, 50509), ports_subset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], ports)
|
||||
|
||||
def test_055_range_proper_subset_edge3(self):
|
||||
"""Portcon query with range proper subset, high equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50501, 50510), ports_subset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50500, 50510)], ports)
|
||||
|
||||
def test_056_single_superset(self):
|
||||
"""Portcon query with single port superset"""
|
||||
q = IoportconQuery(self.p, ports=(50600, 50602), ports_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50601, 50601)], ports)
|
||||
|
||||
def test_056_single_superset_edge1(self):
|
||||
"""Portcon query with single port superset, equal edge case"""
|
||||
q = IoportconQuery(self.p, ports=(50601, 50601), ports_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50601, 50601)], ports)
|
||||
|
||||
def test_057_range_superset(self):
|
||||
"""Portcon query with range superset"""
|
||||
q = IoportconQuery(self.p, ports=(50700, 50711), ports_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50700, 50710)], ports)
|
||||
|
||||
def test_057_range_superset_edge1(self):
|
||||
"""Portcon query with range superset, equal edge case"""
|
||||
q = IoportconQuery(self.p, ports=(50700, 50710), ports_superset=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50700, 50710)], ports)
|
||||
|
||||
def test_058_single_proper_superset(self):
|
||||
"""Portcon query with single port proper superset"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50800, 50802), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], ports)
|
||||
|
||||
def test_058_single_proper_superset_edge1(self):
|
||||
"""Portcon query with single port proper superset, equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50801, 50801), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_058_single_proper_superset_edge2(self):
|
||||
"""Portcon query with single port proper superset, low equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50801, 50802), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], ports)
|
||||
|
||||
def test_058_single_proper_superset_edge3(self):
|
||||
"""Portcon query with single port proper superset, high equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50800, 50801), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50801, 50801)], ports)
|
||||
|
||||
def test_059_range_proper_superset(self):
|
||||
"""Portcon query with range proper superset"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50900, 50911), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], ports)
|
||||
|
||||
def test_059_range_proper_superset_edge1(self):
|
||||
"""Portcon query with range proper superset, equal edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50901, 50910), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([], ports)
|
||||
|
||||
def test_059_range_proper_superset_edge2(self):
|
||||
"""Portcon query with range proper superset, equal high port edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50900, 50910), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], ports)
|
||||
|
||||
def test_059_range_proper_superset_edge3(self):
|
||||
"""Portcon query with range proper superset, equal low port edge case"""
|
||||
q = IoportconQuery(
|
||||
self.p, ports=(50901, 50911), ports_superset=True, ports_proper=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(50901, 50910)], ports)
|
||||
|
||||
def test_060_single_overlap(self):
|
||||
"""Portcon query with single overlap"""
|
||||
q = IoportconQuery(self.p, ports=(60001, 60001), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], ports)
|
||||
|
||||
def test_060_single_overlap_edge1(self):
|
||||
"""Portcon query with single overlap, range match low"""
|
||||
q = IoportconQuery(self.p, ports=(60001, 60002), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], ports)
|
||||
|
||||
def test_060_single_overlap_edge2(self):
|
||||
"""Portcon query with single overlap, range match high"""
|
||||
q = IoportconQuery(self.p, ports=(60000, 60001), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], ports)
|
||||
|
||||
def test_060_single_overlap_edge3(self):
|
||||
"""Portcon query with single overlap, range match proper superset"""
|
||||
q = IoportconQuery(self.p, ports=(60000, 60002), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60001, 60001)], ports)
|
||||
|
||||
def test_061_range_overlap_low_half(self):
|
||||
"""Portcon query with range overlap, low half match"""
|
||||
q = IoportconQuery(self.p, ports=(60100, 60105), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60101, 60110)], ports)
|
||||
|
||||
def test_062_range_overlap_high_half(self):
|
||||
"""Portcon query with range overlap, high half match"""
|
||||
q = IoportconQuery(self.p, ports=(60205, 60211), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60200, 60210)], ports)
|
||||
|
||||
def test_063_range_overlap_middle(self):
|
||||
"""Portcon query with range overlap, middle match"""
|
||||
q = IoportconQuery(self.p, ports=(60305, 60308), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60300, 60310)], ports)
|
||||
|
||||
def test_064_range_overlap_equal(self):
|
||||
"""Portcon query with range overlap, equal match"""
|
||||
q = IoportconQuery(self.p, ports=(60400, 60410), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60400, 60410)], ports)
|
||||
|
||||
def test_065_range_overlap_superset(self):
|
||||
"""Portcon query with range overlap, superset match"""
|
||||
q = IoportconQuery(self.p, ports=(60500, 60510), ports_overlap=True)
|
||||
|
||||
ports = sorted(p.ports for p in q.results())
|
||||
self.assertListEqual([(60501, 60509)], ports)
|
@ -47,3 +47,21 @@ class ValidateRule(unittest.TestCase):
|
||||
|
||||
if cond_block is not None:
|
||||
self.assertEqual(cond_block, rule.conditional_block)
|
||||
|
||||
|
||||
class ValidateXpermRule(unittest.TestCase):
|
||||
|
||||
"""Mixin for validating policy xperm rules."""
|
||||
|
||||
def validate_xperm_rule(self, rule, ruletype, source, target, tclass):
|
||||
"""Validate a rule."""
|
||||
self.assertEqual(ruletype, rule.ruletype)
|
||||
self.assertEqual(source, rule.source)
|
||||
self.assertEqual(target, rule.target)
|
||||
self.assertEqual(tclass, rule.tclass)
|
||||
|
||||
# try:
|
||||
# # This is the common case.
|
||||
# self.assertSetEqual(last_item, rule.perms)
|
||||
# except (AttributeError, RuleUseError):
|
||||
# self.assertEqual(last_item, rule.default)
|
||||
|
231
tests/pcideviceconquery.conf
Normal file
231
tests/pcideviceconquery.conf
Normal file
@ -0,0 +1,231 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity s0;
|
||||
sensitivity s1;
|
||||
sensitivity s2;
|
||||
sensitivity s3;
|
||||
sensitivity s4;
|
||||
sensitivity s5;
|
||||
sensitivity s6;
|
||||
|
||||
dominance { s0 s1 s2 s3 s4 s5 s6 }
|
||||
|
||||
category c0;
|
||||
category c1;
|
||||
category c2;
|
||||
category c3;
|
||||
category c4;
|
||||
|
||||
#level decl
|
||||
level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s4:c0.c4;
|
||||
level s5:c0.c4;
|
||||
level s6:c0.c4;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
role role20_r;
|
||||
role role21a_r;
|
||||
role role21b_r;
|
||||
role role21c_r;
|
||||
|
||||
role role20_r types system;
|
||||
role role21a_r types system;
|
||||
role role21b_r types system;
|
||||
role role21c_r types system;
|
||||
|
||||
type type30;
|
||||
type type31a;
|
||||
type type31b;
|
||||
type type31c;
|
||||
role system types { type30 type31a type31b type31c };
|
||||
|
||||
allow system self:infoflow hi_w;
|
||||
|
||||
#users
|
||||
user system roles { system role20_r role21a_r role21b_r role21c_r } level s0 range s0 - s6:c0.c4;
|
||||
user user10 roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11a roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11b roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11c roles system level s0 range s0 - s2:c0.c4;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:s0
|
||||
sid security system:system:system:s0
|
||||
|
||||
# test 1:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pcidevicecon 1 system:system:system:s0:c0.c1
|
||||
|
||||
# test 10:
|
||||
# pci device: unset
|
||||
# user: user10, exact
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pcidevicecon 10 user10:system:system:s0:c0.c1
|
||||
|
||||
# test 11:
|
||||
# pci device: unset
|
||||
# user: user11(a|b), regex
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pcidevicecon 11 user11a:system:system:s0:c0.c1
|
||||
pcidevicecon 11000 user11b:system:system:s0:c0.c1
|
||||
pcidevicecon 11001 user11c:system:system:s0:c0.c1
|
||||
|
||||
# test 20:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: role20_r, exact
|
||||
# type: unset
|
||||
# range: unset
|
||||
pcidevicecon 20 system:role20_r:system:s0:c0.c1
|
||||
|
||||
# test 21:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: role20(a|c)_r, regex
|
||||
# type: unset
|
||||
# range: unset
|
||||
pcidevicecon 21 system:role21a_r:system:s0:c0.c1
|
||||
pcidevicecon 21000 system:role21b_r:system:s0:c0.c1
|
||||
pcidevicecon 21001 system:role21c_r:system:s0:c0.c1
|
||||
|
||||
# test 30:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type30
|
||||
# range: unset
|
||||
pcidevicecon 30 system:system:type30:s0:c0.c1
|
||||
|
||||
# test 31:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type31(b|c)
|
||||
# range: unset
|
||||
pcidevicecon 31 system:system:type31a:s0:c0.c1
|
||||
pcidevicecon 31000 system:system:type31b:s0:c0.c1
|
||||
pcidevicecon 31001 system:system:type31c:s0:c0.c1
|
||||
|
||||
# test 40:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: equal
|
||||
pcidevicecon 40 system:system:system:s0:c1 - s0:c0.c4
|
||||
|
||||
# test 41:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: overlap
|
||||
pcidevicecon 41 system:system:system:s1:c1 - s1:c1.c3
|
||||
|
||||
# test 42:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: subset
|
||||
pcidevicecon 42 system:system:system:s2:c1 - s2:c1.c3
|
||||
|
||||
# test 43:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: superset
|
||||
pcidevicecon 43 system:system:system:s3:c1 - s3:c1.c3
|
||||
|
||||
# test 44:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper subset
|
||||
pcidevicecon 44 system:system:system:s4:c1 - s4:c1.c3
|
||||
|
||||
# test 45:
|
||||
# pci device: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper superset
|
||||
pcidevicecon 45 system:system:system:s5:c1 - s5:c1.c3
|
||||
|
206
tests/pcideviceconquery.py
Normal file
206
tests/pcideviceconquery.py
Normal file
@ -0,0 +1,206 @@
|
||||
# Derived from tests/portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, PcideviceconQuery
|
||||
|
||||
|
||||
class PcideviceconQueryTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/pcideviceconquery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""Pcidevicecon query with no criteria"""
|
||||
# query with no parameters gets all PCI devices.
|
||||
rules = sorted(self.p.pcidevicecons())
|
||||
|
||||
q = PcideviceconQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_010_user_exact(self):
|
||||
"""Pcidevicecon query with context user exact match"""
|
||||
q = PcideviceconQuery(self.p, user="user10", user_regex=False)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(10)], device)
|
||||
|
||||
def test_011_user_regex(self):
|
||||
"""Pcidevicecon query with context user regex match"""
|
||||
q = PcideviceconQuery(self.p, user="user11(a|b)", user_regex=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(11), (11000)], device)
|
||||
|
||||
def test_020_role_exact(self):
|
||||
"""Pcidevicecon query with context role exact match"""
|
||||
q = PcideviceconQuery(self.p, role="role20_r", role_regex=False)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(20)], device)
|
||||
|
||||
def test_021_role_regex(self):
|
||||
"""Pcidevicecon query with context role regex match"""
|
||||
q = PcideviceconQuery(self.p, role="role21(a|c)_r", role_regex=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(21), (21001)], device)
|
||||
|
||||
def test_030_type_exact(self):
|
||||
"""Pcidevicecon query with context type exact match"""
|
||||
q = PcideviceconQuery(self.p, type_="type30", type_regex=False)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(30)], device)
|
||||
|
||||
def test_031_type_regex(self):
|
||||
"""Pcidevicecon query with context type regex match"""
|
||||
q = PcideviceconQuery(self.p, type_="type31(b|c)", type_regex=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(31000), (31001)], device)
|
||||
|
||||
def test_040_range_exact(self):
|
||||
"""Pcidevicecon query with context range exact match"""
|
||||
q = PcideviceconQuery(self.p, range_="s0:c1 - s0:c0.c4")
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(40)], device)
|
||||
|
||||
def test_041_range_overlap1(self):
|
||||
"""Pcidevicecon query with context range overlap match (equal)"""
|
||||
q = PcideviceconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(41)], device)
|
||||
|
||||
def test_041_range_overlap2(self):
|
||||
"""Pcidevicecon query with context range overlap match (subset)"""
|
||||
q = PcideviceconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(41)], device)
|
||||
|
||||
def test_041_range_overlap3(self):
|
||||
"""Pcidevicecon query with context range overlap match (superset)"""
|
||||
q = PcideviceconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(41)], device)
|
||||
|
||||
def test_041_range_overlap4(self):
|
||||
"""Pcidevicecon query with context range overlap match (overlap low level)"""
|
||||
q = PcideviceconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(41)], device)
|
||||
|
||||
def test_041_range_overlap5(self):
|
||||
"""Pcidevicecon query with context range overlap match (overlap high level)"""
|
||||
q = PcideviceconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(41)], device)
|
||||
|
||||
def test_042_range_subset1(self):
|
||||
"""Pcidevicecon query with context range subset match"""
|
||||
q = PcideviceconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(42)], device)
|
||||
|
||||
def test_042_range_subset2(self):
|
||||
"""Pcidevicecon query with context range subset match (equal)"""
|
||||
q = PcideviceconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(42)], device)
|
||||
|
||||
def test_043_range_superset1(self):
|
||||
"""Pcidevicecon query with context range superset match"""
|
||||
q = PcideviceconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(43)], device)
|
||||
|
||||
def test_043_range_superset2(self):
|
||||
"""Pcidevicecon query with context range superset match (equal)"""
|
||||
q = PcideviceconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(43)], device)
|
||||
|
||||
def test_044_range_proper_subset1(self):
|
||||
"""Pcidevicecon query with context range proper subset match"""
|
||||
q = PcideviceconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(44)], device)
|
||||
|
||||
def test_044_range_proper_subset2(self):
|
||||
"""Pcidevicecon query with context range proper subset match (equal)"""
|
||||
q = PcideviceconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([], device)
|
||||
|
||||
def test_044_range_proper_subset3(self):
|
||||
"""Pcidevicecon query with context range proper subset match (equal low only)"""
|
||||
q = PcideviceconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(44)], device)
|
||||
|
||||
def test_044_range_proper_subset4(self):
|
||||
"""Pcidevicecon query with context range proper subset match (equal high only)"""
|
||||
q = PcideviceconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(44)], device)
|
||||
|
||||
def test_045_range_proper_superset1(self):
|
||||
"""Pcidevicecon query with context range proper superset match"""
|
||||
q = PcideviceconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(45)], device)
|
||||
|
||||
def test_045_range_proper_superset2(self):
|
||||
"""Pcidevicecon query with context range proper superset match (equal)"""
|
||||
q = PcideviceconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([], device)
|
||||
|
||||
def test_045_range_proper_superset3(self):
|
||||
"""Pcidevicecon query with context range proper superset match (equal low)"""
|
||||
q = PcideviceconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(45)], device)
|
||||
|
||||
def test_045_range_proper_superset4(self):
|
||||
"""Pcidevicecon query with context range proper superset match (equal high)"""
|
||||
q = PcideviceconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
device = sorted(p.device for p in q.results())
|
||||
self.assertListEqual([(45)], device)
|
||||
|
231
tests/pirqconquery.conf
Normal file
231
tests/pirqconquery.conf
Normal file
@ -0,0 +1,231 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity s0;
|
||||
sensitivity s1;
|
||||
sensitivity s2;
|
||||
sensitivity s3;
|
||||
sensitivity s4;
|
||||
sensitivity s5;
|
||||
sensitivity s6;
|
||||
|
||||
dominance { s0 s1 s2 s3 s4 s5 s6 }
|
||||
|
||||
category c0;
|
||||
category c1;
|
||||
category c2;
|
||||
category c3;
|
||||
category c4;
|
||||
|
||||
#level decl
|
||||
level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s4:c0.c4;
|
||||
level s5:c0.c4;
|
||||
level s6:c0.c4;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
role role20_r;
|
||||
role role21a_r;
|
||||
role role21b_r;
|
||||
role role21c_r;
|
||||
|
||||
role role20_r types system;
|
||||
role role21a_r types system;
|
||||
role role21b_r types system;
|
||||
role role21c_r types system;
|
||||
|
||||
type type30;
|
||||
type type31a;
|
||||
type type31b;
|
||||
type type31c;
|
||||
role system types { type30 type31a type31b type31c };
|
||||
|
||||
allow system self:infoflow hi_w;
|
||||
|
||||
#users
|
||||
user system roles { system role20_r role21a_r role21b_r role21c_r } level s0 range s0 - s6:c0.c4;
|
||||
user user10 roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11a roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11b roles system level s0 range s0 - s2:c0.c4;
|
||||
user user11c roles system level s0 range s0 - s2:c0.c4;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:s0
|
||||
sid security system:system:system:s0
|
||||
|
||||
# test 1:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pirqcon 1 system:system:system:s0:c0.c1
|
||||
|
||||
# test 10:
|
||||
# irq: unset
|
||||
# user: user10, exact
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pirqcon 10 user10:system:system:s0:c0.c1
|
||||
|
||||
# test 11:
|
||||
# irq: unset
|
||||
# user: user11(a|b), regex
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: unset
|
||||
pirqcon 11 user11a:system:system:s0:c0.c1
|
||||
pirqcon 11000 user11b:system:system:s0:c0.c1
|
||||
pirqcon 11001 user11c:system:system:s0:c0.c1
|
||||
|
||||
# test 20:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: role20_r, exact
|
||||
# type: unset
|
||||
# range: unset
|
||||
pirqcon 20 system:role20_r:system:s0:c0.c1
|
||||
|
||||
# test 21:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: role20(a|c)_r, regex
|
||||
# type: unset
|
||||
# range: unset
|
||||
pirqcon 21 system:role21a_r:system:s0:c0.c1
|
||||
pirqcon 21000 system:role21b_r:system:s0:c0.c1
|
||||
pirqcon 21001 system:role21c_r:system:s0:c0.c1
|
||||
|
||||
# test 30:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type30
|
||||
# range: unset
|
||||
pirqcon 30 system:system:type30:s0:c0.c1
|
||||
|
||||
# test 31:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: type31(b|c)
|
||||
# range: unset
|
||||
pirqcon 31 system:system:type31a:s0:c0.c1
|
||||
pirqcon 31000 system:system:type31b:s0:c0.c1
|
||||
pirqcon 31001 system:system:type31c:s0:c0.c1
|
||||
|
||||
# test 40:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: equal
|
||||
pirqcon 40 system:system:system:s0:c1 - s0:c0.c4
|
||||
|
||||
# test 41:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: overlap
|
||||
pirqcon 41 system:system:system:s1:c1 - s1:c1.c3
|
||||
|
||||
# test 42:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: subset
|
||||
pirqcon 42 system:system:system:s2:c1 - s2:c1.c3
|
||||
|
||||
# test 43:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: superset
|
||||
pirqcon 43 system:system:system:s3:c1 - s3:c1.c3
|
||||
|
||||
# test 44:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper subset
|
||||
pirqcon 44 system:system:system:s4:c1 - s4:c1.c3
|
||||
|
||||
# test 45:
|
||||
# irq: unset
|
||||
# user: unset
|
||||
# role: unset
|
||||
# type: unset
|
||||
# range: proper superset
|
||||
pirqcon 45 system:system:system:s5:c1 - s5:c1.c3
|
||||
|
206
tests/pirqconquery.py
Normal file
206
tests/pirqconquery.py
Normal file
@ -0,0 +1,206 @@
|
||||
# Derived from tests/portconquery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, PirqconQuery
|
||||
|
||||
|
||||
class PirqconQueryTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/pirqconquery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""Pirqcon query with no criteria"""
|
||||
# query with no parameters gets all PCI irqs.
|
||||
rules = sorted(self.p.pirqcons())
|
||||
|
||||
q = PirqconQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_010_user_exact(self):
|
||||
"""Pirqcon query with context user exact match"""
|
||||
q = PirqconQuery(self.p, user="user10", user_regex=False)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(10)], irq)
|
||||
|
||||
def test_011_user_regex(self):
|
||||
"""Pirqcon query with context user regex match"""
|
||||
q = PirqconQuery(self.p, user="user11(a|b)", user_regex=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(11), (11000)], irq)
|
||||
|
||||
def test_020_role_exact(self):
|
||||
"""Pirqcon query with context role exact match"""
|
||||
q = PirqconQuery(self.p, role="role20_r", role_regex=False)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(20)], irq)
|
||||
|
||||
def test_021_role_regex(self):
|
||||
"""Pirqcon query with context role regex match"""
|
||||
q = PirqconQuery(self.p, role="role21(a|c)_r", role_regex=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(21), (21001)], irq)
|
||||
|
||||
def test_030_type_exact(self):
|
||||
"""Pirqcon query with context type exact match"""
|
||||
q = PirqconQuery(self.p, type_="type30", type_regex=False)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(30)], irq)
|
||||
|
||||
def test_031_type_regex(self):
|
||||
"""Pirqcon query with context type regex match"""
|
||||
q = PirqconQuery(self.p, type_="type31(b|c)", type_regex=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(31000), (31001)], irq)
|
||||
|
||||
def test_040_range_exact(self):
|
||||
"""Pirqcon query with context range exact match"""
|
||||
q = PirqconQuery(self.p, range_="s0:c1 - s0:c0.c4")
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(40)], irq)
|
||||
|
||||
def test_041_range_overlap1(self):
|
||||
"""Pirqcon query with context range overlap match (equal)"""
|
||||
q = PirqconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(41)], irq)
|
||||
|
||||
def test_041_range_overlap2(self):
|
||||
"""Pirqcon query with context range overlap match (subset)"""
|
||||
q = PirqconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(41)], irq)
|
||||
|
||||
def test_041_range_overlap3(self):
|
||||
"""Pirqcon query with context range overlap match (superset)"""
|
||||
q = PirqconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(41)], irq)
|
||||
|
||||
def test_041_range_overlap4(self):
|
||||
"""Pirqcon query with context range overlap match (overlap low level)"""
|
||||
q = PirqconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(41)], irq)
|
||||
|
||||
def test_041_range_overlap5(self):
|
||||
"""Pirqcon query with context range overlap match (overlap high level)"""
|
||||
q = PirqconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(41)], irq)
|
||||
|
||||
def test_042_range_subset1(self):
|
||||
"""Pirqcon query with context range subset match"""
|
||||
q = PirqconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(42)], irq)
|
||||
|
||||
def test_042_range_subset2(self):
|
||||
"""Pirqcon query with context range subset match (equal)"""
|
||||
q = PirqconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(42)], irq)
|
||||
|
||||
def test_043_range_superset1(self):
|
||||
"""Pirqcon query with context range superset match"""
|
||||
q = PirqconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(43)], irq)
|
||||
|
||||
def test_043_range_superset2(self):
|
||||
"""Pirqcon query with context range superset match (equal)"""
|
||||
q = PirqconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(43)], irq)
|
||||
|
||||
def test_044_range_proper_subset1(self):
|
||||
"""Pirqcon query with context range proper subset match"""
|
||||
q = PirqconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(44)], irq)
|
||||
|
||||
def test_044_range_proper_subset2(self):
|
||||
"""Pirqcon query with context range proper subset match (equal)"""
|
||||
q = PirqconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([], irq)
|
||||
|
||||
def test_044_range_proper_subset3(self):
|
||||
"""Pirqcon query with context range proper subset match (equal low only)"""
|
||||
q = PirqconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(44)], irq)
|
||||
|
||||
def test_044_range_proper_subset4(self):
|
||||
"""Pirqcon query with context range proper subset match (equal high only)"""
|
||||
q = PirqconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(44)], irq)
|
||||
|
||||
def test_045_range_proper_superset1(self):
|
||||
"""Pirqcon query with context range proper superset match"""
|
||||
q = PirqconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(45)], irq)
|
||||
|
||||
def test_045_range_proper_superset2(self):
|
||||
"""Pirqcon query with context range proper superset match (equal)"""
|
||||
q = PirqconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([], irq)
|
||||
|
||||
def test_045_range_proper_superset3(self):
|
||||
"""Pirqcon query with context range proper superset match (equal low)"""
|
||||
q = PirqconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(45)], irq)
|
||||
|
||||
def test_045_range_proper_superset4(self):
|
||||
"""Pirqcon query with context range proper superset match (equal high)"""
|
||||
q = PirqconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
|
||||
|
||||
irq = sorted(p.irq for p in q.results())
|
||||
self.assertListEqual([(45)], irq)
|
||||
|
265
tests/xpermrulequery.conf
Normal file
265
tests/xpermrulequery.conf
Normal file
@ -0,0 +1,265 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
ioctl
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
ioctl
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
|
||||
class infoflow5
|
||||
inherits infoflow
|
||||
|
||||
class infoflow6
|
||||
inherits infoflow
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
sensitivity low_s;
|
||||
sensitivity medium_s alias med;
|
||||
sensitivity high_s;
|
||||
|
||||
dominance { low_s med high_s }
|
||||
|
||||
category here;
|
||||
category there;
|
||||
category elsewhere alias lost;
|
||||
|
||||
#level decl
|
||||
level low_s:here.there;
|
||||
level med:here, elsewhere;
|
||||
level high_s:here.lost;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
|
||||
|
||||
#########################################
|
||||
# XPERM ioctl declarations and rules
|
||||
|
||||
# test 1
|
||||
# ruletype: unset
|
||||
# source: test1a, direct, no regex
|
||||
# target: unset
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test1a;
|
||||
type test1s, test1a;
|
||||
type test1t;
|
||||
type test1FAIL, test1a;
|
||||
allowxperm test1a test1t:infoflow ioctl { 0xebe0-0xebff }; # sets AVRULE_XPERMS_IOCTLFUNCTION
|
||||
allowxperm test1FAIL self:infoflow ioctl { 0x8800-0x88ff }; # sets AVRULE_XPERMS_IOCTLDRIVER
|
||||
|
||||
# test 2
|
||||
# ruletype: unset
|
||||
# source: test2s, indirect, no regex
|
||||
# target: unset
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test2a;
|
||||
type test2s, test2a;
|
||||
type test2t;
|
||||
allowxperm test2a test2t:infoflow ioctl { 0x5411 0x5451 };
|
||||
|
||||
# test 3
|
||||
# ruletype: unset
|
||||
# source: test3a.*, direct, regex
|
||||
# target: unset
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test3aS;
|
||||
attribute test3b;
|
||||
type test3s, test3aS;
|
||||
type test3t;
|
||||
type test3aFAIL, test3b;
|
||||
allowxperm test3s test3t:infoflow ioctl 0x9999;
|
||||
allowxperm test3aS test3t:infoflow ioctl 0x1111;
|
||||
allowxperm test3b test3t:infoflow ioctl 0x5555;
|
||||
|
||||
# test 4
|
||||
# ruletype: unset
|
||||
# source: test4(s|t), indirect, regex
|
||||
# target: unset
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test4a1;
|
||||
attribute test4a2;
|
||||
type test4s1, test4a1;
|
||||
type test4t1, test4a2;
|
||||
type test4FAIL;
|
||||
allowxperm test4a1 test4a1:infoflow ioctl 0x9999;
|
||||
allowxperm test4a2 test4a2:infoflow ioctl 0x1111;
|
||||
allowxperm test4FAIL self:infoflow ioctl 0x5555;
|
||||
|
||||
# test 5
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: test5a, direct, no regex
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test5a;
|
||||
type test5s;
|
||||
type test5t, test5a;
|
||||
allowxperm test5s test5a:infoflow ioctl 0x9999;
|
||||
allowxperm test5s test5t:infoflow ioctl 0x9999;
|
||||
|
||||
# test 6
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: test6t, indirect, no regex
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test6a;
|
||||
type test6s;
|
||||
type test6t, test6a;
|
||||
allowxperm test6s test6a:infoflow ioctl 0x9999;
|
||||
allowxperm test6s test6t:infoflow ioctl 0x1111;
|
||||
|
||||
# test 7
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: test7a.*, direct, regex
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test7aPASS;
|
||||
attribute test7b;
|
||||
type test7s;
|
||||
type test7t, test7aPASS;
|
||||
type test7aFAIL, test7b;
|
||||
allowxperm test7s test7t:infoflow ioctl 0x9999;
|
||||
allowxperm test7s test7aPASS:infoflow ioctl 0x1111;
|
||||
allowxperm test7s test7b:infoflow ioctl 0x5555;
|
||||
|
||||
# test 8
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: test8(s|t), indirect, regex
|
||||
# class: unset
|
||||
# perms: unset
|
||||
attribute test8a1;
|
||||
attribute test8a2;
|
||||
type test8s1, test8a1;
|
||||
type test8t1, test8a2;
|
||||
type test8FAIL;
|
||||
allowxperm test8a1 test8a1:infoflow ioctl 0x9999;
|
||||
allowxperm test8a2 test8a2:infoflow ioctl 0x1111;
|
||||
allowxperm test8FAIL self:infoflow ioctl 0x5555;
|
||||
|
||||
# test 9
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: unset
|
||||
# class: infoflow2, no regex
|
||||
# perms: unset
|
||||
type test9;
|
||||
allowxperm test9 self:infoflow ioctl 0x9999;
|
||||
allowxperm test9 self:infoflow2 ioctl { 0x5411 0x5451 };
|
||||
|
||||
|
||||
# test 10
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: unset
|
||||
# class: infoflow3,infoflow4 , no regex
|
||||
# perms: unset
|
||||
type test10;
|
||||
allowxperm test10 self:infoflow ioctl 0x9999;
|
||||
allowxperm test10 self:infoflow4 ioctl 0x9999;
|
||||
allowxperm test10 self:infoflow3 ioctl 0x0;
|
||||
|
||||
# test 11
|
||||
# ruletype: unset
|
||||
# source: unset
|
||||
# target: unset
|
||||
# class: infoflow(5|6), regex
|
||||
# perms: unset
|
||||
type test11;
|
||||
allowxperm test11 self:infoflow ioctl 0x9999;
|
||||
allowxperm test11 self:infoflow5 ioctl 0x1111;
|
||||
allowxperm test11 self:infoflow6 ioctl 0x5555;
|
||||
|
||||
# test 14
|
||||
# ruletype: dontauditxperm,auditallowxperm
|
||||
# source: unset
|
||||
# target: unset
|
||||
# class: unset
|
||||
# perms: unset
|
||||
type test14;
|
||||
auditallowxperm test14 self:infoflow7 ioctl 0x1234;
|
||||
dontauditxperm test14 self:infoflow7 ioctl 0x4321;
|
||||
|
||||
############# END XPERM ############################
|
||||
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
#users
|
||||
user system roles system level med range low_s - high_s:here.lost;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:medium_s:here
|
||||
sid security system:system:system:high_s:lost
|
||||
|
||||
#fs_use
|
||||
fs_use_trans devpts system:object_r:system:low_s;
|
||||
fs_use_xattr ext3 system:object_r:system:low_s;
|
||||
fs_use_task pipefs system:object_r:system:low_s;
|
||||
|
||||
#genfscon
|
||||
genfscon proc / system:object_r:system:med
|
||||
genfscon proc /sys system:object_r:system:low_s
|
||||
genfscon selinuxfs / system:object_r:system:high_s:here.there
|
||||
|
||||
portcon tcp 80 system:object_r:system:low_s
|
||||
|
||||
netifcon eth0 system:object_r:system:low_s system:object_r:system:low_s
|
||||
|
||||
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:low_s:here
|
||||
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:low_s:here
|
||||
|
155
tests/xpermrulequery.py
Normal file
155
tests/xpermrulequery.py
Normal file
@ -0,0 +1,155 @@
|
||||
# Derived from tests/XpermRuleQuery.py
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from setools import SELinuxPolicy, XpermRuleQuery
|
||||
|
||||
from . import mixins
|
||||
|
||||
|
||||
class XpermRuleQueryTest(mixins.ValidateXpermRule, unittest.TestCase):
|
||||
|
||||
"""xperm ioctl rule query unit tests."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/xpermrulequery.conf")
|
||||
|
||||
def test_000_unset(self):
|
||||
"""xperm rule query with no criteria."""
|
||||
# query with no parameters gets all Xperm rules.
|
||||
rules = sorted(self.p.xpermrules())
|
||||
|
||||
q = XpermRuleQuery(self.p)
|
||||
q_rules = sorted(q.results())
|
||||
|
||||
self.assertListEqual(rules, q_rules)
|
||||
|
||||
def test_001_source_direct(self):
|
||||
"""Xperm rule query with exact, direct, source match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, source="test1a", source_indirect=False, source_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test1a", "test1t", "infoflow")
|
||||
|
||||
def test_002_source_indirect(self):
|
||||
"""Xperm rule query with exact, indirect, source match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, source="test2s", source_indirect=True, source_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test2a", "test2t", "infoflow")
|
||||
|
||||
def test_003_source_direct_regex(self):
|
||||
"""Xperm rule query with regex, direct, source match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, source="test3a.*", source_indirect=False, source_regex=True)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test3aS", "test3t", "infoflow")
|
||||
|
||||
def test_004_source_indirect_regex(self):
|
||||
"""Xperm rule query with regex, indirect, source match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, source="test4(s|t)", source_indirect=True, source_regex=True)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test4a1", "test4a1", "infoflow")
|
||||
self.validate_xperm_rule(r[1], "allowxperm", "test4a2", "test4a2", "infoflow")
|
||||
|
||||
def test_005_target_direct(self):
|
||||
"""Xperm rule query with exact, direct, target match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, target="test5a", target_indirect=False, target_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test5s", "test5a", "infoflow")
|
||||
|
||||
def test_006_target_indirect(self):
|
||||
"""Xperm rule query with exact, indirect, target match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, target="test6t", target_indirect=True, target_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test6s", "test6a", "infoflow")
|
||||
self.validate_xperm_rule(r[1], "allowxperm", "test6s", "test6t", "infoflow")
|
||||
|
||||
def test_007_target_direct_regex(self):
|
||||
"""Xperm rule query with regex, direct, target match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, target="test7a.*", target_indirect=False, target_regex=True)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test7s", "test7aPASS", "infoflow")
|
||||
|
||||
def test_008_target_indirect_regex(self):
|
||||
"""Xperm rule query with regex, indirect, target match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, target="test8(s|t)", target_indirect=True, target_regex=True)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test8a1", "test8a1", "infoflow")
|
||||
self.validate_xperm_rule(r[1], "allowxperm", "test8a2", "test8a2", "infoflow")
|
||||
|
||||
@unittest.skip("Setting tclass to a string is no longer supported.")
|
||||
def test_009_class(self):
|
||||
"""Xperm rule query with exact object class match."""
|
||||
q = XpermRuleQuery(self.p, tclass="infoflow2", tclass_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 1)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test9", "test9", "infoflow2")
|
||||
|
||||
def test_010_class_list(self):
|
||||
"""Xperm rule query with object class list match."""
|
||||
q = XpermRuleQuery(
|
||||
self.p, tclass=["infoflow3", "infoflow4"], tclass_regex=False)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test10", "test10", "infoflow3")
|
||||
self.validate_xperm_rule(r[1], "allowxperm", "test10", "test10", "infoflow4")
|
||||
|
||||
def test_011_class_regex(self):
|
||||
"""Xperm rule query with object class regex match."""
|
||||
q = XpermRuleQuery(self.p, tclass="infoflow(5|6)", tclass_regex=True)
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "allowxperm", "test11", "test11", "infoflow5")
|
||||
self.validate_xperm_rule(r[1], "allowxperm", "test11", "test11", "infoflow6")
|
||||
|
||||
|
||||
def test_014_ruletype(self):
|
||||
"""Xperm rule query with rule type match."""
|
||||
q = XpermRuleQuery(self.p, ruletype=["auditallowxperm", "dontauditxperm"])
|
||||
|
||||
r = sorted(q.results())
|
||||
self.assertEqual(len(r), 2)
|
||||
self.validate_xperm_rule(r[0], "auditallowxperm", "test14", "test14", "infoflow7")
|
||||
self.validate_xperm_rule(r[1], "dontauditxperm", "test14", "test14", "infoflow7")
|
||||
|
Loading…
Reference in New Issue
Block a user