summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/setoolsgui/setools
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/setoolsgui/setools')
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/__init__.py68
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/boolquery.py66
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/categoryquery.py55
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/commonquery.py60
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/compquery.py39
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/constraintquery.py142
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/contextquery.py98
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/descriptors.py230
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/dta.py603
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/exception.py62
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/fsusequery.py87
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/genfsconquery.py98
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/infoflow.py403
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/initsidquery.py74
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/mixins.py91
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/mlsrulequery.py115
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/netifconquery.py77
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/nodeconquery.py148
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/objclassquery.py101
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/permmap.py363
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/polcapquery.py47
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/__init__.py568
-rwxr-xr-xlib/python2.7/site-packages/setoolsgui/setools/policyrep/_qpol.sobin0 -> 2151445 bytes
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/boolcond.py167
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/constraint.py297
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/context.py68
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/default.py128
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/exception.py248
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/fscontext.py123
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/initsid.py50
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/mls.py463
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/mlsrule.py62
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/netcontext.py167
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/objclass.py110
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/polcap.py40
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/qpol.py1114
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/rbacrule.py92
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/role.py81
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/rule.py72
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/symbol.py74
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/terule.py155
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/typeattr.py174
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/policyrep/user.py86
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/portconquery.py146
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/query.py192
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/rbacrulequery.py147
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/rolequery.py77
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/sensitivityquery.py74
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/terulequery.py178
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/typeattrquery.py70
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/typequery.py96
-rw-r--r--lib/python2.7/site-packages/setoolsgui/setools/userquery.py116
52 files changed, 8462 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/__init__.py b/lib/python2.7/site-packages/setoolsgui/setools/__init__.py
new file mode 100644
index 0000000..4d03553
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/__init__.py
@@ -0,0 +1,68 @@
+"""The SETools SELinux policy analysis library."""
+# Copyright 2014-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/>.
+#
+#try:
+# import pkg_resources
+# # pylint: disable=no-member
+# __version__ = pkg_resources.get_distribution("setools").version
+#except ImportError: # pragma: no cover
+# __version__ = "unknown"
+__version__ = "3.3.8"
+
+# Python classes for policy representation
+from . import policyrep
+from .policyrep import SELinuxPolicy
+
+# Exceptions
+from . import exception
+
+# Component Queries
+from .boolquery import BoolQuery
+from .categoryquery import CategoryQuery
+from .commonquery import CommonQuery
+from .objclassquery import ObjClassQuery
+from .polcapquery import PolCapQuery
+from .rolequery import RoleQuery
+from .sensitivityquery import SensitivityQuery
+from .typequery import TypeQuery
+from .typeattrquery import TypeAttributeQuery
+from .userquery import UserQuery
+
+# Rule Queries
+from .mlsrulequery import MLSRuleQuery
+from .rbacrulequery import RBACRuleQuery
+from .terulequery import TERuleQuery
+
+# Constraint queries
+from .constraintquery import ConstraintQuery
+
+# In-policy Context Queries
+from .fsusequery import FSUseQuery
+from .genfsconquery import GenfsconQuery
+from .initsidquery import InitialSIDQuery
+from .netifconquery import NetifconQuery
+from .nodeconquery import NodeconQuery
+from .portconquery import PortconQuery
+
+# Information Flow Analysis
+from .infoflow import InfoFlowAnalysis
+from .permmap import PermissionMap
+
+# Domain Transition Analysis
+from .dta import DomainTransitionAnalysis
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/boolquery.py b/lib/python2.7/site-packages/setoolsgui/setools/boolquery.py
new file mode 100644
index 0000000..b70b7d5
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/boolquery.py
@@ -0,0 +1,66 @@
+# Copyright 2014-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 logging
+
+from . import compquery
+from .descriptors import CriteriaDescriptor
+
+
+class BoolQuery(compquery.ComponentQuery):
+
+ """Query SELinux policy Booleans.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The Boolean name to match.
+ name_regex If true, regular expression matching
+ will be used on the Boolean name.
+ default The default state to match. If this
+ is None, the default state not be matched.
+ """
+
+ _default = None
+
+ @property
+ def default(self):
+ return self._default
+
+ @default.setter
+ def default(self, value):
+ if value is None:
+ self._default = None
+ else:
+ self._default = bool(value)
+
+ def results(self):
+ """Generator which yields all Booleans matching the criteria."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Default: {0.default}".format(self))
+
+ for boolean in self.policy.bools():
+ if not self._match_name(boolean):
+ continue
+
+ if self.default is not None and boolean.state != self.default:
+ continue
+
+ yield boolean
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/categoryquery.py b/lib/python2.7/site-packages/setoolsgui/setools/categoryquery.py
new file mode 100644
index 0000000..d4d7c4c
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/categoryquery.py
@@ -0,0 +1,55 @@
+# 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 logging
+
+from . import compquery
+from . import mixins
+
+
+class CategoryQuery(mixins.MatchAlias, compquery.ComponentQuery):
+
+ """
+ Query MLS Categories
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the category to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ alias The alias name to match.
+ alias_regex If true, regular expression matching
+ will be used on the alias names.
+ """
+
+ def results(self):
+ """Generator which yields all matching categories."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Alias: {0.alias}, regex: {0.alias_regex}".format(self))
+
+ for cat in self.policy.categories():
+ if not self._match_name(cat):
+ continue
+
+ if not self._match_alias(cat):
+ continue
+
+ yield cat
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/commonquery.py b/lib/python2.7/site-packages/setoolsgui/setools/commonquery.py
new file mode 100644
index 0000000..e105ccb
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/commonquery.py
@@ -0,0 +1,60 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery, mixins
+
+
+class CommonQuery(mixins.MatchPermission, compquery.ComponentQuery):
+
+ """
+ Query common permission sets.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the common to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ perms The permissions to match.
+ perms_equal If true, only commons with permission sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ perms_regex If true, regular expression matching will be used
+ on the permission names instead of set logic.
+ """
+
+ def results(self):
+ """Generator which yields all matching commons."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}".
+ format(self))
+
+ for com in self.policy.commons():
+ if not self._match_name(com):
+ continue
+
+ if not self._match_perms(com):
+ continue
+
+ yield com
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/compquery.py b/lib/python2.7/site-packages/setoolsgui/setools/compquery.py
new file mode 100644
index 0000000..3d8851a
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/compquery.py
@@ -0,0 +1,39 @@
+# Copyright 2014-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/>.
+#
+# pylint: disable=no-member,attribute-defined-outside-init,abstract-method
+import re
+
+from . import query
+from .descriptors import CriteriaDescriptor
+
+
+class ComponentQuery(query.PolicyQuery):
+
+ """Base class for SETools component queries."""
+
+ name = CriteriaDescriptor("name_regex")
+ name_regex = False
+
+ def _match_name(self, obj):
+ """Match the object to the name criteria."""
+ if not self.name:
+ # if there is no criteria, everything matches.
+ return True
+
+ return self._match_regex(obj, self.name, self.name_regex)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/constraintquery.py b/lib/python2.7/site-packages/setoolsgui/setools/constraintquery.py
new file mode 100644
index 0000000..82a6fc2
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/constraintquery.py
@@ -0,0 +1,142 @@
+# 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 logging
+import re
+
+from . import mixins, query
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor
+from .policyrep.exception import ConstraintUseError
+
+
+class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuery):
+
+ """
+ Query constraint rules, (mls)constrain/(mls)validatetrans.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ ruletype The list of 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.
+ perms The permission(s) to match.
+ perms_equal If true, the permission set of the rule
+ must exactly match the permissions
+ criteria. If false, any set intersection
+ will match.
+ perms_regex If true, regular expression matching will be used
+ on the permission names instead of set logic.
+ 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.
+ """
+
+ ruletype = RuletypeDescriptor("validate_constraint_ruletype")
+ user = CriteriaDescriptor("user_regex", "lookup_user")
+ user_regex = False
+ role = CriteriaDescriptor("role_regex", "lookup_role")
+ role_regex = False
+ role_indirect = True
+ type_ = CriteriaDescriptor("type_regex", "lookup_type_or_attr")
+ type_regex = False
+ type_indirect = True
+
+ 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."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ruletypes: {0.ruletype}".format(self))
+ self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
+ self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}".
+ format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+
+ for c in self.policy.constraints():
+ if self.ruletype:
+ if c.ruletype not in self.ruletype:
+ continue
+
+ if not self._match_object_class(c):
+ continue
+
+ try:
+ if not self._match_perms(c):
+ continue
+ except ConstraintUseError:
+ continue
+
+ if self.role and not self._match_expr(
+ c.roles,
+ self.role,
+ self.role_indirect,
+ self.role_regex):
+ continue
+
+ if self.type_ and not self._match_expr(
+ c.types,
+ self.type_,
+ self.type_indirect,
+ self.type_regex):
+ continue
+
+ if self.user and not self._match_expr(
+ c.users,
+ self.user,
+ False,
+ self.user_regex):
+ continue
+
+ yield c
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/contextquery.py b/lib/python2.7/site-packages/setoolsgui/setools/contextquery.py
new file mode 100644
index 0000000..5ce1632
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/contextquery.py
@@ -0,0 +1,98 @@
+# Copyright 2014-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/>.
+#
+# pylint: disable=attribute-defined-outside-init,no-member
+import re
+
+from . import query
+from .descriptors import CriteriaDescriptor
+
+
+class ContextQuery(query.PolicyQuery):
+
+ """
+ Base class for SETools in-policy labeling/context queries.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ context The object to match.
+ user The user to match in the context.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The role to match in the context.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The type to match in the context.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The range to match in the context.
+ range_subset If true, the criteria will match if it
+ is a subset of the context's range.
+ range_overlap If true, the criteria will match if it
+ overlaps any of the context's range.
+ range_superset If true, the criteria will match if it
+ is a superset of the context's range.
+ range_proper If true, use proper superset/subset
+ on range matching operations.
+ No effect if not using set operations.
+ """
+
+ user = CriteriaDescriptor("user_regex", "lookup_user")
+ user_regex = False
+ role = CriteriaDescriptor("role_regex", "lookup_role")
+ role_regex = False
+ type_ = CriteriaDescriptor("type_regex", "lookup_type")
+ type_regex = False
+ range_ = CriteriaDescriptor(lookup_function="lookup_range")
+ range_overlap = False
+ range_subset = False
+ range_superset = False
+ range_proper = False
+
+ def _match_context(self, context):
+
+ if self.user and not query.PolicyQuery._match_regex(
+ context.user,
+ self.user,
+ self.user_regex):
+ return False
+
+ if self.role and not query.PolicyQuery._match_regex(
+ context.role,
+ self.role,
+ self.role_regex):
+ return False
+
+ if self.type_ and not query.PolicyQuery._match_regex(
+ context.type_,
+ self.type_,
+ self.type_regex):
+ return False
+
+ if self.range_ and not query.PolicyQuery._match_range(
+ context.range_,
+ self.range_,
+ self.range_subset,
+ self.range_overlap,
+ self.range_superset,
+ self.range_proper):
+ return False
+
+ return True
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/descriptors.py b/lib/python2.7/site-packages/setoolsgui/setools/descriptors.py
new file mode 100644
index 0000000..eab9210
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/descriptors.py
@@ -0,0 +1,230 @@
+# 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/>.
+#
+"""
+SETools descriptors.
+
+These classes override how a class's attributes are get/set/deleted.
+This is how the @property decorator works.
+
+See https://docs.python.org/3/howto/descriptor.html
+for more details.
+"""
+
+import re
+from collections import defaultdict
+from weakref import WeakKeyDictionary
+
+#
+# Query criteria descriptors
+#
+# Implementation note: if the name_regex attribute value
+# is changed the criteria must be reset.
+#
+
+
+class CriteriaDescriptor(object):
+
+ """
+ Single item criteria descriptor.
+
+ Parameters:
+ name_regex The name of instance's regex setting attribute;
+ used as name_regex below. If unset,
+ regular expressions will never be used.
+ lookup_function The name of the SELinuxPolicy lookup function,
+ e.g. lookup_type or lookup_boolean.
+ default_value The default value of the criteria. The default
+ is None.
+
+ Read-only instance attribute use (obj parameter):
+ policy The instance of SELinuxPolicy
+ name_regex This attribute is read to determine if
+ the criteria should be looked up or
+ compiled into a regex. If the attribute
+ does not exist, False is assumed.
+ """
+
+ def __init__(self, name_regex=None, lookup_function=None, default_value=None):
+ assert name_regex or lookup_function, "A simple attribute should be used if there is " \
+ "no regex nor lookup function."
+ self.regex = name_regex
+ self.default_value = default_value
+ self.lookup_function = lookup_function
+
+ # use weak references so instances can be
+ # garbage collected, rather than unnecessarily
+ # kept around due to this descriptor.
+ self.instances = WeakKeyDictionary()
+
+ def __get__(self, obj, objtype=None):
+ if obj is None:
+ return self
+
+ return self.instances.setdefault(obj, self.default_value)
+
+ def __set__(self, obj, value):
+ if not value:
+ self.instances[obj] = None
+ elif self.regex and getattr(obj, self.regex, False):
+ self.instances[obj] = re.compile(value)
+ elif self.lookup_function:
+ lookup = getattr(obj.policy, self.lookup_function)
+ self.instances[obj] = lookup(value)
+ else:
+ self.instances[obj] = value
+
+
+class CriteriaSetDescriptor(CriteriaDescriptor):
+
+ """Descriptor for a set of criteria."""
+
+ def __set__(self, obj, value):
+ if not value:
+ self.instances[obj] = None
+ elif self.regex and getattr(obj, self.regex, False):
+ self.instances[obj] = re.compile(value)
+ elif self.lookup_function:
+ lookup = getattr(obj.policy, self.lookup_function)
+ self.instances[obj] = set(lookup(v) for v in value)
+ else:
+ self.instances[obj] = set(value)
+
+
+class RuletypeDescriptor(object):
+
+ """
+ Descriptor for a list of rule types.
+
+ Parameters:
+ validator The name of the SELinuxPolicy ruletype
+ validator function, e.g. validate_te_ruletype
+ default_value The default value of the criteria. The default
+ is None.
+
+ Read-only instance attribute use (obj parameter):
+ policy The instance of SELinuxPolicy
+ """
+
+ def __init__(self, validator):
+ self.validator = validator
+
+ # use weak references so instances can be
+ # garbage collected, rather than unnecessarily
+ # kept around due to this descriptor.
+ self.instances = WeakKeyDictionary()
+
+ def __get__(self, obj, objtype=None):
+ if obj is None:
+ return self
+
+ return self.instances.setdefault(obj, None)
+
+ def __set__(self, obj, value):
+ if value:
+ validate = getattr(obj.policy, self.validator)
+ validate(value)
+ self.instances[obj] = value
+ else:
+ self.instances[obj] = None
+
+
+#
+# NetworkX Graph Descriptors
+#
+# These descriptors are used to simplify all
+# of the dictionary use in the NetworkX graph.
+#
+
+
+class NetworkXGraphEdgeDescriptor(object):
+
+ """
+ Descriptor base class for NetworkX graph edge attributes.
+
+ Parameter:
+ name The edge property name
+
+ Instance class attribute use (obj parameter):
+ G The NetworkX graph
+ source The edge's source node
+ target The edge's target node
+ """
+
+ def __init__(self, propname):
+ self.name = propname
+
+ def __get__(self, obj, objtype=None):
+ if obj is None:
+ return self
+
+ return obj.G[obj.source][obj.target][self.name]
+
+ def __set__(self, obj, value):
+ raise NotImplementedError
+
+ def __delete__(self, obj):
+ raise NotImplementedError
+
+
+class EdgeAttrDict(NetworkXGraphEdgeDescriptor):
+
+ """A descriptor for edge attributes that are dictionaries."""
+
+ def __set__(self, obj, value):
+ # None is a special value to initialize the attribute
+ if value is None:
+ obj.G[obj.source][obj.target][self.name] = defaultdict(list)
+ else:
+ raise ValueError("{0} dictionaries should not be assigned directly".format(self.name))
+
+ def __delete__(self, obj):
+ obj.G[obj.source][obj.target][self.name].clear()
+
+
+class EdgeAttrIntMax(NetworkXGraphEdgeDescriptor):
+
+ """
+ A descriptor for edge attributes that are non-negative integers that always
+ keep the max assigned value until re-initialized.
+ """
+
+ def __set__(self, obj, value):
+ # None is a special value to initialize
+ if value is None:
+ obj.G[obj.source][obj.target][self.name] = 0
+ else:
+ current_value = obj.G[obj.source][obj.target][self.name]
+ obj.G[obj.source][obj.target][self.name] = max(current_value, value)
+
+
+class EdgeAttrList(NetworkXGraphEdgeDescriptor):
+
+ """A descriptor for edge attributes that are lists."""
+
+ def __set__(self, obj, value):
+ # None is a special value to initialize
+ if value is None:
+ obj.G[obj.source][obj.target][self.name] = []
+ else:
+ raise ValueError("{0} lists should not be assigned directly".format(self.name))
+
+ def __delete__(self, obj):
+ # in Python3 a .clear() function was added for lists
+ # keep this implementation for Python 2 compat
+ del obj.G[obj.source][obj.target][self.name][:]
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/dta.py b/lib/python2.7/site-packages/setoolsgui/setools/dta.py
new file mode 100644
index 0000000..271efc4
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/dta.py
@@ -0,0 +1,603 @@
+# Copyright 2014-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 itertools
+import logging
+from collections import defaultdict, namedtuple
+
+import networkx as nx
+from networkx.exception import NetworkXError, NetworkXNoPath
+
+from .descriptors import EdgeAttrDict, EdgeAttrList
+
+__all__ = ['DomainTransitionAnalysis']
+
+# Return values for the analysis
+# are in the following tuple formats:
+step_output = namedtuple("step", ["source",
+ "target",
+ "transition",
+ "entrypoints",
+ "setexec",
+ "dyntransition",
+ "setcurrent"])
+
+entrypoint_output = namedtuple("entrypoints", ["name",
+ "entrypoint",
+ "execute",
+ "type_transition"])
+
+
+class DomainTransitionAnalysis(object):
+
+ """Domain transition analysis."""
+
+ def __init__(self, policy, reverse=False, exclude=None):
+ """
+ Parameter:
+ policy The policy to analyze.
+ """
+ self.log = logging.getLogger(self.__class__.__name__)
+
+ self.policy = policy
+ self.exclude = exclude
+ self.reverse = reverse
+ self.rebuildgraph = True
+ self.rebuildsubgraph = True
+ self.G = nx.DiGraph()
+ self.subG = None
+
+ @property
+ def reverse(self):
+ return self._reverse
+
+ @reverse.setter
+ def reverse(self, direction):
+ self._reverse = bool(direction)
+ self.rebuildsubgraph = True
+
+ @property
+ def exclude(self):
+ return self._exclude
+
+ @exclude.setter
+ def exclude(self, types):
+ if types:
+ self._exclude = [self.policy.lookup_type(t) for t in types]
+ else:
+ self._exclude = None
+
+ self.rebuildsubgraph = True
+
+ def shortest_path(self, source, target):
+ """
+ Generator which yields one shortest domain transition path
+ between the source and target types (there may be more).
+
+ Parameters:
+ source The source type.
+ target The target type.
+
+ Yield: generator(steps)
+
+ steps A generator that returns the tuple of
+ source, target, and rules for each
+ domain transition.
+ """
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating one shortest path from {0} to {1}...".format(s, t))
+
+ try:
+ yield self.__generate_steps(nx.shortest_path(self.subG, s, t))
+ except (NetworkXNoPath, NetworkXError):
+ # NetworkXError: the type is valid but not in graph, e.g. excluded
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ pass
+
+ def all_paths(self, source, target, maxlen=2):
+ """
+ Generator which yields all domain transition paths between
+ the source and target up to the specified maximum path
+ length.
+
+ Parameters:
+ source The source type.
+ target The target type.
+ maxlen Maximum length of paths.
+
+ Yield: generator(steps)
+
+ steps A generator that returns the tuple of
+ source, target, and rules for each
+ domain transition.
+ """
+ if maxlen < 1:
+ raise ValueError("Maximum path length must be positive.")
+
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all paths from {0} to {1}, max len {2}...".format(s, t, maxlen))
+
+ try:
+ for path in nx.all_simple_paths(self.subG, s, t, maxlen):
+ yield self.__generate_steps(path)
+ except (NetworkXNoPath, NetworkXError):
+ # NetworkXError: the type is valid but not in graph, e.g. excluded
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ pass
+
+ def all_shortest_paths(self, source, target):
+ """
+ Generator which yields all shortest domain transition paths
+ between the source and target types.
+
+ Parameters:
+ source The source type.
+ target The target type.
+
+ Yield: generator(steps)
+
+ steps A generator that returns the tuple of
+ source, target, and rules for each
+ domain transition.
+ """
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all shortest paths from {0} to {1}...".format(s, t))
+
+ try:
+ for path in nx.all_shortest_paths(self.subG, s, t):
+ yield self.__generate_steps(path)
+ except (NetworkXNoPath, NetworkXError, KeyError):
+ # NetworkXError: the type is valid but not in graph, e.g. excluded
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ # KeyError: work around NetworkX bug
+ # when the source node is not in the graph
+ pass
+
+ def transitions(self, type_):
+ """
+ Generator which yields all domain transitions out of a
+ specified source type.
+
+ Parameters:
+ type_ The starting type.
+
+ Yield: generator(steps)
+
+ steps A generator that returns the tuple of
+ source, target, and rules for each
+ domain transition.
+ """
+ s = self.policy.lookup_type(type_)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all transitions {1} {0}".
+ format(s, "in to" if self.reverse else "out from"))
+
+ try:
+ for source, target in self.subG.out_edges_iter(s):
+ edge = Edge(self.subG, source, target)
+
+ if self.reverse:
+ real_source, real_target = target, source
+ else:
+ real_source, real_target = source, target
+
+ yield step_output(real_source, real_target,
+ edge.transition,
+ self.__generate_entrypoints(edge),
+ edge.setexec,
+ edge.dyntransition,
+ edge.setcurrent)
+
+ except NetworkXError:
+ # NetworkXError: the type is valid but not in graph, e.g. excluded
+ pass
+
+ def get_stats(self): # pragma: no cover
+ """
+ Get the domain transition graph statistics.
+
+ Return: tuple(nodes, edges)
+
+ nodes The number of nodes (types) in the graph.
+ edges The number of edges (domain transitions) in the graph.
+ """
+ return (self.G.number_of_nodes(), self.G.number_of_edges())
+
+ #
+ # Internal functions follow
+ #
+ @staticmethod
+ def __generate_entrypoints(edge):
+ """
+ Generator which yields the entrypoint, execute, and
+ type_transition rules for each entrypoint.
+
+ Parameter:
+ data The dictionary of entrypoints.
+
+ Yield: tuple(type, entry, exec, trans)
+
+ type The entrypoint type.
+ entry The list of entrypoint rules.
+ exec The list of execute rules.
+ trans The list of type_transition rules.
+ """
+ for e in edge.entrypoint:
+ yield entrypoint_output(e, edge.entrypoint[e], edge.execute[e], edge.type_transition[e])
+
+ def __generate_steps(self, path):
+ """
+ Generator which yields the source, target, and associated rules
+ for each domain transition.
+
+ Parameter:
+ path A list of graph node names representing an information flow path.
+
+ Yield: tuple(source, target, transition, entrypoints,
+ setexec, dyntransition, setcurrent)
+
+ source The source type for this step of the domain transition.
+ target The target type for this step of the domain transition.
+ transition The list of transition rules.
+ entrypoints Generator which yields entrypoint-related rules.
+ setexec The list of setexec rules.
+ dyntranstion The list of dynamic transition rules.
+ setcurrent The list of setcurrent rules.
+ """
+
+ for s in range(1, len(path)):
+ source = path[s - 1]
+ target = path[s]
+ edge = Edge(self.subG, source, target)
+
+ # Yield the actual source and target.
+ # The above perspective is reversed
+ # if the graph has been reversed.
+ if self.reverse:
+ real_source, real_target = target, source
+ else:
+ real_source, real_target = source, target
+
+ yield step_output(real_source, real_target,
+ edge.transition,
+ self.__generate_entrypoints(edge),
+ edge.setexec,
+ edge.dyntransition,
+ edge.setcurrent)
+
+ #
+ # Graph building functions
+ #
+
+ # Domain transition requirements:
+ #
+ # Standard transitions a->b:
+ # allow a b:process transition;
+ # allow a b_exec:file execute;
+ # allow b b_exec:file entrypoint;
+ #
+ # and at least one of:
+ # allow a self:process setexec;
+ # type_transition a b_exec:process b;
+ #
+ # Dynamic transition x->y:
+ # allow x y:process dyntransition;
+ # allow x self:process setcurrent;
+ #
+ # Algorithm summary:
+ # 1. iterate over all rules
+ # 1. skip non allow/type_transition rules
+ # 2. if process transition or dyntransition, create edge,
+ # initialize rule lists, add the (dyn)transition rule
+ # 3. if process setexec or setcurrent, add to appropriate dict
+ # keyed on the subject
+ # 4. if file exec, entrypoint, or type_transition:process,
+ # add to appropriate dict keyed on subject,object.
+ # 2. Iterate over all graph edges:
+ # 1. if there is a transition rule (else add to invalid
+ # transition list):
+ # 1. use set intersection to find matching exec
+ # and entrypoint rules. If none, add to invalid
+ # transition list.
+ # 2. for each valid entrypoint, add rules to the
+ # edge's lists if there is either a
+ # type_transition for it or the source process
+ # has setexec permissions.
+ # 3. If there are neither type_transitions nor
+ # setexec permissions, add to the invalid
+ # transition list
+ # 2. if there is a dyntransition rule (else add to invalid
+ # dyntrans list):
+ # 1. If the source has a setcurrent rule, add it
+ # to the edge's list, else add to invalid
+ # dyntransition list.
+ # 3. Iterate over all graph edges:
+ # 1. if the edge has an invalid trans and dyntrans, delete
+ # the edge.
+ # 2. if the edge has an invalid trans, clear the related
+ # lists on the edge.
+ # 3. if the edge has an invalid dyntrans, clear the related
+ # lists on the edge.
+ #
+ def _build_graph(self):
+ self.G.clear()
+
+ self.log.info("Building graph from {0}...".format(self.policy))
+
+ # hash tables keyed on domain type
+ setexec = defaultdict(list)
+ setcurrent = defaultdict(list)
+
+ # hash tables keyed on (domain, entrypoint file type)
+ # the parameter for defaultdict has to be callable
+ # hence the lambda for the nested defaultdict
+ execute = defaultdict(lambda: defaultdict(list))
+ entrypoint = defaultdict(lambda: defaultdict(list))
+
+ # hash table keyed on (domain, entrypoint, target domain)
+ type_trans = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
+
+ for rule in self.policy.terules():
+ if rule.ruletype == "allow":
+ if rule.tclass not in ["process", "file"]:
+ continue
+
+ perms = rule.perms
+
+ if rule.tclass == "process":
+ if "transition" in perms:
+ for s, t in itertools.product(rule.source.expand(), rule.target.expand()):
+ # only add edges if they actually
+ # transition to a new type
+ if s != t:
+ edge = Edge(self.G, s, t, create=True)
+ edge.transition.append(rule)
+
+ if "dyntransition" in perms:
+ for s, t in itertools.product(rule.source.expand(), rule.target.expand()):
+ # only add edges if they actually
+ # transition to a new type
+ if s != t:
+ e = Edge(self.G, s, t, create=True)
+ e.dyntransition.append(rule)
+
+ if "setexec" in perms:
+ for s in rule.source.expand():
+ setexec[s].append(rule)
+
+ if "setcurrent" in perms:
+ for s in rule.source.expand():
+ setcurrent[s].append(rule)
+
+ else:
+ if "execute" in perms:
+ for s, t in itertools.product(
+ rule.source.expand(),
+ rule.target.expand()):
+ execute[s][t].append(rule)
+
+ if "entrypoint" in perms:
+ for s, t in itertools.product(rule.source.expand(), rule.target.expand()):
+ entrypoint[s][t].append(rule)
+
+ elif rule.ruletype == "type_transition":
+ if rule.tclass != "process":
+ continue
+
+ d = rule.default
+ for s, t in itertools.product(rule.source.expand(), rule.target.expand()):
+ type_trans[s][t][d].append(rule)
+
+ invalid_edge = []
+ clear_transition = []
+ clear_dyntransition = []
+
+ for s, t in self.G.edges_iter():
+ edge = Edge(self.G, s, t)
+ invalid_trans = False
+ invalid_dyntrans = False
+
+ if edge.transition:
+ # get matching domain exec w/entrypoint type
+ entry = set(entrypoint[t].keys())
+ exe = set(execute[s].keys())
+ match = entry.intersection(exe)
+
+ if not match:
+ # there are no valid entrypoints
+ invalid_trans = True
+ else:
+ # TODO try to improve the
+ # efficiency in this loop
+ for m in match:
+ if s in setexec or type_trans[s][m]:
+ # add key for each entrypoint
+ edge.entrypoint[m] += entrypoint[t][m]
+ edge.execute[m] += execute[s][m]
+
+ if type_trans[s][m][t]:
+ edge.type_transition[m] += type_trans[s][m][t]
+
+ if s in setexec:
+ edge.setexec.extend(setexec[s])
+
+ if not edge.setexec and not edge.type_transition:
+ invalid_trans = True
+ else:
+ invalid_trans = True
+
+ if edge.dyntransition:
+ if s in setcurrent:
+ edge.setcurrent.extend(setcurrent[s])
+ else:
+ invalid_dyntrans = True
+ else:
+ invalid_dyntrans = True
+
+ # cannot change the edges while iterating over them,
+ # so keep appropriate lists
+ if invalid_trans and invalid_dyntrans:
+ invalid_edge.append(edge)
+ elif invalid_trans:
+ clear_transition.append(edge)
+ elif invalid_dyntrans:
+ clear_dyntransition.append(edge)
+
+ # Remove invalid transitions
+ self.G.remove_edges_from(invalid_edge)
+ for edge in clear_transition:
+ # if only the regular transition is invalid,
+ # clear the relevant lists
+ del edge.transition
+ del edge.execute
+ del edge.entrypoint
+ del edge.type_transition
+ del edge.setexec
+ for edge in clear_dyntransition:
+ # if only the dynamic transition is invalid,
+ # clear the relevant lists
+ del edge.dyntransition
+ del edge.setcurrent
+
+ self.rebuildgraph = False
+ self.rebuildsubgraph = True
+ self.log.info("Completed building graph.")
+
+ def __remove_excluded_entrypoints(self):
+ invalid_edges = []
+ for source, target in self.subG.edges_iter():
+ edge = Edge(self.subG, source, target)
+ entrypoints = set(edge.entrypoint)
+ entrypoints.intersection_update(self.exclude)
+
+ if not entrypoints:
+ # short circuit if there are no
+ # excluded entrypoint types on
+ # this edge.
+ continue
+
+ for e in entrypoints:
+ # clear the entrypoint data
+ del edge.entrypoint[e]
+ del edge.execute[e]
+
+ try:
+ del edge.type_transition[e]
+ except KeyError: # setexec
+ pass
+
+ # cannot delete the edges while iterating over them
+ if not edge.entrypoint and not edge.dyntransition:
+ invalid_edges.append(edge)
+
+ self.subG.remove_edges_from(invalid_edges)
+
+ def _build_subgraph(self):
+ if self.rebuildgraph:
+ self._build_graph()
+
+ self.log.info("Building subgraph.")
+ self.log.debug("Excluding {0}".format(self.exclude))
+ self.log.debug("Reverse {0}".format(self.reverse))
+
+ # reverse graph for reverse DTA
+ if self.reverse:
+ self.subG = self.G.reverse(copy=True)
+ else:
+ self.subG = self.G.copy()
+
+ if self.exclude:
+ # delete excluded domains from subgraph
+ self.subG.remove_nodes_from(self.exclude)
+
+ # delete excluded entrypoints from subgraph
+ self.__remove_excluded_entrypoints()
+
+ self.rebuildsubgraph = False
+ self.log.info("Completed building subgraph.")
+
+
+class Edge(object):
+
+ """
+ A graph edge. Also used for returning domain transition steps.
+
+ Parameters:
+ source The source type of the edge.
+ target The target tyep of the edge.
+
+ Keyword Parameters:
+ create (T/F) create the edge if it does not exist.
+ The default is False.
+ """
+
+ transition = EdgeAttrList('transition')
+ setexec = EdgeAttrList('setexec')
+ dyntransition = EdgeAttrList('dyntransition')
+ setcurrent = EdgeAttrList('setcurrent')
+ entrypoint = EdgeAttrDict('entrypoint')
+ execute = EdgeAttrDict('execute')
+ type_transition = EdgeAttrDict('type_transition')
+
+ def __init__(self, graph, source, target, create=False):
+ self.G = graph
+ self.source = source
+ self.target = target
+
+ # a bit of a hack to make Edges work
+ # in NetworkX functions that work on
+ # 2-tuples of (source, target)
+ # (see __getitem__ below)
+ self.st_tuple = (source, target)
+
+ if not self.G.has_edge(source, target):
+ if not create:
+ raise ValueError("Edge does not exist in graph")
+ else:
+ self.G.add_edge(source, target)
+ self.transition = None
+ self.entrypoint = None
+ self.execute = None
+ self.type_transition = None
+ self.setexec = None
+ self.dyntransition = None
+ self.setcurrent = None
+
+ def __getitem__(self, key):
+ return self.st_tuple[key]
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/exception.py b/lib/python2.7/site-packages/setoolsgui/setools/exception.py
new file mode 100644
index 0000000..c3505cd
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/exception.py
@@ -0,0 +1,62 @@
+# 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/>.
+#
+
+#
+# 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 PermissionMapParseError(PermissionMapException):
+
+ """Exception for parse errors while reading permission map files."""
+ 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/lib/python2.7/site-packages/setoolsgui/setools/fsusequery.py b/lib/python2.7/site-packages/setoolsgui/setools/fsusequery.py
new file mode 100644
index 0000000..6825a45
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/fsusequery.py
@@ -0,0 +1,87 @@
+# Copyright 2014-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 logging
+import re
+
+from . import contextquery
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
+
+
+class FSUseQuery(contextquery.ContextQuery):
+
+ """
+ Query fs_use_* statements.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ ruletype The rule type(s) to match.
+ fs The criteria to match the file system type.
+ fs_regex If true, regular expression matching
+ will be used on the file system type.
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ ruletype = None
+ fs = CriteriaDescriptor("fs_regex")
+ fs_regex = False
+
+ def results(self):
+ """Generator which yields all matching fs_use_* statements."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ruletypes: {0.ruletype}".format(self))
+ self.log.debug("FS: {0.fs!r}, regex: {0.fs_regex}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for fsu in self.policy.fs_uses():
+ if self.ruletype and fsu.ruletype not in self.ruletype:
+ continue
+
+ if self.fs and not self._match_regex(
+ fsu.fs,
+ self.fs,
+ self.fs_regex):
+ continue
+
+ if not self._match_context(fsu.context):
+ continue
+
+ yield fsu
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/genfsconquery.py b/lib/python2.7/site-packages/setoolsgui/setools/genfsconquery.py
new file mode 100644
index 0000000..c67dfd6
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/genfsconquery.py
@@ -0,0 +1,98 @@
+# Copyright 2014-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 logging
+import re
+
+from . import contextquery
+from .descriptors import CriteriaDescriptor
+
+
+class GenfsconQuery(contextquery.ContextQuery):
+
+ """
+ Query genfscon statements.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ fs The criteria to match the file system type.
+ fs_regex If true, regular expression matching
+ will be used on the file system type.
+ path The criteria to match the path.
+ path_regex If true, regular expression matching
+ will be used on the path.
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ filetype = None
+ fs = CriteriaDescriptor("fs_regex")
+ fs_regex = False
+ path = CriteriaDescriptor("path_regex")
+ path_regex = False
+
+ def results(self):
+ """Generator which yields all matching genfscons."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("FS: {0.fs!r}, regex: {0.fs_regex}".format(self))
+ self.log.debug("Path: {0.path!r}, regex: {0.path_regex}".format(self))
+ self.log.debug("Filetype: {0.filetype!r}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for genfs in self.policy.genfscons():
+ if self.fs and not self._match_regex(
+ genfs.fs,
+ self.fs,
+ self.fs_regex):
+ continue
+
+ if self.path and not self._match_regex(
+ genfs.path,
+ self.path,
+ self.path_regex):
+ continue
+
+ if self.filetype and not self.filetype == genfs.filetype:
+ continue
+
+ if not self._match_context(genfs.context):
+ continue
+
+ yield genfs
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/infoflow.py b/lib/python2.7/site-packages/setoolsgui/setools/infoflow.py
new file mode 100644
index 0000000..ea3ec32
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/infoflow.py
@@ -0,0 +1,403 @@
+# Copyright 2014-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 itertools
+import logging
+from collections import namedtuple
+
+import networkx as nx
+from networkx.exception import NetworkXError, NetworkXNoPath
+
+from .descriptors import EdgeAttrIntMax, EdgeAttrList
+
+__all__ = ['InfoFlowAnalysis']
+
+# Return values for the analysis
+# are in the following tuple format:
+step_output = namedtuple("step", ["source",
+ "target",
+ "rules"])
+
+
+class InfoFlowAnalysis(object):
+
+ """Information flow analysis."""
+
+ def __init__(self, policy, perm_map, min_weight=1, exclude=None):
+ """
+ Parameters:
+ policy The policy to analyze.
+ perm_map The permission map or path to the permission map file.
+ minweight The minimum permission weight to include in the analysis.
+ (default is 1)
+ exclude The types excluded from the information flow analysis.
+ (default is none)
+ """
+ self.log = logging.getLogger(self.__class__.__name__)
+
+ self.policy = policy
+
+ self.min_weight = min_weight
+ self.perm_map = perm_map
+ self.exclude = exclude
+ self.rebuildgraph = True
+ self.rebuildsubgraph = True
+
+ self.G = nx.DiGraph()
+ self.subG = None
+
+ @property
+ def min_weight(self):
+ return self._min_weight
+
+ @min_weight.setter
+ def min_weight(self, weight):
+ if not 1 <= weight <= 10:
+ raise ValueError(
+ "Min information flow weight must be an integer 1-10.")
+
+ self._min_weight = weight
+ self.rebuildsubgraph = True
+
+ @property
+ def perm_map(self):
+ return self._perm_map
+
+ @perm_map.setter
+ def perm_map(self, perm_map):
+ self._perm_map = perm_map
+ self.rebuildgraph = True
+ self.rebuildsubgraph = True
+
+ @property
+ def exclude(self):
+ return self._exclude
+
+ @exclude.setter
+ def exclude(self, types):
+ if types:
+ self._exclude = [self.policy.lookup_type(t) for t in types]
+ else:
+ self._exclude = []
+
+ self.rebuildsubgraph = True
+
+ def shortest_path(self, source, target):
+ """
+ Generator which yields one shortest path between the source
+ and target types (there may be more).
+
+ Parameters:
+ source The source type.
+ target The target type.
+
+ Yield: generator(steps)
+
+ steps Yield: tuple(source, target, rules)
+
+ source The source type for this step of the information flow.
+ target The target type for this step of the information flow.
+ rules The list of rules creating this information flow step.
+ """
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating one shortest path from {0} to {1}...".format(s, t))
+
+ try:
+ yield self.__generate_steps(nx.shortest_path(self.subG, s, t))
+ except (NetworkXNoPath, NetworkXError):
+ # NetworkXError: the type is valid but not in graph, e.g.
+ # excluded or disconnected due to min weight
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ pass
+
+ def all_paths(self, source, target, maxlen=2):
+ """
+ Generator which yields all paths between the source and target
+ up to the specified maximum path length. This algorithm
+ tends to get very expensive above 3-5 steps, depending
+ on the policy complexity.
+
+ Parameters:
+ source The source type.
+ target The target type.
+ maxlen Maximum length of paths.
+
+ Yield: generator(steps)
+
+ steps Yield: tuple(source, target, rules)
+
+ source The source type for this step of the information flow.
+ target The target type for this step of the information flow.
+ rules The list of rules creating this information flow step.
+ """
+ if maxlen < 1:
+ raise ValueError("Maximum path length must be positive.")
+
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all paths from {0} to {1}, max len {2}...".format(s, t, maxlen))
+
+ try:
+ for path in nx.all_simple_paths(self.subG, s, t, maxlen):
+ yield self.__generate_steps(path)
+ except (NetworkXNoPath, NetworkXError):
+ # NetworkXError: the type is valid but not in graph, e.g.
+ # excluded or disconnected due to min weight
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ pass
+
+ def all_shortest_paths(self, source, target):
+ """
+ Generator which yields all shortest paths between the source
+ and target types.
+
+ Parameters:
+ source The source type.
+ target The target type.
+
+ Yield: generator(steps)
+
+ steps Yield: tuple(source, target, rules)
+
+ source The source type for this step of the information flow.
+ target The target type for this step of the information flow.
+ rules The list of rules creating this information flow step.
+ """
+ s = self.policy.lookup_type(source)
+ t = self.policy.lookup_type(target)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all shortest paths from {0} to {1}...".format(s, t))
+
+ try:
+ for path in nx.all_shortest_paths(self.subG, s, t):
+ yield self.__generate_steps(path)
+ except (NetworkXNoPath, NetworkXError, KeyError):
+ # NetworkXError: the type is valid but not in graph, e.g.
+ # excluded or disconnected due to min weight
+ # NetworkXNoPath: no paths or the target type is
+ # not in the graph
+ # KeyError: work around NetworkX bug
+ # when the source node is not in the graph
+ pass
+
+ def infoflows(self, type_, out=True):
+ """
+ Generator which yields all information flows in/out of a
+ specified source type.
+
+ Parameters:
+ source The starting type.
+
+ Keyword Parameters:
+ out If true, information flows out of the type will
+ be returned. If false, information flows in to the
+ type will be returned. Default is true.
+
+ Yield: generator(steps)
+
+ steps A generator that returns the tuple of
+ source, target, and rules for each
+ information flow.
+ """
+ s = self.policy.lookup_type(type_)
+
+ if self.rebuildsubgraph:
+ self._build_subgraph()
+
+ self.log.info("Generating all infoflows out of {0}...".format(s))
+
+ if out:
+ flows = self.subG.out_edges_iter(s)
+ else:
+ flows = self.subG.in_edges_iter(s)
+
+ try:
+ for source, target in flows:
+ edge = Edge(self.subG, source, target)
+ yield step_output(source, target, edge.rules)
+ except NetworkXError:
+ # NetworkXError: the type is valid but not in graph, e.g.
+ # excluded or disconnected due to min weight
+ pass
+
+ def get_stats(self): # pragma: no cover
+ """
+ Get the information flow graph statistics.
+
+ Return: tuple(nodes, edges)
+
+ nodes The number of nodes (types) in the graph.
+ edges The number of edges (information flows between types)
+ in the graph.
+ """
+ return (self.G.number_of_nodes(), self.G.number_of_edges())
+
+ #
+ # Internal functions follow
+ #
+
+ def __generate_steps(self, path):
+ """
+ Generator which returns the source, target, and associated rules
+ for each information flow step.
+
+ Parameter:
+ path A list of graph node names representing an information flow path.
+
+ Yield: tuple(source, target, rules)
+
+ source The source type for this step of the information flow.
+ target The target type for this step of the information flow.
+ rules The list of rules creating this information flow step.
+ """
+ for s in range(1, len(path)):
+ edge = Edge(self.subG, path[s - 1], path[s])
+ yield step_output(edge.source, edge.target, edge.rules)
+
+ #
+ #
+ # Graph building functions
+ #
+ #
+ # 1. _build_graph determines the flow in each direction for each TE
+ # rule and then expands the rule. All information flows are
+ # included in this main graph: memory is traded off for efficiency
+ # as the main graph should only need to be rebuilt if permission
+ # weights change.
+ # 2. _build_subgraph derives a subgraph which removes all excluded
+ # types (nodes) and edges (information flows) which are below the
+ # minimum weight. This subgraph is rebuilt only if the main graph
+ # is rebuilt or the minimum weight or excluded types change.
+
+ def _build_graph(self):
+ self.G.clear()
+
+ self.perm_map.map_policy(self.policy)
+
+ self.log.info("Building graph from {0}...".format(self.policy))
+
+ for rule in self.policy.terules():
+ if rule.ruletype != "allow":
+ continue
+
+ (rweight, wweight) = self.perm_map.rule_weight(rule)
+
+ for s, t in itertools.product(rule.source.expand(), rule.target.expand()):
+ # only add flows if they actually flow
+ # in or out of the source type type
+ if s != t:
+ if wweight:
+ edge = Edge(self.G, s, t, create=True)
+ edge.rules.append(rule)
+ edge.weight = wweight
+
+ if rweight:
+ edge = Edge(self.G, t, s, create=True)
+ edge.rules.append(rule)
+ edge.weight = rweight
+
+ self.rebuildgraph = False
+ self.rebuildsubgraph = True
+ self.log.info("Completed building graph.")
+
+ def _build_subgraph(self):
+ if self.rebuildgraph:
+ self._build_graph()
+
+ self.log.info("Building subgraph...")
+ self.log.debug("Excluding {0!r}".format(self.exclude))
+ self.log.debug("Min weight {0}".format(self.min_weight))
+
+ # delete excluded types from subgraph
+ nodes = [n for n in self.G.nodes() if n not in self.exclude]
+ self.subG = self.G.subgraph(nodes)
+
+ # delete edges below minimum weight.
+ # no need if weight is 1, since that
+ # does not exclude any edges.
+ if self.min_weight > 1:
+ delete_list = []
+ for s, t in self.subG.edges_iter():
+ edge = Edge(self.subG, s, t)
+ if edge.weight < self.min_weight:
+ delete_list.append(edge)
+
+ self.subG.remove_edges_from(delete_list)
+
+ self.rebuildsubgraph = False
+ self.log.info("Completed building subgraph.")
+
+
+class Edge(object):
+
+ """
+ A graph edge. Also used for returning information flow steps.
+
+ Parameters:
+ source The source type of the edge.
+ target The target type of the edge.
+
+ Keyword Parameters:
+ create (T/F) create the edge if it does not exist.
+ The default is False.
+ """
+
+ rules = EdgeAttrList('rules')
+
+ # use capacity to store the info flow weight so
+ # we can use network flow algorithms naturally.
+ # The weight for each edge is 1 since each info
+ # flow step is no more costly than another
+ # (see below add_edge() call)
+ weight = EdgeAttrIntMax('capacity')
+
+ def __init__(self, graph, source, target, create=False):
+ self.G = graph
+ self.source = source
+ self.target = target
+
+ # a bit of a hack to make edges work
+ # in NetworkX functions that work on
+ # 2-tuples of (source, target)
+ # (see __getitem__ below)
+ self.st_tuple = (source, target)
+
+ if not self.G.has_edge(source, target):
+ if create:
+ self.G.add_edge(source, target, weight=1)
+ self.rules = None
+ self.weight = None
+ else:
+ raise ValueError("Edge does not exist in graph")
+
+ def __getitem__(self, key):
+ return self.st_tuple[key]
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/initsidquery.py b/lib/python2.7/site-packages/setoolsgui/setools/initsidquery.py
new file mode 100644
index 0000000..1eb3790
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/initsidquery.py
@@ -0,0 +1,74 @@
+# Copyright 2014-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 logging
+
+from . import compquery
+from . import contextquery
+
+
+class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
+
+ """
+ Initial SID (Initial context) query.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The Initial SID name to match.
+ name_regex If true, regular expression matching
+ will be used on the Initial SID name.
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ def results(self):
+ """Generator which yields all matching initial SIDs."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for i in self.policy.initialsids():
+ if not self._match_name(i):
+ continue
+
+ if not self._match_context(i.context):
+ continue
+
+ yield i
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/mixins.py b/lib/python2.7/site-packages/setoolsgui/setools/mixins.py
new file mode 100644
index 0000000..a31d420
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/mixins.py
@@ -0,0 +1,91 @@
+# 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/>.
+#
+# pylint: disable=attribute-defined-outside-init,no-member
+import re
+
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
+
+
+class MatchAlias(object):
+
+ """Mixin for matching an object's aliases."""
+
+ alias = CriteriaDescriptor("alias_regex")
+ alias_regex = False
+
+ def _match_alias(self, obj):
+ """
+ Match the alias criteria
+
+ Parameter:
+ obj An object with an alias generator method named "aliases"
+ """
+
+ if not self.alias:
+ # if there is no criteria, everything matches.
+ return True
+
+ return self._match_in_set(obj.aliases(), self.alias, self.alias_regex)
+
+
+class MatchObjClass(object):
+
+ """Mixin for matching an object's class."""
+
+ tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class")
+ tclass_regex = False
+
+ def _match_object_class(self, obj):
+ """
+ Match the object class criteria
+
+ Parameter:
+ obj An object with an object class attribute named "tclass"
+ """
+
+ if not self.tclass:
+ # if there is no criteria, everything matches.
+ return True
+ elif self.tclass_regex:
+ return bool(self.tclass.search(str(obj.tclass)))
+ else:
+ return obj.tclass in self.tclass
+
+
+class MatchPermission(object):
+
+ """Mixin for matching an object's permissions."""
+
+ perms = CriteriaSetDescriptor("perms_regex")
+ perms_equal = False
+ perms_regex = False
+
+ def _match_perms(self, obj):
+ """
+ Match the permission criteria
+
+ Parameter:
+ obj An object with a permission set class attribute named "perms"
+ """
+
+ if not self.perms:
+ # if there is no criteria, everything matches.
+ return True
+
+ return self._match_regex_or_set(obj.perms, self.perms, self.perms_equal, self.perms_regex)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/mlsrulequery.py b/lib/python2.7/site-packages/setoolsgui/setools/mlsrulequery.py
new file mode 100644
index 0000000..3a9e1bf
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/mlsrulequery.py
@@ -0,0 +1,115 @@
+# Copyright 2014-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 logging
+
+from . import mixins, query
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor
+
+
+class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
+
+ """
+ Query MLS rules.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ ruletype The list of rule type(s) to match.
+ source The name of the source type/attribute to match.
+ source_regex If true, regular expression matching will
+ be used on the source type/attribute.
+ target The name of the target type/attribute to match.
+ target_regex If true, regular expression matching will
+ be used on the target type/attribute.
+ tclass The object class(es) to match.
+ tclass_regex If true, use a regular expression for
+ matching the rule's object class.
+ """
+
+ ruletype = RuletypeDescriptor("validate_mls_ruletype")
+ source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
+ source_regex = False
+ target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
+ target_regex = False
+ tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class")
+ tclass_regex = False
+ default = CriteriaDescriptor(lookup_function="lookup_range")
+ default_overlap = False
+ default_subset = False
+ default_superset = False
+ default_proper = False
+
+ def results(self):
+ """Generator which yields all matching MLS rules."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ruletypes: {0.ruletype}".format(self))
+ self.log.debug("Source: {0.source!r}, regex: {0.source_regex}".format(self))
+ self.log.debug("Target: {0.target!r}, regex: {0.target_regex}".format(self))
+ self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
+ self.log.debug("Default: {0.default!r}, overlap: {0.default_overlap}, "
+ "subset: {0.default_subset}, superset: {0.default_superset}, "
+ "proper: {0.default_proper}".format(self))
+
+ for rule in self.policy.mlsrules():
+ #
+ # Matching on rule type
+ #
+ if self.ruletype:
+ if rule.ruletype not in self.ruletype:
+ continue
+
+ #
+ # Matching on source type
+ #
+ if self.source and not self._match_regex(
+ rule.source,
+ self.source,
+ self.source_regex):
+ continue
+
+ #
+ # Matching on target type
+ #
+ if self.target and not self._match_regex(
+ rule.target,
+ self.target,
+ self.target_regex):
+ continue
+
+ #
+ # Matching on object class
+ #
+ if not self._match_object_class(rule):
+ continue
+
+ #
+ # Matching on range
+ #
+ if self.default and not self._match_range(
+ rule.default,
+ self.default,
+ self.default_subset,
+ self.default_overlap,
+ self.default_superset,
+ self.default_proper):
+ continue
+
+ # if we get here, we have matched all available criteria
+ yield rule
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/netifconquery.py b/lib/python2.7/site-packages/setoolsgui/setools/netifconquery.py
new file mode 100644
index 0000000..30db977
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/netifconquery.py
@@ -0,0 +1,77 @@
+# Copyright 2014-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 logging
+
+from . import compquery
+from . import contextquery
+
+
+class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
+
+ """
+ Network interface context query.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the network interface to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ def results(self):
+ """Generator which yields all matching netifcons."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for netif in self.policy.netifcons():
+ if self.name and not self._match_regex(
+ netif.netif,
+ self.name,
+ self.name_regex):
+ continue
+
+ if not self._match_context(netif.context):
+ continue
+
+ yield netif
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/nodeconquery.py b/lib/python2.7/site-packages/setoolsgui/setools/nodeconquery.py
new file mode 100644
index 0000000..eb21d81
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/nodeconquery.py
@@ -0,0 +1,148 @@
+# Copyright 2014-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/>.
+#
+try:
+ import ipaddress
+except ImportError: # pragma: no cover
+ pass
+
+import logging
+from socket import AF_INET, AF_INET6
+
+from . import contextquery
+
+
+class NodeconQuery(contextquery.ContextQuery):
+
+ """
+ Query nodecon statements.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ network The IPv4/IPv6 address or IPv4/IPv6 network address
+ with netmask, e.g. 192.168.1.0/255.255.255.0 or
+ "192.168.1.0/24".
+ network_overlap If true, the net will match if it overlaps with
+ the nodecon's network instead of equality.
+ ip_version The IP version of the nodecon to match. (socket.AF_INET
+ for IPv4 or socket.AF_INET6 for IPv6)
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ _network = None
+ network_overlap = False
+ _ip_version = None
+
+ @property
+ def ip_version(self):
+ return self._ip_version
+
+ @ip_version.setter
+ def ip_version(self, value):
+ if value:
+ if not (value == AF_INET or value == AF_INET6):
+ raise ValueError(
+ "The address family must be {0} for IPv4 or {1} for IPv6.".
+ format(AF_INET, AF_INET6))
+
+ self._ip_version = value
+ else:
+ self._ip_version = None
+
+ @property
+ def network(self):
+ return self._network
+
+ @network.setter
+ def network(self, value):
+ if value:
+ try:
+ self._network = ipaddress.ip_network(value)
+ except NameError: # pragma: no cover
+ raise RuntimeError("Nodecon IP address/network functions require Python 3.3+.")
+ else:
+ self._network = None
+
+ def results(self):
+ """Generator which yields all matching nodecons."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Network: {0.network!r}, overlap: {0.network_overlap}".format(self))
+ self.log.debug("IP Version: {0.ip_version}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for nodecon in self.policy.nodecons():
+
+ if self.network:
+ try:
+ netmask = ipaddress.ip_address(nodecon.netmask)
+ except NameError: # pragma: no cover
+ # Should never actually hit this since the self.network
+ # setter raises the same exception.
+ raise RuntimeError("Nodecon IP address/network functions require Python 3.3+.")
+
+ # Python 3.3's IPv6Network constructor does not support
+ # expanded netmasks, only CIDR numbers. Convert netmask
+ # into CIDR.
+ # This is Brian Kernighan's method for counting set bits.
+ # If the netmask happens to be invalid, this will
+ # not detect it.
+ CIDR = 0
+ int_netmask = int(netmask)
+ while int_netmask:
+ int_netmask &= int_netmask - 1
+ CIDR += 1
+
+ net = ipaddress.ip_network('{0}/{1}'.format(nodecon.address, CIDR))
+
+ if self.network_overlap:
+ if not self.network.overlaps(net):
+ continue
+ else:
+ if not net == self.network:
+ continue
+
+ if self.ip_version and self.ip_version != nodecon.ip_version:
+ continue
+
+ if not self._match_context(nodecon.context):
+ continue
+
+ yield nodecon
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/objclassquery.py b/lib/python2.7/site-packages/setoolsgui/setools/objclassquery.py
new file mode 100644
index 0000000..8f40df8
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/objclassquery.py
@@ -0,0 +1,101 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
+from .policyrep.exception import NoCommon
+
+
+class ObjClassQuery(compquery.ComponentQuery):
+
+ """
+ Query object classes.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the object set to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ common The name of the inherited common to match.
+ common_regex If true, regular expression matching will
+ be used for matching the common name.
+ perms The permissions to match.
+ perms_equal If true, only commons with permission sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ perms_regex If true, regular expression matching
+ will be used on the permission names instead
+ of set logic.
+ comparison will not be used.
+ perms_indirect If false, permissions inherited from a common
+ permission set not will be evaluated. Default
+ is true.
+ """
+
+ common = CriteriaDescriptor("common_regex", "lookup_common")
+ common_regex = False
+ perms = CriteriaSetDescriptor("perms_regex")
+ perms_equal = False
+ perms_indirect = True
+ perms_regex = False
+
+ def results(self):
+ """Generator which yields all matching object classes."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Common: {0.common!r}, regex: {0.common_regex}".format(self))
+ self.log.debug("Perms: {0.perms}, regex: {0.perms_regex}, "
+ "eq: {0.perms_equal}, indirect: {0.perms_indirect}".format(self))
+
+ for class_ in self.policy.classes():
+ if not self._match_name(class_):
+ continue
+
+ if self.common:
+ try:
+ if not self._match_regex(
+ class_.common,
+ self.common,
+ self.common_regex):
+ continue
+ except NoCommon:
+ continue
+
+ if self.perms:
+ perms = class_.perms
+
+ if self.perms_indirect:
+ try:
+ perms |= class_.common.perms
+ except NoCommon:
+ pass
+
+ if not self._match_regex_or_set(
+ perms,
+ self.perms,
+ self.perms_equal,
+ self.perms_regex):
+ continue
+
+ yield class_
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/permmap.py b/lib/python2.7/site-packages/setoolsgui/setools/permmap.py
new file mode 100644
index 0000000..54cd9f9
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/permmap.py
@@ -0,0 +1,363 @@
+# Copyright 2014-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 sys
+import logging
+from errno import ENOENT
+
+from . import exception
+from . import policyrep
+
+
+class PermissionMap(object):
+
+ """Permission Map for information flow analysis."""
+
+ valid_infoflow_directions = ["r", "w", "b", "n", "u"]
+ min_weight = 1
+ max_weight = 10
+
+ def __init__(self, permmapfile=None):
+ """
+ Parameter:
+ permmapfile The path to the permission map to load.
+ """
+ self.log = logging.getLogger(self.__class__.__name__)
+
+ if permmapfile:
+ self.load(permmapfile)
+ else:
+ for path in ["data/", sys.prefix + "/share/setools/"]:
+ try:
+ self.load(path + "perm_map")
+ break
+ except (IOError, OSError) as err:
+ if err.errno != ENOENT:
+ raise
+ else:
+ raise RuntimeError("Unable to load default permission map.")
+
+ def load(self, permmapfile):
+ """
+ Parameter:
+ permmapfile The path to the permission map to load.
+ """
+ self.log.info("Opening permission map \"{0}\"".format(permmapfile))
+
+ # state machine
+ # 1 = read number of classes
+ # 2 = read class name and number of perms
+ # 3 = read perms
+ with open(permmapfile, "r") as mapfile:
+ class_count = 0
+ num_classes = 0
+ state = 1
+
+ self.permmap = dict()
+
+ for line_num, line in enumerate(mapfile, start=1):
+ entry = line.split()
+
+ if len(entry) == 0 or entry[0][0] == '#':
+ continue
+
+ if state == 1:
+ try:
+ num_classes = int(entry[0])
+ except ValueError:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Invalid number of classes: {2}".
+ format(permmapfile, line_num, entry[0]))
+
+ if num_classes < 1:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Number of classes must be positive: {2}".
+ format(permmapfile, line_num, entry[0]))
+
+ state = 2
+
+ elif state == 2:
+ if len(entry) != 3 or entry[0] != "class":
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Invalid class declaration: {2}".
+ format(permmapfile, line_num, entry))
+
+ class_name = str(entry[1])
+
+ try:
+ num_perms = int(entry[2])
+ except ValueError:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Invalid number of permissions: {2}".
+ format(permmapfile, line_num, entry[2]))
+
+ if num_perms < 1:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Number of permissions must be positive: {2}".
+ format(permmapfile, line_num, entry[2]))
+
+ class_count += 1
+ if class_count > num_classes:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Extra class found: {2}".
+ format(permmapfile, line_num, class_name))
+
+ self.permmap[class_name] = dict()
+ perm_count = 0
+ state = 3
+
+ elif state == 3:
+ perm_name = str(entry[0])
+
+ flow_direction = str(entry[1])
+ if flow_direction not in self.valid_infoflow_directions:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Invalid information flow direction: {2}".
+ format(permmapfile, line_num, entry[1]))
+
+ try:
+ weight = int(entry[2])
+ except ValueError:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Invalid permission weight: {2}".
+ format(permmapfile, line_num, entry[2]))
+
+ if not self.min_weight <= weight <= self.max_weight:
+ raise exception.PermissionMapParseError(
+ "{0}:{1}:Permission weight must be {3}-{4}: {2}".
+ format(permmapfile, line_num, entry[2],
+ self.min_weight, self.max_weight))
+
+ self.permmap[class_name][perm_name] = {'direction': flow_direction,
+ 'weight': weight,
+ 'enabled': True}
+
+ perm_count += 1
+ if perm_count >= num_perms:
+ state = 2
+
+ def exclude_class(self, class_):
+ """
+ Exclude all permissions in an object class for calculating rule weights.
+
+ Parameter:
+ class_ The object class to exclude.
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ """
+
+ classname = str(class_)
+
+ try:
+ for perm in self.permmap[classname]:
+ self.permmap[classname][perm]['enabled'] = False
+ except KeyError:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ def exclude_permission(self, class_, permission):
+ """
+ Exclude a permission for calculating rule weights.
+
+ Parameter:
+ class_ The object class of the permission.
+ permission The permission name to exclude.
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ UnmappedPermission The specified permission is not mapped for the object class.
+ """
+ classname = str(class_)
+
+ if classname not in self.permmap:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ try:
+ self.permmap[classname][permission]['enabled'] = False
+ except KeyError:
+ raise exception.UnmappedPermission("{0}:{1} is not mapped.".
+ format(classname, permission))
+
+ def include_class(self, class_):
+ """
+ Include all permissions in an object class for calculating rule weights.
+
+ Parameter:
+ class_ The object class to include.
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ """
+
+ classname = str(class_)
+
+ try:
+ for perm in self.permmap[classname]:
+ self.permmap[classname][perm]['enabled'] = True
+ except KeyError:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ def include_permission(self, class_, permission):
+ """
+ Include a permission for calculating rule weights.
+
+ Parameter:
+ class_ The object class of the permission.
+ permission The permission name to include.
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ UnmappedPermission The specified permission is not mapped for the object class.
+ """
+
+ classname = str(class_)
+
+ if classname not in self.permmap:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ try:
+ self.permmap[classname][permission]['enabled'] = True
+ except KeyError:
+ 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."""
+ for class_ in policy.classes():
+ class_name = str(class_)
+
+ if class_name not in self.permmap:
+ self.log.info("Adding unmapped class {0} from {1}".format(class_name, policy))
+ self.permmap[class_name] = dict()
+
+ perms = class_.perms
+
+ try:
+ perms |= class_.common.perms
+ except policyrep.exception.NoCommon:
+ pass
+
+ for perm_name in perms:
+ if perm_name not in self.permmap[class_name]:
+ self.log.info("Adding unmapped permission {0} in {1} from {2}".
+ format(perm_name, class_name, policy))
+ self.permmap[class_name][perm_name] = {'direction': 'u',
+ 'weight': 1,
+ 'enabled': True}
+
+ def rule_weight(self, rule):
+ """
+ Get the type enforcement rule's information flow read and write weights.
+
+ Parameter:
+ rule A type enforcement rule.
+
+ Return: Tuple(read_weight, write_weight)
+ read_weight The type enforcement rule's read weight.
+ write_weight The type enforcement rule's write weight.
+ """
+
+ write_weight = 0
+ read_weight = 0
+ class_name = str(rule.tclass)
+
+ if rule.ruletype != 'allow':
+ raise exception.RuleTypeError("{0} rules cannot be used for calculating a weight".
+ format(rule.ruletype))
+
+ if class_name not in self.permmap:
+ 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
+ # is the largest-weight permission in each direction
+ for perm_name in rule.perms:
+ try:
+ mapping = self.permmap[class_name][perm_name]
+ except KeyError:
+ raise exception.UnmappedPermission("{0}:{1} is not mapped.".
+ format(class_name, perm_name))
+
+ if not mapping['enabled']:
+ continue
+
+ if mapping['direction'] == "r":
+ read_weight = max(read_weight, mapping['weight'])
+ elif mapping['direction'] == "w":
+ write_weight = max(write_weight, mapping['weight'])
+ elif mapping['direction'] == "b":
+ read_weight = max(read_weight, mapping['weight'])
+ write_weight = max(write_weight, mapping['weight'])
+
+ return (read_weight, write_weight)
+
+ def set_direction(self, class_, permission, direction):
+ """
+ Set the information flow direction of a permission.
+
+ Parameter:
+ class_ The object class of the permission.
+ permission The permission name.
+ direction The information flow direction the permission (r/w/b/n).
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ UnmappedPermission The specified permission is not mapped for the object class.
+ """
+
+ if direction not in self.valid_infoflow_directions:
+ raise ValueError("Invalid information flow direction: {0}".format(direction))
+
+ classname = str(class_)
+
+ if classname not in self.permmap:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ try:
+ self.permmap[classname][permission]['direction'] = direction
+ except KeyError:
+ raise exception.UnmappedPermission("{0}:{1} is not mapped.".
+ format(classname, permission))
+
+ def set_weight(self, class_, permission, weight):
+ """
+ Set the weight of a permission.
+
+ Parameter:
+ class_ The object class of the permission.
+ permission The permission name.
+ weight The weight of the permission (1-10).
+
+ Exceptions:
+ UnmappedClass The specified object class is not mapped.
+ UnmappedPermission The specified permission is not mapped for the object class.
+ """
+
+ if not self.min_weight <= weight <= self.max_weight:
+ raise ValueError("Permission weights must be 1-10: {0}".format(weight))
+
+ classname = str(class_)
+
+ if classname not in self.permmap:
+ raise exception.UnmappedClass("{0} is not mapped.".format(classname))
+
+ try:
+ self.permmap[classname][permission]['weight'] = weight
+ except KeyError:
+ raise exception.UnmappedPermission("{0}:{1} is not mapped.".
+ format(classname, permission))
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/polcapquery.py b/lib/python2.7/site-packages/setoolsgui/setools/polcapquery.py
new file mode 100644
index 0000000..e024b05
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/polcapquery.py
@@ -0,0 +1,47 @@
+# Copyright 2014-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 logging
+
+from . import compquery
+
+
+class PolCapQuery(compquery.ComponentQuery):
+
+ """
+ Query SELinux policy capabilities
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the policy capability to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ """
+
+ def results(self):
+ """Generator which yields all matching policy capabilities."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+
+ for cap in self.policy.polcaps():
+ if not self._match_name(cap):
+ continue
+
+ yield cap
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/__init__.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/__init__.py
new file mode 100644
index 0000000..b03e524
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/__init__.py
@@ -0,0 +1,568 @@
+# Copyright 2014-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/>.
+#
+# pylint: disable=too-many-public-methods
+#
+# Create a Python representation of the policy.
+# The idea is that this is module provides convenient
+# abstractions and methods for accessing the policy
+# structures.
+import logging
+from itertools import chain
+from errno import ENOENT
+
+try:
+ import selinux
+except ImportError:
+ pass
+
+from . import qpol
+
+# The libqpol SWIG class is not quite natural for
+# Python the policy is repeatedly referenced in the
+# function calls, which makes sense for C code
+# but not for python code, so each object keeps
+# a reference to the policy for internal use.
+# 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
+from . import mls
+from . import objclass
+from . import polcap
+from . import role
+from . import typeattr
+from . import user
+
+# Rules
+from . import mlsrule
+from . import rbacrule
+from . import terule
+
+# Constraints
+from . import constraint
+
+# In-policy Labeling
+from . import fscontext
+from . import initsid
+from . import netcontext
+
+
+class SELinuxPolicy(object):
+
+ """The complete SELinux policy."""
+
+ def __init__(self, policyfile=None):
+ """
+ Parameter:
+ policyfile Path to a policy to open.
+ """
+
+ self.log = logging.getLogger(self.__class__.__name__)
+ self.policy = None
+ self.filename = None
+
+ if policyfile:
+ self._load_policy(policyfile)
+ else:
+ try:
+ self._load_running_policy()
+ except NameError:
+ raise RuntimeError("Loading the running policy requires libselinux Python bindings")
+
+ def __repr__(self):
+ return "<SELinuxPolicy(\"{0}\")>".format(self.filename)
+
+ def __str__(self):
+ return self.filename
+
+ def __deepcopy__(self, memo):
+ # shallow copy as all of the members are immutable
+ newobj = SELinuxPolicy.__new__(SELinuxPolicy)
+ newobj.policy = self.policy
+ newobj.filename = self.filename
+ memo[id(self)] = newobj
+ return newobj
+
+ #
+ # Policy loading functions
+ #
+
+ def _load_policy(self, filename):
+ """Load the specified policy."""
+ self.log.info("Opening SELinux policy \"{0}\"".format(filename))
+
+ try:
+ self.policy = qpol.qpol_policy_factory(str(filename))
+ except SyntaxError as err:
+ raise exception.InvalidPolicy("Error opening policy file \"{0}\": {1}".
+ format(filename, err))
+
+ self.log.info("Successfully opened SELinux policy \"{0}\"".format(filename))
+ self.filename = filename
+
+ @staticmethod
+ def _potential_policies():
+ """Generate a list of potential policies to use."""
+ # Start with binary policies in the standard location
+ base_policy_path = selinux.selinux_binary_policy_path()
+ for version in range(qpol.QPOL_POLICY_MAX_VERSION, qpol.QPOL_POLICY_MIN_VERSION-1, -1):
+ yield "{0}.{1}".format(base_policy_path, version)
+
+ # Last chance, try selinuxfs. This is not first, to avoid
+ # holding kernel memory for a long time
+ if selinux.selinuxfs_exists():
+ yield selinux.selinux_current_policy_path()
+
+ def _load_running_policy(self):
+ """Try to load the current running policy."""
+ self.log.info("Attempting to locate current running policy.")
+
+ for filename in self._potential_policies():
+ try:
+ self._load_policy(filename)
+ except OSError as err:
+ if err.errno != ENOENT:
+ raise
+ else:
+ break
+ else:
+ raise RuntimeError("Unable to locate an SELinux policy to load.")
+
+ #
+ # Policy properties
+ #
+ @property
+ def handle_unknown(self):
+ """The handle unknown permissions setting (allow,deny,reject)"""
+ return self.policy.handle_unknown()
+
+ @property
+ def mls(self):
+ """(T/F) The policy has MLS enabled."""
+ return mls.enabled(self.policy)
+
+ @property
+ def version(self):
+ """The policy database version (e.g. v29)"""
+ return self.policy.version()
+
+ #
+ # Policy statistics
+ #
+
+ @property
+ def allow_count(self):
+ """The number of (type) allow rules."""
+ return self.policy.avrule_allow_count()
+
+ @property
+ def auditallow_count(self):
+ """The number of auditallow rules."""
+ return self.policy.avrule_auditallow_count()
+
+ @property
+ def boolean_count(self):
+ """The number of Booleans."""
+ return self.policy.bool_count()
+
+ @property
+ def category_count(self):
+ """The number of categories."""
+ return sum(1 for _ in self.categories())
+
+ @property
+ def class_count(self):
+ """The number of object classes."""
+ return self.policy.class_count()
+
+ @property
+ def common_count(self):
+ """The number of common permission sets."""
+ return self.policy.common_count()
+
+ @property
+ def conditional_count(self):
+ """The number of conditionals."""
+ return self.policy.cond_count()
+
+ @property
+ def constraint_count(self):
+ """The number of standard constraints."""
+ return sum(1 for c in self.constraints() if c.ruletype == "constrain")
+
+ @property
+ def dontaudit_count(self):
+ """The number of dontaudit rules."""
+ return self.policy.avrule_dontaudit_count()
+
+ @property
+ def fs_use_count(self):
+ """fs_use_* statements."""
+ return self.policy.fs_use_count()
+
+ @property
+ def genfscon_count(self):
+ """The number of genfscon statements."""
+ return self.policy.genfscon_count()
+
+ @property
+ def initialsids_count(self):
+ """The number of initial sid statements."""
+ return self.policy.isid_count()
+
+ @property
+ def level_count(self):
+ """The number of levels."""
+ return sum(1 for _ in self.levels())
+
+ @property
+ def mlsconstraint_count(self):
+ """The number of MLS constraints."""
+ return sum(1 for c in self.constraints() if c.ruletype == "mlsconstrain")
+
+ @property
+ def mlsvalidatetrans_count(self):
+ """The number of MLS validatetrans."""
+ return sum(1 for v in self.constraints() if v.ruletype == "mlsvalidatetrans")
+
+ @property
+ def netifcon_count(self):
+ """The number of netifcon statements."""
+ return self.policy.netifcon_count()
+
+ @property
+ def neverallow_count(self):
+ """The number of neverallow rules."""
+ return self.policy.avrule_neverallow_count()
+
+ @property
+ def nodecon_count(self):
+ """The number of nodecon statements."""
+ return self.policy.nodecon_count()
+
+ @property
+ def permission_count(self):
+ """The number of permissions."""
+ return sum(len(c.perms) for c in chain(self.commons(), self.classes()))
+
+ @property
+ def permissives_count(self):
+ """The number of permissive types."""
+ return self.policy.permissive_count()
+
+ @property
+ def polcap_count(self):
+ """The number of policy capabilities."""
+ return self.policy.polcap_count()
+
+ @property
+ def portcon_count(self):
+ """The number of portcon statements."""
+ return self.policy.portcon_count()
+
+ @property
+ def range_transition_count(self):
+ """The number of range_transition rules."""
+ return self.policy.range_trans_count()
+
+ @property
+ def role_count(self):
+ """The number of roles."""
+ return self.policy.role_count()
+
+ @property
+ def role_allow_count(self):
+ """The number of (role) allow rules."""
+ return self.policy.role_allow_count()
+
+ @property
+ def role_transition_count(self):
+ """The number of role_transition rules."""
+ return self.policy.role_trans_count()
+
+ @property
+ def type_attribute_count(self):
+ """The number of (type) attributes."""
+ return sum(1 for _ in self.typeattributes())
+
+ @property
+ def type_count(self):
+ """The number of types."""
+ return sum(1 for _ in self.types())
+
+ @property
+ def type_change_count(self):
+ """The number of type_change rules."""
+ return self.policy.terule_change_count()
+
+ @property
+ def type_member_count(self):
+ """The number of type_member rules."""
+ return self.policy.terule_member_count()
+
+ @property
+ def type_transition_count(self):
+ """The number of type_transition rules."""
+ return self.policy.terule_trans_count() + self.policy.filename_trans_count()
+
+ @property
+ def user_count(self):
+ """The number of users."""
+ return self.policy.user_count()
+
+ @property
+ def validatetrans_count(self):
+ """The number of validatetrans."""
+ return sum(1 for v in self.constraints() if v.ruletype == "validatetrans")
+
+ #
+ # Policy components lookup functions
+ #
+ def lookup_boolean(self, name):
+ """Look up a Boolean."""
+ return boolcond.boolean_factory(self.policy, name)
+
+ def lookup_class(self, name):
+ """Look up an object class."""
+ return objclass.class_factory(self.policy, name)
+
+ def lookup_common(self, name):
+ """Look up a common permission set."""
+ return objclass.common_factory(self.policy, name)
+
+ def lookup_initialsid(self, name):
+ """Look up an initial sid."""
+ return initsid.initialsid_factory(self.policy, name)
+
+ def lookup_level(self, level):
+ """Look up a MLS level."""
+ return mls.level_factory(self.policy, level)
+
+ def lookup_sensitivity(self, name):
+ """Look up a MLS sensitivity by name."""
+ return mls.sensitivity_factory(self.policy, name)
+
+ def lookup_range(self, range_):
+ """Look up a MLS range."""
+ return mls.range_factory(self.policy, range_)
+
+ def lookup_role(self, name):
+ """Look up a role by name."""
+ return role.role_factory(self.policy, name)
+
+ def lookup_type(self, name):
+ """Look up a type by name."""
+ return typeattr.type_factory(self.policy, name, deref=True)
+
+ def lookup_type_or_attr(self, name):
+ """Look up a type or type attribute by name."""
+ return typeattr.type_or_attr_factory(self.policy, name, deref=True)
+
+ def lookup_typeattr(self, name):
+ """Look up a type attribute by name."""
+ return typeattr.attribute_factory(self.policy, name)
+
+ def lookup_user(self, name):
+ """Look up a user by name."""
+ return user.user_factory(self.policy, name)
+
+ #
+ # Policy components generators
+ #
+
+ def bools(self):
+ """Generator which yields all Booleans."""
+ for bool_ in self.policy.bool_iter():
+ yield boolcond.boolean_factory(self.policy, bool_)
+
+ def categories(self):
+ """Generator which yields all MLS categories."""
+ for cat in self.policy.cat_iter():
+ try:
+ yield mls.category_factory(self.policy, cat)
+ except TypeError:
+ # libqpol unfortunately iterates over aliases too
+ pass
+
+ def classes(self):
+ """Generator which yields all object classes."""
+ for class_ in self.policy.class_iter():
+ yield objclass.class_factory(self.policy, class_)
+
+ def commons(self):
+ """Generator which yields all commons."""
+ for common in self.policy.common_iter():
+ yield objclass.common_factory(self.policy, common)
+
+ def defaults(self):
+ """Generator which yields all default_* statements."""
+ for default_ in self.policy.default_iter():
+ try:
+ for default_obj in default.default_factory(self.policy, default_):
+ yield default_obj
+ except exception.NoDefaults:
+ # qpol iterates over all classes. Handle case
+ # where a class has no default_* settings.
+ pass
+
+ def levels(self):
+ """Generator which yields all level declarations."""
+ for level in self.policy.level_iter():
+
+ try:
+ yield mls.level_decl_factory(self.policy, level)
+ except TypeError:
+ # libqpol unfortunately iterates over levels and sens aliases
+ pass
+
+ def polcaps(self):
+ """Generator which yields all policy capabilities."""
+ for cap in self.policy.polcap_iter():
+ yield polcap.polcap_factory(self.policy, cap)
+
+ def roles(self):
+ """Generator which yields all roles."""
+ for role_ in self.policy.role_iter():
+ yield role.role_factory(self.policy, role_)
+
+ def sensitivities(self):
+ """Generator which yields all sensitivities."""
+ # see mls.py for more info on why level_iter is used here.
+ for sens in self.policy.level_iter():
+ try:
+ yield mls.sensitivity_factory(self.policy, sens)
+ except TypeError:
+ # libqpol unfortunately iterates over sens and aliases
+ pass
+
+ def types(self):
+ """Generator which yields all types."""
+ for type_ in self.policy.type_iter():
+ try:
+ yield typeattr.type_factory(self.policy, type_)
+ except TypeError:
+ # libqpol unfortunately iterates over attributes and aliases
+ pass
+
+ def typeattributes(self):
+ """Generator which yields all (type) attributes."""
+ for type_ in self.policy.type_iter():
+ try:
+ yield typeattr.attribute_factory(self.policy, type_)
+ except TypeError:
+ # libqpol unfortunately iterates over attributes and aliases
+ pass
+
+ def users(self):
+ """Generator which yields all users."""
+ for user_ in self.policy.user_iter():
+ yield user.user_factory(self.policy, user_)
+
+ #
+ # Policy rules generators
+ #
+ def mlsrules(self):
+ """Generator which yields all MLS rules."""
+ for rule in self.policy.range_trans_iter():
+ yield mlsrule.mls_rule_factory(self.policy, rule)
+
+ def rbacrules(self):
+ """Generator which yields all RBAC rules."""
+ for rule in chain(self.policy.role_allow_iter(),
+ self.policy.role_trans_iter()):
+ yield rbacrule.rbac_rule_factory(self.policy, rule)
+
+ def terules(self):
+ """Generator which yields all type enforcement rules."""
+ for rule in chain(self.policy.avrule_iter(),
+ self.policy.terule_iter(),
+ self.policy.filename_trans_iter()):
+ yield terule.te_rule_factory(self.policy, rule)
+
+ #
+ # Policy rule type validators
+ #
+ @staticmethod
+ def validate_constraint_ruletype(types):
+ """Validate constraint types."""
+ constraint.validate_ruletype(types)
+
+ @staticmethod
+ def validate_mls_ruletype(types):
+ """Validate MLS rule types."""
+ mlsrule.validate_ruletype(types)
+
+ @staticmethod
+ def validate_rbac_ruletype(types):
+ """Validate RBAC rule types."""
+ rbacrule.validate_ruletype(types)
+
+ @staticmethod
+ def validate_te_ruletype(types):
+ """Validate type enforcement rule types."""
+ terule.validate_ruletype(types)
+
+ #
+ # Constraints generators
+ #
+
+ def constraints(self):
+ """Generator which yields all constraints (regular and MLS)."""
+ for constraint_ in chain(self.policy.constraint_iter(),
+ self.policy.validatetrans_iter()):
+
+ yield constraint.constraint_factory(self.policy, constraint_)
+
+ #
+ # In-policy Labeling statement generators
+ #
+ def fs_uses(self):
+ """Generator which yields all fs_use_* statements."""
+ for fs_use in self.policy.fs_use_iter():
+ yield fscontext.fs_use_factory(self.policy, fs_use)
+
+ def genfscons(self):
+ """Generator which yields all genfscon statements."""
+ for fscon in self.policy.genfscon_iter():
+ yield fscontext.genfscon_factory(self.policy, fscon)
+
+ def initialsids(self):
+ """Generator which yields all initial SID statements."""
+ for sid in self.policy.isid_iter():
+ yield initsid.initialsid_factory(self.policy, sid)
+
+ def netifcons(self):
+ """Generator which yields all netifcon statements."""
+ for ifcon in self.policy.netifcon_iter():
+ yield netcontext.netifcon_factory(self.policy, ifcon)
+
+ def nodecons(self):
+ """Generator which yields all nodecon statements."""
+ for node in self.policy.nodecon_iter():
+ yield netcontext.nodecon_factory(self.policy, node)
+
+ def portcons(self):
+ """Generator which yields all portcon statements."""
+ for port in self.policy.portcon_iter():
+ yield netcontext.portcon_factory(self.policy, port)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/_qpol.so b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/_qpol.so
new file mode 100755
index 0000000..aaccf28
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/_qpol.so
Binary files differ
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/boolcond.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/boolcond.py
new file mode 100644
index 0000000..c3c0608
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/boolcond.py
@@ -0,0 +1,167 @@
+# Copyright 2014-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/>.
+#
+from . import exception
+from . import qpol
+from . import symbol
+
+
+def boolean_factory(policy, name):
+ """Factory function for creating Boolean statement objects."""
+
+ if isinstance(name, Boolean):
+ assert name.policy == policy
+ return name
+ elif isinstance(name, qpol.qpol_bool_t):
+ return Boolean(policy, name)
+
+ try:
+ return Boolean(policy, qpol.qpol_bool_t(policy, str(name)))
+ except ValueError:
+ raise exception.InvalidBoolean("{0} is not a valid Boolean".format(name))
+
+
+def condexpr_factory(policy, name):
+ """Factory function for creating conditional expression objects."""
+
+ if not isinstance(name, qpol.qpol_cond_t):
+ raise TypeError("Conditional expressions cannot be looked up.")
+
+ return ConditionalExpr(policy, name)
+
+
+class Boolean(symbol.PolicySymbol):
+
+ """A Boolean."""
+
+ @property
+ def state(self):
+ """The default state of the Boolean."""
+ return bool(self.qpol_symbol.state(self.policy))
+
+ def statement(self):
+ """The policy statement."""
+ return "bool {0} {1};".format(self, str(self.state).lower())
+
+
+class ConditionalExpr(symbol.PolicySymbol):
+
+ """A conditional policy expression."""
+
+ _cond_expr_val_to_text = {
+ qpol.QPOL_COND_EXPR_NOT: "!",
+ qpol.QPOL_COND_EXPR_OR: "||",
+ qpol.QPOL_COND_EXPR_AND: "&&",
+ qpol.QPOL_COND_EXPR_XOR: "^",
+ qpol.QPOL_COND_EXPR_EQ: "==",
+ qpol.QPOL_COND_EXPR_NEQ: "!="}
+
+ _cond_expr_val_to_precedence = {
+ qpol.QPOL_COND_EXPR_NOT: 5,
+ qpol.QPOL_COND_EXPR_OR: 1,
+ qpol.QPOL_COND_EXPR_AND: 3,
+ qpol.QPOL_COND_EXPR_XOR: 2,
+ qpol.QPOL_COND_EXPR_EQ: 4,
+ qpol.QPOL_COND_EXPR_NEQ: 4}
+
+ def __contains__(self, other):
+ for expr_node in self.qpol_symbol.expr_node_iter(self.policy):
+ expr_node_type = expr_node.expr_type(self.policy)
+
+ if expr_node_type == qpol.QPOL_COND_EXPR_BOOL and other == \
+ boolean_factory(self.policy, expr_node.get_boolean(self.policy)):
+ return True
+
+ return False
+
+ def __str__(self):
+ # qpol representation is in postfix notation. This code
+ # converts it to infix notation. Parentheses are added
+ # to ensure correct expressions, though they may end up
+ # being overused. Set previous operator at start to the
+ # highest precedence (NOT) so if there is a single binary
+ # operator, no parentheses are output
+ stack = []
+ prev_op_precedence = self._cond_expr_val_to_precedence[qpol.QPOL_COND_EXPR_NOT]
+ for expr_node in self.qpol_symbol.expr_node_iter(self.policy):
+ expr_node_type = expr_node.expr_type(self.policy)
+
+ if expr_node_type == qpol.QPOL_COND_EXPR_BOOL:
+ # append the boolean name
+ nodebool = boolean_factory(
+ self.policy, expr_node.get_boolean(self.policy))
+ stack.append(str(nodebool))
+ elif expr_node_type == qpol.QPOL_COND_EXPR_NOT: # unary operator
+ operand = stack.pop()
+ operator = self._cond_expr_val_to_text[expr_node_type]
+ op_precedence = self._cond_expr_val_to_precedence[expr_node_type]
+
+ # NOT is the highest precedence, so only need
+ # parentheses if the operand is a subexpression
+ if isinstance(operand, list):
+ subexpr = [operator, "(", operand, ")"]
+ else:
+ subexpr = [operator, operand]
+
+ stack.append(subexpr)
+ prev_op_precedence = op_precedence
+ else:
+ operand1 = stack.pop()
+ operand2 = stack.pop()
+ operator = self._cond_expr_val_to_text[expr_node_type]
+ op_precedence = self._cond_expr_val_to_precedence[expr_node_type]
+
+ if prev_op_precedence > op_precedence:
+ # if previous operator is of higher precedence
+ # no parentheses are needed.
+ subexpr = [operand1, operator, operand2]
+ else:
+ subexpr = ["(", operand1, operator, operand2, ")"]
+
+ stack.append(subexpr)
+ prev_op_precedence = op_precedence
+
+ return self.__unwind_subexpression(stack)
+
+ def __unwind_subexpression(self, expr):
+ ret = []
+
+ # do a string.join on sublists (subexpressions)
+ for i in expr:
+ if isinstance(i, list):
+ ret.append(self.__unwind_subexpression(i))
+ else:
+ ret.append(i)
+
+ return ' '.join(ret)
+
+ @property
+ def booleans(self):
+ """The set of Booleans in the expression."""
+ bools = set()
+
+ for expr_node in self.qpol_symbol.expr_node_iter(self.policy):
+ expr_node_type = expr_node.expr_type(self.policy)
+
+ if expr_node_type == qpol.QPOL_COND_EXPR_BOOL:
+ bools.add(boolean_factory(self.policy, expr_node.get_boolean(self.policy)))
+
+ return bools
+
+ def statement(self):
+ raise exception.NoStatement
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/constraint.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/constraint.py
new file mode 100644
index 0000000..9994c5b
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/constraint.py
@@ -0,0 +1,297 @@
+# Copyright 2014-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/>.
+#
+from . import exception
+from . import qpol
+from . import role
+from . import symbol
+from . import objclass
+from . import typeattr
+from . import user
+
+
+def _is_mls(policy, sym):
+ """Determine if this is a regular or MLS constraint/validatetrans."""
+ # this can only be determined by inspecting the expression.
+ for expr_node in sym.expr_iter(policy):
+ sym_type = expr_node.sym_type(policy)
+ expr_type = expr_node.expr_type(policy)
+
+ if expr_type == qpol.QPOL_CEXPR_TYPE_ATTR and sym_type >= qpol.QPOL_CEXPR_SYM_L1L2:
+ return True
+
+ return False
+
+
+def validate_ruletype(types):
+ """Validate constraint rule types."""
+ for t in types:
+ if t not in ["constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans"]:
+ raise exception.InvalidConstraintType("{0} is not a valid constraint type.".format(t))
+
+
+def constraint_factory(policy, sym):
+ """Factory function for creating constraint objects."""
+
+ try:
+ if _is_mls(policy, sym):
+ if isinstance(sym, qpol.qpol_constraint_t):
+ return Constraint(policy, sym, "mlsconstrain")
+ else:
+ return Validatetrans(policy, sym, "mlsvalidatetrans")
+ else:
+ if isinstance(sym, qpol.qpol_constraint_t):
+ return Constraint(policy, sym, "constrain")
+ else:
+ return Validatetrans(policy, sym, "validatetrans")
+
+ except AttributeError:
+ raise TypeError("Constraints cannot be looked-up.")
+
+
+class BaseConstraint(symbol.PolicySymbol):
+
+ """Base class for constraint rules."""
+
+ _expr_type_to_text = {
+ qpol.QPOL_CEXPR_TYPE_NOT: "not",
+ qpol.QPOL_CEXPR_TYPE_AND: "and",
+ qpol.QPOL_CEXPR_TYPE_OR: "\n\tor"}
+
+ _expr_op_to_text = {
+ qpol.QPOL_CEXPR_OP_EQ: "==",
+ qpol.QPOL_CEXPR_OP_NEQ: "!=",
+ qpol.QPOL_CEXPR_OP_DOM: "dom",
+ qpol.QPOL_CEXPR_OP_DOMBY: "domby",
+ qpol.QPOL_CEXPR_OP_INCOMP: "incomp"}
+
+ _sym_to_text = {
+ qpol.QPOL_CEXPR_SYM_USER: "u1",
+ qpol.QPOL_CEXPR_SYM_ROLE: "r1",
+ qpol.QPOL_CEXPR_SYM_TYPE: "t1",
+ qpol.QPOL_CEXPR_SYM_USER + qpol.QPOL_CEXPR_SYM_TARGET: "u2",
+ qpol.QPOL_CEXPR_SYM_ROLE + qpol.QPOL_CEXPR_SYM_TARGET: "r2",
+ qpol.QPOL_CEXPR_SYM_TYPE + qpol.QPOL_CEXPR_SYM_TARGET: "t2",
+ qpol.QPOL_CEXPR_SYM_USER + qpol.QPOL_CEXPR_SYM_XTARGET: "u3",
+ qpol.QPOL_CEXPR_SYM_ROLE + qpol.QPOL_CEXPR_SYM_XTARGET: "r3",
+ qpol.QPOL_CEXPR_SYM_TYPE + qpol.QPOL_CEXPR_SYM_XTARGET: "t3",
+ qpol.QPOL_CEXPR_SYM_L1L2: "l1",
+ qpol.QPOL_CEXPR_SYM_L1H2: "l1",
+ qpol.QPOL_CEXPR_SYM_H1L2: "h1",
+ qpol.QPOL_CEXPR_SYM_H1H2: "h1",
+ qpol.QPOL_CEXPR_SYM_L1H1: "l1",
+ qpol.QPOL_CEXPR_SYM_L2H2: "l2",
+ qpol.QPOL_CEXPR_SYM_L1L2 + qpol.QPOL_CEXPR_SYM_TARGET: "l2",
+ qpol.QPOL_CEXPR_SYM_L1H2 + qpol.QPOL_CEXPR_SYM_TARGET: "h2",
+ qpol.QPOL_CEXPR_SYM_H1L2 + qpol.QPOL_CEXPR_SYM_TARGET: "l2",
+ qpol.QPOL_CEXPR_SYM_H1H2 + qpol.QPOL_CEXPR_SYM_TARGET: "h2",
+ qpol.QPOL_CEXPR_SYM_L1H1 + qpol.QPOL_CEXPR_SYM_TARGET: "h1",
+ qpol.QPOL_CEXPR_SYM_L2H2 + qpol.QPOL_CEXPR_SYM_TARGET: "h2"}
+
+ # Boolean operators
+ _expr_type_to_precedence = {
+ qpol.QPOL_CEXPR_TYPE_NOT: 3,
+ qpol.QPOL_CEXPR_TYPE_AND: 2,
+ qpol.QPOL_CEXPR_TYPE_OR: 1}
+
+ # Logical operators have the same precedence
+ _logical_op_precedence = 4
+
+ def __init__(self, policy, qpol_symbol, ruletype):
+ symbol.PolicySymbol.__init__(self, policy, qpol_symbol)
+ self.ruletype = ruletype
+
+ def __str__(self):
+ raise NotImplementedError
+
+ def _build_expression(self):
+ # qpol representation is in postfix notation. This code
+ # converts it to infix notation. Parentheses are added
+ # to ensure correct expressions, though they may end up
+ # being overused. Set previous operator at start to the
+ # highest precedence (op) so if there is a single binary
+ # operator, no parentheses are output
+
+ stack = []
+ prev_op_precedence = self._logical_op_precedence
+ for expr_node in self.qpol_symbol.expr_iter(self.policy):
+ op = expr_node.op(self.policy)
+ sym_type = expr_node.sym_type(self.policy)
+ expr_type = expr_node.expr_type(self.policy)
+
+ if expr_type == qpol.QPOL_CEXPR_TYPE_ATTR:
+ # logical operator with symbol (e.g. u1 == u2)
+ operand1 = self._sym_to_text[sym_type]
+ operand2 = self._sym_to_text[sym_type + qpol.QPOL_CEXPR_SYM_TARGET]
+ operator = self._expr_op_to_text[op]
+
+ stack.append([operand1, operator, operand2])
+
+ prev_op_precedence = self._logical_op_precedence
+ elif expr_type == qpol.QPOL_CEXPR_TYPE_NAMES:
+ # logical operator with type or attribute list (e.g. t1 == { spam_t eggs_t })
+ operand1 = self._sym_to_text[sym_type]
+ operator = self._expr_op_to_text[op]
+
+ names = list(expr_node.names_iter(self.policy))
+
+ if not names:
+ operand2 = "<empty set>"
+ elif len(names) == 1:
+ operand2 = names[0]
+ else:
+ operand2 = "{{ {0} }}".format(' '.join(names))
+
+ stack.append([operand1, operator, operand2])
+
+ prev_op_precedence = self._logical_op_precedence
+ elif expr_type == qpol.QPOL_CEXPR_TYPE_NOT:
+ # unary operator (not)
+ operand = stack.pop()
+ operator = self._expr_type_to_text[expr_type]
+
+ stack.append([operator, "(", operand, ")"])
+
+ prev_op_precedence = self._expr_type_to_precedence[expr_type]
+ else:
+ # binary operator (and/or)
+ operand1 = stack.pop()
+ operand2 = stack.pop()
+ operator = self._expr_type_to_text[expr_type]
+ op_precedence = self._expr_type_to_precedence[expr_type]
+
+ # if previous operator is of higher precedence
+ # no parentheses are needed.
+ if op_precedence < prev_op_precedence:
+ stack.append([operand1, operator, operand2])
+ else:
+ stack.append(["(", operand1, operator, operand2, ")"])
+
+ prev_op_precedence = op_precedence
+
+ return self.__unwind_subexpression(stack)
+
+ def _get_symbols(self, syms, factory):
+ """
+ Internal generator for getting users/roles/types in a constraint
+ expression. Symbols will be yielded multiple times if they appear
+ in the expression multiple times.
+
+ Parameters:
+ syms List of qpol symbol types.
+ factory The factory function related to these symbols.
+ """
+ for expr_node in self.qpol_symbol.expr_iter(self.policy):
+ sym_type = expr_node.sym_type(self.policy)
+ expr_type = expr_node.expr_type(self.policy)
+
+ if expr_type == qpol.QPOL_CEXPR_TYPE_NAMES and sym_type in syms:
+ for s in expr_node.names_iter(self.policy):
+ yield factory(self.policy, s)
+
+ def __unwind_subexpression(self, expr):
+ ret = []
+
+ # do a string.join on sublists (subexpressions)
+ for i in expr:
+ if isinstance(i, list):
+ ret.append(self.__unwind_subexpression(i))
+ else:
+ ret.append(i)
+
+ return ' '.join(ret)
+
+ # There is no levels function as specific
+ # levels cannot be used in expressions, only
+ # the l1, h1, etc. symbols
+
+ @property
+ def roles(self):
+ """The roles used in the expression."""
+ role_syms = [qpol.QPOL_CEXPR_SYM_ROLE,
+ qpol.QPOL_CEXPR_SYM_ROLE + qpol.QPOL_CEXPR_SYM_TARGET,
+ qpol.QPOL_CEXPR_SYM_ROLE + qpol.QPOL_CEXPR_SYM_XTARGET]
+
+ return set(self._get_symbols(role_syms, role.role_factory))
+
+ @property
+ def perms(self):
+ raise NotImplementedError
+
+ def statement(self):
+ return str(self)
+
+ @property
+ def tclass(self):
+ """Object class for this constraint."""
+ return objclass.class_factory(self.policy, self.qpol_symbol.object_class(self.policy))
+
+ @property
+ def types(self):
+ """The types and type attributes used in the expression."""
+ type_syms = [qpol.QPOL_CEXPR_SYM_TYPE,
+ qpol.QPOL_CEXPR_SYM_TYPE + qpol.QPOL_CEXPR_SYM_TARGET,
+ qpol.QPOL_CEXPR_SYM_TYPE + qpol.QPOL_CEXPR_SYM_XTARGET]
+
+ return set(self._get_symbols(type_syms, typeattr.type_or_attr_factory))
+
+ @property
+ def users(self):
+ """The users used in the expression."""
+ user_syms = [qpol.QPOL_CEXPR_SYM_USER,
+ qpol.QPOL_CEXPR_SYM_USER + qpol.QPOL_CEXPR_SYM_TARGET,
+ qpol.QPOL_CEXPR_SYM_USER + qpol.QPOL_CEXPR_SYM_XTARGET]
+
+ return set(self._get_symbols(user_syms, user.user_factory))
+
+
+class Constraint(BaseConstraint):
+
+ """A constraint rule (constrain/mlsconstrain)."""
+
+ def __str__(self):
+ rule_string = "{0.ruletype} {0.tclass} ".format(self)
+
+ perms = self.perms
+ if len(perms) > 1:
+ rule_string += "{{ {0} }} (\n".format(' '.join(perms))
+ else:
+ # convert to list since sets cannot be indexed
+ rule_string += "{0} (\n".format(list(perms)[0])
+
+ rule_string += "\t{0}\n);".format(self._build_expression())
+
+ return rule_string
+
+ @property
+ def perms(self):
+ """The constraint's permission set."""
+ return set(self.qpol_symbol.perm_iter(self.policy))
+
+
+class Validatetrans(BaseConstraint):
+
+ """A validatetrans rule (validatetrans/mlsvalidatetrans)."""
+
+ def __str__(self):
+ return "{0.ruletype} {0.tclass}\n\t{1}\n);".format(self, self._build_expression())
+
+ @property
+ def perms(self):
+ raise exception.ConstraintUseError("{0} rules do not have permissions.".
+ format(self.ruletype))
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/context.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/context.py
new file mode 100644
index 0000000..f2f3fc7
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/context.py
@@ -0,0 +1,68 @@
+# Copyright 2014-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/>.
+#
+from . import exception
+from . import qpol
+from . import symbol
+from . import user
+from . import role
+from . import typeattr
+from . import mls
+
+
+def context_factory(policy, name):
+ """Factory function for creating context objects."""
+
+ if not isinstance(name, qpol.qpol_context_t):
+ raise TypeError("Contexts cannot be looked-up.")
+
+ return Context(policy, name)
+
+
+class Context(symbol.PolicySymbol):
+
+ """A SELinux security context/security attribute."""
+
+ def __str__(self):
+ try:
+ return "{0.user}:{0.role}:{0.type_}:{0.range_}".format(self)
+ except exception.MLSDisabled:
+ return "{0.user}:{0.role}:{0.type_}".format(self)
+
+ @property
+ def user(self):
+ """The user portion of the context."""
+ return user.user_factory(self.policy, self.qpol_symbol.user(self.policy))
+
+ @property
+ def role(self):
+ """The role portion of the context."""
+ return role.role_factory(self.policy, self.qpol_symbol.role(self.policy))
+
+ @property
+ def type_(self):
+ """The type portion of the context."""
+ return typeattr.type_factory(self.policy, self.qpol_symbol.type_(self.policy))
+
+ @property
+ def range_(self):
+ """The MLS range of the context."""
+ return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy))
+
+ def statement(self):
+ raise exception.NoStatement
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/default.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/default.py
new file mode 100644
index 0000000..175b709
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/default.py
@@ -0,0 +1,128 @@
+# Copyright 2014, 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 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
+ if not sym.object_class(policy):
+ raise exception.NoDefaults
+
+ if sym.user_default(policy):
+ yield UserDefault(policy, sym)
+
+ if sym.role_default(policy):
+ yield RoleDefault(policy, sym)
+
+ if sym.type_default(policy):
+ yield TypeDefault(policy, sym)
+
+ if sym.range_default(policy):
+ yield RangeDefault(policy, sym)
+
+
+class Default(symbol.PolicySymbol):
+
+ """Base class for default_* statements."""
+
+ def __str__(self):
+ raise NotImplementedError
+
+ @property
+ def object_class(self):
+ """The object class."""
+ return objclass.class_factory(self.policy, self.qpol_symbol.object_class(self.policy))
+
+ @property
+ def default(self):
+ raise NotImplementedError
+
+ def statement(self):
+ return str(self)
+
+
+class UserDefault(Default):
+
+ """A default_user statement."""
+
+ def __str__(self):
+ return "default_user {0.object_class} {0.default};".format(self)
+
+ @property
+ def default(self):
+ """The default user location (source/target)."""
+ return self.qpol_symbol.user_default(self.policy)
+
+
+class RoleDefault(Default):
+
+ """A default_role statement."""
+
+ def __str__(self):
+ return "default_role {0.object_class} {0.default};".format(self)
+
+ @property
+ def default(self):
+ """The default role location (source/target)."""
+ return self.qpol_symbol.role_default(self.policy)
+
+
+class TypeDefault(Default):
+
+ """A default_type statement."""
+
+ def __str__(self):
+ return "default_type {0.object_class} {0.default};".format(self)
+
+ @property
+ def default(self):
+ """The default type location (source/target)."""
+ return self.qpol_symbol.type_default(self.policy)
+
+
+class RangeDefault(Default):
+
+ """A default_range statement."""
+
+ def __str__(self):
+ return "default_range {0.object_class} {0.default} {0.default_range};".format(self)
+
+ @property
+ def default(self):
+ """The default range location (source/target)."""
+ return self.qpol_symbol.range_default(self.policy).split()[0]
+
+ @property
+ def default_range(self):
+ """The default range setting (low/high/low_high)."""
+ return self.qpol_symbol.range_default(self.policy).split()[1]
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/exception.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/exception.py
new file mode 100644
index 0000000..ce367c0
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/exception.py
@@ -0,0 +1,248 @@
+# 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/>.
+#
+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 InvalidCategory(InvalidSymbol):
+
+ """Exception for invalid MLS categories."""
+ 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 InvalidLevelDecl(InvalidSymbol):
+
+ """
+ Exception for an invalid level declaration.
+ """
+ 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/lib/python2.7/site-packages/setoolsgui/setools/policyrep/fscontext.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/fscontext.py
new file mode 100644
index 0000000..a17b0bc
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/fscontext.py
@@ -0,0 +1,123 @@
+# Copyright 2014, 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 stat
+
+from . import qpol
+from . import symbol
+from . import context
+
+
+def fs_use_factory(policy, name):
+ """Factory function for creating fs_use_* objects."""
+
+ if not isinstance(name, qpol.qpol_fs_use_t):
+ raise TypeError("fs_use_* cannot be looked-up.")
+
+ return FSUse(policy, name)
+
+
+def genfscon_factory(policy, name):
+ """Factory function for creating genfscon objects."""
+
+ if not isinstance(name, qpol.qpol_genfscon_t):
+ raise TypeError("Genfscons cannot be looked-up.")
+
+ return Genfscon(policy, name)
+
+
+class FSContext(symbol.PolicySymbol):
+
+ """Base class for in-policy labeling rules."""
+
+ def __str__(self):
+ raise NotImplementedError
+
+ @property
+ def fs(self):
+ """The filesystem type for this statement."""
+ return self.qpol_symbol.name(self.policy)
+
+ @property
+ def context(self):
+ """The context for this statement."""
+ return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
+
+ def statement(self):
+ return str(self)
+
+
+class Genfscon(FSContext):
+
+ """A genfscon statement."""
+
+ _filetype_to_text = {
+ 0: "",
+ stat.S_IFBLK: "-b",
+ stat.S_IFCHR: "-c",
+ stat.S_IFDIR: "-d",
+ stat.S_IFIFO: "-p",
+ stat.S_IFREG: "--",
+ stat.S_IFLNK: "-l",
+ stat.S_IFSOCK: "-s"}
+
+ def __str__(self):
+ return "genfscon {0.fs} {0.path} {1} {0.context}".format(
+ self, self._filetype_to_text[self.filetype])
+
+ def __eq__(self, other):
+ # Libqpol allocates new C objects in the
+ # genfscons iterator, so pointer comparison
+ # in the PolicySymbol object doesn't work.
+ try:
+ return (self.fs == other.fs and
+ self.path == other.path and
+ self.filetype == other.filetype and
+ self.context == other.context)
+ except AttributeError:
+ return str(self) == str(other)
+
+ @property
+ def filetype(self):
+ """The file type (e.g. stat.S_IFBLK) for this genfscon statement."""
+ return self.qpol_symbol.object_class(self.policy)
+
+ @property
+ def path(self):
+ """The path for this genfscon statement."""
+ return self.qpol_symbol.path(self.policy)
+
+
+class FSUse(FSContext):
+
+ """A fs_use_* statement."""
+
+ # there are more rule types, but modern SELinux
+ # only supports these three.
+ _ruletype_to_text = {
+ qpol.QPOL_FS_USE_XATTR: 'fs_use_xattr',
+ qpol.QPOL_FS_USE_TRANS: 'fs_use_trans',
+ qpol.QPOL_FS_USE_TASK: 'fs_use_task'}
+
+ def __str__(self):
+ return "{0.ruletype} {0.fs} {0.context};".format(self)
+
+ @property
+ def ruletype(self):
+ """The rule type for this fs_use_* statement."""
+ return self._ruletype_to_text[self.qpol_symbol.behavior(self.policy)]
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/initsid.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/initsid.py
new file mode 100644
index 0000000..0197c74
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/initsid.py
@@ -0,0 +1,50 @@
+# Copyright 2014, 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 qpol
+from . import symbol
+from . import context
+
+
+def initialsid_factory(policy, name):
+ """Factory function for creating initial sid objects."""
+
+ if isinstance(name, InitialSID):
+ assert name.policy == policy
+ return name
+ elif isinstance(name, qpol.qpol_isid_t):
+ return InitialSID(policy, name)
+
+ try:
+ return InitialSID(policy, qpol.qpol_isid_t(policy, name))
+ except ValueError:
+ raise exception.InvalidInitialSid("{0} is not a valid initial sid".format(name))
+
+
+class InitialSID(symbol.PolicySymbol):
+
+ """An initial SID statement."""
+
+ @property
+ def context(self):
+ """The context for this initial SID."""
+ return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
+
+ def statement(self):
+ return "sid {0} {0.context}".format(self)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mls.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mls.py
new file mode 100644
index 0000000..2541704
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mls.py
@@ -0,0 +1,463 @@
+# Copyright 2014-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/>.
+#
+# pylint: disable=protected-access
+import itertools
+
+from . import exception
+from . import qpol
+from . import symbol
+
+# qpol does not expose an equivalent of a sensitivity declaration.
+# qpol_level_t is equivalent to the level declaration:
+# level s0:c0.c1023;
+
+# qpol_mls_level_t represents a level as used in contexts,
+# such as range_transitions or labeling statements such as
+# portcon and nodecon.
+
+# Here qpol_level_t is also used for MLSSensitivity
+# since it has the sensitivity name, dominance, and there
+# is a 1:1 correspondence between the sensitivity declarations
+# and level declarations.
+
+# Hashing has to be handled below because the qpol references,
+# normally used for a hash key, are not the same for multiple
+# instances of the same object (except for level decl).
+
+
+def enabled(policy):
+ """Determine if MLS is enabled."""
+ return policy.capability(qpol.QPOL_CAP_MLS)
+
+
+def category_factory(policy, sym):
+ """Factory function for creating MLS category objects."""
+
+ if not enabled(policy):
+ raise exception.MLSDisabled
+
+ if isinstance(sym, Category):
+ assert sym.policy == policy
+ return sym
+ elif isinstance(sym, qpol.qpol_cat_t):
+ if sym.isalias(policy):
+ raise TypeError("{0} is an alias".format(sym.name(policy)))
+
+ return Category(policy, sym)
+
+ try:
+ return Category(policy, qpol.qpol_cat_t(policy, str(sym)))
+ except ValueError:
+ raise exception.InvalidCategory("{0} is not a valid category".format(sym))
+
+
+def sensitivity_factory(policy, sym):
+ """Factory function for creating MLS sensitivity objects."""
+
+ if not enabled(policy):
+ raise exception.MLSDisabled
+
+ if isinstance(sym, Sensitivity):
+ assert sym.policy == policy
+ return sym
+ elif isinstance(sym, qpol.qpol_level_t):
+ if sym.isalias(policy):
+ raise TypeError("{0} is an alias".format(sym.name(policy)))
+
+ return Sensitivity(policy, sym)
+
+ try:
+ return Sensitivity(policy, qpol.qpol_level_t(policy, str(sym)))
+ except ValueError:
+ raise exception.InvalidSensitivity("{0} is not a valid sensitivity".format(sym))
+
+
+def level_factory(policy, sym):
+ """
+ Factory function for creating MLS level objects (e.g. levels used
+ in contexts of labeling statements)
+ """
+
+ if not enabled(policy):
+ raise exception.MLSDisabled
+
+ if isinstance(sym, Level):
+ assert sym.policy == policy
+ return sym
+ elif isinstance(sym, qpol.qpol_mls_level_t):
+ return Level(policy, sym)
+
+ sens_split = str(sym).split(":")
+
+ sens = sens_split[0]
+ try:
+ semantic_level = qpol.qpol_semantic_level_t(policy, sens)
+ except ValueError:
+ raise exception.InvalidLevel("{0} is invalid ({1} is not a valid sensitivity)".
+ format(sym, sens))
+
+ try:
+ cats = sens_split[1]
+ except IndexError:
+ pass
+ else:
+ for group in cats.split(","):
+ catrange = group.split(".")
+
+ if len(catrange) == 2:
+ try:
+ semantic_level.add_cats(policy, catrange[0], catrange[1])
+ except ValueError:
+ raise exception.InvalidLevel(
+ "{0} is invalid ({1} is not a valid category range)".format(sym, group))
+ elif len(catrange) == 1:
+ try:
+ semantic_level.add_cats(policy, catrange[0], catrange[0])
+ except ValueError:
+ raise exception.InvalidLevel("{0} is invalid ({1} is not a valid category)".
+ format(sym, group))
+ else:
+ raise exception.InvalidLevel("{0} is invalid (level parsing error)".format(sym))
+
+ # convert to level object
+ try:
+ policy_level = qpol.qpol_mls_level_t(policy, semantic_level)
+ except ValueError:
+ raise exception.InvalidLevel(
+ "{0} is invalid (one or more categories are not associated with the sensitivity)".
+ format(sym))
+
+ return Level(policy, policy_level)
+
+
+def level_decl_factory(policy, sym):
+ """
+ Factory function for creating MLS level declaration objects.
+ (level statements) Lookups are only by sensitivity name.
+ """
+
+ if not enabled(policy):
+ raise exception.MLSDisabled
+
+ if isinstance(sym, LevelDecl):
+ assert sym.policy == policy
+ return sym
+ elif isinstance(sym, qpol.qpol_level_t):
+ if sym.isalias(policy):
+ raise TypeError("{0} is an alias".format(sym.name(policy)))
+
+ return LevelDecl(policy, sym)
+
+ try:
+ return LevelDecl(policy, qpol.qpol_level_t(policy, str(sym)))
+ except ValueError:
+ raise exception.InvalidLevelDecl("{0} is not a valid sensitivity".format(sym))
+
+
+def range_factory(policy, sym):
+ """Factory function for creating MLS range objects."""
+
+ if not enabled(policy):
+ raise exception.MLSDisabled
+
+ if isinstance(sym, Range):
+ assert sym.policy == policy
+ return sym
+ elif isinstance(sym, qpol.qpol_mls_range_t):
+ return Range(policy, sym)
+
+ # build range:
+ levels = str(sym).split("-")
+
+ # strip() levels to handle ranges with spaces in them,
+ # e.g. s0:c1 - s0:c0.c255
+ try:
+ low = level_factory(policy, levels[0].strip())
+ except exception.InvalidLevel as ex:
+ raise exception.InvalidRange("{0} is not a valid range ({1}).".format(sym, ex))
+
+ try:
+ high = level_factory(policy, levels[1].strip())
+ except exception.InvalidLevel as ex:
+ raise exception.InvalidRange("{0} is not a valid range ({1}).".format(sym, ex))
+ except IndexError:
+ high = low
+
+ # convert to range object
+ try:
+ policy_range = qpol.qpol_mls_range_t(policy, low.qpol_symbol, high.qpol_symbol)
+ except ValueError:
+ raise exception.InvalidRange("{0} is not a valid range ({1} is not dominated by {2})".
+ format(sym, low, high))
+
+ return Range(policy, policy_range)
+
+
+class BaseMLSComponent(symbol.PolicySymbol):
+
+ """Base class for sensitivities and categories."""
+
+ @property
+ def _value(self):
+ """
+ The value of the component.
+
+ This is a low-level policy detail exposed for internal use only.
+ """
+ return self.qpol_symbol.value(self.policy)
+
+ def aliases(self):
+ """Generator that yields all aliases for this category."""
+
+ for alias in self.qpol_symbol.alias_iter(self.policy):
+ yield alias
+
+
+class Category(BaseMLSComponent):
+
+ """An MLS category."""
+
+ def statement(self):
+ aliases = list(self.aliases())
+ stmt = "category {0}".format(self)
+ if aliases:
+ if len(aliases) > 1:
+ stmt += " alias {{ {0} }}".format(' '.join(aliases))
+ else:
+ stmt += " alias {0}".format(aliases[0])
+ stmt += ";"
+ return stmt
+
+
+class Sensitivity(BaseMLSComponent):
+
+ """An MLS sensitivity"""
+
+ def __eq__(self, other):
+ try:
+ return self._value == other._value
+ except AttributeError:
+ return str(self) == str(other)
+
+ def __ge__(self, other):
+ return self._value >= other._value
+
+ def __gt__(self, other):
+ return self._value > other._value
+
+ def __le__(self, other):
+ return self._value <= other._value
+
+ def __lt__(self, other):
+ return self._value < other._value
+
+ def statement(self):
+ aliases = list(self.aliases())
+ stmt = "sensitivity {0}".format(self)
+ if aliases:
+ if len(aliases) > 1:
+ stmt += " alias {{ {0} }}".format(' '.join(aliases))
+ else:
+ stmt += " alias {0}".format(aliases[0])
+ stmt += ";"
+ return stmt
+
+
+class BaseMLSLevel(symbol.PolicySymbol):
+
+ """Base class for MLS levels."""
+
+ def __str__(self):
+ lvl = str(self.sensitivity)
+
+ # sort by policy declaration order
+ cats = sorted(self.categories(), key=lambda k: k._value)
+
+ if cats:
+ # generate short category notation
+ shortlist = []
+ for _, i in itertools.groupby(cats, key=lambda k,
+ c=itertools.count(): k._value - next(c)):
+ group = list(i)
+ if len(group) > 1:
+ shortlist.append("{0}.{1}".format(group[0], group[-1]))
+ else:
+ shortlist.append(str(group[0]))
+
+ lvl += ":" + ','.join(shortlist)
+
+ return lvl
+
+ @property
+ def sensitivity(self):
+ raise NotImplementedError
+
+ def categories(self):
+ """
+ Generator that yields all individual categories for this level.
+ All categories are yielded, not a compact notation such as
+ c0.c255
+ """
+
+ for cat in self.qpol_symbol.cat_iter(self.policy):
+ yield category_factory(self.policy, cat)
+
+
+class LevelDecl(BaseMLSLevel):
+
+ """
+ The declaration statement for MLS levels, e.g:
+
+ level s7:c0.c1023;
+ """
+ # below comparisons are only based on sensitivity
+ # dominance since, in this context, the allowable
+ # category set is being defined for the level.
+ # object type is asserted here because this cannot
+ # be compared to a Level instance.
+
+ def __eq__(self, other):
+ assert not isinstance(other, Level), "Levels cannot be compared to level declarations"
+
+ try:
+ return self.sensitivity == other.sensitivity
+ except AttributeError:
+ return str(self) == str(other)
+
+ def __ge__(self, other):
+ assert not isinstance(other, Level), "Levels cannot be compared to level declarations"
+ return self.sensitivity >= other.sensitivity
+
+ def __gt__(self, other):
+ assert not isinstance(other, Level), "Levels cannot be compared to level declarations"
+ return self.sensitivity > other.sensitivity
+
+ def __le__(self, other):
+ assert not isinstance(other, Level), "Levels cannot be compared to level declarations"
+ return self.sensitivity <= other.sensitivity
+
+ def __lt__(self, other):
+ assert not isinstance(other, Level), "Levels cannot be compared to level declarations"
+ return self.sensitivity < other.sensitivity
+
+ @property
+ def sensitivity(self):
+ """The sensitivity of the level."""
+ # since the qpol symbol for levels is also used for
+ # MLSSensitivity objects, use self's qpol symbol
+ return sensitivity_factory(self.policy, self.qpol_symbol)
+
+ def statement(self):
+ return "level {0};".format(self)
+
+
+class Level(BaseMLSLevel):
+
+ """An MLS level used in contexts."""
+
+ def __hash__(self):
+ return hash(str(self))
+
+ def __eq__(self, other):
+ try:
+ othercats = set(other.categories())
+ except AttributeError:
+ return str(self) == str(other)
+ else:
+ selfcats = set(self.categories())
+ return self.sensitivity == other.sensitivity and selfcats == othercats
+
+ def __ge__(self, other):
+ """Dom operator."""
+ selfcats = set(self.categories())
+ othercats = set(other.categories())
+ return self.sensitivity >= other.sensitivity and selfcats >= othercats
+
+ def __gt__(self, other):
+ selfcats = set(self.categories())
+ othercats = set(other.categories())
+ return ((self.sensitivity > other.sensitivity and selfcats >= othercats) or
+ (self.sensitivity >= other.sensitivity and selfcats > othercats))
+
+ def __le__(self, other):
+ """Domby operator."""
+ selfcats = set(self.categories())
+ othercats = set(other.categories())
+ return self.sensitivity <= other.sensitivity and selfcats <= othercats
+
+ def __lt__(self, other):
+ selfcats = set(self.categories())
+ othercats = set(other.categories())
+ return ((self.sensitivity < other.sensitivity and selfcats <= othercats) or
+ (self.sensitivity <= other.sensitivity and selfcats < othercats))
+
+ def __xor__(self, other):
+ """Incomp operator."""
+ return not (self >= other or self <= other)
+
+ @property
+ def sensitivity(self):
+ """The sensitivity of the level."""
+ return sensitivity_factory(self.policy, self.qpol_symbol.sens_name(self.policy))
+
+ def statement(self):
+ raise exception.NoStatement
+
+
+class Range(symbol.PolicySymbol):
+
+ """An MLS range"""
+
+ def __str__(self):
+ high = self.high
+ low = self.low
+ if high == low:
+ return str(low)
+
+ return "{0} - {1}".format(low, high)
+
+ def __hash__(self):
+ return hash(str(self))
+
+ def __eq__(self, other):
+ try:
+ return self.low == other.low and self.high == other.high
+ except AttributeError:
+ # remove all spaces in the string representations
+ # to handle cases where the other object does not
+ # have spaces around the '-'
+ other_str = str(other).replace(" ", "")
+ self_str = str(self).replace(" ", "")
+ return self_str == other_str
+
+ def __contains__(self, other):
+ return self.low <= other <= self.high
+
+ @property
+ def high(self):
+ """The high end/clearance level of this range."""
+ return level_factory(self.policy, self.qpol_symbol.high_level(self.policy))
+
+ @property
+ def low(self):
+ """The low end/current level of this range."""
+ return level_factory(self.policy, self.qpol_symbol.low_level(self.policy))
+
+ def statement(self):
+ raise exception.NoStatement
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mlsrule.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mlsrule.py
new file mode 100644
index 0000000..5c91c59
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/mlsrule.py
@@ -0,0 +1,62 @@
+# Copyright 2014, 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 qpol
+from . import rule
+from . import typeattr
+from . import mls
+
+
+def mls_rule_factory(policy, symbol):
+ """Factory function for creating MLS rule objects."""
+ if not isinstance(symbol, qpol.qpol_range_trans_t):
+ raise TypeError("MLS rules cannot be looked-up.")
+
+ return MLSRule(policy, symbol)
+
+
+def validate_ruletype(types):
+ """Validate MLS rule types."""
+ for t in types:
+ if t not in ["range_transition"]:
+ raise exception.InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t))
+
+
+class MLSRule(rule.PolicyRule):
+
+ """An MLS rule."""
+
+ def __str__(self):
+ # TODO: If we ever get more MLS rules, fix this format.
+ return "range_transition {0.source} {0.target}:{0.tclass} {0.default};".format(self)
+
+ @property
+ def source(self):
+ """The rule's source type/attribute."""
+ return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.source_type(self.policy))
+
+ @property
+ def target(self):
+ """The rule's target type/attribute."""
+ return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy))
+
+ @property
+ def default(self):
+ """The rule's default range."""
+ return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy))
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/netcontext.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/netcontext.py
new file mode 100644
index 0000000..5aeed5c
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/netcontext.py
@@ -0,0 +1,167 @@
+# Copyright 2014, 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 socket
+from collections import namedtuple
+
+from . import qpol
+from . import symbol
+from . import context
+
+port_range = namedtuple("port_range", ["low", "high"])
+
+
+def netifcon_factory(policy, name):
+ """Factory function for creating netifcon objects."""
+
+ if not isinstance(name, qpol.qpol_netifcon_t):
+ raise NotImplementedError
+
+ return Netifcon(policy, name)
+
+
+def nodecon_factory(policy, name):
+ """Factory function for creating nodecon objects."""
+
+ if not isinstance(name, qpol.qpol_nodecon_t):
+ raise NotImplementedError
+
+ return Nodecon(policy, name)
+
+
+def portcon_factory(policy, name):
+ """Factory function for creating portcon objects."""
+
+ if not isinstance(name, qpol.qpol_portcon_t):
+ raise NotImplementedError
+
+ return Portcon(policy, name)
+
+
+class NetContext(symbol.PolicySymbol):
+
+ """Base class for in-policy network labeling rules."""
+
+ def __str__(self):
+ raise NotImplementedError
+
+ @property
+ def context(self):
+ """The context for this statement."""
+ return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
+
+ def statement(self):
+ return str(self)
+
+
+class Netifcon(NetContext):
+
+ """A netifcon statement."""
+
+ def __str__(self):
+ return "netifcon {0.netif} {0.context} {0.packet}".format(self)
+
+ @property
+ def netif(self):
+ """The network interface name."""
+ return self.qpol_symbol.name(self.policy)
+
+ @property
+ def context(self):
+ """The context for the interface."""
+ return context.context_factory(self.policy, self.qpol_symbol.if_con(self.policy))
+
+ @property
+ def packet(self):
+ """The context for the packets."""
+ return context.context_factory(self.policy, self.qpol_symbol.msg_con(self.policy))
+
+
+class Nodecon(NetContext):
+
+ """A nodecon statement."""
+
+ def __str__(self):
+ return "nodecon {0.address} {0.netmask} {0.context}".format(self)
+
+ def __eq__(self, other):
+ # Libqpol allocates new C objects in the
+ # nodecons iterator, so pointer comparison
+ # in the PolicySymbol object doesn't work.
+ try:
+ return (self.address == other.address and
+ self.netmask == other.netmask and
+ self.context == other.context)
+ except AttributeError:
+ return (str(self) == str(other))
+
+ @property
+ def ip_version(self):
+ """
+ The IP version for the nodecon (socket.AF_INET or
+ socket.AF_INET6).
+ """
+ return self.qpol_symbol.protocol(self.policy)
+
+ @property
+ def address(self):
+ """The network address for the nodecon."""
+ return self.qpol_symbol.addr(self.policy)
+
+ @property
+ def netmask(self):
+ """The network mask for the nodecon."""
+ return self.qpol_symbol.mask(self.policy)
+
+
+class Portcon(NetContext):
+
+ """A portcon statement."""
+
+ _proto_to_text = {socket.IPPROTO_TCP: 'tcp',
+ socket.IPPROTO_UDP: 'udp'}
+
+ def __str__(self):
+ low, high = self.ports
+ proto = self._proto_to_text[self.protocol]
+
+ if low == high:
+ return "portcon {0} {1} {2}".format(proto, low, self.context)
+ else:
+ return "portcon {0} {1}-{2} {3}".format(proto, low, high, self.context)
+
+ @property
+ def protocol(self):
+ """
+ The protocol number for the portcon (socket.IPPROTO_TCP
+ or socket.IPPROTO_UDP).
+ """
+ return self.qpol_symbol.protocol(self.policy)
+
+ @property
+ def ports(self):
+ """
+ The port range for this portcon.
+
+ Return: Tuple(low, high)
+ low The low port of the range.
+ high The high port of the range.
+ """
+ low = self.qpol_symbol.low_port(self.policy)
+ high = self.qpol_symbol.high_port(self.policy)
+ return port_range(low, high)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/objclass.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/objclass.py
new file mode 100644
index 0000000..bf9a553
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/objclass.py
@@ -0,0 +1,110 @@
+# Copyright 2014-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/>.
+#
+from . import exception
+from . import symbol
+from . import qpol
+
+
+def common_factory(policy, name):
+ """Factory function for creating common permission set objects."""
+
+ if isinstance(name, Common):
+ assert name.policy == policy
+ return name
+ elif isinstance(name, qpol.qpol_common_t):
+ return Common(policy, name)
+
+ try:
+ return Common(policy, qpol.qpol_common_t(policy, str(name)))
+ except ValueError:
+ raise exception.InvalidCommon("{0} is not a valid common".format(name))
+
+
+def class_factory(policy, name):
+ """Factory function for creating object class objects."""
+
+ if isinstance(name, ObjClass):
+ assert name.policy == policy
+ return name
+ elif isinstance(name, qpol.qpol_class_t):
+ return ObjClass(policy, name)
+
+ try:
+ return ObjClass(policy, qpol.qpol_class_t(policy, str(name)))
+ except ValueError:
+ raise exception.InvalidClass("{0} is not a valid object class".format(name))
+
+
+class Common(symbol.PolicySymbol):
+
+ """A common permission set."""
+
+ def __contains__(self, other):
+ return other in self.perms
+
+ @property
+ def perms(self):
+ """The list of the common's permissions."""
+ return set(self.qpol_symbol.perm_iter(self.policy))
+
+ def statement(self):
+ return "common {0}\n{{\n\t{1}\n}}".format(self, '\n\t'.join(self.perms))
+
+
+class ObjClass(Common):
+
+ """An object class."""
+
+ def __contains__(self, other):
+ try:
+ if other in self.common.perms:
+ return True
+ except exception.NoCommon:
+ pass
+
+ return other in self.perms
+
+ @property
+ def common(self):
+ """
+ The common that the object class inherits.
+
+ Exceptions:
+ NoCommon The object class does not inherit a common.
+ """
+
+ try:
+ return common_factory(self.policy, self.qpol_symbol.common(self.policy))
+ except ValueError:
+ raise exception.NoCommon("{0} does not inherit a common.".format(self))
+
+ def statement(self):
+ stmt = "class {0}\n".format(self)
+
+ try:
+ stmt += "inherits {0}\n".format(self.common)
+ except exception.NoCommon:
+ pass
+
+ # a class that inherits may not have additional permissions
+ perms = self.perms
+ if len(perms) > 0:
+ stmt += "{{\n\t{0}\n}}".format('\n\t'.join(perms))
+
+ return stmt
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/polcap.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/polcap.py
new file mode 100644
index 0000000..8ab164d
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/polcap.py
@@ -0,0 +1,40 @@
+# Copyright 2014-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/>.
+#
+from . import qpol
+from . import symbol
+
+
+def polcap_factory(policy, name):
+ """Factory function for creating policy capability objects."""
+
+ if isinstance(name, PolicyCapability):
+ assert name.policy == policy
+ return name
+ elif isinstance(name, qpol.qpol_polcap_t):
+ return PolicyCapability(policy, name)
+ else:
+ raise TypeError("Policy capabilities cannot be looked up.")
+
+
+class PolicyCapability(symbol.PolicySymbol):
+
+ """A policy capability."""
+
+ def statement(self):
+ return "policycap {0};".format(self)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/qpol.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/qpol.py
new file mode 100644
index 0000000..97e602b
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/qpol.py
@@ -0,0 +1,1114 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 2.0.11
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+
+
+
+
+from sys import version_info
+if version_info >= (2,6,0):
+ def swig_import_helper():
+ from os.path import dirname
+ import imp
+ fp = None
+ try:
+ fp, pathname, description = imp.find_module('_qpol', [dirname(__file__)])
+ except ImportError:
+ import _qpol
+ return _qpol
+ if fp is not None:
+ try:
+ _mod = imp.load_module('_qpol', fp, pathname, description)
+ finally:
+ fp.close()
+ return _mod
+ _qpol = swig_import_helper()
+ del swig_import_helper
+else:
+ import _qpol
+del version_info
+try:
+ _swig_property = property
+except NameError:
+ pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+ if (name == "thisown"): return self.this.own(value)
+ if (name == "this"):
+ if type(value).__name__ == 'SwigPyObject':
+ self.__dict__[name] = value
+ return
+ method = class_type.__swig_setmethods__.get(name,None)
+ if method: return method(self,value)
+ if (not static):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+ return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+ if (name == "thisown"): return self.this.own()
+ method = class_type.__swig_getmethods__.get(name,None)
+ if method: return method(self)
+ raise AttributeError(name)
+
+def _swig_repr(self):
+ try: strthis = "proxy of " + self.this.__repr__()
+ except: strthis = ""
+ return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+try:
+ _object = object
+ _newclass = 1
+except AttributeError:
+ class _object : pass
+ _newclass = 0
+
+
+
+def to_str(*args):
+ return _qpol.to_str(*args)
+to_str = _qpol.to_str
+import logging
+from functools import wraps
+
+def QpolGenerator(cast):
+ """
+ A decorator which converts qpol iterators into Python generators.
+
+ Qpol iterators use void* to be generic about their contents.
+ The purpose of the _from_void functions below is to wrap
+ the pointer casting, hence the "cast" variable name here.
+
+ Decorator parameter:
+ cast A wrapper function which casts the qpol iterator return pointer
+ to the proper C data type pointer. The Python function
+ reference to the C Python extension is used, for example:
+
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ """
+
+ def decorate(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ qpol_iter = func(*args)
+ while not qpol_iter.isend():
+ yield cast(qpol_iter.item())
+ qpol_iter.next_()
+
+ return wrapper
+ return decorate
+
+def qpol_logger(level, msg):
+ """Log qpol messages via Python logging."""
+ logging.getLogger("libqpol").debug(msg)
+
+def qpol_policy_factory(path):
+ """Factory function for qpol policy objects."""
+ # The main purpose here is to hook in the
+ # above logger callback.
+ return qpol_policy_t(path, 0, qpol_logger)
+
+QPOL_POLICY_OPTION_NO_NEVERALLOWS = _qpol.QPOL_POLICY_OPTION_NO_NEVERALLOWS
+QPOL_POLICY_OPTION_NO_RULES = _qpol.QPOL_POLICY_OPTION_NO_RULES
+QPOL_POLICY_OPTION_MATCH_SYSTEM = _qpol.QPOL_POLICY_OPTION_MATCH_SYSTEM
+QPOL_POLICY_MAX_VERSION = _qpol.QPOL_POLICY_MAX_VERSION
+QPOL_POLICY_MIN_VERSION = _qpol.QPOL_POLICY_MIN_VERSION
+class qpol_policy_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_policy_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_policy_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_policy_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_policy_t
+ __del__ = lambda self : None;
+ def version(self): return _qpol.qpol_policy_t_version(self)
+ def handle_unknown(self): return _qpol.qpol_policy_t_handle_unknown(self)
+ def capability(self, *args): return _qpol.qpol_policy_t_capability(self, *args)
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ def type_iter(self): return _qpol.qpol_policy_t_type_iter(self)
+ def type_count(self): return _qpol.qpol_policy_t_type_count(self)
+ @QpolGenerator(_qpol.qpol_role_from_void)
+ def role_iter(self): return _qpol.qpol_policy_t_role_iter(self)
+ def role_count(self): return _qpol.qpol_policy_t_role_count(self)
+ @QpolGenerator(_qpol.qpol_level_from_void)
+ def level_iter(self): return _qpol.qpol_policy_t_level_iter(self)
+ def level_count(self): return _qpol.qpol_policy_t_level_count(self)
+ @QpolGenerator(_qpol.qpol_cat_from_void)
+ def cat_iter(self): return _qpol.qpol_policy_t_cat_iter(self)
+ def cat_count(self): return _qpol.qpol_policy_t_cat_count(self)
+ @QpolGenerator(_qpol.qpol_user_from_void)
+ def user_iter(self): return _qpol.qpol_policy_t_user_iter(self)
+ def user_count(self): return _qpol.qpol_policy_t_user_count(self)
+ @QpolGenerator(_qpol.qpol_bool_from_void)
+ def bool_iter(self): return _qpol.qpol_policy_t_bool_iter(self)
+ def bool_count(self): return _qpol.qpol_policy_t_bool_count(self)
+ @QpolGenerator(_qpol.qpol_class_from_void)
+ def class_iter(self, perm=None): return _qpol.qpol_policy_t_class_iter(self, perm)
+ def class_count(self): return _qpol.qpol_policy_t_class_count(self)
+ @QpolGenerator(_qpol.qpol_common_from_void)
+ def common_iter(self, perm=None): return _qpol.qpol_policy_t_common_iter(self, perm)
+ def common_count(self): return _qpol.qpol_policy_t_common_count(self)
+ @QpolGenerator(_qpol.qpol_fs_use_from_void)
+ def fs_use_iter(self): return _qpol.qpol_policy_t_fs_use_iter(self)
+ def fs_use_count(self): return _qpol.qpol_policy_t_fs_use_count(self)
+ @QpolGenerator(_qpol.qpol_genfscon_from_void)
+ def genfscon_iter(self): return _qpol.qpol_policy_t_genfscon_iter(self)
+ def genfscon_count(self): return _qpol.qpol_policy_t_genfscon_count(self)
+ @QpolGenerator(_qpol.qpol_isid_from_void)
+ def isid_iter(self): return _qpol.qpol_policy_t_isid_iter(self)
+ def isid_count(self): return _qpol.qpol_policy_t_isid_count(self)
+ @QpolGenerator(_qpol.qpol_netifcon_from_void)
+ def netifcon_iter(self): return _qpol.qpol_policy_t_netifcon_iter(self)
+ def netifcon_count(self): return _qpol.qpol_policy_t_netifcon_count(self)
+ @QpolGenerator(_qpol.qpol_nodecon_from_void)
+ def nodecon_iter(self): return _qpol.qpol_policy_t_nodecon_iter(self)
+ def nodecon_count(self): return _qpol.qpol_policy_t_nodecon_count(self)
+ @QpolGenerator(_qpol.qpol_portcon_from_void)
+ def portcon_iter(self): return _qpol.qpol_policy_t_portcon_iter(self)
+ def portcon_count(self): return _qpol.qpol_policy_t_portcon_count(self)
+ @QpolGenerator(_qpol.qpol_constraint_from_void)
+ def constraint_iter(self): return _qpol.qpol_policy_t_constraint_iter(self)
+ def constraint_count(self): return _qpol.qpol_policy_t_constraint_count(self)
+ @QpolGenerator(_qpol.qpol_validatetrans_from_void)
+ def validatetrans_iter(self): return _qpol.qpol_policy_t_validatetrans_iter(self)
+ def validatetrans_count(self): return _qpol.qpol_policy_t_validatetrans_count(self)
+ @QpolGenerator(_qpol.qpol_role_allow_from_void)
+ def role_allow_iter(self): return _qpol.qpol_policy_t_role_allow_iter(self)
+ def role_allow_count(self): return _qpol.qpol_policy_t_role_allow_count(self)
+ @QpolGenerator(_qpol.qpol_role_trans_from_void)
+ def role_trans_iter(self): return _qpol.qpol_policy_t_role_trans_iter(self)
+ def role_trans_count(self): return _qpol.qpol_policy_t_role_trans_count(self)
+ @QpolGenerator(_qpol.qpol_range_trans_from_void)
+ def range_trans_iter(self): return _qpol.qpol_policy_t_range_trans_iter(self)
+ def range_trans_count(self): return _qpol.qpol_policy_t_range_trans_count(self)
+ @QpolGenerator(_qpol.qpol_avrule_from_void)
+ def avrule_iter(self): return _qpol.qpol_policy_t_avrule_iter(self)
+ def avrule_allow_count(self): return _qpol.qpol_policy_t_avrule_allow_count(self)
+ def avrule_auditallow_count(self): return _qpol.qpol_policy_t_avrule_auditallow_count(self)
+ def avrule_neverallow_count(self): return _qpol.qpol_policy_t_avrule_neverallow_count(self)
+ def avrule_dontaudit_count(self): return _qpol.qpol_policy_t_avrule_dontaudit_count(self)
+ @QpolGenerator(_qpol.qpol_terule_from_void)
+ def terule_iter(self): return _qpol.qpol_policy_t_terule_iter(self)
+ def terule_trans_count(self): return _qpol.qpol_policy_t_terule_trans_count(self)
+ def terule_change_count(self): return _qpol.qpol_policy_t_terule_change_count(self)
+ def terule_member_count(self): return _qpol.qpol_policy_t_terule_member_count(self)
+ def cond_iter(self): return _qpol.qpol_policy_t_cond_iter(self)
+ def cond_count(self): return _qpol.qpol_policy_t_cond_count(self)
+ @QpolGenerator(_qpol.qpol_filename_trans_from_void)
+ def filename_trans_iter(self): return _qpol.qpol_policy_t_filename_trans_iter(self)
+ def filename_trans_count(self): return _qpol.qpol_policy_t_filename_trans_count(self)
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ def permissive_iter(self): return _qpol.qpol_policy_t_permissive_iter(self)
+ def permissive_count(self): return _qpol.qpol_policy_t_permissive_count(self)
+ def typebounds_iter(self): return _qpol.qpol_policy_t_typebounds_iter(self)
+ def typebounds_count(self): return _qpol.qpol_policy_t_typebounds_count(self)
+ @QpolGenerator(_qpol.qpol_polcap_from_void)
+ def polcap_iter(self): return _qpol.qpol_policy_t_polcap_iter(self)
+ def polcap_count(self): return _qpol.qpol_policy_t_polcap_count(self)
+ @QpolGenerator(_qpol.qpol_default_object_from_void)
+ def default_iter(self): return _qpol.qpol_policy_t_default_iter(self)
+qpol_policy_t_swigregister = _qpol.qpol_policy_t_swigregister
+qpol_policy_t_swigregister(qpol_policy_t)
+
+QPOL_CAP_ATTRIB_NAMES = _qpol.QPOL_CAP_ATTRIB_NAMES
+QPOL_CAP_SYN_RULES = _qpol.QPOL_CAP_SYN_RULES
+QPOL_CAP_LINE_NUMBERS = _qpol.QPOL_CAP_LINE_NUMBERS
+QPOL_CAP_CONDITIONALS = _qpol.QPOL_CAP_CONDITIONALS
+QPOL_CAP_MLS = _qpol.QPOL_CAP_MLS
+QPOL_CAP_MODULES = _qpol.QPOL_CAP_MODULES
+QPOL_CAP_RULES_LOADED = _qpol.QPOL_CAP_RULES_LOADED
+QPOL_CAP_SOURCE = _qpol.QPOL_CAP_SOURCE
+QPOL_CAP_NEVERALLOW = _qpol.QPOL_CAP_NEVERALLOW
+QPOL_CAP_POLCAPS = _qpol.QPOL_CAP_POLCAPS
+QPOL_CAP_BOUNDS = _qpol.QPOL_CAP_BOUNDS
+QPOL_CAP_DEFAULT_OBJECTS = _qpol.QPOL_CAP_DEFAULT_OBJECTS
+QPOL_CAP_DEFAULT_TYPE = _qpol.QPOL_CAP_DEFAULT_TYPE
+QPOL_CAP_PERMISSIVE = _qpol.QPOL_CAP_PERMISSIVE
+QPOL_CAP_FILENAME_TRANS = _qpol.QPOL_CAP_FILENAME_TRANS
+QPOL_CAP_ROLETRANS = _qpol.QPOL_CAP_ROLETRANS
+class qpol_iterator_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_iterator_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_iterator_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_iterator_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_iterator_t
+ __del__ = lambda self : None;
+ def item(self): return _qpol.qpol_iterator_t_item(self)
+ def next_(self): return _qpol.qpol_iterator_t_next_(self)
+ def isend(self): return _qpol.qpol_iterator_t_isend(self)
+ def size(self): return _qpol.qpol_iterator_t_size(self)
+qpol_iterator_t_swigregister = _qpol.qpol_iterator_t_swigregister
+qpol_iterator_t_swigregister(qpol_iterator_t)
+
+class qpol_type_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_type_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_type_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_type_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_type_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_type_t_name(self, *args)
+ def value(self, *args): return _qpol.qpol_type_t_value(self, *args)
+ def isalias(self, *args): return _qpol.qpol_type_t_isalias(self, *args)
+ def isattr(self, *args): return _qpol.qpol_type_t_isattr(self, *args)
+ def ispermissive(self, *args): return _qpol.qpol_type_t_ispermissive(self, *args)
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ def type_iter(self, *args): return _qpol.qpol_type_t_type_iter(self, *args)
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ def attr_iter(self, *args): return _qpol.qpol_type_t_attr_iter(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def alias_iter(self, *args): return _qpol.qpol_type_t_alias_iter(self, *args)
+qpol_type_t_swigregister = _qpol.qpol_type_t_swigregister
+qpol_type_t_swigregister(qpol_type_t)
+
+
+def qpol_type_from_void(*args):
+ return _qpol.qpol_type_from_void(*args)
+qpol_type_from_void = _qpol.qpol_type_from_void
+class qpol_role_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_role_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_role_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_role_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_role_t
+ __del__ = lambda self : None;
+ def value(self, *args): return _qpol.qpol_role_t_value(self, *args)
+ def name(self, *args): return _qpol.qpol_role_t_name(self, *args)
+ @QpolGenerator(_qpol.qpol_type_from_void)
+ def type_iter(self, *args): return _qpol.qpol_role_t_type_iter(self, *args)
+ def dominate_iter(self, *args): return _qpol.qpol_role_t_dominate_iter(self, *args)
+qpol_role_t_swigregister = _qpol.qpol_role_t_swigregister
+qpol_role_t_swigregister(qpol_role_t)
+
+
+def qpol_role_from_void(*args):
+ return _qpol.qpol_role_from_void(*args)
+qpol_role_from_void = _qpol.qpol_role_from_void
+class qpol_level_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_level_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_level_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_level_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_level_t
+ __del__ = lambda self : None;
+ def isalias(self, *args): return _qpol.qpol_level_t_isalias(self, *args)
+ def value(self, *args): return _qpol.qpol_level_t_value(self, *args)
+ def name(self, *args): return _qpol.qpol_level_t_name(self, *args)
+ @QpolGenerator(_qpol.qpol_cat_from_void)
+ def cat_iter(self, *args): return _qpol.qpol_level_t_cat_iter(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def alias_iter(self, *args): return _qpol.qpol_level_t_alias_iter(self, *args)
+qpol_level_t_swigregister = _qpol.qpol_level_t_swigregister
+qpol_level_t_swigregister(qpol_level_t)
+
+
+def qpol_level_from_void(*args):
+ return _qpol.qpol_level_from_void(*args)
+qpol_level_from_void = _qpol.qpol_level_from_void
+class qpol_cat_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_cat_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_cat_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_cat_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_cat_t
+ __del__ = lambda self : None;
+ def isalias(self, *args): return _qpol.qpol_cat_t_isalias(self, *args)
+ def value(self, *args): return _qpol.qpol_cat_t_value(self, *args)
+ def name(self, *args): return _qpol.qpol_cat_t_name(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def alias_iter(self, *args): return _qpol.qpol_cat_t_alias_iter(self, *args)
+qpol_cat_t_swigregister = _qpol.qpol_cat_t_swigregister
+qpol_cat_t_swigregister(qpol_cat_t)
+
+
+def qpol_cat_from_void(*args):
+ return _qpol.qpol_cat_from_void(*args)
+qpol_cat_from_void = _qpol.qpol_cat_from_void
+class qpol_mls_range_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_mls_range_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_mls_range_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_mls_range_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_mls_range_t
+ __del__ = lambda self : None;
+ def high_level(self, *args): return _qpol.qpol_mls_range_t_high_level(self, *args)
+ def low_level(self, *args): return _qpol.qpol_mls_range_t_low_level(self, *args)
+qpol_mls_range_t_swigregister = _qpol.qpol_mls_range_t_swigregister
+qpol_mls_range_t_swigregister(qpol_mls_range_t)
+
+
+def qpol_mls_range_from_void(*args):
+ return _qpol.qpol_mls_range_from_void(*args)
+qpol_mls_range_from_void = _qpol.qpol_mls_range_from_void
+class qpol_semantic_level_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_semantic_level_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_semantic_level_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_semantic_level_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_semantic_level_t
+ __del__ = lambda self : None;
+ def add_cats(self, *args): return _qpol.qpol_semantic_level_t_add_cats(self, *args)
+qpol_semantic_level_t_swigregister = _qpol.qpol_semantic_level_t_swigregister
+qpol_semantic_level_t_swigregister(qpol_semantic_level_t)
+
+class qpol_mls_level_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_mls_level_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_mls_level_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_mls_level_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_mls_level_t
+ __del__ = lambda self : None;
+ def sens_name(self, *args): return _qpol.qpol_mls_level_t_sens_name(self, *args)
+ @QpolGenerator(_qpol.qpol_cat_from_void)
+ def cat_iter(self, *args): return _qpol.qpol_mls_level_t_cat_iter(self, *args)
+qpol_mls_level_t_swigregister = _qpol.qpol_mls_level_t_swigregister
+qpol_mls_level_t_swigregister(qpol_mls_level_t)
+
+
+def qpol_mls_level_from_void(*args):
+ return _qpol.qpol_mls_level_from_void(*args)
+qpol_mls_level_from_void = _qpol.qpol_mls_level_from_void
+class qpol_user_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_user_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_user_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_user_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_user_t
+ __del__ = lambda self : None;
+ def value(self, *args): return _qpol.qpol_user_t_value(self, *args)
+ @QpolGenerator(_qpol.qpol_role_from_void)
+ def role_iter(self, *args): return _qpol.qpol_user_t_role_iter(self, *args)
+ def range(self, *args): return _qpol.qpol_user_t_range(self, *args)
+ def name(self, *args): return _qpol.qpol_user_t_name(self, *args)
+ def dfltlevel(self, *args): return _qpol.qpol_user_t_dfltlevel(self, *args)
+qpol_user_t_swigregister = _qpol.qpol_user_t_swigregister
+qpol_user_t_swigregister(qpol_user_t)
+
+
+def qpol_user_from_void(*args):
+ return _qpol.qpol_user_from_void(*args)
+qpol_user_from_void = _qpol.qpol_user_from_void
+class qpol_bool_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_bool_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_bool_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_bool_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_bool_t
+ __del__ = lambda self : None;
+ def value(self, *args): return _qpol.qpol_bool_t_value(self, *args)
+ def state(self, *args): return _qpol.qpol_bool_t_state(self, *args)
+ def name(self, *args): return _qpol.qpol_bool_t_name(self, *args)
+qpol_bool_t_swigregister = _qpol.qpol_bool_t_swigregister
+qpol_bool_t_swigregister(qpol_bool_t)
+
+
+def qpol_bool_from_void(*args):
+ return _qpol.qpol_bool_from_void(*args)
+qpol_bool_from_void = _qpol.qpol_bool_from_void
+class qpol_context_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_context_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_context_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_context_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_context_t
+ __del__ = lambda self : None;
+ def user(self, *args): return _qpol.qpol_context_t_user(self, *args)
+ def role(self, *args): return _qpol.qpol_context_t_role(self, *args)
+ def type_(self, *args): return _qpol.qpol_context_t_type_(self, *args)
+ def range(self, *args): return _qpol.qpol_context_t_range(self, *args)
+qpol_context_t_swigregister = _qpol.qpol_context_t_swigregister
+qpol_context_t_swigregister(qpol_context_t)
+
+
+def qpol_context_from_void(*args):
+ return _qpol.qpol_context_from_void(*args)
+qpol_context_from_void = _qpol.qpol_context_from_void
+class qpol_class_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_class_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_class_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_class_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_class_t
+ __del__ = lambda self : None;
+ def value(self, *args): return _qpol.qpol_class_t_value(self, *args)
+ def common(self, *args): return _qpol.qpol_class_t_common(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def perm_iter(self, *args): return _qpol.qpol_class_t_perm_iter(self, *args)
+ @QpolGenerator(_qpol.qpol_constraint_from_void)
+ def constraint_iter(self, *args): return _qpol.qpol_class_t_constraint_iter(self, *args)
+ @QpolGenerator(_qpol.qpol_validatetrans_from_void)
+ def validatetrans_iter(self, *args): return _qpol.qpol_class_t_validatetrans_iter(self, *args)
+ def name(self, *args): return _qpol.qpol_class_t_name(self, *args)
+qpol_class_t_swigregister = _qpol.qpol_class_t_swigregister
+qpol_class_t_swigregister(qpol_class_t)
+
+
+def qpol_class_from_void(*args):
+ return _qpol.qpol_class_from_void(*args)
+qpol_class_from_void = _qpol.qpol_class_from_void
+class qpol_common_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_common_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_common_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_common_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_common_t
+ __del__ = lambda self : None;
+ def value(self, *args): return _qpol.qpol_common_t_value(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def perm_iter(self, *args): return _qpol.qpol_common_t_perm_iter(self, *args)
+ def name(self, *args): return _qpol.qpol_common_t_name(self, *args)
+qpol_common_t_swigregister = _qpol.qpol_common_t_swigregister
+qpol_common_t_swigregister(qpol_common_t)
+
+
+def qpol_common_from_void(*args):
+ return _qpol.qpol_common_from_void(*args)
+qpol_common_from_void = _qpol.qpol_common_from_void
+QPOL_FS_USE_XATTR = _qpol.QPOL_FS_USE_XATTR
+QPOL_FS_USE_TRANS = _qpol.QPOL_FS_USE_TRANS
+QPOL_FS_USE_TASK = _qpol.QPOL_FS_USE_TASK
+QPOL_FS_USE_GENFS = _qpol.QPOL_FS_USE_GENFS
+QPOL_FS_USE_NONE = _qpol.QPOL_FS_USE_NONE
+QPOL_FS_USE_PSID = _qpol.QPOL_FS_USE_PSID
+class qpol_fs_use_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_fs_use_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_fs_use_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_fs_use_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_fs_use_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_fs_use_t_name(self, *args)
+ def behavior(self, *args): return _qpol.qpol_fs_use_t_behavior(self, *args)
+ def context(self, *args): return _qpol.qpol_fs_use_t_context(self, *args)
+qpol_fs_use_t_swigregister = _qpol.qpol_fs_use_t_swigregister
+qpol_fs_use_t_swigregister(qpol_fs_use_t)
+
+
+def qpol_fs_use_from_void(*args):
+ return _qpol.qpol_fs_use_from_void(*args)
+qpol_fs_use_from_void = _qpol.qpol_fs_use_from_void
+QPOL_CLASS_ALL = _qpol.QPOL_CLASS_ALL
+QPOL_CLASS_BLK_FILE = _qpol.QPOL_CLASS_BLK_FILE
+QPOL_CLASS_CHR_FILE = _qpol.QPOL_CLASS_CHR_FILE
+QPOL_CLASS_DIR = _qpol.QPOL_CLASS_DIR
+QPOL_CLASS_FIFO_FILE = _qpol.QPOL_CLASS_FIFO_FILE
+QPOL_CLASS_FILE = _qpol.QPOL_CLASS_FILE
+QPOL_CLASS_LNK_FILE = _qpol.QPOL_CLASS_LNK_FILE
+QPOL_CLASS_SOCK_FILE = _qpol.QPOL_CLASS_SOCK_FILE
+class qpol_genfscon_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_genfscon_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_genfscon_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_genfscon_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_genfscon_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_genfscon_t_name(self, *args)
+ def path(self, *args): return _qpol.qpol_genfscon_t_path(self, *args)
+ def object_class(self, *args): return _qpol.qpol_genfscon_t_object_class(self, *args)
+ def context(self, *args): return _qpol.qpol_genfscon_t_context(self, *args)
+qpol_genfscon_t_swigregister = _qpol.qpol_genfscon_t_swigregister
+qpol_genfscon_t_swigregister(qpol_genfscon_t)
+
+
+def qpol_genfscon_from_void(*args):
+ return _qpol.qpol_genfscon_from_void(*args)
+qpol_genfscon_from_void = _qpol.qpol_genfscon_from_void
+class qpol_isid_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_isid_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_isid_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_isid_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_isid_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_isid_t_name(self, *args)
+ def context(self, *args): return _qpol.qpol_isid_t_context(self, *args)
+qpol_isid_t_swigregister = _qpol.qpol_isid_t_swigregister
+qpol_isid_t_swigregister(qpol_isid_t)
+
+
+def qpol_isid_from_void(*args):
+ return _qpol.qpol_isid_from_void(*args)
+qpol_isid_from_void = _qpol.qpol_isid_from_void
+class qpol_netifcon_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_netifcon_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_netifcon_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_netifcon_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_netifcon_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_netifcon_t_name(self, *args)
+ def msg_con(self, *args): return _qpol.qpol_netifcon_t_msg_con(self, *args)
+ def if_con(self, *args): return _qpol.qpol_netifcon_t_if_con(self, *args)
+qpol_netifcon_t_swigregister = _qpol.qpol_netifcon_t_swigregister
+qpol_netifcon_t_swigregister(qpol_netifcon_t)
+
+
+def qpol_netifcon_from_void(*args):
+ return _qpol.qpol_netifcon_from_void(*args)
+qpol_netifcon_from_void = _qpol.qpol_netifcon_from_void
+QPOL_IPV4 = _qpol.QPOL_IPV4
+QPOL_IPV6 = _qpol.QPOL_IPV6
+class qpol_nodecon_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_nodecon_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_nodecon_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_nodecon_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_nodecon_t
+ __del__ = lambda self : None;
+ def addr(self, *args): return _qpol.qpol_nodecon_t_addr(self, *args)
+ def mask(self, *args): return _qpol.qpol_nodecon_t_mask(self, *args)
+ def protocol(self, *args): return _qpol.qpol_nodecon_t_protocol(self, *args)
+ def context(self, *args): return _qpol.qpol_nodecon_t_context(self, *args)
+qpol_nodecon_t_swigregister = _qpol.qpol_nodecon_t_swigregister
+qpol_nodecon_t_swigregister(qpol_nodecon_t)
+
+
+def qpol_nodecon_from_void(*args):
+ return _qpol.qpol_nodecon_from_void(*args)
+qpol_nodecon_from_void = _qpol.qpol_nodecon_from_void
+IPPROTO_TCP = _qpol.IPPROTO_TCP
+IPPROTO_UDP = _qpol.IPPROTO_UDP
+class qpol_portcon_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_portcon_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_portcon_t, name)
+ __repr__ = _swig_repr
+ def __init__(self, *args):
+ this = _qpol.new_qpol_portcon_t(*args)
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_portcon_t
+ __del__ = lambda self : None;
+ def low_port(self, *args): return _qpol.qpol_portcon_t_low_port(self, *args)
+ def high_port(self, *args): return _qpol.qpol_portcon_t_high_port(self, *args)
+ def protocol(self, *args): return _qpol.qpol_portcon_t_protocol(self, *args)
+ def context(self, *args): return _qpol.qpol_portcon_t_context(self, *args)
+qpol_portcon_t_swigregister = _qpol.qpol_portcon_t_swigregister
+qpol_portcon_t_swigregister(qpol_portcon_t)
+
+
+def qpol_portcon_from_void(*args):
+ return _qpol.qpol_portcon_from_void(*args)
+qpol_portcon_from_void = _qpol.qpol_portcon_from_void
+class qpol_constraint_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_constraint_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_constraint_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_constraint_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_constraint_t
+ __del__ = lambda self : None;
+ def object_class(self, *args): return _qpol.qpol_constraint_t_object_class(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def perm_iter(self, *args): return _qpol.qpol_constraint_t_perm_iter(self, *args)
+ @QpolGenerator(_qpol.qpol_constraint_expr_node_from_void)
+ def expr_iter(self, *args): return _qpol.qpol_constraint_t_expr_iter(self, *args)
+qpol_constraint_t_swigregister = _qpol.qpol_constraint_t_swigregister
+qpol_constraint_t_swigregister(qpol_constraint_t)
+
+
+def qpol_constraint_from_void(*args):
+ return _qpol.qpol_constraint_from_void(*args)
+qpol_constraint_from_void = _qpol.qpol_constraint_from_void
+class qpol_validatetrans_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_validatetrans_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_validatetrans_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_validatetrans_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_validatetrans_t
+ __del__ = lambda self : None;
+ def object_class(self, *args): return _qpol.qpol_validatetrans_t_object_class(self, *args)
+ @QpolGenerator(_qpol.qpol_constraint_expr_node_from_void)
+ def expr_iter(self, *args): return _qpol.qpol_validatetrans_t_expr_iter(self, *args)
+qpol_validatetrans_t_swigregister = _qpol.qpol_validatetrans_t_swigregister
+qpol_validatetrans_t_swigregister(qpol_validatetrans_t)
+
+
+def qpol_validatetrans_from_void(*args):
+ return _qpol.qpol_validatetrans_from_void(*args)
+qpol_validatetrans_from_void = _qpol.qpol_validatetrans_from_void
+QPOL_CEXPR_TYPE_NOT = _qpol.QPOL_CEXPR_TYPE_NOT
+QPOL_CEXPR_TYPE_AND = _qpol.QPOL_CEXPR_TYPE_AND
+QPOL_CEXPR_TYPE_OR = _qpol.QPOL_CEXPR_TYPE_OR
+QPOL_CEXPR_TYPE_ATTR = _qpol.QPOL_CEXPR_TYPE_ATTR
+QPOL_CEXPR_TYPE_NAMES = _qpol.QPOL_CEXPR_TYPE_NAMES
+QPOL_CEXPR_SYM_USER = _qpol.QPOL_CEXPR_SYM_USER
+QPOL_CEXPR_SYM_ROLE = _qpol.QPOL_CEXPR_SYM_ROLE
+QPOL_CEXPR_SYM_TYPE = _qpol.QPOL_CEXPR_SYM_TYPE
+QPOL_CEXPR_SYM_TARGET = _qpol.QPOL_CEXPR_SYM_TARGET
+QPOL_CEXPR_SYM_XTARGET = _qpol.QPOL_CEXPR_SYM_XTARGET
+QPOL_CEXPR_SYM_L1L2 = _qpol.QPOL_CEXPR_SYM_L1L2
+QPOL_CEXPR_SYM_L1H2 = _qpol.QPOL_CEXPR_SYM_L1H2
+QPOL_CEXPR_SYM_H1L2 = _qpol.QPOL_CEXPR_SYM_H1L2
+QPOL_CEXPR_SYM_H1H2 = _qpol.QPOL_CEXPR_SYM_H1H2
+QPOL_CEXPR_SYM_L1H1 = _qpol.QPOL_CEXPR_SYM_L1H1
+QPOL_CEXPR_SYM_L2H2 = _qpol.QPOL_CEXPR_SYM_L2H2
+QPOL_CEXPR_OP_EQ = _qpol.QPOL_CEXPR_OP_EQ
+QPOL_CEXPR_OP_NEQ = _qpol.QPOL_CEXPR_OP_NEQ
+QPOL_CEXPR_OP_DOM = _qpol.QPOL_CEXPR_OP_DOM
+QPOL_CEXPR_OP_DOMBY = _qpol.QPOL_CEXPR_OP_DOMBY
+QPOL_CEXPR_OP_INCOMP = _qpol.QPOL_CEXPR_OP_INCOMP
+class qpol_constraint_expr_node_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_constraint_expr_node_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_constraint_expr_node_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_constraint_expr_node_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_constraint_expr_node_t
+ __del__ = lambda self : None;
+ def expr_type(self, *args): return _qpol.qpol_constraint_expr_node_t_expr_type(self, *args)
+ def sym_type(self, *args): return _qpol.qpol_constraint_expr_node_t_sym_type(self, *args)
+ def op(self, *args): return _qpol.qpol_constraint_expr_node_t_op(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def names_iter(self, *args): return _qpol.qpol_constraint_expr_node_t_names_iter(self, *args)
+qpol_constraint_expr_node_t_swigregister = _qpol.qpol_constraint_expr_node_t_swigregister
+qpol_constraint_expr_node_t_swigregister(qpol_constraint_expr_node_t)
+
+
+def qpol_constraint_expr_node_from_void(*args):
+ return _qpol.qpol_constraint_expr_node_from_void(*args)
+qpol_constraint_expr_node_from_void = _qpol.qpol_constraint_expr_node_from_void
+class qpol_role_allow_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_role_allow_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_role_allow_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_role_allow_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_role_allow_t
+ __del__ = lambda self : None;
+ def rule_type(self,policy):
+ return "allow"
+
+ def source_role(self, *args): return _qpol.qpol_role_allow_t_source_role(self, *args)
+ def target_role(self, *args): return _qpol.qpol_role_allow_t_target_role(self, *args)
+qpol_role_allow_t_swigregister = _qpol.qpol_role_allow_t_swigregister
+qpol_role_allow_t_swigregister(qpol_role_allow_t)
+
+
+def qpol_role_allow_from_void(*args):
+ return _qpol.qpol_role_allow_from_void(*args)
+qpol_role_allow_from_void = _qpol.qpol_role_allow_from_void
+class qpol_role_trans_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_role_trans_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_role_trans_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_role_trans_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_role_trans_t
+ __del__ = lambda self : None;
+ def rule_type(self,policy):
+ return "role_transition"
+
+ def source_role(self, *args): return _qpol.qpol_role_trans_t_source_role(self, *args)
+ def target_type(self, *args): return _qpol.qpol_role_trans_t_target_type(self, *args)
+ def object_class(self, *args): return _qpol.qpol_role_trans_t_object_class(self, *args)
+ def default_role(self, *args): return _qpol.qpol_role_trans_t_default_role(self, *args)
+qpol_role_trans_t_swigregister = _qpol.qpol_role_trans_t_swigregister
+qpol_role_trans_t_swigregister(qpol_role_trans_t)
+
+
+def qpol_role_trans_from_void(*args):
+ return _qpol.qpol_role_trans_from_void(*args)
+qpol_role_trans_from_void = _qpol.qpol_role_trans_from_void
+class qpol_range_trans_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_range_trans_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_range_trans_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_range_trans_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_range_trans_t
+ __del__ = lambda self : None;
+ def rule_type(self,policy):
+ return "range_transition"
+
+ def source_type(self, *args): return _qpol.qpol_range_trans_t_source_type(self, *args)
+ def target_type(self, *args): return _qpol.qpol_range_trans_t_target_type(self, *args)
+ def object_class(self, *args): return _qpol.qpol_range_trans_t_object_class(self, *args)
+ def range(self, *args): return _qpol.qpol_range_trans_t_range(self, *args)
+qpol_range_trans_t_swigregister = _qpol.qpol_range_trans_t_swigregister
+qpol_range_trans_t_swigregister(qpol_range_trans_t)
+
+
+def qpol_range_trans_from_void(*args):
+ return _qpol.qpol_range_trans_from_void(*args)
+qpol_range_trans_from_void = _qpol.qpol_range_trans_from_void
+QPOL_RULE_ALLOW = _qpol.QPOL_RULE_ALLOW
+QPOL_RULE_NEVERALLOW = _qpol.QPOL_RULE_NEVERALLOW
+QPOL_RULE_AUDITALLOW = _qpol.QPOL_RULE_AUDITALLOW
+QPOL_RULE_DONTAUDIT = _qpol.QPOL_RULE_DONTAUDIT
+class qpol_avrule_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_avrule_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_avrule_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_avrule_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_avrule_t
+ __del__ = lambda self : None;
+ def rule_type(self, *args): return _qpol.qpol_avrule_t_rule_type(self, *args)
+ def source_type(self, *args): return _qpol.qpol_avrule_t_source_type(self, *args)
+ def target_type(self, *args): return _qpol.qpol_avrule_t_target_type(self, *args)
+ def object_class(self, *args): return _qpol.qpol_avrule_t_object_class(self, *args)
+ @QpolGenerator(_qpol.to_str)
+ def perm_iter(self, *args): return _qpol.qpol_avrule_t_perm_iter(self, *args)
+ def cond(self, *args): return _qpol.qpol_avrule_t_cond(self, *args)
+ def is_enabled(self, *args): return _qpol.qpol_avrule_t_is_enabled(self, *args)
+ def which_list(self, *args): return _qpol.qpol_avrule_t_which_list(self, *args)
+ def syn_avrule_iter(self, *args): return _qpol.qpol_avrule_t_syn_avrule_iter(self, *args)
+qpol_avrule_t_swigregister = _qpol.qpol_avrule_t_swigregister
+qpol_avrule_t_swigregister(qpol_avrule_t)
+
+
+def qpol_avrule_from_void(*args):
+ return _qpol.qpol_avrule_from_void(*args)
+qpol_avrule_from_void = _qpol.qpol_avrule_from_void
+QPOL_RULE_TYPE_TRANS = _qpol.QPOL_RULE_TYPE_TRANS
+QPOL_RULE_TYPE_CHANGE = _qpol.QPOL_RULE_TYPE_CHANGE
+QPOL_RULE_TYPE_MEMBER = _qpol.QPOL_RULE_TYPE_MEMBER
+class qpol_terule_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_terule_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_terule_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_terule_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_terule_t
+ __del__ = lambda self : None;
+ def rule_type(self, *args): return _qpol.qpol_terule_t_rule_type(self, *args)
+ def source_type(self, *args): return _qpol.qpol_terule_t_source_type(self, *args)
+ def target_type(self, *args): return _qpol.qpol_terule_t_target_type(self, *args)
+ def object_class(self, *args): return _qpol.qpol_terule_t_object_class(self, *args)
+ def default_type(self, *args): return _qpol.qpol_terule_t_default_type(self, *args)
+ def cond(self, *args): return _qpol.qpol_terule_t_cond(self, *args)
+ def is_enabled(self, *args): return _qpol.qpol_terule_t_is_enabled(self, *args)
+ def which_list(self, *args): return _qpol.qpol_terule_t_which_list(self, *args)
+ def syn_terule_iter(self, *args): return _qpol.qpol_terule_t_syn_terule_iter(self, *args)
+qpol_terule_t_swigregister = _qpol.qpol_terule_t_swigregister
+qpol_terule_t_swigregister(qpol_terule_t)
+
+
+def qpol_terule_from_void(*args):
+ return _qpol.qpol_terule_from_void(*args)
+qpol_terule_from_void = _qpol.qpol_terule_from_void
+class qpol_cond_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_cond_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_cond_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_cond_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_cond_t
+ __del__ = lambda self : None;
+ @QpolGenerator(_qpol.qpol_cond_expr_node_from_void)
+ def expr_node_iter(self, *args): return _qpol.qpol_cond_t_expr_node_iter(self, *args)
+ def av_true_iter(self, *args): return _qpol.qpol_cond_t_av_true_iter(self, *args)
+ def av_false_iter(self, *args): return _qpol.qpol_cond_t_av_false_iter(self, *args)
+ def te_true_iter(self, *args): return _qpol.qpol_cond_t_te_true_iter(self, *args)
+ def te_false_iter(self, *args): return _qpol.qpol_cond_t_te_false_iter(self, *args)
+ def evaluate(self, *args): return _qpol.qpol_cond_t_evaluate(self, *args)
+qpol_cond_t_swigregister = _qpol.qpol_cond_t_swigregister
+qpol_cond_t_swigregister(qpol_cond_t)
+
+
+def qpol_cond_from_void(*args):
+ return _qpol.qpol_cond_from_void(*args)
+qpol_cond_from_void = _qpol.qpol_cond_from_void
+QPOL_COND_EXPR_BOOL = _qpol.QPOL_COND_EXPR_BOOL
+QPOL_COND_EXPR_NOT = _qpol.QPOL_COND_EXPR_NOT
+QPOL_COND_EXPR_OR = _qpol.QPOL_COND_EXPR_OR
+QPOL_COND_EXPR_AND = _qpol.QPOL_COND_EXPR_AND
+QPOL_COND_EXPR_XOR = _qpol.QPOL_COND_EXPR_XOR
+QPOL_COND_EXPR_EQ = _qpol.QPOL_COND_EXPR_EQ
+QPOL_COND_EXPR_NEQ = _qpol.QPOL_COND_EXPR_NEQ
+class qpol_cond_expr_node_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_cond_expr_node_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_cond_expr_node_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_cond_expr_node_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_cond_expr_node_t
+ __del__ = lambda self : None;
+ def expr_type(self, *args): return _qpol.qpol_cond_expr_node_t_expr_type(self, *args)
+ def get_boolean(self, *args): return _qpol.qpol_cond_expr_node_t_get_boolean(self, *args)
+qpol_cond_expr_node_t_swigregister = _qpol.qpol_cond_expr_node_t_swigregister
+qpol_cond_expr_node_t_swigregister(qpol_cond_expr_node_t)
+
+
+def qpol_cond_expr_node_from_void(*args):
+ return _qpol.qpol_cond_expr_node_from_void(*args)
+qpol_cond_expr_node_from_void = _qpol.qpol_cond_expr_node_from_void
+class qpol_filename_trans_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_filename_trans_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_filename_trans_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_filename_trans_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_filename_trans_t
+ __del__ = lambda self : None;
+ def rule_type(self,policy):
+ return "type_transition"
+
+ def source_type(self, *args): return _qpol.qpol_filename_trans_t_source_type(self, *args)
+ def target_type(self, *args): return _qpol.qpol_filename_trans_t_target_type(self, *args)
+ def object_class(self, *args): return _qpol.qpol_filename_trans_t_object_class(self, *args)
+ def default_type(self, *args): return _qpol.qpol_filename_trans_t_default_type(self, *args)
+ def filename(self, *args): return _qpol.qpol_filename_trans_t_filename(self, *args)
+qpol_filename_trans_t_swigregister = _qpol.qpol_filename_trans_t_swigregister
+qpol_filename_trans_t_swigregister(qpol_filename_trans_t)
+
+
+def qpol_filename_trans_from_void(*args):
+ return _qpol.qpol_filename_trans_from_void(*args)
+qpol_filename_trans_from_void = _qpol.qpol_filename_trans_from_void
+class qpol_polcap_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_polcap_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_polcap_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_polcap_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_polcap_t
+ __del__ = lambda self : None;
+ def name(self, *args): return _qpol.qpol_polcap_t_name(self, *args)
+qpol_polcap_t_swigregister = _qpol.qpol_polcap_t_swigregister
+qpol_polcap_t_swigregister(qpol_polcap_t)
+
+
+def qpol_polcap_from_void(*args):
+ return _qpol.qpol_polcap_from_void(*args)
+qpol_polcap_from_void = _qpol.qpol_polcap_from_void
+class qpol_typebounds_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_typebounds_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_typebounds_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_typebounds_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_typebounds_t
+ __del__ = lambda self : None;
+ def parent_name(self, *args): return _qpol.qpol_typebounds_t_parent_name(self, *args)
+ def child_name(self, *args): return _qpol.qpol_typebounds_t_child_name(self, *args)
+qpol_typebounds_t_swigregister = _qpol.qpol_typebounds_t_swigregister
+qpol_typebounds_t_swigregister(qpol_typebounds_t)
+
+
+def qpol_typebounds_from_void(*args):
+ return _qpol.qpol_typebounds_from_void(*args)
+qpol_typebounds_from_void = _qpol.qpol_typebounds_from_void
+class qpol_rolebounds_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_rolebounds_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_rolebounds_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_rolebounds_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_rolebounds_t
+ __del__ = lambda self : None;
+ def parent_name(self, *args): return _qpol.qpol_rolebounds_t_parent_name(self, *args)
+ def child_name(self, *args): return _qpol.qpol_rolebounds_t_child_name(self, *args)
+qpol_rolebounds_t_swigregister = _qpol.qpol_rolebounds_t_swigregister
+qpol_rolebounds_t_swigregister(qpol_rolebounds_t)
+
+
+def qpol_rolebounds_from_void(*args):
+ return _qpol.qpol_rolebounds_from_void(*args)
+qpol_rolebounds_from_void = _qpol.qpol_rolebounds_from_void
+class qpol_userbounds_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_userbounds_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_userbounds_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_userbounds_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_userbounds_t
+ __del__ = lambda self : None;
+ def parent_name(self, *args): return _qpol.qpol_userbounds_t_parent_name(self, *args)
+ def child_name(self, *args): return _qpol.qpol_userbounds_t_child_name(self, *args)
+qpol_userbounds_t_swigregister = _qpol.qpol_userbounds_t_swigregister
+qpol_userbounds_t_swigregister(qpol_userbounds_t)
+
+
+def qpol_userbounds_from_void(*args):
+ return _qpol.qpol_userbounds_from_void(*args)
+qpol_userbounds_from_void = _qpol.qpol_userbounds_from_void
+class qpol_default_object_t(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, qpol_default_object_t, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, qpol_default_object_t, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _qpol.new_qpol_default_object_t()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _qpol.delete_qpol_default_object_t
+ __del__ = lambda self : None;
+ def object_class(self, *args): return _qpol.qpol_default_object_t_object_class(self, *args)
+ def user_default(self, *args): return _qpol.qpol_default_object_t_user_default(self, *args)
+ def role_default(self, *args): return _qpol.qpol_default_object_t_role_default(self, *args)
+ def type_default(self, *args): return _qpol.qpol_default_object_t_type_default(self, *args)
+ def range_default(self, *args): return _qpol.qpol_default_object_t_range_default(self, *args)
+qpol_default_object_t_swigregister = _qpol.qpol_default_object_t_swigregister
+qpol_default_object_t_swigregister(qpol_default_object_t)
+
+
+def qpol_default_object_from_void(*args):
+ return _qpol.qpol_default_object_from_void(*args)
+qpol_default_object_from_void = _qpol.qpol_default_object_from_void
+# This file is compatible with both classic and new-style classes.
+
+
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rbacrule.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rbacrule.py
new file mode 100644
index 0000000..aa6a0d0
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rbacrule.py
@@ -0,0 +1,92 @@
+# Copyright 2014, 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 qpol
+from . import rule
+from . import role
+from . import typeattr
+
+
+def rbac_rule_factory(policy, name):
+ """Factory function for creating RBAC rule objects."""
+
+ if isinstance(name, qpol.qpol_role_allow_t):
+ return RoleAllow(policy, name)
+ elif isinstance(name, qpol.qpol_role_trans_t):
+ return RoleTransition(policy, name)
+ else:
+ raise TypeError("RBAC rules cannot be looked up.")
+
+
+def validate_ruletype(types):
+ """Validate RBAC rule types."""
+ for t in types:
+ if t not in ["allow", "role_transition"]:
+ raise exception.InvalidRBACRuleType("{0} is not a valid RBAC rule type.".format(t))
+
+
+class RoleAllow(rule.PolicyRule):
+
+ """A role allow rule."""
+
+ def __str__(self):
+ return "allow {0.source} {0.target};".format(self)
+
+ @property
+ def source(self):
+ """The rule's source role."""
+ return role.role_factory(self.policy, self.qpol_symbol.source_role(self.policy))
+
+ @property
+ def target(self):
+ """The rule's target role."""
+ return role.role_factory(self.policy, self.qpol_symbol.target_role(self.policy))
+
+ @property
+ def tclass(self):
+ """The rule's object class."""
+ raise exception.RuleUseError("Role allow rules do not have an object class.")
+
+ @property
+ def default(self):
+ """The rule's default role."""
+ raise exception.RuleUseError("Role allow rules do not have a default role.")
+
+
+class RoleTransition(rule.PolicyRule):
+
+ """A role_transition rule."""
+
+ def __str__(self):
+ return "role_transition {0.source} {0.target}:{0.tclass} {0.default};".format(self)
+
+ @property
+ def source(self):
+ """The rule's source role."""
+ return role.role_factory(self.policy, self.qpol_symbol.source_role(self.policy))
+
+ @property
+ def target(self):
+ """The rule's target type/attribute."""
+ return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy))
+
+ @property
+ def default(self):
+ """The rule's default role."""
+ return role.role_factory(self.policy, self.qpol_symbol.default_role(self.policy))
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/role.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/role.py
new file mode 100644
index 0000000..1d9fbe1
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/role.py
@@ -0,0 +1,81 @@
+# Copyright 2014, 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 qpol
+from . import symbol
+from . import typeattr
+
+
+def role_factory(qpol_policy, name):
+ """Factory function for creating Role objects."""
+
+ if isinstance(name, Role):
+ assert name.policy == qpol_policy
+ return name
+ elif isinstance(name, qpol.qpol_role_t):
+ return Role(qpol_policy, name)
+
+ try:
+ return Role(qpol_policy, qpol.qpol_role_t(qpol_policy, str(name)))
+ except ValueError:
+ raise exception.InvalidRole("{0} is not a valid role".format(name))
+
+
+class BaseRole(symbol.PolicySymbol):
+
+ """Role/role attribute base class."""
+
+ def expand(self):
+ raise NotImplementedError
+
+ def types(self):
+ raise NotImplementedError
+
+
+class Role(BaseRole):
+
+ """A role."""
+
+ def expand(self):
+ """Generator that expands this into its member roles."""
+ yield self
+
+ def types(self):
+ """Generator which yields the role's set of types."""
+
+ for type_ in self.qpol_symbol.type_iter(self.policy):
+ yield typeattr.type_or_attr_factory(self.policy, type_)
+
+ def statement(self):
+ types = list(str(t) for t in self.types())
+ stmt = "role {0}".format(self)
+ if types:
+ if (len(types) > 1):
+ stmt += " types {{ {0} }}".format(' '.join(types))
+ else:
+ stmt += " types {0}".format(types[0])
+ stmt += ";"
+ return stmt
+
+
+class RoleAttribute(BaseRole):
+
+ """A role attribute."""
+
+ pass
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rule.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rule.py
new file mode 100644
index 0000000..73fc812
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/rule.py
@@ -0,0 +1,72 @@
+# Copyright 2014, 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
+
+
+class PolicyRule(symbol.PolicySymbol):
+
+ """This is base class for policy rules."""
+
+ def __str__(self):
+ raise NotImplementedError
+
+ @property
+ def ruletype(self):
+ """The rule type for the rule."""
+ return self.qpol_symbol.rule_type(self.policy)
+
+ @property
+ def source(self):
+ """
+ The source for the rule. This should be overridden by
+ subclasses.
+ """
+ raise NotImplementedError
+
+ @property
+ def target(self):
+ """
+ The target for the rule. This should be overridden by
+ subclasses.
+ """
+ raise NotImplementedError
+
+ @property
+ def tclass(self):
+ """The object class for the rule."""
+ return objclass.class_factory(self.policy, self.qpol_symbol.object_class(self.policy))
+
+ @property
+ def default(self):
+ """
+ The default for the rule. This should be overridden by
+ subclasses.
+ """
+ raise NotImplementedError
+
+ @property
+ def conditional(self):
+ """The conditional expression for this rule."""
+ # Most rules cannot be conditional.
+ raise exception.RuleNotConditional
+
+ def statement(self):
+ return str(self)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/symbol.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/symbol.py
new file mode 100644
index 0000000..4712d7f
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/symbol.py
@@ -0,0 +1,74 @@
+# Copyright 2014, 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/>.
+#
+
+
+class PolicySymbol(object):
+
+ """This is a base class for all policy objects."""
+
+ def __init__(self, policy, qpol_symbol):
+ """
+ Parameters:
+ policy The low-level policy object.
+ qpol_symbol The low-level policy symbol object.
+ """
+
+ assert qpol_symbol
+
+ self.policy = policy
+ self.qpol_symbol = qpol_symbol
+
+ def __str__(self):
+ return self.qpol_symbol.name(self.policy)
+
+ def __hash__(self):
+ return hash(self.qpol_symbol.name(self.policy))
+
+ def __eq__(self, other):
+ try:
+ return self.qpol_symbol.this == other.qpol_symbol.this
+ except AttributeError:
+ return str(self) == str(other)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __lt__(self, other):
+ """Comparison used by Python sorting functions."""
+ return str(self) < str(other)
+
+ def __repr__(self):
+ return "<{0.__class__.__name__}(<qpol_policy_t id={1}>,\"{0}\")>".format(
+ self, id(self.policy))
+
+ def __deepcopy__(self, memo):
+ # shallow copy as all of the members are immutable
+ cls = self.__class__
+ newobj = cls.__new__(cls)
+ newobj.policy = self.policy
+ newobj.qpol_symbol = self.qpol_symbol
+ memo[id(self)] = newobj
+ return newobj
+
+ def statement(self):
+ """
+ A rendering of the policy statement. This should be
+ overridden by subclasses.
+ """
+ raise NotImplementedError
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/terule.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/terule.py
new file mode 100644
index 0000000..d8a9e94
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/terule.py
@@ -0,0 +1,155 @@
+# Copyright 2014, 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 qpol
+from . import rule
+from . import typeattr
+from . import boolcond
+
+
+def te_rule_factory(policy, symbol):
+ """Factory function for creating TE rule objects."""
+
+ if isinstance(symbol, qpol.qpol_avrule_t):
+ return AVRule(policy, symbol)
+ elif isinstance(symbol, (qpol.qpol_terule_t, qpol.qpol_filename_trans_t)):
+ return TERule(policy, symbol)
+ else:
+ raise TypeError("TE rules cannot be looked-up.")
+
+
+def validate_ruletype(types):
+ """Validate TE Rule types."""
+ for t in types:
+ if t not in ["allow", "auditallow", "dontaudit", "neverallow",
+ "type_transition", "type_member", "type_change"]:
+ raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t))
+
+
+class BaseTERule(rule.PolicyRule):
+
+ """A type enforcement rule."""
+
+ @property
+ def source(self):
+ """The rule's source type/attribute."""
+ return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.source_type(self.policy))
+
+ @property
+ def target(self):
+ """The rule's target type/attribute."""
+ return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy))
+
+ @property
+ def filename(self):
+ raise NotImplementedError
+
+ @property
+ def conditional(self):
+ """The rule's conditional expression."""
+ try:
+ return boolcond.condexpr_factory(self.policy, self.qpol_symbol.cond(self.policy))
+ except (AttributeError, ValueError):
+ # AttributeError: name filetrans rules cannot be conditional
+ # so no member function
+ # ValueError: The rule is not conditional
+ raise exception.RuleNotConditional
+
+
+class AVRule(BaseTERule):
+
+ """An access vector type enforcement rule."""
+
+ def __str__(self):
+ rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} ".format(
+ self)
+
+ perms = self.perms
+
+ # allow/dontaudit/auditallow/neverallow rules
+ if len(perms) > 1:
+ rule_string += "{{ {0} }};".format(' '.join(perms))
+ else:
+ # convert to list since sets cannot be indexed
+ rule_string += "{0};".format(list(perms)[0])
+
+ try:
+ rule_string += " [ {0} ]".format(self.conditional)
+ except exception.RuleNotConditional:
+ pass
+
+ return rule_string
+
+ @property
+ def perms(self):
+ """The rule's permission set."""
+ return set(self.qpol_symbol.perm_iter(self.policy))
+
+ @property
+ def default(self):
+ """The rule's default type."""
+ raise exception.RuleUseError("{0} rules do not have a default type.".format(self.ruletype))
+
+ @property
+ def filename(self):
+ raise exception.RuleUseError("{0} rules do not have file names".format(self.ruletype))
+
+
+class TERule(BaseTERule):
+
+ """A type_* type enforcement rule."""
+
+ def __str__(self):
+ rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default}".format(self)
+
+ try:
+ rule_string += " \"{0}\";".format(self.filename)
+ except (exception.TERuleNoFilename, exception.RuleUseError):
+ # invalid use for type_change/member
+ rule_string += ";"
+
+ try:
+ rule_string += " [ {0} ]".format(self.conditional)
+ except exception.RuleNotConditional:
+ pass
+
+ return rule_string
+
+ @property
+ def perms(self):
+ """The rule's permission set."""
+ raise exception.RuleUseError(
+ "{0} rules do not have a permission set.".format(self.ruletype))
+
+ @property
+ def default(self):
+ """The rule's default type."""
+ return typeattr.type_factory(self.policy, self.qpol_symbol.default_type(self.policy))
+
+ @property
+ def filename(self):
+ """The type_transition rule's file name."""
+ try:
+ return self.qpol_symbol.filename(self.policy)
+ except AttributeError:
+ if self.ruletype == "type_transition":
+ raise exception.TERuleNoFilename
+ else:
+ raise exception.RuleUseError("{0} rules do not have file names".
+ format(self.ruletype))
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/typeattr.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/typeattr.py
new file mode 100644
index 0000000..a52c69a
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/typeattr.py
@@ -0,0 +1,174 @@
+# Copyright 2014, 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 qpol
+from . import symbol
+
+
+def _symbol_lookup(qpol_policy, name):
+ """Look up the low-level qpol policy reference"""
+ if isinstance(name, qpol.qpol_type_t):
+ return name
+
+ try:
+ return qpol.qpol_type_t(qpol_policy, str(name))
+ except ValueError:
+ raise exception.InvalidType("{0} is not a valid type/attribute".format(name))
+
+
+def attribute_factory(qpol_policy, name):
+ """Factory function for creating attribute objects."""
+
+ if isinstance(name, TypeAttribute):
+ assert name.policy == qpol_policy
+ return name
+
+ qpol_symbol = _symbol_lookup(qpol_policy, name)
+
+ if not qpol_symbol.isattr(qpol_policy):
+ raise TypeError("{0} is a type".format(qpol_symbol.name(qpol_policy)))
+
+ return TypeAttribute(qpol_policy, qpol_symbol)
+
+
+def type_factory(qpol_policy, name, deref=False):
+ """Factory function for creating type objects."""
+
+ if isinstance(name, Type):
+ assert name.policy == qpol_policy
+ return name
+
+ qpol_symbol = _symbol_lookup(qpol_policy, name)
+
+ if qpol_symbol.isattr(qpol_policy):
+ raise TypeError("{0} is an attribute".format(qpol_symbol.name(qpol_policy)))
+ elif qpol_symbol.isalias(qpol_policy) and not deref:
+ raise TypeError("{0} is an alias.".format(qpol_symbol.name(qpol_policy)))
+
+ return Type(qpol_policy, qpol_symbol)
+
+
+def type_or_attr_factory(qpol_policy, name, deref=False):
+ """Factory function for creating type or attribute objects."""
+
+ if isinstance(name, (Type, TypeAttribute)):
+ assert name.policy == qpol_policy
+ return name
+
+ qpol_symbol = _symbol_lookup(qpol_policy, name)
+
+ if qpol_symbol.isalias(qpol_policy) and not deref:
+ raise TypeError("{0} is an alias.".format(qpol_symbol.name(qpol_policy)))
+
+ if qpol_symbol.isattr(qpol_policy):
+ return TypeAttribute(qpol_policy, qpol_symbol)
+ else:
+ return Type(qpol_policy, qpol_symbol)
+
+
+class BaseType(symbol.PolicySymbol):
+
+ """Type/attribute base class."""
+
+ @property
+ def ispermissive(self):
+ raise NotImplementedError
+
+ def expand(self):
+ """Generator that expands this attribute into its member types."""
+ raise NotImplementedError
+
+ def attributes(self):
+ """Generator that yields all attributes for this type."""
+ raise NotImplementedError
+
+ def aliases(self):
+ """Generator that yields all aliases for this type."""
+ raise NotImplementedError
+
+
+class Type(BaseType):
+
+ """A type."""
+
+ @property
+ def ispermissive(self):
+ """(T/F) the type is permissive."""
+ return self.qpol_symbol.ispermissive(self.policy)
+
+ def expand(self):
+ """Generator that expands this into its member types."""
+ yield self
+
+ def attributes(self):
+ """Generator that yields all attributes for this type."""
+ for attr in self.qpol_symbol.attr_iter(self.policy):
+ yield attribute_factory(self.policy, attr)
+
+ def aliases(self):
+ """Generator that yields all aliases for this type."""
+ for alias in self.qpol_symbol.alias_iter(self.policy):
+ yield alias
+
+ def statement(self):
+ attrs = list(self.attributes())
+ aliases = list(self.aliases())
+ stmt = "type {0}".format(self)
+ if aliases:
+ if len(aliases) > 1:
+ stmt += " alias {{ {0} }}".format(' '.join(aliases))
+ else:
+ stmt += " alias {0}".format(aliases[0])
+ for attr in attrs:
+ stmt += ", {0}".format(attr)
+ stmt += ";"
+ return stmt
+
+
+class TypeAttribute(BaseType):
+
+ """An attribute."""
+
+ def __contains__(self, other):
+ for type_ in self.expand():
+ if other == type_:
+ return True
+
+ return False
+
+ def expand(self):
+ """Generator that expands this attribute into its member types."""
+ for type_ in self.qpol_symbol.type_iter(self.policy):
+ yield type_factory(self.policy, type_)
+
+ def attributes(self):
+ """Generator that yields all attributes for this type."""
+ raise TypeError("{0} is an attribute, thus does not have attributes.".format(self))
+
+ def aliases(self):
+ """Generator that yields all aliases for this type."""
+ raise TypeError("{0} is an attribute, thus does not have aliases.".format(self))
+
+ @property
+ def ispermissive(self):
+ """(T/F) the type is permissive."""
+ raise TypeError("{0} is an attribute, thus cannot be permissive.".format(self))
+
+ def statement(self):
+ return "attribute {0};".format(self)
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/policyrep/user.py b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/user.py
new file mode 100644
index 0000000..94f81bc
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/policyrep/user.py
@@ -0,0 +1,86 @@
+# Copyright 2014, 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 qpol
+from . import role
+from . import mls
+from . import symbol
+
+
+def user_factory(qpol_policy, name):
+ """Factory function for creating User objects."""
+
+ if isinstance(name, User):
+ assert name.policy == qpol_policy
+ return name
+ elif isinstance(name, qpol.qpol_user_t):
+ return User(qpol_policy, name)
+
+ try:
+ return User(qpol_policy, qpol.qpol_user_t(qpol_policy, str(name)))
+ except ValueError:
+ raise exception.InvalidUser("{0} is not a valid user".format(name))
+
+
+class User(symbol.PolicySymbol):
+
+ """A user."""
+
+ @property
+ def roles(self):
+ """The user's set of roles."""
+
+ roleset = set()
+
+ for role_ in self.qpol_symbol.role_iter(self.policy):
+ item = role.role_factory(self.policy, role_)
+
+ # object_r is implicitly added to all roles by the compiler.
+ # technically it is incorrect to skip it, but policy writers
+ # and analysts don't expect to see it in results, and it
+ # will confuse, especially for role set equality user queries.
+ if item != "object_r":
+ roleset.add(item)
+
+ return roleset
+
+ @property
+ def mls_level(self):
+ """The user's default MLS level."""
+ return mls.level_factory(self.policy, self.qpol_symbol.dfltlevel(self.policy))
+
+ @property
+ def mls_range(self):
+ """The user's MLS range."""
+ return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy))
+
+ def statement(self):
+ roles = list(str(r) for r in self.roles)
+ stmt = "user {0} roles ".format(self)
+ if len(roles) > 1:
+ stmt += "{{ {0} }}".format(' '.join(roles))
+ else:
+ stmt += roles[0]
+
+ try:
+ stmt += " level {0.mls_level} range {0.mls_range};".format(self)
+ except exception.MLSDisabled:
+ stmt += ";"
+
+ return stmt
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/portconquery.py b/lib/python2.7/site-packages/setoolsgui/setools/portconquery.py
new file mode 100644
index 0000000..798a828
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/portconquery.py
@@ -0,0 +1,146 @@
+# Copyright 2014-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 logging
+from socket import IPPROTO_TCP, IPPROTO_UDP
+
+from . import contextquery
+from .policyrep.netcontext import port_range
+
+
+class PortconQuery(contextquery.ContextQuery):
+
+ """
+ Port context query.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ protocol The protocol to match (socket.IPPROTO_TCP for
+ TCP or socket.IPPROTO_UDP for UDP)
+
+ ports A 2-tuple of the port range to match. (Set both to
+ the same value for a single port)
+ ports_subset If true, the criteria will match if it is a subset
+ of the portcon's range.
+ ports_overlap If true, the criteria will match if it overlaps
+ any of the portcon's range.
+ ports_superset If true, the criteria will match if it is a superset
+ of the portcon's range.
+ ports_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+
+ user The criteria to match the context's user.
+ user_regex If true, regular expression matching
+ will be used on the user.
+
+ role The criteria to match the context's role.
+ role_regex If true, regular expression matching
+ will be used on the role.
+
+ type_ The criteria to match the context's type.
+ type_regex If true, regular expression matching
+ will be used on the type.
+
+ range_ The criteria to match the context's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the context's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the context's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the context's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ _protocol = None
+ _ports = None
+ ports_subset = False
+ ports_overlap = False
+ ports_superset = False
+ ports_proper = False
+
+ @property
+ def ports(self):
+ return self._ports
+
+ @ports.setter
+ def ports(self, value):
+ pending_ports = port_range(*value)
+
+ if all(pending_ports):
+ if pending_ports.low < 1 or pending_ports.high < 1:
+ raise ValueError("Port numbers must be positive: {0.low}-{0.high}".
+ format(pending_ports))
+
+ if pending_ports.low > pending_ports.high:
+ raise ValueError(
+ "The low port must be smaller than the high port: {0.low}-{0.high}".
+ format(pending_ports))
+
+ self._ports = pending_ports
+ else:
+ self._ports = None
+
+ @property
+ def protocol(self):
+ return self._protocol
+
+ @protocol.setter
+ def protocol(self, value):
+ if value:
+ if not (value == IPPROTO_TCP or value == IPPROTO_UDP):
+ raise ValueError(
+ "The protocol must be {0} for TCP or {1} for UDP.".
+ format(IPPROTO_TCP, IPPROTO_UDP))
+
+ self._protocol = value
+ else:
+ self._protocol = None
+
+ def results(self):
+ """Generator which yields all matching portcons."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ports: {0.ports}, overlap: {0.ports_overlap}, "
+ "subset: {0.ports_subset}, superset: {0.ports_superset}, "
+ "proper: {0.ports_proper}".format(self))
+ self.log.debug("User: {0.user!r}, regex: {0.user_regex}".format(self))
+ self.log.debug("Role: {0.role!r}, regex: {0.role_regex}".format(self))
+ self.log.debug("Type: {0.type_!r}, regex: {0.type_regex}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for portcon in self.policy.portcons():
+
+ if self.ports and not self._match_range(
+ portcon.ports,
+ self.ports,
+ self.ports_subset,
+ self.ports_overlap,
+ self.ports_superset,
+ self.ports_proper):
+ continue
+
+ if self.protocol and self.protocol != portcon.protocol:
+ continue
+
+ if not self._match_context(portcon.context):
+ continue
+
+ yield portcon
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/query.py b/lib/python2.7/site-packages/setoolsgui/setools/query.py
new file mode 100644
index 0000000..358a095
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/query.py
@@ -0,0 +1,192 @@
+# Copyright 2014-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 logging
+
+
+class PolicyQuery(object):
+
+ """Base class for SELinux policy queries."""
+
+ def __init__(self, policy, **kwargs):
+ self.log = logging.getLogger(self.__class__.__name__)
+
+ self.policy = policy
+
+ # keys are sorted in reverse order so regex settings
+ # are set before the criteria, e.g. name_regex
+ # is set before name. This ensures correct behavior
+ # since the criteria descriptors are sensitve to
+ # regex settings.
+ for name in sorted(kwargs.keys(), reverse=True):
+ attr = getattr(self, name, None) # None is not callable
+ if callable(attr):
+ raise ValueError("Keyword parameter {0} conflicts with a callable.".format(name))
+
+ setattr(self, name, kwargs[name])
+
+ @staticmethod
+ def _match_regex(obj, criteria, regex):
+ """
+ Match the object with optional regular expression.
+
+ Parameters:
+ obj The object to match.
+ criteria The criteria to match.
+ regex If regular expression matching should be used.
+ """
+
+ if regex:
+ return bool(criteria.search(str(obj)))
+ else:
+ return obj == criteria
+
+ @staticmethod
+ def _match_set(obj, criteria, equal):
+ """
+ Match the object (a set) with optional set equality.
+
+ Parameters:
+ obj The object to match. (a set)
+ criteria The criteria to match. (a set)
+ equal If set equality should be used. Otherwise
+ any set intersection will match.
+ """
+
+ if equal:
+ return obj == criteria
+ else:
+ return bool(obj.intersection(criteria))
+
+ @staticmethod
+ def _match_in_set(obj, criteria, regex):
+ """
+ Match if the criteria is in the list, with optional
+ regular expression matching.
+
+ Parameters:
+ obj The object to match.
+ criteria The criteria to match.
+ regex If regular expression matching should be used.
+ """
+
+ if regex:
+ return [m for m in obj if criteria.search(str(m))]
+ else:
+ return criteria in obj
+
+ @staticmethod
+ def _match_indirect_regex(obj, criteria, indirect, regex):
+ """
+ Match the object with optional regular expression and indirection.
+
+ Parameters:
+ obj The object to match.
+ criteria The criteria to match.
+ regex If regular expression matching should be used.
+ indirect If object indirection should be used, e.g.
+ expanding an attribute.
+ """
+
+ if indirect:
+ return PolicyQuery._match_in_set((obj.expand()), criteria, regex)
+ else:
+ return PolicyQuery._match_regex(obj, criteria, regex)
+
+ @staticmethod
+ def _match_regex_or_set(obj, criteria, equal, regex):
+ """
+ Match the object (a set) with either set comparisons
+ (equality or intersection) or by regex matching of the
+ set members. Regular expression matching will override
+ the set equality option.
+
+ Parameters:
+ obj The object to match. (a set)
+ criteria The criteria to match.
+ equal If set equality should be used. Otherwise
+ any set intersection will match. Ignored
+ if regular expression matching is used.
+ regex If regular expression matching should be used.
+ """
+
+ if regex:
+ return [m for m in obj if criteria.search(str(m))]
+ else:
+ return PolicyQuery._match_set(obj, set(criteria), equal)
+
+ @staticmethod
+ def _match_range(obj, criteria, subset, overlap, superset, proper):
+ """
+ Match ranges of objects.
+
+ obj An object with attributes named "low" and "high", representing the range.
+ criteria An object with attributes named "low" and "high", representing the criteria.
+ subset If true, the criteria will match if it is a subset obj's range.
+ overlap If true, the criteria will match if it overlaps any of the obj's range.
+ superset If true, the criteria will match if it is a superset of the obj's range.
+ proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ if overlap:
+ return ((obj.low <= criteria.low <= obj.high) or (
+ obj.low <= criteria.high <= obj.high) or (
+ criteria.low <= obj.low and obj.high <= criteria.high))
+ elif subset:
+ if proper:
+ return ((obj.low < criteria.low and criteria.high <= obj.high) or (
+ obj.low <= criteria.low and criteria.high < obj.high))
+ else:
+ return obj.low <= criteria.low and criteria.high <= obj.high
+ elif superset:
+ if proper:
+ return ((criteria.low < obj.low and obj.high <= criteria.high) or (
+ criteria.low <= obj.low and obj.high < criteria.high))
+ else:
+ return (criteria.low <= obj.low and obj.high <= criteria.high)
+ else:
+ return criteria.low == obj.low and obj.high == criteria.high
+
+ @staticmethod
+ def _match_level(obj, criteria, dom, domby, incomp):
+ """
+ Match the an MLS level.
+
+ obj The level to match.
+ criteria The criteria to match. (a level)
+ dom If true, the criteria will match if it dominates obj.
+ domby If true, the criteria will match if it is dominated by obj.
+ incomp If true, the criteria will match if it is incomparable to obj.
+ """
+
+ if dom:
+ return (criteria >= obj)
+ elif domby:
+ return (criteria <= obj)
+ elif incomp:
+ return (criteria ^ obj)
+ else:
+ return (criteria == obj)
+
+ def results(self):
+ """
+ Generator which returns the matches for the query. This method
+ should be overridden by subclasses.
+ """
+ raise NotImplementedError
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/rbacrulequery.py b/lib/python2.7/site-packages/setoolsgui/setools/rbacrulequery.py
new file mode 100644
index 0000000..240b921
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/rbacrulequery.py
@@ -0,0 +1,147 @@
+# Copyright 2014-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 logging
+import re
+
+from . import mixins, query
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor
+from .policyrep.exception import InvalidType, RuleUseError
+
+
+class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
+
+ """
+ Query the RBAC rules.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ ruletype The list of rule type(s) to match.
+ source The name of the source role/attribute to match.
+ source_indirect If true, members of an attribute will be
+ matched rather than the attribute itself.
+ source_regex If true, regular expression matching will
+ be used on the source role/attribute.
+ Obeys the source_indirect option.
+ target The name of the target role/attribute to match.
+ target_indirect If true, members of an attribute will be
+ matched rather than the attribute itself.
+ target_regex If true, regular expression matching will
+ be used on the target role/attribute.
+ Obeys target_indirect option.
+ tclass The object class(es) to match.
+ tclass_regex If true, use a regular expression for
+ matching the rule's object class.
+ default The name of the default role to match.
+ default_regex If true, regular expression matching will
+ be used on the default role.
+ """
+
+ ruletype = RuletypeDescriptor("validate_rbac_ruletype")
+ source = CriteriaDescriptor("source_regex", "lookup_role")
+ source_regex = False
+ source_indirect = True
+ _target = None
+ target_regex = False
+ target_indirect = True
+ tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class")
+ tclass_regex = False
+ default = CriteriaDescriptor("default_regex", "lookup_role")
+ default_regex = False
+
+ @property
+ def target(self):
+ return self._target
+
+ @target.setter
+ def target(self, value):
+ if not value:
+ self._target = None
+ elif self.target_regex:
+ self._target = re.compile(value)
+ else:
+ try:
+ self._target = self.policy.lookup_type_or_attr(value)
+ except InvalidType:
+ self._target = self.policy.lookup_role(value)
+
+ def results(self):
+ """Generator which yields all matching RBAC rules."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ruletypes: {0.ruletype}".format(self))
+ self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, "
+ "regex: {0.source_regex}".format(self))
+ self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, "
+ "regex: {0.target_regex}".format(self))
+ self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
+ self.log.debug("Default: {0.default!r}, regex: {0.default_regex}".format(self))
+
+ for rule in self.policy.rbacrules():
+ #
+ # Matching on rule type
+ #
+ if self.ruletype:
+ if rule.ruletype not in self.ruletype:
+ continue
+
+ #
+ # Matching on source role
+ #
+ if self.source and not self._match_indirect_regex(
+ rule.source,
+ self.source,
+ self.source_indirect,
+ self.source_regex):
+ continue
+
+ #
+ # Matching on target type (role_transition)/role(allow)
+ #
+ if self.target and not self._match_indirect_regex(
+ rule.target,
+ self.target,
+ self.target_indirect,
+ self.target_regex):
+ continue
+
+ #
+ # Matching on object class
+ #
+ try:
+ if not self._match_object_class(rule):
+ continue
+ except RuleUseError:
+ continue
+
+ #
+ # Matching on default role
+ #
+ if self.default:
+ try:
+ if not self._match_regex(
+ rule.default,
+ self.default,
+ self.default_regex):
+ continue
+ except RuleUseError:
+ continue
+
+ # if we get here, we have matched all available criteria
+ yield rule
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/rolequery.py b/lib/python2.7/site-packages/setoolsgui/setools/rolequery.py
new file mode 100644
index 0000000..e95dfa6
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/rolequery.py
@@ -0,0 +1,77 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery
+from .descriptors import CriteriaSetDescriptor
+
+
+class RoleQuery(compquery.ComponentQuery):
+
+ """
+ Query SELinux policy roles.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The role name to match.
+ name_regex If true, regular expression matching
+ will be used on the role names.
+ types The type to match.
+ types_equal If true, only roles with type sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ types_regex If true, regular expression matching
+ will be used on the type names instead
+ of set logic.
+ """
+
+ types = CriteriaSetDescriptor("types_regex", "lookup_type")
+ types_equal = False
+ types_regex = False
+
+ def results(self):
+ """Generator which yields all matching roles."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Types: {0.types!r}, regex: {0.types_regex}, "
+ "eq: {0.types_equal}".format(self))
+
+ for r in self.policy.roles():
+ if r == "object_r":
+ # all types are implicitly added to object_r by the compiler.
+ # technically it is incorrect to skip it, but policy writers
+ # and analysts don't expect to see it in results, and it
+ # will confuse, especially for set equality type queries.
+ continue
+
+ if not self._match_name(r):
+ continue
+
+ if self.types and not self._match_regex_or_set(
+ set(r.types()),
+ self.types,
+ self.types_equal,
+ self.types_regex):
+ continue
+
+ yield r
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/sensitivityquery.py b/lib/python2.7/site-packages/setoolsgui/setools/sensitivityquery.py
new file mode 100644
index 0000000..a102836
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/sensitivityquery.py
@@ -0,0 +1,74 @@
+# 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 logging
+
+from . import compquery
+from . import mixins
+from .descriptors import CriteriaDescriptor
+
+
+class SensitivityQuery(mixins.MatchAlias, compquery.ComponentQuery):
+
+ """
+ Query MLS Sensitivities
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The name of the category to match.
+ name_regex If true, regular expression matching will
+ be used for matching the name.
+ alias The alias name to match.
+ alias_regex If true, regular expression matching
+ will be used on the alias names.
+ sens The criteria to match the sensitivity by dominance.
+ sens_dom If true, the criteria will match if it dominates
+ the sensitivity.
+ sens_domby If true, the criteria will match if it is dominated
+ by the sensitivity.
+ """
+
+ sens = CriteriaDescriptor(lookup_function="lookup_sensitivity")
+ sens_dom = False
+ sens_domby = False
+
+ def results(self):
+ """Generator which yields all matching sensitivities."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Alias: {0.alias}, regex: {0.alias_regex}".format(self))
+ self.log.debug("Sens: {0.sens!r}, dom: {0.sens_dom}, domby: {0.sens_domby}".format(self))
+
+ for s in self.policy.sensitivities():
+ if not self._match_name(s):
+ continue
+
+ if not self._match_alias(s):
+ continue
+
+ if self.sens and not self._match_level(
+ s,
+ self.sens,
+ self.sens_dom,
+ self.sens_domby,
+ False):
+ continue
+
+ yield s
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/terulequery.py b/lib/python2.7/site-packages/setoolsgui/setools/terulequery.py
new file mode 100644
index 0000000..7f3eccf
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/terulequery.py
@@ -0,0 +1,178 @@
+# Copyright 2014-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 logging
+import re
+
+from . import mixins, query
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor
+from .policyrep.exception import RuleUseError, RuleNotConditional
+
+
+class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuery):
+
+ """
+ Query the Type Enforcement rules.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ ruletype The list of rule type(s) to match.
+ source The name of the source type/attribute to match.
+ source_indirect If true, members of an attribute will be
+ matched rather than the attribute itself.
+ Default is true.
+ source_regex If true, regular expression matching will
+ be used on the source type/attribute.
+ Obeys the source_indirect option.
+ Default is false.
+ target The name of the target type/attribute to match.
+ target_indirect If true, members of an attribute will be
+ matched rather than the attribute itself.
+ Default is true.
+ target_regex If true, regular expression matching will
+ be used on the target type/attribute.
+ Obeys target_indirect option.
+ Default is false.
+ tclass The object class(es) to match.
+ tclass_regex If true, use a regular expression for
+ matching the rule's object class.
+ Default is false.
+ perms The set of permission(s) to match.
+ perms_equal If true, the permission set of the rule
+ must exactly match the permissions
+ criteria. If false, any set intersection
+ will match.
+ Default is false.
+ perms_regex If true, regular expression matching will be used
+ on the permission names instead of set logic.
+ default The name of the default type to match.
+ default_regex If true, regular expression matching will be
+ used on the default type.
+ Default is false.
+ boolean The set of boolean(s) to match.
+ boolean_regex If true, regular expression matching will be
+ used on the booleans.
+ Default is false.
+ boolean_equal If true, the booleans in the conditional
+ expression of the rule must exactly match the
+ criteria. If false, any set intersection
+ will match. Default is false.
+ """
+
+ ruletype = RuletypeDescriptor("validate_te_ruletype")
+ source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
+ source_regex = False
+ source_indirect = True
+ target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
+ target_regex = False
+ target_indirect = True
+ default = CriteriaDescriptor("default_regex", "lookup_type")
+ default_regex = False
+ boolean = CriteriaSetDescriptor("boolean_regex", "lookup_boolean")
+ boolean_regex = False
+ boolean_equal = False
+
+ def results(self):
+ """Generator which yields all matching TE rules."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Ruletypes: {0.ruletype}".format(self))
+ self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, "
+ "regex: {0.source_regex}".format(self))
+ self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, "
+ "regex: {0.target_regex}".format(self))
+ self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
+ self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}".
+ format(self))
+ self.log.debug("Default: {0.default!r}, regex: {0.default_regex}".format(self))
+ self.log.debug("Boolean: {0.boolean!r}, eq: {0.boolean_equal}, "
+ "regex: {0.boolean_regex}".format(self))
+
+ for rule in self.policy.terules():
+ #
+ # Matching on rule type
+ #
+ if self.ruletype:
+ if rule.ruletype not in self.ruletype:
+ continue
+
+ #
+ # Matching on source type
+ #
+ if self.source and not self._match_indirect_regex(
+ rule.source,
+ self.source,
+ self.source_indirect,
+ self.source_regex):
+ continue
+
+ #
+ # Matching on target type
+ #
+ if self.target and not self._match_indirect_regex(
+ rule.target,
+ self.target,
+ self.target_indirect,
+ self.target_regex):
+ continue
+
+ #
+ # Matching on object class
+ #
+ if not self._match_object_class(rule):
+ continue
+
+ #
+ # Matching on permission set
+ #
+ try:
+ if not self._match_perms(rule):
+ continue
+ except RuleUseError:
+ continue
+
+ #
+ # Matching on default type
+ #
+ if self.default:
+ try:
+ if not self._match_regex(
+ rule.default,
+ self.default,
+ self.default_regex):
+ continue
+ except RuleUseError:
+ continue
+
+ #
+ # Match on Boolean in conditional expression
+ #
+ if self.boolean:
+ try:
+ if not self._match_regex_or_set(
+ rule.conditional.booleans,
+ self.boolean,
+ self.boolean_equal,
+ self.boolean_regex):
+ continue
+ except RuleNotConditional:
+ continue
+
+ # if we get here, we have matched all available criteria
+ yield rule
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/typeattrquery.py b/lib/python2.7/site-packages/setoolsgui/setools/typeattrquery.py
new file mode 100644
index 0000000..a91026c
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/typeattrquery.py
@@ -0,0 +1,70 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery
+from .descriptors import CriteriaSetDescriptor
+
+
+class TypeAttributeQuery(compquery.ComponentQuery):
+
+ """
+ Query SELinux policy type attributes.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The type name to match.
+ name_regex If true, regular expression matching
+ will be used on the type names.
+ types The type to match.
+ types_equal If true, only attributes with type sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ types_regex If true, regular expression matching
+ will be used on the type names instead
+ of set logic.
+ """
+
+ types = CriteriaSetDescriptor("types_regex", "lookup_type")
+ types_equal = False
+ types_regex = False
+
+ def results(self):
+ """Generator which yields all matching types."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Types: {0.types!r}, regex: {0.types_regex}, "
+ "eq: {0.types_equal}".format(self))
+
+ for attr in self.policy.typeattributes():
+ if not self._match_name(attr):
+ continue
+
+ if self.types and not self._match_regex_or_set(
+ set(attr.expand()),
+ self.types,
+ self.types_equal,
+ self.types_regex):
+ continue
+
+ yield attr
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/typequery.py b/lib/python2.7/site-packages/setoolsgui/setools/typequery.py
new file mode 100644
index 0000000..6634f76
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/typequery.py
@@ -0,0 +1,96 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery
+from . import mixins
+from .descriptors import CriteriaSetDescriptor
+
+
+class TypeQuery(mixins.MatchAlias, compquery.ComponentQuery):
+
+ """
+ Query SELinux policy types.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The type name to match.
+ name_regex If true, regular expression matching
+ will be used on the type names.
+ alias The alias name to match.
+ alias_regex If true, regular expression matching
+ will be used on the alias names.
+ attrs The attribute to match.
+ attrs_equal If true, only types with attribute sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ attrs_regex If true, regular expression matching
+ will be used on the attribute names instead
+ of set logic.
+ permissive The permissive state to match. If this
+ is None, the state is not matched.
+ """
+
+ attrs = CriteriaSetDescriptor("attrs_regex", "lookup_typeattr")
+ attrs_regex = False
+ attrs_equal = False
+ _permissive = None
+
+ @property
+ def permissive(self):
+ return self._permissive
+
+ @permissive.setter
+ def permissive(self, value):
+ if value is None:
+ self._permissive = None
+ else:
+ self._permissive = bool(value)
+
+ def results(self):
+ """Generator which yields all matching types."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Alias: {0.alias}, regex: {0.alias_regex}".format(self))
+ self.log.debug("Attrs: {0.attrs!r}, regex: {0.attrs_regex}, "
+ "eq: {0.attrs_equal}".format(self))
+ self.log.debug("Permissive: {0.permissive}".format(self))
+
+ for t in self.policy.types():
+ if not self._match_name(t):
+ continue
+
+ if not self._match_alias(t):
+ continue
+
+ if self.attrs and not self._match_regex_or_set(
+ set(t.attributes()),
+ self.attrs,
+ self.attrs_equal,
+ self.attrs_regex):
+ continue
+
+ if self.permissive is not None and t.ispermissive != self.permissive:
+ continue
+
+ yield t
diff --git a/lib/python2.7/site-packages/setoolsgui/setools/userquery.py b/lib/python2.7/site-packages/setoolsgui/setools/userquery.py
new file mode 100644
index 0000000..00910cf
--- /dev/null
+++ b/lib/python2.7/site-packages/setoolsgui/setools/userquery.py
@@ -0,0 +1,116 @@
+# Copyright 2014-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 logging
+import re
+
+from . import compquery
+from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
+
+
+class UserQuery(compquery.ComponentQuery):
+
+ """
+ Query SELinux policy users.
+
+ Parameter:
+ policy The policy to query.
+
+ Keyword Parameters/Class attributes:
+ name The user name to match.
+ name_regex If true, regular expression matching
+ will be used on the user names.
+ roles The attribute to match.
+ roles_equal If true, only types with role sets
+ that are equal to the criteria will
+ match. Otherwise, any intersection
+ will match.
+ roles_regex If true, regular expression matching
+ will be used on the role names instead
+ of set logic.
+ level The criteria to match the user's default level.
+ level_dom If true, the criteria will match if it dominates
+ the user's default level.
+ level_domby If true, the criteria will match if it is dominated
+ by the user's default level.
+ level_incomp If true, the criteria will match if it is incomparable
+ to the user's default level.
+ range_ The criteria to match the user's range.
+ range_subset If true, the criteria will match if it is a subset
+ of the user's range.
+ range_overlap If true, the criteria will match if it overlaps
+ any of the user's range.
+ range_superset If true, the criteria will match if it is a superset
+ of the user's range.
+ range_proper If true, use proper superset/subset operations.
+ No effect if not using set operations.
+ """
+
+ level = CriteriaDescriptor(lookup_function="lookup_level")
+ level_dom = False
+ level_domby = False
+ level_incomp = False
+ range_ = CriteriaDescriptor(lookup_function="lookup_range")
+ range_overlap = False
+ range_subset = False
+ range_superset = False
+ range_proper = False
+ roles = CriteriaSetDescriptor("roles_regex", "lookup_role")
+ roles_equal = False
+ roles_regex = False
+
+ def results(self):
+ """Generator which yields all matching users."""
+ self.log.info("Generating results from {0.policy}".format(self))
+ self.log.debug("Name: {0.name!r}, regex: {0.name_regex}".format(self))
+ self.log.debug("Roles: {0.roles!r}, regex: {0.roles_regex}, "
+ "eq: {0.roles_equal}".format(self))
+ self.log.debug("Level: {0.level!r}, dom: {0.level_dom}, domby: {0.level_domby}, "
+ "incomp: {0.level_incomp}".format(self))
+ self.log.debug("Range: {0.range_!r}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
+ "superset: {0.range_superset}, proper: {0.range_proper}".format(self))
+
+ for user in self.policy.users():
+ if not self._match_name(user):
+ continue
+
+ if self.roles and not self._match_regex_or_set(
+ user.roles,
+ self.roles,
+ self.roles_equal,
+ self.roles_regex):
+ continue
+
+ if self.level and not self._match_level(
+ user.mls_level,
+ self.level,
+ self.level_dom,
+ self.level_domby,
+ self.level_incomp):
+ continue
+
+ if self.range_ and not self._match_range(
+ user.mls_range,
+ self.range_,
+ self.range_subset,
+ self.range_overlap,
+ self.range_superset,
+ self.range_proper):
+ continue
+
+ yield user