From f46393efe79ec3b0153e5b72c9545fc7c90696ec Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 13 Dec 2015 14:24:15 +0100 Subject: [PATCH] Report 'None' for successfully executed commands in server, implement a simple firewall to block commands --- src/Mod/Web/App/AppWebPy.cpp | 15 +++++++++ src/Mod/Web/App/Server.cpp | 64 ++++++++++++++++++++++++++++++++++-- src/Mod/Web/App/Server.h | 27 +++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/Mod/Web/App/AppWebPy.cpp b/src/Mod/Web/App/AppWebPy.cpp index 5587e1aef..7e64b53eb 100644 --- a/src/Mod/Web/App/AppWebPy.cpp +++ b/src/Mod/Web/App/AppWebPy.cpp @@ -102,9 +102,24 @@ static PyObject * startServer(PyObject *self, PyObject *args) Py_Return; } +static PyObject * registerServerFirewall(PyObject *self, PyObject *args) +{ + PyObject* obj; + if (!PyArg_ParseTuple(args, "O",&obj)) + return NULL; + + PY_TRY { + Web::Firewall::setInstance(new Web::FirewallPython(Py::Object(obj))); + } PY_CATCH; + + Py_Return; +} + /* registration table */ struct PyMethodDef Web_methods[] = { {"startServer",startServer ,METH_VARARGS, "startServer(address=127.0.0.1,port=0) -- Start a server."}, + {"registerServerFirewall",registerServerFirewall ,METH_VARARGS, + "registerServerFirewall(callable(string)) -- Register a firewall."}, {NULL, NULL} /* end of table marker */ }; diff --git a/src/Mod/Web/App/Server.cpp b/src/Mod/Web/App/Server.cpp index 02f8c2698..2230a8d3f 100644 --- a/src/Mod/Web/App/Server.cpp +++ b/src/Mod/Web/App/Server.cpp @@ -25,7 +25,7 @@ #include #include -# include +#include #include "Server.h" #include @@ -33,6 +33,60 @@ using namespace Web; +Firewall* Firewall::instance = 0; + +Firewall* Firewall::getInstance() +{ + return instance; +} + +void Firewall::setInstance(Firewall* inst) +{ + if (inst != instance) { + delete instance; + instance = inst; + } +} + +Firewall::Firewall() +{ +} + +Firewall::~Firewall() +{ +} + +bool Firewall::filter(const QByteArray& cmd) const +{ + return true; +} + +FirewallPython::FirewallPython(const Py::Object& o) + : obj(o) +{ +} + +FirewallPython::~FirewallPython() +{ +} + +bool FirewallPython::filter(const QByteArray& msg) const +{ + Base::PyGILStateLocker lock; + try { + Py::Callable call(obj); + Py::Tuple args(1); + args.setItem(0, Py::String(msg.constData())); + Py::Boolean ok(call.apply(args)); + return static_cast(ok); + } + catch (const Py::Exception&) { + Base::PyException e; + throw Base::RuntimeError(e.what()); + } +} + +// ---------------------------------------------------------------------------- ServerEvent::ServerEvent(QTcpSocket* sock, const QByteArray& msg) : QEvent(QEvent::User), sock(sock), text(msg) @@ -53,6 +107,8 @@ const QByteArray& ServerEvent::request() const return text; } +// ---------------------------------------------------------------------------- + AppServer::AppServer(QObject* parent) : QTcpServer(parent) { @@ -94,7 +150,11 @@ void AppServer::customEvent(QEvent* e) std::string str; try { - Base::Interpreter().runString(msg); + Firewall* fw = Firewall::getInstance(); + if (!fw || fw->filter(msg)) + str = Base::Interpreter().runString(msg); + else + str = "Command blocked"; } catch (Base::PyException &e) { str = e.what(); diff --git a/src/Mod/Web/App/Server.h b/src/Mod/Web/App/Server.h index 80785d715..574ec54f7 100644 --- a/src/Mod/Web/App/Server.h +++ b/src/Mod/Web/App/Server.h @@ -29,10 +29,37 @@ #include #include #include +#include namespace Web { +class Firewall +{ +public: + Firewall(); + virtual ~Firewall(); + virtual bool filter(const QByteArray&) const = 0; + +public: + static Firewall* getInstance(); + static void setInstance(Firewall*); + +private: + static Firewall* instance; +}; + +class FirewallPython : public Firewall +{ +public: + FirewallPython(const Py::Object&); + virtual ~FirewallPython(); + virtual bool filter(const QByteArray&) const; + +private: + Py::Object obj; +}; + class ServerEvent : public QEvent { public: