diff --git a/historymodel.h b/historymodel.h index cb06cf3..47a5c1a 100644 --- a/historymodel.h +++ b/historymodel.h @@ -4,6 +4,7 @@ #include #include #include +#include class HistoryModel : public QAbstractTableModel { diff --git a/include/api.h b/include/api.h index e89ae3b..4772929 100644 --- a/include/api.h +++ b/include/api.h @@ -1,5 +1,8 @@ #pragma once +//major minor patch +#define LITTLESNITCH_VERSION 100 + #include #include #include @@ -7,6 +10,42 @@ #include #include +#include + +#include + +using json = nlohmann::json; + +template +bool json_get(json j, T& value, K key) noexcept { + try { + j[key].get_to(value); + return true; + } catch (nlohmann::detail::type_error& err) { + std::cout << "key " << key << " error " << err.what(); + } catch (nlohmann::detail::out_of_range& err) { + std::cout << "key " << key << " error " << err.what(); + } catch (nlohmann::detail::other_error& err) { + std::cout << "key " << key << " error " << err.what(); + } + return false; +} + +template +bool json_get(json j, T& value, K key, Ks... keys) noexcept { + try { + return json_get(j[key], value, keys...); + } catch (nlohmann::detail::type_error& err) { + std::cout << "key " << key << " error " << err.what(); + } catch (nlohmann::detail::out_of_range& err) { + std::cout << "key " << key << " error " << err.what(); + } catch (nlohmann::detail::other_error& err) { + std::cout << "key " << key << " error " << err.what(); + } + return false; +} + + //! represents one item in the http history. struct HistoryItem { int id = -1; diff --git a/includes.h b/includes.h index 054b16b..eb459af 100644 --- a/includes.h +++ b/includes.h @@ -1,45 +1,9 @@ #pragma once #include -#include -#include #include #include #include #include #include #include - -using json = nlohmann::json; - -//major minor patch -#define LITTLESNITCH_VERSION 100 - -template -bool json_get(json j, T& value, K key) noexcept { - try { - j[key].get_to(value); - return true; - } catch (nlohmann::detail::type_error& err) { - qDebug() << "key " << key << " error " << err.what(); - } catch (nlohmann::detail::out_of_range& err) { - qDebug() << "key " << key << " error " << err.what(); - } catch (nlohmann::detail::other_error& err) { - qDebug() << "key " << key << " error " << err.what(); - } - return false; -} - -template -bool json_get(json j, T& value, K key, Ks... keys) noexcept { - try { - return json_get(j[key], value, keys...); - } catch (nlohmann::detail::type_error& err) { - qDebug() << "key " << key << " error " << err.what(); - } catch (nlohmann::detail::out_of_range& err) { - qDebug() << "key " << key << " error " << err.what(); - } catch (nlohmann::detail::other_error& err) { - qDebug() << "key " << key << " error " << err.what(); - } - return false; -} diff --git a/networkthread.h b/networkthread.h index a30104e..e566155 100644 --- a/networkthread.h +++ b/networkthread.h @@ -5,6 +5,8 @@ #include #include +#include + class NetworkThread : public QObject { Q_OBJECT diff --git a/pluginhandler.h b/pluginhandler.h index a87eef8..498a482 100644 --- a/pluginhandler.h +++ b/pluginhandler.h @@ -11,7 +11,7 @@ class PluginHandler { private: QStringList loaded_plugins; - ProxyHandler proxyhandler; + http::ProxyHandler proxyhandler; public: bool load(QString path); void loadPlugins(QDir path); diff --git a/plugins/mitmproxy/CMakeLists.txt b/plugins/mitmproxy/CMakeLists.txt index 60622dd..c834a06 100644 --- a/plugins/mitmproxy/CMakeLists.txt +++ b/plugins/mitmproxy/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(mitmproxy_plugin MODULE mitmproxy_network.cpp mitmproxy_network.h) target_include_directories(mitmproxy_plugin PRIVATE ../../include/) -target_link_libraries(mitmproxy_plugin PRIVATE Qt5::Core) +target_link_libraries(mitmproxy_plugin PRIVATE Qt5::Core cppzmq) set_target_properties(mitmproxy_plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_DIR}) diff --git a/plugins/mitmproxy/mitmproxy_network.cpp b/plugins/mitmproxy/mitmproxy_network.cpp index 5e1e064..0e1e0fc 100644 --- a/plugins/mitmproxy/mitmproxy_network.cpp +++ b/plugins/mitmproxy/mitmproxy_network.cpp @@ -1 +1,86 @@ #include + +void mitmproxyPlugin::connect() +{ + socket = new zmq::socket_t(context, zmq::socket_type::pair); + int linger_time = 0; + socket->set(zmq::sockopt::linger, linger_time); + try { + socket->bind(this->path); + } catch (zmq::error_t err) { + qDebug() << "failed binding socket" << err.what(); + emit error(err.what()); + throw; + }; + is_connected = true; + qDebug() << "connected"; +} + +void mitmproxyPlugin::reconnect() +{ + this->disconnect(); + this->connect(); +} + +void mitmproxyPlugin::process(std::string path) +{ + this->path = path; + connect(); + while(true) { + zmq::message_t response; + const auto ret = socket->recv(response, zmq::recv_flags::dontwait); + if(!ret) { + continue; + } + json j; + try { + j = json::parse(response.to_string()); + } catch (nlohmann::detail::parse_error& err) { + qDebug() << err.what(); + qDebug() << "malformed json received " << response.to_string().c_str(); + } + //std::cout << std::setw(4) << j << "\n\n"; + std::string msg_type; + if(!json_get(j, msg_type, "msg")) { + qDebug() << "broken message received " << response.to_string().c_str(); + } else if(msg_type == "responseheaders") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "response") { + qDebug() << "received " << msg_type.c_str(); + //emit httpMessage(j); + } else if(msg_type == "requestheaders") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "request") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "ping") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "error") { + qDebug() << "received " << msg_type.c_str(); + + // websocket events + } else if(msg_type == "websocket_handshake") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "websocket_start") { + qDebug() << "received " << msg_type.c_str(); + std::cout << std::setw(4) << j << "\n\n"; + } else if(msg_type == "websocket_message") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "websocket_end") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "websocket_error") { + } else { + qDebug() << "unknown or broken message type received: " << msg_type.c_str(); + } + + qDebug() << "sending ack"; + std::string m = "{\"msg\": \"ack\"}"; + socket->send(zmq::buffer(m.c_str(), m.length()), zmq::send_flags::dontwait); + } +} + +void mitmproxyPlugin::disconnect() +{ + delete socket; + is_connected = false; + qDebug() << "disconnected"; +} diff --git a/plugins/mitmproxy/mitmproxy_network.h b/plugins/mitmproxy/mitmproxy_network.h index 2834a46..be75111 100644 --- a/plugins/mitmproxy/mitmproxy_network.h +++ b/plugins/mitmproxy/mitmproxy_network.h @@ -4,12 +4,34 @@ #include "proxyinterface.h" #include -class mitmproxyPlugin : public QObject, - public http::ProxyInterface +#include +#include + +class mitmproxyPlugin : public http::ProxyInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "bigsnitch.api.HTTPProxyInterface/100" FILE "mitmproxy.json") Q_INTERFACES(http::ProxyInterface) +private: + std::set received; + zmq::context_t context; + zmq::socket_t *socket; + std::set accepted_flows; + std::string path; + bool is_connected = false; + void connect(); + void reconnect(); public: + //! called in a custom thread, may block. + void process(std::string path) override; + //! returns, whether the proxy is currently connected + bool connected() override; + //! disconnects the handle + void disconnect() override; + // options/settings +signals: + //void finished(); + //void error(QString err); + //void message(http::Flow flow); }; diff --git a/proxyhandler.cpp b/proxyhandler.cpp index ed37291..837766d 100644 --- a/proxyhandler.cpp +++ b/proxyhandler.cpp @@ -4,11 +4,11 @@ bool http::ProxyHandler::loadPlugin(QObject *proxy) { auto inst = qobject_cast(proxy); if(!inst) { - return false; } - + qDebug("loading proxy"); + proxies.insert({"foo", inst}); return true; } diff --git a/proxyhandler.h b/proxyhandler.h index 09007f7..2874ca8 100644 --- a/proxyhandler.h +++ b/proxyhandler.h @@ -9,8 +9,10 @@ namespace http { class ProxyHandler { private: + std::map proxies; public: bool loadPlugin(QObject *proxy); + QStringList getProxies(); }; } diff --git a/settings.h b/settings.h index 89099be..9ac0c49 100644 --- a/settings.h +++ b/settings.h @@ -1,5 +1,4 @@ -#ifndef SETTINGS_H -#define SETTINGS_H +#pragma once #include @@ -18,5 +17,3 @@ public: private: Ui::Settings *ui; }; - -#endif // SETTINGS_H