Report 'None' for successfully executed commands in server, implement a simple firewall to block commands

This commit is contained in:
wmayer 2015-12-13 14:24:15 +01:00
parent 33c9c02aeb
commit f46393efe7
3 changed files with 104 additions and 2 deletions

View File

@ -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 */
};

View File

@ -25,7 +25,7 @@
#include <QCoreApplication>
#include <QTcpSocket>
# include <stdexcept>
#include <stdexcept>
#include "Server.h"
#include <Base/Exception.h>
@ -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<bool>(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();

View File

@ -29,10 +29,37 @@
#include <QEvent>
#include <QTcpSocket>
#include <QTcpServer>
#include <CXX/Objects.hxx>
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: