From 6a650ef1e8db6b492cf0811fd939db5412b713b3 Mon Sep 17 00:00:00 2001 From: End Date: Fri, 21 Aug 2020 20:40:37 +0200 Subject: [PATCH] mehr kram --- httpflow.h | 68 ++++++++++++++++++--------------------- includes.h | 20 ++++++++++++ mitmaddon/littlesnitch.py | 4 ++- networkthread.cpp | 56 ++++++++++++++++---------------- networkthread.h | 2 ++ test.sh | 35 +++----------------- 6 files changed, 89 insertions(+), 96 deletions(-) diff --git a/httpflow.h b/httpflow.h index 4a1734f..131e612 100644 --- a/httpflow.h +++ b/httpflow.h @@ -148,49 +148,45 @@ struct HistoryItem { 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"; - if(!j.contains("flow")) { + //std::cout << std::setw(4) << j << "\n\n"; + json j_flow; + if(!json_get(j, j_flow, "flow")) { return; } - auto j_flow = j.at("flow"); - j_flow.at("id").get_to(flow.uid); + 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"); - if(j_flow.contains("server_conn")) { - j_flow.at("server_conn").at("tls_established").get_to(flow.request.tls); - } - // todo might crash with fabricated/missing json, add parser exception handling - if(j_flow.contains("request")) { - auto j_request = j_flow.at("request"); - - j_request.at("port").get_to(flow.request.port); - j_request.at("host").get_to(flow.request.host); - j_request.at("scheme").get_to(flow.request.scheme); - j_request.at("path").get_to(flow.request.path); - j_request.at("content").get_to(flow.request.content); - j_request.at("method").get_to(flow.request.method); - j_request.at("http_version").get_to(flow.request.http_version); - j_request.at("timestamp_start").get_to(flow.request.timestamp_start); - j_request.at("timestamp_end").get_to(flow.request.timestamp_end); - - auto j_headers = j_request.at("headers"); - for(auto& [k,v] : j_headers.items()) { - flow.request.headers.push_back(std::make_tuple(v.at(0), v.at(1))); + 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(j_flow.contains("response")) { - auto j_response = j_flow.at("response"); + 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"); - j_response.at("status_code").get_to(flow.response.status_code); - j_response.at("http_version").get_to(flow.response.http_version); - j_response.at("reason").get_to(flow.response.reason); - j_response.at("content").get_to(flow.response.content); - j_response.at("timestamp_start").get_to(flow.response.timestamp_start); - j_response.at("timestamp_end").get_to(flow.response.timestamp_end); - - auto j_headers = j_response.at("headers"); - for(auto& [k,v] : j_headers.items()) { - flow.response.headers.push_back(std::make_tuple(v.at(0), v.at(1))); + 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))); + } } } } diff --git a/includes.h b/includes.h index b049085..b8ee75d 100644 --- a/includes.h +++ b/includes.h @@ -11,3 +11,23 @@ using json = nlohmann::json; //major minor patch #define LITTLESNITCH_VERSION 010 + +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() << err.what(); + } catch (nlohmann::detail::out_of_range& err) { + qDebug() << err.what(); + } catch (nlohmann::detail::other_error& err) { + qDebug() << err.what(); + } + return false; +} + +template +bool json_get(json j, T& value, K key, Ks... keys) noexcept { + return json_get(j[key], value, keys...); +} diff --git a/mitmaddon/littlesnitch.py b/mitmaddon/littlesnitch.py index 95275a4..e3f1661 100644 --- a/mitmaddon/littlesnitch.py +++ b/mitmaddon/littlesnitch.py @@ -60,14 +60,16 @@ class NetworkThread(threading.Thread): def send_msg_and_ack(self, msg): while True: + print("m sending") a = convert_to_strings(msg) self.socket.send(str.encode(json.dumps(a))) - if (self.socket.poll(5) & zmq.POLLIN) != 0: + if (self.socket.poll(50) & zmq.POLLIN) != 0: msg = self.socket.recv() try: if msg: result = json.loads(msg) if result["msg"] == "ack": + print("m ack received") return result else: print("got unexpected message {result}") diff --git a/networkthread.cpp b/networkthread.cpp index cd9ac6d..c4a870e 100644 --- a/networkthread.cpp +++ b/networkthread.cpp @@ -37,35 +37,33 @@ void NetworkThread::process() { while(true) { zmq::message_t response; const auto ret = socket->recv(response, zmq::recv_flags::dontwait); - if(ret) { - auto j = json::parse(response.to_string()); - //std::cout << std::setw(4) << j << "\n\n"; - if(j.contains("msg") && j["msg"].is_string()) { - std::string msg_type; - try { - j["msg"].get_to(msg_type); - } catch (nlohmann::detail::type_error& err) { - qDebug() << "json type error, message type not a string: " << response.to_string().c_str(); - emit error("no message type"); - } - if(msg_type == "request") { - } else if (msg_type == "response") { - try { - emit httpMessage(j); - } catch (nlohmann::detail::type_error& err) { - qDebug() << "error reading HTTP Flow"; - emit error("error converting to flow"); - } - } else if(msg_type == "ping") { - } else { - qDebug() << "unknown or broken message type received: " << msg_type.c_str(); - emit error("unknown message"); - } - std::string m = "{\"msg\": \"ack\"}"; - socket->send(zmq::buffer(m.c_str(), m.length()), zmq::send_flags::dontwait); - } else { - qDebug() << "broken message, but correct json: " << response.to_string().c_str(); - } + 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 == "response") { + qDebug() << "received " << msg_type.c_str(); + emit httpMessage(j); + } else if(msg_type == "request") { + qDebug() << "received " << msg_type.c_str(); + } else if(msg_type == "ping") { + qDebug() << "received " << msg_type.c_str(); + } 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); } } diff --git a/networkthread.h b/networkthread.h index 2164173..d0d8bd8 100644 --- a/networkthread.h +++ b/networkthread.h @@ -3,6 +3,7 @@ #include #include #include +#include class NetworkThread : public QObject { @@ -10,6 +11,7 @@ class NetworkThread : public QObject private: zmq::context_t context; zmq::socket_t *socket; + std::set accepted_flows; void connect(); void disconnect(); void reconnect(); diff --git a/test.sh b/test.sh index 8518492..fa74647 100755 --- a/test.sh +++ b/test.sh @@ -1,38 +1,13 @@ #!/bin/sh -mitmdump -k -p 8080 -s mitmaddon/littlesnitch.py & +mitmdump -k -p 8888 -s mitmaddon/littlesnitch.py & ./build/littlesnitch & sleep 1 -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt -curl -x http://localhost:8080 -k https://get.yolo.jetzt +echo "sending requests" +curl -x http://localhost:8888 -k https://blog.fefe.de +curl -x http://localhost:8888 -k https://blog.fefe.de +curl -x http://localhost:8888 -k https://blog.fefe.de killall mitmdump sleep 1