diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d2f03c..f9f7d60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # QtCreator supports the following variables for Android, which are identical to qmake Android variables. @@ -35,6 +35,10 @@ add_executable(littlesnitch networkthread.cpp session.cpp mainwindow.ui + mainwindow.h + networkthread.h + session.h + includes.h ) target_link_libraries(littlesnitch PRIVATE Qt5::Widgets cppzmq sqlite3) diff --git a/includes.h b/includes.h new file mode 100644 index 0000000..58fb550 --- /dev/null +++ b/includes.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +#include +#include +#include + +using json = nlohmann::json; diff --git a/mainwindow.cpp b/mainwindow.cpp index 913c667..277c166 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,17 +1,23 @@ #include "mainwindow.h" + #include "./ui_mainwindow.h" #include +#include "networkthread.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { + current_session = new Session(); + current_session->load("/tmp/littlesnitch.session"); + thread = new QThread; - Worker* worker = new Worker(); + NetworkThread* worker = new NetworkThread(); worker->moveToThread(thread); - //connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString))); connect(thread, SIGNAL (started()), worker, SLOT (process())); - connect(thread, SIGNAL (httpMessage()), worker, SLOT (httpMessage())); + //connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString))); + connect(worker, SIGNAL (httpMessage(json)), current_session, SLOT (saveRequest(json))); + connect(worker, SIGNAL (httpMessage(json)), this, SLOT (updateHistory(json))); thread->start(); ui->setupUi(this); @@ -20,19 +26,13 @@ MainWindow::MainWindow(QWidget *parent) ui->historyHTTPTable->setColumnCount(4); ui->historyHTTPTable->setRowCount(1); - HTTPData data; - data.index = 1; - data.url = "https://test.com"; - data.status = 200; - data.method = "GET"; - data.ttl = 44; - + /* ui->historyHTTPTable->setItem(0,0,new QTableWidgetItem(QString::number(data.index))); ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(data.method))); ui->historyHTTPTable->setItem(0,2,new QTableWidgetItem(QString::fromStdString(data.url))); ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl))); ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); - +*/ } MainWindow::~MainWindow() @@ -40,6 +40,10 @@ MainWindow::~MainWindow() delete ui; } -void MainWindow::httpMessage(HTTPData data) { - qDebug() << data.index; +void MainWindow::updateHistory(json data) { + ui->historyHTTPTable->setItem(0,0,new QTableWidgetItem(QString::fromStdString(data["id"]))); +// ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(data.method))); +// ui->historyHTTPTable->setItem(0,2,new QTableWidgetItem(QString::fromStdString(data.url))); +// ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl))); + ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); } diff --git a/mainwindow.h b/mainwindow.h index 5683ab2..10173d2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,29 +2,13 @@ #include #include -#include -#include -#include +#include +#include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE -class HTTPData { -private: -public: - size_t index; - size_t status; - size_t ttl; - std::string method; - std::string url; - std::string request_headers; - std::string request_content; - std::string response_headers; - std::string response_content; -}; - - class MainWindow : public QMainWindow { Q_OBJECT @@ -32,8 +16,10 @@ class MainWindow : public QMainWindow private: Ui::MainWindow *ui; QThread* thread; + Session* current_session; public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); - void httpMessage(HTTPData data); +public slots: + void updateHistory(json data); }; diff --git a/mitmaddon/littlesnitch.py b/mitmaddon/littlesnitch.py index 1880c63..76a1f8d 100644 --- a/mitmaddon/littlesnitch.py +++ b/mitmaddon/littlesnitch.py @@ -44,6 +44,7 @@ def networking(q): context = zmq.Context() connected = False + a = None while not connected: socket = context.socket(zmq.PAIR) socket.connect("tcp://127.0.0.1:12345") @@ -65,13 +66,16 @@ def networking(q): if msg['msg'] == "ping": send_msg(PONG_MSG, socket) timer = time.monotonic() - - a = q.get(block=False) + + if not a: + a = q.get(block=False) if a: + send_msg(a, socket) msg = get_msg(socket) if msg["msg"] == "ack": - q.task_done() timer = time.monotonic() + a = None + self.q.task_done() else: connected = False @@ -80,17 +84,15 @@ class Counter: self.q = Queue() self.thread = threading.Thread(name="NetworkThread", target=networking, args=(self.q,)) self.thread.start() - self.q.join() def request(self, flow): - self.q.put(flow.get_state()) + self.q.put({'msg': 'request', 'flow': flow.get_state()}) self.q.join() def response(self, flow): - self.q.put(flow.get_state()) + self.q.put({'msg': 'response', 'flow': flow.get_state()}) self.q.join() - addons = [ Counter() ] diff --git a/networkthread.cpp b/networkthread.cpp index 40e9d54..55a82ad 100644 --- a/networkthread.cpp +++ b/networkthread.cpp @@ -6,34 +6,36 @@ NetworkThread::NetworkThread(QObject *parent) : QObject(parent) } void NetworkThread::process() { - zmq::context_t ctx(1); - zmq::socket_t sock(ctx, zmq::socket_type::pair); + zmq::context_t ctx(1); + zmq::socket_t sock(ctx, zmq::socket_type::pair); - try { - sock.bind("tcp://127.0.0.1:12345"); - } catch (zmq::error_t err) { - qDebug() << "failed binding socket" << err.what(); - emit error(err.what()); - return; - }; + try { + sock.bind("tcp://127.0.0.1:12345"); + } catch (zmq::error_t err) { + qDebug() << "failed binding socket" << err.what(); + emit error(err.what()); + return; + }; - while(true){ - bool connected = false; - while(!connected) { - sock.send(zmq::str_buffer("{'type': 'init'}"), zmq::send_flags::dontwait); + while(true){ + bool connected = false; + while(!connected) { + sock.send(zmq::str_buffer("{'type': 'init'}"), zmq::send_flags::dontwait); + zmq::message_t msg; + const auto ret = sock.recv(msg, zmq::recv_flags::dontwait); + if(ret) { + if(msg.to_string() == "{'type': 'ack'}") { + connected = true; + } + } + } + while(connected) { zmq::message_t msg; const auto ret = sock.recv(msg, zmq::recv_flags::dontwait); - if(ret) { - if(msg.to_string() == "{'type': 'ack'}") { - connected = true; - } - } - } - while(connected) { - const auto ret = sock.recv(msg, zmq::recv_flags::dontwait); - if(ret) { + if(ret) { qDebug() << msg.to_string().c_str(); - } - } - } + emit httpMessage(json(msg.to_string())); + } + } + } } diff --git a/networkthread.h b/networkthread.h index 4bf9c9b..d0b6d93 100644 --- a/networkthread.h +++ b/networkthread.h @@ -1,10 +1,15 @@ #pragma once #include +#include + +const auto INIT_MSG = R"({"msg": "init"})"_json; class NetworkThread : public QObject { Q_OBJECT +private: + // add your variables here public: explicit NetworkThread(QObject *parent = nullptr); public slots: @@ -12,7 +17,5 @@ public slots: signals: void finished(); void error(QString err); - void httpMessage(HTTPData); -private: - // add your variables here + void httpMessage(json data); }; diff --git a/session.cpp b/session.cpp index 640070d..a2eca75 100644 --- a/session.cpp +++ b/session.cpp @@ -18,10 +18,12 @@ void Session::load(std::filesystem::path path) auto rc = sqlite3_open(path.c_str(), &db); if(rc) { qDebug("cannot open database"); - qDebug(sqlite3_errmsg(db)); + qDebug() << sqlite3_errmsg(db); unload(); throw; } + // check if tables exist + // create tables or add history } void Session::unload() { @@ -29,3 +31,7 @@ void Session::unload() { sqlite3_close(db); } } + +void Session::saveRequest(json data) { + // todo +} diff --git a/session.h b/session.h index f493603..881ae6f 100644 --- a/session.h +++ b/session.h @@ -1,8 +1,7 @@ #pragma once #include -#include - +#include // static int callback(void *NotUsed, int argc, char **argv, char **azColName){ // int i; @@ -42,11 +41,17 @@ class Session : public QObject { Q_OBJECT private: - sqlite3* db; - + sqlite3* db = nullptr; + bool loaded = false; public: explicit Session(QObject *parent = nullptr); - + ~Session(); + + void load(std::filesystem::path path); + void unload(); + bool isLoaded(); +public slots: + void saveRequest(json data); signals: }; diff --git a/test.sh b/test.sh index 2f3e14c..d64a190 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,6 @@ #!/bin/sh -mitmdump -p 8080 -s mitmaddon/littlesnitch.py & +mitmdump -k -p 8080 -s mitmaddon/littlesnitch.py & ./build/littlesnitch & sleep 1