* Mon Mar 1 2010 Dan Walsh <dwalsh@redhat.com> 2.0.79-5

- Rewrite of sandbox script, add unit test for sandbox
- Update translations
This commit is contained in:
Daniel J Walsh 2010-03-04 21:49:04 +00:00
parent 542a3ce800
commit 1ff0435303
4 changed files with 983 additions and 807 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/audit2allow/audit2allow policycoreutils-2.0.79/audit2allow/audit2allow
--- nsapolicycoreutils/audit2allow/audit2allow 2009-01-13 08:45:35.000000000 -0500
+++ policycoreutils-2.0.79/audit2allow/audit2allow 2010-02-26 14:14:26.000000000 -0500
+++ policycoreutils-2.0.79/audit2allow/audit2allow 2010-03-01 15:27:27.000000000 -0500
@@ -28,6 +28,7 @@
import sepolgen.defaults as defaults
import sepolgen.module as module
@ -56,6 +56,20 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
else:
# This is the default if no input is specified
f = sys.stdin
@@ -153,11 +165,11 @@
def __process_input(self):
if self.__options.type:
avcfilter = audit.AVCTypeFilter(self.__options.type)
- self.__avs = self.__parser.to_access(avcfilter)
+ self.__avs = self.__parser.to_access(avcfilter, dontaudit=self.__options.dontaudit)
csfilter = audit.ComputeSidTypeFilter(self.__options.type)
self.__role_types = self.__parser.to_role(csfilter)
else:
- self.__avs = self.__parser.to_access()
+ self.__avs = self.__parser.to_access(dontaudit=self.__options.dontaudit)
self.__role_types = self.__parser.to_role()
def __load_interface_info(self):
@@ -220,63 +232,44 @@
def __output_audit2why(self):
@ -132,15 +146,6 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
print "\t\tMissing role allow rule.\n"
print "\t\tAdd an allow rule for the role pair.\n"
continue
@@ -314,7 +307,7 @@
g.set_gen_requires(True)
# Generate the policy
- g.add_access(self.__avs)
+ g.add_access(self.__avs, self.__options.dontaudit)
g.add_role_types(self.__role_types)
# Output
@@ -344,5 +337,6 @@
sys.exit(0)
@ -1704,8 +1709,8 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/sandbox/Makefile policycoreutils-2.0.79/sandbox/Makefile
--- nsapolicycoreutils/sandbox/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ policycoreutils-2.0.79/sandbox/Makefile 2010-02-26 14:14:26.000000000 -0500
@@ -0,0 +1,38 @@
+++ policycoreutils-2.0.79/sandbox/Makefile 2010-03-04 16:40:24.000000000 -0500
@@ -0,0 +1,41 @@
+# Installation directories.
+PREFIX ?= ${DESTDIR}/usr
+INITDIR ?= ${DESTDIR}/etc/rc.d/init.d/
@ -1737,6 +1742,9 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+ -mkdir -p $(SYSCONFDIR)
+ install -m 644 sandbox.config $(SYSCONFDIR)/sandbox
+
+test:
+ @python test_sandbox.py -v
+
+clean:
+ -rm -f seunshare *.o *~
+
@ -1746,13 +1754,13 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+relabel:
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/sandbox/sandbox policycoreutils-2.0.79/sandbox/sandbox
--- nsapolicycoreutils/sandbox/sandbox 1969-12-31 19:00:00.000000000 -0500
+++ policycoreutils-2.0.79/sandbox/sandbox 2010-02-26 14:14:26.000000000 -0500
@@ -0,0 +1,377 @@
+++ policycoreutils-2.0.79/sandbox/sandbox 2010-03-04 16:39:22.000000000 -0500
@@ -0,0 +1,415 @@
+#! /usr/bin/python -E
+# Authors: Dan Walsh <dwalsh@redhat.com>
+# Authors: Josh Cogliati
+#
+# Copyright (C) 2009 Red Hat
+# Copyright (C) 2009,2010 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or
@ -1769,13 +1777,14 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import os, sys, getopt, socket, random, fcntl, shutil, re, subprocess
+import os, sys, socket, random, fcntl, shutil, re, subprocess
+import selinux
+import signal
+from tempfile import mkdtemp
+import pwd
+
+PROGNAME = "policycoreutils"
+HOMEDIR=pwd.getpwuid(os.getuid()).pw_dir
+
+import gettext
+gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@ -1790,7 +1799,6 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+ import __builtin__
+ __builtin__.__dict__['_'] = unicode
+
+
+DEFAULT_TYPE = "sandbox_t"
+DEFAULT_X_TYPE = "sandbox_x_t"
+X_FILES = {}
@ -1813,6 +1821,46 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+ sys.stderr.flush()
+ sys.exit(1)
+
+def copyfile(file, dir, dest):
+ import re
+ if file.startswith(dir):
+ dname = os.path.dirname(file)
+ bname = os.path.basename(file)
+ if dname == dir:
+ dest = dest + "/" + bname
+ else:
+ newdir = re.sub(dir, dest, dname)
+ if not os.path.exists(newdir):
+ os.makedirs(newdir)
+ dest = newdir + "/" + bname
+
+ if os.path.isdir(file):
+ shutil.copytree(file, dest)
+ else:
+ shutil.copy2(file, dest)
+ X_FILES[file] = (dest, os.path.getmtime(dest))
+
+def savefile(new, orig, X_ind):
+ copy = False
+ if(X_ind):
+ import gtk
+ dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
+ gtk.BUTTONS_YES_NO,
+ _("Do you want to save changes to '%s' (Y/N): ") % orig)
+ dlg.set_title(_("Sandbox Message"))
+ dlg.set_position(gtk.WIN_POS_MOUSE)
+ dlg.show_all()
+ rc = dlg.run()
+ dlg.destroy()
+ if rc == gtk.RESPONSE_YES:
+ copy = True
+ else:
+ ans = raw_input(_("Do you want to save changes to '%s' (y/N): ") % orig)
+ if(re.match(_("[yY]"),ans)):
+ copy = True
+ if(copy):
+ shutil.copy2(new,orig)
+
+def reserve(level):
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.bind("\0%s" % level)
@ -1837,69 +1885,100 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+ break
+ return level
+
+def gen_context(setype, level=None):
+ if not level:
+ level = gen_mcs()
+def fullpath(cmd):
+ for i in [ "/", "./", "../" ]:
+ if cmd.startswith(i):
+ return cmd
+ for i in os.environ["PATH"].split(':'):
+ f = "%s/%s" % (i, cmd)
+ if os.access(f, os.X_OK):
+ return f
+ return cmd
+
+ con = selinux.getcon()[1].split(":")
+class Sandbox:
+ VERSION = "sandbox .1"
+ SYSLOG = "/var/log/messages"
+
+ execcon = "%s:%s:%s:%s" % (con[0], con[1], setype, level)
+
+ filecon = "%s:%s:%s:%s" % (con[0],
+ "object_r",
+ "%s_file_t" % setype[:-2],
+ level)
+ return execcon, filecon
+ def __init__(self):
+ self.__options = None
+ self.__cmds = None
+ self.__init_files = []
+ self.__paths = []
+ self.__mount = False
+ self.__level = None
+ self.__homedir = None
+ self.__tmpdir = None
+
+def copyfile(file, dir, dest):
+ import re
+ if file.startswith(dir):
+ dname = os.path.dirname(file)
+ bname = os.path.basename(file)
+ if dname == dir:
+ dest = dest + "/" + bname
+ else:
+ newdir = re.sub(dir, dest, dname)
+ os.makedirs(newdir)
+ dest = newdir + "/" + bname
+ def __validate_mount(self):
+ if self.__options.level:
+ if not self.__options.homedir or not self.__options.tmpdir:
+ self.usage(_("Homedir and tempdir required for level mounts"))
+
+ if os.path.isdir(file):
+ shutil.copytree(file, dest)
+ else:
+ shutil.copy2(file, dest)
+ X_FILES[file] = (dest, os.path.getmtime(dest))
+ if not os.path.exists("/usr/sbin/seunshare"):
+ raise ValueError("""
+/usr/sbin/seunshare required for sandbox -M, to install you need to execute
+#yum install /usr/sbin/seunshare
+""")
+ homedir=pwd.getpwuid(os.getuid()).pw_dir
+ fd = open("/proc/self/mountinfo", "r")
+ recs = fd.readlines()
+ fd.close()
+ for i in recs:
+ x = i.split()
+ if x[3] == x[4] and homedir.startswith(x[3]+"/"):
+ return
+ raise ValueError(_("""
+'%s' is required to be a shared mount point for this tool to run.
+'%s' can be added to the HOMEDIR variable in /etc/sysconfig/sandbox
+ along with a reboot will fix the problem.
+""" % ((os.path.dirname(homedir)), os.path.dirname(homedir))))
+
+ def __mount_callback(self, option, opt, value, parser):
+ self.__mount = True
+
+def copyfiles(newhomedir, newtmpdir, files):
+ homedir=pwd.getpwuid(os.getuid()).pw_dir
+ for f in files:
+ copyfile(f,homedir, newhomedir)
+ copyfile(f,"/tmp", newtmpdir)
+ def __x_callback(self, option, opt, value, parser):
+ self.__mount = True
+ setattr(parser.values, option.dest, True)
+
+def savefile(new, orig, X_ind):
+ copy = False
+ if(X_ind):
+ import gtk
+ dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
+ gtk.BUTTONS_YES_NO,
+ _("Do you want to save changes to '%s' (Y/N): ") % orig)
+ dlg.set_title(_("Sandbox Message"))
+ dlg.set_position(gtk.WIN_POS_MOUSE)
+ dlg.show_all()
+ rc = dlg.run()
+ dlg.destroy()
+ if rc == gtk.RESPONSE_YES:
+ copy = True
+ else:
+ ans = raw_input(_("Do you want to save changes to '%s' (y/N): ") % orig)
+ if(re.match(_("[yY]"),ans)):
+ copy = True
+ if(copy):
+ shutil.copy2(new,orig)
+ def __validdir(self, option, opt, value, parser):
+ if not os.path.isdir(value):
+ raise IOError("Directory "+value+" not found")
+ self.__mount = True
+
+def setup_executable(execfile, command):
+ fd = open(execfile, "w+")
+ fd.write("""
+#! /bin/sh
+ def __include(self, option, opt, value, parser):
+ rp = os.path.realpath(os.path.expanduser(value))
+ if not os.path.exists(rp):
+ raise IOError(value+" not found")
+
+ if rp not in self.__init_files:
+ self.__init_files.append(rp)
+
+ def __includefile(self, option, opt, value, parser):
+ fd = open(value, "r")
+ for i in fd.readlines():
+ rp = os.path.realpath(os.path.expanduser(i[:-1]))
+ if rp not in self.__init_files and os.path.exists(rp):
+ self.__init_files.append(rp)
+ fd.close()
+
+ def __copyfiles(self):
+ files = self.__init_files + self.__paths
+ homedir=pwd.getpwuid(os.getuid()).pw_dir
+ for f in files:
+ copyfile(f, homedir, self.__homedir)
+ copyfile(f, "/tmp", self.__tmpdir)
+
+ def __setup_sandboxrc(self):
+ execfile =self.__homedir + "/.sandboxrc"
+ fd = open(execfile, "w+")
+ if self.__options.session:
+ fd.write("""#!/bin/sh
+#TITLE: /etc/gdm/Xsession
+/etc/gdm/Xsession
+""")
+ else:
+ command = " ".join(self.__paths)
+ fd.write("""#! /bin/sh
+#TITLE: %s
+/usr/bin/test -r ~/.xmodmap && /usr/bin/xmodmap ~/.xmodmap
+/usr/bin/matchbox-window-manager -use_titlebar no &
@ -1907,212 +1986,179 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+%s
+kill -TERM $WM_PID 2> /dev/null
+""" % (command, command))
+ fd.close()
+ os.chmod(execfile, 0700)
+ fd.close()
+ os.chmod(execfile, 0700)
+
+def setup_session(execfile, command="/etc/gdm/Xsession"):
+ fd = open(execfile, "w+")
+ fd.write("""
+#!/bin/sh
+#TITLE: %s
+%s
+""" % (command, command))
+ fd.close()
+ os.chmod(execfile, 0700)
+ def usage(self, message = ""):
+ error_exit("%s\n%s" % (self.__parser.usage, message))
+
+ def __parse_options(self):
+ from optparse import OptionParser
+ usage = _("""
+sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [[-i file ] ...] [ -t type ] command
+
+sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [[-i file ] ...] [ -t type ] -S
+""")
+
+ parser = OptionParser(version=self.VERSION, usage=usage)
+ parser.disable_interspersed_args()
+ parser.add_option("-i", "--include",
+ action="callback", callback=self.__include,
+ type="string",
+ help="include file in sandbox")
+ parser.add_option("-I", "--includefile", action="callback", callback=self.__includefile,
+ type="string",
+ help="include contents of file in sandbox")
+ parser.add_option("-t", "--type", dest="setype", action="store", default=DEFAULT_TYPE,
+ help="Run sandbox with SELinux type")
+ parser.add_option("-M", "--mount",
+ action="callback", callback=self.__mount_callback,
+ help="Mount new home and tmp Dir")
+
+ parser.add_option("-S", "--session", action="store_true", dest="session",
+ default=False, help="Run complete desktop session within sandbox")
+ parser.add_option("-X", dest="X_ind",
+ action="callback", callback=self.__x_callback,
+ default=False, help="Run X sandbox")
+
+ parser.add_option("-H", "--homedir",
+ action="callback", callback=self.__validdir,
+ type="string",
+ dest="homedir",
+ help="Alternate homedir to use for mounting")
+
+ parser.add_option("-T", "--tmpdir", dest="tmpdir",
+ type="string",
+ action="callback", callback=self.__validdir,
+ help="Alternate tempdir to use for mounting")
+
+ parser.add_option("-l", "--level", dest="level",
+ help="MCS/MLS Level for the sandbox")
+
+ self.__parser=parser
+
+ self.__options, cmds = parser.parse_args()
+
+ if self.__options.X_ind:
+ if DEFAULT_TYPE == self.__options.setype:
+ self.__options.setype = DEFAULT_X_TYPE
+
+ if self.__mount:
+ self.__validate_mount()
+
+ if self.__options.session:
+ if self.__options.setype in (DEFAULT_TYPE, DEFAULT_X_TYPE):
+ self.__options.setype = selinux.getcon()[1].split(":")[2]
+ if not self.__options.homedir or not self.__options.tmpdir:
+ self.usage(_("Homedir and tempdir required for session"))
+ if len(cmds) > 0:
+ self.usage(_("Commands not allowed in a session"))
+ else:
+ if len(cmds) == 0:
+ self.usage(_("Command required"))
+ cmds[0] = fullpath(cmds[0])
+ self.__cmds = cmds
+
+ for f in cmds:
+ rp = os.path.realpath(f)
+ if os.path.exists(rp):
+ self.__paths.append(rp)
+ else:
+ self.__paths.append(f)
+
+ def __gen_context(self):
+ if self.__options.level:
+ level = self.__options.level
+ else:
+ level = gen_mcs()
+
+ con = selinux.getcon()[1].split(":")
+ self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.__options.setype, level)
+ self.__filecon = "%s:%s:%s:%s" % (con[0], "object_r",
+ "%s_file_t" % self.__options.setype[:-2],
+ level)
+ def __setup_dir(self):
+ if self.__options.level or self.__options.session:
+ return
+ sandboxdir = HOMEDIR + "/.sandbox"
+ if not os.path.exists(sandboxdir):
+ os.mkdir(sandboxdir)
+
+ import warnings
+ warnings.simplefilter("ignore")
+ if self.__options.homedir:
+ chcon = ("/usr/bin/chcon -R %s %s" % (self.__filecon, self.__options.homedir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+ self.__homedir = self.__options.homedir
+ else:
+ selinux.setfscreatecon(self.__filecon)
+ self.__homedir = mkdtemp(dir=sandboxdir, prefix=".sandbox")
+
+ if self.__options.tmpdir:
+ chcon = ("/usr/bin/chcon -R %s %s" % (self.__filecon, self.__options.tmpdir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+ self.__tmpdir = self.__options.homedir
+ else:
+ selinux.setfscreatecon(self.__filecon)
+ self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox")
+ warnings.resetwarnings()
+ selinux.setfscreatecon(None)
+ self.__copyfiles()
+
+ def __execute(self):
+ try:
+ if self.__options.X_ind:
+ xmodmapfile = self.__homedir + "/.xmodmap"
+ xd = open(xmodmapfile,"w")
+ subprocess.Popen(["/usr/bin/xmodmap","-pke"],stdout=xd).wait()
+ xd.close()
+
+ self.__setup_sandboxrc()
+
+ cmds = ("/usr/sbin/seunshare -t %s -h %s -- %s /usr/share/sandbox/sandboxX.sh" % (self.__tmpdir, self.__homedir, self.__execcon)).split()
+ rc = os.spawnvp(os.P_WAIT, cmds[0], cmds)
+ return rc
+
+ if self.__mount:
+ cmds = ("/usr/sbin/seunshare -t %s -h %s -- %s " % (self.__tmpdir, self.__homedir, self.__execcon)).split()+self.__paths
+ rc = os.spawnvp(os.P_WAIT, cmds[0], cmds)
+ return rc
+
+ selinux.setexeccon(self.__execcon)
+ rc = os.spawnvp(os.P_WAIT, self.__cmds[0], self.__cmds)
+ selinux.setexeccon(None)
+ return rc
+
+ finally:
+ for i in self.__paths:
+ if i not in X_FILES:
+ continue
+ (dest, mtime) = X_FILES[i]
+ if os.path.getmtime(dest) > mtime:
+ savefile(dest, i, X_ind)
+
+ if self.__homedir and not self.__options.homedir:
+ shutil.rmtree(self.__homedir)
+ if self.__tmpdir and not self.__options.tmpdir:
+ shutil.rmtree(self.__tmpdir)
+ def main(self):
+ try:
+ self.__parse_options()
+ self.__gen_context()
+ self.__setup_dir()
+ return self.__execute()
+ except KeyboardInterrupt:
+ sys.exit(0)
+
+def validate_home():
+ homedir=pwd.getpwuid(os.getuid()).pw_dir
+ fd = open("/proc/self/mountinfo", "r")
+ recs = fd.readlines()
+ fd.close()
+ for i in recs:
+ x = i.split()
+ if x[3] == x[4] and homedir.startswith(x[3]+"/"):
+ return
+ raise ValueError(_("""
+'%s' is required to be a shared mount point for this tool to run.
+'%s' can be added to the HOMEDIR variable in /etc/sysconfig/sandbox
+ along with a reboot will fix the problem.
+""" % ((os.path.dirname(homedir)), os.path.dirname(homedir))))
+
+if __name__ == '__main__':
+ setup_sighandlers()
+ if selinux.is_selinux_enabled() != 1:
+ error_exit("Requires an SELinux enabled system")
+
+ init_files = []
+
+ def usage(message = ""):
+ text = _("""
+sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [[-i file ] ...] [ -t type ] command
+sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [[-i file ] ...] [ -t type ] -S
+""")
+ error_exit("%s\n%s" % (message, text))
+
+ setype = DEFAULT_TYPE
+ X_ind = False
+ home_and_temp = False
+ level=None
+ newhomedir = None
+ newtmpdir = None
+ existing_home = False
+ existing_temp = False
+ session = False
+ try:
+ gopts, cmds = getopt.getopt(sys.argv[1:], "l:i:hSt:XI:MH:T:",
+ ["help",
+ "include=",
+ "includefile=",
+ "type=",
+ "mount",
+ "homedir=",
+ "tmpdir=",
+ "session",
+ "level="
+ ])
+ for o, a in gopts:
+ if o == "-t" or o == "--type":
+ setype = a
+
+ if o == "-l" or o == "--level":
+ level = a
+
+ if o == "-i" or o == "--include":
+ rp = os.path.realpath(a)
+ if rp not in init_files:
+ init_files.append(rp)
+
+ if o == "-I" or o == "--includefile":
+ fd = open(a, "r")
+ for i in fd.read().split("\n"):
+ if os.path.exists(i):
+ rp = os.path.realpath(i)
+ if rp not in init_files:
+ init_files.append(rp)
+
+ fd.close
+
+ if o == "-X":
+ if DEFAULT_TYPE == setype:
+ setype = DEFAULT_X_TYPE
+ X_ind = True
+ home_and_temp = True
+ if o == "-M" or o == "--mount":
+ home_and_temp = True
+
+ if o == "-H" or o == "--homedir":
+ existing_home = True
+ newhomedir = a
+ if o == "-T" or o == "--tmpdir":
+ existing_temp = True
+ newtmpdir = a
+ if o == "-h" or o == "--help":
+ usage(_("Usage"));
+
+ if o == "-S" or o == "--session":
+ session = True
+ homedir=pwd.getpwuid(os.getuid()).pw_dir
+ if setype in (DEFAULT_TYPE, DEFAULT_X_TYPE):
+ setype = selinux.getcon()[1].split(":")[2]
+
+ if len(cmds) == 0 and not session:
+ usage(_("Command required"))
+
+ if (existing_home or existing_temp) and not home_and_temp:
+ usage(_("-M required when specifying home directory or temp directory"))
+ execcon, filecon = gen_context(setype, level)
+ rc = -1
+
+ if not session and cmds[0][0] != "/" and cmds[0][:2] != "./" and cmds[0][:3] != "../":
+ for i in os.environ["PATH"].split(':'):
+ f = "%s/%s" % (i, cmds[0])
+ if os.access(f, os.X_OK):
+ cmds[0] = f
+ break
+
+ try:
+ if home_and_temp:
+ validate_home()
+
+ if not os.path.exists("/usr/sbin/seunshare"):
+ raise ValueError("""/usr/sbin/seunshare required for sandbox -M, to install you need to execute
+#yum install /usr/sbin/seunshare""")
+ import warnings
+ warnings.simplefilter("ignore")
+ if existing_home:
+ if not os.path.isdir(newhomedir):
+ raise IOError("Home directory "+newhomedir+" not found")
+ if not level and not session:
+ chcon = ("/usr/bin/chcon -R %s %s" % (filecon, newhomedir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+ else:
+ newhomedir = mkdtemp(dir=".", prefix=".sandbox")
+ if session:
+ chcon = ("/usr/bin/chcon --reference %s %s" %( homedir, (newhomedir))).split()
+ else:
+ chcon = ("/usr/bin/chcon %s %s" % (filecon, newhomedir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+
+ if existing_temp:
+ if not os.path.isdir(newtmpdir):
+ raise IOError("Temp directory "+newtmpdir+" not found")
+ if not level and not session:
+ chcon = ("/usr/bin/chcon -R %s %s" % (filecon, newtmpdir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+ else:
+ newtmpdir = mkdtemp(dir="/tmp", prefix=".sandbox")
+ if session:
+ chcon = ("/usr/bin/chcon --reference /tmp %s" % (newtmpdir)).split()
+ else:
+ chcon = ("/usr/bin/chcon %s %s" % (filecon, newtmpdir)).split()
+ rc = os.spawnvp(os.P_WAIT, chcon[0], chcon)
+
+ warnings.resetwarnings()
+ paths = []
+ for i in cmds:
+ f = os.path.realpath(i)
+ if os.path.exists(f):
+ paths.append(f)
+ else:
+ paths.append(i)
+
+ copyfiles(newhomedir, newtmpdir, init_files + paths)
+ if X_ind:
+ xmodmapfile = newhomedir + "/.xmodmap"
+ xd = open(xmodmapfile,"w")
+ subprocess.Popen(["/usr/bin/xmodmap","-pke"],stdout=xd).wait()
+ xd.close()
+
+ execfile = newhomedir + "/.sandboxrc"
+ if session:
+ setup_session(execfile)
+ else:
+ setup_executable(execfile, " ".join(paths))
+
+ cmds = ("/usr/sbin/seunshare -t %s -h %s -- %s /usr/share/sandbox/sandboxX.sh" % (newtmpdir, newhomedir, execcon)).split()
+ rc = os.spawnvp(os.P_WAIT, cmds[0], cmds)
+ else:
+ cmds = ("/usr/sbin/seunshare -t %s -h %s -- %s " % (newtmpdir, newhomedir, execcon)).split()+cmds
+ rc = os.spawnvp(os.P_WAIT, cmds[0], cmds)
+ for i in paths:
+ if i not in X_FILES:
+ continue
+ (dest, mtime) = X_FILES[i]
+ if os.path.getmtime(dest) > mtime:
+ savefile(dest, i, X_ind)
+ else:
+ selinux.setexeccon(execcon)
+ rc = os.spawnvp(os.P_WAIT, cmds[0], cmds)
+ selinux.setexeccon(None)
+ finally:
+ if home_and_temp:
+ if newhomedir and not existing_home:
+ shutil.rmtree(newhomedir)
+ if newtmpdir and not existing_temp:
+ shutil.rmtree(newtmpdir)
+
+ except getopt.GetoptError, error:
+ usage(_("Options Error %s ") % error.msg)
+ sandbox = Sandbox()
+ rc = sandbox.main()
+ except OSError, error:
+ error_exit(error.args[1])
+ except ValueError, error:
@ -2120,7 +2166,7 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+ except KeyError, error:
+ error_exit(_("Invalid value %s") % error.args[0])
+ except IOError, error:
+ error_exit(error.message)
+ error_exit(error)
+ except KeyboardInterrupt:
+ rc = 0
+
@ -2258,10 +2304,11 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+esac
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/sandbox/sandboxX.sh policycoreutils-2.0.79/sandbox/sandboxX.sh
--- nsapolicycoreutils/sandbox/sandboxX.sh 1969-12-31 19:00:00.000000000 -0500
+++ policycoreutils-2.0.79/sandbox/sandboxX.sh 2010-02-26 14:14:26.000000000 -0500
@@ -0,0 +1,14 @@
+++ policycoreutils-2.0.79/sandbox/sandboxX.sh 2010-03-04 16:44:32.000000000 -0500
@@ -0,0 +1,15 @@
+#!/bin/bash
+export TITLE="Sandbox: `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80` Running as `secon -t -l -P`"
+context=`id -Z | secon -t -l -P`
+export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80`"
+export SCREENSIZE="1000x700"
+#export SCREENSIZE=`xdpyinfo | awk '/dimensions/ { print $2 }'`
+trap "exit 0" HUP
@ -2543,6 +2590,108 @@ diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po
+
+ return status;
+}
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/sandbox/test_sandbox.py policycoreutils-2.0.79/sandbox/test_sandbox.py
--- nsapolicycoreutils/sandbox/test_sandbox.py 1969-12-31 19:00:00.000000000 -0500
+++ policycoreutils-2.0.79/sandbox/test_sandbox.py 2010-03-04 16:22:56.000000000 -0500
@@ -0,0 +1,98 @@
+import unittest, os, shutil
+from tempfile import mkdtemp
+from subprocess import Popen, PIPE
+
+class SandboxTests(unittest.TestCase):
+ def assertDenied(self, err):
+ self.assert_('Permission denied' in err,
+ '"Permission denied" not found in %r' % err)
+ def assertNotFound(self, err):
+ self.assert_('not found' in err,
+ '"not found" not found in %r' % err)
+
+ def assertFailure(self, status):
+ self.assert_(status != 0,
+ '"Succeeded when it should have failed')
+
+ def assertSuccess(self, status, err):
+ self.assert_(status == 0,
+ '"Sandbox should have succeeded for this test %r' % err)
+
+ def test_simple_success(self):
+ "Verify that we can read file descriptors handed to sandbox"
+ p1 = Popen(['cat', '/etc/passwd'], stdout = PIPE)
+ p2 = Popen(['sandbox', 'grep', 'root'], stdin = p1.stdout, stdout=PIPE)
+ out, err = p2.communicate()
+ self.assert_('root' in out)
+
+ def test_cant_kill(self):
+ "Verify that we cannot send kill signal in the sandbox"
+ pid = os.getpid()
+ p = Popen(['sandbox', 'kill', '-HUP', str(pid)], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertDenied(err)
+
+ def test_cant_ping(self):
+ "Verify that we can't ping within the sandbox"
+ p = Popen(['sandbox', 'ping', '-c 1 ', '127.0.0.1'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertDenied(err)
+
+ def test_cant_mkdir(self):
+ "Verify that we can't mkdir within the sandbox"
+ p = Popen(['sandbox', 'mkdir', '~/test'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertFailure(p.returncode)
+
+ def test_cant_list_homedir(self):
+ "Verify that we can't list homedir within the sandbox"
+ p = Popen(['sandbox', 'ls', '~'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertFailure(p.returncode)
+
+ def test_cant_send_mail(self):
+ "Verify that we can't send mail within the sandbox"
+ p = Popen(['sandbox', 'mail'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertDenied(err)
+
+ def test_cant_sudo(self):
+ "Verify that we can't run sudo within the sandbox"
+ p = Popen(['sandbox', 'sudo'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertFailure(p.returncode)
+
+ def test_mount(self):
+ "Verify that we mount a file system"
+ p = Popen(['sandbox', '-M', 'id'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+
+ def test_set_level(self):
+ "Verify that we set level a file system"
+ p = Popen(['sandbox', '-l', 's0', 'id'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+
+ def test_homedir(self):
+ "Verify that we set homedir a file system"
+ homedir = mkdtemp(dir=".", prefix=".sandbox_test")
+ p = Popen(['sandbox', '-H', homedir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ shutil.rmtree(homedir)
+ self.assertSuccess(p.returncode, err)
+
+ def test_tmpdir(self):
+ "Verify that we set tmpdir a file system"
+ tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_test")
+ p = Popen(['sandbox', '-T', tmpdir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ shutil.rmtree(tmpdir)
+ self.assertSuccess(p.returncode, err)
+
+if __name__ == "__main__":
+ import selinux
+ if selinux.security_getenforce() == 1:
+ unittest.main()
+ else:
+ print "SELinux must be in enforcing mode for this test"
diff --exclude-from=exclude --exclude=sepolgen-1.0.19 --exclude=gui --exclude=po -N -u -r nsapolicycoreutils/scripts/fixfiles policycoreutils-2.0.79/scripts/fixfiles
--- nsapolicycoreutils/scripts/fixfiles 2009-12-01 15:46:50.000000000 -0500
+++ policycoreutils-2.0.79/scripts/fixfiles 2010-02-26 16:12:15.000000000 -0500

View File

@ -1,6 +1,6 @@
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/access.py
--- nsasepolgen/src/sepolgen/access.py 2009-05-18 13:53:14.000000000 -0400
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py 2009-12-08 17:05:49.000000000 -0500
+++ policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/access.py 2010-03-01 16:43:01.000000000 -0500
@@ -32,6 +32,7 @@
"""
@ -9,16 +9,18 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policyco
def is_idparam(id):
"""Determine if an id is a paramater in the form $N, where N is
@@ -85,6 +86,8 @@
@@ -85,6 +86,10 @@
self.obj_class = None
self.perms = refpolicy.IdSet()
self.audit_msgs = []
+ self.type = audit2why.TERULE
+ self.bools = []
+
+ self.dontaudit = False
# The direction of the information flow represented by this
# access vector - used for matching
@@ -127,7 +130,7 @@
@@ -127,7 +132,7 @@
return self.to_string()
def to_string(self):
@ -27,12 +29,12 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policyco
self.obj_class, self.perms.to_space_str())
def __cmp__(self, other):
@@ -253,20 +256,22 @@
@@ -253,20 +258,23 @@
for av in l:
self.add_av(AccessVector(av))
- def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None):
+ def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[]):
+ def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[], dontaudit=False):
"""Add an access vector to the set.
"""
tgt = self.src.setdefault(src_type, { })
@ -50,13 +52,14 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policyco
- cls[obj_class] = access
+ access.bools = bools
+ access.type = avc_type
+ access.dontaudit = dontaudit
+ cls[obj_class, avc_type] = access
access.perms.update(perms)
if audit_msg:
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/audit.py
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/audit.py
--- nsasepolgen/src/sepolgen/audit.py 2009-12-01 15:46:50.000000000 -0500
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/audit.py 2010-01-06 09:52:35.000000000 -0500
+++ policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/audit.py 2010-03-01 15:25:21.000000000 -0500
@@ -23,6 +23,27 @@
# Convenience functions
@ -165,6 +168,15 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycor
self.compute_sid_msgs = []
self.invalid_msgs = []
self.policy_load_msgs = []
@@ -424,7 +488,7 @@
return role_types
- def to_access(self, avc_filter=None, only_denials=True):
+ def to_access(self, avc_filter=None, only_denials=True, dontaudit=False):
"""Convert the audit logs access into a an access vector set.
Convert the audit logs into an access vector set, optionally
@@ -442,16 +506,17 @@
audit logs parsed by this object.
"""
@ -177,11 +189,11 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycor
if avc_filter.filter(avc):
av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
- avc.accesses, avc)
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools, dontaudit=dontaudit)
else:
av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
- avc.accesses, avc)
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools, dontaudit=dontaudit)
return av_set
class AVCTypeFilter:
@ -191,9 +203,9 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycor
return False
-
-
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/policygen.py
--- nsasepolgen/src/sepolgen/policygen.py 2008-09-12 11:48:15.000000000 -0400
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py 2010-01-08 09:33:54.000000000 -0500
+++ policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/policygen.py 2010-03-01 14:49:37.000000000 -0500
@@ -29,6 +29,8 @@
import access
import interfaces
@ -212,15 +224,10 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py polic
def set_gen_refpol(self, if_set=None, perm_maps=None):
"""Set whether reference policy interfaces are generated.
@@ -141,15 +143,42 @@
"""Return the generated module"""
return self.module
- def __add_allow_rules(self, avs):
+ def __add_allow_rules(self, avs, dontaudit):
@@ -144,8 +146,35 @@
def __add_allow_rules(self, avs):
for av in avs:
- rule = refpolicy.AVRule(av)
+ rule = refpolicy.AVRule(av, dontaudit=dontaudit)
rule = refpolicy.AVRule(av)
+ rule.comment = ""
if self.explain:
rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain))
@ -253,23 +260,9 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py polic
self.module.children.append(rule)
- def add_access(self, av_set):
+ def add_access(self, av_set, dontaudit=False):
"""Add the access from the access vector set to this
module.
"""
@@ -165,7 +194,7 @@
raw_allow = av_set
# Generate the raw allow rules from the filtered list
- self.__add_allow_rules(raw_allow)
+ self.__add_allow_rules(raw_allow, dontaudit)
def add_role_types(self, role_type_set):
for role_type in role_type_set:
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/refpolicy.py
--- nsasepolgen/src/sepolgen/refpolicy.py 2009-10-29 15:21:39.000000000 -0400
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py 2010-01-08 09:33:37.000000000 -0500
+++ policycoreutils-2.0.79/sepolgen-1.0.19/src/sepolgen/refpolicy.py 2010-03-01 14:50:42.000000000 -0500
@@ -398,6 +398,7 @@
return "attribute %s;" % self.name
@ -278,22 +271,12 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py polic
class AVRule(Leaf):
"""SELinux access vector (AV) rule.
@@ -420,21 +421,26 @@
AUDITALLOW = 2
NEVERALLOW = 3
- def __init__(self, av=None, parent=None):
+ def __init__(self, av=None, parent=None, dontaudit=False):
Leaf.__init__(self, parent)
self.src_types = IdSet()
@@ -426,15 +427,17 @@
self.tgt_types = IdSet()
self.obj_classes = IdSet()
self.perms = IdSet()
- self.rule_type = self.ALLOW
+ if dontaudit:
+ self.rule_type = audit2why.DONTAUDIT
+ else:
+ self.rule_type = audit2why.TERULE
+ self.rule_type = audit2why.TERULE
if av:
self.from_av(av)
@ -309,3 +292,12 @@ diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py polic
else:
return "auditallow"
@@ -449,6 +452,8 @@
self.tgt_types.add(av.tgt_type)
self.obj_classes.add(av.obj_class)
self.perms.update(av.perms)
+ if av.dontaudit:
+ self.rule_type = audit2why.DONTAUDIT
def to_string(self):
"""Return a string representation of the rule

View File

@ -7,7 +7,7 @@
Summary: SELinux policy core utilities
Name: policycoreutils
Version: 2.0.79
Release: 2%{?dist}
Release: 5%{?dist}
License: GPLv2+
Group: System Environment/Base
Source: http://www.nsa.gov/selinux/archives/policycoreutils-%{version}.tgz
@ -305,6 +305,16 @@ fi
exit 0
%changelog
* Mon Mar 1 2010 Dan Walsh <dwalsh@redhat.com> 2.0.79-5
- Rewrite of sandbox script, add unit test for sandbox
- Update translations
* Mon Mar 1 2010 Dan Walsh <dwalsh@redhat.com> 2.0.79-4
- Fix patch for dontaudit rules from audit2allow for upstream acceptance
* Fri Feb 26 2010 Dan Walsh <dwalsh@redhat.com> 2.0.79-3
- Fixes for fixfiles
* Wed Feb 17 2010 Dan Walsh <dwalsh@redhat.com> 2.0.79-2
- Fix sandbox to complain if mount-shared has not been run
- Fix to use /etc/sysconfig/sandbox