This commit is contained in:
Tim Blume 2021-03-19 17:40:33 +01:00
parent a0ce50b7cd
commit f99ee2abde
11 changed files with 100 additions and 72 deletions

View file

@ -1,55 +1,3 @@
#pragma once
#include <includes.h>
namespace http {
inline void to_json(json& j, const Flow& flow) {}
inline void from_json(const json& j, Flow& flow) {
//std::cout << std::setw(4) << j << "\n\n";
json j_flow;
if(!json_get(j, j_flow, "flow")) {
return;
}
json_get(j_flow, flow.uid, "id");
if(json j_request; json_get(j_flow, j_request, "request")) {
json_get(j_request, flow.request.tls, "server_conn", "tls_established");
json_get(j_request, flow.request.port, "port");
json_get(j_request, flow.request.host, "host");
json_get(j_request, flow.request.scheme, "scheme");
json_get(j_request, flow.request.path, "path");
json_get(j_request, flow.request.content, "content");
json_get(j_request, flow.request.method, "method");
json_get(j_request, flow.request.http_version, "http_version");
json_get(j_request, flow.request.timestamp_start, "timestamp_start");
json_get(j_request, flow.request.timestamp_end, "timestamp_end");
json j_headers;
if(json_get(j_request, j_headers, "headers")) {
for(auto& [k,v] : j_headers.items()) {
flow.request.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
}
}
}
if(json j_response; json_get(j_flow, j_response, "response")) {
json_get(j_response, flow.response.status_code, "status_code");
json_get(j_response, flow.response.http_version, "http_version");
json_get(j_response, flow.response.reason, "reason");
json_get(j_response, flow.response.content, "content");
json_get(j_response, flow.response.timestamp_start, "timestamp_start");
json_get(j_response, flow.response.timestamp_end, "timestamp_end");
json j_headers;
if(json_get(j_response, j_headers, "headers")) {
for(auto& [k,v] : j_headers.items()) {
flow.response.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
}
}
}
}
}
Q_DECLARE_METATYPE(http::Flow)

View file

@ -105,4 +105,53 @@ struct Flow {
Response response;
};
inline void to_json(json& j, const Flow& flow) {}
inline void from_json(const json& j, Flow& flow) {
//std::cout << std::setw(4) << j << "\n\n";
json j_flow;
if(!json_get(j, j_flow, "flow")) {
return;
}
json_get(j_flow, flow.uid, "id");
if(json j_request; json_get(j_flow, j_request, "request")) {
json_get(j_request, flow.request.tls, "server_conn", "tls_established");
json_get(j_request, flow.request.port, "port");
json_get(j_request, flow.request.host, "host");
json_get(j_request, flow.request.scheme, "scheme");
json_get(j_request, flow.request.path, "path");
json_get(j_request, flow.request.content, "content");
json_get(j_request, flow.request.method, "method");
json_get(j_request, flow.request.http_version, "http_version");
json_get(j_request, flow.request.timestamp_start, "timestamp_start");
json_get(j_request, flow.request.timestamp_end, "timestamp_end");
json j_headers;
if(json_get(j_request, j_headers, "headers")) {
for(auto& [k,v] : j_headers.items()) {
flow.request.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
}
}
}
if(json j_response; json_get(j_flow, j_response, "response")) {
json_get(j_response, flow.response.status_code, "status_code");
json_get(j_response, flow.response.http_version, "http_version");
json_get(j_response, flow.response.reason, "reason");
json_get(j_response, flow.response.content, "content");
json_get(j_response, flow.response.timestamp_start, "timestamp_start");
json_get(j_response, flow.response.timestamp_end, "timestamp_end");
json j_headers;
if(json_get(j_response, j_headers, "headers")) {
for(auto& [k,v] : j_headers.items()) {
flow.response.headers.push_back(std::make_tuple(v.at(0), v.at(1)));
}
}
}
}
}
Q_DECLARE_METATYPE(http::Flow)

View file

@ -10,9 +10,11 @@ namespace http {
//! Interface for implementing proxies
/*!
Interface for implementing proxies
There are no signals, because apparently Qt Plugins do not support interfaces, which inherit from QObject.
(it will fail upon loading the plugin)
*/
class ProxyInterface : public QObject {
Q_OBJECT
class ProxyInterface {
public:
virtual ~ProxyInterface() = default;
//! called in a custom thread, may block.
@ -22,10 +24,9 @@ public:
//! disconnects the handle
virtual void disconnect() = 0;
// options/settings
signals:
virtual void finished();
virtual void error(QString err);
virtual void message(http::Flow flow);
std::function<void()> finished;
std::function<void(QString)> error;
std::function<void(http::Flow flow)> message;
};
}

View file

@ -12,6 +12,9 @@ MainWindow::MainWindow(QWidget *parent)
current_session = new Session();
current_session->load("/tmp/littlesnitch.session");
plugin_handler.loadPlugins(QDir("/home/end/projects/bigsnitch/build/plugins/"));
/*
thread = new QThread;
NetworkThread* worker = new NetworkThread();
worker->moveToThread(thread);
@ -20,7 +23,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(worker, SIGNAL (httpMessage(http::Flow)), current_session, SLOT (saveFlow(http::Flow)), Qt::QueuedConnection);
connect(worker, SIGNAL (httpMessage(http::Flow)), this, SLOT (updateHistory()), Qt::QueuedConnection);
thread->start();
*/
history_model.update(current_session->getHistoryItems());
history_proxy.setSourceModel(&history_model);

View file

@ -7,6 +7,8 @@
#include <httpflow.h>
#include <editandresend.h>
#include <pluginhandler.h>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
@ -23,6 +25,8 @@ private:
HistoryModel history_model;
HistoryProxyModel history_proxy;
PluginHandler plugin_handler;
QAction* editAndResendMenu;
QAction* hideHistoryColumn;
QAction* showHistoryColumn;

View file

@ -12,17 +12,22 @@ bool PluginHandler::load(QString path)
QPluginLoader loader(path);
QObject *plugin = loader.instance();
if (plugin) {
qDebug() << "loading plugin " << plugin;
proxyhandler.loadPlugin(plugin);
loaded_plugins += path;
return true;
} else {
qDebug() << "fo " << loader.errorString();
}
return false;
}
void PluginHandler::loadPlugins(QDir path)
{
qDebug() << "loading plugins from " << path;
const auto entryList = path.entryList(QDir::Files);
for (const QString &fileName : entryList) {
qDebug() << "loading " << fileName;
load(path.absoluteFilePath(fileName));
}
}

View file

@ -1,4 +1,5 @@
add_library(mitmproxy_plugin MODULE mitmproxy_network.cpp mitmproxy_network.h)
SET(CMAKE_AUTOMOC ON)
add_library(mitmproxy_plugin MODULE mitmproxy_network.cpp mitmproxy_network.h mitmproxy.json)
target_include_directories(mitmproxy_plugin PRIVATE ../../include/)
target_link_libraries(mitmproxy_plugin PRIVATE Qt5::Core cppzmq)
set_target_properties(mitmproxy_plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_DIR})

View file

@ -9,7 +9,7 @@ void mitmproxyPlugin::connect()
socket->bind(this->path);
} catch (zmq::error_t err) {
qDebug() << "failed binding socket" << err.what();
emit error(err.what());
error(err.what());
throw;
};
is_connected = true;
@ -47,7 +47,7 @@ void mitmproxyPlugin::process(std::string path)
qDebug() << "received " << msg_type.c_str();
} else if(msg_type == "response") {
qDebug() << "received " << msg_type.c_str();
//emit httpMessage(j);
message(j);
} else if(msg_type == "requestheaders") {
qDebug() << "received " << msg_type.c_str();
} else if(msg_type == "request") {
@ -78,6 +78,11 @@ void mitmproxyPlugin::process(std::string path)
}
}
bool mitmproxyPlugin::connected()
{
return is_connected;
}
void mitmproxyPlugin::disconnect()
{
delete socket;

View file

@ -3,14 +3,20 @@
#include "api.h"
#include "proxyinterface.h"
#include <QObject>
#include <QtPlugin>
#include <set>
#include <zmq.hpp>
class mitmproxyPlugin : public http::ProxyInterface
/*
mitmproxy base plugin
This plugin implements the interface for the basic mitmproxy plugin.
*/
class mitmproxyPlugin : public QObject, http::ProxyInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "bigsnitch.api.HTTPProxyInterface/100" FILE "mitmproxy.json")
Q_PLUGIN_METADATA(IID HTTPProxyInterfaceIID FILE "mitmproxy.json")
Q_INTERFACES(http::ProxyInterface)
private:
std::set<std::string> received;
@ -29,9 +35,4 @@ public:
//! disconnects the handle
void disconnect() override;
// options/settings
signals:
//void finished();
//void error(QString err);
//void message(http::Flow flow);
};

View file

@ -1,4 +1,5 @@
#include "proxyhandler.h"
#include <QThread>
bool http::ProxyHandler::loadPlugin(QObject *proxy)
{
@ -8,7 +9,17 @@ bool http::ProxyHandler::loadPlugin(QObject *proxy)
}
qDebug("loading proxy");
proxies.insert({"foo", inst});
auto thread = new QThread;
proxy->moveToThread(thread);
QObject::connect(thread, SIGNAL (started()), proxy, SLOT (process()));
//connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString)));
QObject::connect(worker, SIGNAL (httpMessage(http::Flow)), current_session, SLOT (saveFlow(http::Flow)), Qt::QueuedConnection);
QObject::connect(worker, SIGNAL (httpMessage(http::Flow)), this, SLOT (updateHistory()), Qt::QueuedConnection);
thread->start();
proxies.insert({"foo", inst, thread});
return true;
}

View file

@ -9,7 +9,7 @@ namespace http {
class ProxyHandler
{
private:
std::map<std::string, ProxyInterface*> proxies;
std::map<std::string, ProxyInterface*, QThread*> proxies;
public:
bool loadPlugin(QObject *proxy);
QStringList getProxies();