# Copyright 2014, 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 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/>. # from . import exception from . import symbol from . import objclass from . import qpol def validate_ruletype(t): """Validate default_* rule types.""" if t not in ["default_role", "default_range", "default_type", "default_user"]: raise exception.InvalidDefaultType("{0} is not a valid default_* rule type.".format(t)) return t def validate_default_value(default): if default not in ["source", "target"]: raise exception.InvalidDefaultValue("{0} is not a valid default_* value.".format(default)) return default def validate_default_range(default): if default not in ["low", "high", "low_high"]: raise exception.InvalidDefaultRange("{0} is not a valid default_* range.".format(default)) return default def default_factory(policy, sym): """Factory generator for creating default_* statement objects.""" # The low level policy groups default_* settings by object class. # Since each class can have up to four default_* statements, # this factory function is a generator which yields up to # four Default objects. if not isinstance(sym, qpol.qpol_default_object_t): raise NotImplementedError # qpol will essentially iterate over all classes # and emit None for classes that don't set a default. # Because of all of this processing, extract almost # all of the information out of the qpol representation. # (we have to determine almost all of it anyway) if not sym.object_class(policy): raise exception.NoDefaults user = sym.user_default(policy) role = sym.role_default(policy) type_ = sym.type_default(policy) range_ = sym.range_default(policy) if user: obj = Default(policy, sym) obj.ruletype = "default_user" obj.default = user yield obj if role: obj = Default(policy, sym) obj.ruletype = "default_role" obj.default = role yield obj if type_: obj = Default(policy, sym) obj.ruletype = "default_type" obj.default = type_ yield obj if range_: # range_ is something like "source low_high" rng = range_.split() obj = RangeDefault(policy, sym) obj.ruletype = "default_range" obj.default = rng[0] obj.default_range = rng[1] yield obj class Default(symbol.PolicySymbol): """Base class for default_* statements.""" ruletype = None default = None def __str__(self): return "{0.ruletype} {0.tclass} {0.default};".format(self) def __hash__(self): return hash("{0.ruletype}|{0.tclass}".format(self)) @property def tclass(self): """The object class.""" return objclass.class_factory(self.policy, self.qpol_symbol.object_class(self.policy)) def statement(self): return str(self) class RangeDefault(Default): """A default_range statement.""" default_range = None def __str__(self): return "{0.ruletype} {0.tclass} {0.default} {0.default_range};".format(self)