Skip to content
API Documentation
BastionGuard™
AlertApp Class Reference

Public Member Functions

 AlertApp ()
int run (int argc, char *argv[])
 AlertApp ()
 ~AlertApp ()
int run (int argc, char *argv[])

Private Member Functions

void on_method_call (const Glib::RefPtr< Gio::DBus::Connection > &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &method, const Glib::VariantContainerBase &params, const Glib::RefPtr< Gio::DBus::MethodInvocation > &inv)
void show_next ()
void resolve_paths ()
void log_user (const std::string &msg)
void ensure_user_token ()
void load_token ()
void load_css ()
void start_tcp_listener ()
void stop_listener ()
void enqueue_alert (const std::string &file, const std::string &family)
void show_next ()

Private Attributes

Glib::RefPtr< Gtk::Application > app
std::queue< std::pair< std::string, std::string > > queue
AlertWindow * current_window = nullptr
std::queue< std::pair< std::string, std::string > > alertQueue
std::unique_ptr< AlertWindowRealtime > current_window
std::string SECURITY_TOKEN
std::string TOKEN_PATH
std::string LOG_PATH
std::atomic< bool > running {false}
std::thread listener_thread
int server_fd {-1}

Detailed Description

Definition at line 201 of file BastionGuard-ransomware-alert.cpp.

Constructor & Destructor Documentation

◆ AlertApp() [1/2]

AlertApp::AlertApp ( )
inline

Definition at line 203 of file BastionGuard-ransomware-alert.cpp.

204 : app(Gtk::Application::create(
205 "org.BastionGuard.ransomware.alert"))
206 {
207 app->hold();
208 }
Glib::RefPtr< Gtk::Application > app

References app.

◆ AlertApp() [2/2]

AlertApp::AlertApp ( )
inline

Definition at line 64 of file BastionGuard-ransomware-realtime-alert.cpp.

65 : app(Gtk::Application::create("org.BastionGuard.realtime.alert"))
66 {
67 app->hold();
68
71 load_token();
72
73 app->signal_shutdown().connect(
74 sigc::mem_fun(*this, &AlertApp::stop_listener)
75 );
76 }

References app, ensure_user_token(), load_token(), resolve_paths(), and stop_listener().

◆ ~AlertApp()

AlertApp::~AlertApp ( )
inline

Definition at line 78 of file BastionGuard-ransomware-realtime-alert.cpp.

79 {
81 }

References stop_listener().

Member Function Documentation

◆ enqueue_alert()

void AlertApp::enqueue_alert ( const std::string & file,
const std::string & family )
inlineprivate

Definition at line 357 of file BastionGuard-ransomware-realtime-alert.cpp.

358 {
359 alertQueue.push({file, family});
360
361 if (!current_window) {
362 show_next();
363 }
364 }
std::queue< std::pair< std::string, std::string > > alertQueue

References alertQueue, current_window, and show_next().

Referenced by start_tcp_listener().

◆ ensure_user_token()

void AlertApp::ensure_user_token ( )
inlineprivate

Definition at line 133 of file BastionGuard-ransomware-realtime-alert.cpp.

134 {
135 const std::string system_token = "/etc/BastionGuard/ransomware.token";
136 const std::string user_token = TOKEN_PATH;
137
138 if (!fs::exists(system_token)) {
139 log_user(_("[ERRORE] Token root NON trovato: ") + system_token);
140 return;
141 }
142
143 if (fs::exists(user_token)) {
144 std::error_code ec;
145 fs::remove(user_token, ec);
146 if (!ec) {
147 log_user(_("[INFO] Vecchio token utente rimosso"));
148 } else {
149 log_user(_("[ERRORE] Non posso rimuovere vecchio token utente"));
150 }
151 }
152
153 std::ifstream src(system_token, std::ios::binary);
154 if (!src.is_open()) {
155 log_user(_("[ERRORE] Non posso aprire token root"));
156 return;
157 }
158
159 std::ofstream dst(user_token, std::ios::binary | std::ios::trunc);
160 if (!dst.is_open()) {
161 log_user(_("[ERRORE] Non posso creare token utente"));
162 return;
163 }
164
165 dst << src.rdbuf();
166 dst.close();
167
168 ::chmod(user_token.c_str(), 0600);
169 ::chown(user_token.c_str(), getuid(), getgid());
170
171 log_user(_("[OK] Token copiato nella home: ") + user_token);
172 }
#define _(s)
void log_user(const std::string &msg)

References _, log_user(), and TOKEN_PATH.

Referenced by AlertApp().

◆ load_css()

void AlertApp::load_css ( )
inlineprivate

Definition at line 190 of file BastionGuard-ransomware-realtime-alert.cpp.

191 {
192 try {
193 auto css = Gtk::CssProvider::create();
194 css->load_from_path(resource(resolve_theme_css()));
195
196 auto display = Gdk::Display::get_default();
197 if (display) {
198 Gtk::StyleContext::add_provider_for_display(
199 display,
200 css,
201 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
202 );
203 }
204 } catch (const std::exception& e) {
205 log_user(std::string("[WARN] load_css exception: ") + e.what());
206 } catch (...) {
207 log_user("[WARN] load_css exception sconosciuta");
208 }
209 }
static std::string resolve_theme_css()
std::string resource(const std::string &rel)
Definition Resource.hpp:31

References log_user(), resolve_theme_css(), and resource().

Referenced by run().

◆ load_token()

void AlertApp::load_token ( )
inlineprivate

Definition at line 174 of file BastionGuard-ransomware-realtime-alert.cpp.

175 {
176 std::ifstream f(TOKEN_PATH);
177 if (!f.is_open()) {
178 log_user(_("[ERRORE] Non posso aprire token utente"));
179 return;
180 }
181
182 std::getline(f, SECURITY_TOKEN);
183 if (SECURITY_TOKEN.empty()) {
184 log_user(_("[ERRORE] Token utente vuoto"));
185 } else {
186 log_user(_("[OK] Token caricato"));
187 }
188 }

References _, log_user(), SECURITY_TOKEN, and TOKEN_PATH.

Referenced by AlertApp().

◆ log_user()

void AlertApp::log_user ( const std::string & msg)
inlineprivate

Definition at line 125 of file BastionGuard-ransomware-realtime-alert.cpp.

126 {
127 std::ofstream f(LOG_PATH, std::ios::app);
128 if (f.is_open()) {
129 f << msg << '\n';
130 }
131 }

References LOG_PATH.

Referenced by ensure_user_token(), load_css(), load_token(), and start_tcp_listener().

◆ on_method_call()

void AlertApp::on_method_call ( const Glib::RefPtr< Gio::DBus::Connection > & ,
const Glib::ustring & ,
const Glib::ustring & ,
const Glib::ustring & ,
const Glib::ustring & method,
const Glib::VariantContainerBase & params,
const Glib::RefPtr< Gio::DBus::MethodInvocation > & inv )
inlineprivate

Definition at line 252 of file BastionGuard-ransomware-alert.cpp.

260 {
261 if (method == "ShowAlert") {
262 Glib::Variant<Glib::ustring> file, family;
263 params.get_child(file, 0);
264 params.get_child(family, 1);
265
266 queue.push({file.get(), family.get()});
267 inv->return_value({});
268
269 if (!current_window)
270 show_next();
271 }
272 }
std::queue< std::pair< std::string, std::string > > queue

References current_window, queue, and show_next().

Referenced by run().

◆ resolve_paths()

void AlertApp::resolve_paths ( )
inlineprivate

Definition at line 104 of file BastionGuard-ransomware-realtime-alert.cpp.

105 {
106 const char* home = std::getenv("HOME");
107 if (!home) {
108 if (passwd* pw = getpwuid(getuid())) {
109 home = pw->pw_dir;
110 }
111 }
112
113 if (!home) {
114 home = "/tmp";
115 }
116
117 const std::string base = std::string(home) + "/.local/share/BastionGuard";
118 std::error_code ec;
119 fs::create_directories(base, ec);
120
121 TOKEN_PATH = base + "/ransomware.token";
122 LOG_PATH = base + "/alert-gui.log";
123 }

References LOG_PATH, and TOKEN_PATH.

Referenced by AlertApp().

◆ run() [1/2]

int AlertApp::run ( int argc,
char * argv[] )
inline

Definition at line 210 of file BastionGuard-ransomware-alert.cpp.

210 {
211 auto connection = Gio::DBus::Connection::get_sync(
212 Gio::DBus::BusType::SESSION
213 );
214
215 auto node_info =
216 Gio::DBus::NodeInfo::create_for_xml(introspection_xml);
217 auto iface_info =
218 node_info->lookup_interface(
219 "org.BastionGuard.Ransomware.Alert");
220
221 Gio::DBus::InterfaceVTable vtable(
222 sigc::mem_fun(*this, &AlertApp::on_method_call)
223 );
224
225 connection->register_object(
226 "/org/BastionGuard/ransomware/alert",
227 iface_info,
228 vtable
229 );
230 auto msg = Glib::VariantContainerBase::create_tuple({
231 Glib::Variant<Glib::ustring>::create(
232 "org.BastionGuard.Ransomware.Alert"),
233 Glib::Variant<guint32>::create(0)
234 });
235
236 connection->call_sync(
237 "/org/freedesktop/DBus",
238 "org.freedesktop.DBus",
239 "RequestName",
240 msg,
241 "org.freedesktop.DBus"
242 );
243
244 return app->run(argc, argv);
245 }
const char introspection_xml[]
void on_method_call(const Glib::RefPtr< Gio::DBus::Connection > &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &method, const Glib::VariantContainerBase &params, const Glib::RefPtr< Gio::DBus::MethodInvocation > &inv)

References app, introspection_xml, and on_method_call().

Referenced by main().

◆ run() [2/2]

int AlertApp::run ( int argc,
char * argv[] )
inline

Definition at line 83 of file BastionGuard-ransomware-realtime-alert.cpp.

84 {
85 load_css();
87 return app->run(argc, argv);
88 }

References app, load_css(), and start_tcp_listener().

◆ show_next() [1/2]

void AlertApp::show_next ( )
inlineprivate

Definition at line 274 of file BastionGuard-ransomware-alert.cpp.

274 {
275 if (current_window || queue.empty())
276 return;
277
278 auto [file, family] = queue.front();
279 queue.pop();
280
282 file, family, queue.size());
283
284 app->add_window(*current_window);
285
286 current_window->signal_ignore_all.connect([this]() {
287 std::queue<std::pair<std::string, std::string>> empty;
288 std::swap(queue, empty);
289 });
290
291 current_window->signal_close_request().connect(
292 [this]() -> bool {
293 current_window = nullptr;
294 show_next();
295 return false;
296 },
297 false
298 );
299
300 current_window->present();
301 }
sigc::signal< void()> signal_ignore_all
AlertWindow(const std::string &file, const std::string &family, size_t pending=0)

References AlertWindow::AlertWindow(), app, current_window, queue, show_next(), and AlertWindow::signal_ignore_all.

Referenced by enqueue_alert(), on_method_call(), and show_next().

◆ show_next() [2/2]

void AlertApp::show_next ( )
inlineprivate

Definition at line 366 of file BastionGuard-ransomware-realtime-alert.cpp.

367 {
368 if (current_window || alertQueue.empty()) {
369 return;
370 }
371
372 auto [file, family] = alertQueue.front();
373 alertQueue.pop();
374
375 current_window = std::make_unique<AlertWindowRealtime>(file, family, alertQueue.size());
376
377 current_window->signal_ignore_all.connect([this]() {
378 std::queue<std::pair<std::string, std::string>> empty;
379 std::swap(alertQueue, empty);
380
381 if (current_window) {
382 current_window->hide();
383 }
384 });
385
386 current_window->signal_hide().connect([this]() {
387 Glib::signal_idle().connect_once([this]() {
388 current_window.reset();
389 show_next();
390 });
391 });
392
393 current_window->present();
394 }

References alertQueue, current_window, and show_next().

◆ start_tcp_listener()

void AlertApp::start_tcp_listener ( )
inlineprivate

Definition at line 211 of file BastionGuard-ransomware-realtime-alert.cpp.

212 {
213 if (running.load()) {
214 return;
215 }
216
217 running = true;
218
219 listener_thread = std::thread([this]() {
220 log_user(_("[INFO] Avvio listener TCP..."));
221
222 server_fd = ::socket(AF_INET, SOCK_STREAM, 0);
223 if (server_fd < 0) {
224 log_user(_("[ERRORE] socket fallita"));
225 running = false;
226 return;
227 }
228
229 int opt = 1;
230 ::setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
231
232 sockaddr_in addr{};
233 addr.sin_family = AF_INET;
234 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
235 addr.sin_port = htons(1025);
236
237 if (::bind(server_fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
238 log_user(_("[ERRORE] bind fallita: ") + std::string(std::strerror(errno)));
239 ::close(server_fd);
240 server_fd = -1;
241 running = false;
242 return;
243 }
244
245 log_user(_("[OK] Bind su 127.0.0.1:1025"));
246
247 if (::listen(server_fd, 5) < 0) {
248 log_user(_("[ERRORE] listen fallita"));
249 ::close(server_fd);
250 server_fd = -1;
251 running = false;
252 return;
253 }
254
255 log_user(_("[OK] Listener avviato"));
256
257 while (running.load()) {
258 int client = ::accept(server_fd, nullptr, nullptr);
259 if (client < 0) {
260 if (!running.load()) {
261 break;
262 }
263
264 if (errno == EINTR) {
265 continue;
266 }
267
268 log_user(_("[WARN] accept fallita: ") + std::string(std::strerror(errno)));
269 continue;
270 }
271
272 char buf[2048];
273 const ssize_t n = ::read(client, buf, sizeof(buf) - 1);
274 ::close(client);
275
276 if (n <= 0) {
277 continue;
278 }
279
280 buf[n] = '\0';
281 std::string msg(buf);
282
283 const auto p1 = msg.find('|');
284 const auto p2 = (p1 == std::string::npos) ? std::string::npos : msg.find('|', p1 + 1);
285
286 if (p1 == std::string::npos || p2 == std::string::npos) {
287 continue;
288 }
289
290 const std::string token = msg.substr(0, p1);
291 const std::string file = msg.substr(p1 + 1, p2 - p1 - 1);
292 const std::string family = msg.substr(p2 + 1);
293
294 if (file.find("antiransom_inotify.log") != std::string::npos) {
295 log_user(_("[IGNORATO] Alert proveniente dal log interno"));
296 continue;
297 }
298
299 if (token != SECURITY_TOKEN) {
300 log_user(_("[SCARTATO] Token non valido"));
301 continue;
302 }
303
304 // Il percorso ricevuto dal processo realtime deve indicare
305 // esclusivamente un file regolare assoluto. Non seguire
306 // symlink e non mostrare azioni di quarantena per directory.
307 const fs::path alert_path(file);
308 std::error_code path_ec;
309 const fs::file_status path_status =
310 fs::symlink_status(alert_path, path_ec);
311
312 if (!alert_path.is_absolute() || path_ec ||
313 !fs::exists(path_status) ||
314 !fs::is_regular_file(path_status)) {
315 log_user(_("[SCARTATO] Percorso alert non regolare: ") + file);
316 continue;
317 }
318
319 Glib::signal_idle().connect_once([this, file, family]() {
320 if (!running.load()) {
321 return;
322 }
323 enqueue_alert(file, family);
324 });
325 }
326
327 if (server_fd >= 0) {
328 ::close(server_fd);
329 server_fd = -1;
330 }
331
332 log_user(_("[INFO] Listener TCP terminato"));
333 });
334 }
#define AF_INET
Definition bsc_ebpf.c:56
void enqueue_alert(const std::string &file, const std::string &family)

References _, AF_INET, enqueue_alert(), listener_thread, log_user(), running, SECURITY_TOKEN, and server_fd.

Referenced by run().

◆ stop_listener()

void AlertApp::stop_listener ( )
inlineprivate

Definition at line 336 of file BastionGuard-ransomware-realtime-alert.cpp.

337 {
338 const bool was_running = running.exchange(false);
339 if (!was_running) {
340 if (listener_thread.joinable()) {
341 listener_thread.join();
342 }
343 return;
344 }
345
346 if (server_fd >= 0) {
347 ::shutdown(server_fd, SHUT_RDWR);
348 ::close(server_fd);
349 server_fd = -1;
350 }
351
352 if (listener_thread.joinable()) {
353 listener_thread.join();
354 }
355 }

References listener_thread, running, and server_fd.

Referenced by AlertApp(), and ~AlertApp().

Member Data Documentation

◆ alertQueue

std::queue<std::pair<std::string, std::string> > AlertApp::alertQueue
private

Definition at line 93 of file BastionGuard-ransomware-realtime-alert.cpp.

Referenced by enqueue_alert(), and show_next().

◆ app

Glib::RefPtr< Gtk::Application > AlertApp::app
private

Definition at line 248 of file BastionGuard-ransomware-alert.cpp.

Referenced by AlertApp(), run(), and show_next().

◆ current_window [1/2]

AlertWindow* AlertApp::current_window = nullptr
private

Definition at line 250 of file BastionGuard-ransomware-alert.cpp.

Referenced by enqueue_alert(), on_method_call(), and show_next().

◆ current_window [2/2]

std::unique_ptr<AlertWindowRealtime> AlertApp::current_window
private

Definition at line 94 of file BastionGuard-ransomware-realtime-alert.cpp.

◆ listener_thread

std::thread AlertApp::listener_thread
private

◆ LOG_PATH

std::string AlertApp::LOG_PATH
private

Definition at line 98 of file BastionGuard-ransomware-realtime-alert.cpp.

Referenced by log_user(), and resolve_paths().

◆ queue

std::queue<std::pair<std::string, std::string> > AlertApp::queue
private

Definition at line 249 of file BastionGuard-ransomware-alert.cpp.

Referenced by on_method_call(), and show_next().

◆ running

std::atomic<bool> AlertApp::running {false}
private

◆ SECURITY_TOKEN

std::string AlertApp::SECURITY_TOKEN
private

Definition at line 96 of file BastionGuard-ransomware-realtime-alert.cpp.

Referenced by load_token(), and start_tcp_listener().

◆ server_fd

int AlertApp::server_fd {-1}
private

◆ TOKEN_PATH

std::string AlertApp::TOKEN_PATH
private

The documentation for this class was generated from the following files: