This commit is contained in:
Tim Blume 2020-08-26 20:58:36 +02:00
parent 6a650ef1e8
commit ea0a5e74f2
11 changed files with 224 additions and 152 deletions

View file

@ -36,11 +36,13 @@ add_executable(littlesnitch
networkthread.cpp
session.cpp
httpflow.cpp
historymodel.cpp
mainwindow.h
httpflow.h
networkthread.h
session.h
includes.h
historymodel.h
mainwindow.ui
)

78
historymodel.cpp Normal file
View file

@ -0,0 +1,78 @@
#include "historymodel.h"
#include <QDateTime>
HistoryModel::HistoryModel(QObject *parent)
{
Q_UNUSED(parent);
}
int HistoryModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if(current_items) {
return current_items->size();
}
return 0;
}
int HistoryModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 7;
}
QVariant HistoryModel::data(const QModelIndex &index, int role) const
{
if(role != Qt::DisplayRole) {
return QVariant();
}
if(!current_items) {
return QVariant();
}
int row = index.row();
int col = index.column();
try {
auto item = current_items->at(row);
switch(col) {
case 0: {
return QString::number(item.id);
}
case 1: {
QDateTime timestamp;
timestamp.setTime_t(item.timestamp);
return timestamp.toString(Qt::SystemLocaleShortDate);
}
case 2: {
std::string url = item.scheme + "://" + item.host + ":" + std::to_string(item.port) + item.path;
return QString::fromStdString(url);
}
case 3: {
return item.status_code;
}
case 4: {
return QString::fromStdString(item.reason);
}
case 5: {
return item.rtt;
}
case 6:{
return QString::number(item.size);
}
}
} catch (std::out_of_range const& exc) {
qDebug() << "historymodel data " << exc.what();
}
return QVariant();
}
void HistoryModel::update(std::vector<HistoryItem> *items)
{
if(current_items) {
delete current_items;
}
current_items = items;
}

31
historymodel.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include <includes.h>
#include <QAbstractTableModel>
struct HistoryItem {
int id = -1;
double timestamp = 0;
std::string method;
std::string scheme;
std::string host;
unsigned short port = 0;
std::string path;
int status_code = 0;
std::string reason;
double rtt = 0.0;
size_t size = 0;
};
class HistoryModel : public QAbstractTableModel
{
Q_OBJECT
private:
std::vector<HistoryItem>* current_items = nullptr;
public:
HistoryModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void update(std::vector<HistoryItem>* items);
};

View file

@ -131,20 +131,6 @@ struct Flow {
Response response;
};
struct HistoryItem {
int id;
double timestamp;
std::string method;
std::string scheme;
std::string host;
unsigned short port;
std::string path;
int status_code;
std::string reason;
double rtt;
int size;
};
inline void to_json(json& j, const Flow& flow) {}
inline void from_json(const json& j, Flow& flow) {

View file

@ -1,5 +1,5 @@
#include "mainwindow.h"
#include <historymodel.h>
#include "./ui_mainwindow.h"
#include <QtGui>
#include "networkthread.h"
@ -21,19 +21,12 @@ MainWindow::MainWindow(QWidget *parent)
connect(worker, SIGNAL (httpMessage(http::Flow)), this, SLOT (updateHistory()), Qt::QueuedConnection);
thread->start();
history_model.update(current_session->getHistoryItems());
ui->setupUi(this);
ui->historyHTTPTable->setShowGrid(true);
ui->historyHTTPTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->historyHTTPTable->setColumnCount(7);
ui->historyHTTPTable->setRowCount(1);
/*
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);
*/
ui->historyHTTPTable->setModel(&history_model);
}
MainWindow::~MainWindow()
@ -42,28 +35,7 @@ MainWindow::~MainWindow()
}
void MainWindow::updateHistory() {
int i = 0;
auto items = current_session->getHistoryItems();
for(auto& item : *items) {
ui->historyHTTPTable->setRowCount(i+1);
int j = 0;
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::number(item.id)));
QDateTime timestamp;
timestamp.setTime_t(item.timestamp);
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(timestamp.toString(Qt::SystemLocaleShortDate)));
std::string url = item.scheme + "://" + item.host + ":" + std::to_string(item.port) + item.path;
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::fromStdString(url)));
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.status_code));
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(QString::fromStdString(item.reason)));
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.rtt));
ui->historyHTTPTable->setItem(i,j++,new QTableWidgetItem(item.size));
i++;
}
delete items;
//ui->historyHTTPTable->setItem(0,0,new QTableWidgetItem(QString::fromStdString(flow.request.server_conn_id)));
//ui->historyHTTPTable->setItem(0,1,new QTableWidgetItem(QString::fromStdString(flow.request.method)));
//ui->historyHTTPTable->setItem(0,2,new QTableWidgetItem(QString::fromStdString(flow.request.host)));
//ui->historyHTTPTable->setItem(0,3,new QTableWidgetItem(QString::number(data.ttl)));
history_model.update(current_session->getHistoryItems());
ui->historyHTTPTable->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
}
@ -71,3 +43,7 @@ void MainWindow::on_searchEdit_textEdited(const QString &arg1)
{
emit updateHistory();
}
void MainWindow::on_historyHTTPTable_cellClicked(int row, int column)
{
}

View file

@ -18,6 +18,7 @@ private:
Ui::MainWindow *ui;
QThread* thread;
Session* current_session;
HistoryModel history_model;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
@ -25,4 +26,5 @@ public slots:
void updateHistory();
private slots:
void on_searchEdit_textEdited(const QString &arg1);
void on_historyHTTPTable_cellClicked(int row, int column);
};

View file

@ -73,7 +73,7 @@
<height>100</height>
</size>
</property>
<widget class="QWidget" name="tabWidget_2Page1" native="true">
<widget class="QWidget" name="tabWidget_2Page1">
<attribute name="title">
<string/>
</attribute>
@ -110,7 +110,7 @@
<height>200</height>
</size>
</property>
<widget class="QWidget" name="tabWidgetPage1_2" native="true">
<widget class="QWidget" name="tabWidgetPage1_2">
<attribute name="title">
<string/>
</attribute>
@ -163,7 +163,7 @@
<property name="minimumSize">
<size>
<width>800</width>
<height>100</height>
<height>200</height>
</size>
</property>
<property name="layoutDirection">
@ -179,97 +179,93 @@
<attribute name="title">
<string/>
</attribute>
<widget class="QTableWidget" name="historyHTTPTable">
<property name="geometry">
<rect>
<x>9</x>
<y>40</y>
<width>769</width>
<height>109</height>
</rect>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
<widget class="QLineEdit" name="searchEdit">
<property name="geometry">
<rect>
<x>101</x>
<y>9</y>
<width>142</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="searchBox">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>86</width>
<height>25</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>all</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<widget class="QComboBox" name="searchBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>all</string>
</property>
</item>
<item>
<property name="text">
<string>ID</string>
</property>
</item>
<item>
<property name="text">
<string>Method</string>
</property>
</item>
<item>
<property name="text">
<string>URL</string>
</property>
</item>
<item>
<property name="text">
<string>Code</string>
</property>
</item>
<item>
<property name="text">
<string>Tags</string>
</property>
</item>
</widget>
</item>
<item>
<property name="text">
<string>ID</string>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="searchEdit"/>
</item>
<item>
<property name="text">
<string>Method</string>
</property>
<item row="2" column="0" colspan="2">
<widget class="QTableView" name="historyHTTPTable">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>1</width>
<height>0</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderDefaultSectionSize">
<number>19</number>
</attribute>
</widget>
</item>
<item>
<property name="text">
<string>URL</string>
</property>
</item>
<item>
<property name="text">
<string>Code</string>
</property>
</item>
<item>
<property name="text">
<string>Tags</string>
</property>
</item>
</widget>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
<zorder>tabWidget</zorder>
<zorder>widget_2</zorder>
<zorder>splitter_2</zorder>
<zorder>widget</zorder>
<zorder>splitter</zorder>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
@ -277,7 +273,7 @@
<x>0</x>
<y>0</y>
<width>818</width>
<height>22</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">

View file

@ -9,6 +9,7 @@ class NetworkThread : public QObject
{
Q_OBJECT
private:
std::set<std::string> received;
zmq::context_t context;
zmq::socket_t *socket;
std::set<std::string> accepted_flows;

View file

@ -133,15 +133,16 @@ std::optional<std::string> Session::getSetting(std::string key) {
return std::nullopt;
}
std::vector<http::HistoryItem>* Session::getHistoryItems() {
std::vector<HistoryItem>* Session::getHistoryItems() {
// todo check reset return code
sqlite3_reset(stmt_get_all_history);
std::vector<http::HistoryItem>* result = new std::vector<http::HistoryItem>();
std::vector<HistoryItem>* result = new std::vector<HistoryItem>();
auto rc = sqlite3_step(stmt_get_all_history);
while(rc == SQLITE_ROW) {
int j = 0;
http::HistoryItem i;
HistoryItem i;
i.id = sqlite3_column_int(stmt_get_all_history, j++);
i.timestamp = sqlite3_column_double(stmt_get_all_history, j++);
i.method = std::string((const char*)sqlite3_column_text(stmt_get_all_history, j++));

View file

@ -3,6 +3,7 @@
#include <QObject>
#include <includes.h>
#include <httpflow.h>
#include <historymodel.h>
#include <optional>
class Session : public QObject
@ -103,7 +104,7 @@ public:
void unload();
bool isLoaded();
std::optional<std::string> getSetting(std::string key);
std::vector<http::HistoryItem>* getHistoryItems();
std::vector<HistoryItem>* getHistoryItems();
public slots:
int saveRequest(http::Flow flow);
int saveRequestHeader(std::string key, std::string value, int id);

26
test.sh
View file

@ -1,19 +1,17 @@
#!/bin/sh
mitmdump -k -p 8888 -s mitmaddon/littlesnitch.py &
mitmdump -k -p 1878 -s mitmaddon/littlesnitch.py &
export mitmpid=$!
./build/littlesnitch &
sleep 1
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
killall mitmdump
sleep 5
curl -x http://localhost:1878 -k https://yolo.jetzt
sleep 2
killall mitmdump
sleep 3
killall mitmdump
killall mitmdump
curl -x http://localhost:1878 -k https://get.yolo.jetzt
sleep 2
kill -9 $mitmpid
kill -9 $mitmpid
sleep 2
kill -9 $mitmpid
kill -9 $mitmpid