summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/sepolgen/module.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/sepolgen/module.py')
-rw-r--r--lib/python2.7/site-packages/sepolgen/module.py216
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/sepolgen/module.py b/lib/python2.7/site-packages/sepolgen/module.py
new file mode 100644
index 0000000..c09676a
--- /dev/null
+++ b/lib/python2.7/site-packages/sepolgen/module.py
@@ -0,0 +1,216 @@
+# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
+#
+# Copyright (C) 2006 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; version 2 only
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""
+Utilities for dealing with the compilation of modules and creation
+of module tress.
+"""
+
+import re
+import tempfile
+try:
+ from subprocess import getstatusoutput
+except ImportError:
+ from commands import getstatusoutput
+import os
+import os.path
+import shutil
+
+import selinux
+
+from . import defaults
+
+
+def is_valid_name(modname):
+ """Check that a module name is valid.
+ """
+ m = re.findall("[^a-zA-Z0-9_\-\.]", modname)
+ if len(m) == 0 and modname[0].isalpha():
+ return True
+ else:
+ return False
+
+class ModuleTree:
+ def __init__(self, modname):
+ self.modname = modname
+ self.dirname = None
+
+ def dir_name(self):
+ return self.dirname
+
+ def te_name(self):
+ return self.dirname + "/" + self.modname + ".te"
+
+ def fc_name(self):
+ return self.dirname + "/" + self.modname + ".fc"
+
+ def if_name(self):
+ return self.dirname + "/" + self.modname + ".if"
+
+ def package_name(self):
+ return self.dirname + "/" + self.modname + ".pp"
+
+ def makefile_name(self):
+ return self.dirname + "/Makefile"
+
+ def create(self, parent_dirname, makefile_include=None):
+ self.dirname = parent_dirname + "/" + self.modname
+ os.mkdir(self.dirname)
+ fd = open(self.makefile_name(), "w")
+ if makefile_include:
+ fd.write("include " + makefile_include)
+ else:
+ fd.write("include " + defaults.refpolicy_makefile())
+ fd.close()
+
+ # Create empty files for the standard refpolicy
+ # module files
+ open(self.te_name(), "w").close()
+ open(self.fc_name(), "w").close()
+ open(self.if_name(), "w").close()
+
+def modname_from_sourcename(sourcename):
+ return os.path.splitext(os.path.split(sourcename)[1])[0]
+
+class ModuleCompiler:
+ """ModuleCompiler eases running of the module compiler.
+
+ The ModuleCompiler class encapsulates running the commandline
+ module compiler (checkmodule) and module packager (semodule_package).
+ You are likely interested in the create_module_package method.
+
+ Several options are controlled via paramaters (only effects the
+ non-refpol builds):
+
+ .mls [boolean] Generate an MLS module (by passed -M to
+ checkmodule). True to generate an MLS module, false
+ otherwise.
+
+ .module [boolean] Generate a module instead of a base module.
+ True to generate a module, false to generate a base.
+
+ .checkmodule [string] Fully qualified path to the module compiler.
+ Default is /usr/bin/checkmodule.
+
+ .semodule_package [string] Fully qualified path to the module
+ packager. Defaults to /usr/bin/semodule_package.
+ .output [file object] File object used to write verbose
+ output of the compililation and packaging process.
+ """
+ def __init__(self, output=None):
+ """Create a ModuleCompiler instance, optionally with an
+ output file object for verbose output of the compilation process.
+ """
+ self.mls = selinux.is_selinux_mls_enabled()
+ self.module = True
+ self.checkmodule = "/usr/bin/checkmodule"
+ self.semodule_package = "/usr/bin/semodule_package"
+ self.output = output
+ self.last_output = ""
+ self.refpol_makefile = defaults.refpolicy_makefile()
+ self.make = "/usr/bin/make"
+
+ def o(self, str):
+ if self.output:
+ self.output.write(str + "\n")
+ self.last_output = str
+
+ def run(self, command):
+ self.o(command)
+ rc, output = getstatusoutput(command)
+ self.o(output)
+
+ return rc
+
+ def gen_filenames(self, sourcename):
+ """Generate the module and policy package filenames from
+ a source file name. The source file must be in the form
+ of "foo.te". This will generate "foo.mod" and "foo.pp".
+
+ Returns a tuple with (modname, policypackage).
+ """
+ splitname = sourcename.split(".")
+ if len(splitname) < 2:
+ raise RuntimeError("invalid sourcefile name %s (must end in .te)", sourcename)
+ # Handle other periods in the filename correctly
+ basename = ".".join(splitname[0:-1])
+ modname = basename + ".mod"
+ packagename = basename + ".pp"
+
+ return (modname, packagename)
+
+ def create_module_package(self, sourcename, refpolicy=True):
+ """Create a module package saved in a packagename from a
+ sourcename.
+
+ The create_module_package creates a module package saved in a
+ file named sourcename (.pp is the standard extension) from a
+ source file (.te is the standard extension). The source file
+ should contain SELinux policy statements appropriate for a
+ base or non-base module (depending on the setting of .module).
+
+ Only file names are accepted, not open file objects or
+ descriptors because the command line SELinux tools are used.
+
+ On error a RuntimeError will be raised with a descriptive
+ error message.
+ """
+ if refpolicy:
+ self.refpol_build(sourcename)
+ else:
+ modname, packagename = self.gen_filenames(sourcename)
+ self.compile(sourcename, modname)
+ self.package(modname, packagename)
+ os.unlink(modname)
+
+ def refpol_build(self, sourcename):
+ # Compile
+ command = self.make + " -f " + self.refpol_makefile
+ rc = self.run(command)
+
+ # Raise an error if the process failed
+ if rc != 0:
+ raise RuntimeError("compilation failed:\n%s" % self.last_output)
+
+ def compile(self, sourcename, modname):
+ s = [self.checkmodule]
+ if self.mls:
+ s.append("-M")
+ if self.module:
+ s.append("-m")
+ s.append("-o")
+ s.append(modname)
+ s.append(sourcename)
+
+ rc = self.run(" ".join(s))
+ if rc != 0:
+ raise RuntimeError("compilation failed:\n%s" % self.last_output)
+
+ def package(self, modname, packagename):
+ s = [self.semodule_package]
+ s.append("-o")
+ s.append(packagename)
+ s.append("-m")
+ s.append(modname)
+
+ rc = self.run(" ".join(s))
+ if rc != 0:
+ raise RuntimeError("packaging failed [%s]" % self.last_output)
+
+