diff --git a/CMakeLists.txt b/CMakeLists.txt index bbd08b5..4d6057c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,15 +3,21 @@ cmake_minimum_required(VERSION 3.5) project(bigsnitch LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) +# for BSD link_directories(/usr/local/lib) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(PLUGIN_DIR ${CMAKE_BINARY_DIR}/plugins) + find_package(Qt5 COMPONENTS Widgets REQUIRED) find_package(cppzmq REQUIRED) find_package(nlohmann_json REQUIRED) @@ -19,45 +25,65 @@ find_package(SQLite3 REQUIRED) find_package(Catch2 REQUIRED) add_executable(bigsnitch - main.cpp - mainwindow.cpp - networkthread.cpp - session.cpp - httpflow.cpp - historymodel.cpp - editandresend.cpp - addonhandler.cpp - mainwindow.h - httpflow.h - networkthread.h - session.h - includes.h - historymodel.h - editandresend.h - addonhandler.h - include/api.h - include/httpsender.h - include/httpreceiver.h - mainwindow.ui - editandresend.ui -) + main.cpp + mainwindow.cpp + networkthread.cpp + session.cpp + httpflow.cpp + proxyhandler.cpp + historymodel.cpp + editandresend.cpp + settings.cpp + + mainwindow.h + httpflow.h + networkthread.h + session.h + includes.h + proxyhandler.h + historymodel.h + editandresend.h + settings.h + + include/api.h + include/proxyinterface.h + include/httpsender.h + include/httpreceiver.h + + mainwindow.ui + editandresend.ui + settings.ui + ) target_include_directories(bigsnitch PRIVATE /usr/local/include) target_link_libraries(bigsnitch PRIVATE Qt5::Widgets cppzmq sqlite3) add_executable(bigsnitch_tests - tests/generic_tests.cpp - networkthread.cpp -) + tests/generic_tests.cpp + networkthread.cpp + ) target_include_directories(bigsnitch_tests PRIVATE /usr/local/include) target_link_libraries(bigsnitch_tests PRIVATE Qt5::Widgets cppzmq sqlite3 Catch2::Catch2) -file(GLOB_RECURSE addonfiles addons/CMakeLists.txt) -foreach(loopvar IN ITEMS ${addonfiles}) - include(${loopvar}) -endforeach(loopvar) +add_subdirectory(plugins/mitmproxy/) include(CTest) include(Catch) catch_discover_tests(bigsnitch_tests) + +option(BUILD_DOCS "build documentation" ON) +if(BUILD_DOCS) + find_package(Doxygen REQUIRED) + set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in) + set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + + configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) + message("Doxygen build started") + + add_custom_target( doc_doxygen ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" + VERBATIM ) +endif(BUILD_DOCS) diff --git a/addonhandler.cpp b/addonhandler.cpp deleted file mode 100644 index 8df7653..0000000 --- a/addonhandler.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "addonhandler.h" -#include - -AddonHandler::AddonHandler() -{ - -} - -std::optional AddonHandler::load(std::filesystem::path path) -{ - // load library - void* lib = dlopen(path.c_str(), RTLD_LAZY); - if(!lib) { - qDebug() << "addon " << path.c_str() << " not loaded!"; - return std::nullopt; - } - - auto get_name = reinterpret_cast(dlsym(lib, "get_name")); - std::string name; - try { - get_name(); - } catch (...) { - return std::nullopt; - } - auto initialize = reinterpret_cast(dlsym(lib, "initialize")); - try { - if(initialize) { - initialize(); - } - } catch (...) { - return std::nullopt; - } - - on_request.append(name, dlsym(lib, "on_request")); - on_response.append(name, dlsym(lib, "on_response")); - - loaded_addon_paths.insert(std::make_pair(name, path)); - loaded_addon_libs.insert(std::make_pair(name, lib)); - - return name; -} - -void AddonHandler::unload(std::string name) -{ - on_request.remove(name); - on_response.remove(name); - void* lib = loaded_addon_libs.find(name)->second; - auto deinitialize = reinterpret_cast(dlsym(lib, "initialize")); - try { - if(deinitialize) { - deinitialize(); - } - } catch (...) { - qDebug() << "deinitialize failed"; - } -} - -bool AddonHandler::isLoaded(std::string name) -{ - return loaded_addon_libs.count(name); -} - -std::map AddonHandler::loadedAddons() -{ - return std::map(); -} diff --git a/addonhandler.h b/addonhandler.h deleted file mode 100644 index 46457f3..0000000 --- a/addonhandler.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include -#include - -template -class DLWrapper { -private: - std::map funcs; -public: - void append(std::string name, void* ptr) { - if(ptr) { - funcs.insert({name, ptr}); - } - } - - void remove(std::string name) { - for(auto it = funcs.begin(); it != funcs.end(); ) { - if(it->first == name) { - it = funcs.erase(it); - return; - } else { - ++it; - } - } - } - - template - void operator()(Args... args) const { - for(auto fun : funcs) { - (T)(fun)(args...); - } - } -}; - -/* -the addon handler loads addon shared library objects and calls -in every loaded addon the implemented events, when they're implemented. -*/ -class AddonHandler -{ -private: - //list of loaded addons with library pointer - std::map loaded_addon_paths; - std::map loaded_addon_libs; -public: - AddonHandler(); - // loads an addon and returns it's name, if successfully loaded - std::optional load(std::filesystem::path path); - // unload an addon - void unload(std::string name); - // returns whether an addon with name is loaded - bool isLoaded(std::string name); - // returns the list of loaded addons (name, path) - std::map loadedAddons(); - - DLWrapper on_request; - DLWrapper on_response; -}; - diff --git a/addons/yararules/CMakeLists.txt b/addons/yararules/CMakeLists.txt deleted file mode 100644 index 8ea8d34..0000000 --- a/addons/yararules/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -cmake_minimum_required(VERSION 3.9) - -project(yararules VERSION 1.0.0 DESCRIPTION "addon for tagging using yara rules") - -add_library(yararules SHARED ${CMAKE_CURRENT_LIST_DIR}/yararules.cpp) -set_target_properties(yararules PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION 1) -target_include_directories(yararules PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include/) diff --git a/addons/yararules/yararules.cpp b/addons/yararules/yararules.cpp deleted file mode 100644 index 683b3ed..0000000 --- a/addons/yararules/yararules.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -extern "C" const char* get_name() { - return "yararules"; -} diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 0000000..51251cd --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,2 @@ +OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs/ +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/ @CMAKE_CURRENT_SOURCE_DIR@/include/ @CMAKE_CURRENT_SOURCE_DIR@/docs diff --git a/include/api.h b/include/api.h index 6ab935a..e89ae3b 100644 --- a/include/api.h +++ b/include/api.h @@ -7,6 +7,7 @@ #include #include +//! represents one item in the http history. struct HistoryItem { int id = -1; double timestamp = 0; diff --git a/include/proxyinterface.h b/include/proxyinterface.h new file mode 100644 index 0000000..c8f4cfd --- /dev/null +++ b/include/proxyinterface.h @@ -0,0 +1,33 @@ +#pragma once + +#include "include/api.h" +#include + +namespace http { + +#define HTTPProxyInterfaceIID "bigsnitch.api.HTTPProxyInterface/100" + +//! Interface for implementing proxies +/*! + Interface for implementing proxies +*/ +class ProxyInterface { + +public: + virtual ~ProxyInterface() = default; + //! called in a custom thread, may block. + virtual void process(std::string path) = 0; + //! returns, whether the proxy is currently connected + virtual bool connected() = 0; + //! disconnects the handle + virtual void disconnect() = 0; + // options/settings +signals: + void finished(); + void error(QString err); + void message(http::Flow flow); +}; + +} + +Q_DECLARE_INTERFACE(http::ProxyInterface, HTTPProxyInterfaceIID) diff --git a/plugins/mitmproxy/CMakeLists.txt b/plugins/mitmproxy/CMakeLists.txt new file mode 100644 index 0000000..60622dd --- /dev/null +++ b/plugins/mitmproxy/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(mitmproxy_plugin MODULE mitmproxy_network.cpp mitmproxy_network.h) +target_include_directories(mitmproxy_plugin PRIVATE ../../include/) +target_link_libraries(mitmproxy_plugin PRIVATE Qt5::Core) +set_target_properties(mitmproxy_plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_DIR}) diff --git a/plugins/mitmproxy/mitmproxy.json b/plugins/mitmproxy/mitmproxy.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/plugins/mitmproxy/mitmproxy.json @@ -0,0 +1 @@ +{} diff --git a/plugins/mitmproxy/mitmproxy_network.cpp b/plugins/mitmproxy/mitmproxy_network.cpp new file mode 100644 index 0000000..5e1e064 --- /dev/null +++ b/plugins/mitmproxy/mitmproxy_network.cpp @@ -0,0 +1 @@ +#include diff --git a/plugins/mitmproxy/mitmproxy_network.h b/plugins/mitmproxy/mitmproxy_network.h new file mode 100644 index 0000000..7624b4d --- /dev/null +++ b/plugins/mitmproxy/mitmproxy_network.h @@ -0,0 +1,6 @@ +#pragma once + +#include "api.h" +#include + + diff --git a/proxyhandler.cpp b/proxyhandler.cpp new file mode 100644 index 0000000..149a2e3 --- /dev/null +++ b/proxyhandler.cpp @@ -0,0 +1,11 @@ +#include "proxyhandler.h" + +bool PluginHandler::load(std::string path) +{ + +} + +void PluginHandler::loadPlugins(std::string path) +{ + +} diff --git a/proxyhandler.h b/proxyhandler.h new file mode 100644 index 0000000..f5cc65a --- /dev/null +++ b/proxyhandler.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include + +class PluginHandler +{ +public: + bool load(std::string path); + void loadPlugins(std::string path); +}; diff --git a/settings.cpp b/settings.cpp new file mode 100644 index 0000000..8e4d714 --- /dev/null +++ b/settings.cpp @@ -0,0 +1,14 @@ +#include "settings.h" +#include "ui_settings.h" + +Settings::Settings(QWidget *parent) : + QWidget(parent), + ui(new Ui::Settings) +{ + ui->setupUi(this); +} + +Settings::~Settings() +{ + delete ui; +} diff --git a/settings.h b/settings.h new file mode 100644 index 0000000..89099be --- /dev/null +++ b/settings.h @@ -0,0 +1,22 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include + +namespace Ui { +class Settings; +} + +class Settings : public QWidget +{ + Q_OBJECT + +public: + explicit Settings(QWidget *parent = nullptr); + ~Settings(); + +private: + Ui::Settings *ui; +}; + +#endif // SETTINGS_H diff --git a/settings.ui b/settings.ui new file mode 100644 index 0000000..563fe36 --- /dev/null +++ b/settings.ui @@ -0,0 +1,19 @@ + + + Settings + + + + 0 + 0 + 747 + 625 + + + + Form + + + + +