stuff
This commit is contained in:
parent
b8db080960
commit
c1888e1cc3
10 changed files with 96 additions and 75 deletions
|
@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
|
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
|
||||||
|
@ -35,6 +35,10 @@ add_executable(littlesnitch
|
||||||
networkthread.cpp
|
networkthread.cpp
|
||||||
session.cpp
|
session.cpp
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
|
mainwindow.h
|
||||||
|
networkthread.h
|
||||||
|
session.h
|
||||||
|
includes.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(littlesnitch PRIVATE Qt5::Widgets cppzmq sqlite3)
|
target_link_libraries(littlesnitch PRIVATE Qt5::Widgets cppzmq sqlite3)
|
||||||
|
|
9
includes.h
Normal file
9
includes.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zmq.hpp>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
|
@ -1,17 +1,23 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "./ui_mainwindow.h"
|
#include "./ui_mainwindow.h"
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
#include "networkthread.h"
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent),
|
: QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
|
current_session = new Session();
|
||||||
|
current_session->load("/tmp/littlesnitch.session");
|
||||||
|
|
||||||
thread = new QThread;
|
thread = new QThread;
|
||||||
Worker* worker = new Worker();
|
NetworkThread* worker = new NetworkThread();
|
||||||
worker->moveToThread(thread);
|
worker->moveToThread(thread);
|
||||||
//connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString)));
|
|
||||||
connect(thread, SIGNAL (started()), worker, SLOT (process()));
|
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();
|
thread->start();
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
@ -20,19 +26,13 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
ui->historyHTTPTable->setColumnCount(4);
|
ui->historyHTTPTable->setColumnCount(4);
|
||||||
ui->historyHTTPTable->setRowCount(1);
|
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,0,new QTableWidgetItem(QString::number(data.index)));
|
||||||
ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(data.method)));
|
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,2,new QTableWidgetItem(QString::fromStdString(data.url)));
|
||||||
ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl)));
|
ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl)));
|
||||||
ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
@ -40,6 +40,10 @@ MainWindow::~MainWindow()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::httpMessage(HTTPData data) {
|
void MainWindow::updateHistory(json data) {
|
||||||
qDebug() << data.index;
|
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);
|
||||||
}
|
}
|
||||||
|
|
24
mainwindow.h
24
mainwindow.h
|
@ -2,29 +2,13 @@
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <zmq.hpp>
|
#include <session.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <includes.h>
|
||||||
#include <sqlite3.h>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
QT_END_NAMESPACE
|
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
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -32,8 +16,10 @@ class MainWindow : public QMainWindow
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QThread* thread;
|
QThread* thread;
|
||||||
|
Session* current_session;
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = nullptr);
|
MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
void httpMessage(HTTPData data);
|
public slots:
|
||||||
|
void updateHistory(json data);
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@ def networking(q):
|
||||||
|
|
||||||
context = zmq.Context()
|
context = zmq.Context()
|
||||||
connected = False
|
connected = False
|
||||||
|
a = None
|
||||||
while not connected:
|
while not connected:
|
||||||
socket = context.socket(zmq.PAIR)
|
socket = context.socket(zmq.PAIR)
|
||||||
socket.connect("tcp://127.0.0.1:12345")
|
socket.connect("tcp://127.0.0.1:12345")
|
||||||
|
@ -65,13 +66,16 @@ def networking(q):
|
||||||
if msg['msg'] == "ping":
|
if msg['msg'] == "ping":
|
||||||
send_msg(PONG_MSG, socket)
|
send_msg(PONG_MSG, socket)
|
||||||
timer = time.monotonic()
|
timer = time.monotonic()
|
||||||
|
|
||||||
a = q.get(block=False)
|
if not a:
|
||||||
|
a = q.get(block=False)
|
||||||
if a:
|
if a:
|
||||||
|
send_msg(a, socket)
|
||||||
msg = get_msg(socket)
|
msg = get_msg(socket)
|
||||||
if msg["msg"] == "ack":
|
if msg["msg"] == "ack":
|
||||||
q.task_done()
|
|
||||||
timer = time.monotonic()
|
timer = time.monotonic()
|
||||||
|
a = None
|
||||||
|
self.q.task_done()
|
||||||
else:
|
else:
|
||||||
connected = False
|
connected = False
|
||||||
|
|
||||||
|
@ -80,17 +84,15 @@ class Counter:
|
||||||
self.q = Queue()
|
self.q = Queue()
|
||||||
self.thread = threading.Thread(name="NetworkThread", target=networking, args=(self.q,))
|
self.thread = threading.Thread(name="NetworkThread", target=networking, args=(self.q,))
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
self.q.join()
|
|
||||||
|
|
||||||
def request(self, flow):
|
def request(self, flow):
|
||||||
self.q.put(flow.get_state())
|
self.q.put({'msg': 'request', 'flow': flow.get_state()})
|
||||||
self.q.join()
|
self.q.join()
|
||||||
|
|
||||||
def response(self, flow):
|
def response(self, flow):
|
||||||
self.q.put(flow.get_state())
|
self.q.put({'msg': 'response', 'flow': flow.get_state()})
|
||||||
self.q.join()
|
self.q.join()
|
||||||
|
|
||||||
|
|
||||||
addons = [
|
addons = [
|
||||||
Counter()
|
Counter()
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,34 +6,36 @@ NetworkThread::NetworkThread(QObject *parent) : QObject(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkThread::process() {
|
void NetworkThread::process() {
|
||||||
zmq::context_t ctx(1);
|
zmq::context_t ctx(1);
|
||||||
zmq::socket_t sock(ctx, zmq::socket_type::pair);
|
zmq::socket_t sock(ctx, zmq::socket_type::pair);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sock.bind("tcp://127.0.0.1:12345");
|
sock.bind("tcp://127.0.0.1:12345");
|
||||||
} catch (zmq::error_t err) {
|
} catch (zmq::error_t err) {
|
||||||
qDebug() << "failed binding socket" << err.what();
|
qDebug() << "failed binding socket" << err.what();
|
||||||
emit error(err.what());
|
emit error(err.what());
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
while(!connected) {
|
while(!connected) {
|
||||||
sock.send(zmq::str_buffer("{'type': 'init'}"), zmq::send_flags::dontwait);
|
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;
|
zmq::message_t msg;
|
||||||
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
if(msg.to_string() == "{'type': 'ack'}") {
|
|
||||||
connected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(connected) {
|
|
||||||
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
|
||||||
if(ret) {
|
|
||||||
qDebug() << msg.to_string().c_str();
|
qDebug() << msg.to_string().c_str();
|
||||||
}
|
emit httpMessage(json(msg.to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <includes.h>
|
||||||
|
|
||||||
|
const auto INIT_MSG = R"({"msg": "init"})"_json;
|
||||||
|
|
||||||
class NetworkThread : public QObject
|
class NetworkThread : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
// add your variables here
|
||||||
public:
|
public:
|
||||||
explicit NetworkThread(QObject *parent = nullptr);
|
explicit NetworkThread(QObject *parent = nullptr);
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -12,7 +17,5 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
void error(QString err);
|
void error(QString err);
|
||||||
void httpMessage(HTTPData);
|
void httpMessage(json data);
|
||||||
private:
|
|
||||||
// add your variables here
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,10 +18,12 @@ void Session::load(std::filesystem::path path)
|
||||||
auto rc = sqlite3_open(path.c_str(), &db);
|
auto rc = sqlite3_open(path.c_str(), &db);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
qDebug("cannot open database");
|
qDebug("cannot open database");
|
||||||
qDebug(sqlite3_errmsg(db));
|
qDebug() << sqlite3_errmsg(db);
|
||||||
unload();
|
unload();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
// check if tables exist
|
||||||
|
// create tables or add history
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::unload() {
|
void Session::unload() {
|
||||||
|
@ -29,3 +31,7 @@ void Session::unload() {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::saveRequest(json data) {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
15
session.h
15
session.h
|
@ -1,8 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <sqlite3.h>
|
#include <includes.h>
|
||||||
|
|
||||||
|
|
||||||
// static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
// static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
||||||
// int i;
|
// int i;
|
||||||
|
@ -42,11 +41,17 @@ class Session : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
sqlite3* db;
|
sqlite3* db = nullptr;
|
||||||
|
bool loaded = false;
|
||||||
public:
|
public:
|
||||||
explicit Session(QObject *parent = nullptr);
|
explicit Session(QObject *parent = nullptr);
|
||||||
|
~Session();
|
||||||
|
|
||||||
|
void load(std::filesystem::path path);
|
||||||
|
void unload();
|
||||||
|
bool isLoaded();
|
||||||
|
public slots:
|
||||||
|
void saveRequest(json data);
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
2
test.sh
2
test.sh
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
mitmdump -p 8080 -s mitmaddon/littlesnitch.py &
|
mitmdump -k -p 8080 -s mitmaddon/littlesnitch.py &
|
||||||
./build/littlesnitch &
|
./build/littlesnitch &
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
Loading…
Reference in a new issue