Implement TypeAttributeQuery.

closes #13
closes #14
This commit is contained in:
Chris PeBenito 2015-03-16 10:46:33 -04:00
parent 39898d9572
commit 4ecd6d00a5
6 changed files with 354 additions and 2 deletions

11
seinfo
View File

@ -33,7 +33,7 @@ parser.add_argument("--flat", help="Print without item count nor indentation.",
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
queries = parser.add_argument_group("Component Queries")
queries.add_argument("-a", "--attribute", help="Print type attributes.", dest="attrquery",
queries.add_argument("-a", "--attribute", help="Print type attributes.", dest="typeattrquery",
default=None, nargs='?', const=True, metavar="ATTR")
queries.add_argument("-b", "--bool", help="Print Booleans.", dest="boolquery",
default=None, nargs='?', const=True, metavar="BOOL")
@ -198,6 +198,13 @@ try:
q = setools.typequery.TypeQuery(p)
components.append(("Types", q))
if args.typeattrquery or args.all:
if isinstance(args.typeattrquery, str):
q = setools.typeattrquery.TypeAttributeQuery(p, name=args.typeattrquery)
else:
q = setools.typeattrquery.TypeAttributeQuery(p)
components.append(("Type Attributes", q))
if args.userquery or args.all:
if isinstance(args.userquery, str):
q = setools.userquery.UserQuery(p, name=args.userquery)
@ -225,7 +232,7 @@ try:
print(" Sensitivities: {0:7} Categories: {1:7}".format(
p.level_count, p.category_count))
print(" Types: {0:7} Attributes: {1:7}".format(
p.type_count, p.attribute_count))
p.type_count, p.type_attribute_count))
print(" Users: {0:7} Roles: {1:7}".format(
p.user_count, p.role_count))
print(" Booleans: {0:7} Cond. Expr.: {1:7}".format(

View File

@ -36,6 +36,7 @@ from . import polcapquery
from . import rolequery
from . import sensitivityquery
from . import typequery
from . import typeattrquery
from . import userquery
# Rule Queries

101
setools/typeattrquery.py Normal file
View File

@ -0,0 +1,101 @@
# Copyright 2014-2015, Tresys Technology, LLC
#
# 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 re
from . import compquery
class TypeAttributeQuery(compquery.ComponentQuery):
"""Query SELinux policy type attributes."""
def __init__(self, policy,
name="", name_regex=False,
types=set(), types_equal=False, types_regex=False):
"""
Parameter:
policy The policy to query.
name The type name to match.
name_regex If true, regular expression matching
will be used on the type names.
types The type to match.
types_equal If true, only attributes with type sets
that are equal to the criteria will
match. Otherwise, any intersection
will match.
types_regex If true, regular expression matching
will be used on the type names instead
of set logic.
"""
self.policy = policy
self.set_name(name, regex=name_regex)
self.set_types(types, regex=types_regex, equal=types_equal)
def results(self):
"""Generator which yields all matching types."""
for a in self.policy.typeattributes():
if self.name and not self._match_name(a):
continue
if self.types and not self._match_regex_or_set(
set(a.expand()),
self.types_cmp,
self.types_equal,
self.types_regex):
continue
yield a
def set_types(self, types, **opts):
"""
Set the criteria for the attribute's types.
Parameter:
alias Name to match the component's types.
Keyword Options:
regex If true, regular expression matching will be used
instead of set logic.
equal If true, the type set of the attribute
must equal the type criteria to
match. If false, any intersection in the
critera will cause a rule match.
Exceptions:
NameError Invalid keyword option.
"""
self.types = types
for k in list(opts.keys()):
if k == "regex":
self.types_regex = opts[k]
elif k == "equal":
self.types_equal = opts[k]
else:
raise NameError("Invalid types option: {0}".format(k))
if not self.types:
self.types_cmp = None
elif self.types_regex:
self.types_cmp = re.compile(self.types)
else:
self.types_cmp = set(self.policy.lookup_type(t) for t in self.types)

View File

@ -34,5 +34,6 @@ from . import rbacrulequery
from . import rolequery
from . import sensitivityquery
from . import terulequery
from . import typeattrquery
from . import typequery
from . import userquery

169
tests/typeattrquery.conf Normal file
View File

@ -0,0 +1,169 @@
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 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;
role system;
role system types system;
################################################################################
# Type enforcement declarations and rules
########################################
#
# Type Query
#
# test 1
# name: test1
# types: unset
attribute test1;
# test 2
# name: test2(a|b) regex
# types: unset
attribute test2a;
attribute test2b;
# test 10
# name: unset
# types:
attribute test10a;
attribute test10b;
attribute test10c;
type test10t1, test10a;
type test10t2, test10a, test10b;
type test10t3, test10a, test10b, test10c;
type test10t4, test10b, test10c;
type test10t5, test10a, test10c;
type test10t6, test10b;
type test10t7, test10c;
# test 11
# name: unset
# types:
attribute test11a;
attribute test11b;
attribute test11c;
type test11t1, test11a;
type test11t2, test11a, test11b;
type test11t3, test11a, test11b, test11c;
type test11t4, test11b, test11c;
type test11t5, test11a, test11c;
type test11t6, test11b;
type test11t7, test11c;
# test 12
# name: unset
# types:
attribute test12a;
attribute test12b;
attribute test12c;
type test12t1, test12a;
type test12t2, test12a, test12b;
type test12t3, test12a, test12b, test12c;
type test12t4, test12b, test12c;
type test12t5, test12a, test12c;
type test12t6, test12b;
type test12t7, test12c;
################################################################################
#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

73
tests/typeattrquery.py Normal file
View File

@ -0,0 +1,73 @@
# Copyright 2014-2015, Tresys Technology, LLC
#
# 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
from setools.typeattrquery import TypeAttributeQuery
class TypeAttributeQueryTest(unittest.TestCase):
def setUp(self):
self.p = SELinuxPolicy("tests/typeattrquery.conf")
def test_000_unset(self):
"""Type attribute query with no criteria."""
# query with no parameters gets all attrs.
allattrs = sorted(self.p.typeattributes())
q = TypeAttributeQuery(self.p)
qattrs = sorted(q.results())
self.assertListEqual(allattrs, qattrs)
def test_001_name_exact(self):
"""Type attribute query with exact name match."""
q = TypeAttributeQuery(self.p, name="test1")
attrs = sorted(str(t) for t in q.results())
self.assertListEqual(["test1"], attrs)
def test_002_name_regex(self):
"""Type attribute query with regex name match."""
q = TypeAttributeQuery(self.p, name="test2(a|b)", name_regex=True)
attrs = sorted(str(t) for t in q.results())
self.assertListEqual(["test2a", "test2b"], attrs)
def test_010_type_set_intersect(self):
"""Type attribute query with type set intersection."""
q = TypeAttributeQuery(self.p, types=["test10t1", "test10t7"])
attrs = sorted(str(t) for t in q.results())
self.assertListEqual(["test10a", "test10c"], attrs)
def test_011_type_set_equality(self):
"""Type attribute query with type set equality."""
q = TypeAttributeQuery(self.p, types=["test11t1", "test11t2",
"test11t3", "test11t5"], types_equal=True)
attrs = sorted(str(t) for t in q.results())
self.assertListEqual(["test11a"], attrs)
def test_012_type_set_regex(self):
"""Type attribute query with type set regex match."""
q = TypeAttributeQuery(self.p, types="test12t(1|2)", types_regex=True)
attrs = sorted(str(t) for t in q.results())
self.assertListEqual(["test12a", "test12b"], attrs)