"""Restricted execution facilities.

The class RExec exports methods r_exec(), r_eval(), r_execfile(), and
r_import(), which correspond roughly to the built-in operations
exec, eval(), execfile() and import, but executing the code in an
environment that only exposes those built-in operations that are
deemed safe.  To this end, a modest collection of 'fake' modules is
created which mimics the standard modules by the same names.  It is a
policy decision which built-in modules and operations are made
available; this module provides a reasonable default, but derived
classes can change the policies e.g. by overriding or extending class
variables like ok_builtin_modules or methods like make_sys().

XXX To do:
- r_open should allow writing tmp dir
- r_exec etc. with explicit globals/locals? (Use rexec("exec ... in ...")?)

"""


import sys
import __builtin__
import os
import ihooks
import imp

__all__ = ["RExec"]

class FileBase:

    ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
            'readlines', 'seek', 'tell', 'write', 'writelines')


class FileWrapper(FileBase):

    # XXX This is just like a Bastion -- should use that!

    def __init__(self, f):
        self.f = f
        for m in self.ok_file_methods:
            if not hasattr(self, m) and hasattr(f, m):
                setattr(self, m, getattr(f, m))

    def close(self):
        self.flush()


TEMPLATE = """
def %s(self, *args):
        return apply(getattr(self.mod, self.name).%s, args)
"""

class FileDelegate(FileBase):

    def __init__(self, mod, name):
        self.mod = mod
        self.name = name

    for m in FileBase.ok_file_methods + ('close',):
        exec TEMPLATE % (m, m)


class RHooks(ihooks.Hooks):

    def __init__(self, *args):
        # Hacks to support both old and new interfaces:
        # old interface was RHooks(rexec[, verbose])
        # new interface is RHooks([verbose])
        verbose = 0
        rexec = None
        if args and type(args[-1]) == type(0):
            verbose = args[-1]
            args = args[:-1]
        if args and hasattr(args[0], '__class__'):
            rexec = args[0]
            args = args[1:]
        if args:
            raise TypeError, "too many arguments"
        ihooks.Hooks.__init__(self, verbose)
        self.rexec = rexec

    def set_rexec(self, rexec):
        # Called by RExec instance to complete initialization
        self.rexec = rexec

    def get_suffixes(self):
        return self.rexec.get_suffixes()

    def is_builtin(self, name):
        return self.rexec.is_builtin(name)

    def init_builtin(self, name):
        m = __import__(name)
        return self.rexec.copy_except(m, ())

    def init_frozen(self, name): raise SystemError, "don't use this"
    def load_source(self, *args): raise SystemError, "don't use this"
    def load_compiled(self, *args): raise SystemError, "don't use this"
    def load_package(self, *args): raise SystemError, "don't use this"

    def load_dynamic(self, name, filename, file):
        return self.rexec.load_dynamic(name, filename, file)

    def add_module(self, name):
        return self.rexec.add_module(name)

    def modules_dict(self):
        return self.rexec.modules

    def default_path(self):
        return self.rexec.modules['sys'].path


# XXX Backwards compatibility
RModuleLoader = ihooks.FancyModuleLoader
RModuleImporter = ihooks.ModuleImporter


class RExec(ihooks._Verbose):
    """Basic restricted execution framework.

    Code executed in this restricted environment will only have access to
    modules and functions that are deemed safe; you can subclass RExec to
    add or remove capabilities as desired.

    The RExec class can prevent code from performing unsafe operations like
    reading or writing disk files, or using TCP/IP sockets.  However, it does
    not protect against code using extremely large amounts of memory or
    processor time.

    """

    ok_path = tuple(sys.path)           # That's a policy decision

    ok_builtin_modules = ('audioop', 'array', 'binascii',
                          'cmath', 'errno', 'imageop',
                          'marshal', 'math', 'md5', 'operator',
                          'parser', 'regex', 'pcre', 'rotor', 'select',
                          'sha', '_sre', 'strop', 'struct', 'time')

    ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink',
                      'stat', 'times', 'uname', 'getpid', 'getppid',
                      'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')

    ok_sys_names = ('ps1', 'ps2', 'copyright', 'version',
                    'platform', 'exit', 'maxint')

    nok_builtin_names = ('open', 'file', 'reload', '__import__')

    ok_file_types = (imp.C_EXTENSION, imp.PY_SOURCE)

    def __init__(self, hooks = None, verbose = 0):
        """Returns an instance of the RExec class.

        The hooks parameter is an instance of the RHooks class or a subclass
        of it.  If it is omitted or None, the default RHooks class is
        instantiated.

        Whenever the RExec module searches for a module (even a built-in one)
        or reads a module's code, it doesn't actually go out to the file
        system itself.  Rather, it calls methods of an RHooks instance that
        was passed to or created by its constructor.  (Actually, the RExec
        object doesn't make these calls --- they are made by a module loader
        object that's part of the RExec object.  This allows another level of
        flexibility, which can be useful when changing the mechanics of
        import within the restricted environment.)

        By providing an alternate RHooks object, we can control the file
        system accesses made to import a module, without changing the
        actual algorithm that controls the order in which those accesses are
        made.  For instance, we could substitute an RHooks object that
        passes all filesystem requests to a file server elsewhere, via some
        RPC mechanism such as ILU.  Grail's applet loader uses this to support
        importing applets from a URL for a directory.

        If the verbose parameter is true, additional debugging output may be
        sent to standard output.

        """
        ihooks._Verbose.__init__(self, verbose)
        # XXX There's a circular reference here:
        self.hooks = hooks or RHooks(verbose)
        self.hooks.set_rexec(self)
        self.modules = {}
        self.ok_dynamic_modules = self.ok_builtin_modules
        list = []
        for mname in self.ok_builtin_modules:
            if mname in sys.builtin_module_names:
                list.append(mname)
        self.ok_builtin_modules = tuple(list)
        self.set_trusted_path()
        self.make_builtin()
        self.make_initial_modules()
        # make_sys must be last because it adds the already created
        # modules to its builtin_module_names
        self.make_sys()
        self.loader = RModuleLoader(self.hooks, verbose)
        self.importer = RModuleImporter(self.loader, verbose)

    def set_trusted_path(self):
        # Set the path from which dynamic modules may be loaded.
        # Those dynamic modules must also occur in ok_builtin_modules
        self.trusted_path = filter(os.path.isabs, sys.path)

    def load_dynamic(self, name, filename, file):
        if name not in self.ok_dynamic_modules:
            raise ImportError, "untrusted dynamic module: %s" % name
        if name in sys.modules:
            src = sys.modules[name]
        else:
            src = imp.load_dynamic(name, filename, file)
        dst = self.copy_except(src, [])
        return dst

    def make_initial_modules(self):
        self.make_main()
        self.make_osname()

    # Helpers for RHooks

    def get_suffixes(self):
        return [item   # (suff, mode, type)
                for item in imp.get_suffixes()
                if item[2] in self.ok_file_types]

    def is_builtin(self, mname):
        return mname in self.ok_builtin_modules

    # The make_* methods create specific built-in modules

    def make_builtin(self):
        m = self.copy_except(__builtin__, self.nok_builtin_names)
        m.__import__ = self.r_import
        m.reload = self.r_reload
        m.open = m.file = self.r_open

    def make_main(self):
        m = self.add_module('__main__')

    def make_osname(self):
        osname = os.name
        src = __import__(osname)
        dst = self.copy_only(src, self.ok_posix_names)
        dst.environ = e = {}
        for key, value in os.environ.items():
            e[key] = value

    def make_sys(self):
        m = self.copy_only(sys, self.ok_sys_names)
        m.modules = self.modules
        m.argv = ['RESTRICTED']
        m.path = map(None, self.ok_path)
        m.exc_info = self.r_exc_info
        m = self.modules['sys']
        l = self.modules.keys() + list(self.ok_builtin_modules)
        l.sort()
        m.builtin_module_names = tuple(l)

    # The copy_* methods copy existing modules with some changes

    def copy_except(self, src, exceptions):
        dst = self.copy_none(src)
        for name in dir(src):
            setattr(dst, name, getattr(src, name))
        for name in exceptions:
            try:
                delattr(dst, name)
            except AttributeError:
                pass
        return dst

    def copy_only(self, src, names):
        dst = self.copy_none(src)
        for name in names:
            try:
                value = getattr(src, name)
            except AttributeError:
                continue
            setattr(dst, name, value)
        return dst

    def copy_none(self, src):
        m = self.add_module(src.__name__)
        m.__doc__ = src.__doc__
        return m

    # Add a module -- return an existing module or create one

    def add_module(self, mname):
        m = self.modules.get(mname)
        if m is None:
            self.modules[mname] = m = self.hooks.new_module(mname)
        m.__builtins__ = self.modules['__builtin__']
        return m

    # The r* methods are public interfaces

    def r_exec(self, code):
        """Execute code within a restricted environment.

        The code parameter must either be a string containing one or more
        lines of Python code, or a compiled code object, which will be
        executed in the restricted environment's __main__ module.

        """
        m = self.add_module('__main__')
        exec code in m.__dict__

    def r_eval(self, code):
        """Evaluate code within a restricted environment.

        The code parameter must either be a string containing a Python
        expression, or a compiled code object, which will be evaluated in
        the restricted environment's __main__ module.  The value of the
        expression or code object will be returned.

        """
        m = self.add_module('__main__')
        return eval(code, m.__dict__)

    def r_execfile(self, file):
        """Execute the Python code in the file in the restricted
        environment's __main__ module.

        """
        m = self.add_module('__main__')
        execfile(file, m.__dict__)

    def r_import(self, mname, globals={}, locals={}, fromlist=[]):
        """Import a module, raising an ImportError exception if the module
        is considered unsafe.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        """
        return self.importer.import_module(mname, globals, locals, fromlist)

    def r_reload(self, m):
        """Reload the module object, re-parsing and re-initializing it.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        """
        return self.importer.reload(m)

    def r_unload(self, m):
        """Unload the module.

        Removes it from the restricted environment's sys.modules dictionary.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        """
        return self.importer.unload(m)

    # The s_* methods are similar but also swap std{in,out,err}

    def make_delegate_files(self):
        s = self.modules['sys']
        self.delegate_stdin = FileDelegate(s, 'stdin')
        self.delegate_stdout = FileDelegate(s, 'stdout')
        self.delegate_stderr = FileDelegate(s, 'stderr')
        self.restricted_stdin = FileWrapper(sys.stdin)
        self.restricted_stdout = FileWrapper(sys.stdout)
        self.restricted_stderr = FileWrapper(sys.stderr)

    def set_files(self):
        if not hasattr(self, 'save_stdin'):
            self.save_files()
        if not hasattr(self, 'delegate_stdin'):
            self.make_delegate_files()
        s = self.modules['sys']
        s.stdin = self.restricted_stdin
        s.stdout = self.restricted_stdout
        s.stderr = self.restricted_stderr
        sys.stdin = self.delegate_stdin
        sys.stdout = self.delegate_stdout
        sys.stderr = self.delegate_stderr

    def reset_files(self):
        self.restore_files()
        s = self.modules['sys']
        self.restricted_stdin = s.stdin
        self.restricted_stdout = s.stdout
        self.restricted_stderr = s.stderr


    def save_files(self):
        self.save_stdin = sys.stdin
        self.save_stdout = sys.stdout
        self.save_stderr = sys.stderr

    def restore_files(self):
        sys.stdin = self.save_stdin
        sys.stdout = self.save_stdout
        sys.stderr = self.save_stderr

    def s_apply(self, func, args=(), kw=None):
        self.save_files()
        try:
            self.set_files()
            if kw:
                r = apply(func, args, kw)
            else:
                r = apply(func, args)
        finally:
            self.restore_files()
        return r

    def s_exec(self, *args):
        """Execute code within a restricted environment.

        Similar to the r_exec() method, but the code will be granted access
        to restricted versions of the standard I/O streams sys.stdin,
        sys.stderr, and sys.stdout.

        The code parameter must either be a string containing one or more
        lines of Python code, or a compiled code object, which will be
        executed in the restricted environment's __main__ module.

        """
        return self.s_apply(self.r_exec, args)

    def s_eval(self, *args):
        """Evaluate code within a restricted environment.

        Similar to the r_eval() method, but the code will be granted access
        to restricted versions of the standard I/O streams sys.stdin,
        sys.stderr, and sys.stdout.

        The code parameter must either be a string containing a Python
        expression, or a compiled code object, which will be evaluated in
        the restricted environment's __main__ module.  The value of the
        expression or code object will be returned.

        """
        return self.s_apply(self.r_eval, args)

    def s_execfile(self, *args):
        """Execute the Python code in the file in the restricted
        environment's __main__ module.

        Similar to the r_execfile() method, but the code will be granted
        access to restricted versions of the standard I/O streams sys.stdin,
        sys.stderr, and sys.stdout.

        """
        return self.s_apply(self.r_execfile, args)

    def s_import(self, *args):
        """Import a module, raising an ImportError exception if the module
        is considered unsafe.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        Similar to the r_import() method, but has access to restricted
        versions of the standard I/O streams sys.stdin, sys.stderr, and
        sys.stdout.

        """
        return self.s_apply(self.r_import, args)

    def s_reload(self, *args):
        """Reload the module object, re-parsing and re-initializing it.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        Similar to the r_reload() method, but has access to restricted
        versions of the standard I/O streams sys.stdin, sys.stderr, and
        sys.stdout.

        """
        return self.s_apply(self.r_reload, args)

    def s_unload(self, *args):
        """Unload the module.

        Removes it from the restricted environment's sys.modules dictionary.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        Similar to the r_unload() method, but has access to restricted
        versions of the standard I/O streams sys.stdin, sys.stderr, and
        sys.stdout.

        """
        return self.s_apply(self.r_unload, args)

    # Restricted open(...)

    def r_open(self, file, mode='r', buf=-1):
        """Method called when open() is called in the restricted environment.

        The arguments are identical to those of the open() function, and a
        file object (or a class instance compatible with file objects)
        should be returned.  RExec's default behaviour is allow opening
        any file for reading, but forbidding any attempt to write a file.

        This method is implicitly called by code executing in the
        restricted environment.  Overriding this method in a subclass is
        used to change the policies enforced by a restricted environment.

        """
        if mode not in ('r', 'rb'):
            raise IOError, "can't open files for writing in restricted mode"
        return open(file, mode, buf)

    # Restricted version of sys.exc_info()

    def r_exc_info(self):
        ty, va, tr = sys.exc_info()
        tr = None
        return ty, va, tr


def test():
    import getopt, traceback
    opts, args = getopt.getopt(sys.argv[1:], 'vt:')
    verbose = 0
    trusted = []
    for o, a in opts:
        if o == '-v':
            verbose = verbose+1
        if o == '-t':
            trusted.append(a)
    r = RExec(verbose=verbose)
    if trusted:
        r.ok_builtin_modules = r.ok_builtin_modules + tuple(trusted)
    if args:
        r.modules['sys'].argv = args
        r.modules['sys'].path.insert(0, os.path.dirname(args[0]))
    else:
        r.modules['sys'].path.insert(0, "")
    fp = sys.stdin
    if args and args[0] != '-':
        try:
            fp = open(args[0])
        except IOError, msg:
            print "%s: can't open file %s" % (sys.argv[0], `args[0]`)
            return 1
    if fp.isatty():
        try:
            import readline
        except ImportError:
            pass
        import code
        class RestrictedConsole(code.InteractiveConsole):
            def runcode(self, co):
                self.locals['__builtins__'] = r.modules['__builtin__']
                r.s_apply(code.InteractiveConsole.runcode, (self, co))
        try:
            RestrictedConsole(r.modules['__main__'].__dict__).interact()
        except SystemExit, n:
            return n
    else:
        text = fp.read()
        fp.close()
        c = compile(text, fp.name, 'exec')
        try:
            r.s_exec(c)
        except SystemExit, n:
            return n
        except:
            traceback.print_exc()
            return 1


if __name__ == '__main__':
    sys.exit(test())
