Skip to content
API Documentation
BastionGuard™
BastionGuard-privacyd.cpp File Reference

Go to the source code of this file.

Functions

void write_log (const std::string &msg)
std::vector< std::string > detect_active_devices ()
void monitor_loop ()
void handle_signal (int)
int main (int argc, char **argv)

Variables

static std::atomic< bool > running {true}
static std::mutex log_mutex

Function Documentation

◆ detect_active_devices()

std::vector< std::string > detect_active_devices ( )

Definition at line 92 of file BastionGuard-privacyd.cpp.

92 {
93 std::vector<std::string> result;
94 const std::vector<std::string> prefixes = {"/dev/video", "/dev/snd/pcm"};
95
96 // /proc è race-y: i PID possono sparire in qualsiasi momento tra open e iter.
97 // Usiamo l'overload con std::error_code per non lanciare eccezioni
98 // (altrimenti std::terminate nel thread monitor_loop -> SIGABRT).
99 std::error_code ec;
100 fs::directory_iterator proc_it("/proc", ec);
101 if (ec) return result;
102
103 for (; proc_it != fs::directory_iterator(); proc_it.increment(ec)) {
104 if (ec) break; // PID scomparso mentre iteravamo
105
106 const auto& pid_entry = *proc_it;
107 std::error_code ec_dir;
108 if (!pid_entry.is_directory(ec_dir) || ec_dir) continue;
109
110 const std::string pid_str = pid_entry.path().filename();
111 if (!std::all_of(pid_str.begin(), pid_str.end(), ::isdigit)) continue;
112
113 const std::string fd_path = "/proc/" + pid_str + "/fd";
114 std::error_code ec_exists;
115 if (!fs::exists(fd_path, ec_exists) || ec_exists) continue;
116
117 std::error_code ec_fd;
118 fs::directory_iterator fd_it(
119 fd_path,
120 fs::directory_options::skip_permission_denied,
121 ec_fd);
122 if (ec_fd) continue;
123
124 for (; fd_it != fs::directory_iterator(); fd_it.increment(ec_fd)) {
125 if (ec_fd) break; // processo terminato mentre iteravamo gli fd
126
127 const auto& fd_entry = *fd_it;
128 std::error_code ec_link;
129 auto link = fs::read_symlink(fd_entry.path(), ec_link);
130 if (ec_link) continue;
131 const std::string target = link.string();
132
133 for (const auto& prefix : prefixes) {
134 if (target.find(prefix) == 0) {
135 std::ifstream comm("/proc/" + pid_str + "/comm");
136 std::string name;
137 std::getline(comm, name);
138 if (name.empty()) name = "(sconosciuto)";
139 result.push_back(name + " (PID=" + pid_str + ")");
140 break;
141 }
142 }
143 }
144 }
145
146 std::sort(result.begin(), result.end());
147 result.erase(std::unique(result.begin(), result.end()), result.end());
148 return result;
149}

References detect_active_devices().

Referenced by detect_active_devices(), and monitor_loop().

◆ handle_signal()

void handle_signal ( int )

Definition at line 195 of file BastionGuard-privacyd.cpp.

195{ running = false; }
static std::atomic< bool > running

References handle_signal(), and running.

Referenced by handle_signal(), handle_signal(), main(), main(), and main().

◆ main()

int main ( int argc,
char ** argv )

Definition at line 197 of file BastionGuard-privacyd.cpp.

197 {
198 setlocale(LC_ALL, "");
199 bindtextdomain("BastionGuard", LOCALEDIR);
200 bind_textdomain_codeset("BastionGuard", "UTF-8");
201 textdomain("BastionGuard");
202
203 std::signal(SIGINT, handle_signal);
204 std::signal(SIGTERM, handle_signal);
205
206 write_log(_("=== Avvio BastionGuard-privacyd (headless) ==="));
207
208 std::thread monitor(monitor_loop);
209 while (running)
210 std::this_thread::sleep_for(std::chrono::seconds(1));
211
212 if (monitor.joinable()) monitor.join();
213
214 write_log(_("=== Arresto BastionGuard-privacyd ==="));
215 return 0;
216}
#define _(s)
void handle_signal(int)
void monitor_loop()
void write_log(const std::string &msg)
#define LOCALEDIR

References _, handle_signal(), LOCALEDIR, main(), monitor_loop(), running, and write_log().

◆ monitor_loop()

void monitor_loop ( )

Definition at line 152 of file BastionGuard-privacyd.cpp.

152 {
153 std::set<std::string> known;
154 write_log(_("[privacyd] Avviato monitoraggio webcam/microfono."));
155
156 while (running) {
157 try {
158 auto active = detect_active_devices();
159
160 for (const auto& proc : active) {
161 if (!known.count(proc)) {
162 known.insert(proc);
163 write_log(_("Nuovo accesso: ") + proc);
164 }
165 }
166
167 for (auto it = known.begin(); it != known.end();) {
168 if (std::find(active.begin(), active.end(), *it) == active.end()) {
169 write_log(
170 Glib::ustring::compose(
171 _("Accesso terminato: %1"),
172 *it
173 )
174 );
175 it = known.erase(it);
176 } else ++it;
177 }
178 } catch (const std::exception& e) {
179 // Difesa in profondità: qualsiasi eccezione non catturata qui
180 // ucciderebbe il daemon.
181 try { write_log(std::string("[privacyd] Errore monitor_loop: ") + e.what()); }
182 catch (...) {}
183 } catch (...) {
184 try { write_log("[privacyd] Errore sconosciuto in monitor_loop"); }
185 catch (...) {}
186 }
187
188 std::this_thread::sleep_for(std::chrono::seconds(3));
189 }
190
191 write_log(_("[privacyd] Monitoraggio terminato."));
192}
std::vector< std::string > detect_active_devices()

References _, detect_active_devices(), monitor_loop(), running, and write_log().

Referenced by main(), main(), and monitor_loop().

◆ write_log()

void write_log ( const std::string & msg)

Definition at line 40 of file BastionGuard-privacyd.cpp.

40 {
41 std::thread([msg]() {
42 try {
43 std::lock_guard<std::mutex> lock(log_mutex);
44 std::string base_dir = Glib::get_home_dir() + "/.local/share/BastionGuard/logs";
45 if (!fs::exists(base_dir))
46 fs::create_directories(base_dir);
47
48
49 auto t = std::time(nullptr);
50 std::tm tm{};
51 localtime_r(&t, &tm); // thread-safe
52 char datebuf[16];
53 std::strftime(datebuf, sizeof(datebuf), "%Y-%m-%d", &tm);
54 std::string log_path = base_dir + "/privacyd_" + std::string(datebuf) + ".log";
55
56
57 std::ofstream f(log_path, std::ios::app);
58 if (!f.is_open()) return;
59
60 char timebuf[32];
61 std::strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
62 f << "[" << timebuf << "] " << msg << std::endl;
63
64
65 const auto now = std::chrono::system_clock::now();
66 const auto seven_days = std::chrono::hours(24 * 7);
67
68 for (const auto& entry : fs::directory_iterator(base_dir)) {
69 if (entry.is_regular_file()) {
70 auto ftime = fs::last_write_time(entry);
71 auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
72 ftime - fs::file_time_type::clock::now()
73 + std::chrono::system_clock::now());
74 auto age = now - sctp;
75
76 if (age > seven_days) {
77 try {
78 fs::remove(entry.path());
79 } catch (...) {
80
81 }
82 }
83 }
84 }
85 } catch (...) {
86 std::cerr << _("[privacyd] Errore scrittura log.") << std::endl;
87 }
88 }).detach();
89}
static std::mutex log_mutex

References _, log_mutex, and write_log().

Referenced by main(), main(), monitor_loop(), send_device_added(), send_device_removed(), and write_log().

Variable Documentation

◆ log_mutex

std::mutex log_mutex
static

Definition at line 38 of file BastionGuard-privacyd.cpp.

Referenced by write_log().

◆ running

std::atomic<bool> running {true}
static