symbian-qemu-0.9.1-12/python-2.6.1/Doc/library/rexec.rst
changeset 1 2fb8b9db1c86
--- /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.