| 
									
										
										
										
											1998-08-10 19:42:37 +00:00
										 |  |  | \section{\module{rexec} --- | 
					
						
							| 
									
										
										
										
											1999-04-22 21:23:22 +00:00
										 |  |  |          Restricted execution framework} | 
					
						
							| 
									
										
										
										
											1998-07-23 17:59:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-04-22 21:23:22 +00:00
										 |  |  | \declaremodule{standard}{rexec} | 
					
						
							| 
									
										
										
										
											1998-07-23 17:59:49 +00:00
										 |  |  | \modulesynopsis{Basic restricted execution framework.} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-09-10 17:37:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | This module contains the \class{RExec} class, which supports | 
					
						
							| 
									
										
										
										
											1998-05-08 13:27:38 +00:00
										 |  |  | \method{r_eval()}, \method{r_execfile()}, \method{r_exec()}, and | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \method{r_import()} methods, which are restricted versions of the standard | 
					
						
							| 
									
										
										
										
											1998-05-08 13:27:38 +00:00
										 |  |  | Python functions \method{eval()}, \method{execfile()} and | 
					
						
							|  |  |  | the \keyword{exec} and \keyword{import} statements. | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | Code executed in this restricted environment will | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | only have access to modules and functions that are deemed safe; you | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | can subclass \class{RExec} to add or remove capabilities as desired. | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-20 04:24:09 +00:00
										 |  |  | \note{The \class{RExec} class can prevent code from performing | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | unsafe operations like reading or writing disk files, or using TCP/IP | 
					
						
							|  |  |  | sockets.  However, it does not protect against code using extremely | 
					
						
							| 
									
										
										
										
											2001-10-20 04:24:09 +00:00
										 |  |  | large amounts of memory or processor time.} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}} | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | Returns an instance of the \class{RExec} class.   | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \var{hooks} is an instance of the \class{RHooks} class or a subclass of it. | 
					
						
							|  |  |  | If it is omitted or \code{None}, the default \class{RHooks} class is | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | instantiated. | 
					
						
							| 
									
										
										
										
											1999-04-22 21:23:22 +00:00
										 |  |  | Whenever the \module{rexec} module searches for a module (even a | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2001-07-06 20:30:11 +00:00
										 |  |  | allows another level of flexibility, which can be useful when changing | 
					
						
							|  |  |  | the mechanics of \keyword{import} within the restricted environment.) | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | By providing an alternate \class{RHooks} object, we can control the | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | file system accesses made to import a module, without changing the | 
					
						
							|  |  |  | actual algorithm that controls the order in which those accesses are | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | importing applets from a URL for a directory. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | If \var{verbose} is true, additional debugging output may be sent to | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | standard output. | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \end{classdesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-22 18:21:53 +00:00
										 |  |  | It is important to be aware that code running in a restricted | 
					
						
							|  |  |  | environment can still call the \function{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 | 
					
						
							|  |  |  | \exception{SystemExit} exception.  Removing the \function{sys.exit()} | 
					
						
							|  |  |  | function from the restricted environment is not sufficient --- the | 
					
						
							|  |  |  | restricted code could still use \code{raise SystemExit}.  Removing | 
					
						
							|  |  |  | \exception{SystemExit} is not a reasonable option; some library code | 
					
						
							|  |  |  | makes use of this and would break were it not available. | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-22 18:21:53 +00:00
										 |  |  | \begin{seealso} | 
					
						
							|  |  |  |   \seetitle[http://grail.sourceforge.net/]{Grail Home Page}{Grail is a | 
					
						
							|  |  |  |             Web browser written entirely in Python.  It uses the | 
					
						
							|  |  |  |             \module{rexec} module as a foundation for supporting | 
					
						
							|  |  |  |             Python applets, and can be used as an example usage of | 
					
						
							|  |  |  |             this module.} | 
					
						
							|  |  |  | \end{seealso} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-22 18:21:53 +00:00
										 |  |  | \subsection{RExec Objects \label{rexec-objects}} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | \class{RExec} instances support the following methods: | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_eval}{code} | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | \var{code} must either be a string containing a Python expression, or | 
					
						
							|  |  |  | a compiled code object, which will be evaluated in the restricted | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | environment's \module{__main__} module.  The value of the expression or | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | code object will be returned. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_exec}{code} | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | \var{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 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | restricted environment's \module{__main__} module. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_execfile}{filename} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | Execute the Python code contained in the file \var{filename} in the | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | restricted environment's \module{__main__} module. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | Methods whose names begin with \samp{s_} are similar to the functions | 
					
						
							|  |  |  | beginning with \samp{r_}, but the code will be granted access to | 
					
						
							| 
									
										
										
										
											1998-02-23 14:37:40 +00:00
										 |  |  | restricted versions of the standard I/O streams \code{sys.stdin}, | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \code{sys.stderr}, and \code{sys.stdout}. | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_eval}{code} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | \var{code} must be a string containing a Python expression, which will | 
					
						
							|  |  |  | be evaluated in the restricted environment.   | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_exec}{code} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | \var{code} must be a string containing one or more lines of Python code, | 
					
						
							|  |  |  | which will be executed in the restricted environment.   | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_execfile}{code} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | Execute the Python code contained in the file \var{filename} in the | 
					
						
							|  |  |  | restricted environment. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | \class{RExec} objects must also support various methods which will be | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_import}{modulename\optional{, globals\optional{, | 
					
						
							|  |  |  |                              locals\optional{, fromlist}}}} | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | Import the module \var{modulename}, raising an \exception{ImportError} | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | exception if the module is considered unsafe. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_open}{filename\optional{, mode\optional{, bufsize}}} | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | Method called when \function{open()} is called in the restricted | 
					
						
							|  |  |  | environment.  The arguments are identical to those of \function{open()}, | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | and a file object (or a class instance compatible with file objects) | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | should be returned.  \class{RExec}'s default behaviour is allow opening | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | any file for reading, but forbidding any attempt to write a file.  See | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | the example below for an implementation of a less restrictive | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \method{r_open()}. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_reload}{module} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | Reload the module object \var{module}, re-parsing and re-initializing it.   | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{r_unload}{module} | 
					
						
							| 
									
										
										
										
											2001-07-06 20:30:11 +00:00
										 |  |  | Unload the module object \var{module} (remove it from the | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | restricted environment's \code{sys.modules} dictionary). | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | And their equivalents with access to restricted standard I/O streams: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_import}{modulename\optional{, globals\optional{, | 
					
						
							|  |  |  |                              locals\optional{, fromlist}}}} | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | Import the module \var{modulename}, raising an \exception{ImportError} | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  | exception if the module is considered unsafe. | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_reload}{module} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | Reload the module object \var{module}, re-parsing and re-initializing it.   | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \begin{methoddesc}{s_unload}{module} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | Unload the module object \var{module}.    | 
					
						
							|  |  |  | % XXX what are the semantics of this?  
 | 
					
						
							| 
									
										
										
										
											1998-04-02 18:51:30 +00:00
										 |  |  | \end{methoddesc} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-22 18:21:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | \subsection{Defining restricted environments \label{rexec-extension}} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The \class{RExec} class has the following class attributes, which are | 
					
						
							|  |  |  | used by the \method{__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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{memberdesc}{nok_builtin_names} | 
					
						
							|  |  |  | Contains the names of built-in functions which will \emph{not} be | 
					
						
							|  |  |  | available to programs running in the restricted environment.  The | 
					
						
							|  |  |  | value for \class{RExec} is \code{('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.) | 
					
						
							|  |  |  | \end{memberdesc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{memberdesc}{ok_builtin_modules} | 
					
						
							|  |  |  | Contains the names of built-in modules which can be safely imported. | 
					
						
							|  |  |  | The value for \class{RExec} is \code{('audioop', 'array', 'binascii', | 
					
						
							|  |  |  | 'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator', | 
					
						
							|  |  |  | 'parser', 'regex', 'rotor', '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. | 
					
						
							|  |  |  | \end{memberdesc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{memberdesc}{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 \code{sys.path} (at the time | 
					
						
							|  |  |  | the module is loaded) for unrestricted code. | 
					
						
							|  |  |  | \end{memberdesc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{memberdesc}{ok_posix_names} | 
					
						
							|  |  |  | % Should this be called ok_os_names?
 | 
					
						
							|  |  |  | Contains the names of the functions in the \refmodule{os} module which will be | 
					
						
							|  |  |  | available to programs running in the restricted environment.  The | 
					
						
							|  |  |  | value for \class{RExec} is \code{('error', 'fstat', 'listdir', | 
					
						
							|  |  |  | 'lstat', 'readlink', 'stat', 'times', 'uname', 'getpid', 'getppid', | 
					
						
							|  |  |  | 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')}. | 
					
						
							|  |  |  | \end{memberdesc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{memberdesc}{ok_sys_names} | 
					
						
							|  |  |  | Contains the names of the functions and variables in the \refmodule{sys} | 
					
						
							|  |  |  | module which will be available to programs running in the restricted | 
					
						
							|  |  |  | environment.  The value for \class{RExec} is \code{('ps1', 'ps2', | 
					
						
							|  |  |  | 'copyright', 'version', 'platform', 'exit', 'maxint')}. | 
					
						
							|  |  |  | \end{memberdesc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | \subsection{An example} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Let us say that we want a slightly more relaxed policy than the | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | 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: | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | \begin{verbatim} | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | class TmpWriterRExec(rexec.RExec): | 
					
						
							|  |  |  |     def r_open(self, file, mode='r', buf=-1): | 
					
						
							| 
									
										
										
										
											1996-10-24 22:14:06 +00:00
										 |  |  |         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" | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  |         return open(file, mode, buf) | 
					
						
							| 
									
										
										
										
											1998-02-13 06:58:54 +00:00
										 |  |  | \end{verbatim} | 
					
						
							| 
									
										
										
										
											1997-07-17 16:34:52 +00:00
										 |  |  | %
 | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											1998-03-14 07:08:02 +00:00
										 |  |  | \method{r_open()} method would have to simplify the filename to | 
					
						
							| 
									
										
										
										
											1996-10-22 01:11:19 +00:00
										 |  |  | \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. |