sqlite eingebaut
This commit is contained in:
parent
d8b52dcb44
commit
075ada7d3e
4 changed files with 265 additions and 109 deletions
142
httpflow.h
142
httpflow.h
|
@ -7,24 +7,24 @@
|
||||||
{
|
{
|
||||||
"flow": {
|
"flow": {
|
||||||
"client_conn": {
|
"client_conn": {
|
||||||
"address": [
|
"address": [
|
||||||
"::1",
|
"::1",
|
||||||
37570,
|
37570,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
],
|
],
|
||||||
"alpn_proto_negotiated": "http/1.1",
|
"alpn_proto_negotiated": "http/1.1",
|
||||||
"cipher_name": "TLS_AES_256_GCM_SHA384",
|
"cipher_name": "TLS_AES_256_GCM_SHA384",
|
||||||
"clientcert": null,
|
"clientcert": null,
|
||||||
"id": "a1e82917-2d58-4b99-be9e-2b962bc499b2",
|
"id": "a1e82917-2d58-4b99-be9e-2b962bc499b2",
|
||||||
"mitmcert": "mitmcertstring",
|
"mitmcert": "mitmcertstring",
|
||||||
"sni": "yolo.jetzt",
|
"sni": "yolo.jetzt",
|
||||||
"timestamp_end": null,
|
"timestamp_end": null,
|
||||||
"timestamp_start": 1597284668.6260498,
|
"timestamp_start": 1597284668.6260498,
|
||||||
"timestamp_tls_setup": 1597284669.8449724,
|
"timestamp_tls_setup": 1597284669.8449724,
|
||||||
"tls_established": true,
|
"tls_established": true,
|
||||||
"tls_extensions": [...],
|
"tls_extensions": [...],
|
||||||
"tls_version": "TLSv1.3"
|
"tls_version": "TLSv1.3"
|
||||||
},
|
},
|
||||||
"error": null,
|
"error": null,
|
||||||
"id": "a6aa4e6e-ca31-4f58-bf47-2da7bfcf0000",
|
"id": "a6aa4e6e-ca31-4f58-bf47-2da7bfcf0000",
|
||||||
|
@ -33,56 +33,56 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"mode": "transparent",
|
"mode": "transparent",
|
||||||
"request": {
|
"request": {
|
||||||
"content": "",
|
"content": "",
|
||||||
"first_line_format": "relative",
|
"first_line_format": "relative",
|
||||||
"headers": [
|
"headers": [
|
||||||
[
|
[
|
||||||
"Host",
|
"Host",
|
||||||
"yolo.jetzt"
|
"yolo.jetzt"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"User-Agent",
|
"User-Agent",
|
||||||
"curl/7.68.0"
|
"curl/7.68.0"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Accept",
|
"Accept",
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"host": "yolo.jetzt",
|
"host": "yolo.jetzt",
|
||||||
"http_version": "HTTP/1.1",
|
"http_version": "HTTP/1.1",
|
||||||
"is_replay": false,
|
"is_replay": false,
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"path": "/",
|
"path": "/",
|
||||||
"port": 443,
|
"port": 443,
|
||||||
"scheme": "https",
|
"scheme": "https",
|
||||||
"timestamp_end": 1597284669.92817,
|
"timestamp_end": 1597284669.92817,
|
||||||
"timestamp_start": 1597284669.8761458
|
"timestamp_start": 1597284669.8761458
|
||||||
},
|
},
|
||||||
"response": null,
|
"response": null,
|
||||||
"server_conn": {
|
"server_conn": {
|
||||||
"address": [
|
"address": [
|
||||||
"yolo.jetzt",
|
"yolo.jetzt",
|
||||||
443
|
443
|
||||||
],
|
],
|
||||||
"alpn_proto_negotiated": "http/1.1",
|
"alpn_proto_negotiated": "http/1.1",
|
||||||
"cert": "certstring",
|
"cert": "certstring",
|
||||||
"id": "50a3b79d-2912-45f3-991b-c03406a1018f",
|
"id": "50a3b79d-2912-45f3-991b-c03406a1018f",
|
||||||
"ip_address": [
|
"ip_address": [
|
||||||
"95.156.226.69",
|
"95.156.226.69",
|
||||||
443
|
443
|
||||||
],
|
],
|
||||||
"sni": "yolo.jetzt",
|
"sni": "yolo.jetzt",
|
||||||
"source_address": [
|
"source_address": [
|
||||||
"192.168.42.102",
|
"192.168.42.102",
|
||||||
44949
|
44949
|
||||||
],
|
],
|
||||||
"timestamp_end": null,
|
"timestamp_end": null,
|
||||||
"timestamp_start": 1597284669.2133315,
|
"timestamp_start": 1597284669.2133315,
|
||||||
"timestamp_tcp_setup": 1597284669.2892282,
|
"timestamp_tcp_setup": 1597284669.2892282,
|
||||||
"timestamp_tls_setup": 1597284669.584602,
|
"timestamp_tls_setup": 1597284669.584602,
|
||||||
"tls_established": true,
|
"tls_established": true,
|
||||||
"tls_version": "TLSv1.2",
|
"tls_version": "TLSv1.2",
|
||||||
"via": null
|
"via": null
|
||||||
},
|
},
|
||||||
"type": "http",
|
"type": "http",
|
||||||
"version": 7
|
"version": 7
|
||||||
|
@ -117,7 +117,15 @@ struct Request
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Response {};
|
struct Response {
|
||||||
|
int status_code;
|
||||||
|
std::string http_version;
|
||||||
|
std::string reason;
|
||||||
|
std::string content;
|
||||||
|
double timestamp_start;
|
||||||
|
double timestamp_end;
|
||||||
|
std::vector<std::tuple<std::string,std::string>> headers;
|
||||||
|
};
|
||||||
|
|
||||||
struct Flow {
|
struct Flow {
|
||||||
Request request;
|
Request request;
|
||||||
|
@ -144,7 +152,7 @@ inline void from_json(const json& j, Flow& flow) {
|
||||||
j.at("flow").at("request").at("method").get_to(flow.request.method);
|
j.at("flow").at("request").at("method").get_to(flow.request.method);
|
||||||
j.at("flow").at("request").at("http_version").get_to(flow.request.http_version);
|
j.at("flow").at("request").at("http_version").get_to(flow.request.http_version);
|
||||||
|
|
||||||
//j.at("server_conn").at("address").get_to(flow.server_conn_address);
|
//j.at("server_conn").at("address").get_to(flow.server_conn_address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
//major minor patch
|
||||||
|
#define LITTLESNITCH_VERSION 010
|
||||||
|
|
118
session.cpp
118
session.cpp
|
@ -9,29 +9,133 @@ Session::~Session() {
|
||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::open_db(std::filesystem::path path) {
|
||||||
void Session::load(std::filesystem::path path)
|
|
||||||
{
|
|
||||||
if(db) {
|
if(db) {
|
||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rc = sqlite3_open(path.c_str(), &db);
|
auto rc = sqlite3_open(path.c_str(), &db);
|
||||||
if(rc) {
|
if(rc != SQLITE_OK) {
|
||||||
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::prepare(const char* query, sqlite3_stmt** stmt) {
|
||||||
|
auto rc = sqlite3_prepare_v2(db, query, strlen(query), stmt, 0);
|
||||||
|
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
qDebug() << "cannot prepare statement";
|
||||||
|
qDebug() << query;
|
||||||
|
qDebug() << sqlite3_errmsg(db);
|
||||||
|
unload();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Session::prepare_and_exec(const char* query) {
|
||||||
|
sqlite3_stmt* res;
|
||||||
|
prepare(query, &res);
|
||||||
|
bool result = sqlite3_step(res)==SQLITE_OK;
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::prepare_tables() {
|
||||||
|
sqlite3_stmt* res;
|
||||||
|
|
||||||
|
prepare(check_tbl, &res);
|
||||||
|
auto s = "session";
|
||||||
|
sqlite3_bind_text(res, 1, s, strlen(s), nullptr);
|
||||||
|
auto rc = sqlite3_step(res);
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
|
||||||
|
if(rc == SQLITE_ROW) {
|
||||||
|
prepare(check_session_info, &res);
|
||||||
|
auto v = "version";
|
||||||
|
sqlite3_bind_text(res, 1, v, strlen(v), nullptr);
|
||||||
|
rc = sqlite3_step(res);
|
||||||
|
|
||||||
|
if(rc == SQLITE_ROW) {
|
||||||
|
const char* version = (const char*)sqlite3_column_text(res, 1);
|
||||||
|
if(std::atoi(version) != LITTLESNITCH_VERSION) {
|
||||||
|
qDebug() << "version " << version << " is not supported!";
|
||||||
|
unload();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "loaded session with version " << version;
|
||||||
|
sqlite3_finalize(res);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qDebug("broken database, was not able to check session info");
|
||||||
|
qDebug() << sqlite3_errmsg(db);
|
||||||
|
unload();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_and_exec(create_request_tbl);
|
||||||
|
prepare_and_exec(create_request_header_tbl);
|
||||||
|
prepare_and_exec(create_response_tbl);
|
||||||
|
prepare_and_exec(create_response_header_tbl);
|
||||||
|
prepare_and_exec(create_flow_tbl);
|
||||||
|
prepare_and_exec(create_session_tbl);
|
||||||
|
|
||||||
|
prepare(last_inserted_id, &stmt_last_inserted_id);
|
||||||
|
prepare(insert_request, &stmt_insert_request);
|
||||||
|
prepare(insert_request_header, &stmt_insert_request_header);
|
||||||
|
prepare(insert_response, &stmt_insert_response);
|
||||||
|
prepare(insert_response_header, &stmt_insert_response_header);
|
||||||
|
prepare(insert_flow, &stmt_insert_flow);
|
||||||
|
prepare(insert_session, &stmt_insert_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::load(std::filesystem::path path)
|
||||||
|
{
|
||||||
|
open_db(path);
|
||||||
|
prepare_tables();
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::unload() {
|
void Session::unload() {
|
||||||
if(db) {
|
if(db) {
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
}
|
}
|
||||||
|
loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Session::isLoaded() {
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::bind_text(sqlite3_stmt* stmt, int id, std::string text) {
|
||||||
|
qDebug() << id << " " << text.c_str() << " " << strlen(text.c_str());
|
||||||
|
sqlite3_bind_text(stmt, id, text.c_str(), -1, SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::saveRequest(http::Flow flow) {
|
void Session::saveRequest(http::Flow flow) {
|
||||||
// todo
|
bind_text(stmt_insert_request, 1, flow.request.server_conn_id);
|
||||||
|
bind_text(stmt_insert_request, 2, flow.request.server_ip_address);
|
||||||
|
sqlite3_bind_int(stmt_insert_request, 3, flow.request.tls);
|
||||||
|
bind_text(stmt_insert_request, 4, flow.request.content);
|
||||||
|
bind_text(stmt_insert_request, 5, flow.request.scheme);
|
||||||
|
bind_text(stmt_insert_request, 6, flow.request.method);
|
||||||
|
bind_text(stmt_insert_request, 7, flow.request.host);
|
||||||
|
bind_text(stmt_insert_request, 8, flow.request.address);
|
||||||
|
sqlite3_bind_int(stmt_insert_request, 9, flow.request.port);
|
||||||
|
bind_text(stmt_insert_request, 10, flow.request.http_version);
|
||||||
|
bind_text(stmt_insert_request, 11, flow.request.path);
|
||||||
|
sqlite3_bind_double(stmt_insert_request, 12, flow.request.timestamp_start);
|
||||||
|
sqlite3_bind_double(stmt_insert_request, 13, flow.request.timestamp_end);
|
||||||
|
bind_text(stmt_insert_request, 14, flow.request.error);
|
||||||
|
auto rc = sqlite3_step(stmt_insert_request);
|
||||||
|
sqlite3_reset(stmt_insert_request);
|
||||||
|
if(rc != SQLITE_DONE) {
|
||||||
|
qDebug() << "inserting request failed" << rc;
|
||||||
|
qDebug() << sqlite3_errmsg(db);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
111
session.h
111
session.h
|
@ -4,50 +4,91 @@
|
||||||
#include <includes.h>
|
#include <includes.h>
|
||||||
#include <httpflow.h>
|
#include <httpflow.h>
|
||||||
|
|
||||||
// static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
|
||||||
// int i;
|
|
||||||
// for(i=0; i<argc; i++){
|
|
||||||
// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
|
||||||
// }
|
|
||||||
// printf("\n");
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// int main(int argc, char **argv){
|
|
||||||
// sqlite3 *db;
|
|
||||||
// char *zErrMsg = 0;
|
|
||||||
// int rc;
|
|
||||||
//
|
|
||||||
// if( argc!=3 ){
|
|
||||||
// fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
|
|
||||||
// return(1);
|
|
||||||
// }
|
|
||||||
// rc = sqlite3_open(argv[1], &db);
|
|
||||||
// if( rc ){
|
|
||||||
// fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
|
||||||
// sqlite3_close(db);
|
|
||||||
// return(1);
|
|
||||||
// }
|
|
||||||
// rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
|
|
||||||
// if( rc!=SQLITE_OK ){
|
|
||||||
// fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
|
||||||
// sqlite3_free(zErrMsg);
|
|
||||||
// }
|
|
||||||
// sqlite3_close(db);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
class Session : public QObject
|
class Session : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
|
const char* create_request_tbl = R"rstr( CREATE TABLE request(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
server_conn_id TEXT,
|
||||||
|
server_ip_address TEXT,
|
||||||
|
tls INTEGER,
|
||||||
|
content TEXT,
|
||||||
|
scheme TEXT,
|
||||||
|
method TEXT,
|
||||||
|
host TEXT,
|
||||||
|
address TEXT,
|
||||||
|
port INTEGER,
|
||||||
|
http_version TEXT,
|
||||||
|
path TEXT,
|
||||||
|
timestamp_start REAL,
|
||||||
|
timestamp_end REAL,
|
||||||
|
error TEXT
|
||||||
|
); )rstr";
|
||||||
|
const char* create_request_header_tbl = R"rstr( CREATE TABLE request_header(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
key TEXT,
|
||||||
|
value TEXT,
|
||||||
|
request_id INTEGER,
|
||||||
|
FOREIGN KEY(request_id) REFERENCES request(referer_id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||||
|
); )rstr";
|
||||||
|
const char* create_response_tbl = R"rstr( CREATE TABLE response(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
status_code INTEGER,
|
||||||
|
http_version TEXT,
|
||||||
|
reason TEXT,
|
||||||
|
content TEXT,
|
||||||
|
timestamp_start REAL,
|
||||||
|
timestamp_end REAL
|
||||||
|
); )rstr";
|
||||||
|
const char* create_response_header_tbl = R"rstr( CREATE TABLE response_header(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
key TEXT,
|
||||||
|
value TEXT,
|
||||||
|
response_id INTEGER,
|
||||||
|
FOREIGN KEY(response_id) REFERENCES response(referer_id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||||
|
); )rstr";
|
||||||
|
const char* create_flow_tbl = R"rstr( CREATE TABLE flow(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
request_id INTEGER,
|
||||||
|
response_id INTEGER,
|
||||||
|
FOREIGN KEY(request_id) REFERENCES request(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY(response_id) REFERENCES response(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||||
|
); )rstr";
|
||||||
|
const char* create_session_tbl = R"rstr( CREATE TABLE session(
|
||||||
|
key TEXT UNIQUE NOT NULL PRIMARY KEY,
|
||||||
|
value TEXT
|
||||||
|
); )rstr";
|
||||||
|
const char* last_inserted_id = R"rstr( SELECT last_insert_rowid(); )rstr";
|
||||||
|
const char* check_tbl = R"rstr( SELECT name FROM sqlite_master WHERE type='table' AND name=?; )rstr";
|
||||||
|
const char* check_session_info = R"rstr( SELECT value FROM session WHERE key=?; )rstr";
|
||||||
|
const char* insert_request = R"rstr( INSERT INTO request (server_conn_id, server_ip_address, tls, content, scheme, method, host, address, port, http_version, path, timestamp_start, timestamp_end, error) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?); )rstr";
|
||||||
|
const char* insert_request_header = R"rstr( INSERT INTO request_header (key, value, request_id) VALUES (?,?,?); )rstr";
|
||||||
|
const char* insert_response = R"rstr( INSERT INTO response (status_code, http_version, reason, content, timestamp_start, timestamp_end) VALUES (?,?,?,?,?,?); )rstr";
|
||||||
|
const char* insert_response_header = R"rstr( INSERT INTO response_header (key, value, response_id) VALUES (?,?,?); )rstr";
|
||||||
|
const char* insert_flow = R"rstr( INSERT INTO flow (request_id, response_id) VALUES (?,?); )rstr";
|
||||||
|
const char* insert_session = R"rstr( INSERT INTO session (key, value) VALUES (?,?); )rstr";
|
||||||
|
|
||||||
sqlite3* db = nullptr;
|
sqlite3* db = nullptr;
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
|
|
||||||
|
sqlite3_stmt* stmt_last_inserted_id = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_request = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_request_header = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_response = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_response_header = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_flow = nullptr;
|
||||||
|
sqlite3_stmt* stmt_insert_session = nullptr;
|
||||||
|
|
||||||
|
void open_db(std::filesystem::path path);
|
||||||
|
void prepare_tables();
|
||||||
|
void prepare(const char* query, sqlite3_stmt** stmt);
|
||||||
|
bool prepare_and_exec(const char* query);
|
||||||
|
void bind_text(sqlite3_stmt* stmt, int id, std::string text);
|
||||||
public:
|
public:
|
||||||
explicit Session(QObject *parent = nullptr);
|
explicit Session(QObject *parent = nullptr);
|
||||||
~Session();
|
~Session();
|
||||||
|
|
||||||
void load(std::filesystem::path path);
|
void load(std::filesystem::path path);
|
||||||
void unload();
|
void unload();
|
||||||
bool isLoaded();
|
bool isLoaded();
|
||||||
|
|
Loading…
Reference in a new issue