Kross::Python::PythonSecurity Class Reference

#include <pythonsecurity.h>

Inheritance diagram for Kross::Python::PythonSecurity:

Inheritance graph
[legend]
Collaboration diagram for Kross::Python::PythonSecurity:

Collaboration graph
[legend]
List of all members.

Detailed Description

This class handles the used Zope3 RestrictedPython package to spend a restricted sandbox for scripting code.

The RestrictedPython code is avaible as Python files. So, this class takes care of loading them and spending the functions we need to access the functionality from within Kross. That way it's easy to update the module with a newer version if some security issues show up.

What the RestrictedPython code does is to compile the plain python code (py) into compiled python code (pyc) and manipulate those compiled code by replacing unsafe code with own wrapped code. As example a simple "x = y.z" would be transfered to "x = _getattr_(y, 'z')". The _getattr_ is defined in the RestrictedPython module and will take care of applied restrictions.

See also:
http://www.zope.org

http://svn.zope.org/Zope3/trunk/src/RestrictedPython/

Definition at line 56 of file pythonsecurity.h.

Public Member Functions

 PythonSecurity (PythonInterpreter *interpreter)
virtual ~PythonSecurity ()
PyObject * compile_restricted (const QString &source, const QString &filename, const QString &mode)


Constructor & Destructor Documentation

PythonSecurity::PythonSecurity PythonInterpreter interpreter  )  [explicit]
 

Constructor.

Parameters:
interpreter The PythonInterpreter instance used to create this Module.

Definition at line 28 of file pythonsecurity.cpp.

00029     : Py::ExtensionModule<PythonSecurity>("PythonSecurity")
00030     , m_interpreter(interpreter)
00031     , m_pymodule(0)
00032 {
00033     add_varargs_method("_getattr_", &PythonSecurity::_getattr_, "Secure wapper around the getattr method.");
00034     initialize("The PythonSecurity module used to wrap the RestrictedPython functionality.");
00035 
00036     /* TESTCASE
00037     initRestrictedPython();
00038     compile_restricted(
00039         "a = 2 + 5\n"
00040         "import os\n"
00041         "import sys\n"
00042         "b = sys.path\n"
00043         "print \"######### >>>testcase<<< #########\" \n"
00044         ,
00045         "mytestcase", // filename
00046         "exec" // 'exec' or 'eval' or 'single'
00047     );
00048     */
00049 
00050 }

PythonSecurity::~PythonSecurity  )  [virtual]
 

Destructor.

Definition at line 52 of file pythonsecurity.cpp.

00053 {
00054     delete m_pymodule;
00055 }


Member Function Documentation

PyObject * PythonSecurity::compile_restricted const QString source,
const QString filename,
const QString mode
 

Compile python scripting code and return a restricted code object.

Parameters:
source The python scripting code.
filename The filename used on errormessages.
mode Compilemode, could be 'exec' or 'eval' or 'single'.
Returns:
The compiled python code object on success else NULL. The caller owns the resulting object and needs to take care to decrease the ref-counter it not needed any longer.

Definition at line 109 of file pythonsecurity.cpp.

References QString::utf8().

00110 {
00111     kdDebug()<<"PythonSecurity::compile_restricted"<<endl;
00112     if(! m_pymodule)
00113         initRestrictedPython(); // throws exception if failed
00114 
00115     try {
00116         Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict();
00117 
00118         PyObject* func = PyDict_GetItemString(m_pymodule->getDict().ptr(), "compile_restricted");
00119         if(! func)
00120             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such function '%1'.").arg("compile_restricted")) );
00121 
00122         Py::Callable funcobject(func, true); // the funcobject takes care of freeing our func pyobject.
00123 
00124         if(! funcobject.isCallable())
00125             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Function '%1' is not callable.").arg("compile_restricted")) );
00126 
00127         Py::Tuple args(3);
00128         args[0] = Py::String(source.utf8());
00129         args[1] = Py::String(filename.utf8());
00130         args[2] = Py::String(mode.utf8());
00131 
00132         Py::Object result = funcobject.apply(args);
00133 
00134         PyObject* pycode = PyEval_EvalCode(
00135             (PyCodeObject*)result.ptr(),
00136             mainmoduledict.ptr(),
00137             mainmoduledict.ptr()
00138         );
00139         if(! pycode)
00140             throw Py::Exception();
00141 
00142         /*
00143         kdDebug()<<"$---------------------------------------------------"<<endl;
00144         Py::List ml = mainmoduledict;
00145         for(Py::List::size_type mi = 0; mi < ml.length(); ++mi) {
00146             kdDebug() << QString("-------------------") << endl;
00147             kdDebug() << QString("dir() = %1").arg( ml[mi].str().as_string().c_str() ) << endl;
00148             //kdDebug() << QString("dir().dir() = %1").arg( Py::Object(ml[mi]).dir().as_string().c_str() ) << endl;
00149         }
00150         kdDebug()<<"$---------------------------------------------------"<<endl;
00151         */
00152 
00153         Py::Object code(pycode);
00154         kdDebug()<< code.as_string().c_str() << " callable=" << PyCallable_Check(code.ptr()) << endl;
00155         Py::List l = code.dir();
00156         for(Py::List::size_type i = 0; i < l.length(); ++i) {
00157             kdDebug() << QString("dir() = %1").arg( l[i].str().as_string().c_str() ) << endl;
00158             //kdDebug() << QString("dir().dir() = %1").arg( Py::Object(l[i]).dir().as_string().c_str() ) << endl;
00159         }
00160 
00161         return pycode;
00162     }
00163     catch(Py::Exception& e) { 
00164         QString err = Py::value(e).as_string().c_str();
00165         e.clear();
00166         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Function '%1' failed with python exception: %2").arg("compile_restricted").arg(err) ) );
00167     }
00168 }


The documentation for this class was generated from the following files:
Generated on Thu Feb 9 18:01:41 2006 for Kross by  doxygen 1.4.6