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

Go to the source code of this file.

Classes

struct  USBDevice

Functions

void write_log (const std::string &msg)
void send_device_added (const USBDevice &dev)
void send_device_removed (const std::string &devnode)
std::vector< USBDevice > detect_usb_devices ()
void monitor_loop ()
void handle_signal (int)
static bool load_lang_conf ()
int main ()

Variables

static std::atomic< bool > running {true}
static std::mutex log_mutex
static GDBusConnection * bus = nullptr

Function Documentation

◆ detect_usb_devices()

std::vector< USBDevice > detect_usb_devices ( )

Definition at line 143 of file BastionGuard-usbd-gdbus.cpp.

144{
145 std::vector<USBDevice> result;
146
147 struct udev *udev = udev_new();
148 if (!udev) return result;
149
150 struct udev_enumerate *enumerate = udev_enumerate_new(udev);
151 if (!enumerate) { udev_unref(udev); return result; }
152
153 udev_enumerate_add_match_subsystem(enumerate, "block");
154 udev_enumerate_scan_devices(enumerate);
155
156 struct udev_list_entry *entries = udev_enumerate_get_list_entry(enumerate);
157 struct udev_list_entry *entry;
158
159 udev_list_entry_foreach(entry, entries)
160 {
161 const char *path = udev_list_entry_get_name(entry);
162 struct udev_device *dev = udev_device_new_from_syspath(udev, path);
163 if (!dev) continue;
164 const char *devtype = udev_device_get_devtype(dev);
165 if (!devtype || std::string(devtype) != "disk") {
166 udev_device_unref(dev);
167 continue;
168 }
169
170
171 struct udev_device *usb =
172 udev_device_get_parent_with_subsystem_devtype(
173 dev, "usb", "usb_device");
174
175 if (!usb) {
176 udev_device_unref(dev);
177 continue;
178 }
179
180 const char *size = udev_device_get_sysattr_value(dev, "size");
181 if (!size || std::strtoull(size, nullptr, 10) == 0) {
182 udev_device_unref(dev);
183 continue;
184 }
185
186 const char *rem = udev_device_get_sysattr_value(dev, "removable");
187 if (!rem || std::string(rem) != "1") {
188 udev_device_unref(dev);
189 continue;
190 }
191
192 USBDevice info;
193
194 const char *devnode = udev_device_get_devnode(dev);
195 if (!devnode) {
196 udev_device_unref(dev);
197 continue;
198 }
199
200 info.devnode = devnode;
201
202 const char *vendor = udev_device_get_sysattr_value(usb, "manufacturer");
203 const char *product = udev_device_get_sysattr_value(usb, "product");
204 const char *serial = udev_device_get_sysattr_value(usb, "serial");
205
206 if (vendor) info.name += vendor;
207 if (product) {
208 if (!info.name.empty()) info.name += " ";
209 info.name += product;
210 }
211
212 if (info.name.empty())
213 info.name = info.devnode;
214
215 if (serial) info.serial = serial;
216
217 result.push_back(info);
218
219 udev_device_unref(dev);
220 }
221
222 udev_enumerate_unref(enumerate);
223 udev_unref(udev);
224
225 return result;
226}

References detect_usb_devices(), USBDevice::devnode, USBDevice::name, and USBDevice::serial.

Referenced by detect_usb_devices(), and monitor_loop().

◆ handle_signal()

void handle_signal ( int )

Definition at line 268 of file BastionGuard-usbd-gdbus.cpp.

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

References handle_signal(), and running.

◆ load_lang_conf()

bool load_lang_conf ( )
static

Definition at line 270 of file BastionGuard-usbd-gdbus.cpp.

271{
272 const std::string lang_conf = Glib::get_home_dir() + "/.config/BastionGuard/lang.conf";
273 std::ifstream f(lang_conf);
274 if (!f.is_open())
275 return false;
276
277 std::string line;
278 bool any = false;
279
280 while (std::getline(f, line)) {
281 if (line.empty() || line[0] == '#')
282 continue;
283
284 auto pos = line.find('=');
285 if (pos == std::string::npos)
286 continue;
287
288 std::string key = line.substr(0, pos);
289 std::string val = line.substr(pos + 1);
290
291 auto ltrim = [](std::string& s){
292 s.erase(0, s.find_first_not_of(" \t\r\n"));
293 };
294 auto rtrim = [](std::string& s){
295 s.erase(s.find_last_not_of(" \t\r\n") + 1);
296 };
297 ltrim(key); rtrim(key);
298 ltrim(val); rtrim(val);
299
300 if (!key.empty() && !val.empty()) {
301 setenv(key.c_str(), val.c_str(), 1);
302 any = true;
303 }
304 }
305
306 return any;
307}

References load_lang_conf().

◆ main()

int main ( void )

Definition at line 308 of file BastionGuard-usbd-gdbus.cpp.

309{
310 bool loaded = load_lang_conf();
311
312
313 std::setlocale(LC_ALL, "");
314 bindtextdomain("BastionGuard", LOCALEDIR);
315 bind_textdomain_codeset("BastionGuard", "UTF-8");
316 textdomain("BastionGuard");
317
318 if (loaded) {
319 std::cerr << _("[Lang] Config caricata da ~/.config/BastionGuard/lang.conf") << "\n";
320 } else {
321 std::cerr << _("[Lang] Nessuna config trovata, uso locale di sistema") << "\n";
322 }
323
324 std::signal(SIGINT, handle_signal);
325 std::signal(SIGTERM, handle_signal);
326
327 // D-Bus init through GLib/GIO, independent from the init system.
328 GError* dbus_error = nullptr;
329 bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &dbus_error);
330 if (!bus) {
331 std::cerr << _("Errore apertura system bus: ")
332 << (dbus_error ? dbus_error->message : _("errore sconosciuto"))
333 << "\n";
334 if (dbus_error) g_error_free(dbus_error);
335 return 1;
336 }
337
338 GVariant* request_reply = g_dbus_connection_call_sync(
339 bus,
340 "org.freedesktop.DBus",
341 "/org/freedesktop/DBus",
342 "org.freedesktop.DBus",
343 "RequestName",
344 g_variant_new("(su)", "org.BastionGuard.USBD", 0u),
345 G_VARIANT_TYPE("(u)"),
346 G_DBUS_CALL_FLAGS_NONE,
347 -1,
348 nullptr,
349 &dbus_error);
350
351 if (!request_reply) {
352 std::cerr << _("Errore registrazione nome DBus: ")
353 << (dbus_error ? dbus_error->message : _("errore sconosciuto"))
354 << "\n";
355 if (dbus_error) g_error_free(dbus_error);
356 g_object_unref(bus);
357 bus = nullptr;
358 return 1;
359 }
360
361 guint32 request_result = 0;
362 g_variant_get(request_reply, "(u)", &request_result);
363 g_variant_unref(request_reply);
364 if (request_result != 1u && request_result != 4u) {
365 std::cerr << _("Nome DBus org.BastionGuard.USBD già occupato.\n");
366 g_object_unref(bus);
367 bus = nullptr;
368 return 1;
369 }
370
371 write_log(_("BastionGuard-usbd avviato."));
372
373 std::thread th(monitor_loop);
374
375 while (running)
376 std::this_thread::sleep_for(std::chrono::seconds(1));
377
378 if (th.joinable()) th.join();
379
380 g_object_unref(bus);
381 bus = nullptr;
382 write_log(_("BastionGuard-usbd terminato."));
383
384 return 0;
385}
#define _(s)
void handle_signal(int)
void monitor_loop()
void write_log(const std::string &msg)
static bool load_lang_conf()
static GDBusConnection * bus
#define LOCALEDIR

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

◆ monitor_loop()

void monitor_loop ( )

Definition at line 229 of file BastionGuard-usbd-gdbus.cpp.

230{
231 write_log(_("Monitor USB avviato."));
232
233 std::set<std::string> known;
234
235 while (running)
236 {
237 auto list = detect_usb_devices();
238
239 for (auto &d : list) {
240 if (!known.count(d.devnode)) {
241 known.insert(d.devnode);
242 write_log(_("Collegato USB: ") + d.name + " (" + d.devnode + ")");
244 }
245 }
246
247 for (auto it = known.begin(); it != known.end(); ) {
248 bool still = false;
249 for (auto &d : list)
250 if (d.devnode == *it) still = true;
251
252 if (!still) {
253 write_log(_("Rimosso USB: ") + *it);
255 it = known.erase(it);
256 } else {
257 ++it;
258 }
259 }
260
261 std::this_thread::sleep_for(std::chrono::seconds(2));
262 }
263
264 write_log(_("Monitor USB terminato."));
265}
std::vector< USBDevice > detect_usb_devices()
void send_device_removed(const std::string &devnode)
void send_device_added(const USBDevice &dev)

References _, detect_usb_devices(), monitor_loop(), running, send_device_added(), send_device_removed(), and write_log().

◆ send_device_added()

void send_device_added ( const USBDevice & dev)

Definition at line 100 of file BastionGuard-usbd-gdbus.cpp.

101{
102 if (!bus) return;
103
104 GError* error = nullptr;
105 g_dbus_connection_emit_signal(
106 bus,
107 nullptr,
108 "/org/BastionGuard/USBD",
109 "org.BastionGuard.USBD",
110 "DeviceAdded",
111 g_variant_new("(sss)",
112 dev.name.c_str(),
113 dev.devnode.c_str(),
114 dev.serial.c_str()),
115 &error);
116
117 if (error) {
118 write_log(std::string(_("Errore invio segnale DeviceAdded: ")) + error->message);
119 g_error_free(error);
120 }
121}

References _, bus, USBDevice::devnode, USBDevice::name, send_device_added(), USBDevice::serial, and write_log().

Referenced by monitor_loop(), and send_device_added().

◆ send_device_removed()

void send_device_removed ( const std::string & devnode)

Definition at line 123 of file BastionGuard-usbd-gdbus.cpp.

124{
125 if (!bus) return;
126
127 GError* error = nullptr;
128 g_dbus_connection_emit_signal(
129 bus,
130 nullptr,
131 "/org/BastionGuard/USBD",
132 "org.BastionGuard.USBD",
133 "DeviceRemoved",
134 g_variant_new("(s)", devnode.c_str()),
135 &error);
136
137 if (error) {
138 write_log(std::string(_("Errore invio segnale DeviceRemoved: ")) + error->message);
139 g_error_free(error);
140 }
141}

References _, bus, send_device_removed(), and write_log().

Referenced by monitor_loop(), and send_device_removed().

◆ write_log()

void write_log ( const std::string & msg)

Definition at line 45 of file BastionGuard-usbd-gdbus.cpp.

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

References log_mutex, and write_log().

Variable Documentation

◆ bus

GDBusConnection* bus = nullptr
static

Definition at line 43 of file BastionGuard-usbd-gdbus.cpp.

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

◆ log_mutex

std::mutex log_mutex
static

Definition at line 42 of file BastionGuard-usbd-gdbus.cpp.

◆ running

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

Definition at line 41 of file BastionGuard-usbd-gdbus.cpp.