diff --git a/httpflow.h b/httpflow.h index 70d817e..a0a64bd 100644 --- a/httpflow.h +++ b/httpflow.h @@ -7,24 +7,24 @@ { "flow": { "client_conn": { - "address": [ - "::1", - 37570, - 0, - 0 - ], - "alpn_proto_negotiated": "http/1.1", - "cipher_name": "TLS_AES_256_GCM_SHA384", - "clientcert": null, - "id": "a1e82917-2d58-4b99-be9e-2b962bc499b2", - "mitmcert": "mitmcertstring", - "sni": "yolo.jetzt", - "timestamp_end": null, - "timestamp_start": 1597284668.6260498, - "timestamp_tls_setup": 1597284669.8449724, - "tls_established": true, - "tls_extensions": [...], - "tls_version": "TLSv1.3" + "address": [ + "::1", + 37570, + 0, + 0 + ], + "alpn_proto_negotiated": "http/1.1", + "cipher_name": "TLS_AES_256_GCM_SHA384", + "clientcert": null, + "id": "a1e82917-2d58-4b99-be9e-2b962bc499b2", + "mitmcert": "mitmcertstring", + "sni": "yolo.jetzt", + "timestamp_end": null, + "timestamp_start": 1597284668.6260498, + "timestamp_tls_setup": 1597284669.8449724, + "tls_established": true, + "tls_extensions": [...], + "tls_version": "TLSv1.3" }, "error": null, "id": "a6aa4e6e-ca31-4f58-bf47-2da7bfcf0000", @@ -33,56 +33,56 @@ "metadata": {}, "mode": "transparent", "request": { - "content": "", - "first_line_format": "relative", - "headers": [ - [ - "Host", - "yolo.jetzt" - ], - [ - "User-Agent", - "curl/7.68.0" - ], - [ - "Accept", - ] - ], - "host": "yolo.jetzt", - "http_version": "HTTP/1.1", - "is_replay": false, - "method": "GET", - "path": "/", - "port": 443, - "scheme": "https", - "timestamp_end": 1597284669.92817, - "timestamp_start": 1597284669.8761458 + "content": "", + "first_line_format": "relative", + "headers": [ + [ + "Host", + "yolo.jetzt" + ], + [ + "User-Agent", + "curl/7.68.0" + ], + [ + "Accept", + ] + ], + "host": "yolo.jetzt", + "http_version": "HTTP/1.1", + "is_replay": false, + "method": "GET", + "path": "/", + "port": 443, + "scheme": "https", + "timestamp_end": 1597284669.92817, + "timestamp_start": 1597284669.8761458 }, "response": null, "server_conn": { - "address": [ - "yolo.jetzt", - 443 - ], - "alpn_proto_negotiated": "http/1.1", - "cert": "certstring", - "id": "50a3b79d-2912-45f3-991b-c03406a1018f", - "ip_address": [ - "95.156.226.69", - 443 - ], - "sni": "yolo.jetzt", - "source_address": [ - "192.168.42.102", - 44949 - ], - "timestamp_end": null, - "timestamp_start": 1597284669.2133315, - "timestamp_tcp_setup": 1597284669.2892282, - "timestamp_tls_setup": 1597284669.584602, - "tls_established": true, - "tls_version": "TLSv1.2", - "via": null + "address": [ + "yolo.jetzt", + 443 + ], + "alpn_proto_negotiated": "http/1.1", + "cert": "certstring", + "id": "50a3b79d-2912-45f3-991b-c03406a1018f", + "ip_address": [ + "95.156.226.69", + 443 + ], + "sni": "yolo.jetzt", + "source_address": [ + "192.168.42.102", + 44949 + ], + "timestamp_end": null, + "timestamp_start": 1597284669.2133315, + "timestamp_tcp_setup": 1597284669.2892282, + "timestamp_tls_setup": 1597284669.584602, + "tls_established": true, + "tls_version": "TLSv1.2", + "via": null }, "type": "http", "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> headers; +}; struct Flow { 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("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); } } diff --git a/includes.h b/includes.h index 268d0ba..b049085 100644 --- a/includes.h +++ b/includes.h @@ -8,3 +8,6 @@ #include using json = nlohmann::json; + +//major minor patch +#define LITTLESNITCH_VERSION 010 diff --git a/session.cpp b/session.cpp index 888818f..a323067 100644 --- a/session.cpp +++ b/session.cpp @@ -9,29 +9,133 @@ Session::~Session() { unload(); } - -void Session::load(std::filesystem::path path) -{ +void Session::open_db(std::filesystem::path path) { if(db) { unload(); } + auto rc = sqlite3_open(path.c_str(), &db); - if(rc) { + if(rc != SQLITE_OK) { qDebug("cannot open database"); qDebug() << sqlite3_errmsg(db); unload(); 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() { if(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) { - // 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; + } } diff --git a/session.h b/session.h index af1e345..1629b9e 100644 --- a/session.h +++ b/session.h @@ -4,50 +4,91 @@ #include #include -// static int callback(void *NotUsed, int argc, char **argv, char **azColName){ -// int i; -// for(i=0; i