mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-01 14:48:07 +00:00
Constraint/Validatetrans: Refactor to load attributes on construction.
This commit is contained in:
parent
d0012dacaa
commit
ded09017d6
@ -39,6 +39,11 @@ cdef class BaseConstraint(PolicySymbol):
|
|||||||
sepol.constraint_node_t *handle
|
sepol.constraint_node_t *handle
|
||||||
readonly object ruletype
|
readonly object ruletype
|
||||||
readonly object tclass
|
readonly object tclass
|
||||||
|
list _postfix_expression
|
||||||
|
list _infix_expression
|
||||||
|
readonly frozenset users
|
||||||
|
readonly frozenset roles
|
||||||
|
readonly frozenset types
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -65,60 +70,63 @@ cdef class BaseConstraint(PolicySymbol):
|
|||||||
Return: list
|
Return: list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_precedence = {
|
if self._infix_expression is None:
|
||||||
"not": 4,
|
_precedence = {
|
||||||
"and": 2,
|
"not": 4,
|
||||||
"or": 1,
|
"and": 2,
|
||||||
"==": 3,
|
"or": 1,
|
||||||
"!=": 3,
|
"==": 3,
|
||||||
"dom": 3,
|
"!=": 3,
|
||||||
"domby": 3,
|
"dom": 3,
|
||||||
"incomp": 3}
|
"domby": 3,
|
||||||
|
"incomp": 3}
|
||||||
|
|
||||||
_max_precedence = 4
|
_max_precedence = 4
|
||||||
|
|
||||||
_operands = ["u1", "u2", "u3",
|
_operands = ["u1", "u2", "u3",
|
||||||
"r1", "r2", "r3",
|
"r1", "r2", "r3",
|
||||||
"t1", "t2", "t3",
|
"t1", "t2", "t3",
|
||||||
"l1", "l2",
|
"l1", "l2",
|
||||||
"h1", "h2"]
|
"h1", "h2"]
|
||||||
|
|
||||||
# qpol representation is in postfix notation. This code
|
# sepol representation is in postfix notation. This code
|
||||||
# converts it to infix notation. Parentheses are added
|
# converts it to infix notation. Parentheses are added
|
||||||
# to ensure correct expressions, though they may end up
|
# to ensure correct expressions, though they may end up
|
||||||
# being overused. Set previous operator at start to the
|
# being overused. Set previous operator at start to the
|
||||||
# highest precedence (op) so if there is a single binary
|
# highest precedence (op) so if there is a single binary
|
||||||
# operator, no parentheses are output
|
# operator, no parentheses are output
|
||||||
stack = []
|
stack = []
|
||||||
prev_op_precedence = _max_precedence
|
prev_op_precedence = _max_precedence
|
||||||
for op in self.postfix_expression():
|
for op in self.postfix_expression():
|
||||||
if isinstance(op, frozenset) or op in _operands:
|
if isinstance(op, frozenset) or op in _operands:
|
||||||
# operands
|
# operands
|
||||||
stack.append(op)
|
stack.append(op)
|
||||||
else:
|
|
||||||
# operators
|
|
||||||
if op == "not":
|
|
||||||
# unary operator
|
|
||||||
operator = op
|
|
||||||
operand = stack.pop()
|
|
||||||
op_precedence = _precedence[op]
|
|
||||||
stack.append([operator, "(", operand, ")"])
|
|
||||||
else:
|
else:
|
||||||
# binary operators
|
# operators
|
||||||
operand2 = stack.pop()
|
if op == "not":
|
||||||
operand1 = stack.pop()
|
# unary operator
|
||||||
operator = op
|
operator = op
|
||||||
|
operand = stack.pop()
|
||||||
# if previous operator is of higher precedence
|
op_precedence = _precedence[op]
|
||||||
# no parentheses are needed.
|
stack.append([operator, "(", operand, ")"])
|
||||||
if _precedence[op] < prev_op_precedence:
|
|
||||||
stack.append([operand1, operator, operand2])
|
|
||||||
else:
|
else:
|
||||||
stack.append(["(", operand1, operator, operand2, ")"])
|
# binary operators
|
||||||
|
operand2 = stack.pop()
|
||||||
|
operand1 = stack.pop()
|
||||||
|
operator = op
|
||||||
|
|
||||||
prev_op_precedence = _precedence[op]
|
# if previous operator is of higher precedence
|
||||||
|
# no parentheses are needed.
|
||||||
|
if _precedence[op] < prev_op_precedence:
|
||||||
|
stack.append([operand1, operator, operand2])
|
||||||
|
else:
|
||||||
|
stack.append(["(", operand1, operator, operand2, ")"])
|
||||||
|
|
||||||
return self._flatten_expression(stack)
|
prev_op_precedence = _precedence[op]
|
||||||
|
|
||||||
|
self._infix_expression = self._flatten_expression(stack)
|
||||||
|
|
||||||
|
return self._infix_expression
|
||||||
|
|
||||||
def postfix_expression(self):
|
def postfix_expression(self):
|
||||||
"""
|
"""
|
||||||
@ -126,41 +134,7 @@ cdef class BaseConstraint(PolicySymbol):
|
|||||||
|
|
||||||
Return: list
|
Return: list
|
||||||
"""
|
"""
|
||||||
expression = []
|
return self._postfix_expression
|
||||||
for expr_node in ConstraintExprIterator.factory(self.policy, self.handle.expr):
|
|
||||||
expression.extend(expr_node())
|
|
||||||
|
|
||||||
return expression
|
|
||||||
|
|
||||||
@property
|
|
||||||
def roles(self):
|
|
||||||
"""The roles used in the expression."""
|
|
||||||
roles = set()
|
|
||||||
for expr_node in ConstraintExprIterator.factory(self.policy, self.handle.expr):
|
|
||||||
if expr_node.roles:
|
|
||||||
roles.update(expr_node.names)
|
|
||||||
|
|
||||||
return roles
|
|
||||||
|
|
||||||
@property
|
|
||||||
def types(self):
|
|
||||||
"""The types and type attributes used in the expression."""
|
|
||||||
types = set()
|
|
||||||
for expr_node in ConstraintExprIterator.factory(self.policy, self.handle.expr):
|
|
||||||
if expr_node.types:
|
|
||||||
types.update(expr_node.names)
|
|
||||||
|
|
||||||
return types
|
|
||||||
|
|
||||||
@property
|
|
||||||
def users(self):
|
|
||||||
"""The users used in the expression."""
|
|
||||||
users = set()
|
|
||||||
for expr_node in ConstraintExprIterator.factory(self.policy, self.handle.expr):
|
|
||||||
if expr_node.users:
|
|
||||||
users.update(expr_node.names)
|
|
||||||
|
|
||||||
return users
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Internal functions
|
# Internal functions
|
||||||
@ -198,20 +172,41 @@ cdef class Constraint(BaseConstraint):
|
|||||||
|
|
||||||
"""A constraint rule (constrain/mlsconstrain)."""
|
"""A constraint rule (constrain/mlsconstrain)."""
|
||||||
|
|
||||||
|
cdef readonly frozenset perms
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
cdef factory(SELinuxPolicy policy, ObjClass tclass, sepol.constraint_node_t *symbol):
|
cdef factory(SELinuxPolicy policy, ObjClass tclass, sepol.constraint_node_t *symbol):
|
||||||
"""Factory function for creating Constraint objects."""
|
"""Factory function for creating Constraint objects."""
|
||||||
c = Constraint()
|
cdef:
|
||||||
|
Constraint c = Constraint.__new__(Constraint)
|
||||||
|
list users = []
|
||||||
|
list roles = []
|
||||||
|
list types = []
|
||||||
|
|
||||||
c.policy = policy
|
c.policy = policy
|
||||||
c.handle = symbol
|
c.handle = symbol
|
||||||
c.tclass = tclass
|
c.tclass = tclass
|
||||||
|
c.perms = frozenset(PermissionVectorIterator.factory(policy, tclass, symbol.permissions))
|
||||||
|
|
||||||
|
c.ruletype = ConstraintRuletype.constrain
|
||||||
|
c._postfix_expression = []
|
||||||
for expr_node in ConstraintExprIterator.factory(policy, symbol.expr):
|
for expr_node in ConstraintExprIterator.factory(policy, symbol.expr):
|
||||||
if expr_node.mls:
|
if expr_node.mls:
|
||||||
c.ruletype = ConstraintRuletype.mlsconstrain
|
c.ruletype = ConstraintRuletype.mlsconstrain
|
||||||
break
|
|
||||||
else:
|
if expr_node.types:
|
||||||
c.ruletype = ConstraintRuletype.constrain
|
types.extend(expr_node.names)
|
||||||
|
elif expr_node.roles:
|
||||||
|
roles.extend(expr_node.names)
|
||||||
|
elif expr_node.users:
|
||||||
|
users.extend(expr_node.names)
|
||||||
|
|
||||||
|
c._postfix_expression.extend(expr_node())
|
||||||
|
|
||||||
|
c.users = frozenset(users)
|
||||||
|
c.roles = frozenset(roles)
|
||||||
|
c.types = frozenset(types)
|
||||||
|
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
@ -229,12 +224,6 @@ cdef class Constraint(BaseConstraint):
|
|||||||
|
|
||||||
return rule_string
|
return rule_string
|
||||||
|
|
||||||
@property
|
|
||||||
def perms(self):
|
|
||||||
"""The constraint's permission set."""
|
|
||||||
return set(p for p in PermissionVectorIterator.factory(self.policy, self.tclass,
|
|
||||||
self.handle.permissions))
|
|
||||||
|
|
||||||
|
|
||||||
cdef class Validatetrans(BaseConstraint):
|
cdef class Validatetrans(BaseConstraint):
|
||||||
|
|
||||||
@ -243,17 +232,34 @@ cdef class Validatetrans(BaseConstraint):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
cdef factory(SELinuxPolicy policy, ObjClass tclass, sepol.constraint_node_t *symbol):
|
cdef factory(SELinuxPolicy policy, ObjClass tclass, sepol.constraint_node_t *symbol):
|
||||||
"""Factory function for creating Validatetrans objects."""
|
"""Factory function for creating Validatetrans objects."""
|
||||||
v = Validatetrans()
|
cdef:
|
||||||
|
Validatetrans v = Validatetrans.__new__(Validatetrans)
|
||||||
|
list users = []
|
||||||
|
list roles = []
|
||||||
|
list types = []
|
||||||
|
|
||||||
v.policy = policy
|
v.policy = policy
|
||||||
v.handle = symbol
|
v.handle = symbol
|
||||||
v.tclass = tclass
|
v.tclass = tclass
|
||||||
|
|
||||||
|
v.ruletype = ConstraintRuletype.validatetrans
|
||||||
|
v._postfix_expression = []
|
||||||
for expr_node in ConstraintExprIterator.factory(policy, symbol.expr):
|
for expr_node in ConstraintExprIterator.factory(policy, symbol.expr):
|
||||||
if expr_node.mls:
|
if expr_node.mls:
|
||||||
v.ruletype = ConstraintRuletype.mlsvalidatetrans
|
v.ruletype = ConstraintRuletype.mlsvalidatetrans
|
||||||
break
|
|
||||||
else:
|
if expr_node.types:
|
||||||
v.ruletype = ConstraintRuletype.validatetrans
|
types.extend(expr_node.names)
|
||||||
|
elif expr_node.roles:
|
||||||
|
roles.extend(expr_node.names)
|
||||||
|
elif expr_node.users:
|
||||||
|
users.extend(expr_node.names)
|
||||||
|
|
||||||
|
v._postfix_expression.extend(expr_node())
|
||||||
|
|
||||||
|
v.users = frozenset(users)
|
||||||
|
v.roles = frozenset(roles)
|
||||||
|
v.types = frozenset(types)
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
@ -94,9 +94,9 @@ cdef class Type(BaseType):
|
|||||||
return _type_cache[<uintptr_t>symbol]
|
return _type_cache[<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
t = Type.__new__(Type)
|
t = Type.__new__(Type)
|
||||||
|
_type_cache[<uintptr_t>symbol] = t
|
||||||
t.policy = policy
|
t.policy = policy
|
||||||
t.handle = symbol
|
t.handle = symbol
|
||||||
_type_cache[<uintptr_t>symbol] = t
|
|
||||||
t.value = symbol.s.value
|
t.value = symbol.s.value
|
||||||
t.name = policy.type_value_to_name(symbol.s.value - 1)
|
t.name = policy.type_value_to_name(symbol.s.value - 1)
|
||||||
t.ispermissive = <bint>symbol.flags & sepol.TYPE_FLAGS_PERMISSIVE
|
t.ispermissive = <bint>symbol.flags & sepol.TYPE_FLAGS_PERMISSIVE
|
||||||
|
Loading…
Reference in New Issue
Block a user