Skip to content
API Documentation
BastionGuard™
Config.cpp
Go to the documentation of this file.
2#include <filesystem>
3#include <fstream>
4#include <iomanip>
5#include <nlohmann/json.hpp>
6#include <sstream>
7#include <cstdlib>
8#include <stdexcept>
9
10namespace bsc::config {
11using json = nlohmann::json;
12
13namespace {
14std::string expand_path(std::string path) {
15 if (path.empty()) return path;
16 if (path[0] == '~') {
17 if (const char* home = std::getenv("HOME")) path.replace(0, 1, home);
18 }
19 return path;
20}
21
22nlohmann::json to_json(const Config& cfg) {
23 return nlohmann::json{
24 {"LogLevel", cfg.log_level},
25 {"Firewall", cfg.firewall},
26 {"DefaultAction", cfg.default_action},
27 {"DefaultDuration", cfg.default_duration},
28 {"ProcMonitorMethod", cfg.proc_monitor_method},
29 {"EBPFObjPath", cfg.ebpf_obj_path},
30 {"InterceptUnknown", cfg.intercept_unknown},
31 {"LogUTC", cfg.log_utc},
32 {"LogMicro", cfg.log_micro},
33 {"Server", {{"Address", cfg.server.address}, {"LogFile", cfg.server.log_file}, {"Authentication", {{"Type", cfg.server.authentication.type}}}}},
34 {"Rules", {{"Path", cfg.rules.path}, {"EnableChecksums", cfg.rules.enable_checksums}}},
35 {"FwOptions", {{"ConfigPath", cfg.fw_options.config_path}, {"MonitorInterval", cfg.fw_options.monitor_interval}, {"QueueNum", cfg.fw_options.queue_num}, {"QueueBypass", cfg.fw_options.queue_bypass}}},
36 {"Stats", {{"MaxEvents", cfg.stats.max_events}, {"MaxStats", cfg.stats.max_stats}, {"Workers", cfg.stats.workers}}},
37 {"Internal", {{"GCPercent", cfg.internal.gc_percent}, {"FlushConnsOnStart", cfg.internal.flush_conns_on_start}}},
38 {"Tasks", {{"ConfigPath", cfg.tasks.config_path}}}
39 };
40}
41}
42
43std::string read_file(const std::string& path) {
44 std::ifstream in(path);
45 if (!in) throw std::runtime_error("cannot open config file: " + path);
46 std::ostringstream ss;
47 ss << in.rdbuf();
48 return ss.str();
49}
50
51Config load_file(const std::string& path) {
52 Config cfg;
53 cfg.source_path = expand_path(path);
54 auto raw = read_file(cfg.source_path);
55 auto j = json::parse(raw);
56 cfg.log_level = j.value("LogLevel", cfg.log_level);
57 cfg.firewall = j.value("Firewall", cfg.firewall);
58 cfg.default_action = j.value("DefaultAction", cfg.default_action);
59 cfg.default_duration = j.value("DefaultDuration", cfg.default_duration);
60 cfg.proc_monitor_method = j.value("ProcMonitorMethod", cfg.proc_monitor_method);
61 cfg.ebpf_obj_path = j.value("EBPFObjPath", cfg.ebpf_obj_path);
62 cfg.intercept_unknown = j.value("InterceptUnknown", cfg.intercept_unknown);
63 cfg.log_utc = j.value("LogUTC", cfg.log_utc);
64 cfg.log_micro = j.value("LogMicro", cfg.log_micro);
65 if (j.contains("Server")) {
66 const auto& s = j["Server"];
67 cfg.server.address = expand_path(s.value("Address", cfg.server.address));
68 cfg.server.log_file = expand_path(s.value("LogFile", cfg.server.log_file));
69 if (s.contains("Authentication")) {
70 const auto& a = s["Authentication"];
71 cfg.server.authentication.type = a.value("Type", cfg.server.authentication.type);
72 }
73 }
74 if (j.contains("Rules")) {
75 const auto& r = j["Rules"];
76 cfg.rules.path = expand_path(r.value("Path", cfg.rules.path));
77 cfg.rules.enable_checksums = r.value("EnableChecksums", cfg.rules.enable_checksums);
78 }
79 if (j.contains("FwOptions")) {
80 const auto& f = j["FwOptions"];
81 cfg.fw_options.config_path = expand_path(f.value("ConfigPath", cfg.fw_options.config_path));
82 cfg.fw_options.monitor_interval = f.value("MonitorInterval", cfg.fw_options.monitor_interval);
83 cfg.fw_options.queue_num = f.value("QueueNum", cfg.fw_options.queue_num);
84 cfg.fw_options.queue_bypass = f.value("QueueBypass", cfg.fw_options.queue_bypass);
85 }
86 if (j.contains("Stats")) {
87 const auto& s = j["Stats"];
88 cfg.stats.max_events = s.value("MaxEvents", cfg.stats.max_events);
89 cfg.stats.max_stats = s.value("MaxStats", cfg.stats.max_stats);
90 cfg.stats.workers = s.value("Workers", cfg.stats.workers);
91 }
92 if (j.contains("Internal")) {
93 const auto& i = j["Internal"];
94 cfg.internal.gc_percent = i.value("GCPercent", cfg.internal.gc_percent);
95 cfg.internal.flush_conns_on_start = i.value("FlushConnsOnStart", cfg.internal.flush_conns_on_start);
96 }
97 if (j.contains("Tasks")) {
98 const auto& t = j["Tasks"];
99 cfg.tasks.config_path = expand_path(t.value("ConfigPath", cfg.tasks.config_path));
100 }
101 return cfg;
102}
103
104bool save_file(const Config& cfg, const std::string& path) {
105 const auto out_path = expand_path(path);
106 std::filesystem::create_directories(std::filesystem::path(out_path).parent_path());
107 std::ofstream out(out_path);
108 if (!out) return false;
109 out << std::setw(2) << to_json(cfg) << "\n";
110 return true;
111}
112
113} // namespace bsc::config
nlohmann::json to_json(const Config &cfg)
Definition Config.cpp:22
std::string expand_path(std::string path)
Definition Config.cpp:14
nlohmann::json json
Definition Config.cpp:11
bool save_file(const Config &cfg, const std::string &path)
Definition Config.cpp:104
std::string read_file(const std::string &path)
Definition Config.cpp:43
Config load_file(const std::string &path)
Definition Config.cpp:51
StatsOptions stats
Definition Config.hpp:60
RulesOptions rules
Definition Config.hpp:58
std::string default_duration
Definition Config.hpp:53
std::string proc_monitor_method
Definition Config.hpp:54
std::string firewall
Definition Config.hpp:51
InternalOptions internal
Definition Config.hpp:59
std::int32_t log_level
Definition Config.hpp:50
std::string ebpf_obj_path
Definition Config.hpp:55
FwOptions fw_options
Definition Config.hpp:56
TasksOptions tasks
Definition Config.hpp:61
std::string source_path
Definition Config.hpp:49
ServerConfig server
Definition Config.hpp:57
std::string default_action
Definition Config.hpp:52