@@ -6,22 +6,22 @@ \section{Standard Module \sectcode{rexec}}
66\code {r_exec()}, \code {r_eval()}, \code {r_execfile()}, and
77\code {r_import()} methods, which are restricted versions of the standard
88Python functions \code {exec()}, \code {eval()}, \code {execfile()}, and
9- \code {import()}. Code executed in this restricted environment will
9+ the \code {import} statement.
10+ Code executed in this restricted environment will
1011only have access to modules and functions that are deemed safe; you
1112can subclass \code {RExec} to add or remove capabilities as desired.
1213
1314\emph {Note: } The \code {RExec} class can prevent code from performing
1415unsafe operations like reading or writing disk files, or using TCP/IP
1516sockets. However, it does not protect against code using extremely
1617large amounts of memory or CPU time.
17- % XXX is there any protection against this?
1818
19- \begin {funcdesc }{RExec}{\optional {hooks\, verbose} }
19+ \begin {funcdesc }{RExec}{\optional {hooks\optional { \ , verbose}} }
2020Returns an instance of the \code {RExec} class.
2121
22- % XXX is ihooks.py documented? If yes, there should be a ref here
23-
2422\var {hooks} is an instance of the \code {RHooks} class or a subclass of it.
23+ If it is omitted or \code {None}, the default \code {RHooks} class is
24+ instantiated.
2525Whenever the RExec module searches for a module (even a built-in one)
2626or reads a module's code, it doesn't actually go out to the file
2727system itself. Rather, it calls methods of an RHooks instance that
@@ -30,20 +30,19 @@ \section{Standard Module \sectcode{rexec}}
3030object that's part of the RExec object. This allows another level of
3131flexibility, e.g. using packages.)
3232
33- By providing an alternate RHooks object, we can control the actual
33+ By providing an alternate RHooks object, we can control the
3434file system accesses made to import a module, without changing the
3535actual algorithm that controls the order in which those accesses are
3636made. For instance, we could substitute an RHooks object that passes
3737all filesystem requests to a file server elsewhere, via some RPC
3838mechanism such as ILU. Grail's applet loader uses this to support
3939importing applets from a URL for a directory.
4040
41- % XXX does verbose actually do anything at the moment?
42- If \var {verbose} is true, additional debugging output will be sent to
41+ If \var {verbose} is true, additional debugging output may be sent to
4342standard output.
4443\end {funcdesc }
4544
46- RExec instances have the following attributes, which are used by the
45+ The RExec class has the following class attributes, which are used by the
4746\code {__init__} method. Changing them on an existing instance won't
4847have any effect; instead, create a subclass of \code {RExec} and assign
4948them new values in the class definition. Instances of the new class
@@ -53,23 +52,32 @@ \section{Standard Module \sectcode{rexec}}
5352\renewcommand {\indexsubitem }{(RExec object attribute)}
5453\begin {datadesc }{nok_builtin_names}
5554Contains the names of built-in functions which will \emph {not } be
56- available to programs running in the restricted environment. The
57- value for \code {RExec} is \code {('open',} \code {reload',}
58- \code {__import__')}.
55+ available to programs running in the restricted environment. The
56+ value for \code {RExec} is \code {('open',} \code {'reload',}
57+ \code {'__import__')}. (This gives the exceptions, because by far the
58+ majority of built-in functions are harmless. A subclass that wants to
59+ override this variable should probably start with the value from the
60+ base class and concatenate additional forbidden functions --- when new
61+ dangerous built-in functions are added to Python, they will also be
62+ added to this module.)
5963\end {datadesc }
6064
6165\begin {datadesc }{ok_builtin_modules}
6266Contains the names of built-in modules which can be safely imported.
63- The value for \code {RExec} is \code {('array',} \code {'binascii',} \code {'audioop',}
64- \code {'imageop',} \code {'marshal',} \code {'math',} \code {'md5',} \code {'parser',} \code {'regex',} \code {'rotor',}
65- \code {'select',} \code {'strop',} \code {'struct',} \code {'time')}.
67+ The value for \code {RExec} is \code {('audioop',} \code {'array',}
68+ \code {'binascii',} \code {'cmath',} \code {'errno',} \code {'imageop',}
69+ \code {'marshal',} \code {'math',} \code {'md5',} \code {'operator',}
70+ \code {'parser',} \code {'regex',} \code {'rotor',} \code {'select',}
71+ \code {'strop',} \code {'struct',} \code {'time')}. A similar remark
72+ about overriding this variable applies --- use the value from the base
73+ class as a starting point.
6674\end {datadesc }
6775
6876\begin {datadesc }{ok_path}
6977Contains the directories which will be searched when an \code {import}
7078is performed in the restricted environment.
71- The value for \code {RExec} is the same as \code {sys.path} for
72- unrestricted code.
79+ The value for \code {RExec} is the same as \code {sys.path} (at the time
80+ the module is loaded) for unrestricted code.
7381\end {datadesc }
7482
7583\begin {datadesc }{ok_posix_names}
@@ -84,35 +92,38 @@ \section{Standard Module \sectcode{rexec}}
8492\end {datadesc }
8593
8694\begin {datadesc }{ok_sys_names}
87- Contains the names of the functions and variables in the \code {sys} module which will be
88- available to programs running in the restricted environment. The
89- value for \code {RExec} is \code {('ps1',} \code {'ps2 ',}
90- \code {'copyright ',} \code {'version ',} \code {'platform ',} \code {'exit ',}
91- \code {'maxint')}.
95+ Contains the names of the functions and variables in the \code {sys}
96+ module which will be available to programs running in the restricted
97+ environment. The value for \code {RExec} is \code {('ps1',}
98+ \code {'ps2 ',} \code {'copyright ',} \code {'version ',} \code {'platform ',}
99+ \code {'exit',} \code {' maxint')}.
92100\end {datadesc }
93101
94102RExec instances support the following methods:
95103\renewcommand {\indexsubitem }{(RExec object method)}
96104
97105\begin {funcdesc }{r_eval}{code}
98- \var {code} must either be a string containing a Python expression, or a compiled code object, which will
99- be evaluated in the restricted environment. The value of the expression or code object will be returned.
106+ \var {code} must either be a string containing a Python expression, or
107+ a compiled code object, which will be evaluated in the restricted
108+ environment's \code {__main__} module. The value of the expression or
109+ code object will be returned.
100110\end {funcdesc }
101111
102112\begin {funcdesc }{r_exec}{code}
103- \var {code} must either be a string containing one or more lines of Python code, or a compiled code object,
104- which will be executed in the restricted environment.
113+ \var {code} must either be a string containing one or more lines of
114+ Python code, or a compiled code object, which will be executed in the
115+ restricted environment's \code {__main__} module.
105116\end {funcdesc }
106117
107118\begin {funcdesc }{r_execfile}{filename}
108119Execute the Python code contained in the file \var {filename} in the
109- restricted environment.
120+ restricted environment's \code {__main__} module .
110121\end {funcdesc }
111122
112123Methods whose names begin with \code {s_} are similar to the functions
113124beginning with \code {r_}, but the code will be granted access to
114- restricted versions of \code {sys.stdin}, \code {sys.stderr}, and
115- \code {sys.stdout}.
125+ restricted versions of the standard I/O streans \code {sys.stdin},
126+ \code {sys.stderr}, and \code {sys. stdout}.
116127
117128\begin {funcdesc }{s_eval}{code}
118129\var {code} must be a string containing a Python expression, which will
@@ -129,13 +140,14 @@ \section{Standard Module \sectcode{rexec}}
129140restricted environment.
130141\end {funcdesc }
131142
132- \code {RExec} objects must also support various methods which will be implicitly called
133- by code executing in the restricted environment. Overriding these
134- methods in a subclass is used to change the policies enforced by a restricted environment.
143+ \code {RExec} objects must also support various methods which will be
144+ implicitly called by code executing in the restricted environment.
145+ Overriding these methods in a subclass is used to change the policies
146+ enforced by a restricted environment.
135147
136- \begin {funcdesc }{r_import}{modulename\optional {\, globals, locals, fromlist}}
137- Import the module \var {modulename}, raising an \code {ImportError} exception
138- if the module is considered unsafe.
148+ \begin {funcdesc }{r_import}{modulename\optional {\, globals\ , locals\ , fromlist}}
149+ Import the module \var {modulename}, raising an \code {ImportError}
150+ exception if the module is considered unsafe.
139151\end {funcdesc }
140152
141153\begin {funcdesc }{r_open}{filename\optional {\, mode\optional {\, bufsize}}}
@@ -144,21 +156,24 @@ \section{Standard Module \sectcode{rexec}}
144156and a file object (or a class instance compatible with file objects)
145157should be returned. \code {RExec}'s default behaviour is allow opening
146158any file for reading, but forbidding any attempt to write a file. See
147- the example below for an implementation of a less restrictive \code {r_open()}.
159+ the example below for an implementation of a less restrictive
160+ \code {r_open()}.
148161\end {funcdesc }
149162
150163\begin {funcdesc }{r_reload}{module}
151164Reload the module object \var {module}, re-parsing and re-initializing it.
152165\end {funcdesc }
153166
154167\begin {funcdesc }{r_unload}{module}
155- Unload the module object \var {module}.
156- % XXX what are the semantics of this?
168+ Unload the module object \var {module} (i.e., remove it from the
169+ restricted environment's \code {sys.modules} dictionary).
157170\end {funcdesc }
158171
172+ And their equivalents with access to restricted standard I/O streams:
173+
159174\begin {funcdesc }{s_import}{modulename\optional {\, globals, locals, fromlist}}
160- Import the module \var {modulename}, raising an \code {ImportError} exception
161- if the module is considered unsafe.
175+ Import the module \var {modulename}, raising an \code {ImportError}
176+ exception if the module is considered unsafe.
162177\end {funcdesc }
163178
164179\begin {funcdesc }{s_reload}{module}
@@ -179,13 +194,16 @@ \subsection{An example}
179194\bcode \begin {verbatim }
180195class TmpWriterRExec(rexec.RExec):
181196 def r_open(self, file, mode='r', buf=-1):
182- if mode in ('r', 'rb'): pass
183- elif mode in ('w', 'wb'):
184- # check filename : must begin with /tmp/
185- if file[0:5]!='/tmp/':
186- raise IOError, "can't open files for writing outside of /tmp"
187- elif string.find(file, '/../')!=-1:
188- raise IOError, "'..' in filename; open for writing forbidden"
197+ if mode in ('r', 'rb'):
198+ pass
199+ elif mode in ('w', 'wb', 'a', 'ab'):
200+ # check filename : must begin with /tmp/
201+ if file[:5]!='/tmp/':
202+ raise IOError, "can't write outside /tmp"
203+ elif (string.find(file, '/../') >= 0 or
204+ file[:3] == '../' or file[-3:] == '/..'):
205+ raise IOError, "'..' in filename forbidden"
206+ else: raise IOError, "Illegal open() mode"
189207 return open(file, mode, buf)
190208\end {verbatim }\ecode
191209
0 commit comments