lib

pythonsecurity.cpp

00001 /***************************************************************************
00002  * pythonsecurity.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "pythonsecurity.h"
00021 #include "pythoninterpreter.h"
00022 #include "pythonmodule.h"
00023 
00024 #include <kdebug.h>
00025 
00026 using namespace Kross::Python;
00027 
00028 PythonSecurity::PythonSecurity(PythonInterpreter* interpreter)
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 }
00051 
00052 PythonSecurity::~PythonSecurity()
00053 {
00054     delete m_pymodule;
00055 }
00056 
00057 void PythonSecurity::initRestrictedPython()
00058 {
00059     try {
00060         Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict();
00061         PyObject* pymodule = PyImport_ImportModuleEx(
00062             "RestrictedPython", // name of the module being imported (may be a dotted name)
00063             mainmoduledict.ptr(), // reference to the current global namespace
00064             mainmoduledict.ptr(), // reference to the local namespace
00065             0 // PyObject *fromlist
00066         );
00067         if(! pymodule)
00068             throw Py::Exception();
00069         m_pymodule = new Py::Module(pymodule, true);
00070 
00071         PyObject* pyrun = PyRun_String(
00072             //"import os\n"
00073             //"import sys\n"
00074             "import __main__\n"
00075             "import PythonSecurity\n"
00076             "from RestrictedPython import compile_restricted, PrintCollector\n"
00077             "from RestrictedPython.Eval import RestrictionCapableEval\n"
00078             "from RestrictedPython.RCompile import RModule\n"
00079 
00080             "setattr(__main__, '_getattr_', PythonSecurity._getattr_)\n"
00081             "setattr(__main__, '_print_', PrintCollector)\n"
00082             ,
00083             Py_file_input,
00084             m_pymodule->getDict().ptr(),
00085             m_pymodule->getDict().ptr()
00086         );
00087         if(! pyrun)
00088             throw Py::Exception();
00089 
00090         kdDebug()<<"!!!!!!!!!!!!!! PythonSecurity::PythonSecurity SUCCESS !!!!!!!!!!!!!!!!!"<<endl;
00091     }
00092     catch(Py::Exception& e) {
00093         QString err = Py::value(e).as_string().c_str();
00094         e.clear();
00095         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to initialize PythonSecurity module: %1").arg(err) ) );
00096     }
00097 }
00098 
00099 Py::Object PythonSecurity::_getattr_(const Py::Tuple& args)
00100 {
00101     kdDebug() << "PythonSecurity::_getattr_" << endl;
00102     for(uint i = 0; i < args.size(); i++) {
00103         Py::Object o = args[i];
00104         kdDebug()<<o.as_string().c_str()<<endl;
00105     }
00106     return Py::None();
00107 }
00108 
00109 PyObject* PythonSecurity::compile_restricted(const QString& source, const QString& filename, const QString& mode)
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 }
00169 
00170 #if 0
00171 void PythonSecurity::compile_restricted_function(const Py::Tuple& /*args*/, const QString& /*body*/, const QString& /*name*/, const QString& /*filename*/, const Py::Object& /*globalize*/)
00172 {
00173     //TODO
00174 }
00175 
00176 void PythonSecurity::compile_restricted_exec(const QString& /*source*/, const QString& /*filename*/)
00177 {
00178     //TODO
00179 }
00180 
00181 void PythonSecurity::compile_restricted_eval(const QString& /*source*/, const QString& /*filename*/)
00182 {
00183     //TODO
00184 }
00185 #endif
00186 
KDE Home | KDE Accessibility Home | Description of Access Keys