diff options
-rwxr-xr-x | bin/rainbow-easy | 89 | ||||
-rwxr-xr-x | bin/rainbow-gc | 4 | ||||
-rwxr-xr-x | bin/rainbow-resume | 64 | ||||
-rwxr-xr-x | bin/rainbow-run | 5 | ||||
-rwxr-xr-x | bin/rainbow-sugarize | 4 | ||||
-rwxr-xr-x | bin/rainbow-xify | 4 | ||||
-rw-r--r-- | rainbow/inject.py | 1 | ||||
-rw-r--r-- | rainbow/util.py | 44 |
8 files changed, 132 insertions, 83 deletions
diff --git a/bin/rainbow-easy b/bin/rainbow-easy index cdcef8d..9955007 100755 --- a/bin/rainbow-easy +++ b/bin/rainbow-easy @@ -1,45 +1,50 @@ -#!/bin/bash +#!/usr/bin/python -function usage() { - echo "sudo $0 ID /path/to/program" - echo "ex: sudo $0 banking /bin/bash" - exit 1 -} - -if [ -z "$1" ] || [ -z "$SUDO_USER" ]; then usage || exit 1; fi - -ID="$1"; shift - -read_parent_envvar () { -python <<EOF import os -from os.path import join +import sys -ppid = os.getppid() -env = open(join('/proc', str(ppid),'environ')).read().split('\0') -for kv in env: - if kv.startswith("$1="): - print kv[len("$1="):] -EOF -} - -PARENT_PATH=`read_parent_envvar PATH` - -if [ -z "$DISPLAY" ]; then - DISPLAY=`read_parent_envvar DISPLAY` -fi - -exec /usr/sbin/rainbow-run \ - -q \ - -s /var/spool/rainbow/2 \ - -u "$SUDO_USER" -c "`pwd`" \ - -f 0 -f 1 -f 2 \ - -i "${SUDO_USER}_${ID}" \ - -E "DISPLAY=$DISPLAY" \ - -E "XAUTHORITY=${XAUTHORITY:-${HOME}/.Xauthority}" \ - -E "PATH=${PARENT_PATH}" \ - -a /usr/bin/rainbow-xify \ - -o audio \ - -o network \ - -- \ - "$@" +from os.path import join +from optparse import OptionParser + +from rainbow.util import enable_verbose_tracebacks, make_reporter, EnvMerge + +enable_verbose_tracebacks() + +usage = "usage: sudo %prog [options] ACTIVITY /path/to/program" + +def main(): + parser = OptionParser(usage=usage, version='0.1') + opts, args = parser.parse_args() + if len(args) < 2 or "SUDO_USER" not in os.environ: + parser.print_help() + exit(1) + + activity = args[0] + launch_argv = args[1:] + + env = EnvMerge() + path = env.parent_envvar("PATH") or "" + term = env.parent_envvar("TERM") or "" + display = env.prefer_our_envvar("DISPLAY") or "" + xauthority = env.prefer_our_envvar("XAUTHORITY") or "" + + rainbow_argv = [ + "/usr/sbin/rainbow-run", + "-s", "/var/spool/rainbow/2", + "-u", os.environ["SUDO_USER"], + "-c", os.getcwd(), + "-f", "0", "-f", "1", "-f", "2", + "-E", "DISPLAY="+display, + "-E", "XAUTHORITY="+xauthority, + "-E", "PATH="+path, + "-E", "TERM="+term, + "-a", "/usr/bin/rainbow-xify", + "-o", "audio", + "-o", "network", + "-i", "%s_%s" % (os.environ["SUDO_USER"], activity), + "--"] + launch_argv + + return os.execv(rainbow_argv[0], rainbow_argv) + +if __name__ == "__main__": + main() diff --git a/bin/rainbow-gc b/bin/rainbow-gc index 6f1d99a..efcec8f 100755 --- a/bin/rainbow-gc +++ b/bin/rainbow-gc @@ -8,7 +8,9 @@ from os.path import join, isdir, islink, exists from optparse import OptionParser from glob import glob -from rainbow.util import trace, make_reporter +from rainbow.util import make_reporter, enable_verbose_tracebacks + +enable_verbose_tracebacks() def active_uid(uid): cmd = ['/usr/bin/pgrep', '-U', uid] diff --git a/bin/rainbow-resume b/bin/rainbow-resume index 3e11487..1cf919a 100755 --- a/bin/rainbow-resume +++ b/bin/rainbow-resume @@ -1,26 +1,50 @@ -#!/bin/bash +#!/usr/bin/python -function usage() { - echo "sudo $0 RESUME_UID /path/to/program" - echo "ex: sudo $0 banking /bin/bash" - exit 1 -} +import os +import sys -if [ -z "$1" ] || [ -z "$SUDO_USER" ]; then usage || exit 1; fi +from os.path import join +from optparse import OptionParser -RESUME_UID="$1"; shift +from rainbow.util import make_reporter, enable_verbose_tracebacks, EnvMerge -if [ -z "$DISPLAY" ]; then - DISPLAY=`python <<EOF -import os -from os.path import join +enable_verbose_tracebacks() + +usage = "usage: sudo %prog [options] RESUME_UID /path/to/program" + +def main(): + parser = OptionParser(usage=usage, version='0.1') + opts, args = parser.parse_args() + if len(args) < 2 or "SUDO_USER" not in os.environ: + parser.print_help() + exit(1) + + resume_uid = args[0] + launch_argv = args[1:] + + env = EnvMerge() + path = env.parent_envvar("PATH") or "" + term = env.parent_envvar("TERM") or "" + display = env.prefer_our_envvar("DISPLAY") or "" + xauthority = env.prefer_our_envvar("XAUTHORITY") or "" + + rainbow_argv = [ + "/usr/sbin/rainbow-run", + "-s", "/var/spool/rainbow/2", + "-u", os.environ["SUDO_USER"], + "-c", os.getcwd(), + "-f", "0", "-f", "1", "-f", "2", + "-E", "DISPLAY="+display, + "-E", "XAUTHORITY="+xauthority, + "-E", "PATH="+path, + "-E", "TERM="+term, + "-a", "/usr/bin/rainbow-xify", + "-o", "audio", + "-o", "network", + "-r", resume_uid, + "--"] + launch_argv -ppid = os.getppid() -env = open(join('/proc', str(ppid),'environ')).read().split('\0') -for kv in env: - if kv.startswith("DISPLAY="): - print kv[len("DISPLAY="):] -EOF` -fi + return os.execv(rainbow_argv[0], rainbow_argv) -exec /usr/sbin/rainbow-run -s /var/spool/rainbow/2 -u "$SUDO_USER" -c "`pwd`" -f 0 -f 1 -f 2 -E "DISPLAY=$DISPLAY" -E "XAUTHORITY=$XAUTHORITY" -a /usr/bin/rainbow-xify -o audio -o network -r "$RESUME_UID" -- "$@" +if __name__ == "__main__": + main() diff --git a/bin/rainbow-run b/bin/rainbow-run index 70ba823..fc5aed5 100755 --- a/bin/rainbow-run +++ b/bin/rainbow-run @@ -12,9 +12,10 @@ from pprint import pformat from rainbow.inject import inject from rainbow.permissions import PermissionSet -from rainbow.util import make_reporter, trace, unshare, CLONE_NEWNS, read_envdir +from rainbow.util import make_reporter, enable_verbose_tracebacks +from rainbow.util import unshare, CLONE_NEWNS, read_envdir -sys.excepthook = trace +enable_verbose_tracebacks() def main(): parser = OptionParser(version='0.1') diff --git a/bin/rainbow-sugarize b/bin/rainbow-sugarize index ec0f119..694f261 100755 --- a/bin/rainbow-sugarize +++ b/bin/rainbow-sugarize @@ -8,9 +8,9 @@ from os.path import join, isdir, dirname, exists from optparse import OptionParser from shutil import copyfile -from rainbow.util import make_reporter, trace, make_dirs +from rainbow.util import make_reporter, enable_verbose_tracebacks, make_dirs -sys.excepthook = trace +enable_verbose_tracebacks() def main(): parser = OptionParser(version='0.1') diff --git a/bin/rainbow-xify b/bin/rainbow-xify index c2f633e..2aafb76 100755 --- a/bin/rainbow-xify +++ b/bin/rainbow-xify @@ -8,9 +8,9 @@ from os.path import join, isdir, dirname, exists from optparse import OptionParser from shutil import copyfile -from rainbow.util import make_reporter, trace, make_dirs +from rainbow.util import make_reporter, enable_verbose_tracebacks, make_dirs -sys.excepthook = trace +enable_verbose_tracebacks() def main(): parser = OptionParser(version='0.1') diff --git a/rainbow/inject.py b/rainbow/inject.py index f628f6d..304c526 100644 --- a/rainbow/inject.py +++ b/rainbow/inject.py @@ -329,6 +329,7 @@ def inject(log, spool, env, argv, cwd, pset, safe_fds, owner_uid, owner_gid, env.update(configure_x11(log, spool, owner_uid, owner_gid, uid, env, safe_fds)) if assistant: env.update(run_assistant(log, assistant, env, owner_uid, owner_gid, uid, groups, safe_fds)) + env['HOME'] = home mount_fsen(log, home) configure_network(log, pset) diff --git a/rainbow/util.py b/rainbow/util.py index 3679c20..8217d3c 100644 --- a/rainbow/util.py +++ b/rainbow/util.py @@ -1,4 +1,6 @@ -import os +from __future__ import with_statement + +import os, sys from stat import ST_MODE, ST_UID, ST_GID, S_ISREG @@ -73,19 +75,11 @@ def profile(profiler): return inner return wrapper -def trace(etype=None, value=None, tb=None): - try: - from IPython.ultraTB import AutoFormattedTB - trace_any = AutoFormattedTB(mode='Verbose', color_scheme='NoColor', call_pdb=0) - trace_exact = trace_any - except: - from traceback import print_exc, print_exception - trace_any = print_exc - trace_exact = print_exception - if etype or value or tb: - trace_exact(etype, value, tb) - else: - trace_any() +def enable_verbose_tracebacks(): + import sys, cgitb + cgitb.enable(format="plain") + cgitb.handler = sys.excepthook.handle + return cgitb.handler ### File mode checking. @@ -503,3 +497,25 @@ def read_envdir(envdir, overrides=None): k, v = binding.split('=',1) env[k] = v return env + +class EnvMerge(object): + def __init__(self): + self.parent_env = None + + def read_parent_envfile(self): + ppid = str(os.getppid()) + with open(join('/proc', ppid,'environ')) as f: + self.parent_env = f.read().split('\0') + + def parent_envvar(self, key): + if self.parent_env is None: + self.read_parent_envfile() + for kv in self.parent_env: + if kv.startswith(key + "="): + return kv[len(key +"="):] + return None + + def prefer_our_envvar(self, key): + if key in os.environ: + return os.environ[key] + return self.parent_envvar(key) |