--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Doc/library/rexec.rst Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,290 @@
+
+:mod:`rexec` --- Restricted execution framework
+===============================================
+
+.. module:: rexec
+ :synopsis: Basic restricted execution framework.
+ :deprecated:
+
+.. deprecated:: 2.6
+ The :mod:`rexec` module has been removed in Python 3.0.
+
+.. versionchanged:: 2.3
+ Disabled module.
+
+.. warning::
+
+ The documentation has been left in place to help in reading old code that uses
+ the module.
+
+This module contains the :class:`RExec` class, which supports :meth:`r_eval`,
+:meth:`r_execfile`, :meth:`r_exec`, and :meth:`r_import` methods, which are
+restricted versions of the standard Python functions :meth:`eval`,
+:meth:`execfile` and the :keyword:`exec` and :keyword:`import` statements. Code
+executed in this restricted environment will only have access to modules and
+functions that are deemed safe; you can subclass :class:`RExec` to add or remove
+capabilities as desired.
+
+.. warning::
+
+ While the :mod:`rexec` module is designed to perform as described below, it does
+ have a few known vulnerabilities which could be exploited by carefully written
+ code. Thus it should not be relied upon in situations requiring "production
+ ready" security. In such situations, execution via sub-processes or very
+ careful "cleansing" of both code and data to be processed may be necessary.
+ Alternatively, help in patching known :mod:`rexec` vulnerabilities would be
+ welcomed.
+
+.. note::
+
+ The :class:`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.
+
+
+.. class:: RExec([hooks[, verbose]])
+
+ Returns an instance of the :class:`RExec` class.
+
+ *hooks* is an instance of the :class:`RHooks` class or a subclass of it. If it
+ is omitted or ``None``, the default :class:`RHooks` class is instantiated.
+ Whenever the :mod:`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 :class:`RHooks` instance that was passed to or
+ created by its constructor. (Actually, the :class:`RExec` object doesn't make
+ these calls --- they are made by a module loader object that's part of the
+ :class:`RExec` object. This allows another level of flexibility, which can be
+ useful when changing the mechanics of :keyword:`import` within the restricted
+ environment.)
+
+ By providing an alternate :class:`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 :class:`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 *verbose* is true, additional debugging output may be sent to standard
+ output.
+
+It is important to be aware that code running in a restricted environment can
+still call the :func:`sys.exit` function. To disallow restricted code from
+exiting the interpreter, always protect calls that cause restricted code to run
+with a :keyword:`try`/:keyword:`except` statement that catches the
+:exc:`SystemExit` exception. Removing the :func:`sys.exit` function from the
+restricted environment is not sufficient --- the restricted code could still use
+``raise SystemExit``. Removing :exc:`SystemExit` is not a reasonable option;
+some library code makes use of this and would break were it not available.
+
+
+.. seealso::
+
+ `Grail Home Page <http://grail.sourceforge.net/>`_
+ Grail is a Web browser written entirely in Python. It uses the :mod:`rexec`
+ module as a foundation for supporting Python applets, and can be used as an
+ example usage of this module.
+
+
+.. _rexec-objects:
+
+RExec Objects
+-------------
+
+:class:`RExec` instances support the following methods:
+
+
+.. method:: RExec.r_eval(code)
+
+ *code* must either be a string containing a Python expression, or a compiled
+ code object, which will be evaluated in the restricted environment's
+ :mod:`__main__` module. The value of the expression or code object will be
+ returned.
+
+
+.. method:: RExec.r_exec(code)
+
+ *code* 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
+ :mod:`__main__` module.
+
+
+.. method:: RExec.r_execfile(filename)
+
+ Execute the Python code contained in the file *filename* in the restricted
+ environment's :mod:`__main__` module.
+
+Methods whose names begin with ``s_`` are similar to the functions beginning
+with ``r_``, but the code will be granted access to restricted versions of the
+standard I/O streams ``sys.stdin``, ``sys.stderr``, and ``sys.stdout``.
+
+
+.. method:: RExec.s_eval(code)
+
+ *code* must be a string containing a Python expression, which will be evaluated
+ in the restricted environment.
+
+
+.. method:: RExec.s_exec(code)
+
+ *code* must be a string containing one or more lines of Python code, which will
+ be executed in the restricted environment.
+
+
+.. method:: RExec.s_execfile(code)
+
+ Execute the Python code contained in the file *filename* in the restricted
+ environment.
+
+:class:`RExec` objects must also support various methods which will be
+implicitly called by code executing in the restricted environment. Overriding
+these methods in a subclass is used to change the policies enforced by a
+restricted environment.
+
+
+.. method:: RExec.r_import(modulename[, globals[, locals[, fromlist]]])
+
+ Import the module *modulename*, raising an :exc:`ImportError` exception if the
+ module is considered unsafe.
+
+
+.. method:: RExec.r_open(filename[, mode[, bufsize]])
+
+ Method called when :func:`open` is called in the restricted environment. The
+ arguments are identical to those of :func:`open`, and a file object (or a class
+ instance compatible with file objects) should be returned. :class:`RExec`'s
+ default behaviour is allow opening any file for reading, but forbidding any
+ attempt to write a file. See the example below for an implementation of a less
+ restrictive :meth:`r_open`.
+
+
+.. method:: RExec.r_reload(module)
+
+ Reload the module object *module*, re-parsing and re-initializing it.
+
+
+.. method:: RExec.r_unload(module)
+
+ Unload the module object *module* (remove it from the restricted environment's
+ ``sys.modules`` dictionary).
+
+And their equivalents with access to restricted standard I/O streams:
+
+
+.. method:: RExec.s_import(modulename[, globals[, locals[, fromlist]]])
+
+ Import the module *modulename*, raising an :exc:`ImportError` exception if the
+ module is considered unsafe.
+
+
+.. method:: RExec.s_reload(module)
+
+ Reload the module object *module*, re-parsing and re-initializing it.
+
+
+.. method:: RExec.s_unload(module)
+
+ Unload the module object *module*.
+
+ .. XXX what are the semantics of this?
+
+
+.. _rexec-extension:
+
+Defining restricted environments
+--------------------------------
+
+The :class:`RExec` class has the following class attributes, which are used by
+the :meth:`__init__` method. Changing them on an existing instance won't have
+any effect; instead, create a subclass of :class:`RExec` and assign them new
+values in the class definition. Instances of the new class will then use those
+new values. All these attributes are tuples of strings.
+
+
+.. attribute:: RExec.nok_builtin_names
+
+ Contains the names of built-in functions which will *not* be available to
+ programs running in the restricted environment. The value for :class:`RExec` is
+ ``('open', 'reload', '__import__')``. (This gives the exceptions, because by far
+ the majority of built-in functions are harmless. A subclass that wants to
+ override this variable should probably start with the value from the base class
+ and concatenate additional forbidden functions --- when new dangerous built-in
+ functions are added to Python, they will also be added to this module.)
+
+
+.. attribute:: RExec.ok_builtin_modules
+
+ Contains the names of built-in modules which can be safely imported. The value
+ for :class:`RExec` is ``('audioop', 'array', 'binascii', 'cmath', 'errno',
+ 'imageop', 'marshal', 'math', 'md5', 'operator', 'parser', 'regex', 'select',
+ 'sha', '_sre', 'strop', 'struct', 'time')``. A similar remark about overriding
+ this variable applies --- use the value from the base class as a starting point.
+
+
+.. attribute:: RExec.ok_path
+
+ Contains the directories which will be searched when an :keyword:`import` is
+ performed in the restricted environment. The value for :class:`RExec` is the
+ same as ``sys.path`` (at the time the module is loaded) for unrestricted code.
+
+
+.. attribute:: RExec.ok_posix_names
+
+ Contains the names of the functions in the :mod:`os` module which will be
+ available to programs running in the restricted environment. The value for
+ :class:`RExec` is ``('error', 'fstat', 'listdir', 'lstat', 'readlink', 'stat',
+ 'times', 'uname', 'getpid', 'getppid', 'getcwd', 'getuid', 'getgid', 'geteuid',
+ 'getegid')``.
+
+ .. Should this be called ok_os_names?
+
+
+.. attribute:: RExec.ok_sys_names
+
+ Contains the names of the functions and variables in the :mod:`sys` module which
+ will be available to programs running in the restricted environment. The value
+ for :class:`RExec` is ``('ps1', 'ps2', 'copyright', 'version', 'platform',
+ 'exit', 'maxint')``.
+
+
+.. attribute:: RExec.ok_file_types
+
+ Contains the file types from which modules are allowed to be loaded. Each file
+ type is an integer constant defined in the :mod:`imp` module. The meaningful
+ values are :const:`PY_SOURCE`, :const:`PY_COMPILED`, and :const:`C_EXTENSION`.
+ The value for :class:`RExec` is ``(C_EXTENSION, PY_SOURCE)``. Adding
+ :const:`PY_COMPILED` in subclasses is not recommended; an attacker could exit
+ the restricted execution mode by putting a forged byte-compiled file
+ (:file:`.pyc`) anywhere in your file system, for example by writing it to
+ :file:`/tmp` or uploading it to the :file:`/incoming` directory of your public
+ FTP server.
+
+
+An example
+----------
+
+Let us say that we want a slightly more relaxed policy than the standard
+:class:`RExec` class. For example, if we're willing to allow files in
+:file:`/tmp` to be written, we can subclass the :class:`RExec` class::
+
+ class TmpWriterRExec(rexec.RExec):
+ def r_open(self, file, mode='r', buf=-1):
+ if mode in ('r', 'rb'):
+ pass
+ elif mode in ('w', 'wb', 'a', 'ab'):
+ # check filename : must begin with /tmp/
+ if file[:5]!='/tmp/':
+ raise IOError, "can't write outside /tmp"
+ elif (string.find(file, '/../') >= 0 or
+ file[:3] == '../' or file[-3:] == '/..'):
+ raise IOError, "'..' in filename forbidden"
+ else: raise IOError, "Illegal open() mode"
+ return open(file, mode, buf)
+
+Notice that the above code will occasionally forbid a perfectly valid filename;
+for example, code in the restricted environment won't be able to open a file
+called :file:`/tmp/foo/../bar`. To fix this, the :meth:`r_open` method would
+have to simplify the filename to :file:`/tmp/bar`, which would require splitting
+apart the filename and performing various operations on it. In cases where
+security is at stake, it may be preferable to write simple code which is
+sometimes overly restrictive, instead of more general code that is also more
+complex and may harbor a subtle security hole.