#!/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 = "policycoreutils"
try:
    import gettext
    kwargs = {}
    if sys.version_info < (3,):
        kwargs['unicode'] = True
    gettext.install(PROGNAME,
                    localedir="/usr/share/locale",
                    codeset='utf-8',
                    **kwargs)
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

    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("-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
        else:
            if self.__options.level:
                self.__homedir = self.__options.homedir
                self.__tmpdir = self.__options.tmpdir

            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_")
        self.__copyfiles()
        selinux.chcon(self.__homedir, self.__filecon, recursive=True)
        selinux.chcon(self.__tmpdir, 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]

                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 IOError as error:
        error_exit(error)
    except KeyboardInterrupt:
        rc = 0

    sys.exit(rc)
