"""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


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 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_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


class RModuleLoader(ihooks.FancyModuleLoader):

    def load_module(self, name, stuff):
        file, filename, info = stuff
        m = ihooks.FancyModuleLoader.load_module(self, name, stuff)
        m.__filename__ = filename
        return m


class RModuleImporter(ihooks.ModuleImporter):

    def reload(self, module, path=None):
        if path is None and hasattr(module, '__filename__'):
	    head, tail = os.path.split(module.__filename__)
	    path = [os.path.join(head, '')]
        return ihooks.ModuleImporter.reload(self, module, path)


class RExec(ihooks._Verbose):

    """Restricted Execution environment."""

    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', 'rotor', 'select',
			  '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', 'reload', '__import__')

    def __init__(self, hooks = None, verbose = 0):
	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 sys.modules.has_key(name):
	    src = sys.modules[name]
	else:
	    import imp
	    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 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 = 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 = 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):
	return self.add_module(src.__name__)

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

    def add_module(self, mname):
	if self.modules.has_key(mname):
	    return self.modules[mname]
	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):
	m = self.add_module('__main__')
	exec code in m.__dict__

    def r_eval(self, code):
	m = self.add_module('__main__')
	return eval(code, m.__dict__)

    def r_execfile(self, file):
	m = self.add_module('__main__')
	return execfile(file, m.__dict__)

    def r_import(self, mname, globals={}, locals={}, fromlist=[]):
	return self.importer.import_module(mname, globals, locals, fromlist)

    def r_reload(self, m):
        return self.importer.reload(m)

    def r_unload(self, m):
        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()
    
    def s_exec(self, *args):
        self.s_apply(self.r_exec, args)
    
    def s_eval(self, *args):
        self.s_apply(self.r_eval, args)
    
    def s_execfile(self, *args):
        self.s_apply(self.r_execfile, args)
    
    def s_import(self, *args):
        self.s_apply(self.r_import, args)
    
    def s_reload(self, *args):
        self.s_apply(self.r_reload, args)
    
    def s_unload(self, *args):
        self.s_apply(self.r_unload, args)
    
    # Restricted open(...)
    
    def r_open(self, file, mode='r', buf=-1):
        if mode not in ('r', 'rb'):
            raise IOError, "can't open files for writing in restricted mode"
        return open(file, mode, buf)


def test():
    import traceback
    r = RExec(verbose=('-v' in sys.argv[1:]))
    print "*** RESTRICTED *** Python", sys.version
    print sys.copyright
    while 1:
	try:
	    try:
		s = raw_input('>>> ')
	    except EOFError:
		print
		break
	    if s and s[0] != '#':
		s = s + '\n'
		c = compile(s, '<stdin>', 'single')
		r.r_exec(c)
	except SystemExit, n:
	    sys.exit(n)
	except:
	    traceback.print_exc()


if __name__ == '__main__':
    test()
