From c146f0ab47a6502201446b29ae776d3030c86230 Mon Sep 17 00:00:00 2001 From: Chris PeBenito Date: Wed, 1 Apr 2015 12:10:45 -0400 Subject: [PATCH] Restructure exceptions across the entire project. Group all exception classes into a module for each package. This is the first step towards having all exceptions raised by setools libs be a child of SEToolsException. --- setools/__init__.py | 5 +- setools/constraintquery.py | 2 +- setools/exception.py | 56 ++++++++ setools/objclassquery.py | 2 +- setools/permmap.py | 44 ++---- setools/policyrep/__init__.py | 12 +- setools/policyrep/boolcond.py | 11 +- setools/policyrep/constraint.py | 18 +-- setools/policyrep/context.py | 3 +- setools/policyrep/default.py | 9 +- setools/policyrep/exception.py | 234 +++++++++++++++++++++++++++++++ setools/policyrep/initsid.py | 9 +- setools/policyrep/mls.py | 78 ++++------- setools/policyrep/mlsrule.py | 9 +- setools/policyrep/objclass.py | 27 +--- setools/policyrep/rbacrule.py | 13 +- setools/policyrep/role.py | 9 +- setools/policyrep/rule.py | 28 +--- setools/policyrep/symbol.py | 28 ---- setools/policyrep/terule.py | 40 ++---- setools/policyrep/typeattr.py | 9 +- setools/policyrep/user.py | 9 +- setools/rbacrulequery.py | 3 +- setools/terulequery.py | 2 +- tests/dta.py | 4 +- tests/infoflow.py | 4 +- tests/mlsrulequery.py | 2 +- tests/permmap.py | 3 +- tests/policyrep/mls.py | 4 +- tests/policyrep/selinuxpolicy.py | 4 +- tests/rbacrulequery.py | 2 +- tests/terulequery.py | 2 +- 32 files changed, 400 insertions(+), 285 deletions(-) create mode 100644 setools/exception.py create mode 100644 setools/policyrep/exception.py diff --git a/setools/__init__.py b/setools/__init__.py index 6caee6d..a9c0a88 100644 --- a/setools/__init__.py +++ b/setools/__init__.py @@ -25,7 +25,10 @@ except: # pragma: no cover # Python classes for policy representation from . import policyrep -from .policyrep import SELinuxPolicy, InvalidPolicy +from .policyrep import SELinuxPolicy + +# Exceptions +from . import exception # Component Queries from . import boolquery diff --git a/setools/constraintquery.py b/setools/constraintquery.py index 8c03a73..bac43e1 100644 --- a/setools/constraintquery.py +++ b/setools/constraintquery.py @@ -21,7 +21,7 @@ import re from . import mixins from .query import PolicyQuery -from .policyrep.constraint import ConstraintUseError +from .policyrep.exception import ConstraintUseError class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, PolicyQuery): diff --git a/setools/exception.py b/setools/exception.py new file mode 100644 index 0000000..676783f --- /dev/null +++ b/setools/exception.py @@ -0,0 +1,56 @@ +# 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 +# . +# + +# +# Base class for exceptions +# + + +class SEToolsException(Exception): + + """Base class for all SETools exceptions.""" + pass + +# +# Permission map exceptions +# + + +class PermissionMapException(SEToolsException): + + """Base class for all permission map exceptions.""" + pass + + +class RuleTypeError(PermissionMapException): + + """Exception for using rules with incorrect rule type.""" + pass + + +class UnmappedClass(PermissionMapException): + + """Exception for classes that are unmapped""" + pass + + +class UnmappedPermission(PermissionMapException): + + """Exception for permissions that are unmapped""" + pass diff --git a/setools/objclassquery.py b/setools/objclassquery.py index db6e2de..293bce9 100644 --- a/setools/objclassquery.py +++ b/setools/objclassquery.py @@ -20,7 +20,7 @@ import logging import re from . import compquery -from .policyrep.objclass import NoCommon +from .policyrep.exception import NoCommon class ObjClassQuery(compquery.ComponentQuery): diff --git a/setools/permmap.py b/setools/permmap.py index c0f3436..ffecd6c 100644 --- a/setools/permmap.py +++ b/setools/permmap.py @@ -18,27 +18,10 @@ # import logging +from . import exception from . import policyrep -class RuleTypeError(Exception): - - """Exception for using rules with incorrect rule type.""" - pass - - -class UnmappedClass(Exception): - - """Exception for classes that are unmapped""" - pass - - -class UnmappedPermission(Exception): - - """Exception for permissions that are unmapped""" - pass - - class PermissionMap(object): """Permission Map for information flow analysis.""" @@ -169,7 +152,7 @@ class PermissionMap(object): for perm in self.permmap[classname]: self.permmap[classname][perm]['enabled'] = False except KeyError: - raise UnmappedClass("{0} is not mapped.".format(classname)) + raise exception.UnmappedClass("{0} is not mapped.".format(classname)) def exclude_permission(self, class_, permission): """ @@ -186,12 +169,13 @@ class PermissionMap(object): classname = str(class_) if classname not in self.permmap: - raise UnmappedClass("{0} is not mapped.".format(classname)) + raise exception.UnmappedClass("{0} is not mapped.".format(classname)) try: self.permmap[classname][permission]['enabled'] = False except KeyError: - raise UnmappedPermission("{0}:{1} is not mapped.".format(classname, permission)) + raise exception.UnmappedPermission("{0}:{1} is not mapped.". + format(classname, permission)) def include_class(self, class_): """ @@ -210,7 +194,7 @@ class PermissionMap(object): for perm in self.permmap[classname]: self.permmap[classname][perm]['enabled'] = True except KeyError: - raise UnmappedClass("{0} is not mapped.".format(classname)) + raise exception.UnmappedClass("{0} is not mapped.".format(classname)) def include_permission(self, class_, permission): """ @@ -228,12 +212,13 @@ class PermissionMap(object): classname = str(class_) if classname not in self.permmap: - raise UnmappedClass("{0} is not mapped.".format(classname)) + raise exception.UnmappedClass("{0} is not mapped.".format(classname)) try: self.permmap[classname][permission]['enabled'] = True except KeyError: - raise UnmappedPermission("{0}:{1} is not mapped.".format(classname, permission)) + raise exception.UnmappedPermission("{0}:{1} is not mapped.". + format(classname, permission)) def map_policy(self, policy): """Create mappings for all classes and permissions in the specified policy.""" @@ -248,7 +233,7 @@ class PermissionMap(object): try: perms |= c.common.perms - except policyrep.objclass.NoCommon: + except policyrep.exception.NoCommon: pass for perm_name in perms: @@ -276,11 +261,11 @@ class PermissionMap(object): class_name = str(rule.tclass) if rule.ruletype != 'allow': - raise RuleTypeError("{0} rules cannot be used for calculating a weight". - format(rule.ruletype)) + raise exception.RuleTypeError("{0} rules cannot be used for calculating a weight". + format(rule.ruletype)) if class_name not in self.permmap: - raise UnmappedClass("{0} is not mapped.".format(class_name)) + raise exception.UnmappedClass("{0} is not mapped.".format(class_name)) # iterate over the permissions and determine the # weight of the rule in each direction. The result @@ -289,7 +274,8 @@ class PermissionMap(object): try: mapping = self.permmap[class_name][perm_name] except KeyError: - raise UnmappedPermission("{0}:{1} is not mapped.".format(class_name, perm_name)) + raise exception.UnmappedPermission("{0}:{1} is not mapped.". + format(class_name, perm_name)) if not mapping['enabled']: continue diff --git a/setools/policyrep/__init__.py b/setools/policyrep/__init__.py index fb09570..3cf4b44 100644 --- a/setools/policyrep/__init__.py +++ b/setools/policyrep/__init__.py @@ -33,6 +33,9 @@ from . import qpol # This also makes sense since an object would only # be valid for the policy it comes from. +# Exceptions +from . import exception + # Components from . import boolcond from . import default @@ -57,12 +60,6 @@ from . import initsid from . import netcontext -class InvalidPolicy(SyntaxError): - - """Exception for invalid policy.""" - pass - - class SELinuxPolicy(object): """The complete SELinux policy.""" @@ -79,7 +76,8 @@ class SELinuxPolicy(object): try: self.policy = qpol.qpol_policy_factory(policyfile) except SyntaxError as err: - raise InvalidPolicy("Error opening policy file \"{0}\": {1}".format(policyfile, err)) + raise exception.InvalidPolicy("Error opening policy file \"{0}\": {1}". + format(policyfile, err)) self.filename = policyfile diff --git a/setools/policyrep/boolcond.py b/setools/policyrep/boolcond.py index b37a7f8..49d77cc 100644 --- a/setools/policyrep/boolcond.py +++ b/setools/policyrep/boolcond.py @@ -16,16 +16,11 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol -class InvalidBoolean(symbol.InvalidSymbol): - - """Exception for invalid Booleans.""" - pass - - def boolean_factory(policy, symbol): """Factory function for creating Boolean statement objects.""" @@ -35,7 +30,7 @@ def boolean_factory(policy, symbol): try: return Boolean(policy, qpol.qpol_bool_t(policy, symbol)) except ValueError: - raise InvalidBoolean("{0} is not a valid Boolean".format(symbol)) + raise exception.InvalidBoolean("{0} is not a valid Boolean".format(symbol)) def condexpr_factory(policy, symbol): @@ -165,4 +160,4 @@ class ConditionalExpr(symbol.PolicySymbol): return bools def statement(self): - raise symbol.NoStatement + raise exception.NoStatement diff --git a/setools/policyrep/constraint.py b/setools/policyrep/constraint.py index ccc912c..fdc495a 100644 --- a/setools/policyrep/constraint.py +++ b/setools/policyrep/constraint.py @@ -16,6 +16,7 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import role from . import symbol @@ -24,18 +25,6 @@ from . import typeattr from . import user -class ConstraintUseError(symbol.SymbolUseError): - - """Exception when getting permissions from a validatetrans.""" - pass - - -class InvalidConstraintType(symbol.InvalidSymbol): - - """Exception for invalid constraint types.""" - 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. @@ -53,7 +42,7 @@ def validate_ruletype(types): """Validate constraint rule types.""" for t in types: if t not in ["constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans"]: - raise InvalidConstraintType("{0} is not a valid constraint type.".format(t)) + raise exception.InvalidConstraintType("{0} is not a valid constraint type.".format(t)) def constraint_factory(policy, symbol): @@ -305,4 +294,5 @@ class Validatetrans(BaseConstraint): @property def perms(self): - raise ConstraintUseError("{0} rules do not have permissions.".format(self.ruletype)) + raise exception.ConstraintUseError("{0} rules do not have permissions.". + format(self.ruletype)) diff --git a/setools/policyrep/context.py b/setools/policyrep/context.py index a19cd49..1c1f605 100644 --- a/setools/policyrep/context.py +++ b/setools/policyrep/context.py @@ -16,6 +16,7 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol from . import user @@ -64,4 +65,4 @@ class Context(symbol.PolicySymbol): return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy)) def statement(self): - raise symbol.NoStatement + raise exception.NoStatement diff --git a/setools/policyrep/default.py b/setools/policyrep/default.py index feb8485..9e1c911 100644 --- a/setools/policyrep/default.py +++ b/setools/policyrep/default.py @@ -16,17 +16,12 @@ # License along with SETools. If not, see # . # +from . import exception from . import symbol from . import objclass from . import qpol -class NoDefaults(symbol.InvalidSymbol): - - """Exception for classes that have no default_* statements.""" - pass - - def default_factory(policy, symbol): """Factory generator for creating default_* statement objects.""" @@ -41,7 +36,7 @@ def default_factory(policy, symbol): # qpol will essentially iterate over all classes # and emit None for classes that don't set a default if not symbol.object_class(policy): - raise NoDefaults + raise exception.NoDefaults if symbol.user_default(policy): yield UserDefault(policy, symbol) diff --git a/setools/policyrep/exception.py b/setools/policyrep/exception.py new file mode 100644 index 0000000..e0d081d --- /dev/null +++ b/setools/policyrep/exception.py @@ -0,0 +1,234 @@ +# 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 +# . +# +from ..exception import SEToolsException + +# +# Policyrep base exception +# + + +class PolicyrepException(SEToolsException): + + """Base class for all policyrep exceptions.""" + pass + + +# +# General Policyrep exceptions +# + + +class InvalidPolicy(SyntaxError, PolicyrepException): + + """Exception for invalid policy.""" + pass + + +class MLSDisabled(PolicyrepException): + + """ + Exception when MLS is disabled. + """ + pass + + +# +# Invalid component exceptions +# +class InvalidSymbol(ValueError, PolicyrepException): + + """ + Base class for invalid symbols. Typically this is attempting to + look up an object in the policy, but it does not exist. + """ + pass + + +class InvalidBoolean(InvalidSymbol): + + """Exception for invalid Booleans.""" + pass + + +class InvalidClass(InvalidSymbol): + + """Exception for invalid object classes.""" + pass + + +class InvalidCommon(InvalidSymbol): + + """Exception for invalid common permission sets.""" + pass + + +class InvalidInitialSid(InvalidSymbol): + + """Exception for invalid initial sids.""" + pass + + +class InvalidLevel(InvalidSymbol): + + """ + Exception for an invalid level. + """ + pass + + +class InvalidRange(InvalidSymbol): + + """ + Exception for an invalid range. + """ + pass + + +class InvalidRole(InvalidSymbol): + + """Exception for invalid roles.""" + pass + + +class InvalidSensitivity(InvalidSymbol): + + """ + Exception for an invalid sensitivity. + """ + pass + + +class InvalidType(InvalidSymbol): + + """Exception for invalid types and attributes.""" + pass + + +class InvalidUser(InvalidSymbol): + + """Exception for invalid users.""" + pass + +# +# Rule type exceptions +# + + +class InvalidRuleType(InvalidSymbol): + + """Exception for invalid rule types.""" + pass + + +class InvalidConstraintType(InvalidSymbol): + + """Exception for invalid constraint types.""" + # This is not a rule but is similar. + pass + + +class InvalidMLSRuleType(InvalidRuleType): + + """Exception for invalid MLS rule types.""" + pass + + +class InvalidRBACRuleType(InvalidRuleType): + + """Exception for invalid RBAC rule types.""" + pass + + +class InvalidTERuleType(InvalidRuleType): + + """Exception for invalid TE rule types.""" + pass + + +# +# Object use errors +# +class SymbolUseError(PolicyrepException): + + """ + Base class for incorrectly using an object. Typically this is + for classes with strong similarities, but with slight variances in + functionality, e.g. allow vs type_transition rules. + """ + pass + + +class RuleUseError(SymbolUseError): + + """ + Base class for incorrect parameters for a rule. For + example, trying to get the permissions of a rule that has no + permissions. + """ + pass + + +class ConstraintUseError(SymbolUseError): + + """Exception when getting permissions from a validatetrans.""" + pass + + +class NoStatement(SymbolUseError): + + """ + Exception for objects that have no inherent statement, such + as conditional expressions and MLS ranges. + """ + pass + + +# +# Other exceptions +# +class NoCommon(PolicyrepException): + + """ + Exception when a class does not inherit a common permission set. + """ + pass + + +class NoDefaults(InvalidSymbol): + + """Exception for classes that have no default_* statements.""" + pass + + +class RuleNotConditional(PolicyrepException): + + """ + Exception when getting the conditional expression for rules + that are unconditional (not conditional). + """ + pass + + +class TERuleNoFilename(PolicyrepException): + + """ + Exception when getting the file name of a + type_transition rule that has no file name. + """ + pass diff --git a/setools/policyrep/initsid.py b/setools/policyrep/initsid.py index 198b998..7e970b9 100644 --- a/setools/policyrep/initsid.py +++ b/setools/policyrep/initsid.py @@ -16,17 +16,12 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol from . import context -class InvalidInitialSid(symbol.InvalidSymbol): - - """Exception for invalid initial sids.""" - pass - - def initialsid_factory(policy, symbol): """Factory function for creating initial sid objects.""" @@ -36,7 +31,7 @@ def initialsid_factory(policy, symbol): try: return InitialSID(policy, qpol.qpol_isid_t(policy, symbol)) except ValueError: - raise InvalidInitialSid("{0} is not a valid initial sid".format(symbol)) + raise exception.InvalidInitialSid("{0} is not a valid initial sid".format(symbol)) class InitialSID(symbol.PolicySymbol): diff --git a/setools/policyrep/mls.py b/setools/policyrep/mls.py index 2f6845d..967e41d 100644 --- a/setools/policyrep/mls.py +++ b/setools/policyrep/mls.py @@ -18,6 +18,7 @@ # import itertools +from . import exception from . import qpol from . import symbol @@ -39,38 +40,6 @@ from . import symbol # instances of the same object (except for level decl). -class InvalidSensitivity(symbol.InvalidSymbol): - - """ - Exception for an invalid sensitivity. - """ - pass - - -class InvalidLevel(symbol.InvalidSymbol): - - """ - Exception for an invalid level. - """ - pass - - -class InvalidRange(symbol.InvalidSymbol): - - """ - Exception for an invalid range. - """ - pass - - -class MLSDisabled(Exception): - - """ - Exception when MLS is disabled. - """ - pass - - def enabled(policy): """Determine if MLS is enabled.""" return policy.capability(qpol.QPOL_CAP_MLS) @@ -80,7 +49,7 @@ def category_factory(policy, symbol): """Factory function for creating MLS category objects.""" if not enabled(policy): - raise MLSDisabled + raise exception.MLSDisabled if not isinstance(symbol, qpol.qpol_cat_t): raise NotImplementedError @@ -95,7 +64,7 @@ def sensitivity_factory(policy, symbol): """Factory function for creating MLS sensitivity objects.""" if not enabled(policy): - raise MLSDisabled + raise exception.MLSDisabled if isinstance(symbol, qpol.qpol_level_t): if symbol.isalias(policy): @@ -106,7 +75,7 @@ def sensitivity_factory(policy, symbol): try: return Sensitivity(policy, qpol.qpol_level_t(policy, symbol)) except ValueError: - raise InvalidSensitivity("{0} is not a valid sensitivity".format(symbol)) + raise exception.InvalidSensitivity("{0} is not a valid sensitivity".format(symbol)) def level_factory(policy, symbol): @@ -116,7 +85,7 @@ def level_factory(policy, symbol): """ if not enabled(policy): - raise MLSDisabled + raise exception.MLSDisabled if isinstance(symbol, qpol.qpol_mls_level_t): return Level(policy, symbol) @@ -127,7 +96,8 @@ def level_factory(policy, symbol): try: semantic_level = qpol.qpol_semantic_level_t(policy, sens) except ValueError: - raise InvalidLevel("{0} is invalid ({1} is not a valid sensitivity)".format(symbol, sens)) + raise exception.InvalidLevel("{0} is invalid ({1} is not a valid sensitivity)". + format(symbol, sens)) try: cats = sens_split[1] @@ -141,22 +111,22 @@ def level_factory(policy, symbol): try: semantic_level.add_cats(policy, catrange[0], catrange[1]) except ValueError: - raise InvalidLevel("{0} is invalid ({1} is not a valid category range)". - format(symbol, group)) + raise exception.InvalidLevel( + "{0} is invalid ({1} is not a valid category range)".format(symbol, group)) elif len(catrange) == 1: try: semantic_level.add_cats(policy, catrange[0], catrange[0]) except ValueError: - raise InvalidLevel("{0} is invalid ({1} is not a valid category)". - format(symbol, group)) + raise exception.InvalidLevel("{0} is invalid ({1} is not a valid category)". + format(symbol, group)) else: - raise InvalidLevel("{0} is invalid (level parsing error)".format(symbol)) + raise exception.InvalidLevel("{0} is invalid (level parsing error)".format(symbol)) # convert to level object try: policy_level = qpol.qpol_mls_level_t(policy, semantic_level) except ValueError: - raise InvalidLevel( + raise exception.InvalidLevel( "{0} is invalid (one or more categories are not associated with the sensitivity)". format(symbol)) @@ -170,7 +140,7 @@ def level_decl_factory(policy, symbol): """ if not enabled(policy): - raise MLSDisabled + raise exception.MLSDisabled if isinstance(symbol, qpol.qpol_level_t): if symbol.isalias(policy): @@ -181,14 +151,14 @@ def level_decl_factory(policy, symbol): try: return LevelDecl(policy, qpol.qpol_level_t(policy, symbol)) except ValueError: - raise InvalidLevel("{0} is not a valid sensitivity".format(symbol)) + raise exception.InvalidLevel("{0} is not a valid sensitivity".format(symbol)) def range_factory(policy, symbol): """Factory function for creating MLS range objects.""" if not enabled(policy): - raise MLSDisabled + raise exception.MLSDisabled if isinstance(symbol, qpol.qpol_mls_range_t): return Range(policy, symbol) @@ -200,13 +170,13 @@ def range_factory(policy, symbol): # e.g. s0:c1 - s0:c0.c255 try: low = level_factory(policy, levels[0].strip()) - except InvalidLevel as e: - raise InvalidRange("{0} is not a valid range ({1}).".format(symbol, e)) + except exception.InvalidLevel as e: + raise exception.InvalidRange("{0} is not a valid range ({1}).".format(symbol, e)) try: high = level_factory(policy, levels[1].strip()) - except InvalidLevel as e: - raise InvalidRange("{0} is not a valid range ({1}).".format(symbol, e)) + except exception.InvalidLevel as e: + raise exception.InvalidRange("{0} is not a valid range ({1}).".format(symbol, e)) except IndexError: high = low @@ -214,8 +184,8 @@ def range_factory(policy, symbol): try: policy_range = qpol.qpol_mls_range_t(policy, low.qpol_symbol, high.qpol_symbol) except ValueError: - raise InvalidRange("{0} is not a valid range ({1} is not dominated by {2})". - format(symbol, low, high)) + raise exception.InvalidRange("{0} is not a valid range ({1} is not dominated by {2})". + format(symbol, low, high)) return Range(policy, policy_range) @@ -399,7 +369,7 @@ class Level(BaseMLSLevel): return sensitivity_factory(self.policy, self.qpol_symbol.sens_name(self.policy)) def statement(self): - return symbol.NoStatement + return exception.NoStatement class Range(symbol.PolicySymbol): @@ -442,4 +412,4 @@ class Range(symbol.PolicySymbol): return level_factory(self.policy, self.qpol_symbol.low_level(self.policy)) def statement(self): - raise symbol.NoStatement + raise exception.NoStatement diff --git a/setools/policyrep/mlsrule.py b/setools/policyrep/mlsrule.py index 2de92fd..727c328 100644 --- a/setools/policyrep/mlsrule.py +++ b/setools/policyrep/mlsrule.py @@ -16,6 +16,7 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import rule from . import typeattr @@ -23,12 +24,6 @@ from . import mls from . import boolcond -class InvalidMLSRuleType(rule.InvalidRuleType): - - """Exception for invalid MLS rule types.""" - pass - - def mls_rule_factory(policy, symbol): """Factory function for creating MLS rule objects.""" if not isinstance(symbol, qpol.qpol_range_trans_t): @@ -41,7 +36,7 @@ def validate_ruletype(types): """Validate MLS rule types.""" for t in types: if t not in ["range_transition"]: - raise InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t)) + raise exception.InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t)) class MLSRule(rule.PolicyRule): diff --git a/setools/policyrep/objclass.py b/setools/policyrep/objclass.py index c68162d..b61d363 100644 --- a/setools/policyrep/objclass.py +++ b/setools/policyrep/objclass.py @@ -16,30 +16,11 @@ # License along with SETools. If not, see # . # +from . import exception from . import symbol from . import qpol -class InvalidCommon(symbol.InvalidSymbol): - - """Exception for invalid common permission sets.""" - pass - - -class InvalidClass(symbol.InvalidSymbol): - - """Exception for invalid object classes.""" - pass - - -class NoCommon(Exception): - - """ - Exception when a class does not inherit a common permission set. - """ - pass - - def common_factory(policy, name): """Factory function for creating common permission set objects.""" @@ -49,7 +30,7 @@ def common_factory(policy, name): try: symbol = qpol.qpol_common_t(policy, name) except ValueError: - raise InvalidCommon("{0} is not a valid common".format(name)) + raise exception.InvalidCommon("{0} is not a valid common".format(name)) return Common(policy, symbol) @@ -63,7 +44,7 @@ def class_factory(policy, name): try: symbol = qpol.qpol_class_t(policy, name) except ValueError: - raise InvalidClass("{0} is not a valid object class".format(name)) + raise exception.InvalidClass("{0} is not a valid object class".format(name)) return ObjClass(policy, symbol) @@ -100,7 +81,7 @@ class ObjClass(Common): try: return common_factory(self.policy, self.qpol_symbol.common(self.policy)) except ValueError: - raise NoCommon("{0} does not inherit a common.".format(self)) + raise exception.NoCommon("{0} does not inherit a common.".format(self)) def statement(self): stmt = "class {0}\n".format(self) diff --git a/setools/policyrep/rbacrule.py b/setools/policyrep/rbacrule.py index ce7240e..75a2159 100644 --- a/setools/policyrep/rbacrule.py +++ b/setools/policyrep/rbacrule.py @@ -16,18 +16,13 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import rule from . import role from . import typeattr -class InvalidRBACRuleType(rule.InvalidRuleType): - - """Exception for invalid RBAC rule types.""" - pass - - def rbac_rule_factory(policy, symbol): """Factory function for creating RBAC rule objects.""" @@ -43,7 +38,7 @@ def validate_ruletype(types): """Validate RBAC rule types.""" for t in types: if t not in ["allow", "role_transition"]: - raise InvalidTERuleType("{0} is not a valid RBAC rule type.".format(t)) + raise exception.InvalidTERuleType("{0} is not a valid RBAC rule type.".format(t)) class RoleAllow(rule.PolicyRule): @@ -66,12 +61,12 @@ class RoleAllow(rule.PolicyRule): @property def tclass(self): """The rule's object class.""" - raise rule.RuleUseError("Role allow rules do not have an object class.") + raise exception.RuleUseError("Role allow rules do not have an object class.") @property def default(self): """The rule's default role.""" - raise rule.RuleUseError("Role allow rules do not have a default role.") + raise exception.RuleUseError("Role allow rules do not have a default role.") class RoleTransition(rule.PolicyRule): diff --git a/setools/policyrep/role.py b/setools/policyrep/role.py index 3faa59a..a0cf8a7 100644 --- a/setools/policyrep/role.py +++ b/setools/policyrep/role.py @@ -16,17 +16,12 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol from . import typeattr -class InvalidRole(symbol.InvalidSymbol): - - """Exception for invalid roles.""" - pass - - def role_factory(qpol_policy, name): """Factory function for creating Role objects.""" @@ -36,7 +31,7 @@ def role_factory(qpol_policy, name): try: symbol = qpol.qpol_role_t(qpol_policy, name) except ValueError: - raise InvalidRole("{0} is not a valid role".format(name)) + raise exception.InvalidRole("{0} is not a valid role".format(name)) return Role(qpol_policy, symbol) diff --git a/setools/policyrep/rule.py b/setools/policyrep/rule.py index 4531d0d..dcbbd39 100644 --- a/setools/policyrep/rule.py +++ b/setools/policyrep/rule.py @@ -16,36 +16,12 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol from . import objclass -class InvalidRuleType(symbol.InvalidSymbol): - - """Exception for invalid rule types.""" - pass - - -class RuleUseError(symbol.SymbolUseError): - - """ - Exception when getting incorrect parameters for a rule. For - example, trying to get the permissions of a rule that has no - permissions. - """ - pass - - -class RuleNotConditional(Exception): - - """ - Exception when getting the conditional expression for rules - that are unconditional (not conditional). - """ - pass - - class PolicyRule(symbol.PolicySymbol): """This is base class for policy rules.""" @@ -91,7 +67,7 @@ class PolicyRule(symbol.PolicySymbol): def conditional(self): """The conditional expression for this rule.""" # Most rules cannot be conditional. - raise RuleNotConditional + raise exception.RuleNotConditional def statement(self): return str(self) diff --git a/setools/policyrep/symbol.py b/setools/policyrep/symbol.py index 385040d..36bb340 100644 --- a/setools/policyrep/symbol.py +++ b/setools/policyrep/symbol.py @@ -19,34 +19,6 @@ from . import qpol -class InvalidSymbol(ValueError): - - """ - Exception for invalid symbols. Typically this is attempting to - look up an object in the policy, but it does not exist. - """ - pass - - -class NoStatement(Exception): - - """ - Exception for objects that have no inherent statement, such - as conditional expressions and MLS ranges. - """ - pass - - -class SymbolUseError(Exception): - - """ - Exception for incorrectly using a symbol. Typically this is - for classes with strong similarities, but with slight variances in - functionality, e.g. allow vs type_transition rules. - """ - pass - - class PolicySymbol(object): """This is a base class for all policy objects.""" diff --git a/setools/policyrep/terule.py b/setools/policyrep/terule.py index 9fc25f5..3d05541 100644 --- a/setools/policyrep/terule.py +++ b/setools/policyrep/terule.py @@ -16,6 +16,7 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol from . import rule @@ -23,21 +24,6 @@ from . import typeattr from . import boolcond -class InvalidTERuleType(rule.InvalidRuleType): - - """Exception for invalid TE rule types.""" - pass - - -class TERuleNoFilename(Exception): - - """ - Exception when getting the file name of a - type_transition rule that has no file name. - """ - pass - - def te_rule_factory(policy, symbol): """Factory function for creating TE rule objects.""" @@ -54,7 +40,7 @@ def validate_ruletype(types): for t in types: if t not in ["allow", "auditallow", "dontaudit", "neverallow", "type_transition", "type_member", "type_change"]: - raise InvalidTERuleType("{0} is not a valid TE rule type.".format(t)) + raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t)) class BaseTERule(rule.PolicyRule): @@ -84,7 +70,7 @@ class BaseTERule(rule.PolicyRule): # AttributeError: name filetrans rules cannot be conditional # so no member function # ValueError: The rule is not conditional - raise rule.RuleNotConditional + raise exception.RuleNotConditional class AVRule(BaseTERule): @@ -106,7 +92,7 @@ class AVRule(BaseTERule): try: rule_string += " [ {0} ]".format(self.conditional) - except rule.RuleNotConditional: + except exception.RuleNotConditional: pass return rule_string @@ -119,11 +105,11 @@ class AVRule(BaseTERule): @property def default(self): """The rule's default type.""" - raise rule.RuleUseError("{0} rules do not have a default type.".format(self.ruletype)) + raise exception.RuleUseError("{0} rules do not have a default type.".format(self.ruletype)) @property def filename(self): - raise rule.RuleUseError("{0} rules do not have file names".format(self.ruletype)) + raise exception.RuleUseError("{0} rules do not have file names".format(self.ruletype)) class TERule(BaseTERule): @@ -135,13 +121,13 @@ class TERule(BaseTERule): try: rule_string += " \"{0}\";".format(self.filename) - except (TERuleNoFilename, rule.RuleUseError): + except (exception.TERuleNoFilename, exception.RuleUseError): # invalid use for type_change/member rule_string += ";" try: rule_string += " [ {0} ]".format(self.conditional) - except rule.RuleNotConditional: + except exception.RuleNotConditional: pass return rule_string @@ -149,7 +135,7 @@ class TERule(BaseTERule): @property def perms(self): """The rule's permission set.""" - raise rule.RuleUseError( + raise exception.RuleUseError( "{0} rules do not have a permission set.".format(self.ruletype)) @property @@ -158,7 +144,8 @@ class TERule(BaseTERule): try: return typeattr.type_factory(self.policy, self.qpol_symbol.default_type(self.policy)) except AttributeError: - raise rule.RuleUseError("{0} rules do not have a default type.".format(self.ruletype)) + raise exception.RuleUseError("{0} rules do not have a default type.". + format(self.ruletype)) @property def filename(self): @@ -167,6 +154,7 @@ class TERule(BaseTERule): return self.qpol_symbol.filename(self.policy) except AttributeError: if self.ruletype == "type_transition": - raise TERuleNoFilename + raise exception.TERuleNoFilename else: - raise rule.RuleUseError("{0} rules do not have file names".format(self.ruletype)) + raise exception.RuleUseError("{0} rules do not have file names". + format(self.ruletype)) diff --git a/setools/policyrep/typeattr.py b/setools/policyrep/typeattr.py index f2ed596..e4b5f62 100644 --- a/setools/policyrep/typeattr.py +++ b/setools/policyrep/typeattr.py @@ -16,16 +16,11 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import symbol -class InvalidType(symbol.InvalidSymbol): - - """Exception for invalid types and attributes.""" - pass - - def _symbol_lookup(qpol_policy, name): """Look up the low-level qpol policy reference""" if isinstance(name, qpol.qpol_type_t): @@ -34,7 +29,7 @@ def _symbol_lookup(qpol_policy, name): try: return qpol.qpol_type_t(qpol_policy, name) except ValueError: - raise InvalidType("{0} is not a valid type/attribute".format(name)) + raise exception.InvalidType("{0} is not a valid type/attribute".format(name)) def attribute_factory(qpol_policy, name): diff --git a/setools/policyrep/user.py b/setools/policyrep/user.py index 2b4e9b7..db4d13f 100644 --- a/setools/policyrep/user.py +++ b/setools/policyrep/user.py @@ -16,18 +16,13 @@ # License along with SETools. If not, see # . # +from . import exception from . import qpol from . import role from . import mls from . import symbol -class InvalidUser(symbol.InvalidSymbol): - - """Exception for invalid users.""" - pass - - def user_factory(qpol_policy, name): """Factory function for creating User objects.""" @@ -37,7 +32,7 @@ def user_factory(qpol_policy, name): try: symbol = qpol.qpol_user_t(qpol_policy, name) except ValueError: - raise InvalidUser("{0} is not a valid user".format(name)) + raise exception.InvalidUser("{0} is not a valid user".format(name)) return User(qpol_policy, symbol) diff --git a/setools/rbacrulequery.py b/setools/rbacrulequery.py index ffc16fd..5c5e3b3 100644 --- a/setools/rbacrulequery.py +++ b/setools/rbacrulequery.py @@ -19,8 +19,7 @@ import logging import re -from .policyrep.rule import RuleUseError -from .policyrep.typeattr import InvalidType +from .policyrep.exception import InvalidType, RuleUseError from . import rulequery diff --git a/setools/terulequery.py b/setools/terulequery.py index 91bb1a2..83554b9 100644 --- a/setools/terulequery.py +++ b/setools/terulequery.py @@ -19,7 +19,7 @@ import logging import re -from .policyrep.rule import RuleUseError, RuleNotConditional +from .policyrep.exception import RuleUseError, RuleNotConditional from . import mixins from . import rulequery diff --git a/tests/dta.py b/tests/dta.py index 84753b2..c16bd61 100644 --- a/tests/dta.py +++ b/tests/dta.py @@ -21,8 +21,8 @@ import networkx as nx from setools import SELinuxPolicy from setools.dta import DomainTransitionAnalysis -from setools.policyrep.rule import RuleNotConditional -from setools.policyrep.typeattr import InvalidType, Type +from setools.policyrep.exception import InvalidType, RuleNotConditional +from setools.policyrep.typeattr import Type class DomainTransitionAnalysisTest(unittest.TestCase): diff --git a/tests/infoflow.py b/tests/infoflow.py index 09d5f95..4ce018e 100644 --- a/tests/infoflow.py +++ b/tests/infoflow.py @@ -22,8 +22,8 @@ import networkx as nx from setools import SELinuxPolicy from setools.infoflow import InfoFlowAnalysis from setools.permmap import PermissionMap -from setools.policyrep.rule import RuleNotConditional -from setools.policyrep.typeattr import InvalidType, Type +from setools.policyrep.exception import InvalidType, RuleNotConditional +from setools.policyrep.typeattr import Type # Note: the testing for having correct rules on every edge is only diff --git a/tests/mlsrulequery.py b/tests/mlsrulequery.py index 37a04ea..1b64823 100644 --- a/tests/mlsrulequery.py +++ b/tests/mlsrulequery.py @@ -19,7 +19,7 @@ import unittest from setools import SELinuxPolicy from setools.mlsrulequery import MLSRuleQuery -from setools.policyrep.rule import RuleNotConditional +from setools.policyrep.exception import InvalidMLSRuleType, RuleNotConditional # Note: the test policy has been written assuming range_transition # statements could have attributes. However, range_transition diff --git a/tests/permmap.py b/tests/permmap.py index d5e8e24..0bad796 100644 --- a/tests/permmap.py +++ b/tests/permmap.py @@ -23,7 +23,8 @@ except ImportError: from mock import MagicMock from setools import SELinuxPolicy -from setools.permmap import PermissionMap, UnmappedClass, UnmappedPermission, RuleTypeError +from setools.permmap import PermissionMap +from setools.exception import RuleTypeError, UnmappedClass, UnmappedPermission class PermissionMapTest(unittest.TestCase): diff --git a/tests/policyrep/mls.py b/tests/policyrep/mls.py index a113268..ee44070 100644 --- a/tests/policyrep/mls.py +++ b/tests/policyrep/mls.py @@ -24,9 +24,9 @@ except ImportError: from setools import SELinuxPolicy from setools.policyrep import qpol +from setools.policyrep.exception import MLSDisabled, InvalidLevel, InvalidRange from setools.policyrep.mls import sensitivity_factory, category_factory, level_factory, \ - range_factory, level_decl_factory, \ - MLSDisabled, InvalidLevel, InvalidRange + range_factory, level_decl_factory class SensitivityFactoryTest(unittest.TestCase): diff --git a/tests/policyrep/selinuxpolicy.py b/tests/policyrep/selinuxpolicy.py index 433cbc5..0f1e59b 100644 --- a/tests/policyrep/selinuxpolicy.py +++ b/tests/policyrep/selinuxpolicy.py @@ -22,8 +22,8 @@ import subprocess import tempfile import unittest -from setools import SELinuxPolicy, InvalidPolicy -from setools.boolquery import BoolQuery +from setools import SELinuxPolicy +from setools.policyrep.exception import InvalidPolicy class SELinuxPolicyTest(unittest.TestCase): diff --git a/tests/rbacrulequery.py b/tests/rbacrulequery.py index 687c4e1..57237bb 100644 --- a/tests/rbacrulequery.py +++ b/tests/rbacrulequery.py @@ -19,7 +19,7 @@ import unittest from setools import SELinuxPolicy from setools.rbacrulequery import RBACRuleQuery -from setools.policyrep.rule import RuleUseError, RuleNotConditional +from setools.policyrep.exception import RuleUseError, RuleNotConditional class RBACRuleQueryTest(unittest.TestCase): diff --git a/tests/terulequery.py b/tests/terulequery.py index bc55625..2271374 100644 --- a/tests/terulequery.py +++ b/tests/terulequery.py @@ -19,7 +19,7 @@ import unittest from setools import SELinuxPolicy from setools.terulequery import TERuleQuery -from setools.policyrep.rule import RuleNotConditional +from setools.policyrep.exception import RuleNotConditional class TERuleQueryTest(unittest.TestCase):