Implement DefaultQuery

Closes #93
Closes #74
This commit is contained in:
Chris PeBenito 2016-02-01 09:06:02 -05:00
parent eafaad4dde
commit 8c5a7caa9e
5 changed files with 298 additions and 0 deletions

View File

@ -51,6 +51,9 @@ from .terulequery import TERuleQuery
# Constraint queries
from .constraintquery import ConstraintQuery
# Other queries
from .defaultquery import DefaultQuery
# In-policy Context Queries
from .fsusequery import FSUseQuery
from .genfsconquery import GenfsconQuery

71
setools/defaultquery.py Normal file
View File

@ -0,0 +1,71 @@
# 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 logging
import re
from .query import PolicyQuery
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .mixins import MatchObjClass
class DefaultQuery(MatchObjClass, PolicyQuery):
"""
Query default_* statements.
Parameter:
policy The policy to query.
Keyword Parameters/Class attributes:
ruletype The rule type(s) to match.
tclass The object class(es) to match.
tclass_regex If true, use a regular expression for
matching the rule's object class.
default The default to base new contexts (e.g. "source" or "target")
default_range The range to use on new context, default_range only
("low", "high", "low_high")
"""
ruletype = CriteriaSetDescriptor(lookup_function="validate_default_ruletype")
default = CriteriaDescriptor(lookup_function="validate_default_value")
default_range = CriteriaDescriptor(lookup_function="validate_default_range")
def results(self):
"""Generator which yields all matching default_* statements."""
self.log.info("Generating results from {0.policy}".format(self))
self.log.debug("Ruletypes: {0.ruletype}".format(self))
for d in self.policy.defaults():
if self.ruletype and d.ruletype not in self.ruletype:
continue
if not self._match_object_class(d):
continue
if self.default and d.default != self.default:
continue
if self.default_range:
try:
if d.default_range != self.default_range:
continue
except AttributeError:
continue
yield d

View File

@ -19,6 +19,7 @@ from . import boolquery
from . import categoryquery
from . import constraintquery
from . import commonquery
from . import defaultquery
from . import diff
from . import dta
from . import fsusequery

125
tests/defaultquery.conf Normal file
View File

@ -0,0 +1,125 @@
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
}
########################################
#
# Default settings
#
default_user infoflow target;
default_role { infoflow infoflow3 } source;
default_type infoflow4 target;
default_range infoflow5 target low;
default_range infoflow7 target high;
#########################################
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
################################################################################
#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

98
tests/defaultquery.py Normal file
View File

@ -0,0 +1,98 @@
# Copyright 2016, 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, DefaultQuery
from setools.policyrep.exception import InvalidDefaultType, InvalidClass, \
InvalidDefaultValue, InvalidDefaultRange
class DefaultQueryTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.p = SELinuxPolicy("tests/defaultquery.conf")
def test_000_unset(self):
"""Default query: no criteria."""
# query with no parameters gets all defaults
alldefaults = sorted(self.p.defaults())
q = DefaultQuery(self.p)
qdefaults = sorted(q.results())
self.assertListEqual(alldefaults, qdefaults)
def test_001_ruletype(self):
"""Default query: ruletype criterion."""
q = DefaultQuery(self.p, ruletype=["default_user"])
defaults = list(q.results())
self.assertEqual(1, len(defaults))
d = defaults[0]
self.assertEqual("default_user", d.ruletype)
self.assertEqual("infoflow", d.tclass)
self.assertEqual("target", d.default)
def test_010_class_list(self):
"""Default query: object class list match."""
q = DefaultQuery(self.p, tclass=["infoflow3", "infoflow4"])
defaults = sorted(d.tclass for d in q.results())
self.assertListEqual(["infoflow3", "infoflow4"], defaults)
def test_011_class_regex(self):
"""Default query: object class regex match."""
q = DefaultQuery(self.p, tclass="infoflow(3|5)", tclass_regex=True)
defaults = sorted(c.tclass for c in q.results())
self.assertListEqual(["infoflow3", "infoflow5"], defaults)
def test_020_default(self):
"""Default query: default setting."""
q = DefaultQuery(self.p, default="source")
defaults = sorted(c.tclass for c in q.results())
self.assertListEqual(["infoflow", "infoflow3"], defaults)
def test_030_default_range(self):
"""Default query: default_range setting."""
q = DefaultQuery(self.p, default_range="high")
defaults = sorted(c.tclass for c in q.results())
self.assertListEqual(["infoflow7"], defaults)
def test_900_invalid_ruletype(self):
"""Default query: invalid ruletype"""
with self.assertRaises(InvalidDefaultType):
q = DefaultQuery(self.p, ruletype=["INVALID"])
def test_901_invalid_class(self):
"""Default query: invalid object class"""
with self.assertRaises(InvalidClass):
q = DefaultQuery(self.p, tclass=["INVALID"])
def test_902_invalid_default_value(self):
"""Default query: invalid default value"""
with self.assertRaises(InvalidDefaultValue):
q = DefaultQuery(self.p, default="INVALID")
def test_903_invalid_default_range(self):
"""Default query: invalid default range"""
with self.assertRaises(InvalidDefaultRange):
q = DefaultQuery(self.p, default_range="INVALID")