Skip to content
API Documentation
BastionGuard™
Backend Class Reference

#include <Backend.hpp>

Classes

struct  ScanStatus
struct  SambaScanState

Public Member Functions

 ~Backend ()
void setupAlertListener ()
void moveToQuarantine (const std::string &)
void sendRansomwareAlert (const std::string &path, const std::string &family)
bool isSambaScanRunning ()
void start_antiransom ()
void stop_antiransom ()
sigc::signal< void(const std::string &)> & signal_antiransom_event ()
bool updateYaraRules (std::function< void(int, int, const std::string &)> progressCallback=nullptr)
bool reload_dnsmasq ()
bool updatePhishLists ()
bool isPhishAutoUpdateEnabled ()
bool enablePhishAutoUpdate (bool enable)
std::vector< std::string > getWhitelist () const
void addToWhitelist (const std::string &domain)
void removeFromWhitelist (const std::string &domain)
void saveWhitelist () const
void loadWhitelist ()
void mergeWhitelistSources ()
bool isBankDomain (const std::string &host) const
bool updateBankListFromURL (const std::string &source_url)
std::string checkUrl (const std::string &url)
bool isGoogleSafeEnabled () const
void setGoogleSafeEnabled (bool enabled)
void setGoogleSafeApiKey (const std::string &key)
std::string getGoogleSafeApiKey () const
void saveGoogleSafeConfig ()
bool testGoogleSafeKey ()
void start_antiphish ()
void stop_antiphish ()
bool isAntiphishActive ()
sigc::signal< void(const std::string &)> & signal_antiphish_event ()
bool updateSanesecurityDB (std::function< void(int, int, const std::string &)> progressCallback=nullptr)
void scanSambaDir (const std::string &dir)
void ensureQuarantinePath ()
void setPhishingPort (int port)
int getPhishingPort () const
std::string getSambaConfigPath () const
std::vector< std::string > getSambaDirs ()
void saveSambaConfig (bool enabled, const std::vector< std::string > &dirs)
bool addSambaDir (const std::string &dir)
bool removeSambaDir (const std::string &dir)
bool isSambaEnabled ()
void setSambaEnabled (bool enabled)
void scanAllSambaDirs ()
void resetSambaStop ()
void requestStopSambaScan ()
void saveSMBCredentials (const std::string &url, const std::string &user, const std::string &pass)
std::pair< std::string, std::string > getCreds (const std::string &url)
SMBCCTX * createThreadSmbContext ()
void smb_collect_files (SMBCCTX *ctx, const std::string &url, std::vector< std::string > &out)
void smb_collect_files_impl (SMBCCTX *ctx, const std::string &url, std::vector< std::string > &out)
bool smb_read_file_with_ctx (SMBCCTX *ctx, const std::string &smbPath, std::function< bool(const char *, size_t)>)
bool smb_copy_file (const std::string &smbPath, const std::filesystem::path &dest)
ScanStatus get_current_scan_files ()
SambaScanState get_current_scan_files () const
void applyFirewallFromBlacklist (const std::vector< std::string > &blacklistLines)
void setFirewallType (FirewallType fw)
FirewallType getFirewallType () const
void setFirewallEnabled (bool enabled)
bool isFirewallEnabled () const
void loadFirewallConfig ()
void saveFirewallConfig () const
void applyFirewallFromPhishingBlacklist ()
void scheduleFirewallApply (const std::string &inputPath)

Static Public Member Functions

static Backend & instance ()
static std::string getAppVersion ()
static int getAppBuild ()
static bool enableClamonacc ()
static bool disableClamonacc ()
static bool isClamonaccActive ()
static std::string getClamonaccStatus ()
static void setQuarantinePath (const std::string &path)
static std::string getQuarantinePath ()
static std::vector< std::string > getClamonaccLogs ()
static std::string getLastUpdateDate ()
static std::string getDbVersion ()
static std::vector< std::string > getOnAccessPaths ()
static std::vector< std::string > getOnAccessEvents ()
static bool installClamdIfMissing ()
static bool isAntiransomActive ()
static void smb_auth_fn (SMBCCTX *context, const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen)
static bool isValidSMB (const std::string &url)
static std::string resolveSambaDir (const std::string &path)

Public Attributes

std::function< void(const std::string &)> onBankListReload
std::atomic< bool > samba_stop_requested { false }
std::map< std::string, std::pair< std::string, std::string > > smb_credentials
std::function< void(const std::string &, float)> samba_progress_callback = nullptr
SambaScanState samba_scan_state

Private Member Functions

 Backend ()
 Backend (const Backend &)=delete
Backend & operator= (const Backend &)=delete
void initSambaClient ()
std::string getSambaCredsPath () const
void loadSMBCredentials ()

Private Attributes

AntiRansomEngine antiransom_
sigc::signal< void(const std::string &)> antiransom_signal_
std::function< void(int, int, const std::string &)> progressCallback_
std::mutex smb_mutex
std::unique_ptr< WebProbe > webprobe_
std::vector< std::string > whitelist_
bool googleSafeEnabled_ = false
std::string googleSafeApiKey_
bool firewallEnabled_ = false
FirewallType firewallType_ = FirewallType::NONE
SMBCCTX * smb_context = nullptr
std::string samba_last_temp_dir
float samba_last_progress = 0.0f

Detailed Description

Definition at line 36 of file Backend.hpp.

Constructor & Destructor Documentation

◆ ~Backend()

◆ Backend() [1/2]

Backend::Backend ( )
private

Definition at line 703 of file Backend.cpp.

704 : antiransom_()
705{
711
712
713
715
716
717 try {
718 std::string fwCfg =
719 Glib::get_home_dir() + "/.config/BastionGuard/firewall.conf";
720
721 if (std::filesystem::exists(fwCfg)) {
722 std::ifstream fin(fwCfg);
723 std::string line;
724 std::getline(fin, line);
725
726 if (line.find("firewalld") != std::string::npos)
728 else if (line.find("ufw") != std::string::npos)
730 else
732
733 std::cout << "[Backend] Firewall caricato da config: "
734 << line << std::endl;
735 } else {
736 std::cout << "[Backend] Firewall autodetect: "
737 << static_cast<int>(firewallType_) << std::endl;
738 }
739 } catch (...) {
740 std::cerr << _("[Backend] ⚠ Errore lettura configurazione firewall\n");
741 }
742
743
744 try {
746 std::cout << _("[Backend] 🛰️ Listener D-Bus ransomware attivo\n");
747 } catch (const std::exception& e) {
748 std::cerr << _("[Backend] ⚠ Impossibile avviare listener D-Bus ransomware: ")
749 << e.what() << std::endl;
750 }
751
752
753 googleSafeEnabled_ = false;
754 googleSafeApiKey_.clear();
755
756
757 try {
758 const char* home = getenv("HOME");
759 std::string cfgPath = std::string(home) + "/.config/BastionGuard/googlesafe.conf";
760 if (std::filesystem::exists(cfgPath)) {
761 std::ifstream fin(cfgPath);
762 std::string line;
763 while (std::getline(fin, line)) {
764 if (line.find("google_safe_enabled=true") != std::string::npos)
765 googleSafeEnabled_ = true;
766 if (line.find("google_safe_key=") != std::string::npos) {
767 auto pos = line.find('=');
768 if (pos != std::string::npos)
769 googleSafeApiKey_ = line.substr(pos + 1);
770 }
771 }
772 std::cout << _("[Backend] Configurazione Google Safe caricata da ") << cfgPath << "\n";
773 }
774 } catch (...) {
775 std::cerr << _("[Backend] ⚠ Impossibile leggere config Google Safe\n");
776 }
777
779 std::cout << Glib::ustring::compose(
780 _("[Backend] Google Safe Browsing attivo (API Key: %1)\n"),
781 googleSafeApiKey_.empty() ? _("vuota") : _("presente")
782 );
783
784 else
785 std::cout << _("[Backend] Google Safe Browsing disattivato.\n");
786
787
788 std::string blacklist = resource("phishing/blacklist.txt");
789
790 if (!std::filesystem::exists(blacklist)) {
791 std::cerr << _("[Backend] Blacklist non trovata in ") << blacklist
792 << _(" — provo a scaricarla con updatePhishLists()\n");
793 if (updatePhishLists()) {
794 blacklist = resource("phishing/blacklist.txt");
795 std::cout << _("[Backend] Blacklist aggiornata e trovata in ") << blacklist << std::endl;
796 } else {
797 std::cerr << _("[Backend] updatePhishLists() fallita, continuerò senza WebProbe\n");
798 }
799 }
800
801 const auto [warning_port, warning_https_port] = read_ports_from_conf();
802 (void)warning_https_port;
803
804 if (!blacklist.empty() && std::filesystem::exists(blacklist)) {
805 try {
806 webprobe_ = std::make_unique<WebProbe>(blacklist, warning_port);
807 std::cout << _("[Backend] WebProbe avviato su porta ") << warning_port
808 << _(" con blacklist: ") << blacklist << std::endl;
809 } catch (const std::exception& ex) {
810 std::cerr << _("[Backend] Errore inizializzazione WebProbe: ") << ex.what() << std::endl;
811 webprobe_.reset();
812 }
813 } else {
814 std::cerr << _("[Backend] Nessuna blacklist disponibile, WebProbe non inizializzato\n");
815 }
816
817
818 try {
820 std::cout << _("[Backend] Whitelist caricata con ")
821 << whitelist_.size() << " voci.\n";
822 } catch (const std::exception& e) {
823 std::cerr << _("[Backend] ⚠ Errore caricamento whitelist: ")
824 << e.what() << std::endl;
825 }
826
827 }
std::pair< int, int > read_ports_from_conf()
Definition Backend.cpp:288
static void loadQuarantinePathFromConfig()
Definition Backend.cpp:378
#define _(s)
AntiRansomEngine antiransom_
Definition Backend.hpp:198
std::vector< std::string > whitelist_
Definition Backend.hpp:203
void initSambaClient()
Definition Backend.cpp:2273
bool updatePhishLists()
Definition Backend.cpp:1086
void loadSMBCredentials()
Definition Backend.cpp:1993
void ensureQuarantinePath()
Definition Backend.cpp:2745
void loadFirewallConfig()
Definition Backend.cpp:3135
std::unique_ptr< WebProbe > webprobe_
Definition Backend.hpp:202
void setupAlertListener()
Definition Backend.cpp:2620
std::string googleSafeApiKey_
Definition Backend.hpp:206
void loadWhitelist()
Definition Backend.cpp:2943
FirewallType firewallType_
Definition Backend.hpp:208
bool googleSafeEnabled_
Definition Backend.hpp:205
static FirewallType detectFirewall()
std::string resource(const std::string &rel)
Definition Resource.hpp:31

References _, antiransom_, FirewallDetector::detectFirewall(), ensureQuarantinePath(), FIREWALLD, firewallType_, googleSafeApiKey_, googleSafeEnabled_, initSambaClient(), loadFirewallConfig(), loadQuarantinePathFromConfig(), loadSMBCredentials(), loadWhitelist(), NONE, read_ports_from_conf(), resource(), setupAlertListener(), UFW, updatePhishLists(), webprobe_, and whitelist_.

Referenced by Backend(), instance(), and operator=().

◆ Backend() [2/2]

Backend::Backend ( const Backend & )
privatedelete

References Backend().

Member Function Documentation

◆ addSambaDir()

bool Backend::addSambaDir ( const std::string & dir)

◆ addToWhitelist()

void Backend::addToWhitelist ( const std::string & domain)

Definition at line 2913 of file Backend.cpp.

2913 {
2914 if (domain.empty()) return;
2915 // evita duplicati
2916 if (std::find(whitelist_.begin(), whitelist_.end(), domain) == whitelist_.end()) {
2917 whitelist_.push_back(domain);
2918 saveWhitelist();
2919 }
2920}
void saveWhitelist() const
Definition Backend.cpp:2930

References saveWhitelist(), and whitelist_.

Referenced by ~Backend().

◆ applyFirewallFromBlacklist()

void Backend::applyFirewallFromBlacklist ( const std::vector< std::string > & blacklistLines)

Definition at line 3092 of file Backend.cpp.

3094 {
3096 return;
3097
3098 std::string outPath;
3099 if (!create_secure_firewall_input(blacklistLines, outPath)) {
3100 std::cout << _("[Firewall] Nessun IP valido estratto\n");
3101 return;
3102 }
3103
3104 scheduleFirewallApply(outPath);
3105}
void scheduleFirewallApply(const std::string &inputPath)
Definition Backend.cpp:3207
bool firewallEnabled_
Definition Backend.hpp:207
bool create_secure_firewall_input(const std::vector< std::string > &blacklistLines, std::string &outPath)
Definition Backend.cpp:3003

References _, firewallEnabled_, firewallType_, NONE, and scheduleFirewallApply().

Referenced by updatePhishLists().

◆ applyFirewallFromPhishingBlacklist()

void Backend::applyFirewallFromPhishingBlacklist ( )

Definition at line 3174 of file Backend.cpp.

3175{
3177 return;
3178
3179 const std::string blacklistPath =
3180 "/usr/share/BastionGuard/data/phishing/blacklist.txt";
3181
3182 std::ifstream fin(blacklistPath);
3183 if (!fin) {
3184 std::cerr << _("[Firewall] Impossibile aprire blacklist\n");
3185 return;
3186 }
3187
3188 std::vector<std::string> lines;
3189 std::string line;
3190 while (std::getline(fin, line))
3191 lines.push_back(line);
3192
3193 fin.close();
3194
3195
3196 std::string outPath;
3197 if (!create_secure_firewall_input(lines, outPath)) {
3198 std::cout << _("[Firewall] Nessun IP valido trovato\n");
3199 return;
3200 }
3201
3202 scheduleFirewallApply(outPath);
3203}

References _, firewallEnabled_, firewallType_, NONE, and scheduleFirewallApply().

◆ checkUrl()

std::string Backend::checkUrl ( const std::string & url)

Definition at line 1629 of file Backend.cpp.

1629 {
1630 if (!webprobe_) return url;
1631 std::string result = webprobe_->check_url(url);
1632
1633 if (result != url) {
1634
1635 antiphish_signal_.emit(url);
1636 }
1637
1638 return result;
1639}
sigc::signal< void(const std::string &)> antiphish_signal_
Definition Backend.cpp:1627

References antiphish_signal_, and webprobe_.

◆ createThreadSmbContext()

SMBCCTX * Backend::createThreadSmbContext ( )

Definition at line 1871 of file Backend.cpp.

1872{
1873 SMBCCTX* ctx = smbc_new_context();
1874 if (!ctx) return nullptr;
1875
1876 smbc_setOptionUseKerberos(ctx, false);
1877 smbc_setFunctionAuthDataWithContext(ctx, Backend::smb_auth_fn);
1878 smbc_setOptionUserData(ctx, this);
1879
1880 if (!smbc_init_context(ctx)) {
1881 smbc_free_context(ctx, 1);
1882 return nullptr;
1883 }
1884
1885 return ctx;
1886}
static void smb_auth_fn(SMBCCTX *context, const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen)
Definition Backend.cpp:1891

References smb_auth_fn().

Referenced by scanSambaDir(), and smb_copy_file().

◆ disableClamonacc()

bool Backend::disableClamonacc ( )
static

Definition at line 461 of file Backend.cpp.

461 {
462 auto service = findClamonaccService();
463 return bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
464 "--system", "disable", "--now", service}).ok();
465}
static std::string findClamonaccService()
Definition Backend.cpp:443
Result run(const std::vector< std::string > &args, bool merge_stderr=false, std::size_t limit=8U *1024U *1024U, const std::map< std::string, std::string > &environment={}, const std::function< bool(const std::string &)> &on_line={})

References findClamonaccService(), and bg_process::run().

Referenced by ~Backend().

◆ enableClamonacc()

bool Backend::enableClamonacc ( )
static

Definition at line 455 of file Backend.cpp.

455 {
456 auto service = findClamonaccService();
457 return bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
458 "--system", "enable", "--now", service}).ok();
459}

References findClamonaccService(), and bg_process::run().

Referenced by ~Backend().

◆ enablePhishAutoUpdate()

bool Backend::enablePhishAutoUpdate ( bool enable)

Definition at line 1732 of file Backend.cpp.

1732 {
1733 int ret = bg_process::run({"pkexec", "/usr/libexec/bastionguard/bastionguard-service",
1734 "--system", enable ? "enable" : "disable", "--now", "BastionGuard-phishing-updater.timer"}).exit_code;
1735
1736 if (ret == 0) {
1737 if (enable) {
1738 std::cout << "✔ " << _("Timer aggiornamento phishing attivato correttamente.") << std::endl;
1739 } else {
1740 std::cout << "ℹ️ " << _("Timer aggiornamento phishing disattivato.") << std::endl;
1741 }
1742 return true;
1743 } else {
1744 if (enable) {
1745 std::cerr << "❌ " << _("Errore durante l’attivazione del timer di aggiornamento phishing!") << std::endl;
1746 } else {
1747 std::cerr << "⚠️ " << _("Errore durante la disattivazione del timer di aggiornamento phishing!") << std::endl;
1748 }
1749 return false;
1750 }
1751}

References _, and bg_process::run().

Referenced by SettingsPage::build_antiphish_tab(), and ~Backend().

◆ ensureQuarantinePath()

void Backend::ensureQuarantinePath ( )

Definition at line 2745 of file Backend.cpp.

2745 {
2746 try {
2747 std::string quarantineDir = Backend::getQuarantinePath();
2748
2749 if (quarantineDir.empty()) {
2750 quarantineDir = "/var/lib/clamav/quarantine";
2751 }
2752
2753 std::filesystem::path qPath(quarantineDir);
2754
2755 if (!std::filesystem::exists(qPath)) {
2756 std::filesystem::create_directories(qPath);
2757 std::cout << _("📁 Creata directory di quarantena: ") << qPath << "\n";
2758 }
2759
2760
2761 std::filesystem::permissions(qPath,
2762 std::filesystem::perms::owner_all |
2763 std::filesystem::perms::group_read |
2764 std::filesystem::perms::group_write,
2765 std::filesystem::perm_options::replace
2766 );
2767 } catch (const std::exception& ex) {
2768 std::cerr << _("❌ Errore in ensureQuarantinePath(): ") << ex.what() << "\n";
2769 }
2770}
static std::string getQuarantinePath()
Definition Backend.cpp:496

References _, and getQuarantinePath().

Referenced by Backend(), getQuarantinePath(), and setQuarantinePath().

◆ get_current_scan_files() [1/2]

Backend::ScanStatus Backend::get_current_scan_files ( )

Definition at line 2985 of file Backend.cpp.

2986{
2987 ScanStatus st;
2988
2990 st.current_scanning = samba_scan_state.current_file;
2991 st.files = samba_scan_state.log;
2992 st.progress = samba_last_progress;
2993 st.infected = samba_scan_state.infected;
2994 st.temp_dir = samba_last_temp_dir;
2995 return st;
2996}
std::string samba_last_temp_dir
Definition Backend.hpp:213
float samba_last_progress
Definition Backend.hpp:214
SambaScanState samba_scan_state
Definition Backend.hpp:172
std::string current_file
Definition Backend.hpp:167
std::vector< std::string > log
Definition Backend.hpp:168

References Backend::SambaScanState::current_file, Backend::ScanStatus::current_scanning, Backend::ScanStatus::files, Backend::SambaScanState::infected, Backend::ScanStatus::infected, Backend::SambaScanState::log, Backend::ScanStatus::progress, samba_last_progress, samba_last_temp_dir, samba_scan_state, Backend::SambaScanState::scan_active, Backend::ScanStatus::scan_active, and Backend::ScanStatus::temp_dir.

Referenced by SambaPage::onScanNow().

◆ get_current_scan_files() [2/2]

SambaScanState Backend::get_current_scan_files ( ) const
inline

Definition at line 174 of file Backend.hpp.

174{ return samba_scan_state; }

References samba_scan_state.

◆ getAppBuild()

int Backend::getAppBuild ( )
static

Definition at line 78 of file Backend.cpp.

78 {
79#ifdef BASTIONGUARD_BUILD
80 return BASTIONGUARD_BUILD;
81#else
82 return 0;
83#endif
84}

Referenced by DashboardPage::check_updates_async(), and ~Backend().

◆ getAppVersion()

std::string Backend::getAppVersion ( )
static

Definition at line 70 of file Backend.cpp.

70 {
71#ifdef BASTIONGUARD_VERSION
72 return BASTIONGUARD_VERSION;
73#else
74 return "0.0.0";
75#endif
76}

Referenced by DashboardPage::check_updates_async(), and ~Backend().

◆ getClamonaccLogs()

std::vector< std::string > Backend::getClamonaccLogs ( )
static

Definition at line 505 of file Backend.cpp.

505 {
506 std::vector<std::string> lines;
507 for (auto service : CLAMONACC_SERVICES) {
508 const auto logs = bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
509 "--system", "logs", service, "100"});
510 if (!logs.started) continue;
511 std::istringstream stream(logs.output);
512 std::string line;
513 while (std::getline(stream, line)) lines.push_back(line + "\n");
514
515 if (!lines.empty()) break;
516 }
517 return lines;
518}
static const char * CLAMONACC_SERVICES[]
Definition Backend.cpp:407

References CLAMONACC_SERVICES, and bg_process::run().

Referenced by LogPage::update_logs(), and ~Backend().

◆ getClamonaccStatus()

std::string Backend::getClamonaccStatus ( )
static

Definition at line 484 of file Backend.cpp.

484 {
485 return isClamonaccActive() ? _("Abilitata") : _("Disabilitata");
486}
static bool isClamonaccActive()
Definition Backend.cpp:467

References _, and isClamonaccActive().

Referenced by ~Backend().

◆ getCreds()

std::pair< std::string, std::string > Backend::getCreds ( const std::string & url)

Definition at line 2028 of file Backend.cpp.

2029{
2030 std::string path = getSambaCredsPath();
2031 std::ifstream f(path);
2032
2033 if (!f.is_open())
2034 return {"",""};
2035
2036 std::string line;
2037 std::string cur;
2038 bool found = false;
2039 std::string user, pass;
2040
2041 while (std::getline(f, line)) {
2042 if (line.empty()) continue;
2043
2044 if (line == "[" + url + "]") {
2045 found = true;
2046 continue;
2047 }
2048
2049 if (found) {
2050 if (line.rfind("user=", 0) == 0)
2051 user = b64_decode(line.substr(5));
2052
2053 else if (line.rfind("pass=", 0) == 0)
2054 pass = decrypt_pass(line.substr(5));
2055
2056 if (!user.empty() && !pass.empty())
2057 return { user, pass };
2058 }
2059 }
2060
2061 return {"",""};
2062}
static std::string decrypt_pass(const std::string &enc)
Definition Backend.cpp:107
static std::string b64_decode(const std::string &s)
Definition Backend.cpp:90
std::string getSambaCredsPath() const
Definition Backend.cpp:248

References b64_decode(), decrypt_pass(), and getSambaCredsPath().

Referenced by smb_auth_fn().

◆ getDbVersion()

std::string Backend::getDbVersion ( )
static

Definition at line 556 of file Backend.cpp.

556 {
557 namespace fs = std::filesystem;
558
559
560 std::vector<std::string> db_files = {
561 "/var/lib/clamav/daily.cld",
562 "/var/lib/clamav/daily.cvd",
563 "/var/lib/clamav/main.cld",
564 "/var/lib/clamav/main.cvd"
565 };
566
567 for (const auto &file : db_files) {
568 if (!fs::exists(file))
569 continue;
570
571 std::ifstream f(file, std::ios::binary);
572 if (!f.is_open())
573 continue;
574
575 std::string line;
576 std::getline(f, line);
577
578
579 size_t first_colon = line.find(':');
580 size_t second_colon = line.find(':', first_colon + 1);
581 size_t third_colon = line.find(':', second_colon + 1);
582
583 if (first_colon == std::string::npos || second_colon == std::string::npos)
584 continue;
585
586 std::string date_part = line.substr(first_colon + 1, second_colon - first_colon - 1);
587 std::string version = line.substr(second_colon + 1, third_colon - second_colon - 1);
588
589 std::ostringstream out;
590 out << "daily.cvd v" << version << " (" << date_part << ")";
591 return out.str();
592 }
593
594 return _("sconosciuta");
595}

References _.

Referenced by DashboardPage::update_from_logs(), and ~Backend().

◆ getFirewallType()

FirewallType Backend::getFirewallType ( ) const

Definition at line 3122 of file Backend.cpp.

3122 {
3123 return firewallType_;
3124}

References firewallType_.

◆ getGoogleSafeApiKey()

std::string Backend::getGoogleSafeApiKey ( ) const
inline

Definition at line 88 of file Backend.hpp.

88{ return googleSafeApiKey_; }

References googleSafeApiKey_.

◆ getLastUpdateDate()

std::string Backend::getLastUpdateDate ( )
static

Definition at line 522 of file Backend.cpp.

522 {
523 namespace fs = std::filesystem;
524 std::vector<std::string> db_files = {
525 "/var/lib/clamav/daily.cvd",
526 "/var/lib/clamav/main.cvd",
527 "/var/lib/clamav/bytecode.cvd",
528 "/var/lib/clamav/daily.cld",
529 "/var/lib/clamav/main.cld",
530 "/var/lib/clamav/bytecode.cld"
531 };
532
533 std::time_t newest = 0;
534 for (const auto& file : db_files) {
535 if (fs::exists(file)) {
536 auto ftime = fs::last_write_time(file);
537 auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
538 ftime - fs::file_time_type::clock::now() + std::chrono::system_clock::now());
539 std::time_t t = std::chrono::system_clock::to_time_t(sctp);
540 if (t > newest) newest = t;
541 }
542 }
543
544 if (newest == 0)
545 return _("sconosciuta");
546
547 char buf[64];
548 std::tm tmbuf{};
549 localtime_r(&newest, &tmbuf); // thread-safe
550 std::strftime(buf, sizeof(buf), "%d %B %Y %H:%M", &tmbuf);
551 return buf;
552}

References _.

Referenced by DashboardPage::update_from_logs(), and ~Backend().

◆ getOnAccessEvents()

std::vector< std::string > Backend::getOnAccessEvents ( )
static

Definition at line 620 of file Backend.cpp.

620 {
621 std::vector<std::string> events;
622 for (auto service : CLAMONACC_SERVICES) {
623 const auto logs = bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
624 "--system", "logs", service, "50"});
625 if (!logs.started) continue;
626 std::istringstream stream(logs.output);
627 std::string line;
628 while (std::getline(stream, line)) {
629 if (line.find("Scanned file") != std::string::npos ||
630 line.find("FOUND") != std::string::npos ||
631 line.find("Access denied") != std::string::npos ||
632 line.find("ERROR") != std::string::npos) {
633 events.push_back(line);
634 }
635 }
636
637 if (!events.empty()) break;
638 }
639 return events;
640}

References CLAMONACC_SERVICES, and bg_process::run().

Referenced by DashboardPage::update_from_logs(), and ~Backend().

◆ getOnAccessPaths()

std::vector< std::string > Backend::getOnAccessPaths ( )
static

Definition at line 603 of file Backend.cpp.

603 {
604 std::vector<std::string> paths;
605 std::ifstream f("/etc/clamav/clamd.conf");
606 if (!f.is_open()) return paths;
607
608 std::string line;
609 while (std::getline(f, line)) {
610 if (line.find("OnAccessIncludePath") == 0) {
611 auto pos = line.find(' ');
612 if (pos != std::string::npos) {
613 paths.push_back(line.substr(pos + 1));
614 }
615 }
616 }
617 return paths;
618}

Referenced by ~Backend().

◆ getPhishingPort()

int Backend::getPhishingPort ( ) const

Definition at line 2981 of file Backend.cpp.

2981 {
2982 return 5353;
2983}

◆ getQuarantinePath()

std::string Backend::getQuarantinePath ( )
static

Definition at line 496 of file Backend.cpp.

496 {
499 return quarantinePath;
500}
static std::string quarantinePath
Definition Backend.cpp:339

References ensureQuarantinePath(), loadQuarantinePathFromConfig(), and quarantinePath.

Referenced by ensureQuarantinePath(), Quarantine::getQuarantinePath(), and ~Backend().

◆ getSambaConfigPath()

std::string Backend::getSambaConfigPath ( ) const

Definition at line 1754 of file Backend.cpp.

1754 {
1755 const char* home = getenv("HOME");
1756 if (!home) return "/tmp/BastionGuard/samba.conf";
1757
1758 std::string cfgDir = std::string(home) + "/.config/BastionGuard";
1759 std::filesystem::create_directories(cfgDir);
1760
1761 return cfgDir + "/samba.conf";
1762}

Referenced by getSambaDirs(), isSambaEnabled(), removeSambaDir(), saveSambaConfig(), and setSambaEnabled().

◆ getSambaCredsPath()

std::string Backend::getSambaCredsPath ( ) const
private

Definition at line 248 of file Backend.cpp.

248 {
249 const char* home = getenv("HOME");
250 if (!home)
251 return "/tmp/BastionGuard/cred.conf";
252
253 std::string dir = std::string(home) + "/.config/BastionGuard";
254 std::filesystem::create_directories(dir);
255
256 return dir + "/cred.conf";
257}

Referenced by getCreds(), loadSMBCredentials(), and saveSMBCredentials().

◆ getSambaDirs()

std::vector< std::string > Backend::getSambaDirs ( )

Definition at line 1764 of file Backend.cpp.

1765{
1766 std::vector<std::string> out;
1767 std::ifstream f(getSambaConfigPath());
1768 if (!f.is_open()) return out;
1769
1770 std::string line;
1771 while (std::getline(f, line))
1772 {
1773 line = trim(line);
1774 if (line.empty()) continue;
1775 if (line == "enabled=true" || line == "enabled=false") continue;
1776
1777 out.push_back(line);
1778 }
1779 return out;
1780}
static std::string trim(const std::string &s)
Definition Backend.cpp:112
std::string getSambaConfigPath() const
Definition Backend.cpp:1754

References getSambaConfigPath(), and trim().

Referenced by SambaPage::onScanNow(), removeSambaDir(), and scanAllSambaDirs().

◆ getWhitelist()

std::vector< std::string > Backend::getWhitelist ( ) const

Definition at line 2909 of file Backend.cpp.

2909 {
2910 return whitelist_;
2911}

References whitelist_.

Referenced by ~Backend().

◆ initSambaClient()

void Backend::initSambaClient ( )
private

Definition at line 2273 of file Backend.cpp.

2274{
2275
2276}

Referenced by Backend().

◆ installClamdIfMissing()

bool Backend::installClamdIfMissing ( )
static

Definition at line 664 of file Backend.cpp.

664 {
665 if (isClamdInstalled()) {
666 std::cout << _("✔ clamd già installato\n");
667 return true;
668 }
669
670 std::string distro = detectDistro();
671 std::cout << _("⚠ clamd non trovato, tentativo installazione per ") << distro << "...\n";
672
673 int ret = -1;
674 if (distro == "debian" || distro == "ubuntu" || distro == "linuxmint") {
675 ret = installPackages({"apt-get", "update"});
676 if (ret == 0) ret = installPackages({"apt-get", "install", "-y", "clamav", "clamav-daemon"});
677 } else if (distro == "fedora") {
678 ret = installPackages({"dnf", "install", "-y", "clamav", "clamav-update"});
679 } else if (distro == "centos" || distro == "rhel") {
680 ret = installPackages({"yum", "install", "-y", "clamav", "clamav-update"});
681 } else if (distro == "opensuse" || distro == "suse") {
682 ret = installPackages({"zypper", "install", "-y", "clamav"});
683 } else if (distro == "arch" || distro == "manjaro" || distro == "endeavouros") {
684 ret = installPackages({"pacman", "-S", "--needed", "--noconfirm", "clamav"});
685 } else if (distro == "gentoo" || distro == "funtoo") {
686 ret = installPackages({"emerge", "app-antivirus/clamav"});
687 } else if (distro == "slackware") {
688 ret = installPackages({"slackpkg", "install", "clamav"});
689 } else {
690 std::cerr << _("❌ Distribuzione non riconosciuta: ") << distro << "\n";
691 return false;
692 }
693
694 if (ret == 0) {
695 std::cout << _("✔ clamd installato correttamente\n");
696 return true;
697 } else {
698 std::cerr << _("❌ Errore durante l’installazione di clamd\n");
699 return false;
700 }
701}
static int installPackages(const std::vector< std::string > &args)
Definition Backend.cpp:646
static std::string detectDistro()
Definition Backend.cpp:653
static bool isClamdInstalled()
Definition Backend.cpp:658

References _, detectDistro(), installPackages(), and isClamdInstalled().

Referenced by SettingsPage::onSave(), and ~Backend().

◆ instance()

◆ isAntiphishActive()

bool Backend::isAntiphishActive ( )

Definition at line 1618 of file Backend.cpp.

1618 {
1619 int ret = (bg_process::run({"/usr/libexec/bastionguard/bastionguard-service", "--system", "is-active", "BastionGuard-phishing-scanner.service"}).exit_code);
1620 return (ret == 0);
1621}

References bg_process::run().

◆ isAntiransomActive()

bool Backend::isAntiransomActive ( )
static

Definition at line 1613 of file Backend.cpp.

1613 {
1614 return bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
1615 "--user", "is-active", "BastionGuard-ransomware-scanner.service"}).ok();
1616}

References bg_process::run().

Referenced by ~Backend().

◆ isBankDomain()

bool Backend::isBankDomain ( const std::string & host) const

Definition at line 2962 of file Backend.cpp.

2962 {
2963 return std::find(whitelist_.begin(), whitelist_.end(), host) != whitelist_.end();
2964}

References whitelist_.

Referenced by ~Backend().

◆ isClamonaccActive()

bool Backend::isClamonaccActive ( )
static

Definition at line 467 of file Backend.cpp.

467 {
468 for (auto service : CLAMONACC_SERVICES) {
469 const auto check = bg_process::run({"/usr/libexec/bastionguard/bastionguard-service",
470 "--system", "is-active", service});
471 if (!check.started) continue;
472 std::string result = check.output;
473
474 // Normalizza
475 result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
476 result.erase(std::remove(result.begin(), result.end(), '\r'), result.end());
477
478 if (result == "active")
479 return true;
480 }
481 return false;
482}

References CLAMONACC_SERVICES, bg_process::Result::output, and bg_process::run().

Referenced by getClamonaccStatus(), DashboardPage::update_from_logs(), and ~Backend().

◆ isFirewallEnabled()

bool Backend::isFirewallEnabled ( ) const

Definition at line 3131 of file Backend.cpp.

3131 {
3132 return firewallEnabled_;
3133}

References firewallEnabled_.

Referenced by updatePhishLists().

◆ isGoogleSafeEnabled()

bool Backend::isGoogleSafeEnabled ( ) const
inline

Definition at line 85 of file Backend.hpp.

85{ return googleSafeEnabled_; }

References googleSafeEnabled_.

◆ isPhishAutoUpdateEnabled()

bool Backend::isPhishAutoUpdateEnabled ( )

Definition at line 1727 of file Backend.cpp.

1727 {
1728 int ret = (bg_process::run({"/usr/libexec/bastionguard/bastionguard-service", "--system", "is-enabled", "BastionGuard-phishing-updater.timer"}).exit_code);
1729 return (ret == 0);
1730}

References bg_process::run().

Referenced by ~Backend().

◆ isSambaEnabled()

bool Backend::isSambaEnabled ( )

Definition at line 260 of file Backend.cpp.

260 {
261 std::ifstream f(getSambaConfigPath());
262 if (!f.is_open()) return false;
263
264 std::string line;
265 while (std::getline(f, line)) {
266 if (line.find("enabled=true") != std::string::npos)
267 return true;
268 }
269 return false;
270}

References getSambaConfigPath().

Referenced by addSambaDir(), and removeSambaDir().

◆ isSambaScanRunning()

bool Backend::isSambaScanRunning ( )

Definition at line 241 of file Backend.cpp.

242{
243
244 int ret = (bg_process::run({"pgrep", "-f", "clamdscan"}).exit_code);
245 return (ret == 0);
246}

References bg_process::run().

Referenced by ~Backend().

◆ isValidSMB()

bool Backend::isValidSMB ( const std::string & url)
static

Definition at line 1919 of file Backend.cpp.

1920{
1921
1922 if (url.rfind("smb://", 0) != 0)
1923 return false;
1924
1925
1926 std::regex re(R"(smb:\/\/[^\/]+\/[^\/]+)");
1927 return std::regex_search(url, re);
1928}

Referenced by SambaPage::onAddDir().

◆ loadFirewallConfig()

void Backend::loadFirewallConfig ( )

Definition at line 3135 of file Backend.cpp.

3135 {
3136 const char* home = std::getenv("HOME");
3137 if (!home) return;
3138
3139 std::ifstream fin(std::string(home) + "/.config/BastionGuard/firewall.conf");
3140 if (!fin) return;
3141
3142 std::string line;
3143 while (std::getline(fin, line)) {
3144 if (line == "firewall_enabled=true")
3145 firewallEnabled_ = true;
3146 else if (line == "firewall_enabled=false")
3147 firewallEnabled_ = false;
3148 else if (line == "firewall_type=firewalld")
3150 else if (line == "firewall_type=ufw")
3152 }
3153}

References FIREWALLD, firewallEnabled_, firewallType_, and UFW.

Referenced by Backend().

◆ loadSMBCredentials()

void Backend::loadSMBCredentials ( )
private

Definition at line 1993 of file Backend.cpp.

1994{
1995 smb_credentials.clear();
1996
1997 std::string path = getSambaCredsPath();
1998 std::ifstream fin(path);
1999 if (!fin.is_open())
2000 return;
2001
2002 std::string line, cur;
2003
2004 while (std::getline(fin, line)) {
2005 if (line.empty()) continue;
2006
2007 if (line[0] == '[' && line.back() == ']') {
2008 cur = line.substr(1, line.size()-2);
2009 smb_credentials[cur] = {"",""};
2010 }
2011 else if (line.find("user=") == 0) {
2012 smb_credentials[cur].first = b64_decode(line.substr(5));
2013 }
2014 else if (line.find("pass=") == 0) {
2015 smb_credentials[cur].second = b64_decode(line.substr(5));
2016 }
2017 }
2018
2019 fin.close();
2020
2021 std::cout << _("✔ Credenziali SMB caricate: ")
2022 << smb_credentials.size() << " share\n";
2023}
std::map< std::string, std::pair< std::string, std::string > > smb_credentials
Definition Backend.hpp:123

References _, b64_decode(), getSambaCredsPath(), and smb_credentials.

Referenced by Backend().

◆ loadWhitelist()

void Backend::loadWhitelist ( )

Definition at line 2943 of file Backend.cpp.

2943 {
2944 whitelist_.clear();
2945 std::string path = Glib::get_home_dir() + "/.config/BastionGuard/whitelist.json";
2946 if (!std::filesystem::exists(path)) return;
2947
2948 try {
2949 std::ifstream f(path);
2950 json j;
2951 f >> j;
2952 if (j.is_array()) {
2953 for (auto& item : j)
2954 whitelist_.push_back(item.get<std::string>());
2955 }
2956 std::cout << _("✔ Whitelist caricata (") << whitelist_.size() << " voci)\n";
2957 } catch (const std::exception& e) {
2958 std::cerr << _("⚠ Errore caricamento whitelist: ") << e.what() << std::endl;
2959 }
2960}
nlohmann::json json
Definition Backend.cpp:2908

References _, and whitelist_.

Referenced by Backend(), mergeWhitelistSources(), and ~Backend().

◆ mergeWhitelistSources()

void Backend::mergeWhitelistSources ( )

Definition at line 1039 of file Backend.cpp.

1039 {
1040 // Ricarica whitelist.json in whitelist_
1041 loadWhitelist();
1042
1043 const std::string txtPath =
1044 Glib::get_home_dir() +
1045 "/.local/share/BastionGuard/phishing/whitelist.txt";
1046
1047 if (!std::filesystem::exists(txtPath)) return;
1048
1049 std::ifstream f(txtPath);
1050 if (!f.is_open()) return;
1051
1052 bool changed = false;
1053 std::string line;
1054 while (std::getline(f, line)) {
1055 // trim
1056 const char* ws = " \t\r\n\f\v";
1057 size_t s = line.find_first_not_of(ws);
1058 if (s == std::string::npos) continue;
1059 size_t e = line.find_last_not_of(ws);
1060 line = line.substr(s, e - s + 1);
1061 if (line.empty() || line[0] == '#') continue;
1062
1063 if (std::find(whitelist_.begin(), whitelist_.end(), line)
1064 == whitelist_.end()) {
1065 whitelist_.push_back(line);
1066 changed = true;
1067 }
1068 }
1069 f.close();
1070
1071 if (changed) {
1072 // Risalva JSON unificato
1073 saveWhitelist();
1074
1075 // Riscrive anche il .txt con il contenuto unificato
1076 std::ofstream out(txtPath, std::ios::trunc);
1077 if (out.is_open())
1078 for (const auto& d : whitelist_)
1079 out << d << "\n";
1080
1081 std::cout << _("[Backend] ✅ Whitelist merged: ")
1082 << whitelist_.size() << " voci totali\n";
1083 }
1084}

References _, loadWhitelist(), saveWhitelist(), and whitelist_.

Referenced by updatePhishLists(), and ~Backend().

◆ moveToQuarantine()

void Backend::moveToQuarantine ( const std::string & path)

Definition at line 2722 of file Backend.cpp.

2722 {
2723 // Tutte le richieste passano dalla stessa implementazione validata.
2724 // Quarantine::move() accetta esclusivamente file regolari e rifiuta
2725 // directory, symlink e altri oggetti del filesystem.
2726 const bool moved = Quarantine::move(path);
2727
2728 Glib::signal_idle().connect_once([path, moved]() {
2729 if (moved) {
2731 nullptr,
2732 _("File spostato in quarantena con successo:\n") + path,
2733 Gtk::MessageType::INFO);
2734 } else {
2736 nullptr,
2737 _("Impossibile spostare l'elemento in quarantena. "
2738 "Sono accettati esclusivamente file regolari:\n") + path,
2739 Gtk::MessageType::ERROR);
2740 }
2741 });
2742}
static bool move(const std::string &file)
static void show_message(Gtk::Window *parent, const std::string &message, Gtk::MessageType type=Gtk::MessageType::INFO, const std::string &secondary=std::string())
Definition Utils.cpp:33

References _, Quarantine::move(), and Utils::show_message().

Referenced by ~Backend().

◆ operator=()

Backend & Backend::operator= ( const Backend & )
privatedelete

References Backend().

◆ reload_dnsmasq()

bool Backend::reload_dnsmasq ( )

Definition at line 2966 of file Backend.cpp.

2966 {
2967 int ret = (bg_process::run({"pkexec", "/usr/libexec/bastionguard/bastionguard-service", "--system", "reload", "dnsmasq.service"}).exit_code);
2968 if (ret == 0) {
2969 std::cout << _("✔ dnsmasq ricaricato correttamente.\n");
2970 return true;
2971 } else {
2972 std::cerr << _("⚠️ Errore nel reload di dnsmasq.\n");
2973 return false;
2974 }
2975}

References _, and bg_process::run().

Referenced by ~Backend().

◆ removeFromWhitelist()

void Backend::removeFromWhitelist ( const std::string & domain)

Definition at line 2922 of file Backend.cpp.

2922 {
2923 whitelist_.erase(
2924 std::remove(whitelist_.begin(), whitelist_.end(), domain),
2925 whitelist_.end()
2926 );
2927 saveWhitelist();
2928}

References saveWhitelist(), and whitelist_.

Referenced by ~Backend().

◆ removeSambaDir()

bool Backend::removeSambaDir ( const std::string & dir)

Definition at line 2577 of file Backend.cpp.

2577 {
2578 auto dirs = getSambaDirs();
2579
2580 auto it = std::remove(dirs.begin(), dirs.end(), dir);
2581 if (it == dirs.end()) {
2582 std::cerr << "⚠️ " << _("Directory Samba non trovata: ") << dir << "\n";
2583 return false;
2584 }
2585
2586 dirs.erase(it, dirs.end());
2587
2588
2589 bool enabled = isSambaEnabled();
2590
2591
2592 std::ofstream f(getSambaConfigPath(), std::ios::trunc);
2593 if (!f.is_open()) {
2594 std::cerr << _("⚠️ Impossibile riscrivere la configurazione Samba\n");
2595 return false;
2596 }
2597
2598 f << "enabled=" << (enabled ? "true" : "false") << "\n";
2599
2600
2601 for (const auto& d : dirs)
2602 f << d << "\n";
2603
2604 std::cout << "✔ " << _("Rimossa directory Samba: ") << dir << "\n";
2605 return true;
2606}
bool isSambaEnabled()
Definition Backend.cpp:260
std::vector< std::string > getSambaDirs()
Definition Backend.cpp:1764

References _, getSambaConfigPath(), getSambaDirs(), and isSambaEnabled().

Referenced by addSambaDir().

◆ requestStopSambaScan()

void Backend::requestStopSambaScan ( )

Definition at line 2572 of file Backend.cpp.

2572 {
2573 samba_stop_requested = true;
2574}
std::atomic< bool > samba_stop_requested
Definition Backend.hpp:113

References samba_stop_requested.

Referenced by addSambaDir(), and SambaPage::onScanNow().

◆ resetSambaStop()

void Backend::resetSambaStop ( )

Definition at line 2568 of file Backend.cpp.

2568 {
2569 samba_stop_requested = false;
2570}

References samba_stop_requested.

Referenced by addSambaDir(), and SambaPage::onScanNow().

◆ resolveSambaDir()

std::string Backend::resolveSambaDir ( const std::string & path)
static

Definition at line 2065 of file Backend.cpp.

2066{
2067
2068 if (path.rfind("smb://", 0) == 0)
2069 return path;
2070
2071
2072 return path;
2073}

Referenced by SambaPage::onAddDir().

◆ saveFirewallConfig()

void Backend::saveFirewallConfig ( ) const

Definition at line 3155 of file Backend.cpp.

3155 {
3156 const char* home = std::getenv("HOME");
3157 if (!home) return;
3158
3159 std::ofstream fout;
3160 fout.open(std::string(home) + "/.config/BastionGuard/firewall.conf");
3161
3162 fout << "firewall_enabled=" << (firewallEnabled_ ? "true" : "false") << "\n";
3163
3164 switch (firewallType_) {
3166 fout << "firewall_type=firewalld\n"; break;
3167 case FirewallType::UFW:
3168 fout << "firewall_type=ufw\n"; break;
3169 default:
3170 break;
3171 }
3172}

References FIREWALLD, firewallEnabled_, firewallType_, and UFW.

Referenced by setFirewallEnabled(), and setFirewallType().

◆ saveGoogleSafeConfig()

void Backend::saveGoogleSafeConfig ( )

Definition at line 1648 of file Backend.cpp.

1648 {
1649 try {
1650 const char* home = getenv("HOME");
1651 if (!home) {
1652 std::cerr << "[Backend] ❌ " << _("Variabile HOME non trovata") << "\n";
1653 return;
1654 }
1655
1656 std::string cfgDir = std::string(home) + "/.config/BastionGuard";
1657 std::string cfgPath = cfgDir + "/googlesafe.conf";
1658
1659 std::filesystem::create_directories(cfgDir);
1660
1661 std::ofstream fout(cfgPath, std::ios::trunc);
1662 if (!fout.is_open()) {
1663 std::cerr << "[Backend] ❌ " << _("Impossibile aprire il file di configurazione per scrittura: ")
1664 << cfgPath << "\n";
1665 return;
1666 }
1667
1668 fout << "# " << _("Configurazione Google Safe Browsing") << "\n";
1669 fout << "google_safe_enabled=" << (googleSafeEnabled_ ? "true" : "false") << "\n";
1670 fout << "google_safe_key=" << googleSafeApiKey_ << "\n";
1671 fout.close();
1672
1673 std::cout << "[Backend] ✔ " << _("Configurazione Google Safe salvata in ") << cfgPath << "\n";
1674 } catch (const std::exception& ex) {
1675 std::cerr << "[Backend] ⚠ " << _("Errore durante il salvataggio della configurazione Google Safe: ")
1676 << ex.what() << "\n";
1677 }
1678}

References _, googleSafeApiKey_, and googleSafeEnabled_.

Referenced by SettingsPage::build_antiphish_tab().

◆ saveSambaConfig()

void Backend::saveSambaConfig ( bool enabled,
const std::vector< std::string > & dirs )

Definition at line 2608 of file Backend.cpp.

2609{
2610 std::ofstream f(getSambaConfigPath(), std::ios::trunc);
2611 f << "enabled=" << (enabled ? "true" : "false") << "\n";
2612
2613 for (auto& d : dirs)
2614 f << trim(d) << "\n";
2615}

References getSambaConfigPath(), and trim().

Referenced by SambaPage::saveConfig().

◆ saveSMBCredentials()

void Backend::saveSMBCredentials ( const std::string & url,
const std::string & user,
const std::string & pass )

Definition at line 1930 of file Backend.cpp.

1933{
1934
1935 std::regex re(R"(smb:\/\/([^\/]+)\/([^\/]+))");
1936 std::smatch m;
1937
1938 std::string key = url;
1939 if (std::regex_search(url, m, re)) {
1940 key = "smb://" + m[1].str() + "/" + m[2].str();
1941 }
1942
1943 smb_credentials[key] = { user, pass };
1944
1945
1946 std::string path = getSambaCredsPath();
1947 std::ifstream fin(path);
1948
1949 std::map<std::string,std::pair<std::string,std::string>> all;
1950
1951 // Carica file esistente
1952 if (fin.is_open()) {
1953 std::string line;
1954 std::string cur;
1955
1956 while (std::getline(fin, line)) {
1957 if (line.empty()) continue;
1958
1959 if (line[0] == '[' && line.back() == ']') {
1960 cur = line.substr(1, line.size()-2);
1961 all[cur] = {"",""};
1962 }
1963 else if (line.find("user=") == 0) {
1964 all[cur].first = b64_decode(line.substr(5));
1965 }
1966 else if (line.find("pass=") == 0) {
1967 all[cur].second = decrypt_pass(line.substr(5));
1968 }
1969 }
1970 }
1971 fin.close();
1972
1973
1974 all[key] = { user, pass };
1975
1976
1977 std::ofstream fout(path, std::ios::trunc);
1978 if (!fout.is_open()) {
1979 std::cerr << _("❌ Impossibile scrivere credenziali SMB\n");
1980 return;
1981 }
1982
1983 for (auto &kv : all) {
1984 fout << "[" << kv.first << "]\n";
1985 fout << "user=" << b64_encode(kv.second.first) << "\n";
1986 fout << "pass=" << encrypt_pass(kv.second.second) << "\n\n";
1987 }
1988
1989 fout.close();
1990 std::cout << _("✔ Credenziali SMB salvate in modo sicuro (XOR + Base64)\n");
1991}
static std::string encrypt_pass(const std::string &pass)
Definition Backend.cpp:103
static std::string b64_encode(const std::string &s)
Definition Backend.cpp:86

References _, b64_decode(), b64_encode(), decrypt_pass(), encrypt_pass(), getSambaCredsPath(), and smb_credentials.

Referenced by SambaPage::onAddDir().

◆ saveWhitelist()

void Backend::saveWhitelist ( ) const

Definition at line 2930 of file Backend.cpp.

2930 {
2931 try {
2932 std::filesystem::create_directories(Glib::get_home_dir() + "/.config/BastionGuard");
2933 std::ofstream f(Glib::get_home_dir() + "/.config/BastionGuard/whitelist.json", std::ios::trunc);
2934 json j(whitelist_);
2935 f << j.dump(2);
2936 f.close();
2937 std::cout << _("✔ Whitelist salvata (") << whitelist_.size() << " voci)\n";
2938 } catch (const std::exception& e) {
2939 std::cerr << _("❌ Errore salvataggio whitelist: ") << e.what() << std::endl;
2940 }
2941}

References _, and whitelist_.

Referenced by addToWhitelist(), mergeWhitelistSources(), removeFromWhitelist(), and ~Backend().

◆ scanAllSambaDirs()

void Backend::scanAllSambaDirs ( )

Definition at line 2773 of file Backend.cpp.

2774{
2775 samba_stop_requested = false;
2776
2777 auto dirs = getSambaDirs();
2778 if (dirs.empty()) {
2780 samba_progress_callback("Nessuna directory Samba configurata.", 1.0f);
2781 return;
2782 }
2783
2784 for (const auto& dir : dirs)
2785 {
2787 break;
2788
2789 scanSambaDir(dir);
2790 }
2791
2793 samba_progress_callback("Tutte le scansioni completate.", 1.0f);
2794}
std::function< void(const std::string &, float)> samba_progress_callback
Definition Backend.hpp:150
void scanSambaDir(const std::string &dir)
Definition Backend.cpp:2280

References getSambaDirs(), samba_progress_callback, samba_stop_requested, and scanSambaDir().

Referenced by addSambaDir().

◆ scanSambaDir()

void Backend::scanSambaDir ( const std::string & dir)

Definition at line 2280 of file Backend.cpp.

2281{
2282 namespace fs = std::filesystem;
2283
2284 samba_stop_requested = false;
2285 samba_scan_state = {};
2287 samba_last_progress = 0.0f;
2288
2289
2290 std::string scanPath = trim(dirInput);
2291
2292 // Mantieni copia originale SENZA "/" finale (serve per FOUND)
2293 std::string originalSmbRoot = scanPath;
2294 if (!originalSmbRoot.empty() && originalSmbRoot.back() == '/')
2295 originalSmbRoot.pop_back();
2296
2297 // Aggiungi "/" finale per scansione interna
2298 if (scanPath.rfind("smb://", 0) == 0)
2299 {
2300 if (scanPath.back() != '/')
2301 scanPath += '/';
2302 }
2303
2304 auto push_log = [&](const std::string& s)
2305 {
2306 samba_scan_state.log.push_back(s);
2309 };
2310
2311 push_log(_("=== Scansione Samba: ") + scanPath + " ===");
2312
2313 bool isSmb = scanPath.rfind("smb://", 0) == 0;
2314
2315 std::vector<fs::path> files;
2316 std::vector<std::string> smbFiles;
2317
2318 SMBCCTX* ctx = nullptr;
2319
2320
2321 if (isSmb)
2322 {
2323 push_log(_("Percorso SMB rilevato. Creo contesto SMB..."));
2324
2325 ctx = createThreadSmbContext();
2326 if (!ctx)
2327 {
2328 push_log(_("ERRORE: impossibile creare contesto SMB."));
2330 return;
2331 }
2332
2333 smb_collect_files(ctx, scanPath, smbFiles);
2334
2335 if (smbFiles.empty())
2336 {
2337 push_log(_("ERRORE: impossibile elencare la share SMB."));
2339 return;
2340 }
2341
2342 for (auto& f : smbFiles)
2343 files.push_back(f);
2344
2345 push_log(_("File trovati via SMB: ") + std::to_string(files.size()));
2346 }
2347
2348 else
2349 {
2350 if (!fs::exists(scanPath))
2351 {
2352 push_log(_("ERRORE: directory locale non trovata."));
2354 return;
2355 }
2356
2357 try
2358 {
2359 for (auto& e :
2360 fs::recursive_directory_iterator(scanPath, fs::directory_options::skip_permission_denied))
2361 {
2362 if (e.is_regular_file())
2363 files.push_back(e.path());
2364 }
2365 }
2366 catch (...)
2367 {
2368 push_log(_("ERRORE: impossibile scansionare la directory locale."));
2369 }
2370
2371 if (files.empty())
2372 {
2373 push_log(_("Nessun file da scansionare."));
2375 return;
2376 }
2377
2378 push_log(_("File trovati localmente: ") + std::to_string(files.size()));
2379 }
2380
2381
2382
2383 std::string clamdscanPath;
2384 const char* paths[] = {
2385 "/usr/bin/clamdscan",
2386 "/usr/local/bin/clamdscan",
2387 "/bin/clamdscan"
2388 };
2389 for (auto p : paths)
2390 if (fs::exists(p)) { clamdscanPath = p; break; }
2391
2392 if (clamdscanPath.empty()) {
2393 push_log(_("ERRORE: clamdscan non trovato."));
2395 return;
2396 }
2397
2398
2399 if ((bg_process::run({"pgrep", "-f", "clamd"}).exit_code) != 0 &&
2400 (bg_process::run({"pgrep", "-f", "clamav-daemon"}).exit_code) != 0)
2401 {
2402 push_log(_("ERRORE: il demone clamd non è attivo."));
2404 return;
2405 }
2406
2407 push_log(_("Demone ClamAV rilevato."));
2408
2409
2410 //-----------------------------------------------------------
2411 // Temp directory
2412 //-----------------------------------------------------------
2413 fs::path tempDir = make_temp_scan_dir();
2414
2415 if (tempDir.empty()) {
2416 push_log(_("ERRORE: impossibile determinare una directory temporanea valida (path vuoto)."));
2418 return;
2419 }
2420
2421 std::error_code ec;
2422 if (!fs::exists(tempDir, ec) || ec) {
2423 push_log(_("ERRORE: directory temporanea non esistente o non accessibile: ") + tempDir.string());
2424 if (ec) push_log(std::string("std::filesystem error: ") + ec.message());
2426 return;
2427 }
2428
2429 if (!fs::is_directory(tempDir, ec) || ec) {
2430 push_log(_("ERRORE: path temporaneo non è una directory valida: ") + tempDir.string());
2431 if (ec) push_log(std::string("std::filesystem error: ") + ec.message());
2433 return;
2434 }
2435
2436 samba_last_temp_dir = tempDir.string();
2437 push_log("Temp dir: " + samba_last_temp_dir);
2438
2439
2440
2441 //-----------------------------------------------------------
2442 // Copia file
2443 //-----------------------------------------------------------
2444 size_t total = files.size();
2445 size_t copied = 0;
2446
2447 push_log(_("Trovati ") + std::to_string(total) + _(" file da copiare."));
2448
2449 for (const auto& src : files)
2450 {
2451 if (samba_stop_requested) goto end_scan;
2452
2453 fs::path dest;
2454
2455 if (!isSmb)
2456 {
2457 fs::path rel = fs::relative(src, scanPath);
2458 dest = tempDir / rel;
2459
2460 fs::create_directories(dest.parent_path());
2461
2462 std::error_code ec;
2463 fs::copy_file(src, dest, fs::copy_options::overwrite_existing, ec);
2464 if (ec)
2465 {
2466 push_log(_("ERRORE copia locale: ") + rel.string());
2467 continue;
2468 }
2469 }
2470 else
2471 {
2472 std::string smbFile = src.string();
2473
2474 std::string relative = smbFile.substr(scanPath.size());
2475 if (!relative.empty() && relative[0] == '/')
2476 relative.erase(0,1);
2477
2478 dest = tempDir / relative;
2479 fs::create_directories(dest.parent_path());
2480
2481 bool ok = smb_read_file_with_ctx(
2482 ctx,
2483 smbFile,
2484 [&](const char* data, size_t n)
2485 {
2486 std::ofstream out(dest, std::ios::binary | std::ios::app);
2487 if (!out.is_open()) return false;
2488 out.write(data, n);
2489 return true;
2490 }
2491 );
2492
2493 if (!ok)
2494 {
2495 push_log(_("ERRORE lettura SMB: ") + smbFile);
2496 continue;
2497 }
2498 }
2499
2500 samba_scan_state.current_file = src.string();
2501 copied++;
2502
2503 samba_last_progress = float(copied) / float(total) * 0.30f;
2504 push_log(_("Copiato: ") + src.string());
2505 }
2506
2508 goto end_scan;
2509
2510
2511
2512 {
2513 // Paths are supplied as distinct argv entries and cannot alter command syntax.
2514 push_log(_("Eseguo scansione ClamAV: ") + tempDir.string());
2515 size_t scanned = 0;
2516 auto scan = bg_process::run({clamdscanPath, "--fdpass", "--no-summary", "--multiscan",
2517 "--", tempDir.string()}, true, 32U * 1024U * 1024U, {},
2518 [&](const std::string& line) {
2519 if (samba_stop_requested) return false;
2520
2521 push_log("ClamAV: " + line);
2522
2523 std::string filename = line.substr(0, line.find(':'));
2524 samba_scan_state.current_file = filename;
2525
2526 if (line.find("FOUND") != std::string::npos)
2527 {
2528 fs::path tmpFile = filename;
2529 fs::path rel = fs::relative(tmpFile, tempDir);
2530
2531
2532 std::string orig = originalSmbRoot + "/" + rel.string();
2533
2535 push_log("INFETTO: " + orig);
2536
2537 sendRansomwareAlert(orig, "Virus");
2538 }
2539
2540 scanned++;
2541 samba_last_progress = 0.30f + 0.70f * (float(scanned) / float(total));
2542 return true;
2543 });
2544 if (!scan.started || scan.truncated) push_log(_("ERRORE: scansione ClamAV non completata."));
2545 std::this_thread::sleep_for(std::chrono::milliseconds(300));
2546 }
2547
2548
2549 end_scan:
2550
2552
2553 push_log(_("=== Scansione completata ==="));
2554 push_log(_("File analizzati: ") + std::to_string(files.size()));
2555 push_log(_("File infetti: ") + std::to_string(samba_scan_state.infected));
2556
2558 samba_progress_callback(_("Scansione completata."), 1.0f);
2559
2560 try { fs::remove_all(tempDir); } catch (...) {}
2561
2562 samba_last_temp_dir.clear();
2563}
static std::filesystem::path make_temp_scan_dir()
Definition Backend.cpp:1803
void smb_collect_files(SMBCCTX *ctx, const std::string &url, std::vector< std::string > &out)
Definition Backend.cpp:2076
void sendRansomwareAlert(const std::string &path, const std::string &family)
Definition Backend.cpp:2658
SMBCCTX * createThreadSmbContext()
Definition Backend.cpp:1871
bool smb_read_file_with_ctx(SMBCCTX *ctx, const std::string &smbPath, std::function< bool(const char *, size_t)>)
Definition Backend.cpp:2153

References _, createThreadSmbContext(), Backend::SambaScanState::current_file, bg_process::Result::exit_code, Backend::SambaScanState::infected, Backend::SambaScanState::log, make_temp_scan_dir(), bg_process::run(), samba_last_progress, samba_last_temp_dir, samba_progress_callback, samba_scan_state, samba_stop_requested, Backend::SambaScanState::scan_active, sendRansomwareAlert(), smb_collect_files(), smb_read_file_with_ctx(), and trim().

Referenced by SambaPage::onScanNow(), and scanAllSambaDirs().

◆ scheduleFirewallApply()

void Backend::scheduleFirewallApply ( const std::string & inputPath)

Definition at line 3207 of file Backend.cpp.

3207 {
3208 static std::atomic<bool> pending{false};
3209
3210 if (pending.exchange(true)) {
3211 ::unlink(inputPath.c_str());
3212 return;
3213 }
3214
3215 std::thread([inputPath] {
3216 std::this_thread::sleep_for(std::chrono::seconds(2));
3217
3218 const int exitCode = run_firewall_helper(inputPath);
3219 if (exitCode != 0) {
3220 std::cerr << _("[Firewall] Applicazione helper fallita, codice: ")
3221 << exitCode << "\n";
3222 ::unlink(inputPath.c_str());
3223 }
3224
3225 pending.store(false);
3226 }).detach();
3227}
int run_firewall_helper(const std::string &inputPath)
Definition Backend.cpp:3060

References _.

Referenced by applyFirewallFromBlacklist(), and applyFirewallFromPhishingBlacklist().

◆ sendRansomwareAlert()

void Backend::sendRansomwareAlert ( const std::string & path,
const std::string & family )

Definition at line 2658 of file Backend.cpp.

2659{
2660 try {
2661 auto conn = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::SESSION);
2662
2663
2664 auto args = Glib::VariantContainerBase::create_tuple({
2665 Glib::Variant<Glib::ustring>::create("org.BastionGuard.Ransomware.Alert")
2666 });
2667
2668 bool nameHasOwner = false;
2669 try {
2670 auto reply = conn->call_sync(
2671 "/org/freedesktop/DBus",
2672 "org.freedesktop.DBus",
2673 "NameHasOwner",
2674 args,
2675 "org.freedesktop.DBus"
2676 );
2677
2678 Glib::Variant<bool> result;
2679 reply.get_child(result, 0);
2680 nameHasOwner = result.get();
2681 } catch (const Glib::Error& ex) {
2682 std::cerr << _("⚠️ Impossibile verificare il listener D-Bus: ")
2683 << ex.what() << std::endl;
2684 }
2685
2686 if (!nameHasOwner) {
2687 std::cerr << _("⚠️ Listener org.BastionGuard.Ransomware.Alert non attivo — nessun popup verrà mostrato.") << std::endl;
2688 return;
2689 }
2690
2691
2692 auto parameters = Glib::VariantContainerBase::create_tuple({
2693 Glib::Variant<Glib::ustring>::create(path),
2694 Glib::Variant<Glib::ustring>::create(family)
2695 });
2696
2697
2698 conn->call_sync(
2699 "/org/BastionGuard/ransomware/alert",
2700 "org.BastionGuard.Ransomware.Alert",
2701 "ShowAlert",
2702 parameters,
2703 "org.BastionGuard.Ransomware.Alert",
2704 -1,
2705 Gio::DBus::CallFlags::NONE,
2706 Glib::VariantType()
2707 );
2708
2709 std::cout << Glib::ustring::compose(
2710 _("📢 Alert ransomware inviato via D-Bus:\n - File: %1\n - Famiglia: %2"),
2711 path, family
2712 ) << std::endl;
2713 }
2714 catch (const Glib::Error& ex) {
2715 std::cerr << _("❌ Errore nell'invio alert D-Bus: ") << ex.what() << std::endl;
2716 }
2717}

References _.

Referenced by scanSambaDir(), and ~Backend().

◆ setFirewallEnabled()

void Backend::setFirewallEnabled ( bool enabled)

Definition at line 3126 of file Backend.cpp.

3126 {
3127 firewallEnabled_ = enabled;
3129}
void saveFirewallConfig() const
Definition Backend.cpp:3155

References firewallEnabled_, and saveFirewallConfig().

Referenced by SettingsPage::build_antiphish_tab().

◆ setFirewallType()

void Backend::setFirewallType ( FirewallType fw)

Definition at line 3112 of file Backend.cpp.

3112 {
3113 firewallType_ = fw;
3114
3115 if (fw != FirewallType::NONE)
3116 firewallEnabled_ = true;
3117
3119}

References firewallEnabled_, firewallType_, NONE, and saveFirewallConfig().

◆ setGoogleSafeApiKey()

void Backend::setGoogleSafeApiKey ( const std::string & key)
inline

Definition at line 87 of file Backend.hpp.

87{ googleSafeApiKey_ = key; }

References googleSafeApiKey_.

Referenced by SettingsPage::build_antiphish_tab().

◆ setGoogleSafeEnabled()

void Backend::setGoogleSafeEnabled ( bool enabled)
inline

Definition at line 86 of file Backend.hpp.

86{ googleSafeEnabled_ = enabled; }

References googleSafeEnabled_.

Referenced by SettingsPage::build_antiphish_tab().

◆ setPhishingPort()

void Backend::setPhishingPort ( int port)

Definition at line 2977 of file Backend.cpp.

2977 {
2978 std::cout << _("[Backend] setPhishingPort(") << port << _(") — funzione non più usata.") << std::endl;
2979}

References _.

◆ setQuarantinePath()

void Backend::setQuarantinePath ( const std::string & path)
static

Definition at line 490 of file Backend.cpp.

490 {
491 quarantinePath = path;
494}
static void persistQuarantinePath(const std::string &path)
Definition Backend.cpp:355

References ensureQuarantinePath(), persistQuarantinePath(), and quarantinePath.

Referenced by SettingsPage::onQuarantineClicked(), and ~Backend().

◆ setSambaEnabled()

void Backend::setSambaEnabled ( bool enabled)

Definition at line 272 of file Backend.cpp.

272 {
273 std::ofstream f(getSambaConfigPath(), std::ios::trunc);
274 if (!f.is_open()) {
275 std::cerr << "⚠️ " << _("Impossibile scrivere la configurazione Samba") << "\n";
276 return;
277 }
278
279 f << "enabled=" << (enabled ? "true" : "false") << "\n";
280 f.close();
281
282 std::cout << "ℹ️ " << _("Stato Samba salvato: ")
283 << (enabled ? _("abilitato") : _("disabilitato")) << "\n";
284}

References _, and getSambaConfigPath().

Referenced by addSambaDir().

◆ setupAlertListener()

void Backend::setupAlertListener ( )

Definition at line 2620 of file Backend.cpp.

2621{
2622 std::cout << _("🔧 Inizializzazione canale D-Bus per invio alert...") << std::endl;
2623
2624 try {
2625 auto connection = Gio::DBus::Connection::get_sync(Gio::DBus::BusType::SESSION);
2626
2627
2628 auto result = connection->call_sync(
2629 "/org/freedesktop/DBus",
2630 "org.freedesktop.DBus",
2631 "NameHasOwner",
2632 Glib::VariantContainerBase::create_tuple({
2633 Glib::Variant<Glib::ustring>::create("org.BastionGuard.Ransomware.Alert")
2634 }),
2635 "org.freedesktop.DBus",
2636 -1,
2637 Gio::DBus::CallFlags::NONE,
2638 Glib::VariantType()
2639 );
2640
2641 bool listener_attivo = false;
2642 if (result.gobj() != nullptr) {
2643 Glib::Variant<bool> active;
2644 result.get_child(active, 0);
2645 listener_attivo = active.get();
2646 }
2647
2648 if (listener_attivo)
2649 std::cout << _("🟢 Servizio BastionGuard-ransomware-alert trovato su D-Bus.") << std::endl;
2650 else
2651 std::cerr << _("⚠️ Servizio BastionGuard-ransomware-alert non attivo. Gli avvisi non verranno mostrati.") << std::endl;
2652
2653 } catch (const Glib::Error& ex) {
2654 std::cerr << _("❌ Errore inizializzazione D-Bus: ") << ex.what() << std::endl;
2655 }
2656}

References _.

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

◆ signal_antiphish_event()

sigc::signal< void(const std::string &)> & Backend::signal_antiphish_event ( )

Definition at line 1641 of file Backend.cpp.

1641 {
1642 return antiphish_signal_;
1643}

References antiphish_signal_.

◆ signal_antiransom_event()

sigc::signal< void(const std::string &)> & Backend::signal_antiransom_event ( )

Definition at line 1623 of file Backend.cpp.

1623 {
1624 return antiransom_signal_;
1625}
sigc::signal< void(const std::string &)> antiransom_signal_
Definition Backend.hpp:199

References antiransom_signal_.

Referenced by ~Backend().

◆ smb_auth_fn()

void Backend::smb_auth_fn ( SMBCCTX * context,
const char * srv,
const char * shr,
char * wg,
int wglen,
char * un,
int unlen,
char * pw,
int pwlen )
static

Definition at line 1891 of file Backend.cpp.

1897{
1898 std::string key = "smb://" + std::string(srv) + "/" + std::string(shr);
1899
1900 auto creds = Backend::instance().getCreds(key);
1901
1902 std::string user = creds.first;
1903 std::string pass = creds.second;
1904
1905 if (user.empty()) user = "guest";
1906 if (pass.empty()) pass = "";
1907
1908 strncpy(un, user.c_str(), unlen - 1);
1909 un[unlen - 1] = '\0';
1910
1911 strncpy(pw, pass.c_str(), pwlen - 1);
1912 pw[pwlen - 1] = '\0';
1913
1914 strncpy(wg, "WORKGROUP", wglen - 1);
1915 wg[wglen - 1] = '\0';
1916}
static Backend & instance()
Definition Backend.cpp:830
std::pair< std::string, std::string > getCreds(const std::string &url)
Definition Backend.cpp:2028

References getCreds(), and instance().

Referenced by createThreadSmbContext().

◆ smb_collect_files()

void Backend::smb_collect_files ( SMBCCTX * ctx,
const std::string & url,
std::vector< std::string > & out )

Definition at line 2076 of file Backend.cpp.

2079{
2080 if (!ctx) {
2081 std::cerr << _("SMB ERROR: contesto SMB nullo\n");
2082 return;
2083 }
2084
2085 smb_collect_files_impl(ctx, url, out);
2086}
void smb_collect_files_impl(SMBCCTX *ctx, const std::string &url, std::vector< std::string > &out)
Definition Backend.cpp:2091

References _, and smb_collect_files_impl().

Referenced by scanSambaDir().

◆ smb_collect_files_impl()

void Backend::smb_collect_files_impl ( SMBCCTX * ctx,
const std::string & url,
std::vector< std::string > & out )

Definition at line 2091 of file Backend.cpp.

2095{
2096 if (!ctx) {
2097 std::cerr << "SMB ERROR: ctx NULL in smb_collect_files_impl\n";
2098 return;
2099 }
2100
2101
2102 auto fn_opendir = smbc_getFunctionOpendir(ctx);
2103 auto fn_readdir = smbc_getFunctionReaddir(ctx);
2104 auto fn_closedir = smbc_getFunctionClosedir(ctx);
2105
2106 if (!fn_opendir || !fn_readdir || !fn_closedir) {
2107 std::cerr << _("SMB ERROR: funzioni SMB mancanti (contesto non valido)\n");
2108 return;
2109 }
2110
2111
2112 SMBCFILE* dir = fn_opendir(ctx, url.c_str());
2113 if (!dir) {
2114 int err = errno;
2115 std::cerr << _("SMB ERROR: impossibile aprire ") << url
2116 << " (errno=" << err << ")\n";
2117 return;
2118 }
2119
2120 struct smbc_dirent* ent = nullptr;
2121
2122
2123 while ((ent = fn_readdir(ctx, dir)) != nullptr)
2124 {
2125 if (!ent) continue;
2126
2127 const char* name = ent->name;
2128 if (!name || name[0] == '.') continue; // ignora . e ..
2129
2130 std::string full = url;
2131 if (full.back() != '/')
2132 full += "/";
2133 full += name;
2134
2135 switch (ent->smbc_type)
2136 {
2137 case SMBC_FILE:
2138 out.push_back(full);
2139 break;
2140
2141 case SMBC_DIR:
2142 smb_collect_files_impl(ctx, full, out);
2143 break;
2144
2145 default:
2146 break;
2147 }
2148 }
2149
2150 fn_closedir(ctx, dir);
2151}

References _, and smb_collect_files_impl().

Referenced by smb_collect_files(), and smb_collect_files_impl().

◆ smb_copy_file()

bool Backend::smb_copy_file ( const std::string & smbPath,
const std::filesystem::path & dest )

Definition at line 2200 of file Backend.cpp.

2202{
2203 namespace fs = std::filesystem;
2204
2205 SMBCCTX* ctx = createThreadSmbContext();
2206 if (!ctx) {
2207 std::cerr << _("SMB ERROR: impossibile creare contesto SMB\n");
2208 return false;
2209 }
2210
2211 // Crea directory destinazione
2212 std::error_code ec;
2213 fs::create_directories(dest.parent_path(), ec);
2214 if (ec) {
2215 std::cerr << _("SMB ERROR: impossibile creare directory ")
2216 << dest.parent_path().string()
2217 << " (" << ec.message() << ")\n";
2218 smbc_free_context(ctx, 1);
2219 return false;
2220 }
2221
2222 fs::permissions(dest.parent_path(),
2223 fs::perms::owner_all |
2224 fs::perms::group_read | fs::perms::group_exec |
2225 fs::perms::others_read | fs::perms::others_exec,
2226 fs::perm_options::add,
2227 ec);
2228
2229
2230 std::ofstream out(dest, std::ios::binary | std::ios::trunc);
2231 if (!out.is_open()) {
2232 std::cerr << _("SMB ERROR: impossibile aprire file locale ")
2233 << dest.string() << _(" per scrittura\n");
2234 smbc_free_context(ctx, 1);
2235 return false;
2236 }
2237
2238 bool ok = smb_read_file_with_ctx(
2239 ctx,
2240 smbPath,
2241 [&](const char* data, size_t n) -> bool
2242 {
2243 out.write(data, static_cast<std::streamsize>(n));
2244 return out.good();
2245 }
2246 );
2247
2248 out.flush();
2249 out.close();
2250
2251 smbc_free_context(ctx, 1);
2252
2253 if (!ok) {
2254 std::cerr << _("SMB ERROR: copia fallita per: ") << smbPath << "\n";
2255 std::error_code ec2;
2256 fs::remove(dest, ec2);
2257 return false;
2258 }
2259
2260
2261 fs::permissions(dest,
2262 fs::perms::owner_read | fs::perms::owner_write |
2263 fs::perms::group_read |
2264 fs::perms::others_read,
2265 fs::perm_options::replace,
2266 ec);
2267
2268 return true;
2269}

References _, createThreadSmbContext(), and smb_read_file_with_ctx().

◆ smb_read_file_with_ctx()

bool Backend::smb_read_file_with_ctx ( SMBCCTX * ctx,
const std::string & smbPath,
std::function< bool(const char *, size_t)> onChunk )

Definition at line 2153 of file Backend.cpp.

2157{
2158 if (!ctx) {
2159 std::cerr << _("SMB ERROR: ctx nullo\n");
2160 return false;
2161 }
2162
2163
2164 auto fn_open = smbc_getFunctionOpen (ctx);
2165 auto fn_read = smbc_getFunctionRead (ctx);
2166 auto fn_close = smbc_getFunctionClose (ctx);
2167
2168 if (!fn_open || !fn_read || !fn_close)
2169 {
2170 std::cerr << _("SMB ERROR: funzioni SMB non disponibili\n");
2171 return false;
2172 }
2173
2174
2175 SMBCFILE* fd = fn_open(ctx, smbPath.c_str(), O_RDONLY, 0);
2176 if (!fd) {
2177 std::cerr << _("SMB ERROR: impossibile aprire file: ") << smbPath << "\n";
2178 return false;
2179 }
2180
2181 char buffer[8192];
2182 ssize_t n = 0;
2183
2184 while ((n = fn_read(ctx, fd, buffer, sizeof(buffer))) > 0)
2185 {
2186 if (!onChunk(buffer, (size_t)n))
2187 {
2188 std::cerr << _("SMB ERROR: callback fallita\n");
2189 fn_close(ctx, fd);
2190 return false;
2191 }
2192 }
2193
2194 fn_close(ctx, fd);
2195 return true;
2196}

References _.

Referenced by scanSambaDir(), and smb_copy_file().

◆ start_antiphish()

void Backend::start_antiphish ( )

Definition at line 1520 of file Backend.cpp.

1520 {
1521 std::cout << _("▶ Avvio protezione Anti-Phishing...\n");
1522 int ret = (bg_process::run({"pkexec", "/usr/libexec/bastionguard/bastionguard-service", "--system", "start", "BastionGuard-phishing-scanner.service"}).exit_code);
1523 if (ret == 0) {
1524 std::cout << _("✔ Servizio Anti-Phishing avviato\n");
1525 } else {
1526 std::cerr << _("❌ Errore avvio servizio Anti-Phishing\n");
1527 }
1528}

References _, and bg_process::run().

Referenced by SettingsPage::onAntiphishToggled().

◆ start_antiransom()

void Backend::start_antiransom ( )

Definition at line 837 of file Backend.cpp.

837 {
838 const int ret = bg_process::run({"runuser", "-u", Glib::get_user_name(), "--",
839 "/usr/libexec/bastionguard/bastionguard-service",
840 "--user", "start", "BastionGuard-ransomware-scanner.service"}).exit_code;
841 if (ret == 0)
842 std::cout << _("✔ Servizio Anti-Ransomware avviato\n");
843 else
844 std::cerr << _("❌ Errore avvio servizio Anti-Ransomware\n");
845}

References _, and bg_process::run().

Referenced by SettingsPage::onAntiransomToggled(), and ~Backend().

◆ stop_antiphish()

void Backend::stop_antiphish ( )

Definition at line 1530 of file Backend.cpp.

1530 {
1531 std::cout << _("⏹ Arresto protezione Anti-Phishing...\n");
1532 int ret = (bg_process::run({"pkexec", "/usr/libexec/bastionguard/bastionguard-service", "--system", "stop", "BastionGuard-phishing-scanner.service"}).exit_code);
1533 if (ret == 0) {
1534 std::cout << _("✔ Servizio Anti-Phishing fermato\n");
1535 } else {
1536 std::cerr << _("⚠ Errore arresto BastionGuard-phishing-scanner.service\n");
1537 }
1538}

References _, and bg_process::run().

Referenced by SettingsPage::onAntiphishToggled().

◆ stop_antiransom()

void Backend::stop_antiransom ( )

Definition at line 847 of file Backend.cpp.

847 {
848 const int ret = bg_process::run({"runuser", "-u", Glib::get_user_name(), "--",
849 "/usr/libexec/bastionguard/bastionguard-service",
850 "--user", "stop", "BastionGuard-ransomware-scanner.service"}).exit_code;
851 if (ret == 0)
852 std::cout << _("✔ Servizio Anti-Ransomware fermato\n");
853 else
854 std::cerr << _("⚠ Impossibile fermare il servizio Anti-Ransomware\n");
855}

References _, and bg_process::run().

Referenced by SettingsPage::onAntiransomToggled(), and ~Backend().

◆ testGoogleSafeKey()

bool Backend::testGoogleSafeKey ( )

Definition at line 1680 of file Backend.cpp.

1680 {
1681 if (googleSafeApiKey_.empty()) {
1682 std::cerr << "[Backend] ❌ " << _("Nessuna chiave API Google Safe impostata") << "\n";
1683 return false;
1684 }
1685
1686 CURL* curl = curl_easy_init();
1687 if (!curl) {
1688 std::cerr << "[Backend] ⚠ " << _("Impossibile inizializzare la libreria CURL") << "\n";
1689 return false;
1690 }
1691
1692 std::string url = "https://safebrowsing.googleapis.com/v4/threatLists?key=" + googleSafeApiKey_;
1693 std::string response;
1694
1695 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
1696 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
1697 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
1698 curl_easy_setopt(curl, CURLOPT_USERAGENT, "BastionGuard/1.0");
1699
1700 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
1701 +[](void* contents, size_t size, size_t nmemb, void* userp) -> size_t {
1702 ((std::string*)userp)->append((char*)contents, size * nmemb);
1703 return size * nmemb;
1704 });
1705 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
1706
1707 CURLcode res = curl_easy_perform(curl);
1708
1709 if (res != CURLE_OK) {
1710 std::cerr << "[Backend] ⚠ " << _("Errore nella richiesta HTTP a Google Safe: ")
1711 << curl_easy_strerror(res) << "\n";
1712 curl_easy_cleanup(curl);
1713 return false;
1714 }
1715
1716 curl_easy_cleanup(curl);
1717
1718 if (response.find("threatType") != std::string::npos) {
1719 std::cout << "[Backend] ✔ " << _("Chiave Google Safe valida e attiva") << "\n";
1720 return true;
1721 } else {
1722 std::cerr << "[Backend] ❌ " << _("Chiave API non valida o risposta inattesa dal server") << "\n";
1723 return false;
1724 }
1725}

References _, and googleSafeApiKey_.

Referenced by SettingsPage::build_antiphish_tab().

◆ updateBankListFromURL()

bool Backend::updateBankListFromURL ( const std::string & source_url)

Definition at line 2805 of file Backend.cpp.

2805 {
2806 if (url.rfind("https://", 0) != 0) {
2807 std::cerr << _("[Backend] ❌ La lista banche deve essere scaricata via HTTPS.\n");
2808 return false;
2809 }
2810
2811 std::string dir = Glib::get_home_dir() + "/.local/share/BastionGuard";
2812 std::string path = dir + "/banks.json";
2813 std::string tmp_path = path + ".download";
2814 std::filesystem::create_directories(dir);
2815 std::error_code cleanup_ec;
2816 std::filesystem::remove(tmp_path, cleanup_ec);
2817
2818 CURL* curl = curl_easy_init();
2819 if (!curl) {
2820 std::cerr << _("[Backend] ❌ Errore: init cURL\n");
2821 return false;
2822 }
2823
2824 std::ofstream outfile(tmp_path, std::ios::binary | std::ios::trunc);
2825 if (!outfile.is_open()) {
2826 std::cerr << _("[Backend] ❌ Errore apertura file temporaneo ") << tmp_path << "\n";
2827 curl_easy_cleanup(curl);
2828 return false;
2829 }
2830
2831 std::cout << _("[Backend] 🌍 Download da URL: ") << url << std::endl;
2832
2833 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
2834 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
2835 curl_easy_setopt(curl, CURLOPT_USERAGENT, "BastionGuard/1.0");
2836 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
2837 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 25L);
2838 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
2839 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
2840 curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
2841 curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
2842
2843 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &outfile);
2844 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
2845 +[](void* ptr, size_t size, size_t nmemb, void* stream) -> size_t {
2846 std::ofstream* out = static_cast<std::ofstream*>(stream);
2847 out->write(static_cast<const char*>(ptr), size * nmemb);
2848 return size * nmemb;
2849 });
2850
2851 CURLcode res = curl_easy_perform(curl);
2852 long response_code = 0;
2853 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
2854 outfile.flush();
2855 outfile.close();
2856 curl_easy_cleanup(curl);
2857
2858 std::cout << _("[Backend] Risultato cURL: ") << res << " (" << curl_easy_strerror(res) << "), HTTP " << response_code << "\n";
2859
2860 if (res != CURLE_OK || response_code != 200) {
2861 std::cerr << _("[Backend] ❌ Errore rete o HTTP (") << curl_easy_strerror(res) << ")\n";
2862 std::error_code ec; std::filesystem::remove(tmp_path, ec);
2863 return false;
2864 }
2865
2866 if (!std::filesystem::exists(tmp_path) || std::filesystem::file_size(tmp_path) < 50) {
2867 std::cerr << _("[Backend] ⚠ banks.json scaricato ma vuoto.\n");
2868 std::error_code ec; std::filesystem::remove(tmp_path, ec);
2869 return false;
2870 }
2871
2872 // Validate the trust-list structure before replacing the last known-good copy.
2873 try {
2874 std::ifstream check(tmp_path);
2875 nlohmann::json j;
2876 check >> j;
2877 if (!j.is_object() || !j.contains("list") || !j["list"].is_array() || j["list"].empty()) {
2878 std::cerr << _("[Backend] ❌ banks.json non ha una struttura valida.\n");
2879 std::error_code ec; std::filesystem::remove(tmp_path, ec);
2880 return false;
2881 }
2882 for (const auto& item : j["list"]) {
2883 if (item.is_string()) continue;
2884 if (item.is_object() && item.contains("value") && item["value"].is_string()) continue;
2885 std::cerr << _("[Backend] ❌ banks.json contiene una voce non valida.\n");
2886 std::error_code ec; std::filesystem::remove(tmp_path, ec);
2887 return false;
2888 }
2889 } catch (...) {
2890 std::cerr << _("[Backend] ❌ banks.json non è JSON valido.\n");
2891 std::error_code ec; std::filesystem::remove(tmp_path, ec);
2892 return false;
2893 }
2894
2895 std::error_code replace_ec;
2896 std::filesystem::rename(tmp_path, path, replace_ec);
2897 if (replace_ec) {
2898 std::cerr << _("[Backend] ❌ Impossibile sostituire banks.json: ") << replace_ec.message() << "\n";
2899 std::filesystem::remove(tmp_path, cleanup_ec);
2900 return false;
2901 }
2902
2903 std::cout << _("[Backend] ✅ Lista banche aggiornata (") << std::filesystem::file_size(path) << " bytes)\n";
2904 return true;
2905}

References _.

Referenced by BankPage::auto_update_bank_list(), and BankPage::on_refresh_clicked().

◆ updatePhishLists()

bool Backend::updatePhishLists ( )

Definition at line 1086 of file Backend.cpp.

1086 {
1087 // Unifica whitelist.json + whitelist.txt prima di procedere
1089
1090 namespace fs = std::filesystem;
1091
1092 std::string userBase = getRuntimeDataDir();
1093 std::string baseDir = userBase + "/data/phishing";
1094 std::string finalPath = baseDir + "/blacklist.txt";
1095 std::string finalReduce = baseDir + "/blacklist-reduce.txt";
1096
1097 // Use a private per-update directory instead of predictable /tmp names.
1098 // The privileged helper verifies owner/mode before consuming it.
1099 std::string stage_template = "/tmp/bastionguard-phish.XXXXXX";
1100 std::vector<char> stage_buf(stage_template.begin(), stage_template.end());
1101 stage_buf.push_back('\0');
1102 char* stage_ptr = ::mkdtemp(stage_buf.data());
1103 if (!stage_ptr) {
1104 std::cerr << _("[Phishing] Impossibile creare staging directory sicura.\n");
1105 return false;
1106 }
1107 std::string stagingDir(stage_ptr);
1108 ::chmod(stagingDir.c_str(), 0700);
1109
1110 std::string tmpPath = stagingDir + "/blacklist.txt";
1111 std::string tmpReduce = stagingDir + "/blacklist-reduce.txt";
1112 std::string tmpDnsmasq = stagingDir + "/dnsmasq-blacklist.conf";
1113
1114 fs::create_directories(baseDir);
1115
1116 struct Cleanup {
1117 std::vector<std::string> paths;
1118 ~Cleanup() {
1119 for (auto &p : paths) {
1120 try {
1121 if (!p.empty() && std::filesystem::exists(p))
1122 std::filesystem::remove(p);
1123 } catch(...) {}
1124 }
1125 }
1126 };
1127 Cleanup cleanup;
1128 cleanup.paths.push_back(tmpPath);
1129 cleanup.paths.push_back(tmpReduce);
1130 cleanup.paths.push_back(tmpDnsmasq);
1131 cleanup.paths.push_back(stagingDir);
1132
1133 std::vector<std::string> sources = {
1134 "https://phishing.army/download/phishing_army_blocklist.txt",
1135 "https://openphish.com/feed.txt",
1136 "https://urlhaus.abuse.ch/downloads/text/",
1137 };
1138
1139 auto trim = [](std::string &s) {
1140 const char *ws = " \t\n\r\f\v";
1141 size_t start = s.find_first_not_of(ws);
1142 if (start == std::string::npos) { s.clear(); return; }
1143 size_t end = s.find_last_not_of(ws);
1144 s = s.substr(start, end - start + 1);
1145 };
1146
1147 const std::regex re_ipv4(R"((?:(?:25[0-5]|2[0-4]\d|1?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|1?\d{1,2})){3}))");
1148 const std::regex re_ipv6(R"((?:[0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4}){2,7}))");
1149
1150 auto looks_like_ip = [&](const std::string &s)->bool{
1151 return std::regex_search(s, re_ipv4) || std::regex_search(s, re_ipv6);
1152 };
1153
1154 auto looks_like_url_or_domain = [](const std::string &s) -> bool {
1155 if (s.empty()) return false;
1156 if (s.find("http://") != std::string::npos || s.find("https://") != std::string::npos) return true;
1157 if (s.find('.') != std::string::npos) {
1158 bool all_digits = true;
1159 for (char c : s) {
1160 if (!std::isdigit(static_cast<unsigned char>(c)) && c != '.') { all_digits = false; break; }
1161 }
1162 return !all_digits;
1163 }
1164 return false;
1165 };
1166
1167
1168 {
1169 std::ofstream out(tmpPath, std::ios::trunc);
1170 if (!out.is_open()) {
1171 std::cerr << _("❌ Impossibile scrivere ") << tmpPath << "\n";
1172 return false;
1173 }
1174
1175 for (const auto& url : sources) {
1176 const auto download = bg_process::run({"curl", "--fail", "--silent", "--max-time", "30",
1177 "--user-agent", "BastionGuard-PhishUpdater/1.0",
1178 "--", url}, false, 16U * 1024U * 1024U);
1179 if (!download.ok()) { std::cerr << _("⚠ Impossibile aprire ") << url << "\n"; continue; }
1180
1181 bool any = false;
1182 std::string acc;
1183 std::istringstream fetched(download.output);
1184 std::string fragment;
1185 while (std::getline(fetched, fragment)) {
1186 acc.append(fragment).append("\n");
1187 while (true) {
1188 size_t nl = acc.find('\n');
1189 if (nl == std::string::npos) break;
1190 std::string line = acc.substr(0, nl);
1191 acc.erase(0, nl + 1);
1192 if (!line.empty() && line.back() == '\r') line.pop_back();
1193 trim(line);
1194 if (line.empty() || line[0] == '#') continue;
1195
1196 if (looks_like_ip(line) || looks_like_url_or_domain(line)) {
1197 out << line << "\n";
1198 any = true;
1199 }
1200 }
1201 }
1202 if (!any) std::cerr << _("⚠ Nessun dato da ") << url << "\n";
1203 else out << "\n";
1204 }
1205 out.close();
1206 ::chmod(tmpPath.c_str(), 0600);
1207 }
1208
1209
1210 {
1211 std::ifstream fin(tmpPath);
1212 if (!fin.is_open()) return false;
1213
1214 std::unordered_set<std::string> seen;
1215 std::vector<std::string> lines;
1216 std::string line;
1217 while (std::getline(fin, line)) {
1218 if (!line.empty() && line.back() == '\r') line.pop_back();
1219 trim(line);
1220 if (line.empty() || line[0] == '#') continue;
1221 if (seen.insert(line).second) lines.push_back(line);
1222 }
1223 fin.close();
1224
1225 const size_t maxLines = 30;
1226 std::ofstream fout(tmpReduce, std::ios::trunc);
1227 for (size_t i = 0; i < std::min(lines.size(), maxLines); ++i)
1228 fout << lines[i] << "\n";
1229 fout << _("# ... lista completa salvata in blacklist.txt\n");
1230 fout.close();
1231 ::chmod(tmpReduce.c_str(), 0600);
1232 }
1233
1234 copy_to_final(tmpPath, finalPath);
1235 copy_to_final(tmpReduce, finalReduce);
1236
1237 try {
1238 std::ifstream fin(finalPath);
1239 if (!fin.is_open()) {
1240 std::cerr << _("❌ Impossibile aprire la blacklist per generare dnsmasq.") << std::endl;
1241 } else {
1242 std::ofstream fout(tmpDnsmasq, std::ios::trunc);
1243 if (!fout.is_open()) {
1244 std::cerr << _("❌ Impossibile creare file temporaneo dnsmasq.") << std::endl;
1245 } else {
1246
1247
1248 static const std::unordered_set<std::string> infra_whitelist = {
1249 "github.com",
1250 "githubusercontent.com",
1251 "gitlab.com",
1252 "bitbucket.org",
1253 "sourceforge.net",
1254
1255
1256 "archive.org",
1257
1258
1259 "npmjs.com",
1260 "jsdelivr.net",
1261 "unpkg.com",
1262
1263
1264 "cloudflare.com",
1265 "cloudfront.net",
1266 "amazonaws.com",
1267 "azurewebsites.net",
1268 "windows.net",
1269 "vercel.app",
1270 "netlify.app",
1271 "herokuapp.com",
1272
1273
1274 "googleapis.com",
1275 "googleusercontent.com",
1276 "gstatic.com",
1277 "firebaseapp.com",
1278 "firebasestorage.googleapis.com",
1279
1280 "microsoft.com",
1281 "office.com",
1282 "live.com"
1283 };
1284
1285
1286 std::unordered_set<std::string> trusted;
1287
1288 auto load_json_list = [&](const std::string& path) {
1289 if (!fs::exists(path)) return;
1290 try {
1291 std::ifstream f(path);
1292 nlohmann::json j;
1293 f >> j;
1294
1295 auto push_str = [&](const nlohmann::json& arr) {
1296 for (auto& v : arr) {
1297 if (v.is_string()) trusted.insert(v.get<std::string>());
1298 }
1299 };
1300
1301 if (j.is_array()) {
1302 push_str(j);
1303 } else if (j.contains("list") && j["list"].is_array()) {
1304 push_str(j["list"]);
1305 } else if (j.contains("whitelist") && j["whitelist"].is_array()) {
1306 push_str(j["whitelist"]);
1307 }
1308 } catch (...) {}
1309 };
1310
1311 auto load_text_list = [&](const std::string& path) {
1312 if (!fs::exists(path)) return;
1313
1314 try {
1315 std::ifstream f(path);
1316 std::string line;
1317 while (std::getline(f, line)) {
1318 line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
1319 line.erase(std::remove(line.begin(), line.end(), '\n'), line.end());
1320
1321 const char* ws = " \t\f\v";
1322 size_t start = line.find_first_not_of(ws);
1323 if (start == std::string::npos) continue;
1324 size_t end = line.find_last_not_of(ws);
1325 line = line.substr(start, end - start + 1);
1326
1327 if (line.empty() || line[0] == '#')
1328 continue;
1329
1330 trusted.insert(line);
1331 }
1332 } catch (...) {}
1333 };
1334
1335 load_json_list("/usr/share/BastionGuard/data/bank/banks.json");
1336
1337 if (const char* home = std::getenv("HOME")) {
1338 load_json_list(std::string(home) + "/.config/BastionGuard/whitelist.json");
1339 load_text_list(std::string(home) + "/.local/share/BastionGuard/phishing/whitelist.txt");
1340 }
1341
1342 auto clean_domain = [](std::string s) {
1343 std::transform(s.begin(), s.end(), s.begin(),
1344 [](unsigned char c){ return (char)std::tolower(c); });
1345
1346 const char* ws = " \t\r\n\f\v";
1347 size_t start = s.find_first_not_of(ws);
1348 if (start == std::string::npos) return std::string{};
1349 size_t end = s.find_last_not_of(ws);
1350 s = s.substr(start, end - start + 1);
1351
1352 if (auto pos = s.find("://"); pos != std::string::npos)
1353 s = s.substr(pos + 3);
1354
1355 for (char c : {'/', ' ', ';', '"', '\'', '%', '&', '(', ')', '=', '?', '*', '#'})
1356 if (auto p = s.find(c); p != std::string::npos)
1357 s = s.substr(0, p);
1358
1359 if (auto at = s.rfind('@'); at != std::string::npos)
1360 s = s.substr(at + 1);
1361
1362 if (auto colon = s.find(':'); colon != std::string::npos)
1363 s = s.substr(0, colon);
1364
1365 if (s.rfind("www.", 0) == 0)
1366 s.erase(0, 4);
1367
1368 while (!s.empty() && s.front() == '.')
1369 s.erase(0, 1);
1370 while (!s.empty() && s.back() == '.')
1371 s.pop_back();
1372
1373 return s;
1374 };
1375
1376
1377 auto is_whitelisted_domain = [&](const std::string& domain,
1378 const std::unordered_set<std::string>& wl) -> bool {
1379 if (domain.empty()) return false;
1380 if (wl.count(domain)) return true;
1381
1382 size_t dot = domain.find('.');
1383 while (dot != std::string::npos) {
1384 std::string parent = domain.substr(dot + 1);
1385 if (wl.count(parent)) return true;
1386 dot = domain.find('.', dot + 1);
1387 }
1388 return false;
1389 };
1390
1391
1392 if (!trusted.empty()) {
1393 std::unordered_set<std::string> normalized;
1394 normalized.reserve(trusted.size());
1395 for (const auto& d : trusted) normalized.insert(clean_domain(d));
1396 trusted.swap(normalized);
1397 }
1398
1399 std::cerr << _("[Backend] ✅ Whitelist utente/banca caricata: ")
1400 << trusted.size() << " domini.\n";
1401 std::cerr << _("[Backend] ✅ Whitelist infrastrutturale: ")
1402 << infra_whitelist.size() << _(" domini.\n");
1403
1404 size_t written = 0, skipped = 0, skipped_ip = 0;
1405 std::string line;
1406
1407 while (std::getline(fin, line)) {
1408 line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
1409 line.erase(std::remove(line.begin(), line.end(), '\n'), line.end());
1410 if (line.empty() || line[0] == '#') continue;
1411
1412
1413 std::string host = line;
1414
1415 if (auto pos = host.find("://"); pos != std::string::npos)
1416 host = host.substr(pos + 3);
1417
1418
1419 for (char c : {'/', ' ', ';', '"', '\'', '%', '&', '(', ')', '=', '?', '*', '#'})
1420 if (auto p = host.find(c); p != std::string::npos)
1421 host = host.substr(0, p);
1422
1423
1424 if (auto at = host.rfind('@'); at != std::string::npos)
1425 host = host.substr(at + 1);
1426
1427
1428 if (auto colon = host.find(':'); colon != std::string::npos)
1429 host = host.substr(0, colon);
1430
1431 std::string clean_host = clean_domain(host);
1432 if (clean_host.empty()) continue;
1433
1434 if (looks_like_ip(clean_host)) {
1435 skipped_ip++;
1436 continue;
1437 }
1438
1439
1440 if (is_whitelisted_domain(clean_host, infra_whitelist)) {
1441 skipped++;
1442 continue;
1443 }
1444 if (is_whitelisted_domain(clean_host, trusted)) {
1445 skipped++;
1446 continue;
1447 }
1448
1449 fout << "address=/" << clean_host << "/127.0.0.2\n";
1450 written++;
1451
1452 if (written % 1000 == 0) fout.flush();
1453 if (written > 1000000) break;
1454 }
1455
1456 fout.close();
1457 ::chmod(tmpDnsmasq.c_str(), 0600);
1458 fin.close();
1459
1460 std::cout << _("✔ File dnsmasq generato: ") << written
1461 << _(" voci. Skipped whitelist: ") << skipped
1462 << _(" | Skipped IP: ") << skipped_ip << "\n";
1463
1464 bool script_ok = run_phishing_updater_script(stagingDir);
1465 if (!script_ok) {
1466 std::cerr << _("[Phishing] Installazione privilegiata annullata o fallita; ")
1467 << _("nessun fallback insicuro viene eseguito.\n");
1468 return false;
1469 }
1470 fs::remove(tmpDnsmasq);
1471 }
1472 }
1473 } catch (const std::exception& e) {
1474 std::cerr << _("⚠ Errore generazione dnsmasq blocklist: ") << e.what() << std::endl;
1475 }
1476
1477
1478
1479
1480 try {
1481 if (!isFirewallEnabled()) {
1482 std::cout << _("[Firewall] Blocco IP disabilitato — salto applicazione regole.\n");
1483 } else if (firewallType_ == FirewallType::NONE) {
1484 std::cout << _("[Firewall] Nessun firewall supportato rilevato.\n");
1485 } else {
1486 std::ifstream fin(finalPath);
1487 std::vector<std::string> lines;
1488 std::string line;
1489
1490 while (std::getline(fin, line))
1491 lines.push_back(line);
1492
1493 const auto before = lines.size();
1494
1496
1497 std::cout << _("[Firewall] Tentata applicazione regole da ")
1498 << before << _(" righe blacklist ")
1499 << "(firewall=" << static_cast<int>(firewallType_) << ")\n";
1500 }
1501 }
1502 catch (const std::exception& e) {
1503 std::cerr << _("[Firewall] Errore applicazione regole firewall: ")
1504 << e.what() << std::endl;
1505 }
1506 catch (...) {
1507 std::cerr << _("[Firewall] Errore sconosciuto applicazione regole firewall.\n");
1508 }
1509
1510
1511 std::cout << _("✔ Blacklist phishing aggiornata in ") << finalPath
1512 << _(" e ridotta in ") << finalReduce << "\n";
1513 return true;
1514}
static bool copy_to_final(const std::string &src, const std::string &dest)
Definition Backend.cpp:431
static bool run_phishing_updater_script(const std::string &staging_dir)
Definition Backend.cpp:1005
static std::string getRuntimeDataDir()
Definition Backend.cpp:413
bool isFirewallEnabled() const
Definition Backend.cpp:3131
void applyFirewallFromBlacklist(const std::vector< std::string > &blacklistLines)
Definition Backend.cpp:3092
void mergeWhitelistSources()
Definition Backend.cpp:1039

References _, applyFirewallFromBlacklist(), copy_to_final(), firewallType_, getRuntimeDataDir(), isFirewallEnabled(), mergeWhitelistSources(), NONE, bg_process::run(), run_phishing_updater_script(), and trim().

Referenced by Backend(), SettingsPage::build_antiphish_tab(), SettingsPage::build_whitelist_tab(), main(), and ~Backend().

◆ updateSanesecurityDB()

bool Backend::updateSanesecurityDB ( std::function< void(int, int, const std::string &)> progressCallback = nullptr)

Definition at line 1542 of file Backend.cpp.

1543{
1544 namespace fs = std::filesystem;
1545
1546 std::string userBase = getRuntimeDataDir();
1547 std::string baseDir = userBase + "/data/sanesecurity";
1548 std::string tmpDir = "/tmp/sanesecurity";
1549
1550 fs::create_directories(tmpDir);
1551 fs::create_directories(baseDir);
1552
1553 std::vector<std::string> dbs = {
1554 "scamsigs.hdb",
1555 "scam.ndb",
1556 "phish.ndb",
1557 "rogue.hdb",
1558 "ransomware.ndb"
1559 };
1560
1561 int total = static_cast<int>(dbs.size());
1562 int current = 0;
1563
1564 std::cout << _("⬇ Inizio aggiornamento Sanesecurity DB...") << "\n";
1565
1566 for (const auto& db : dbs) {
1567 ++current;
1568 if (progressCallback)
1569 progressCallback(current - 1, total, db);
1570
1571 std::string url = "https://sanesecurity.com/clamav/" + db;
1572 std::string dest = tmpDir + "/" + db;
1573 std::string finalPath = baseDir + "/" + db;
1574 std::string systemDest = "/usr/share/BastionGuard/data/sanesecurity/" + db;
1575
1576 std::cout << _("⬇ Scarico ") << db << " ...\n";
1577
1578 const auto download = bg_process::run({"curl", "--fail", "--silent", "--location",
1579 "--max-time", "30", "-o", dest, "--", url});
1580 const int ret = download.exit_code;
1581
1582 if (ret != 0 || !fs::exists(dest) || fs::file_size(dest) < 100) {
1583 std::cerr << _("⚠ Errore download o file vuoto: ") << db << "\n";
1584 if (progressCallback)
1585 progressCallback(current, total, db);
1586 continue;
1587 }
1588
1589
1590 if (!copy_to_final(dest, finalPath)) {
1591 std::cerr << _("❌ Errore copia locale ") << finalPath << "\n";
1592 return false;
1593 }
1594
1595
1596 if (install_to_system_data(dest, systemDest)) {
1597 std::cout << _("✔ ") << db << _(" installato system-wide in ") << systemDest << "\n";
1598 } else {
1599 std::cout << _("ℹ ") << db << _(" disponibile solo in ") << finalPath << "\n";
1600 }
1601
1602 if (progressCallback)
1603 progressCallback(current, total, db);
1604 }
1605
1606 std::cout << _("✔ Database Sanesecurity aggiornato in ") << baseDir << "\n";
1607 return true;
1608}
static bool install_to_system_data(const std::string &src, const std::string &dest)
Definition Backend.cpp:321

References _, copy_to_final(), bg_process::Result::exit_code, getRuntimeDataDir(), install_to_system_data(), and bg_process::run().

Referenced by SettingsPage::build_antiransom_tab().

◆ updateYaraRules()

bool Backend::updateYaraRules ( std::function< void(int, int, const std::string &)> progressCallback = nullptr)

Definition at line 857 of file Backend.cpp.

858{
859 namespace fs = std::filesystem;
860
861 std::string userYaraDir = getRuntimeDataDir() + "/data/yara";
862 std::string systemYaraDir = "/usr/share/BastionGuard/data/yara";
863
864 fs::create_directories(userYaraDir);
865
866 std::vector<std::string> files = {
867 "ByteCode.MSIL.Ransomware.Apis.yara",
868 "ByteCode.MSIL.Ransomware.Thanos.yara",
869 "Linux.Ransomware.KillDisk.yara",
870 "Win32.Ransomware.WannaCry.yara",
871 "Win32.Ransomware.LockBit.yara",
872 "Win64.Ransomware.BlackBasta.yara",
873 "ByteCode.MSIL.Ransomware.ChupaCabra.yara",
874 "ByteCode.MSIL.Ransomware.Cring.yara",
875 "ByteCode.MSIL.Ransomware.Dusk.yara",
876 "ByteCode.MSIL.Ransomware.EAF.yara",
877 "ByteCode.MSIL.Ransomware.Eternity.yara",
878 "ByteCode.MSIL.Ransomware.Fantom.yara",
879 "ByteCode.MSIL.Ransomware.GhosTEncryptor.yara",
880 "ByteCode.MSIL.Ransomware.Ghostbin.yara",
881 "ByteCode.MSIL.Ransomware.GoodWill.yara",
882 "ByteCode.MSIL.Ransomware.HarpoonLocker.yara",
883 "ByteCode.MSIL.Ransomware.Hog.yara",
884 "ByteCode.MSIL.Ransomware.Invert.yara",
885 "ByteCode.MSIL.Ransomware.Janelle.yara",
886 "ByteCode.MSIL.Ransomware.Khonsari.yara",
887 "ByteCode.MSIL.Ransomware.McBurglar.yara",
888 "ByteCode.MSIL.Ransomware.Moisha.yara",
889 "ByteCode.MSIL.Ransomware.Namaste.yara",
890 "ByteCode.MSIL.Ransomware.Oct.yara",
891 "ByteCode.MSIL.Ransomware.Pacman.yara",
892 "ByteCode.MSIL.Ransomware.PoliceRecords.yara",
893 "ByteCode.MSIL.Ransomware.Povlsomware.yara",
894 "ByteCode.MSIL.Ransomware.Retis.yara",
895 "ByteCode.MSIL.Ransomware.TaRRaK.yara",
896 "ByteCode.MSIL.Ransomware.TimeCrypt.yara",
897 "ByteCode.MSIL.Ransomware.TimeTime.yara",
898 "ByteCode.MSIL.Ransomware.Venom.yara",
899 "ByteCode.MSIL.Ransomware.WildFire.yara",
900 "ByteCode.MSIL.Ransomware.WormLocker.yara",
901 "ByteCode.MSIL.Ransomware.ZeroLocker.yara",
902 "Bytecode.MSIL.Ransomware.CobraLocker.yara",
903 "Linux.Ransomware.GwisinLocker.yara",
904 "Linux.Ransomware.Helldown.yara",
905 "Linux.Ransomware.LuckyJoe.yara",
906 "Linux.Ransomware.RedAlert.yara",
907 "Win32.Ransomware.Conti.yara",
908 "Win32.Ransomware.BlackCat.yara",
909 "Win32.Ransomware.Clop.yara",
910 "Win32.Ransomware.Ryuk.yara",
911 "Win64.Ransomware.Cactus.yara",
912 "Win64.Ransomware.Pandora.yara",
913 "Win64.Ransomware.HermeticRansom.yara"
914 };
915
916 std::string baseUrl =
917 "https://raw.githubusercontent.com/reversinglabs/reversinglabs-yara-rules/develop/yara/ransomware";
918
919 int total = files.size();
920 int index = 0;
921 int successCount = 0;
922 int failCount = 0;
923 bool blockedDetected = false;
924
925 std::cout << _("⬇ Inizio aggiornamento delle regole YARA...") << "\n";
926
927 for (const auto& file : files) {
928 ++index;
929
930 if (progressCallback)
931 progressCallback(index, total, file);
932
933 std::string url = baseUrl + "/" + file;
934 std::string dest = userYaraDir + "/" + file;
935
936 const auto download = bg_process::run({"curl", "--fail", "--silent", "--show-error",
937 "--location", "--max-time", "10", "-o", dest, "--", url}, true);
938 const std::string& output = download.output;
939 if (!download.ok()) {
940 std::error_code ec;
941 fs::remove(dest, ec);
942 failCount++;
943 continue;
944 }
945
946 if (fs::exists(dest)) {
947 auto size = fs::file_size(dest);
948
949 if (size < 100 ||
950 output.find("redirect_to_local_warning_server") != std::string::npos) {
951 blockedDetected = true;
952 fs::remove(dest);
953 failCount++;
954 continue;
955 }
956
957 std::cout << _("✔ Aggiornato: ") << file << "\n";
958 successCount++;
959
960 } else {
961 failCount++;
962 }
963 }
964
965 std::cout << "\n📊 " << _("Totale riusciti: ") << successCount
966 << " | " << _("Falliti: ") << failCount << "\n";
967
968 if (blockedDetected) {
969 std::cerr << _("⚠ Alcuni download sono stati bloccati dall'AntiPhishing.") << "\n";
970 }
971
972 std::cout << _("📁 Regole salvate in: ") << userYaraDir << "\n";
973
974
975 if (successCount > 0) {
976
977 // Install each downloaded rule by argv, never interpolate file paths
978 // into a root shell script.
979 bool copied_all = true;
980 for (const auto& file : files) {
981 const fs::path src_path = fs::path(userYaraDir) / file;
982 if (!fs::exists(src_path)) continue;
983 const fs::path dst_path = fs::path(systemYaraDir) / file;
984 if (!bg_process::run({"pkexec", "/usr/bin/install", "-D", "-m", "0644",
985 src_path.string(), dst_path.string()}).ok())
986 copied_all = false;
987 }
988 if (copied_all)
989 std::cout << _("✔ Copiate anche in /usr/share/BastionGuard/data/yara") << "\n";
990 else
991 std::cerr << _("⚠ Alcune regole YARA non sono state installate nel sistema") << "\n";
992 }
993
994 return successCount > 0;
995}

References _, getRuntimeDataDir(), bg_process::Result::ok(), bg_process::Result::output, and bg_process::run().

Referenced by SettingsPage::build_antiransom_tab(), and ~Backend().

Member Data Documentation

◆ antiransom_

AntiRansomEngine Backend::antiransom_
private

Definition at line 198 of file Backend.hpp.

Referenced by Backend().

◆ antiransom_signal_

sigc::signal<void(const std::string&)> Backend::antiransom_signal_
private

Definition at line 199 of file Backend.hpp.

Referenced by signal_antiransom_event().

◆ firewallEnabled_

◆ firewallType_

◆ googleSafeApiKey_

std::string Backend::googleSafeApiKey_
private

◆ googleSafeEnabled_

bool Backend::googleSafeEnabled_ = false
private

◆ onBankListReload

std::function<void(const std::string&)> Backend::onBankListReload

Definition at line 80 of file Backend.hpp.

◆ progressCallback_

std::function<void(int, int, const std::string&)> Backend::progressCallback_
private

Definition at line 200 of file Backend.hpp.

◆ samba_last_progress

float Backend::samba_last_progress = 0.0f
private

Definition at line 214 of file Backend.hpp.

Referenced by get_current_scan_files(), and scanSambaDir().

◆ samba_last_temp_dir

std::string Backend::samba_last_temp_dir
private

Definition at line 213 of file Backend.hpp.

Referenced by get_current_scan_files(), and scanSambaDir().

◆ samba_progress_callback

std::function<void(const std::string&, float)> Backend::samba_progress_callback = nullptr

Definition at line 150 of file Backend.hpp.

Referenced by SambaPage::onScanNow(), scanAllSambaDirs(), and scanSambaDir().

◆ samba_scan_state

SambaScanState Backend::samba_scan_state

Definition at line 172 of file Backend.hpp.

Referenced by get_current_scan_files(), get_current_scan_files(), and scanSambaDir().

◆ samba_stop_requested

std::atomic<bool> Backend::samba_stop_requested { false }

Definition at line 113 of file Backend.hpp.

Referenced by requestStopSambaScan(), resetSambaStop(), scanAllSambaDirs(), and scanSambaDir().

◆ smb_context

SMBCCTX* Backend::smb_context = nullptr
private

Definition at line 209 of file Backend.hpp.

◆ smb_credentials

std::map<std::string, std::pair<std::string,std::string> > Backend::smb_credentials

Definition at line 123 of file Backend.hpp.

Referenced by loadSMBCredentials(), and saveSMBCredentials().

◆ smb_mutex

std::mutex Backend::smb_mutex
private

Definition at line 201 of file Backend.hpp.

◆ webprobe_

std::unique_ptr<WebProbe> Backend::webprobe_
private

Definition at line 202 of file Backend.hpp.

Referenced by Backend(), and checkUrl().

◆ whitelist_

std::vector<std::string> Backend::whitelist_
private

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