admin.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2021 Google LLC
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdlib.h>
  14. #include <dbus/dbus.h>
  15. #include <gdbus/gdbus.h>
  16. #include <sys/file.h>
  17. #include <sys/stat.h>
  18. #include <errno.h>
  19. #include "lib/bluetooth.h"
  20. #include "lib/uuid.h"
  21. #include "src/adapter.h"
  22. #include "src/dbus-common.h"
  23. #include "src/device.h"
  24. #include "src/error.h"
  25. #include "src/log.h"
  26. #include "src/plugin.h"
  27. #include "src/textfile.h"
  28. #include "src/shared/queue.h"
  29. #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1"
  30. #define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1"
  31. #define ADMIN_POLICY_STORAGE STORAGEDIR "/admin_policy_settings"
  32. #define DBUS_BLUEZ_SERVICE "org.bluez"
  33. #define BTD_DEVICE_INTERFACE "org.bluez.Device1"
  34. static DBusConnection *dbus_conn;
  35. static struct queue *devices; /* List of struct device_data objects */
  36. /* |policy_data| has the same life cycle as btd_adapter */
  37. static struct btd_admin_policy {
  38. struct btd_adapter *adapter;
  39. uint16_t adapter_id;
  40. struct queue *service_allowlist;
  41. } *policy_data = NULL;
  42. struct device_data {
  43. struct btd_device *device;
  44. char *path;
  45. bool affected;
  46. };
  47. static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter)
  48. {
  49. struct btd_admin_policy *admin_policy = NULL;
  50. admin_policy = g_try_malloc(sizeof(*admin_policy));
  51. if (!admin_policy) {
  52. btd_error(btd_adapter_get_index(adapter),
  53. "Failed to allocate memory for admin_policy");
  54. return NULL;
  55. }
  56. admin_policy->adapter = adapter;
  57. admin_policy->adapter_id = btd_adapter_get_index(adapter);
  58. admin_policy->service_allowlist = queue_new();
  59. return admin_policy;
  60. }
  61. static void free_service_allowlist(struct queue *q)
  62. {
  63. queue_destroy(q, free);
  64. }
  65. static void admin_policy_free(void *data)
  66. {
  67. struct btd_admin_policy *admin_policy = data;
  68. free_service_allowlist(admin_policy->service_allowlist);
  69. g_free(admin_policy);
  70. }
  71. static void admin_policy_destroy(struct btd_admin_policy *admin_policy)
  72. {
  73. const char *path = adapter_get_path(admin_policy->adapter);
  74. g_dbus_unregister_interface(dbus_conn, path,
  75. ADMIN_POLICY_SET_INTERFACE);
  76. g_dbus_unregister_interface(dbus_conn, path,
  77. ADMIN_POLICY_STATUS_INTERFACE);
  78. admin_policy_free(admin_policy);
  79. }
  80. static bool uuid_match(const void *data, const void *match_data)
  81. {
  82. const bt_uuid_t *uuid = data;
  83. const bt_uuid_t *match_uuid = match_data;
  84. return bt_uuid_cmp(uuid, match_uuid) == 0;
  85. }
  86. static struct queue *parse_allow_service_list(struct btd_adapter *adapter,
  87. DBusMessage *msg)
  88. {
  89. DBusMessageIter iter, arr_iter;
  90. struct queue *uuid_list = NULL;
  91. dbus_message_iter_init(msg, &iter);
  92. if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
  93. return NULL;
  94. uuid_list = queue_new();
  95. dbus_message_iter_recurse(&iter, &arr_iter);
  96. do {
  97. const int type = dbus_message_iter_get_arg_type(&arr_iter);
  98. char *uuid_param;
  99. bt_uuid_t *uuid;
  100. if (type == DBUS_TYPE_INVALID)
  101. break;
  102. if (type != DBUS_TYPE_STRING)
  103. goto failed;
  104. dbus_message_iter_get_basic(&arr_iter, &uuid_param);
  105. uuid = g_try_malloc(sizeof(*uuid));
  106. if (!uuid)
  107. goto failed;
  108. if (bt_string_to_uuid(uuid, uuid_param)) {
  109. g_free(uuid);
  110. goto failed;
  111. }
  112. dbus_message_iter_next(&arr_iter);
  113. if (queue_find(uuid_list, uuid_match, uuid)) {
  114. g_free(uuid);
  115. continue;
  116. }
  117. queue_push_head(uuid_list, uuid);
  118. } while (true);
  119. return uuid_list;
  120. failed:
  121. queue_destroy(uuid_list, g_free);
  122. return NULL;
  123. }
  124. static bool service_allowlist_set(struct btd_admin_policy *admin_policy,
  125. struct queue *uuid_list)
  126. {
  127. struct btd_adapter *adapter = admin_policy->adapter;
  128. if (!btd_adapter_set_allowed_uuids(adapter, uuid_list))
  129. return false;
  130. free_service_allowlist(admin_policy->service_allowlist);
  131. admin_policy->service_allowlist = uuid_list;
  132. return true;
  133. }
  134. static void update_device_affected(void *data, void *user_data)
  135. {
  136. struct device_data *dev_data = data;
  137. bool affected;
  138. if (!dev_data) {
  139. error("Unexpected NULL device_data when updating device");
  140. return;
  141. }
  142. affected = !btd_device_all_services_allowed(dev_data->device);
  143. if (affected == dev_data->affected)
  144. return;
  145. dev_data->affected = affected;
  146. g_dbus_emit_property_changed(dbus_conn, dev_data->path,
  147. ADMIN_POLICY_STATUS_INTERFACE, "AffectedByPolicy");
  148. }
  149. static void free_uuid_strings(char **uuid_strs, gsize num)
  150. {
  151. gsize i;
  152. for (i = 0; i < num; i++)
  153. g_free(uuid_strs[i]);
  154. g_free(uuid_strs);
  155. }
  156. static char **new_uuid_strings(struct queue *allowlist, gsize *num)
  157. {
  158. const struct queue_entry *entry = NULL;
  159. bt_uuid_t *uuid = NULL;
  160. char **uuid_strs = NULL;
  161. gsize i = 0, allowlist_num;
  162. allowlist_num = queue_length(allowlist);
  163. if (!allowlist_num) {
  164. *num = 0;
  165. return NULL;
  166. }
  167. /* Set num to a non-zero number so that whoever call this could know if
  168. * this function success or not
  169. */
  170. *num = 1;
  171. uuid_strs = g_try_malloc_n(allowlist_num, sizeof(char *));
  172. if (!uuid_strs)
  173. return NULL;
  174. for (entry = queue_get_entries(allowlist); entry != NULL;
  175. entry = entry->next) {
  176. uuid = entry->data;
  177. uuid_strs[i] = g_try_malloc0(MAX_LEN_UUID_STR * sizeof(char));
  178. if (!uuid_strs[i])
  179. goto failed;
  180. bt_uuid_to_string(uuid, uuid_strs[i], MAX_LEN_UUID_STR);
  181. i++;
  182. }
  183. *num = allowlist_num;
  184. return uuid_strs;
  185. failed:
  186. free_uuid_strings(uuid_strs, i);
  187. return NULL;
  188. }
  189. static void store_policy_settings(struct btd_admin_policy *admin_policy)
  190. {
  191. GKeyFile *key_file = NULL;
  192. char *filename = ADMIN_POLICY_STORAGE;
  193. char *key_file_data = NULL;
  194. char **uuid_strs = NULL;
  195. gsize length, num_uuids;
  196. key_file = g_key_file_new();
  197. uuid_strs = new_uuid_strings(admin_policy->service_allowlist,
  198. &num_uuids);
  199. if (!uuid_strs && num_uuids) {
  200. btd_error(admin_policy->adapter_id,
  201. "Failed to allocate uuid strings");
  202. goto failed;
  203. }
  204. g_key_file_set_string_list(key_file, "General", "ServiceAllowlist",
  205. (const gchar * const *)uuid_strs,
  206. num_uuids);
  207. if (create_file(ADMIN_POLICY_STORAGE, 0600) < 0) {
  208. btd_error(admin_policy->adapter_id, "create %s failed, %s",
  209. filename, strerror(errno));
  210. goto failed;
  211. }
  212. key_file_data = g_key_file_to_data(key_file, &length, NULL);
  213. g_file_set_contents(ADMIN_POLICY_STORAGE, key_file_data, length, NULL);
  214. g_free(key_file_data);
  215. free_uuid_strings(uuid_strs, num_uuids);
  216. failed:
  217. g_key_file_free(key_file);
  218. }
  219. static void key_file_load_service_allowlist(GKeyFile *key_file,
  220. struct btd_admin_policy *admin_policy)
  221. {
  222. GError *gerr = NULL;
  223. struct queue *uuid_list = NULL;
  224. gchar **uuids = NULL;
  225. gsize num, i;
  226. uuids = g_key_file_get_string_list(key_file, "General",
  227. "ServiceAllowlist", &num, &gerr);
  228. if (gerr) {
  229. btd_error(admin_policy->adapter_id,
  230. "Failed to load ServiceAllowlist");
  231. g_error_free(gerr);
  232. return;
  233. }
  234. uuid_list = queue_new();
  235. for (i = 0; i < num; i++) {
  236. bt_uuid_t *uuid = g_try_malloc(sizeof(*uuid));
  237. if (!uuid)
  238. goto failed;
  239. if (bt_string_to_uuid(uuid, uuids[i])) {
  240. btd_error(admin_policy->adapter_id,
  241. "Failed to convert '%s' to uuid struct",
  242. *uuids);
  243. g_free(uuid);
  244. goto failed;
  245. }
  246. queue_push_tail(uuid_list, uuid);
  247. }
  248. if (!service_allowlist_set(admin_policy, uuid_list))
  249. goto failed;
  250. g_strfreev(uuids);
  251. return;
  252. failed:
  253. g_strfreev(uuids);
  254. free_service_allowlist(uuid_list);
  255. }
  256. static void load_policy_settings(struct btd_admin_policy *admin_policy)
  257. {
  258. GKeyFile *key_file;
  259. char *filename = ADMIN_POLICY_STORAGE;
  260. struct stat st;
  261. if (stat(filename, &st) < 0)
  262. store_policy_settings(policy_data);
  263. key_file = g_key_file_new();
  264. g_key_file_load_from_file(key_file, filename, 0, NULL);
  265. key_file_load_service_allowlist(key_file, admin_policy);
  266. g_key_file_free(key_file);
  267. }
  268. static DBusMessage *set_service_allowlist(DBusConnection *conn,
  269. DBusMessage *msg, void *user_data)
  270. {
  271. struct btd_admin_policy *admin_policy = user_data;
  272. struct btd_adapter *adapter = admin_policy->adapter;
  273. struct queue *uuid_list = NULL;
  274. const char *sender = dbus_message_get_sender(msg);
  275. DBG("sender %s", sender);
  276. /* Parse parameters */
  277. uuid_list = parse_allow_service_list(adapter, msg);
  278. if (!uuid_list) {
  279. btd_error(admin_policy->adapter_id,
  280. "Failed on parsing allowed service list");
  281. return btd_error_invalid_args(msg);
  282. }
  283. if (service_allowlist_set(admin_policy, uuid_list)) {
  284. store_policy_settings(admin_policy);
  285. } else {
  286. free_service_allowlist(uuid_list);
  287. return btd_error_failed(msg, "service_allowlist_set failed");
  288. }
  289. g_dbus_emit_property_changed(dbus_conn,
  290. adapter_get_path(policy_data->adapter),
  291. ADMIN_POLICY_STATUS_INTERFACE,
  292. "ServiceAllowList");
  293. queue_foreach(devices, update_device_affected, NULL);
  294. return dbus_message_new_method_return(msg);
  295. }
  296. static const GDBusMethodTable admin_policy_adapter_methods[] = {
  297. { GDBUS_METHOD("SetServiceAllowList", GDBUS_ARGS({ "UUIDs", "as" }),
  298. NULL, set_service_allowlist) },
  299. { }
  300. };
  301. static void append_service_uuid(void *data, void *user_data)
  302. {
  303. bt_uuid_t *uuid = data;
  304. DBusMessageIter *entry = user_data;
  305. char uuid_str[MAX_LEN_UUID_STR];
  306. const char *uuid_str_ptr = uuid_str;
  307. if (!uuid) {
  308. error("Unexpected NULL uuid data in service_allowlist");
  309. return;
  310. }
  311. bt_uuid_to_string(uuid, uuid_str, MAX_LEN_UUID_STR);
  312. dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &uuid_str_ptr);
  313. }
  314. static gboolean property_get_service_allowlist(
  315. const GDBusPropertyTable *property,
  316. DBusMessageIter *iter, void *user_data)
  317. {
  318. struct btd_admin_policy *admin_policy = user_data;
  319. DBusMessageIter entry;
  320. dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
  321. DBUS_TYPE_STRING_AS_STRING, &entry);
  322. queue_foreach(admin_policy->service_allowlist, append_service_uuid,
  323. &entry);
  324. dbus_message_iter_close_container(iter, &entry);
  325. return TRUE;
  326. }
  327. static const GDBusPropertyTable admin_policy_adapter_properties[] = {
  328. { "ServiceAllowList", "as", property_get_service_allowlist },
  329. { }
  330. };
  331. static bool device_data_match(const void *a, const void *b)
  332. {
  333. const struct device_data *data = a;
  334. const struct btd_device *dev = b;
  335. if (!data) {
  336. error("Unexpected NULL device_data");
  337. return false;
  338. }
  339. return data->device == dev;
  340. }
  341. static gboolean property_get_affected_by_policy(
  342. const GDBusPropertyTable *property,
  343. DBusMessageIter *iter, void *user_data)
  344. {
  345. struct device_data *data = user_data;
  346. if (!data) {
  347. error("Unexpected error: device_data is NULL");
  348. return FALSE;
  349. }
  350. dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
  351. &data->affected);
  352. return TRUE;
  353. }
  354. static const GDBusPropertyTable admin_policy_device_properties[] = {
  355. { "AffectedByPolicy", "b", property_get_affected_by_policy },
  356. { }
  357. };
  358. static void free_device_data(void *data)
  359. {
  360. struct device_data *device_data = data;
  361. g_free(device_data->path);
  362. g_free(device_data);
  363. }
  364. static void remove_device_data(void *data)
  365. {
  366. struct device_data *device_data = data;
  367. DBG("device_data for %s removing", device_data->path);
  368. queue_remove(devices, device_data);
  369. free_device_data(device_data);
  370. }
  371. static int admin_policy_adapter_probe(struct btd_adapter *adapter)
  372. {
  373. const char *adapter_path;
  374. if (policy_data) {
  375. btd_warn(policy_data->adapter_id,
  376. "Policy data already exists");
  377. admin_policy_free(policy_data);
  378. policy_data = NULL;
  379. }
  380. policy_data = admin_policy_new(adapter);
  381. if (!policy_data)
  382. return -ENOMEM;
  383. load_policy_settings(policy_data);
  384. adapter_path = adapter_get_path(adapter);
  385. if (!g_dbus_register_interface(dbus_conn, adapter_path,
  386. ADMIN_POLICY_SET_INTERFACE,
  387. admin_policy_adapter_methods, NULL,
  388. NULL, policy_data, NULL)) {
  389. btd_error(policy_data->adapter_id,
  390. "Admin Policy Set interface init failed on path %s",
  391. adapter_path);
  392. return -EINVAL;
  393. }
  394. btd_info(policy_data->adapter_id,
  395. "Admin Policy Set interface registered");
  396. if (!g_dbus_register_interface(dbus_conn, adapter_path,
  397. ADMIN_POLICY_STATUS_INTERFACE,
  398. NULL, NULL,
  399. admin_policy_adapter_properties,
  400. policy_data, NULL)) {
  401. btd_error(policy_data->adapter_id,
  402. "Admin Policy Status interface init failed on path %s",
  403. adapter_path);
  404. return -EINVAL;
  405. }
  406. btd_info(policy_data->adapter_id,
  407. "Admin Policy Status interface registered");
  408. return 0;
  409. }
  410. static void admin_policy_device_added(struct btd_adapter *adapter,
  411. struct btd_device *device)
  412. {
  413. struct device_data *data;
  414. if (queue_find(devices, device_data_match, device))
  415. return;
  416. data = g_new0(struct device_data, 1);
  417. if (!data) {
  418. btd_error(btd_adapter_get_index(adapter),
  419. "Failed to allocate memory for device_data");
  420. return;
  421. }
  422. data->device = device;
  423. data->path = g_strdup(device_get_path(device));
  424. data->affected = !btd_device_all_services_allowed(data->device);
  425. if (!g_dbus_register_interface(dbus_conn, data->path,
  426. ADMIN_POLICY_STATUS_INTERFACE,
  427. NULL, NULL,
  428. admin_policy_device_properties,
  429. data, remove_device_data)) {
  430. btd_error(btd_adapter_get_index(adapter),
  431. "Admin Policy Status interface init failed on path %s",
  432. device_get_path(device));
  433. free_device_data(data);
  434. return;
  435. }
  436. queue_push_tail(devices, data);
  437. DBG("device_data for %s added", data->path);
  438. }
  439. static void unregister_device_data(void *data, void *user_data)
  440. {
  441. struct device_data *dev_data = data;
  442. g_dbus_unregister_interface(dbus_conn, dev_data->path,
  443. ADMIN_POLICY_STATUS_INTERFACE);
  444. }
  445. static void admin_policy_device_removed(struct btd_adapter *adapter,
  446. struct btd_device *device)
  447. {
  448. struct device_data *data;
  449. data = queue_find(devices, device_data_match, device);
  450. if (data)
  451. unregister_device_data(data, NULL);
  452. }
  453. static void admin_policy_remove(struct btd_adapter *adapter)
  454. {
  455. DBG("");
  456. queue_foreach(devices, unregister_device_data, NULL);
  457. queue_destroy(devices, g_free);
  458. devices = NULL;
  459. if (policy_data) {
  460. admin_policy_destroy(policy_data);
  461. policy_data = NULL;
  462. }
  463. }
  464. static struct btd_adapter_driver admin_policy_driver = {
  465. .name = "admin_policy",
  466. .probe = admin_policy_adapter_probe,
  467. .resume = NULL,
  468. .remove = admin_policy_remove,
  469. .device_resolved = admin_policy_device_added,
  470. .device_removed = admin_policy_device_removed
  471. };
  472. static int admin_init(void)
  473. {
  474. DBG("");
  475. dbus_conn = btd_get_dbus_connection();
  476. devices = queue_new();
  477. return btd_register_adapter_driver(&admin_policy_driver);
  478. }
  479. static void admin_exit(void)
  480. {
  481. DBG("");
  482. btd_unregister_adapter_driver(&admin_policy_driver);
  483. }
  484. BLUETOOTH_PLUGIN_DEFINE(admin, VERSION,
  485. BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
  486. admin_init, admin_exit)