Merge validatetrans into constraints in policyrep.

This commit is contained in:
Chris PeBenito 2015-03-14 14:52:58 -04:00
parent 3c8afd93e2
commit e3f2a98c43
8 changed files with 44 additions and 249 deletions

12
seinfo
View File

@ -101,9 +101,10 @@ try:
if args.constraintquery or args.all:
if isinstance(args.constraintquery, str):
q = setools.constraintquery.ConstraintQuery(p, tclass=args.constraintquery)
q = setools.constraintquery.ConstraintQuery(p, tclass=args.constraintquery,
ruletype=["constrain", "mlsconstrain"])
else:
q = setools.constraintquery.ConstraintQuery(p)
q = setools.constraintquery.ConstraintQuery(p, ruletype=["constrain", "mlsconstrain"])
components.append(("Constraints", q))
if args.fsusequery or args.all:
@ -206,9 +207,12 @@ try:
if args.validatetransquery or args.all:
if isinstance(args.validatetransquery, str):
q = setools.validatetransquery.ValidatetransQuery(p, tclass=args.validatetransquery)
q = setools.constraintquery.ConstraintQuery(p, tclass=args.validatetransquery,
ruletype=["validatetrans",
"mlsvalidatetrans"])
else:
q = setools.validatetransquery.ValidatetransQuery(p)
q = setools.constraintquery.ConstraintQuery(p, ruletype=["validatetrans",
"mlsvalidatetrans"])
components.append(("Validatetrans", q))
if (not components or args.all) and not args.flat:

View File

@ -45,7 +45,6 @@ from . import terulequery
# Constraint queries
from . import constraintquery
from . import validatetransquery
# In-policy Context Queries
from . import fsusequery

View File

@ -20,6 +20,7 @@ import re
from . import mixins
from .query import PolicyQuery
from .policyrep.constraint import ConstraintUseError
class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, PolicyQuery):
@ -105,8 +106,12 @@ class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, PolicyQuery)
if self.tclass and not self._match_object_class(c.tclass):
continue
if self.perms and not self._match_perms(c.perms):
continue
if self.perms:
try:
if not self._match_perms(c.perms):
continue
except ConstraintUseError:
continue
if self.role and not self._match_expr(
c.roles,

View File

@ -177,7 +177,7 @@ class SELinuxPolicy(object):
@property
def mlsvalidatetrans_count(self):
"""The number of MLS validatetrans."""
return sum(1 for v in self.validatetrans() if v.ruletype == "mlsvalidatetrans")
return sum(1 for v in self.constraints() if v.ruletype == "mlsvalidatetrans")
@property
def netifcon_count(self):
@ -262,7 +262,7 @@ class SELinuxPolicy(object):
@property
def validatetrans_count(self):
"""The number of validatetrans."""
return sum(1 for v in self.validatetrans() if v.ruletype == "validatetrans")
return sum(1 for v in self.constraints() if v.ruletype == "validatetrans")
#
# Policy components lookup functions
@ -446,15 +446,11 @@ class SELinuxPolicy(object):
def constraints(self):
"""Generator which yields all constraints (regular and MLS)."""
for constraint_ in self.policy.constraint_iter():
for constraint_ in chain(self.policy.constraint_iter(),
self.policy.validatetrans_iter()):
yield constraint.constraint_factory(self.policy, constraint_)
def validatetrans(self):
"""Generator which yields all validatetrans (regular and MLS)."""
for validatetrans in self.policy.validatetrans_iter():
yield constraint.validatetrans_factory(self.policy, validatetrans)
#
# In-policy Labeling statement generators
#

View File

@ -24,6 +24,12 @@ from . import typeattr
from . import user
class ConstraintUseError(symbol.SymbolUseError):
"""Exception when getting permissions from a validatetrans."""
pass
def _is_mls(policy, symbol):
# determine if this is a regular or MLS constraint/validatetrans.
# this can only be determined by inspecting the expression.
@ -42,27 +48,20 @@ def constraint_factory(policy, symbol):
try:
if _is_mls(policy, symbol):
return Constraint(policy, symbol, "mlsconstrain")
if isinstance(symbol, qpol.qpol_constraint_t):
return Constraint(policy, symbol, "mlsconstrain")
else:
return Validatetrans(policy, symbol, "mlsvalidatetrans")
else:
return Constraint(policy, symbol, "constrain")
if isinstance(symbol, qpol.qpol_constraint_t):
return Constraint(policy, symbol, "constrain")
else:
return Validatetrans(policy, symbol, "validatetrans")
except AttributeError:
raise TypeError("Constraints cannot be looked-up.")
def validatetrans_factory(policy, symbol):
"""Factory function for creating validatetrans objects."""
try:
if _is_mls(policy, symbol):
return Validatetrans(policy, symbol, "mlsvalidatetrans")
else:
return Validatetrans(policy, symbol, "validatetrans")
except AttributeError:
raise TypeError("validatetrans cannot be looked-up.")
class BaseConstraint(symbol.PolicySymbol):
"""Abstract base class for constraint rules."""
@ -229,6 +228,10 @@ class BaseConstraint(symbol.PolicySymbol):
return set(self._get_symbols(role_syms, role.role_factory))
@property
def perms(self):
raise NotImplementedError
def statement(self):
return str(self)
@ -286,3 +289,7 @@ class Validatetrans(BaseConstraint):
def __str__(self):
return "{0.ruletype} {0.tclass}\n\t{1}\n);".format(self, self._build_expression())
@property
def perms(self):
raise ConstraintUseError("{0} rules do not have permissions.".format(self.ruletype))

View File

@ -1,217 +0,0 @@
# Copyright 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 mixins
from .query import PolicyQuery
class ValidatetransQuery(mixins.MatchObjClass, PolicyQuery):
"""Query validatetrans rules (validatetrans/mlsvalidatetrans)."""
def __init__(self, policy,
ruletype=[],
tclass="", tclass_regex=False,
role="", role_regex=False, role_indirect=True,
type_="", type_regex=False, type_indirect=True,
user="", user_regex=False):
"""
Parameter:
policy The policy to query.
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.
role The name of the role to match in the
constraint expression.
role_indirect If true, members of an attribute will be
matched rather than the attribute itself.
role_regex If true, regular expression matching will
be used on the role.
type_ The name of the type/attribute to match in the
constraint expression.
type_indirect If true, members of an attribute will be
matched rather than the attribute itself.
type_regex If true, regular expression matching will
be used on the type/attribute.
user The name of the user to match in the
constraint expression.
user_regex If true, regular expression matching will
be used on the user.
"""
self.policy = policy
self.set_ruletype(ruletype)
self.set_tclass(tclass, regex=tclass_regex)
self.set_role(role, regex=role_regex, indirect=role_indirect)
self.set_type(type_, regex=type_regex, indirect=type_indirect)
self.set_user(user, regex=user_regex)
def _match_expr(self, expr, criteria, indirect, regex):
"""
Match roles/types/users in a constraint expression,
optionally by expanding the contents of attributes.
Parameters:
expr The expression to match.
criteria The criteria to match.
indirect If attributes in the expression should be expanded.
regex If regular expression matching should be used.
"""
if indirect:
obj = set()
for item in expr:
obj.update(item.expand())
else:
obj = expr
return self._match_in_set(obj, criteria, regex)
def results(self):
"""Generator which yields all matching constraints rules."""
for c in self.policy.validatetrans():
if self.ruletype:
if c.ruletype not in self.ruletype:
continue
if self.tclass and not self._match_object_class(c.tclass):
continue
if self.role and not self._match_expr(
c.roles,
self.role_cmp,
self.role_indirect,
self.role_regex):
continue
if self.type_ and not self._match_expr(
c.types,
self.type_cmp,
self.type_indirect,
self.type_regex):
continue
if self.user and not self._match_expr(
c.users,
self.user_cmp,
False,
self.user_regex):
continue
yield c
def set_ruletype(self, ruletype):
"""
Set the rule types for the rule query.
Parameter:
ruletype The rule types to match.
"""
self.ruletype = ruletype
def set_role(self, role, **opts):
"""
Set the criteria for matching the constraint's role.
Parameter:
role Name to match the constraint's role.
regex If true, regular expression matching will be used.
Exceptions:
NameError Invalid keyword option.
"""
self.role = role
for k in list(opts.keys()):
if k == "regex":
self.role_regex = opts[k]
elif k == "indirect":
self.role_indirect = opts[k]
else:
raise NameError("Invalid name option: {0}".format(k))
if not self.role:
self.role_cmp = None
elif self.role_regex:
self.role_cmp = re.compile(self.role)
else:
self.role_cmp = self.policy.lookup_role(self.role)
def set_type(self, type_, **opts):
"""
Set the criteria for matching the constraint's type.
Parameter:
type_ Name to match the constraint's type.
regex If true, regular expression matching will be used.
Exceptions:
NameError Invalid keyword option.
"""
self.type_ = type_
for k in list(opts.keys()):
if k == "regex":
self.type_regex = opts[k]
elif k == "indirect":
self.type_indirect = opts[k]
else:
raise NameError("Invalid name option: {0}".format(k))
if not self.type_:
self.type_cmp = None
elif self.type_regex:
self.type_cmp = re.compile(self.type_)
else:
self.type_cmp = self.policy.lookup_type(type_)
def set_user(self, user, **opts):
"""
Set the criteria for matching the constraint's user.
Parameter:
user Name to match the constraint's user.
regex If true, regular expression matching will be used.
Exceptions:
NameError Invalid keyword option.
"""
self.user = user
for k in list(opts.keys()):
if k == "regex":
self.user_regex = opts[k]
else:
raise NameError("Invalid name option: {0}".format(k))
if not self.user:
self.user_cmp = None
elif self.user_regex:
self.user_cmp = re.compile(self.user)
else:
self.user_cmp = self.policy.lookup_user(self.user)

View File

@ -17,6 +17,7 @@
#
from . import boolquery
from . import categoryquery
from . import constraintquery
from . import commonquery
from . import dta
from . import fsusequery

View File

@ -235,7 +235,7 @@ constrain test30 hi_w (u1 == u2 or r1 == test30r);
# type: unset
# user: unset
constrain test31a hi_w (u1 == u2 or r1 == test31ra);
constrain test31b hi_w (u1 == u2 or r2 == test31rb);
validatetrans test31b (u1 == u2 or r2 == test31rb);
# test 40:
# ruletype: unset