#!/usr/bin/python3 -Es
# Authors: Dan Walsh <dwalsh@redhat.com>
# Authors: Thomas Liu <tliu@fedoraproject.org>
# Authors: Josh Cogliati
#
# 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
# 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
#

import os
import stat
import sys
import socket
import random
import fcntl
import shutil
import re
import subprocess
import selinux
import signal
from tempfile import mkdtemp
import pwd
import sepolicy

SEUNSHARE = "/usr/sbin/seunshare"
SANDBOXSH = "/usr/share/sandbox/sandboxX.sh"
PROGNAME = "selinux-sandbox"
try:
    import gettext
    kwargs = {}
    if sys.version_info < (3,):
        kwargs['unicode'] = True
    t = gettext.translation(PROGNAME,
                    localedir="/usr/share/locale",
                    **kwargs,
                    fallback=True)
    _ = t.gettext
except:
    try:
        import builtins
        builtins.__dict__['_'] = str
    except ImportError:
        import __builtin__
        __builtin__.__dict__['_'] = unicode

DEFAULT_WINDOWSIZE = "1000x700"
DEFAULT_TYPE = "sandbox_t"
DEFAULT_X_TYPE = "sandbox_x_t"
SAVE_FILES = {}

random.seed(None)


def sighandler(signum, frame):
    signal.signal(signum, signal.SIG_IGN)
    os.kill(0, signum)
    raise KeyboardInterrupt


def setup_sighandlers():
    signal.signal(signal.SIGHUP, sighandler)
    signal.signal(signal.SIGQUIT, sighandler)
    signal.signal(signal.SIGTERM, sighandler)


def error_exit(msg):
    sys.stderr.write("%s: " % sys.argv[0])
    sys.stderr.write("%s\n" % msg)
    sys.stderr.flush()
    sys.exit(1)


def copyfile(file, srcdir, dest):
    import re
    if file.startswith(srcdir):
        dname = os.path.dirname(file)
        bname = os.path.basename(file)
        if dname == srcdir:
            dest = dest + "/" + bname
        else:
            newdir = re.sub(srcdir, dest, dname)
            if not os.path.exists(newdir):
                os.makedirs(newdir)
            dest = newdir + "/" + bname

        try:
            if os.path.isdir(file):
                shutil.copytree(file, dest)
            else:
                shutil.copy2(file, dest)

        except shutil.Error as elist:
            for e in elist.message:
                sys.stderr.write(e[2])

        SAVE_FILES[file] = (dest, os.path.getmtime(dest))


def savefile(new, orig, X_ind):
    copy = False
    if X_ind:
        import gi
        gi.require_version('Gtk', '3.0')
        from gi.repository import Gtk
        dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
                                Gtk.ButtonsType.YES_NO,
                                _("Do you want to save changes to '%s' (Y/N): ") % orig)
        dlg.set_title(_("Sandbox Message"))
        dlg.set_position(Gtk.WindowPosition.MOUSE)
        dlg.show_all()
        rc = dlg.run()
        dlg.destroy()
        if rc == Gtk.ResponseType.YES:
            copy = True
    else:
        try:
            input = raw_input
        except NameError:
            pass
        ans = 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)
    fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)


def get_range():
    try:
        level = selinux.getcon_raw()[1].split(":")[4]
        lowc, highc = level.split(".")
        low = int(lowc[1:])
        high = int(highc[1:]) + 1
        if high - low == 0:
            raise IndexError

        return low, high
    except IndexError:
        raise ValueError(_("User account must be setup with an MCS Range"))


def gen_mcs():
    low, high = get_range()

    level = None
    ctr = 0
    total = high - low
    total = (total * (total - 1)) / 2
    while ctr < total:
        ctr += 1
        i1 = random.randrange(low, high)
        i2 = random.randrange(low, high)
        if i1 == i2:
            continue
        if i1 > i2:
            tmp = i1
            i1 = i2
            i2 = tmp
        level = "s0:c%d,c%d" % (i1, i2)
        try:
            reserve(level)
        except socket.error:
            continue
        break
    if level:
        return level
    raise ValueError(_("Failed to find any unused category sets.  Consider a larger MCS range for this user."))


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


class Sandbox:
    SYSLOG = "/var/log/messages"

    def __init__(self):
        self.setype = DEFAULT_TYPE
        self.__options = None
        self.__cmds = None
        self.__init_files = []
        self.__paths = []
        self.__mount = False
        self.__level = None
        self.__homedir = None
        self.__tmpdir = None
        self.__runuserdir = None

    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 not os.path.exists(SEUNSHARE):
            raise ValueError(_("""
%s is required for the action you want to perform.
""") % SEUNSHARE)

    def __mount_callback(self, option, opt, value, parser):
        self.__mount = True

    def __x_callback(self, option, opt, value, parser):
        self.__mount = True
        setattr(parser.values, option.dest, True)
        if not os.path.exists(SEUNSHARE):
            raise ValueError(_("""
%s is required for the action you want to perform.
""") % SEUNSHARE)

        if not os.path.exists(SANDBOXSH):
            raise ValueError(_("""
%s is required for the action you want to perform.
""") % SANDBOXSH)

    def __validdir(self, option, opt, value, parser):
        if not os.path.isdir(value):
            raise IOError("Directory " + value + " not found")
        setattr(parser.values, option.dest, value)
        self.__mount = True

    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():
            try:
                self.__include(option, opt, i[:-1], parser)
            except IOError as e:
                sys.stderr.write(str(e))
            except TypeError as e:
                sys.stderr.write(str(e))
        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)
            copyfile(f, "/var/tmp", self.__tmpdir)

    def __setup_sandboxrc(self, wm="/usr/bin/openbox"):
        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 = self.__paths[0] + " "
            for p in self.__paths[1:]:
                command += "'%s' " % p
            fd.write("""#! /bin/sh
#TITLE: %s
# /usr/bin/test -r ~/.xmodmap && /usr/bin/xmodmap ~/.xmodmap
%s &
WM_PID=$!
if which dbus-run-session >/dev/null 2>&1; then
    dbus-run-session -- %s
else
    dbus-launch --exit-with-session %s
fi
kill -TERM $WM_PID  2> /dev/null
""" % (command, wm, command, command))
        fd.close()
        os.chmod(execfile, 0o700)

    def usage(self, message=""):
        error_exit("%s\n%s" % (self.__parser.usage, message))

    def __parse_options(self):
        from optparse import OptionParser
        types = ""
        try:
            types = _("""
Policy defines the following types for use with the -t:
\t%s
""") % "\n\t".join(next(sepolicy.info(sepolicy.ATTRIBUTE, "sandbox_type"))['types'])
        except StopIteration:
            pass

        usage = _("""
sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] command

sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] -S
%s
""") % types

        parser = OptionParser(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=_("read list of files to include in sandbox from INCLUDEFILE"))
        parser.add_option("-t", "--type", dest="setype", action="store", default=None,
                          help=_("run sandbox with SELinux type"))
        parser.add_option("-M", "--mount",
                          action="callback", callback=self.__mount_callback,
                          help=_("mount new home and/or tmp directory"))

        parser.add_option("-d", "--dpi",
                          dest="dpi", action="store",
                          help=_("dots per inch for X display"))

        parser.add_option("-S", "--session", action="store_true", dest="session",
                          default=False, help=_("run complete desktop session within sandbox"))

        parser.add_option("-s", "--shred", action="store_true", dest="shred",
                          default=False, help=_("Shred content before temporary directories are removed"))

        parser.add_option("-X", dest="X_ind",
                          action="callback", callback=self.__x_callback,
                          default=False, help=_("run X application within a sandbox"))

        parser.add_option("-H", "--homedir",
                          action="callback", callback=self.__validdir,
                          type="string",
                          dest="homedir",
                          help=_("alternate home directory to use for mounting"))

        parser.add_option("-T", "--tmpdir", dest="tmpdir",
                          type="string",
                          action="callback", callback=self.__validdir,
                          help=_("alternate /tmp directory to use for mounting"))

        parser.add_option("-R", "--runuserdir", dest="runuserdir",
                          type="string",
                          action="callback", callback=self.__validdir,
                          help=_("alternate XDG_RUNTIME_DIR - /run/user/$UID - directory to use for mounting"))

        parser.add_option("-w", "--windowsize", dest="windowsize",
                          type="string", default=DEFAULT_WINDOWSIZE,
                          help="size of the sandbox window")

        parser.add_option("-W", "--windowmanager", dest="wm",
                          type="string",
                          default="/usr/bin/openbox",
                          help=_("alternate window manager"))

        parser.add_option("-l", "--level", dest="level",
                          help=_("MCS/MLS level for the sandbox"))

        parser.add_option("-C", "--capabilities",
                          action="store_true", dest="usecaps", default=False,
                          help="Allow apps requiring capabilities to run within the sandbox.")

        self.__parser = parser

        self.__options, cmds = parser.parse_args()

        if self.__options.X_ind:
            self.setype = DEFAULT_X_TYPE
        else:
            try:
                next(sepolicy.info(sepolicy.TYPE, "sandbox_t"))
            except StopIteration:
                raise ValueError(_("Sandbox Policy is not currently installed.\nYou need to install the selinux-policy-sandbox package in order to run this command"))

        if self.__options.setype:
            self.setype = self.__options.setype

        if self.__mount:
            self.__validate_mount()

        if self.__options.session:
            if not self.__options.setype:
                self.setype = selinux.getcon()[1].split(":")[2]
            if not self.__options.homedir or not self.__options.tmpdir:
                self.usage(_("You must specify a Homedir and tempdir when setting up a session sandbox"))
            if len(cmds) > 0:
                self.usage(_("Commands are not allowed in a session sandbox"))
            self.__options.X_ind = True
            self.__homedir = self.__options.homedir
            self.__tmpdir = self.__options.tmpdir
            self.__runuserdir = self.__options.runuserdir
        else:
            if self.__options.level:
                self.__homedir = self.__options.homedir
                self.__tmpdir = self.__options.tmpdir
                self.__runuserdir = self.__options.runuserdir

            if len(cmds) == 0:
                self.usage(_("Command required"))
            cmds[0] = fullpath(cmds[0])
            if not os.access(cmds[0], os.X_OK):
                self.usage(_("%s is not an executable") % 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.setype, level)
        self.__filecon = "%s:object_r:sandbox_file_t:%s" % (con[0], level)

    def __setup_dir(self):
        selinux.setfscreatecon(self.__filecon)
        if self.__options.homedir:
            self.__homedir = self.__options.homedir
        else:
            self.__homedir = mkdtemp(dir="/tmp", prefix=".sandbox_home_")

        if self.__options.tmpdir:
            self.__tmpdir = self.__options.tmpdir
        else:
            self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
        if self.__options.runuserdir:
            self.__runuserdir = self.__options.runuserdir
        else:
            self.__runuserdir = mkdtemp(dir="/tmp", prefix=".sandbox_runuser_")
        self.__copyfiles()
        selinux.chcon(self.__homedir, self.__filecon, recursive=True)
        selinux.chcon(self.__tmpdir, self.__filecon, recursive=True)
        selinux.chcon(self.__runuserdir, self.__filecon, recursive=True)
        selinux.setfscreatecon(None)

    def __execute(self):
        try:
            cmds = [SEUNSHARE, "-Z", self.__execcon]
            if self.__options.usecaps:
                cmds.append('-C')
            if self.__mount:
                cmds += ["-t", self.__tmpdir, "-h", self.__homedir, "-r", self.__runuserdir]

                if self.__options.X_ind:
                    if self.__options.dpi:
                        dpi = self.__options.dpi
                    else:
                        import gi
                        gi.require_version('Gtk', '3.0')
                        from gi.repository import Gtk
                        dpi = str(Gtk.Settings.get_default().props.gtk_xft_dpi / 1024)

                    xmodmapfile = self.__homedir + "/.xmodmap"
                    xd = open(xmodmapfile, "w")
                    subprocess.Popen(["/usr/bin/xmodmap", "-pke"], stdout=xd).wait()
                    xd.close()

                    self.__setup_sandboxrc(self.__options.wm)

                    cmds += ["--", SANDBOXSH, self.__options.windowsize, dpi]
                else:
                    cmds += ["--"] + self.__paths
                return subprocess.Popen(cmds).wait()

            pid = os.fork()
            if pid == 0:
                rc = os.setsid()
                if rc:
                    return rc
                selinux.setexeccon(self.__execcon)
                os.execv(self.__cmds[0], self.__cmds)
            rc = os.waitpid(pid, 0)
            return os.WEXITSTATUS(rc[1])

        finally:
            for i in self.__paths:
                if i not in SAVE_FILES:
                    continue
                (dest, mtime) = SAVE_FILES[i]
                if os.path.getmtime(dest) > mtime:
                    savefile(dest, i, self.__options.X_ind)

            if self.__homedir and not self.__options.homedir:
                if self.__options.shred:
                    self.shred(self.__homedir)
                shutil.rmtree(self.__homedir)
            if self.__tmpdir and not self.__options.tmpdir:
                if self.__options.shred:
                    self.shred(self.__homedir)
                shutil.rmtree(self.__tmpdir)

    def shred(self, path):
        for root, dirs, files in os.walk(path):
            for f in files:
                dest = root + "/" + f
                subprocess.Popen(["/usr/bin/shred", dest]).wait()

    def main(self):
        try:
            self.__parse_options()
            self.__gen_context()
            if self.__mount:
                self.__setup_dir()
            return self.__execute()
        except KeyboardInterrupt:
            sys.exit(0)


if __name__ == '__main__':
    setup_sighandlers()
    if selinux.is_selinux_enabled() != 1:
        error_exit("Requires an SELinux enabled system")

    try:
        sandbox = Sandbox()
        rc = sandbox.main()
    except OSError as error:
        error_exit(error)
    except ValueError as error:
        error_exit(error.args[0])
    except KeyError as error:
        error_exit(_("Invalid value %s") % error.args[0])
    except KeyboardInterrupt:
        rc = 0

    sys.exit(rc)
