doxygen support added, mitmproxy plugin migration started

This commit is contained in:
Tim Blume 2021-01-06 22:43:48 +01:00
parent ff5081e8cf
commit 44709f0498
17 changed files with 180 additions and 170 deletions

View file

@ -3,15 +3,21 @@ cmake_minimum_required(VERSION 3.5)
project(bigsnitch LANGUAGES CXX) project(bigsnitch LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
# for BSD
link_directories(/usr/local/lib) link_directories(/usr/local/lib)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) 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(Qt5 COMPONENTS Widgets REQUIRED)
find_package(cppzmq REQUIRED) find_package(cppzmq REQUIRED)
find_package(nlohmann_json REQUIRED) find_package(nlohmann_json REQUIRED)
@ -19,45 +25,65 @@ find_package(SQLite3 REQUIRED)
find_package(Catch2 REQUIRED) find_package(Catch2 REQUIRED)
add_executable(bigsnitch add_executable(bigsnitch
main.cpp main.cpp
mainwindow.cpp mainwindow.cpp
networkthread.cpp networkthread.cpp
session.cpp session.cpp
httpflow.cpp httpflow.cpp
historymodel.cpp proxyhandler.cpp
editandresend.cpp historymodel.cpp
addonhandler.cpp editandresend.cpp
mainwindow.h settings.cpp
httpflow.h
networkthread.h mainwindow.h
session.h httpflow.h
includes.h networkthread.h
historymodel.h session.h
editandresend.h includes.h
addonhandler.h proxyhandler.h
include/api.h historymodel.h
include/httpsender.h editandresend.h
include/httpreceiver.h settings.h
mainwindow.ui
editandresend.ui 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_include_directories(bigsnitch PRIVATE /usr/local/include)
target_link_libraries(bigsnitch PRIVATE Qt5::Widgets cppzmq sqlite3) target_link_libraries(bigsnitch PRIVATE Qt5::Widgets cppzmq sqlite3)
add_executable(bigsnitch_tests add_executable(bigsnitch_tests
tests/generic_tests.cpp tests/generic_tests.cpp
networkthread.cpp networkthread.cpp
) )
target_include_directories(bigsnitch_tests PRIVATE /usr/local/include) target_include_directories(bigsnitch_tests PRIVATE /usr/local/include)
target_link_libraries(bigsnitch_tests PRIVATE Qt5::Widgets cppzmq sqlite3 Catch2::Catch2) target_link_libraries(bigsnitch_tests PRIVATE Qt5::Widgets cppzmq sqlite3 Catch2::Catch2)
file(GLOB_RECURSE addonfiles addons/CMakeLists.txt) add_subdirectory(plugins/mitmproxy/)
foreach(loopvar IN ITEMS ${addonfiles})
include(${loopvar})
endforeach(loopvar)
include(CTest) include(CTest)
include(Catch) include(Catch)
catch_discover_tests(bigsnitch_tests) 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)

View file

@ -1,66 +0,0 @@
#include "addonhandler.h"
#include <dlfcn.h>
AddonHandler::AddonHandler()
{
}
std::optional<std::string> 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<const char*(*)()>(dlsym(lib, "get_name"));
std::string name;
try {
get_name();
} catch (...) {
return std::nullopt;
}
auto initialize = reinterpret_cast<const char*(*)()>(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<const char*(*)()>(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<std::string, std::filesystem::path> AddonHandler::loadedAddons()
{
return std::map<std::string, std::filesystem::path>();
}

View file

@ -1,61 +0,0 @@
#pragma once
#include <includes.h>
#include <dlfcn.h>
#include <functional>
template <typename T>
class DLWrapper {
private:
std::map<std::string, void*> 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<typename ...Args>
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<std::string, std::filesystem::path> loaded_addon_paths;
std::map<std::string, void*> loaded_addon_libs;
public:
AddonHandler();
// loads an addon and returns it's name, if successfully loaded
std::optional<std::string> 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<std::string, std::filesystem::path> loadedAddons();
DLWrapper<void(*)(int)> on_request;
DLWrapper<void(*)(int)> on_response;
};

View file

@ -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/)

View file

@ -1,5 +0,0 @@
#pragma once
extern "C" const char* get_name() {
return "yararules";
}

2
docs/Doxyfile.in Normal file
View file

@ -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

View file

@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
//! represents one item in the http history.
struct HistoryItem { struct HistoryItem {
int id = -1; int id = -1;
double timestamp = 0; double timestamp = 0;

33
include/proxyinterface.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include "include/api.h"
#include <QObject>
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)

View file

@ -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})

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1 @@
#include <mitmproxy_network.h>

View file

@ -0,0 +1,6 @@
#pragma once
#include "api.h"
#include <QObject>

11
proxyhandler.cpp Normal file
View file

@ -0,0 +1,11 @@
#include "proxyhandler.h"
bool PluginHandler::load(std::string path)
{
}
void PluginHandler::loadPlugins(std::string path)
{
}

11
proxyhandler.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include <include/api.h>
#include <include/proxyinterface.h>
class PluginHandler
{
public:
bool load(std::string path);
void loadPlugins(std::string path);
};

14
settings.cpp Normal file
View file

@ -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;
}

22
settings.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QWidget>
namespace Ui {
class Settings;
}
class Settings : public QWidget
{
Q_OBJECT
public:
explicit Settings(QWidget *parent = nullptr);
~Settings();
private:
Ui::Settings *ui;
};
#endif // SETTINGS_H

19
settings.ui Normal file
View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Settings</class>
<widget class="QWidget" name="Settings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>747</width>
<height>625</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
</widget>
<resources/>
<connections/>
</ui>