259 auto header = Gtk::make_managed<Gtk::HeaderBar>();
260 header->set_show_title_buttons(
false);
261 header->set_decoration_layout(
"");
262 header->get_style_context()->add_class(
"custom-headerbar");
264 auto title_label = Gtk::make_managed<Gtk::Label>(
_(
"BastionGuard - Configurazione iniziale"));
265 title_label->get_style_context()->add_class(
"header-title");
266 title_label->set_halign(Gtk::Align::CENTER);
267 title_label->set_valign(Gtk::Align::CENTER);
268 header->set_title_widget(*title_label);
270 auto header_right = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
273 auto pix_min = Gdk::Pixbuf::create_from_file(
resource(
"icon-minimize.png"), 32, 32,
true);
275 btn_minimize->set_child(*Gtk::make_managed<Gtk::Image>(pix_min));
276 btn_minimize->get_style_context()->add_class(
"header-button");
280 std::cerr <<
_(
"⚠ Errore caricamento icona minimize\n");
284 auto pix_close = Gdk::Pixbuf::create_from_file(
resource(
"icon-close.png"), 32, 32,
true);
285 btn_close = Gtk::make_managed<Gtk::Button>();
286 btn_close->set_child(*Gtk::make_managed<Gtk::Image>(pix_close));
287 btn_close->get_style_context()->add_class(
"header-button");
291 std::cerr <<
_(
"⚠ Errore caricamento icona close\n");
294 header->pack_end(*header_right);
295 set_titlebar(*header);
300 auto main_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 0);
301 main_box->set_vexpand(
false);
302 main_box->set_hexpand(
true);
303 set_child(*main_box);
305 auto sidebar = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 10);
306 sidebar->set_size_request(240, -1);
307 sidebar->set_vexpand(
false);
308 sidebar->get_style_context()->add_class(
"sidebar");
310 auto header_sidebar = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
311 header_sidebar->get_style_context()->add_class(
"sidebar-header");
314 auto pixbuf = Gdk::Pixbuf::create_from_file(
resource(
"logo-sidebar.png"), 96, 96,
true);
315 auto logo = Gtk::make_managed<Gtk::Image>(pixbuf);
316 header_sidebar->append(*logo);
318 std::cerr <<
_(
"⚠ Impossibile caricare logo-sidebar.png\n");
321 auto lbl = Gtk::make_managed<Gtk::Label>(
"BastionGuard");
322 lbl->set_halign(Gtk::Align::START);
323 lbl->get_style_context()->add_class(
"sidebar-title");
324 header_sidebar->append(*lbl);
326 sidebar->append(*header_sidebar);
328 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
329 spacer->set_vexpand(
true);
330 sidebar->append(*spacer);
332 main_box->append(*sidebar);
334 auto content_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 12);
335 content_box->set_margin(24);
336 content_box->set_hexpand(
true);
337 content_box->set_vexpand(
false);
338 content_box->get_style_context()->add_class(
"content");
339 main_box->append(*content_box);
341 auto title = Gtk::make_managed<Gtk::Label>(
_(
"Scegli quali servizi di protezione attivare"));
342 title->get_style_context()->add_class(
"title");
343 content_box->append(*title);
345 auto subtitle = Gtk::make_managed<Gtk::Label>(
346 _(
"I servizi selezionati verranno avviati automaticamente al login.\n"
347 "Potrai modificarli in qualsiasi momento dalle impostazioni."));
348 subtitle->set_wrap();
349 subtitle->add_css_class(
"alert-info");
350 content_box->append(*subtitle);
352 auto grid = Gtk::make_managed<Gtk::Grid>();
353 grid->set_column_spacing(20);
354 grid->set_row_spacing(10);
355 grid->set_margin_top(12);
356 grid->set_margin_bottom(12);
357 grid->set_vexpand(
false);
358 grid->set_valign(Gtk::Align::START);
359 content_box->append(*grid);
361 std::vector<ServiceInfo> services = {
362 {
"BastionGuard-privacyd.service",
_(
"Privacy Guard"),
_(
"Blocco microfono e webcam quando non in uso")},
363 {
"BastionGuard-ransomware-alert.service",
_(
"Ransomware Alert"),
_(
"Notifiche su possibili attività ransomware")},
364 {
"BastionGuard-ransomware-realtime-alert.service",
_(
"Ransomware Realtime Alert"),
_(
"Avvisi in tempo reale su comportamenti sospetti")},
365 {
"BastionGuard-ransomware-scanner.service",
_(
"Ransomware Scanner"),
_(
"Scansione periodica alla ricerca di comportamenti malevoli")},
366 {
"BastionGuard-useragent.service",
_(
"User-Agent Randomizer"),
_(
"Modifica user-agent per aumentare anonimato")},
367 {
"BastionGuard-pacd.service",
_(
"PAC Daemon"),
_(
"Gestione automatica di proxy PAC sicuri")},
368 {
"BastionGuard-phishing-scanner.service",
_(
"Phishing Scanner (System)"),
_(
"Scansione anti-phishing a livello di sistema")},
369 {
"BastionGuard-mailproxy.service",
_(
"Mail Proxy"),
_(
"Proxy SMTP locale per protezione email in uscita")},
370 {
"BastionGuard-usbd.service",
_(
"USB Protection (System)"),
_(
"Monitoraggio e blocco dispositivi USB sospetti")},
371 {
"BastionGuard-ransomware-realtime.service",
_(
"Ransomware Realtime (System)"),
_(
"Monitor realtime ransomware a livello di sistema")},
375 services.push_back({
"BastionGuard-cef.service",
_(
"CEF Sandbox Service"),
_(
"Supporto in background per pagamenti sicuri con CEF")});
379 for (
const auto& svc : services)
381 auto check = Gtk::make_managed<Gtk::CheckButton>(svc.label);
382 check->set_active(
true);
384 auto desc = Gtk::make_managed<Gtk::Label>(svc.description);
385 desc->add_css_class(
"label");
387 desc->set_halign(Gtk::Align::START);
388 desc->set_margin_start(24);
389 desc->set_max_width_chars(50);
390 desc->set_ellipsize(Pango::EllipsizeMode::END);
392 grid->attach(*check, 0, row, 1, 1);
393 grid->attach(*desc, 1, row, 1, 1);
401 auto btn_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 12);
402 btn_box->set_halign(Gtk::Align::END);
403 btn_box->set_margin_top(16);
404 btn_box->set_vexpand(
false);
406 auto btn_minimal = Gtk::make_managed<Gtk::Button>(
_(
"Configurazione minima"));
407 btn_minimal->get_style_context()->add_class(
"btn-warning");
410 auto btn_all = Gtk::make_managed<Gtk::Button>(
_(
"Attiva tutto"));
411 btn_all->get_style_context()->add_class(
"btn-primary");
414 auto btn_apply = Gtk::make_managed<Gtk::Button>(
_(
"Applica e continua"));
415 btn_apply->get_style_context()->add_class(
"btn-success");
418 btn_box->append(*btn_minimal);
419 btn_box->append(*btn_all);
420 btn_box->append(*btn_apply);
422 content_box->append(*btn_box);
506 if (ca_src.empty()) {
507 std::cerr <<
_(
"[FirstRun] CA NSS utente non trovata\n");
511 auto nss_add = [&](
const std::string& db) {
512 if (!std::filesystem::exists(db))
515 const std::string prefix =
516 std::filesystem::exists(db +
"/cert9.db") ?
"sql:" :
"dbm:";
518 run_cmd({
"certutil",
"-D",
"-d", prefix + db,
"-n",
"BastionGuard-CA"},
true);
520 bool ok =
run_cmd({
"certutil",
"-A",
522 "-n",
"BastionGuard-CA",
524 "-i", ca_src},
false);
527 std::cerr <<
_(
"[FirstRun] ✅ NSS: ") << db <<
"\n";
530 const std::string home = Glib::get_home_dir();
533 for (
const auto& db : std::vector<std::string>{
534 home +
"/.pki/nssdb",
535 home +
"/snap/chromium/current/.pki/nssdb",
536 home +
"/.var/app/org.chromium.Chromium/.pki/nssdb",
537 home +
"/.var/app/com.google.Chrome/.pki/nssdb",
538 home +
"/.var/app/com.brave.Browser/.pki/nssdb",
539 home +
"/.var/app/com.microsoft.Edge/.pki/nssdb",
540 home +
"/.var/app/com.opera.Opera/.pki/nssdb",
541 home +
"/.var/app/com.vivaldi.Vivaldi/.pki/nssdb",
542 home +
"/.config/BraveSoftware/Brave-Browser/Default",
543 home +
"/.config/microsoft-edge/Default",
544 home +
"/.config/opera",
545 home +
"/.config/vivaldi/Default",
546 home +
"/.config/chromium/Default",
547 home +
"/.config/yandex-browser/Default",
552 auto is_profile = [](
const std::string& n) {
553 for (
const auto& s : {
557 ".dev-edition-default",
561 if (n.size() >= std::string(s).size() &&
562 n.compare(n.size() - std::string(s).size(), std::string(s).size(), s) == 0)
565 return n.size() > 9 && n[8] ==
'.';
568 for (
const auto& base : std::vector<std::string>{
569 home +
"/.mozilla/firefox",
570 home +
"/.var/app/org.mozilla.firefox/.mozilla/firefox",
571 home +
"/.var/app/org.mozilla.firefoxesr/.mozilla/firefox",
572 home +
"/snap/firefox/current/.mozilla/firefox",
573 home +
"/.librewolf",
574 home +
"/.var/app/io.gitlab.librewolf-community/.librewolf",
577 home +
"/.var/app/one.ablaze.floorp/.floorp",
579 home +
"/.var/app/io.github.zen_browser.zen/.zen",
581 home +
"/.thunderbird",
582 home +
"/.var/app/org.mozilla.Thunderbird/.thunderbird",
583 home +
"/snap/thunderbird/current/.thunderbird",
585 if (!std::filesystem::exists(base))
589 for (
const auto& e : std::filesystem::directory_iterator(base)) {
590 if (e.is_directory() && is_profile(e.path().filename().string()))
591 nss_add(e.path().string());
596 std::cerr <<
_(
"[FirstRun] ✅ NSS profili utente aggiornati\n");
658 auto proc = Gio::Subprocess::create(
659 {
"/usr/libexec/bastionguard/bastionguard-service",
"--user",
"is-enabled", service_name},
660 Gio::Subprocess::Flags::STDOUT_PIPE |
661 Gio::Subprocess::Flags::STDERR_PIPE
664 auto [stdout_str, stderr_str] = proc->communicate_utf8(
"");
666 if (!proc->get_successful())
669 std::string result = stdout_str.raw();
670 result.erase(std::remove(result.begin(), result.end(),
'\n'), result.end());
671 result.erase(std::remove(result.begin(), result.end(),
'\r'), result.end());
673 return result ==
"enabled";