lib

pythonsecurity.cpp
1/***************************************************************************
2 * pythonsecurity.cpp
3 * This file is part of the KDE project
4 * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 ***************************************************************************/
19
20#include "pythonsecurity.h"
21#include "pythoninterpreter.h"
22#include "pythonmodule.h"
23
24using namespace Kross::Python;
25
27 : Py::ExtensionModule<PythonSecurity>("PythonSecurity")
28 , m_interpreter(interpreter)
29 , m_pymodule(0)
30{
31 add_varargs_method("_getattr_", &PythonSecurity::_getattr_, "Secure wapper around the getattr method.");
32 initialize("The PythonSecurity module used to wrap the RestrictedPython functionality.");
33
34 /* TESTCASE
35 initRestrictedPython();
36 compile_restricted(
37 "a = 2 + 5\n"
38 "import os\n"
39 "import sys\n"
40 "b = sys.path\n"
41 "print \"######### >>>testcase<<< #########\" \n"
42 ,
43 "mytestcase", // filename
44 "exec" // 'exec' or 'eval' or 'single'
45 );
46 */
47
48}
49
51{
52 delete m_pymodule;
53}
54
55void PythonSecurity::initRestrictedPython()
56{
57 try {
58 Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict();
59 PyObject* pymodule = PyImport_ImportModuleEx(
60 "RestrictedPython", // name of the module being imported (may be a dotted name)
61 mainmoduledict.ptr(), // reference to the current global namespace
62 mainmoduledict.ptr(), // reference to the local namespace
63 0 // PyObject *fromlist
64 );
65 if(! pymodule)
66 throw Py::Exception();
67 m_pymodule = new Py::Module(pymodule, true);
68
69 PyObject* pyrun = PyRun_String(
70 //"import os\n"
71 //"import sys\n"
72 "import __main__\n"
73 "import PythonSecurity\n"
74 "from RestrictedPython import compile_restricted, PrintCollector\n"
75 "from RestrictedPython.Eval import RestrictionCapableEval\n"
76 "from RestrictedPython.RCompile import RModule\n"
77
78 "setattr(__main__, '_getattr_', PythonSecurity._getattr_)\n"
79 "setattr(__main__, '_print_', PrintCollector)\n"
80 ,
81 Py_file_input,
82 m_pymodule->getDict().ptr(),
83 m_pymodule->getDict().ptr()
84 );
85 if(! pyrun)
86 throw Py::Exception();
87
88 krossdebug("PythonSecurity::PythonSecurity SUCCESSFULLY LOADED");
89 }
90 catch(Py::Exception& e) {
91 TQString err = Py::value(e).as_string().c_str();
92 e.clear();
93 throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(TQString("Failed to initialize PythonSecurity module: %1").arg(err) ) );
94 }
95}
96
97Py::Object PythonSecurity::_getattr_(const Py::Tuple& args)
98{
99 krossdebug("PythonSecurity::_getattr_");
100 for(uint i = 0; i < args.size(); i++) {
101 Py::Object o = args[i];
102 krossdebug( o.as_string().c_str() );
103 }
104 return Py::None();
105}
106
107PyObject* PythonSecurity::compile_restricted(const TQString& source, const TQString& filename, const TQString& mode)
108{
109 krossdebug("PythonSecurity::compile_restricted");
110 if(! m_pymodule)
111 initRestrictedPython(); // throws exception if failed
112
113 try {
114 Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict();
115
116 PyObject* func = PyDict_GetItemString(m_pymodule->getDict().ptr(), "compile_restricted");
117 if(! func)
118 throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(TQString("No such function '%1'.").arg("compile_restricted")) );
119
120 Py::Callable funcobject(func, true); // the funcobject takes care of freeing our func pyobject.
121
122 if(! funcobject.isCallable())
123 throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(TQString("Function '%1' is not callable.").arg("compile_restricted")) );
124
125 Py::Tuple args(3);
126 args[0] = Py::String(source.utf8());
127 args[1] = Py::String(filename.utf8());
128 args[2] = Py::String(mode.utf8());
129
130 Py::Object result = funcobject.apply(args);
131
132 PyObject* pycode = PyEval_EvalCode(
133 (PyCodeObject*)result.ptr(),
134 mainmoduledict.ptr(),
135 mainmoduledict.ptr()
136 );
137 if(! pycode)
138 throw Py::Exception();
139
140 /*
141 Py::List ml = mainmoduledict;
142 for(Py::List::size_type mi = 0; mi < ml.length(); ++mi) {
143 krossdebug( TQString("dir() = %1").arg( ml[mi].str().as_string().c_str() ) );
144 //krossdebug( TQString("dir().dir() = %1").arg( Py::Object(ml[mi]).dir().as_string().c_str() ) );
145 }
146 */
147
148 Py::Object code(pycode);
149 krossdebug( TQString("%1 callable=%2").arg(code.as_string().c_str()).arg(PyCallable_Check(code.ptr())) );
150 Py::List l = code.dir();
151 for(Py::List::size_type i = 0; i < l.length(); ++i) {
152 krossdebug( TQString("dir() = %1").arg( l[i].str().as_string().c_str() ) );
153 //krossdebug( TQString("dir().dir() = %1").arg( Py::Object(l[i]).dir().as_string().c_str() ) );
154 }
155
156 return pycode;
157 }
158 catch(Py::Exception& e) {
159 TQString err = Py::value(e).as_string().c_str();
160 e.clear();
161 throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(TQString("Function '%1' failed with python exception: %2").arg("compile_restricted").arg(err) ) );
162 }
163}
164
165#if 0
166void PythonSecurity::compile_restricted_function(const Py::Tuple& /*args*/, const TQString& /*body*/, const TQString& /*name*/, const TQString& /*filename*/, const Py::Object& /*globalize*/)
167{
168 //TODO
169}
170
171void PythonSecurity::compile_restricted_exec(const TQString& /*source*/, const TQString& /*filename*/)
172{
173 //TODO
174}
175
176void PythonSecurity::compile_restricted_eval(const TQString& /*source*/, const TQString& /*filename*/)
177{
178 //TODO
179}
180#endif
181
Common exception class used for representing exceptions in Kross.
Definition exception.h:39
TDESharedPtr< Exception > Ptr
Shared pointer to implement reference-counting.
Definition exception.h:45
Python interpreter bridge.
PyObject * compile_restricted(const TQString &source, const TQString &filename, const TQString &mode)
Compile python scripting code and return a restricted code object.
virtual ~PythonSecurity()
Destructor.
PythonSecurity(PythonInterpreter *interpreter)
Constructor.
The Python plugin for the Kross scripting framework.
KOFFICE_EXPORT void krossdebug(const TQString &s)
Debugging function.