fix(quarantine): prevent directory moves
This commit is contained in:
parent
7e60e566d4
commit
1c5dfc1a84
28 changed files with 2100 additions and 268 deletions
|
|
@ -542,8 +542,8 @@ target_include_directories(BastionGuard
|
|||
)
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2340,7 +2340,6 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version=2.0
|
||||
build=20260411
|
||||
version=2.0.1
|
||||
build=20260726
|
||||
|
|
|
|||
5
debian/change_cmake/CMakeLists.txt
vendored
5
debian/change_cmake/CMakeLists.txt
vendored
|
|
@ -672,8 +672,8 @@ target_include_directories(BastionGuard
|
|||
)
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2398,7 +2398,6 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
2
debian/changelog
vendored
2
debian/changelog
vendored
|
|
@ -1,4 +1,4 @@
|
|||
bastionguard (2.0-1) stable; urgency=low
|
||||
bastionguard (2.0.1-1) stable; urgency=low
|
||||
|
||||
* Debian package.
|
||||
|
||||
|
|
|
|||
2
debian/changelog_ubuntu24
vendored
2
debian/changelog_ubuntu24
vendored
|
|
@ -1,4 +1,4 @@
|
|||
bastionguard (2.0-1ubuntu24.04.1) noble; urgency=low
|
||||
bastionguard (2.0.1-1ubuntu24.04.1) noble; urgency=low
|
||||
|
||||
* Ubuntu 24.04 (Noble) package.
|
||||
|
||||
|
|
|
|||
2
debian/changelog_ubuntu25
vendored
2
debian/changelog_ubuntu25
vendored
|
|
@ -1,4 +1,4 @@
|
|||
bastionguard (2.0-1ubuntu25.10) questing; urgency=low
|
||||
bastionguard (2.0.1-1ubuntu25.10) questing; urgency=low
|
||||
|
||||
* Ubuntu 25.10 (Questing Quokka) package.
|
||||
|
||||
|
|
|
|||
2
debian/changelog_ubuntu26
vendored
2
debian/changelog_ubuntu26
vendored
|
|
@ -1,4 +1,4 @@
|
|||
bastionguard (2.0-1ubuntu26.04) questing; urgency=low
|
||||
bastionguard (2.0.1-1ubuntu26.04) questing; urgency=low
|
||||
|
||||
* Ubuntu 26.04 (Resolute Raccoon) package.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
|
||||
Name: bastionguard
|
||||
Version: 2.0
|
||||
Version: 2.0.1
|
||||
Release: 1%{?dist}
|
||||
Summary: BastionGuard Security Platform
|
||||
|
||||
|
|
@ -27,7 +27,8 @@ Provides: bastionguard = %{version}-%{release}
|
|||
Obsoletes: bastionguard < %{version}-%{release}
|
||||
|
||||
License: GPLv3
|
||||
URL: https://git.bastionguard.eu/specialworld83/BastionGuard
|
||||
URL: https://bastionguard.eu
|
||||
Vendor: BastionGuard
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
%global debug_package %{nil}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,28 @@ find_package(PkgConfig REQUIRED)
|
|||
find_package(Gettext REQUIRED)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(cmake/BastionGuardInit.cmake)
|
||||
bastionguard_detect_init_system(BG_INIT_SYSTEM)
|
||||
|
||||
set(BG_SERVICECTL_PATH "/usr/libexec/bastionguard/bastionguard-service")
|
||||
set(BASTIONGUARD_DINIT_SYSTEM_DIR "/etc/dinit.d" CACHE PATH
|
||||
"Dinit system service description directory")
|
||||
set(BASTIONGUARD_DINIT_USER_DIR "/usr/lib/dinit.d/user" CACHE PATH
|
||||
"Dinit user service description directory")
|
||||
set(BG_DINIT_ENABLE_DIR
|
||||
"${BASTIONGUARD_DINIT_SYSTEM_DIR}/bastionguard.d")
|
||||
configure_file(
|
||||
data/init/common/bastionguard-init-config.in
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bastionguard-init-config"
|
||||
@ONLY
|
||||
NEWLINE_STYLE UNIX
|
||||
)
|
||||
message(STATUS "BastionGuard init backend: ${BG_INIT_SYSTEM}")
|
||||
add_compile_definitions(
|
||||
BASTIONGUARD_INIT_SYSTEM=\"${BG_INIT_SYSTEM}\"
|
||||
BASTIONGUARD_SERVICECTL_PATH=\"${BG_SERVICECTL_PATH}\"
|
||||
)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
# ============================================================
|
||||
# BastionGuard – RPATH centralizzato
|
||||
|
|
@ -234,29 +256,25 @@ endfunction()
|
|||
# ======================
|
||||
# libsystemd / sd-bus
|
||||
# ======================
|
||||
pkg_check_modules(SYSTEMD REQUIRED libsystemd)
|
||||
|
||||
if (SYSTEMD_FOUND)
|
||||
message(STATUS "✔ libsystemd trovato: ${SYSTEMD_VERSION}")
|
||||
include_directories(${SYSTEMD_INCLUDE_DIRS})
|
||||
link_directories(${SYSTEMD_LIBRARY_DIRS})
|
||||
add_definitions(${SYSTEMD_CFLAGS_OTHER})
|
||||
else()
|
||||
message(FATAL_ERROR "❌ libsystemd non trovato. Installa libsystemd-dev")
|
||||
endif()
|
||||
# ======================
|
||||
# systemd (sd-bus) — necessario su Debian/Ubuntu recenti (DSO missing)
|
||||
# ======================
|
||||
# sd-bus is used by the StatusNotifierItem implementation, not for service
|
||||
# management. It remains optional on OpenRC, SysVinit and Dinit systems.
|
||||
pkg_check_modules(SYSTEMD QUIET libsystemd)
|
||||
|
||||
if (SYSTEMD_FOUND)
|
||||
if(SYSTEMD_FOUND)
|
||||
message(STATUS "✔ libsystemd trovato: ${SYSTEMD_VERSION}")
|
||||
include_directories(${SYSTEMD_INCLUDE_DIRS})
|
||||
bg_link_directories(${SYSTEMD_LIBRARY_DIRS})
|
||||
add_definitions(${SYSTEMD_CFLAGS_OTHER})
|
||||
add_compile_definitions(BASTIONGUARD_HAS_SDBUS=1)
|
||||
set(BG_TRAYICON_SOURCE src/TrayIcon.cpp)
|
||||
else()
|
||||
message(WARNING "⚠ libsystemd non trovato (libsystemd-dev). Alcune feature potrebbero non compilare.")
|
||||
message(WARNING "libsystemd non trovato: tray SNI disabilitata; init ${BG_INIT_SYSTEM} resta supportato")
|
||||
add_compile_definitions(BASTIONGUARD_HAS_SDBUS=0)
|
||||
set(BG_TRAYICON_SOURCE src/TrayIconStub.cpp)
|
||||
endif()
|
||||
|
||||
function(bg_link_systemd tgt)
|
||||
if (SYSTEMD_FOUND AND TARGET ${tgt})
|
||||
if(SYSTEMD_FOUND AND TARGET ${tgt})
|
||||
target_include_directories(${tgt} PRIVATE ${SYSTEMD_INCLUDE_DIRS})
|
||||
target_link_directories(${tgt} PRIVATE ${SYSTEMD_LIBRARY_DIRS})
|
||||
target_link_libraries(${tgt} PRIVATE ${SYSTEMD_LIBRARIES})
|
||||
|
|
@ -291,8 +309,12 @@ else()
|
|||
message(STATUS "✔ rsync trovato: ${RSYNC_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
# Option to control whether systemd services are enabled / started at install time.
|
||||
option(ENABLE_SYSTEMD_SERVICES "Enable and start systemd services at install time" OFF)
|
||||
# Option to control whether init services are enabled / started at install time.
|
||||
option(ENABLE_INIT_SERVICES "Enable and start BastionGuard init services at install time" OFF)
|
||||
option(ENABLE_SYSTEMD_SERVICES "Deprecated alias for ENABLE_INIT_SERVICES" OFF)
|
||||
if(ENABLE_SYSTEMD_SERVICES)
|
||||
set(ENABLE_INIT_SERVICES ON)
|
||||
endif()
|
||||
|
||||
install(DIRECTORY data/
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/BastionGuard/data
|
||||
|
|
@ -658,7 +680,7 @@ target_link_libraries(firewall
|
|||
set(BastionGuard_SOURCES
|
||||
src/main.cpp
|
||||
src/MainWindow.cpp
|
||||
src/TrayIcon.cpp
|
||||
${BG_TRAYICON_SOURCE}
|
||||
src/Backend.cpp
|
||||
src/DashboardPage.cpp
|
||||
src/ScanPage.cpp
|
||||
|
|
@ -714,8 +736,8 @@ target_include_directories(BastionGuard
|
|||
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -737,7 +759,6 @@ target_link_libraries(BastionGuard
|
|||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
)
|
||||
target_link_options(BastionGuard PRIVATE -lsystemd)
|
||||
bg_set_rpath(BastionGuard)
|
||||
bg_link_systemd(BastionGuard)
|
||||
if(ENABLE_CEF)
|
||||
|
|
@ -1343,14 +1364,15 @@ install(TARGETS BastionGuard-privacyd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR
|
|||
# Demone USB (BastionGuard-usbd)
|
||||
# ======================
|
||||
|
||||
# Trova libsystemd
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SYSTEMD REQUIRED libsystemd)
|
||||
if(SYSTEMD_FOUND)
|
||||
set(BG_USBD_BUS_SOURCE src/usb/BastionGuard-usbd.cpp)
|
||||
else()
|
||||
set(BG_USBD_BUS_SOURCE src/usb/BastionGuard-usbd-gdbus.cpp)
|
||||
endif()
|
||||
|
||||
set(USBD_SOURCES
|
||||
src/usb/BastionGuard-usbd.cpp
|
||||
${BG_USBD_BUS_SOURCE}
|
||||
src/usb/LiveScanDialog.cpp
|
||||
|
||||
)
|
||||
|
||||
add_executable(BastionGuard-usbd ${USBD_SOURCES})
|
||||
|
|
@ -1367,7 +1389,7 @@ target_link_libraries(BastionGuard-usbd
|
|||
${GIOMM_LIBRARIES}
|
||||
${SIGC_LIBRARIES}
|
||||
${UDEV_LIBRARIES}
|
||||
${SYSTEMD_LIBRARIES} # <── FIX CRITICO
|
||||
${SYSTEMD_LIBRARIES}
|
||||
)
|
||||
bg_set_rpath(BastionGuard-usbd)
|
||||
target_compile_definitions(BastionGuard-usbd PRIVATE
|
||||
|
|
@ -1657,7 +1679,7 @@ endif()
|
|||
|
||||
# ======================
|
||||
# BastionGuard-mailproxy — proxy SMTP utente
|
||||
# Gira come systemctl --user, senza privilegi root
|
||||
# Gira come servizio utente, senza privilegi root
|
||||
# ======================
|
||||
|
||||
add_executable(BastionGuard-mailproxy
|
||||
|
|
@ -1689,11 +1711,7 @@ install(TARGETS BastionGuard-mailproxy
|
|||
WORLD_READ WORLD_EXECUTE
|
||||
)
|
||||
|
||||
# Installa il service file systemd --user
|
||||
install(FILES
|
||||
data/service/BastionGuard-mailproxy.service
|
||||
DESTINATION /usr/lib/systemd/user
|
||||
)
|
||||
# Il service file viene installato nella sezione init-system centralizzata.
|
||||
|
||||
# ============================================================
|
||||
# BastionGuard WebUI
|
||||
|
|
@ -1912,13 +1930,15 @@ if(ENABLE_BASTIONGUARD_SECURE_CONNECTION)
|
|||
--sysconfdir=/etc
|
||||
--localedir=share/locale
|
||||
--buildtype=release
|
||||
-Dinstall_systemd_service=false
|
||||
--reconfigure
|
||||
|
||||
BUILD_COMMAND
|
||||
${MESON_EXECUTABLE} compile -C "${BG_SC_BINARY_DIR}"
|
||||
|
||||
INSTALL_COMMAND
|
||||
${MESON_EXECUTABLE} install -C "${BG_SC_BINARY_DIR}" --destdir "${BG_SC_INSTALL_DIR}"
|
||||
${CMAKE_COMMAND} -E rm -rf "${BG_SC_INSTALL_DIR}"
|
||||
COMMAND ${MESON_EXECUTABLE} install -C "${BG_SC_BINARY_DIR}" --destdir "${BG_SC_INSTALL_DIR}"
|
||||
|
||||
BUILD_ALWAYS 1
|
||||
|
||||
|
|
@ -2350,7 +2370,9 @@ if (INSTALL_NGINX_DEFAULTS)
|
|||
message(STATUS \"[NGINX] Testo configurazione...\")
|
||||
execute_process(COMMAND nginx -t RESULT_VARIABLE nginx_test)
|
||||
if(nginx_test EQUAL 0)
|
||||
execute_process(COMMAND systemctl restart nginx)
|
||||
execute_process(
|
||||
COMMAND ${BG_SERVICECTL_PATH} --system restart nginx.service
|
||||
)
|
||||
message(STATUS \"[NGINX] ✅ Configurazione valida, Nginx riavviato.\")
|
||||
else()
|
||||
message(WARNING \"[NGINX] ⚠ Test configurazione fallito. Controlla con: sudo nginx -t\")
|
||||
|
|
@ -2429,38 +2451,196 @@ endif()
|
|||
# Services
|
||||
# ======================
|
||||
|
||||
# opzione per abilitare automaticamente le user units durante 'cmake --install' (default OFF)
|
||||
option(ENABLE_USER_AGENT_AUTO "Attempt to enable systemd --user unit for logged-in users at install time" OFF)
|
||||
# opzione per abilitare automaticamente i servizi utente durante install
|
||||
option(ENABLE_USER_AGENT_AUTO "Attempt to enable user services for logged-in users at install time" OFF)
|
||||
|
||||
# install system units (system-wide)
|
||||
# Dispatcher e supervisori comuni a tutti i backend.
|
||||
install(PROGRAMS
|
||||
data/init/common/bastionguard-service
|
||||
data/init/common/bastionguard-supervise
|
||||
data/init/common/bastionguard-periodic
|
||||
data/init/common/bastionguard-sanesecurity-update
|
||||
DESTINATION /usr/libexec/bastionguard
|
||||
)
|
||||
install(FILES
|
||||
data/service/BastionGuard-phishing-scanner.service
|
||||
data/service/BastionGuard-phishing-updater.service
|
||||
data/service/BastionGuard-phishing-updater.timer
|
||||
data/service/BastionGuard-ransomware-realtime.service
|
||||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bastionguard-init-config"
|
||||
DESTINATION /usr/libexec/bastionguard
|
||||
)
|
||||
|
||||
# install user units (systemd --user services)
|
||||
install(FILES
|
||||
data/service/BastionGuard-useragent.service
|
||||
data/service/BastionGuard-privacyd.service
|
||||
data/service/BastionGuard-ransomware-alert.service
|
||||
data/service/BastionGuard-ransomware-realtime-alert.service
|
||||
data/service/BastionGuard-ransomware-scanner.service
|
||||
data/service/BastionGuard-pacd.service
|
||||
data/service/BastionGuard-mailproxy.service
|
||||
data/service/BastionGuard-user-session-watch.service
|
||||
DESTINATION /usr/lib/systemd/user
|
||||
)
|
||||
if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
||||
install(FILES
|
||||
data/service/BastionGuard-phishing-scanner.service
|
||||
data/service/BastionGuard-phishing-updater.service
|
||||
data/service/BastionGuard-phishing-updater.timer
|
||||
data/service/BastionGuard-ransomware-realtime.service
|
||||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
if(ENABLE_CEF AND ENABLE_CEF_DAEMON)
|
||||
install(FILES data/service/BastionGuard-cef.service
|
||||
if(ENABLE_BASTIONGUARD_SECURE_CONNECTION)
|
||||
install(FILES
|
||||
thirdparty/bastionguard-secure-connection/dist/bsc-daemon.service
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
endif()
|
||||
|
||||
install(FILES
|
||||
data/service/BastionGuard-useragent.service
|
||||
data/service/BastionGuard-privacyd.service
|
||||
data/service/BastionGuard-ransomware-alert.service
|
||||
data/service/BastionGuard-ransomware-realtime-alert.service
|
||||
data/service/BastionGuard-ransomware-scanner.service
|
||||
data/service/BastionGuard-pacd.service
|
||||
data/service/BastionGuard-mailproxy.service
|
||||
data/service/BastionGuard-user-session-watch.service
|
||||
DESTINATION /usr/lib/systemd/user
|
||||
)
|
||||
|
||||
if(ENABLE_CEF AND ENABLE_CEF_DAEMON)
|
||||
install(FILES data/service/BastionGuard-cef.service
|
||||
DESTINATION /usr/lib/systemd/user
|
||||
)
|
||||
endif()
|
||||
elseif(BG_INIT_SYSTEM STREQUAL "OPENRC")
|
||||
function(bg_install_openrc_service service_name)
|
||||
install(PROGRAMS data/init/openrc/bastionguard-openrc-service
|
||||
DESTINATION /etc/init.d
|
||||
RENAME "${service_name}")
|
||||
endfunction()
|
||||
|
||||
bg_install_openrc_service(BastionGuard-phishing-scanner)
|
||||
bg_install_openrc_service(BastionGuard-phishing-updater)
|
||||
bg_install_openrc_service(BastionGuard-phishing-updater-timer)
|
||||
bg_install_openrc_service(BastionGuard-ransomware-realtime)
|
||||
bg_install_openrc_service(bastionguard-sanesecurity)
|
||||
bg_install_openrc_service(bastionguard-sanesecurity-timer)
|
||||
bg_install_openrc_service(BastionGuard-usbd)
|
||||
bg_install_openrc_service(clamav-clamonacc)
|
||||
if(ENABLE_BASTIONGUARD_SECURE_CONNECTION)
|
||||
bg_install_openrc_service(bsc-daemon)
|
||||
endif()
|
||||
|
||||
install(FILES data/init/common/bastionguard-user-services.desktop
|
||||
DESTINATION /etc/xdg/autostart)
|
||||
elseif(BG_INIT_SYSTEM STREQUAL "SYSVINIT")
|
||||
function(bg_install_sysv_service service_name)
|
||||
set(BG_SYSV_SERVICE_NAME "${service_name}")
|
||||
set(_generated_service
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/init/sysvinit/${service_name}")
|
||||
configure_file(
|
||||
data/init/sysvinit/bastionguard-sysv-service.in
|
||||
"${_generated_service}"
|
||||
@ONLY
|
||||
NEWLINE_STYLE UNIX
|
||||
)
|
||||
install(PROGRAMS "${_generated_service}"
|
||||
DESTINATION /etc/init.d)
|
||||
endfunction()
|
||||
|
||||
bg_install_sysv_service(BastionGuard-phishing-scanner)
|
||||
bg_install_sysv_service(BastionGuard-phishing-updater)
|
||||
bg_install_sysv_service(BastionGuard-phishing-updater-timer)
|
||||
bg_install_sysv_service(BastionGuard-ransomware-realtime)
|
||||
bg_install_sysv_service(bastionguard-sanesecurity)
|
||||
bg_install_sysv_service(bastionguard-sanesecurity-timer)
|
||||
bg_install_sysv_service(BastionGuard-usbd)
|
||||
bg_install_sysv_service(clamav-clamonacc)
|
||||
if(ENABLE_BASTIONGUARD_SECURE_CONNECTION)
|
||||
bg_install_sysv_service(bsc-daemon)
|
||||
endif()
|
||||
|
||||
install(FILES data/init/common/bastionguard-user-services.desktop
|
||||
DESTINATION /etc/xdg/autostart)
|
||||
elseif(BG_INIT_SYSTEM STREQUAL "DINIT")
|
||||
install(PROGRAMS
|
||||
data/init/dinit/bastionguard-dinit-run
|
||||
data/init/dinit/bastionguard-dinit-user-run
|
||||
DESTINATION /usr/libexec/bastionguard
|
||||
)
|
||||
|
||||
set(_generated_dinit_root
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/init/dinit/bastionguard")
|
||||
configure_file(
|
||||
data/init/dinit/bastionguard-dinit-root.in
|
||||
"${_generated_dinit_root}"
|
||||
@ONLY
|
||||
NEWLINE_STYLE UNIX
|
||||
)
|
||||
install(FILES "${_generated_dinit_root}"
|
||||
DESTINATION "${BASTIONGUARD_DINIT_SYSTEM_DIR}")
|
||||
install(DIRECTORY DESTINATION "${BG_DINIT_ENABLE_DIR}")
|
||||
|
||||
function(bg_install_dinit_service service_name service_type restart_policy)
|
||||
set(BG_DINIT_SERVICE_NAME "${service_name}")
|
||||
set(BG_DINIT_SERVICE_TYPE "${service_type}")
|
||||
set(BG_DINIT_SERVICE_RESTART "${restart_policy}")
|
||||
if(service_type STREQUAL "process")
|
||||
set(BG_DINIT_SERVICE_RESTART_OPTIONS
|
||||
"restart-delay = 5\nrestart-limit-count = 0")
|
||||
else()
|
||||
set(BG_DINIT_SERVICE_RESTART_OPTIONS "")
|
||||
endif()
|
||||
set(_generated_service
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/init/dinit/system/${service_name}")
|
||||
configure_file(
|
||||
data/init/dinit/bastionguard-dinit-service.in
|
||||
"${_generated_service}"
|
||||
@ONLY
|
||||
NEWLINE_STYLE UNIX
|
||||
)
|
||||
install(FILES "${_generated_service}"
|
||||
DESTINATION "${BASTIONGUARD_DINIT_SYSTEM_DIR}")
|
||||
endfunction()
|
||||
|
||||
bg_install_dinit_service(BastionGuard-phishing-scanner process on-failure)
|
||||
bg_install_dinit_service(BastionGuard-phishing-updater process false)
|
||||
bg_install_dinit_service(BastionGuard-phishing-updater-timer process on-failure)
|
||||
bg_install_dinit_service(BastionGuard-ransomware-realtime process on-failure)
|
||||
bg_install_dinit_service(bastionguard-sanesecurity process false)
|
||||
bg_install_dinit_service(bastionguard-sanesecurity-timer process on-failure)
|
||||
bg_install_dinit_service(BastionGuard-usbd process on-failure)
|
||||
bg_install_dinit_service(clamav-clamonacc process on-failure)
|
||||
if(ENABLE_BASTIONGUARD_SECURE_CONNECTION)
|
||||
bg_install_dinit_service(bsc-daemon process on-failure)
|
||||
endif()
|
||||
|
||||
function(bg_install_dinit_user_service service_name restart_policy restart_delay)
|
||||
set(BG_DINIT_USER_SERVICE_NAME "${service_name}")
|
||||
set(BG_DINIT_USER_SERVICE_RESTART "${restart_policy}")
|
||||
set(BG_DINIT_USER_RESTART_DELAY "${restart_delay}")
|
||||
set(_generated_service
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/init/dinit/user/${service_name}")
|
||||
configure_file(
|
||||
data/init/dinit/bastionguard-dinit-user-service.in
|
||||
"${_generated_service}"
|
||||
@ONLY
|
||||
NEWLINE_STYLE UNIX
|
||||
)
|
||||
install(FILES "${_generated_service}"
|
||||
DESTINATION "${BASTIONGUARD_DINIT_USER_DIR}")
|
||||
endfunction()
|
||||
|
||||
bg_install_dinit_user_service(BastionGuard-useragent true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-privacyd true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-ransomware-alert on-failure 3)
|
||||
bg_install_dinit_user_service(BastionGuard-ransomware-realtime-alert true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-ransomware-scanner true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-pacd true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-mailproxy true 3)
|
||||
bg_install_dinit_user_service(BastionGuard-user-session-watch true 3)
|
||||
if(ENABLE_CEF AND ENABLE_CEF_DAEMON)
|
||||
bg_install_dinit_user_service(BastionGuard-cef true 3)
|
||||
endif()
|
||||
|
||||
install(FILES data/init/common/bastionguard-user-services.desktop
|
||||
DESTINATION /etc/xdg/autostart)
|
||||
endif()
|
||||
|
||||
# Mantiene la copia dati dell'unità CEF prevista da questo CMake.
|
||||
if(ENABLE_CEF AND ENABLE_CEF_DAEMON)
|
||||
install(FILES data/service/BastionGuard-cef.service
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/BastionGuard/data/service
|
||||
)
|
||||
|
|
@ -2476,6 +2656,7 @@ install(PROGRAMS
|
|||
data/scripts/BastionGuard-export-env.sh
|
||||
data/scripts/BastionGuard-locale.sh
|
||||
data/scripts/BastionGuard-setup-clamav-daemon.sh
|
||||
data/scripts/BastionGuard-restart-user-services.sh
|
||||
data/scripts/BastionGuard-user-session-watch.sh
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/BastionGuard/data/scripts
|
||||
)
|
||||
|
|
@ -2607,40 +2788,38 @@ bg_install_code( "
|
|||
|
||||
|
||||
|
||||
if(ENABLE_SYSTEMD_SERVICES)
|
||||
if(ENABLE_INIT_SERVICES)
|
||||
bg_install_code( "
|
||||
message(STATUS \"[Systemd] Ricarico configurazione systemd...\")
|
||||
execute_process(COMMAND systemctl daemon-reload)
|
||||
if(DEFINED ENV{DESTDIR} AND NOT \"\$ENV{DESTDIR}\" STREQUAL \"\")
|
||||
message(STATUS \"[Init] DESTDIR attivo: salto enable/start dei servizi\")
|
||||
else()
|
||||
message(STATUS \"[Init] Backend: ${BG_INIT_SYSTEM}\")
|
||||
execute_process(COMMAND ${BG_SERVICECTL_PATH} --system daemon-reload)
|
||||
|
||||
message(STATUS \"[Systemd] Abilito BastionGuard-phishing-scanner...\")
|
||||
execute_process(COMMAND systemctl enable BastionGuard-phishing-scanner.service)
|
||||
message(STATUS \"[Init] Abilito e avvio BastionGuard-phishing-scanner...\")
|
||||
execute_process(
|
||||
COMMAND ${BG_SERVICECTL_PATH} --system enable --now BastionGuard-phishing-scanner.service
|
||||
)
|
||||
|
||||
message(STATUS \"[Systemd] Avvio BastionGuard-phishing-scanner...\")
|
||||
execute_process(COMMAND systemctl start BastionGuard-phishing-scanner.service)
|
||||
message(STATUS \"[Init] Abilito e avvio BastionGuard-ransomware-realtime...\")
|
||||
execute_process(
|
||||
COMMAND ${BG_SERVICECTL_PATH} --system enable --now BastionGuard-ransomware-realtime.service
|
||||
)
|
||||
|
||||
message(STATUS \"[Systemd] Riavvio BastionGuard-phishing-scanner...\")
|
||||
execute_process(COMMAND systemctl restart BastionGuard-phishing-scanner.service)
|
||||
if(${ENABLE_BASTIONGUARD_SECURE_CONNECTION})
|
||||
message(STATUS \"[Init] Abilito e avvio bsc-daemon...\")
|
||||
execute_process(
|
||||
COMMAND ${BG_SERVICECTL_PATH} --system enable --now bsc-daemon.service
|
||||
)
|
||||
endif()
|
||||
|
||||
message(STATUS \"[Systemd] Abilito BastionGuard-ransomware-realtime...\")
|
||||
execute_process(COMMAND systemctl enable BastionGuard-ransomware-realtime.service)
|
||||
|
||||
message(STATUS \"[Systemd] Avvio BastionGuard-ransomware-realtime...\")
|
||||
execute_process(COMMAND systemctl start BastionGuard-ransomware-realtime.service)
|
||||
|
||||
message(STATUS \"[Systemd] Riavvio BastionGuard-ransomware-realtime...\")
|
||||
execute_process(COMMAND systemctl restart BastionGuard-ransomware-realtime.service)
|
||||
|
||||
message(STATUS \"[Systemd] Abilito BastionGuard-phishing-scanner on graphical...\")
|
||||
execute_process(COMMAND systemctl enable BastionGuard-restart-on-graphical.service)
|
||||
|
||||
message(STATUS \"[Systemd] Riavvio BastionGuard-phishing-scanner on graphical...\")
|
||||
execute_process(COMMAND systemctl start BastionGuard-restart-on-graphical.service)
|
||||
|
||||
message(STATUS \"[Systemd] Riavvio polkit ...\")
|
||||
execute_process(COMMAND systemctl start polkit.service)
|
||||
execute_process(
|
||||
COMMAND ${BG_SERVICECTL_PATH} --system start polkit.service
|
||||
)
|
||||
endif()
|
||||
")
|
||||
else()
|
||||
message(STATUS "Systemd service install-time actions are disabled. To enable, run CMake with -DENABLE_SYSTEMD_SERVICES=ON")
|
||||
message(STATUS "Init service install-time actions are disabled. Use -DENABLE_INIT_SERVICES=ON to enable them")
|
||||
endif()
|
||||
|
||||
# ============================================================
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
#
|
||||
|
||||
Name: bastionguard
|
||||
Version: 2.0
|
||||
Release: %mkrel 2
|
||||
Version: 2.0.1
|
||||
Release: %mkrel 1
|
||||
%global yara_version 4.5.5
|
||||
%global yara_stage %{_builddir}/%{name}-%{version}/.yara-stage
|
||||
|
||||
|
|
@ -31,8 +31,9 @@ Provides: bastionguard = %{version}-%{release}
|
|||
Provides: bundled(yara) = %{yara_version}
|
||||
Obsoletes: bastionguard < %{version}-%{release}
|
||||
|
||||
License: GPLv3+ and BSD
|
||||
URL: https://git.bastionguard.eu/specialworld83/BastionGuard
|
||||
License: GPLv3
|
||||
URL: https://bastionguard.eu
|
||||
Vendor: BastionGuard
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source1: https://github.com/VirusTotal/yara/archive/refs/tags/v%{yara_version}.tar.gz#/yara-%{yara_version}.tar.gz
|
||||
|
||||
|
|
|
|||
|
|
@ -757,8 +757,8 @@ target_include_directories(BastionGuard
|
|||
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2497,7 +2497,7 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
|
||||
Name: bastionguard
|
||||
Version: 2.0
|
||||
Release: 3
|
||||
Version: 2.0.1
|
||||
Release: 1
|
||||
|
||||
%global yara_version 4.5.5
|
||||
%global yara_stage %{_builddir}/%{name}-%{version}/.yara-stage
|
||||
|
|
@ -32,8 +32,10 @@ Provides: bastionguard = %{version}-%{release}
|
|||
Provides: bundled(yara) = %{yara_version}
|
||||
Obsoletes: bastionguard < %{version}-%{release}
|
||||
|
||||
License: GPLv3+ AND BSD-3-Clause
|
||||
URL: https://git.bastionguard.eu/specialworld83/BastionGuard
|
||||
License: GPLv3
|
||||
URL: https://bastionguard.eu
|
||||
Vendor: BastionGuard
|
||||
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source1: https://github.com/VirusTotal/yara/archive/refs/tags/v%{yara_version}.tar.gz#/yara-%{yara_version}.tar.gz
|
||||
|
||||
|
|
|
|||
|
|
@ -763,8 +763,8 @@ target_include_directories(BastionGuard
|
|||
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2501,7 +2501,7 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,12 @@
|
|||
#
|
||||
|
||||
Name: bastionguard
|
||||
Version: 2.0
|
||||
Version: 2.0.1
|
||||
Release: 1leap
|
||||
Summary: BastionGuard Security Platform
|
||||
License: GPL-3.0-or-later
|
||||
URL: https://git.bastionguard.eu/specialworld83/BastionGuard
|
||||
License: GPLv3
|
||||
URL: https://bastionguard.eu
|
||||
Vendor: BastionGuard
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
# Disable debuginfo / debugsource packages.
|
||||
|
|
|
|||
|
|
@ -719,8 +719,8 @@ target_include_directories(BastionGuard
|
|||
)
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2460,7 +2460,7 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,12 @@
|
|||
#
|
||||
|
||||
Name: bastionguard
|
||||
Version: 2.0
|
||||
Release: 2
|
||||
Version: 2.0.1
|
||||
Release: 1
|
||||
Summary: BastionGuard Security Platform
|
||||
License: GPL-3.0-or-later
|
||||
URL: https://git.bastionguard.eu/specialworld83/BastionGuard-ci
|
||||
License: GPLv3
|
||||
URL: https://bastionguard.eu
|
||||
Vendor: BastionGuard
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
Provides: bastionguard = %{version}-%{release}
|
||||
|
|
|
|||
|
|
@ -719,8 +719,8 @@ target_include_directories(BastionGuard
|
|||
)
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2460,7 +2460,7 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
# Maintainer: BastionGuard info@bastionguard.eu
|
||||
|
||||
pkgname=bastionguard
|
||||
pkgver=2.0
|
||||
pkgver=2.0.1
|
||||
pkgrel=1
|
||||
pkgdesc="BastionGuard - transparent security control plane for Linux desktops"
|
||||
arch=('x86_64')
|
||||
|
|
|
|||
|
|
@ -636,8 +636,8 @@ target_include_directories(BastionGuard
|
|||
)
|
||||
|
||||
target_compile_definitions(BastionGuard PRIVATE
|
||||
BASTIONGUARD_VERSION="2.0"
|
||||
BASTIONGUARD_BUILD=20260411
|
||||
BASTIONGUARD_VERSION="2.0.1"
|
||||
BASTIONGUARD_BUILD=20260726
|
||||
)
|
||||
|
||||
target_link_libraries(BastionGuard
|
||||
|
|
@ -2384,7 +2384,7 @@ if(BG_INIT_SYSTEM STREQUAL "SYSTEMD")
|
|||
data/service/bastionguard-sanesecurity.service
|
||||
data/service/bastionguard-sanesecurity.timer
|
||||
data/service/BastionGuard-usbd.service
|
||||
data/service/clamav-clamonacc.service
|
||||
|
||||
DESTINATION /usr/lib/systemd/system
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2740,38 +2740,25 @@ void Backend::sendRansomwareAlert(const std::string& path, const std::string& fa
|
|||
|
||||
|
||||
void Backend::moveToQuarantine(const std::string& path) {
|
||||
try {
|
||||
std::string quarantineDir = Backend::getQuarantinePath();
|
||||
if (!std::filesystem::exists(quarantineDir))
|
||||
Backend::instance().ensureQuarantinePath();
|
||||
// Tutte le richieste passano dalla stessa implementazione validata.
|
||||
// Quarantine::move() accetta esclusivamente file regolari e rifiuta
|
||||
// directory, symlink e altri oggetti del filesystem.
|
||||
const bool moved = Quarantine::move(path);
|
||||
|
||||
auto src = std::filesystem::path(path);
|
||||
auto dest = std::filesystem::path(quarantineDir) / src.filename();
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::rename(src, dest, ec);
|
||||
if (ec) {
|
||||
std::cerr << _("⚠️ Impossibile spostare il file, provo copia: ")
|
||||
<< ec.message() << "\n";
|
||||
std::filesystem::copy_file(src, dest,
|
||||
std::filesystem::copy_options::overwrite_existing, ec);
|
||||
if (!ec)
|
||||
std::filesystem::remove(src);
|
||||
}
|
||||
|
||||
std::cout << _("🧰 File spostato in quarantena: ") << dest << "\n";
|
||||
|
||||
|
||||
Glib::signal_idle().connect_once([dest]() {
|
||||
Glib::signal_idle().connect_once([path, moved]() {
|
||||
if (moved) {
|
||||
Utils::show_message(
|
||||
nullptr,
|
||||
_("File spostato in quarantena con successo:\n") + dest.string(),
|
||||
_("File spostato in quarantena con successo:\n") + path,
|
||||
Gtk::MessageType::INFO);
|
||||
});
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << _("❌ Errore durante la quarantena: ") << ex.what() << "\n";
|
||||
}
|
||||
} else {
|
||||
Utils::show_message(
|
||||
nullptr,
|
||||
_("Impossibile spostare l'elemento in quarantena. "
|
||||
"Sono accettati esclusivamente file regolari:\n") + path,
|
||||
Gtk::MessageType::ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,205 +21,396 @@
|
|||
#include "Resource.hpp"
|
||||
#include "Quarantine.hpp"
|
||||
#include "Backend.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <system_error>
|
||||
#include <unistd.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string Quarantine::getQuarantinePath() {
|
||||
namespace {
|
||||
|
||||
std::string path = Backend::getQuarantinePath();
|
||||
if (path.empty()) {
|
||||
bool is_regular_file_without_following_symlinks(const fs::path& path,
|
||||
std::error_code& ec)
|
||||
{
|
||||
ec.clear();
|
||||
const fs::file_status status = fs::symlink_status(path, ec);
|
||||
return !ec && fs::exists(status) && fs::is_regular_file(status);
|
||||
}
|
||||
|
||||
const char* home = std::getenv("HOME");
|
||||
path = std::string(home ? home : "/tmp") + "/.local/share/BastionGuard/quarantine";
|
||||
fs::path normalize_path(const fs::path& path, std::error_code& ec)
|
||||
{
|
||||
ec.clear();
|
||||
fs::path normalized = fs::weakly_canonical(path, ec);
|
||||
if (!ec)
|
||||
return normalized.lexically_normal();
|
||||
|
||||
ec.clear();
|
||||
normalized = fs::absolute(path, ec);
|
||||
if (!ec)
|
||||
return normalized.lexically_normal();
|
||||
|
||||
return path.lexically_normal();
|
||||
}
|
||||
|
||||
bool is_path_inside(const fs::path& candidate, const fs::path& directory)
|
||||
{
|
||||
std::error_code candidate_ec;
|
||||
std::error_code directory_ec;
|
||||
|
||||
const fs::path normalized_candidate = normalize_path(candidate, candidate_ec);
|
||||
const fs::path normalized_directory = normalize_path(directory, directory_ec);
|
||||
|
||||
if (candidate_ec || directory_ec || normalized_directory.empty())
|
||||
return false;
|
||||
|
||||
auto candidate_it = normalized_candidate.begin();
|
||||
for (auto directory_it = normalized_directory.begin();
|
||||
directory_it != normalized_directory.end();
|
||||
++directory_it, ++candidate_it) {
|
||||
if (candidate_it == normalized_candidate.end() ||
|
||||
*candidate_it != *directory_it) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void remove_without_throwing(const fs::path& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
fs::remove(path, ec);
|
||||
}
|
||||
|
||||
bool copy_then_remove(const fs::path& source, const fs::path& destination)
|
||||
{
|
||||
std::error_code copy_ec;
|
||||
fs::copy_file(source, destination, fs::copy_options::none, copy_ec);
|
||||
if (copy_ec) {
|
||||
std::cerr << _("❌ Errore copia in quarantena: ")
|
||||
<< copy_ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code remove_ec;
|
||||
fs::remove(source, remove_ec);
|
||||
if (remove_ec) {
|
||||
std::cerr << _("❌ Impossibile rimuovere il file originale dopo la copia: ")
|
||||
<< remove_ec.message() << std::endl;
|
||||
|
||||
// La quarantena non è riuscita: non lasciare una copia che possa
|
||||
// essere interpretata come isolamento completato.
|
||||
remove_without_throwing(destination);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string Quarantine::getQuarantinePath()
|
||||
{
|
||||
std::string path = Backend::getQuarantinePath();
|
||||
if (path.empty()) {
|
||||
const char* home = std::getenv("HOME");
|
||||
path = std::string(home ? home : "/tmp") +
|
||||
"/.local/share/BastionGuard/quarantine";
|
||||
}
|
||||
|
||||
try {
|
||||
if (!fs::exists(path)) {
|
||||
fs::create_directories(path);
|
||||
const fs::path quarantine_path(path);
|
||||
|
||||
if (quarantine_path.empty() ||
|
||||
quarantine_path == quarantine_path.root_path()) {
|
||||
std::cerr << _("❌ Percorso di quarantena non valido: ")
|
||||
<< quarantine_path << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
fs::create_directories(quarantine_path, ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Errore creazione cartella quarantena: ")
|
||||
<< ec.message() << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
ec.clear();
|
||||
if (!fs::is_directory(quarantine_path, ec) || ec) {
|
||||
std::cerr << _("❌ Il percorso di quarantena non è una directory valida: ")
|
||||
<< quarantine_path << std::endl;
|
||||
return {};
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << _("❌ Errore creazione cartella quarantena: ") << e.what() << std::endl;
|
||||
std::cerr << _("❌ Errore creazione cartella quarantena: ")
|
||||
<< e.what() << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool Quarantine::move(const std::string& filepath) {
|
||||
bool Quarantine::move(const std::string& filepath)
|
||||
{
|
||||
try {
|
||||
std::string quarantineDir = getQuarantinePath();
|
||||
std::cerr << "DEBUG move(): quarantineDir=" << quarantineDir << std::endl;
|
||||
|
||||
fs::path src(filepath);
|
||||
if (!fs::exists(src)) {
|
||||
std::cerr << _("❌ File inesistente: ") << filepath << std::endl;
|
||||
if (filepath.empty()) {
|
||||
std::cerr << _("❌ Percorso file vuoto: quarantena annullata")
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::path dest = fs::path(quarantineDir) / src.filename();
|
||||
std::error_code ec;
|
||||
fs::path src = fs::absolute(fs::path(filepath), ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Impossibile risolvere il percorso del file: ")
|
||||
<< filepath << " | " << ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
src = src.lexically_normal();
|
||||
|
||||
// Protezione fondamentale: non seguire symlink e non accettare
|
||||
// directory, socket, FIFO o device. Solo file regolari.
|
||||
if (!is_regular_file_without_following_symlinks(src, ec)) {
|
||||
std::cerr << _("❌ Quarantena rifiutata: il percorso non è un file regolare: ")
|
||||
<< src;
|
||||
if (ec)
|
||||
std::cerr << " | " << ec.message();
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string quarantine_dir_string = getQuarantinePath();
|
||||
if (quarantine_dir_string.empty())
|
||||
return false;
|
||||
|
||||
const fs::path quarantine_dir(quarantine_dir_string);
|
||||
|
||||
// Evita loop e tentativi di mettere nuovamente in quarantena un file
|
||||
// che si trova già nell'area protetta.
|
||||
if (is_path_inside(src, quarantine_dir)) {
|
||||
std::cerr << _("❌ Il file è già contenuto nella quarantena: ")
|
||||
<< src << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::path dest = quarantine_dir / src.filename();
|
||||
|
||||
int counter = 1;
|
||||
while (fs::exists(dest) || fs::exists(dest.string() + ".meta")) {
|
||||
dest = fs::path(quarantineDir) /
|
||||
(src.stem().string() + "_" + std::to_string(counter) + src.extension().string());
|
||||
counter++;
|
||||
dest = quarantine_dir /
|
||||
(src.stem().string() + "_" + std::to_string(counter) +
|
||||
src.extension().string());
|
||||
++counter;
|
||||
}
|
||||
|
||||
|
||||
std::string metaPath = dest.string() + ".meta";
|
||||
std::ofstream meta(metaPath);
|
||||
const fs::path meta_path(dest.string() + ".meta");
|
||||
std::ofstream meta(meta_path, std::ios::out | std::ios::trunc);
|
||||
if (!meta.is_open()) {
|
||||
std::cerr << _("❌ Errore: impossibile creare il file meta in ") << metaPath << std::endl;
|
||||
std::cerr << _("❌ Impossibile creare i metadata di quarantena: ")
|
||||
<< meta_path << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
meta << src.string() << '\n';
|
||||
meta.flush();
|
||||
if (!meta.good()) {
|
||||
meta.close();
|
||||
remove_without_throwing(meta_path);
|
||||
std::cerr << _("❌ Scrittura metadata di quarantena fallita: ")
|
||||
<< meta_path << std::endl;
|
||||
return false;
|
||||
}
|
||||
meta << fs::absolute(src).string();
|
||||
meta.close();
|
||||
|
||||
|
||||
std::error_code ec;
|
||||
ec.clear();
|
||||
fs::rename(src, dest, ec);
|
||||
|
||||
if (ec) {
|
||||
if (ec == std::make_error_code(std::errc::cross_device_link)) {
|
||||
std::cerr << _("DEBUG move(): filesystem differente, uso copia e rimozione\n");
|
||||
|
||||
if (ec == std::errc::cross_device_link) {
|
||||
std::cerr << _("DEBUG move(): cross-device link, uso copy+remove\n");
|
||||
|
||||
std::error_code ec_copy;
|
||||
fs::copy_file(src, dest, fs::copy_options::overwrite_existing, ec_copy);
|
||||
if (ec_copy) {
|
||||
std::cerr << _("❌ Errore copia in quarantena: ")
|
||||
<< ec_copy.message() << std::endl;
|
||||
fs::remove(metaPath);
|
||||
if (!copy_then_remove(src, dest)) {
|
||||
remove_without_throwing(meta_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec_rm;
|
||||
fs::remove(src, ec_rm);
|
||||
if (ec_rm) {
|
||||
std::cerr << _("⚠ Impossibile rimuovere il file originale: ")
|
||||
<< ec_rm.message() << std::endl;
|
||||
}
|
||||
|
||||
} else {
|
||||
std::cerr << _("❌ Errore spostamento quarantena: ")
|
||||
<< ec.message() << std::endl;
|
||||
fs::remove(metaPath);
|
||||
remove_without_throwing(meta_path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << _("✔ File spostato in quarantena: ") << dest << std::endl;
|
||||
std::cout << _("✔ File spostato in quarantena: ")
|
||||
<< dest << std::endl;
|
||||
return true;
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << _("❌ Errore spostamento quarantena: ") << e.what() << std::endl;
|
||||
std::cerr << _("❌ Errore spostamento quarantena: ")
|
||||
<< e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Quarantine::restore(const std::string& quarantinedFile) {
|
||||
bool Quarantine::restore(const std::string& quarantinedFile)
|
||||
{
|
||||
try {
|
||||
fs::path qf(quarantinedFile);
|
||||
fs::path meta = qf.string() + ".meta";
|
||||
std::error_code ec;
|
||||
fs::path qf = fs::absolute(fs::path(quarantinedFile), ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Percorso quarantena non valido: ")
|
||||
<< quarantinedFile << " | " << ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
qf = qf.lexically_normal();
|
||||
|
||||
if (!fs::exists(meta)) {
|
||||
std::cerr << _("❌ Ripristino impossibile: metadata mancante per ")
|
||||
<< quarantinedFile << std::endl;
|
||||
const std::string quarantine_dir_string = getQuarantinePath();
|
||||
if (quarantine_dir_string.empty())
|
||||
return false;
|
||||
|
||||
const fs::path quarantine_dir(quarantine_dir_string);
|
||||
if (!is_path_inside(qf, quarantine_dir)) {
|
||||
std::cerr << _("❌ Ripristino rifiutato: file esterno alla quarantena: ")
|
||||
<< qf << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_regular_file_without_following_symlinks(qf, ec)) {
|
||||
std::cerr << _("❌ Ripristino rifiutato: elemento non regolare: ")
|
||||
<< qf << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const fs::path meta(qf.string() + ".meta");
|
||||
if (!is_regular_file_without_following_symlinks(meta, ec)) {
|
||||
std::cerr << _("❌ Ripristino impossibile: metadata mancante o non valido per ")
|
||||
<< qf << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream in(meta);
|
||||
std::string originalPath;
|
||||
std::getline(in, originalPath);
|
||||
std::string original_path;
|
||||
std::getline(in, original_path);
|
||||
in.close();
|
||||
|
||||
if (originalPath.empty()) {
|
||||
if (original_path.empty()) {
|
||||
std::cerr << _("❌ Ripristino impossibile: metadata vuoto o corrotto in ")
|
||||
<< meta << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::path orig = fs::absolute(originalPath);
|
||||
fs::path original = fs::absolute(fs::path(original_path), ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Percorso originale non valido nei metadata: ")
|
||||
<< original_path << " | " << ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
original = original.lexically_normal();
|
||||
|
||||
if (!fs::exists(qf)) {
|
||||
std::cerr << _("❌ Ripristino impossibile: file in quarantena mancante ")
|
||||
<< qf << std::endl;
|
||||
fs::remove(meta);
|
||||
if (is_path_inside(original, quarantine_dir)) {
|
||||
std::cerr << _("❌ Ripristino rifiutato: destinazione interna alla quarantena: ")
|
||||
<< original << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::create_directories(orig.parent_path());
|
||||
|
||||
fs::path finalDest = orig;
|
||||
int counter = 1;
|
||||
while (fs::exists(finalDest)) {
|
||||
finalDest = orig.parent_path() /
|
||||
(orig.stem().string() + "_restored" +
|
||||
std::to_string(counter) + orig.extension().string());
|
||||
counter++;
|
||||
fs::create_directories(original.parent_path(), ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Impossibile ricreare la directory originale: ")
|
||||
<< original.parent_path() << " | " << ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
fs::rename(qf, finalDest, ec);
|
||||
fs::path final_dest = original;
|
||||
int counter = 1;
|
||||
while (fs::exists(final_dest)) {
|
||||
final_dest = original.parent_path() /
|
||||
(original.stem().string() + "_restored" +
|
||||
std::to_string(counter) + original.extension().string());
|
||||
++counter;
|
||||
}
|
||||
|
||||
ec.clear();
|
||||
fs::rename(qf, final_dest, ec);
|
||||
|
||||
if (ec) {
|
||||
if (ec == std::errc::cross_device_link) {
|
||||
std::cerr << _("DEBUG restore(): cross-device link, uso copy+remove\n");
|
||||
if (ec == std::make_error_code(std::errc::cross_device_link)) {
|
||||
std::cerr << _("DEBUG restore(): filesystem differente, uso copia e rimozione\n");
|
||||
|
||||
std::error_code ec_copy;
|
||||
fs::copy_file(qf, finalDest, fs::copy_options::overwrite_existing, ec_copy);
|
||||
if (ec_copy) {
|
||||
std::cerr << _("❌ Errore copia durante il ripristino: ")
|
||||
<< ec_copy.message() << std::endl;
|
||||
if (!copy_then_remove(qf, final_dest))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec_rm;
|
||||
fs::remove(qf, ec_rm);
|
||||
if (ec_rm) {
|
||||
std::cerr << _("⚠ Impossibile rimuovere il file in quarantena: ")
|
||||
<< ec_rm.message() << std::endl;
|
||||
}
|
||||
|
||||
} else {
|
||||
std::cerr << _("❌ Errore ripristino: ") << ec.message() << std::endl;
|
||||
std::cerr << _("❌ Errore ripristino: ")
|
||||
<< ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fs::remove(meta);
|
||||
remove_without_throwing(meta);
|
||||
|
||||
std::cout << _("✔ File ripristinato in: ") << finalDest << std::endl;
|
||||
std::cout << _("✔ File ripristinato in: ")
|
||||
<< final_dest << std::endl;
|
||||
return true;
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << _("❌ Errore ripristino: ") << e.what() << std::endl;
|
||||
std::cerr << _("❌ Errore ripristino: ")
|
||||
<< e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Quarantine::remove(const std::string& quarantinedFile) {
|
||||
bool Quarantine::remove(const std::string& quarantinedFile)
|
||||
{
|
||||
try {
|
||||
fs::path qf(quarantinedFile);
|
||||
fs::path meta = qf.string() + ".meta";
|
||||
std::error_code ec;
|
||||
fs::path qf = fs::absolute(fs::path(quarantinedFile), ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Percorso quarantena non valido: ")
|
||||
<< quarantinedFile << " | " << ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
qf = qf.lexically_normal();
|
||||
|
||||
if (fs::exists(qf)) fs::remove(qf);
|
||||
if (fs::exists(meta)) fs::remove(meta);
|
||||
const std::string quarantine_dir_string = getQuarantinePath();
|
||||
if (quarantine_dir_string.empty())
|
||||
return false;
|
||||
|
||||
std::cout << _("✔ File eliminato dalla quarantena: ") << quarantinedFile << std::endl;
|
||||
if (!is_path_inside(qf, fs::path(quarantine_dir_string))) {
|
||||
std::cerr << _("❌ Eliminazione rifiutata: file esterno alla quarantena: ")
|
||||
<< qf << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_regular_file_without_following_symlinks(qf, ec)) {
|
||||
std::cerr << _("❌ Eliminazione rifiutata: elemento non regolare: ")
|
||||
<< qf << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const fs::path meta(qf.string() + ".meta");
|
||||
|
||||
ec.clear();
|
||||
fs::remove(qf, ec);
|
||||
if (ec) {
|
||||
std::cerr << _("❌ Errore eliminazione file in quarantena: ")
|
||||
<< ec.message() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
remove_without_throwing(meta);
|
||||
|
||||
std::cout << _("✔ File eliminato dalla quarantena: ")
|
||||
<< qf << std::endl;
|
||||
return true;
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << _("❌ Errore eliminazione: ") << e.what() << std::endl;
|
||||
std::cerr << _("❌ Errore eliminazione: ")
|
||||
<< e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,10 +95,25 @@ bool QuarantinePage::refreshList() {
|
|||
std::error_code ec_q;
|
||||
for (const auto& entry : fs::directory_iterator(quarantineDir, ec_q)) {
|
||||
if (ec_q) break;
|
||||
if (!entry.is_regular_file()) continue;
|
||||
std::error_code ec_type;
|
||||
const fs::file_status status = entry.symlink_status(ec_type);
|
||||
if (ec_type || !fs::is_regular_file(status))
|
||||
continue;
|
||||
|
||||
// ignora i metadata
|
||||
if (entry.path().extension() == ".meta") continue;
|
||||
// Un file .meta è un sidecar solo quando esiste il payload con lo
|
||||
// stesso nome senza l'ultima estensione. In questo modo un malware
|
||||
// reale chiamato, per esempio, sample.meta resta visibile nella GUI.
|
||||
if (entry.path().extension() == ".meta") {
|
||||
fs::path payload = entry.path();
|
||||
payload.replace_extension();
|
||||
|
||||
std::error_code ec_payload;
|
||||
const fs::file_status payload_status =
|
||||
fs::symlink_status(payload, ec_payload);
|
||||
|
||||
if (!ec_payload && fs::is_regular_file(payload_status))
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
|
||||
|
|
|
|||
1213
src/activation.cpp
Normal file
1213
src/activation.cpp
Normal file
File diff suppressed because it is too large
Load diff
36
src/activation.hpp
Normal file
36
src/activation.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* BastionGuard™ Recovery Data
|
||||
* Copyright (C) 2025–2026 Calogero Scarnà. All rights reserved.
|
||||
*
|
||||
* Proprietary activation support for donation-based distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace BastionGuard::Activation {
|
||||
|
||||
struct ActivationStatus {
|
||||
bool active = false;
|
||||
bool expired = false;
|
||||
std::string machine_id;
|
||||
std::string motherboard_serial;
|
||||
std::string owner;
|
||||
std::string edition;
|
||||
std::string expires;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
std::string activation_engine_id();
|
||||
std::string machine_id();
|
||||
std::string motherboard_serial();
|
||||
std::string activation_key_path();
|
||||
std::string hardware_cache_path();
|
||||
bool refresh_hardware_cache(std::string& error_message);
|
||||
bool save_system_key_if_valid(const std::string& raw_key, std::string& error_message);
|
||||
ActivationStatus validate_key(const std::string& raw_key);
|
||||
ActivationStatus validate_installed_key();
|
||||
bool save_key_if_valid(const std::string& raw_key, std::string& error_message);
|
||||
|
||||
} // namespace BastionGuard::Activation
|
||||
66
src/activation_helper/bastionguard_activation_helper.cpp
Normal file
66
src/activation_helper/bastionguard_activation_helper.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* BastionGuard™ Activation Helper
|
||||
* Runs through pkexec to read root-only DMI identifiers and save the
|
||||
* donation-bundle activation key system-wide.
|
||||
*/
|
||||
|
||||
#include "activation.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string read_stdin_all() {
|
||||
std::ostringstream content;
|
||||
content << std::cin.rdbuf();
|
||||
return content.str();
|
||||
}
|
||||
|
||||
void print_hardware_info() {
|
||||
std::cout << "MACHINE_ID=" << BastionGuard::Activation::machine_id() << "\n"
|
||||
<< "MOTHERBOARD_SERIAL=" << BastionGuard::Activation::motherboard_serial() << "\n"
|
||||
<< "ENGINE=" << BastionGuard::Activation::activation_engine_id() << "\n"
|
||||
<< "KEY_FORMAT=BGRD3 + KEYID" << "\n"
|
||||
<< "ACTIVATION_KEY_PATH=" << BastionGuard::Activation::activation_key_path() << "\n"
|
||||
<< "HARDWARE_CACHE_PATH=" << BastionGuard::Activation::hardware_cache_path() << "\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (::geteuid() != 0) {
|
||||
std::cerr << "This helper must run with administrator rights through pkexec.\n";
|
||||
return 10;
|
||||
}
|
||||
|
||||
const std::string command = (argc >= 2 && argv[1]) ? argv[1] : "";
|
||||
|
||||
if (command == "hardware") {
|
||||
std::string error;
|
||||
if (!BastionGuard::Activation::refresh_hardware_cache(error)) {
|
||||
std::cerr << error << "\n";
|
||||
return 20;
|
||||
}
|
||||
print_hardware_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command == "save-key") {
|
||||
const std::string raw_key = read_stdin_all();
|
||||
std::string error;
|
||||
if (!BastionGuard::Activation::save_system_key_if_valid(raw_key, error)) {
|
||||
std::cerr << error << "\n";
|
||||
return 30;
|
||||
}
|
||||
std::cout << "OK\n";
|
||||
print_hardware_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cerr << "Usage: bastionguard-activation-helper hardware | save-key\n";
|
||||
return 64;
|
||||
}
|
||||
|
|
@ -301,6 +301,21 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
// Il percorso ricevuto dal processo realtime deve indicare
|
||||
// esclusivamente un file regolare assoluto. Non seguire
|
||||
// symlink e non mostrare azioni di quarantena per directory.
|
||||
const fs::path alert_path(file);
|
||||
std::error_code path_ec;
|
||||
const fs::file_status path_status =
|
||||
fs::symlink_status(alert_path, path_ec);
|
||||
|
||||
if (!alert_path.is_absolute() || path_ec ||
|
||||
!fs::exists(path_status) ||
|
||||
!fs::is_regular_file(path_status)) {
|
||||
log_user(_("[SCARTATO] Percorso alert non regolare: ") + file);
|
||||
continue;
|
||||
}
|
||||
|
||||
Glib::signal_idle().connect_once([this, file, family]() {
|
||||
if (!running.load()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,98 @@ static const std::string LOG_FILE = "/var/log/BastionGuard/antiransom_inotify.lo
|
|||
static std::vector<std::string> WATCH_DIRS;
|
||||
|
||||
static std::string SECURITY_TOKEN;
|
||||
static std::vector<std::filesystem::path> EXCLUDED_DIRS;
|
||||
|
||||
static inline bool is_regular_file_safe(const std::string& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
const std::filesystem::file_status status =
|
||||
std::filesystem::symlink_status(path, ec);
|
||||
return !ec && std::filesystem::exists(status) &&
|
||||
std::filesystem::is_regular_file(status);
|
||||
}
|
||||
|
||||
static std::filesystem::path normalize_path(const std::filesystem::path& path,
|
||||
std::error_code& ec)
|
||||
{
|
||||
ec.clear();
|
||||
std::filesystem::path normalized =
|
||||
std::filesystem::weakly_canonical(path, ec);
|
||||
if (!ec)
|
||||
return normalized.lexically_normal();
|
||||
|
||||
ec.clear();
|
||||
normalized = std::filesystem::absolute(path, ec);
|
||||
if (!ec)
|
||||
return normalized.lexically_normal();
|
||||
|
||||
return path.lexically_normal();
|
||||
}
|
||||
|
||||
static bool is_path_inside(const std::filesystem::path& candidate,
|
||||
const std::filesystem::path& directory)
|
||||
{
|
||||
std::error_code candidate_ec;
|
||||
std::error_code directory_ec;
|
||||
|
||||
const auto normalized_candidate = normalize_path(candidate, candidate_ec);
|
||||
const auto normalized_directory = normalize_path(directory, directory_ec);
|
||||
|
||||
if (candidate_ec || directory_ec || normalized_directory.empty())
|
||||
return false;
|
||||
|
||||
auto candidate_it = normalized_candidate.begin();
|
||||
for (auto directory_it = normalized_directory.begin();
|
||||
directory_it != normalized_directory.end();
|
||||
++directory_it, ++candidate_it) {
|
||||
if (candidate_it == normalized_candidate.end() ||
|
||||
*candidate_it != *directory_it) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_excluded_path(const std::string& path)
|
||||
{
|
||||
if (path.empty())
|
||||
return false;
|
||||
|
||||
const std::filesystem::path candidate(path);
|
||||
for (const auto& excluded : EXCLUDED_DIRS) {
|
||||
if (is_path_inside(candidate, excluded))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string configured_quarantine_path(const std::string& home)
|
||||
{
|
||||
const std::string fallback =
|
||||
home + "/.local/share/BastionGuard/quarantine";
|
||||
const std::string config =
|
||||
home + "/.config/BastionGuard/config.ini";
|
||||
|
||||
std::ifstream in(config);
|
||||
if (!in.is_open())
|
||||
return fallback;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
const auto pos = line.find('=');
|
||||
if (pos == std::string::npos)
|
||||
continue;
|
||||
|
||||
const std::string key = line.substr(0, pos);
|
||||
const std::string value = line.substr(pos + 1);
|
||||
if (key == "quarantinePath" && !value.empty())
|
||||
return value;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
|
|
@ -489,6 +581,13 @@ static bool load_or_create_token()
|
|||
|
||||
static void send_socket_alert(const std::string& file, const std::string& family)
|
||||
{
|
||||
// Non inviare alert azionabili per directory, symlink o file già
|
||||
// contenuti nella quarantena.
|
||||
if (!is_regular_file_safe(file) || is_excluded_path(file)) {
|
||||
log_msg(_("Alert non inviato: percorso non regolare o escluso: ") + file);
|
||||
return;
|
||||
}
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
return;
|
||||
|
|
@ -577,12 +676,6 @@ static std::string get_process_exe(pid_t pid)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static inline bool is_regular_file_safe(const std::string& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
return std::filesystem::is_regular_file(path, ec) && !ec;
|
||||
}
|
||||
|
||||
static inline bool looks_like_archive_path(const std::string& path)
|
||||
{
|
||||
std::string lower = path;
|
||||
|
|
@ -604,6 +697,11 @@ static void send_archive_alert(
|
|||
const std::string& file,
|
||||
const ArchiveInspectionResult& ar)
|
||||
{
|
||||
if (!is_regular_file_safe(file) || is_excluded_path(file)) {
|
||||
log_msg(_("Alert archivio non inviato: percorso non regolare o escluso: ") + file);
|
||||
return;
|
||||
}
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
return;
|
||||
|
|
@ -757,6 +855,9 @@ public:
|
|||
|
||||
bool scan_file(const std::string& path)
|
||||
{
|
||||
if (!is_regular_file_safe(path) || is_excluded_path(path))
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::mutex> lock(yara_mutex);
|
||||
|
||||
if (!rules)
|
||||
|
|
@ -967,6 +1068,11 @@ public:
|
|||
{
|
||||
std::error_code ec;
|
||||
|
||||
if (is_excluded_path(root)) {
|
||||
log_msg(_("SKIP: directory esclusa dal realtime: ") + root);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(root, ec) || ec) {
|
||||
log_msg("SKIP: " + root + _(" non accessibile"));
|
||||
return;
|
||||
|
|
@ -987,10 +1093,18 @@ public:
|
|||
}
|
||||
|
||||
const auto& entry = *it;
|
||||
const std::string entry_path = entry.path().string();
|
||||
|
||||
if (is_excluded_path(entry_path)) {
|
||||
std::error_code type_ec;
|
||||
if (entry.is_directory(type_ec) && !type_ec)
|
||||
it.disable_recursion_pending();
|
||||
continue;
|
||||
}
|
||||
|
||||
ec.clear();
|
||||
if (entry.is_directory(ec) && !ec) {
|
||||
add_watch(entry.path().string());
|
||||
add_watch(entry_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1032,6 +1146,12 @@ public:
|
|||
if (!dir.empty() && ev->len > 0) {
|
||||
std::string full = dir + "/" + ev->name;
|
||||
|
||||
if (is_excluded_path(full)) {
|
||||
log_msg(_("INOTIFY IGNORATO: percorso escluso: ") + full);
|
||||
i += sizeof(struct inotify_event) + ev->len;
|
||||
continue;
|
||||
}
|
||||
|
||||
log_msg("INOTIFY EVENT: " + full + " [" +
|
||||
decode_mask(ev->mask) + "]");
|
||||
|
||||
|
|
@ -1116,6 +1236,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
std::string home = pw->pw_dir;
|
||||
|
||||
EXCLUDED_DIRS.clear();
|
||||
EXCLUDED_DIRS.emplace_back(configured_quarantine_path(home));
|
||||
|
||||
for (const auto& excluded : EXCLUDED_DIRS)
|
||||
log_msg(_("Directory esclusa dal realtime: ") + excluded.string());
|
||||
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(home, ec) || ec) {
|
||||
log_msg(_("ERRORE FATALE: HOME non accessibile: ") + home);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue