1 # Copyright 2015, Tresys Technology, LLC 2 # 3 # This file is part of SETools. 4 # 5 # SETools is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU Lesser General Public License as 7 # published by the Free Software Foundation, either version 2.1 of 8 # the License, or (at your option) any later version. 9 # 10 # SETools is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU Lesser General Public License for more details. 14 # 15 # You should have received a copy of the GNU Lesser General Public 16 # License along with SETools. If not, see 17 # <http://www.gnu.org/licenses/>. 18 # 19 import logging 20 import re 21 22 from . import mixins, query 23 from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor 24 from .policyrep.exception import ConstraintUseError 25 26 27 class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuery): 28 29 """ 30 Query constraint rules, (mls)constrain/(mls)validatetrans. 31 32 Parameter: 33 policy The policy to query. 34 35 Keyword Parameters/Class attributes: 36 ruletype The list of rule type(s) to match. 37 tclass The object class(es) to match. 38 tclass_regex If true, use a regular expression for 39 matching the rule's object class. 40 perms The permission(s) to match. 41 perms_equal If true, the permission set of the rule 42 must exactly match the permissions 43 criteria. If false, any set intersection 44 will match. 45 perms_regex If true, regular expression matching will be used 46 on the permission names instead of set logic. 47 role The name of the role to match in the 48 constraint expression. 49 role_indirect If true, members of an attribute will be 50 matched rather than the attribute itself. 51 role_regex If true, regular expression matching will 52 be used on the role. 53 type_ The name of the type/attribute to match in the 54 constraint expression. 55 type_indirect If true, members of an attribute will be 56 matched rather than the attribute itself. 57 type_regex If true, regular expression matching will 58 be used on the type/attribute. 59 user The name of the user to match in the 60 constraint expression. 61 user_regex If true, regular expression matching will 62 be used on the user. 63 """ 64 65 ruletype = CriteriaSetDescriptor(lookup_function="validate_constraint_ruletype") 66 user = CriteriaDescriptor("user_regex", "lookup_user") 67 user_regex = False 68 role = CriteriaDescriptor("role_regex", "lookup_role") 69 role_regex = False 70 role_indirect = True 71 type_ = CriteriaDescriptor("type_regex", "lookup_type_or_attr") 72 type_regex = False 73 type_indirect = True 74 75 def _match_expr(self, expr, criteria, indirect, regex): 76 """ 77 Match roles/types/users in a constraint expression, 78 optionally by expanding the contents of attributes. 79 80 Parameters: 81 expr The expression to match. 82 criteria The criteria to match. 83 indirect If attributes in the expression should be expanded. 84 regex If regular expression matching should be used. 85 """ 86 87 if indirect: 88 obj = set() 89 for item in expr: 90 obj.update(item.expand()) 91 else: 92 obj = expr 93 94 return self._match_in_set(obj, criteria, regex) 95 96 def results(self): 97 """Generator which yields all matching constraints rules.""" 98 self.log.info("Generating results from {0.policy}".format(self)) 99 self.log.debug("Ruletypes: {0.ruletype}".format(self)) 100 self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self)) 101 self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}". 102 format(self)) 103 self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self)) 104 self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self)) 105 self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self)) 106 107 for c in self.policy.constraints(): 108 if self.ruletype: 109 if c.ruletype not in self.ruletype: 110 continue 111 112 if not self._match_object_class(c): 113 continue 114 115 try: 116 if not self._match_perms(c): 117 continue 118 except ConstraintUseError: 119 continue 120 121 if self.role and not self._match_expr( 122 c.roles, 123 self.role, 124 self.role_indirect, 125 self.role_regex): 126 continue 127 128 if self.type_ and not self._match_expr( 129 c.types, 130 self.type_, 131 self.type_indirect, 132 self.type_regex): 133 continue 134 135 if self.user and not self._match_expr( 136 c.users, 137 self.user, 138 False, 139 self.user_regex): 140 continue 141 142 yield c 143