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:
Richard Haines 2015-12-16 16:47:14 +00:00 committed by Chris PeBenito
parent dd29dc9c43
commit 3532ed2fff
25 changed files with 4434 additions and 23 deletions

89
seinfo
View File

@ -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:

View File

@ -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,

View File

@ -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

View 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
View 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
View 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

View 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
View 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

View File

@ -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

View 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

View 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
View 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

View 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
View 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
View 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
View 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
View 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
View 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)

View File

@ -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)

View 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
View 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
View 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
View 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
View 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
View 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")