From patchwork Wed Jul 28 13:15:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41D63C432BE for ; Wed, 28 Jul 2021 13:15:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1A40E6100A for ; Wed, 28 Jul 2021 13:15:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235301AbhG1NPr (ORCPT ); Wed, 28 Jul 2021 09:15:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235204AbhG1NPq (ORCPT ); Wed, 28 Jul 2021 09:15:46 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84FC0C061757 for ; Wed, 28 Jul 2021 06:15:44 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id hf7-20020a0562140e87b02902dc988b8675so1935502qvb.3 for ; Wed, 28 Jul 2021 06:15:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DL2MaMzk+eOHtADn15C9fhPVEM1UNggN3rQz3EprNuo=; b=UvVwgLLGuSf8WTxOLfrzFlirzPZFI7kajuwabmBftKk2/oIIKT7PMRId1QkEB+TncW 0I190KLwUNdIlTYJkW+eSv3nujzIsWs4JxwGzMQdtSdiDGN8yIJCcYQ4MlKYmT4LLu9Z vRYiQRmF4s6hJCAftfpG0dGhGd4YfiL8qOqXEv4Pk0NP1KgUwYhRTdWiStVub2yGWDPi bKKxpVZVdtl8XY4YZzWEcenXz37LHr03lWz+IVvqSxEzUEY8OKCmS9Z/N7aeE6TkNsFh JKQLZsosMnQLXvCaLb83HgM4wiGeeG6pbXtFf05+DpqisxH7yvgabtYSJLM4DW/sKqlH glLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DL2MaMzk+eOHtADn15C9fhPVEM1UNggN3rQz3EprNuo=; b=jn/MzYoOyYvkiu3Hiy82b0yaEm7Qlc1UFgqlf3nIRDQXXnPZO4XYeIfw0hmFjZXqPL zLnTW7JZ0y5XXNYj/nFbSnbBMW2HCuDYZvrgtFzrkHCbJLPa3PhhZLQAQMkfNFJHA9pC RMgOTWrwraiI5LRsIIg55/PkN+s9MDV2X3cO5gE424pMk7zH8KFFNGVl5d7atwSTrP2Z O/2O5OBJjEBFUq8OT3+VJbVRB1tzjHcQmEjlW4zKW4Un9iSzEhIP4bQYmWFlDPTw3ada b5ISTjcsY7Knuqa+6086smxv9er1DxfUwEInKJrVby41SHcaJ3Sr6rSz+lk0inC4PC7y G3FQ== X-Gm-Message-State: AOAM530ScCVX0A135UVCo4fwl3o1Sv1LDjxSkdpMHVPqIFF69dVVtdBj H7ElBfKOq79AMq0MGf5SixkHGHkg1eDiDW99RejQ53OwrHpH+Iyl1NaK9lCjRx+XPTY9LwqdpXa hg7jFatg/L1PmpiaRvSTWqKq52b5/1Y07vzabsr8a645magbiiPNfqgwwjXJOybju0ksh1pXcHO Rv5JgWyFb5rPY= X-Google-Smtp-Source: ABdhPJwJxhFcm9VNAmMa/7nVT/tHuLi3nUoMBr2sNCO1jQl/Cj82/ke8OPoyu6LCFt3jpvjmzcY1lfAAyVq/Ulg2Lg== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a05:6214:dab:: with SMTP id h11mr2771808qvh.21.1627478143430; Wed, 28 Jul 2021 06:15:43 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:17 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.1.Ic71b1ed97538a06d02425ba502690bdab1c5d836@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 01/13] core: add is_allowed property in btd_service From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds is_allowed property in btd_service. When is_allowed is set to false, calling btd_service_connect and service_accept will fail and the existing service connection gets disconnected. Reviewed-by: Miao-chen Chou --- Changes in v3: - Rename plugins/admin_policy.c -> plugins/admin.c - Use device_added callback in btd_adapter_driver instead of listen for dbus - Add authorization method in profiles/health/mcap.c and block incoming connections in adapter authorization function. Changes in v2: - Move bt_uuid_hash and bt_uuid_equal functions to adapter.c. - Modify the criteria to say a device is `Affected` from any-of-uuid to any-of-auto-connect-profile. - Remove the code to remove/reprobe disallowed/allowed profiles, instead, check if the service is allowed in bt_io_accept connect_cb. - Fix a typo in emit_property_change in plugin/admin_policy.c:set_service_allowlist - Instead of using device_state_cb, utilize D-BUS client to watch device added/removed. - Add a document in doc/ src/service.c | 39 +++++++++++++++++++++++++++++++++++++++ src/service.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/src/service.c b/src/service.c index 21a52762e..929d6c136 100644 --- a/src/service.c +++ b/src/service.c @@ -41,6 +41,7 @@ struct btd_service { void *user_data; btd_service_state_t state; int err; + bool is_allowed; }; struct service_state_callback { @@ -133,6 +134,7 @@ struct btd_service *service_create(struct btd_device *device, service->device = device; /* Weak ref */ service->profile = profile; service->state = BTD_SERVICE_STATE_UNAVAILABLE; + service->is_allowed = true; return service; } @@ -186,6 +188,18 @@ int service_accept(struct btd_service *service) if (!service->profile->accept) return -ENOSYS; + if (!service->is_allowed) { + info("service %s is not allowed", + service->profile->remote_uuid); + return -ECONNABORTED; + } + + if (!service->is_allowed) { + info("service %s is not allowed", + service->profile->remote_uuid); + return -ECONNABORTED; + } + err = service->profile->accept(service); if (!err) goto done; @@ -245,6 +259,12 @@ int btd_service_connect(struct btd_service *service) return -EBUSY; } + if (!service->is_allowed) { + info("service %s is not allowed", + service->profile->remote_uuid); + return -ECONNABORTED; + } + err = profile->connect(service); if (err == 0) { change_state(service, BTD_SERVICE_STATE_CONNECTING, 0); @@ -361,6 +381,25 @@ bool btd_service_remove_state_cb(unsigned int id) return false; } +void btd_service_set_allowed(struct btd_service *service, bool allowed) +{ + if (allowed == service->is_allowed) + return; + + service->is_allowed = allowed; + + if (!allowed && (service->state == BTD_SERVICE_STATE_CONNECTING || + service->state == BTD_SERVICE_STATE_CONNECTED)) { + btd_service_disconnect(service); + return; + } +} + +bool btd_service_is_allowed(struct btd_service *service) +{ + return service->is_allowed; +} + void btd_service_connecting_complete(struct btd_service *service, int err) { if (service->state != BTD_SERVICE_STATE_DISCONNECTED && diff --git a/src/service.h b/src/service.h index 88530cc17..5a2a02447 100644 --- a/src/service.h +++ b/src/service.h @@ -51,6 +51,8 @@ int btd_service_get_error(const struct btd_service *service); unsigned int btd_service_add_state_cb(btd_service_state_cb cb, void *user_data); bool btd_service_remove_state_cb(unsigned int id); +void btd_service_set_allowed(struct btd_service *service, bool allowed); +bool btd_service_is_allowed(struct btd_service *service); /* Functions used by profile implementation */ void btd_service_connecting_complete(struct btd_service *service, int err); From patchwork Wed Jul 28 13:15:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49D3CC4338F for ; Wed, 28 Jul 2021 13:15:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D6AD61019 for ; Wed, 28 Jul 2021 13:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236153AbhG1NPw (ORCPT ); Wed, 28 Jul 2021 09:15:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233315AbhG1NPv (ORCPT ); Wed, 28 Jul 2021 09:15:51 -0400 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 845AEC061757 for ; Wed, 28 Jul 2021 06:15:49 -0700 (PDT) Received: by mail-qk1-x74a.google.com with SMTP id c3-20020a05620a0ce3b02903b8eff05707so965520qkj.5 for ; Wed, 28 Jul 2021 06:15:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZjS6HME28Nlel7aho3iCIwOFgAjKxhsWfpa41gQF6dE=; b=GhVcfAbJSusvltRhpit4tR2HMQmrJU7nBLaf3//+dj9GwGber6OdOLIuIJSg6mNbvn AQNHBwnjOQpchCvpA/1r7mmTGKV+jGzTqoFPJMKNS7oOXiXGKFqVNa7kQD6mSTpoYJQ8 2mh/aUCCRpfERoP7XP81VkbE8KJjcnCFSwfd8mxJ2kbR8WbU1URAt01Ui2ufPt3Vm6dB Gxh4hZjliPo57nEBStfMNxWryjze8Po6POY71dGLwtD5cfSzFjJMUJ+xtuozpf/NpovT LxeEqQ2Bevt0HpsCD26Kro2Ha8UN84t1xVT3t/Tb1jEqO/kTOq5bDP/HYQ8x17qFqbq0 fEtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZjS6HME28Nlel7aho3iCIwOFgAjKxhsWfpa41gQF6dE=; b=kjKkYxuA3qC6YarLT40Yr71m6pAqd1vMKJHgQeWGUufRPTo1HMJi62D38zq26nsWra ysqOz5dEUP5jculDYhWhvyPPSwU+rDqeyAV3+cjKtRTBKFJoQ6Lvk5JHiC4sCG6hsjBD lMOVLR18lDM20Qu/kHW9Ul7irVzQBY/a+nHo6gzr43bpWnlfIUPTvpD1yyvjs1NSknXk 5CqbuE5gi3tZoGV/Ck2UnGa4PocKgNjfRmDeFoNHkHnMlbu+B2rkMgSmB6lFxdoqMy9W poFhDWm0z/mgnnt2toNOXDVcwop7LKYHH2vf3i91pCZIEeW8S+y8gNPGlECVFbV27DbY V+6w== X-Gm-Message-State: AOAM531zMxLkrvWNsN3Lai7MqL0z120Sz4NQhopYxgtKA48JgJu3cdk7 ooF055dfTPxEHjVyY0HWYgi7N9/doXl6AMwrtBS1nlEZH+eXBc/N83Qnr0t2p/N6heEYCWACxSP mI96ClEOa5JPlo0oSrp3+I8acBlx5EOgx+BsyQOl1CZLxJwKCP3trDBgk1pFmxFGGSR9yhEmKiD vE0HBhXHaEKds= X-Google-Smtp-Source: ABdhPJw4bmb5qb0FcHOU0ySFP1rkmUlG1vYN7LQS9/z1yUl9v1ZNeujLPVtPHJCs7SwBH1sJsMO72p0J/hdqDmXnFg== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a05:6214:f66:: with SMTP id iy6mr25013660qvb.58.1627478148403; Wed, 28 Jul 2021 06:15:48 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:18 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.2.Ibc0b5f02cb249f9aca9efe45e2dadc5e50b7d89e@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 02/13] core: add adapter and device allowed_uuid functions From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This implements functions in src/adapter.c and src/device.c for plugins setting a list of allowed services. Reviewed-by: Miao-chen Chou --- (no changes since v1) src/adapter.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/adapter.h | 8 +++++ src/device.c | 64 +++++++++++++++++++++++++++++++++++- src/device.h | 2 ++ 4 files changed, 163 insertions(+), 1 deletion(-) diff --git a/src/adapter.c b/src/adapter.c index 663b778e4..c7fe27d19 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -260,6 +260,8 @@ struct btd_adapter { struct btd_battery_provider_manager *battery_provider_manager; + GHashTable *allowed_uuid_set; /* Set of allowed service UUIDs */ + gboolean initialized; GSList *pin_callbacks; @@ -3489,6 +3491,93 @@ static DBusMessage *connect_device(DBusConnection *conn, return NULL; } +static void update_device_allowed_services(void *data, void *user_data) +{ + struct btd_device *device = data; + + btd_device_update_allowed_services(device); +} + +static void add_uuid_to_uuid_set(void *data, void *user_data) +{ + bt_uuid_t *uuid = data; + GHashTable *uuid_set = user_data; + + if (!uuid) { + error("Found NULL in UUID allowed list"); + return; + } + + g_hash_table_add(uuid_set, uuid); +} + +static guint bt_uuid_hash(gconstpointer key) +{ + const bt_uuid_t *uuid = key; + bt_uuid_t uuid_128; + uint64_t *val; + + if (!uuid) + return 0; + + bt_uuid_to_uuid128(uuid, &uuid_128); + val = (uint64_t *)&uuid_128.value.u128; + + return g_int64_hash(val) ^ g_int64_hash(val+1); +} + +static gboolean bt_uuid_equal(gconstpointer v1, gconstpointer v2) +{ + const bt_uuid_t *uuid1 = v1; + const bt_uuid_t *uuid2 = v2; + + if (!uuid1 || !uuid2) + return !uuid1 && !uuid2; + + return bt_uuid_cmp(uuid1, uuid2) == 0; +} + +bool btd_adapter_set_allowed_uuids(struct btd_adapter *adapter, + struct queue *uuids) +{ + if (!adapter) + return false; + + if (adapter->allowed_uuid_set) + g_hash_table_destroy(adapter->allowed_uuid_set); + + adapter->allowed_uuid_set = g_hash_table_new(bt_uuid_hash, + bt_uuid_equal); + if (!adapter->allowed_uuid_set) { + btd_error(adapter->dev_id, + "Failed to allocate allowed_uuid_set"); + return false; + } + + queue_foreach(uuids, add_uuid_to_uuid_set, adapter->allowed_uuid_set); + g_slist_foreach(adapter->devices, update_device_allowed_services, NULL); + + return true; +} + +bool btd_adapter_is_uuid_allowed(struct btd_adapter *adapter, + const char *uuid_str) +{ + bt_uuid_t uuid; + + if (!adapter || !adapter->allowed_uuid_set) + return true; + + if (bt_string_to_uuid(&uuid, uuid_str)) { + btd_error(adapter->dev_id, + "Failed to parse UUID string '%s'", uuid_str); + return false; + } + + return !g_hash_table_size(adapter->allowed_uuid_set) || + g_hash_table_contains(adapter->allowed_uuid_set, &uuid); +} + static const GDBusMethodTable adapter_methods[] = { { GDBUS_ASYNC_METHOD("StartDiscovery", NULL, NULL, start_discovery) }, { GDBUS_METHOD("SetDiscoveryFilter", @@ -5404,6 +5493,7 @@ static void adapter_free(gpointer user_data) g_free(adapter->stored_alias); g_free(adapter->current_alias); free(adapter->modalias); + g_hash_table_destroy(adapter->allowed_uuid_set); g_free(adapter); } diff --git a/src/adapter.h b/src/adapter.h index 60b5e3bcc..7cac51451 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -25,6 +25,7 @@ struct btd_adapter; struct btd_device; +struct queue; struct btd_adapter *btd_adapter_get_default(void); bool btd_adapter_is_default(struct btd_adapter *adapter); @@ -97,6 +98,8 @@ void adapter_service_remove(struct btd_adapter *adapter, uint32_t handle); struct agent *adapter_get_agent(struct btd_adapter *adapter); +bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid); + struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter); void btd_adapter_unref(struct btd_adapter *adapter); @@ -240,3 +243,8 @@ enum kernel_features { }; bool btd_has_kernel_features(uint32_t feature); + +bool btd_adapter_set_allowed_uuids(struct btd_adapter *adapter, + struct queue *uuids); +bool btd_adapter_is_uuid_allowed(struct btd_adapter *adapter, + const char *uuid_str); diff --git a/src/device.c b/src/device.c index b29aa195d..c4a4497da 100644 --- a/src/device.c +++ b/src/device.c @@ -1929,6 +1929,56 @@ static int service_prio_cmp(gconstpointer a, gconstpointer b) return p2->priority - p1->priority; } +bool btd_device_all_services_allowed(struct btd_device *dev) +{ + GSList *l; + struct btd_adapter *adapter = dev->adapter; + struct btd_service *service; + struct btd_profile *profile; + + for (l = dev->services; l != NULL; l = g_slist_next(l)) { + service = l->data; + profile = btd_service_get_profile(service); + + if (!profile || !profile->auto_connect) + continue; + + if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid)) + return false; + } + + return true; +} + +void btd_device_update_allowed_services(struct btd_device *dev) +{ + struct btd_adapter *adapter = dev->adapter; + struct btd_service *service; + struct btd_profile *profile; + GSList *l; + bool is_allowed; + char addr[18]; + + /* If service discovery is ongoing, let the service discovery complete + * callback call this function. + */ + if (dev->browse) { + ba2str(&dev->bdaddr, addr); + DBG("service discovery of %s is ongoing. Skip updating allowed " + "services", addr); + return; + } + + for (l = dev->services; l != NULL; l = g_slist_next(l)) { + service = l->data; + profile = btd_service_get_profile(service); + + is_allowed = btd_adapter_is_uuid_allowed(adapter, + profile->remote_uuid); + btd_service_set_allowed(service, is_allowed); + } +} + static GSList *create_pending_list(struct btd_device *dev, const char *uuid) { struct btd_service *service; @@ -1937,9 +1987,14 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid) if (uuid) { service = find_connectable_service(dev, uuid); - if (service) + + if (!service) + return dev->pending; + + if (btd_service_is_allowed(service)) return g_slist_prepend(dev->pending, service); + info("service %s is blocked", uuid); return dev->pending; } @@ -1950,6 +2005,11 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid) if (!p->auto_connect) continue; + if (!btd_service_is_allowed(service)) { + info("service %s is blocked", p->remote_uuid); + continue; + } + if (g_slist_find(dev->pending, service)) continue; @@ -2633,6 +2693,8 @@ static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type, dev->svc_callbacks); g_free(cb); } + + btd_device_update_allowed_services(dev); } static struct bonding_req *bonding_request_new(DBusMessage *msg, diff --git a/src/device.h b/src/device.h index 4ae9abe0d..5f615cb4b 100644 --- a/src/device.h +++ b/src/device.h @@ -175,5 +175,7 @@ uint32_t btd_device_get_current_flags(struct btd_device *dev); void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags, uint32_t current_flags); +bool btd_device_all_services_allowed(struct btd_device *dev); +void btd_device_update_allowed_services(struct btd_device *dev); void btd_device_init(void); void btd_device_cleanup(void); From patchwork Wed Jul 28 13:15:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-21.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EB68C432BE for ; Wed, 28 Jul 2021 13:15:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1FFA160F91 for ; Wed, 28 Jul 2021 13:15:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236209AbhG1NPz (ORCPT ); Wed, 28 Jul 2021 09:15:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233315AbhG1NPz (ORCPT ); Wed, 28 Jul 2021 09:15:55 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F23CBC061757 for ; Wed, 28 Jul 2021 06:15:53 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id y125-20020a2532830000b029058328f1b02eso2492717yby.7 for ; Wed, 28 Jul 2021 06:15:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=rpiPOzmTxUmQLBZkNI79pcAyBGS3USA6umBlfJ/AEMA=; b=cEJAsLr4ReUqNwCYP0PPFgLQKtK+vyLcBT34a2UrsIPcGZQlHqjE8x4bz3Bqq3tixe hrpNwvQN1xrNAIdaMxqoZx9Lnjz1IaUJbi4ZJEvP4mG1/qOKMub3SHYeikNvCb6stGb1 AgZ4pD98nxumTZDp1K8y8MUYkJFbFH15+nNZxvBpEpWlXcSQm57VJqdgq203aV1m4a3p 5kMF51WzquIRn3md4aOHRLJzpaUkL7E73bxhJesqvAJOl50mO1Vy4hheVCLB7EqKYlFI QZh3DBP7A57cefr3bu+MhvAxJkuF26DGS2ph6Se6mcbVAOvgdsEXYmvpkssDzqzUMSF/ ZpVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=rpiPOzmTxUmQLBZkNI79pcAyBGS3USA6umBlfJ/AEMA=; b=XdV3f9YBgaBCaTg4izMQb4KZqWLzg9JIpNYUB7IA8zXLZTH0X0EbniWdl2hQTO9v/c Pi+THbSY29EN9Lw8NpBmzke1GQVcHvwONijNSn1W/NWvnIt+1YQq5tK/WO9Ev4dppKRM A9A6xnS8aZTTNEemOpcjRjwn/1spYlzwTAo0rVyu5r5aps2s33n8vPqLF1EA/+NOxzim lEFaZIaYc+diYuLhFp7oMsVukvknajPDnFqytGVOuqfq7KN1kGdf1/lVTX+GzpzaOTa5 Kctnp1c2aTpHpIV1zLz27vLrTNaUyz1yGfqy6p2lvfAO1iTWzdHZWOR+fJ9KhaWhWOe8 ixZw== X-Gm-Message-State: AOAM530fsSzxyr/wXQ8nhQrhPzFGvW3/BckduGmfSsMe0jq9UdsRh9Xg +PNcYShwcUsbyQypPh48gBvqbRDkBo7SvYPsNanBeqatqp1jmGhmca1lMnH75PL7vbP0Dc95LVF 58n4QvA46Q2u0+OPCap1mpcrgglv8kIOFM9l8wBJHilH8j9QNsxsJvw4lSKLodNzM+ON9H5f+ko UdUq4TJUM1Nw8= X-Google-Smtp-Source: ABdhPJxCq27Q6nql0k/YabtmmdG0oowTKIKoLkGhABOoaONXoVfkuoR4fHc9mXMPwM2VN2L87Usue/w9XOFDDKOlPw== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:2688:: with SMTP id m130mr22712013ybm.146.1627478153162; Wed, 28 Jul 2021 06:15:53 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:19 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.3.If0cf6e1feb9e9cc8106793bcaea60202852d7095@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 03/13] mcap: add adapter authorization From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung Currently mcap is the only profile that doesn't request adatper authorization. This patch adds a argument when creating the mcap instance to set authorize method. The reason why we don't use btd_request_authorization directly like all other profiles is because tools/mcaptest includes the profile/health/mcap.h. If we add dependency to adapter.h in mcap.h, it will make mcaptest depend on adapter and be not able to build independently. --- (no changes since v1) profiles/health/hdp.c | 1 + profiles/health/mcap.c | 39 +++++++++++++++++++++++++++++++++++++-- profiles/health/mcap.h | 7 +++++++ tools/mcaptest.c | 2 +- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/profiles/health/hdp.c b/profiles/health/hdp.c index 6bc41946f..efa8955ef 100644 --- a/profiles/health/hdp.c +++ b/profiles/health/hdp.c @@ -1347,6 +1347,7 @@ static gboolean update_adapter(struct hdp_adapter *hdp_adapter) mcl_connected, mcl_reconnected, mcl_disconnected, mcl_uncached, NULL, /* CSP is not used by now */ + btd_request_authorization, hdp_adapter, &err); if (hdp_adapter->mi == NULL) { error("Error creating the MCAP instance: %s", err->message); diff --git a/profiles/health/mcap.c b/profiles/health/mcap.c index be13af37a..d4cb69f77 100644 --- a/profiles/health/mcap.c +++ b/profiles/health/mcap.c @@ -14,6 +14,7 @@ #endif #define _GNU_SOURCE +#include #include #include #include @@ -23,6 +24,7 @@ #include #include "lib/bluetooth.h" +#include "lib/uuid.h" #include "bluetooth/l2cap.h" #include "btio/btio.h" #include "src/log.h" @@ -1980,7 +1982,6 @@ static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl) mcl->state = MCL_CONNECTED; mcl->role = MCL_ACCEPTOR; mcl->req = MCL_AVAILABLE; - mcl->cc = g_io_channel_ref(chan); mcl->ctrl |= MCAP_CTRL_STD_OP; mcap_sync_init(mcl); @@ -2005,19 +2006,39 @@ static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl) mcl->mi->mcl_connected_cb(mcl, mcl->mi->user_data); } +static void auth_callback(void *err, void *user_data) +{ + struct mcap_mcl *mcl = user_data; + DBusError *derr = err; + + if (derr) { + error("Access denied: %s", derr->message); + goto reject; + } + + set_mcl_conf(mcl->cc, mcl); + return; + +reject: + g_io_channel_shutdown(mcl->cc, TRUE, NULL); + g_io_channel_unref(mcl->cc); +} + static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr, gpointer user_data) { struct mcap_instance *mi = user_data; struct mcap_mcl *mcl; - bdaddr_t dst; + bdaddr_t src, dst; char address[18], srcstr[18]; GError *err = NULL; + guint ret; if (gerr) return; bt_io_get(chan, &err, + BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID); @@ -2044,6 +2065,18 @@ static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr, mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1; } + mcl->cc = g_io_channel_ref(chan); + if (mi->authorize_cb) { + ret = mi->authorize_cb(&src, &dst, HDP_UUID, auth_callback, + mcl); + if (ret != 0) + return; + + error("HDP: authorization for device %s failed", address); + g_io_channel_unref(mcl->cc); + goto drop; + } + set_mcl_conf(chan, mcl); return; @@ -2060,6 +2093,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src, mcap_mcl_event_cb mcl_disconnected, mcap_mcl_event_cb mcl_uncached, mcap_info_ind_event_cb mcl_sync_info_ind, + mcap_authorize_cb authorize_cb, gpointer user_data, GError **gerr) { @@ -2089,6 +2123,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src, mi->mcl_disconnected_cb = mcl_disconnected; mi->mcl_uncached_cb = mcl_uncached; mi->mcl_sync_infoind_cb = mcl_sync_info_ind; + mi->authorize_cb = authorize_cb; mi->user_data = user_data; mi->csp_enabled = FALSE; diff --git a/profiles/health/mcap.h b/profiles/health/mcap.h index 5a94c8b63..aa69b0d32 100644 --- a/profiles/health/mcap.h +++ b/profiles/health/mcap.h @@ -249,6 +249,11 @@ typedef void (* mcap_sync_set_cb) (struct mcap_mcl *mcl, GError *err, gpointer data); +typedef void mcap_auth_cb(void *err, void *user_data); +typedef guint (* mcap_authorize_cb) (const bdaddr_t *src, const bdaddr_t *dst, + const char *uuid, mcap_auth_cb cb, + void *user_data); + struct mcap_mdl_cb { mcap_mdl_event_cb mdl_connected; /* Remote device has created a MDL */ mcap_mdl_event_cb mdl_closed; /* Remote device has closed a MDL */ @@ -271,6 +276,7 @@ struct mcap_instance { mcap_mcl_event_cb mcl_disconnected_cb; /* MCL disconnected */ mcap_mcl_event_cb mcl_uncached_cb; /* MCL has been removed from MCAP cache */ mcap_info_ind_event_cb mcl_sync_infoind_cb; /* (CSP Master) Received info indication */ + mcap_authorize_cb authorize_cb; /* Method to request authorization */ gpointer user_data; /* Data to be provided in callbacks */ int ref; /* Reference counter */ @@ -404,6 +410,7 @@ struct mcap_instance *mcap_create_instance(const bdaddr_t *src, mcap_mcl_event_cb mcl_disconnected, mcap_mcl_event_cb mcl_uncached, mcap_info_ind_event_cb mcl_sync_info_ind, + mcap_authorize_cb authorize_cb, gpointer user_data, GError **gerr); void mcap_release_instance(struct mcap_instance *mi); diff --git a/tools/mcaptest.c b/tools/mcaptest.c index dcef0b908..63ee22149 100644 --- a/tools/mcaptest.c +++ b/tools/mcaptest.c @@ -434,7 +434,7 @@ int main(int argc, char *argv[]) mcl_connected, mcl_reconnected, mcl_disconnected, mcl_uncached, NULL, /* CSP is not used right now */ - NULL, &err); + NULL, NULL, &err); if (!mcap) { printf("MCAP instance creation failed %s\n", err->message); From patchwork Wed Jul 28 13:15:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-21.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED366C4338F for ; Wed, 28 Jul 2021 13:16:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D7D3E60240 for ; Wed, 28 Jul 2021 13:16:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236233AbhG1NQB (ORCPT ); Wed, 28 Jul 2021 09:16:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233315AbhG1NQA (ORCPT ); Wed, 28 Jul 2021 09:16:00 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4250AC061757 for ; Wed, 28 Jul 2021 06:15:59 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id t101-20020a25aaee0000b0290578c0c455b2so2766697ybi.13 for ; Wed, 28 Jul 2021 06:15:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7edK40cZnbgtgLANdMuyepBsOSk6qB2TDi4Pn5PpTyw=; b=Od7MgcumYt0KOUlJyJNmq8fACOSs2CE+5j71UFOU/YCvZRTjh/WG0k90PAw8fan+L+ pmeL8jt7WPH4q5C6bovT/69PzzflxMKX9U7Pl0Fw1Yb1TAVG/vGjPPRxUP3ANuvfi/JU YN1MerMq/st7FY7307UtTQdgewq/MW027eIJVlQUQ5vfl1LHnHtBkulN7YQs9dPnjA13 QDN7/DqGEd0PEMlmw4keBAkadI+U66AWwvxCZrCsxW50l28hvLOc9wGUId9tJES50Phh hqvPyvNVXii15GZG1K0oVLsWqtmqHMi87SeuKay1cHaWV+pUhicD8IU60bbRofh2vvrD M7ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7edK40cZnbgtgLANdMuyepBsOSk6qB2TDi4Pn5PpTyw=; b=WJcOXeeyP5NaQQoVj8YFFdwdIE3fYp4ngdt5X/I8XAHeA/BxLOBgeEKYJv0PmR8gGB 11JvwavucwekkOXO12IMUNQJP2zv7RbtEKX0esqEbP5GfR+Tcq68ue2eADVcdAScfZr1 xSFEbJVMBfJsBDYnfqcHgxBlgRuovOzY08zByjToHsDgBTNUwp+jbYjmajxUD5WUWpz0 qSOnkuZNGM9zn++Py8cLWMzkvhv6HN1wYwGX6Su/m5aIWcBLSwypcWpHhy6bR1eQWGCR N8yuLutDkb3Q98xsverwc8OQaQfOwd+YcNnmOg9P1L7/mByG5+Ynh1lZ0MnZcMKJY2dx gxcg== X-Gm-Message-State: AOAM531cvsfz82/+ZM+38EF3wu/Gt6RFS8xFmujNhIeNEmtZ9G8yTUtp z6PexEU0X/U7I7k7rcx6hdcQ8zONkuFd/tZgYXhWyYIgAzTxIe+5OOujZZYS7CZaJoSjmqXTUTa Jpa71o1oq11GWtfL1dfsc+fIX7MxbZpFFzh4z4kvdHK7zqo7TUs3eVkYQGf7IxZWVqg3HRzpvuJ TNvUrbtSsg1W4= X-Google-Smtp-Source: ABdhPJy4UiPsH489nUk4utxwlfE5YzwcGjm0+wPKt2SeAbGpsQftg+S8Q+NKdYTWMBMtT42LonJEs3Q/QmSeReJDLA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:d1c4:: with SMTP id i187mr4813620ybg.200.1627478158415; Wed, 28 Jul 2021 06:15:58 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:20 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.4.Ia4dc489979e4bf7ffa3421199b1b9fd8d7f00bbc@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 04/13] core: block not allowed UUID connect in auth From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This ensures any incoming profile connection will be blocked if its UUID is not allowed by the following assumption: 1. Each system profile asks adapter authorization when seeing a incoming connection. 2. Each external profile checks if its UUID is allowed by adapter when seeing a incoming connection. --- The following test steps were performed after enabling admin_policy plugin: 1. Set ServiceAllowList to ["1234"]. 2. Turn on a paired classic keyboard. Verify it can not be connected. 3. Set ServiceAllowList to ["1800","1801","180A","180F","1812"] 4. Turn off and turn on the keyboard. Verift it can be connected. (no changes since v1) src/adapter.c | 5 +++++ src/profile.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/adapter.c b/src/adapter.c index c7fe27d19..6c8096147 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -7118,6 +7118,11 @@ static gboolean process_auth_queue(gpointer user_data) if (auth->svc_id > 0) return FALSE; + if (!btd_adapter_is_uuid_allowed(adapter, auth->uuid)) { + auth->cb(&err, auth->user_data); + goto next; + } + if (device_is_trusted(device) == TRUE) { auth->cb(NULL, auth->user_data); goto next; diff --git a/src/profile.c b/src/profile.c index 60d17b6ae..58500c747 100644 --- a/src/profile.c +++ b/src/profile.c @@ -1249,6 +1249,11 @@ static void ext_confirm(GIOChannel *io, gpointer user_data) DBG("incoming connect from %s", addr); + if (btd_adapter_is_uuid_allowed(adapter_find(&src), uuid)) { + info("UUID %s is not allowed. Igoring the connection", uuid); + return; + } + conn = create_conn(server, io, &src, &dst); if (conn == NULL) return; @@ -1272,6 +1277,7 @@ static void ext_direct_connect(GIOChannel *io, GError *err, gpointer user_data) struct ext_profile *ext = server->ext; GError *gerr = NULL; struct ext_io *conn; + const char *uuid = ext->service ? ext->service : ext->uuid; bdaddr_t src, dst; bt_io_get(io, &gerr, @@ -1285,6 +1291,12 @@ static void ext_direct_connect(GIOChannel *io, GError *err, gpointer user_data) return; } + if (btd_adapter_is_uuid_allowed(adapter_find(&src), ext->uuid)) { + info("UUID %s is not allowed. Igoring the connection", + ext->uuid); + return; + } + conn = create_conn(server, io, &src, &dst); if (conn == NULL) return; From patchwork Wed Jul 28 13:15:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-21.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D47FC4338F for ; Wed, 28 Jul 2021 13:16:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5EE3B60240 for ; Wed, 28 Jul 2021 13:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236254AbhG1NQI (ORCPT ); Wed, 28 Jul 2021 09:16:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233315AbhG1NQH (ORCPT ); Wed, 28 Jul 2021 09:16:07 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 048F0C061757 for ; Wed, 28 Jul 2021 06:16:05 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id p71-20020a25424a0000b029056092741626so2741442yba.19 for ; Wed, 28 Jul 2021 06:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=YNwxtFl+Q5xNneMOHue6J/67p8nZOPpKbvtqaiUgyEs=; b=kvICbf05hP2Nhr9lA9T5YPAcSMxDW27m5xiVdSeZOuvHheu4iHz5BqxBjOETVeYONW V81aXzaHFVDwdDiSHI2jfg7CgxTxzuv2zt7D6t0+ZeJD+ym/H2lKT4O1YU1o0+Y7GIpM CZiptpTTkhngk/o1tQ5WMILmdS5RNRIUhYHpQbB0kK6U0b4aN6+5R7yq76uNDjdQAUim V6oOZU+sS9armeuVxwQo/GtBdngSXQZOhPt7d6Q/85MWPlrQvrNL7Zr8NiFb6RVrAAUy 4bsHLz8yPEhhSZ6bMJZGbU/XlPxNmzPYdIArVyxru3Y7qHHehbi3DWk659l5ky9vkW3q kvNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=YNwxtFl+Q5xNneMOHue6J/67p8nZOPpKbvtqaiUgyEs=; b=NA17u7DomgF/BmSgaLbVoQNYLRsu5Y1cduRI51ui3x0ECbRaca28OGc41+VWGj2QJA 61UhSMkoFtjeEWIE/P+3WBFNdCUHiL8/KrYRVAHtCC6hnL4dcMsUnoAYSQIjvOVgdS+/ YZ/eFcCdRlWcSuz5xkcbWxPKEIRJBNqK02ZSlAFzGrkCYdPyqlYTWzvmEZOss6L+aIkB OmboJzHgFAp7jcaVdNWU2nsGj05IpIb1CnzOiryAXg8co6v1Fq2sI79v/HGNcvLhdKCF peJBjNibb3JOTuP/j4SYR885qdwlqXke6eRp55Yxi6ovw1uTzfv5uAuU4J5RlH2hMxbt yBcg== X-Gm-Message-State: AOAM532jPG7hx3U9swLHVfI98YbxMTo1ejNgxVFTfVGG3ahJGDYmRrGd wVT6Z0y/GUiGZ07OwlyRTQY2YMuv4mpbZNUbCKrQAmKhSK7EOjvY6MX0dtGdV+4vV4FQfKp5UCO kymZJ7HlgzGp79+XkJt9/HGMPUHRYhMhDuB3JTjY7ZLFdqLamR64o0S1FDCG4y1w95JHidnLPsF OIj2IxU8pDr7A= X-Google-Smtp-Source: ABdhPJx4BysB1mTistNHKJ8OuWJ5MgneKIm1XDIih8G4Blt43XsxDLvviIne9Rv83SNzmqUXwK1v7crafOm76iDhPA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a5b:648:: with SMTP id o8mr4237312ybq.260.1627478164145; Wed, 28 Jul 2021 06:16:04 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:21 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.5.Iee308dd18bfdfd3dae9e343e78b3942ee462314f@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 05/13] core: add device_added and device_removed to adapter driver From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds device_added and device_removed to btd_adapter_driver so that a driver can get notification when device is added or removed. --- (no changes since v1) src/adapter.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++----- src/adapter.h | 4 ++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index 6c8096147..5c556b569 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -1218,6 +1218,9 @@ void adapter_service_remove(struct btd_adapter *adapter, uint32_t handle) remove_record_from_server(rec->handle); } +static void adapter_add_device(struct btd_adapter *adapter, + struct btd_device *device); + static struct btd_device *adapter_create_device(struct btd_adapter *adapter, const bdaddr_t *bdaddr, uint8_t bdaddr_type) @@ -1228,8 +1231,7 @@ static struct btd_device *adapter_create_device(struct btd_adapter *adapter, if (!device) return NULL; - adapter->devices = g_slist_append(adapter->devices, device); - + adapter_add_device(adapter, device); return device; } @@ -1256,6 +1258,9 @@ static void service_auth_cancel(struct service_auth *auth) g_free(auth); } +static void adapter_remove_device(struct btd_adapter *adapter, + struct btd_device *device); + void btd_adapter_remove_device(struct btd_adapter *adapter, struct btd_device *dev) { @@ -1263,7 +1268,7 @@ void btd_adapter_remove_device(struct btd_adapter *adapter, adapter->connect_list = g_slist_remove(adapter->connect_list, dev); - adapter->devices = g_slist_remove(adapter->devices, dev); + adapter_remove_device(adapter, dev); btd_adv_monitor_device_remove(adapter->adv_monitor_manager, dev); adapter->discovery_found = g_slist_remove(adapter->discovery_found, @@ -4665,7 +4670,7 @@ static void load_devices(struct btd_adapter *adapter) goto free; btd_device_set_temporary(device, false); - adapter->devices = g_slist_append(adapter->devices, device); + adapter_add_device(adapter, device); /* TODO: register services from pre-loaded list of primaries */ @@ -4827,6 +4832,48 @@ void adapter_remove_profile(struct btd_adapter *adapter, gpointer p) profile->adapter_remove(profile, adapter); } +static void device_added_drivers(struct btd_adapter *adapter, + struct btd_device *device) +{ + struct btd_adapter_driver *driver; + GSList *l; + + for (l = adapter_drivers; l; l = l->next) { + driver = l->data; + + if (driver->device_added) + driver->device_added(adapter, device); + } +} + +static void device_removed_drivers(struct btd_adapter *adapter, + struct btd_device *device) +{ + struct btd_adapter_driver *driver; + GSList *l; + + for (l = adapter_drivers; l; l = l->next) { + driver = l->data; + + if (driver->device_removed) + driver->device_removed(adapter, device); + } +} + +static void adapter_add_device(struct btd_adapter *adapter, + struct btd_device *device) +{ + adapter->devices = g_slist_append(adapter->devices, device); + device_added_drivers(adapter, device); +} + +static void adapter_remove_device(struct btd_adapter *adapter, + struct btd_device *device) +{ + adapter->devices = g_slist_remove(adapter->devices, device); + device_removed_drivers(adapter, device); +} + static void adapter_add_connection(struct btd_adapter *adapter, struct btd_device *device, uint8_t bdaddr_type) @@ -6445,8 +6492,10 @@ static void adapter_remove(struct btd_adapter *adapter) g_slist_free(adapter->connect_list); adapter->connect_list = NULL; - for (l = adapter->devices; l; l = l->next) + for (l = adapter->devices; l; l = l->next) { + device_removed_drivers(adapter, l->data); device_remove(l->data, FALSE); + } g_slist_free(adapter->devices); adapter->devices = NULL; diff --git a/src/adapter.h b/src/adapter.h index 7cac51451..a2567330d 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -111,6 +111,10 @@ struct btd_adapter_driver { int (*probe) (struct btd_adapter *adapter); void (*remove) (struct btd_adapter *adapter); void (*resume) (struct btd_adapter *adapter); + void (*device_added) (struct btd_adapter *adapter, + struct btd_device *device); + void (*device_removed) (struct btd_adapter *adapter, + struct btd_device *device); }; typedef void (*service_auth_cb) (DBusError *derr, void *user_data); From patchwork Wed Jul 28 13:15:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405597 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 058A8C432BE for ; Wed, 28 Jul 2021 13:16:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4F4D60295 for ; Wed, 28 Jul 2021 13:16:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236292AbhG1NQO (ORCPT ); Wed, 28 Jul 2021 09:16:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236289AbhG1NQM (ORCPT ); Wed, 28 Jul 2021 09:16:12 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 041BCC061765 for ; Wed, 28 Jul 2021 06:16:11 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id d69-20020a25e6480000b02904f4a117bd74so2764351ybh.17 for ; Wed, 28 Jul 2021 06:16:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=sSwyhyBbbT8FDD76nL3HeaEtb8Ol8lNd71HJ8NDZ5UI=; b=iYNlkWgUbVDMvemLAN8D/WiY7VusExFjMjlsCqF5UJtAyB3HpKWGTl+G5Hu8xdcBEy 7S2I8Fyy5FEumkLrMC8ouFMa4NADLtqwoSfCpnSRJ2zTb5x0GOA0efCCuKlfimanWnHc ADzLc2VsOIDnqvQ9OxS6w8j6wteXxl9W6ohyzUFyj4aF64zq0rWhhkYapDVJujwOek2m pcDZv1YZp6l77SHg7RQxY9b/x2ZGwr726pTgVelB4ULVRLOHwkr45aK4a8AYWwF7H3hl kwvwGDtemS9039/2/2vqRaHhnftxp34kxqybqIfvfs1IreGNi5WCWRhA7y5Hu8DwZKmH mQhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=sSwyhyBbbT8FDD76nL3HeaEtb8Ol8lNd71HJ8NDZ5UI=; b=Ay2OTxsbDk0gqETP/LEUFcoCTEOoPlpsq5FG9yiNmxYLtfUQgABgKAxzv8wr5VlR/9 l+/30bZcdoqpwvfH1EB4fpDKmIdAlsDtq5xqYxNcoLNlAC4sCRQIEaR6D7AdUkeqJfKD kwXf/rcsTC7Xt6xuQ4CXjVhQhOfMor7wUEYN6kOWDa/ULkwsHwuNox9cfvDdIFA2TYcM 1h5wh+naKBP1/d8xsFw8Ob/A6HeyGhLFqWYrayWpFYwxVr00095AENTUjlZu8XsjMoJg B9LAng7kjeKjvMmQlCdKMxGDItkFuA2cnsIUlwnBpt0ug01/l2uxDG72cSdwyAynRmGh Zo5g== X-Gm-Message-State: AOAM532JthJDszQkYryC8Fm9pwYOy0qO9qOSm5U8+N2GgKOM57UyHPSQ WlwXJlSlHS22Ftmm2YHN0CIaiJNBnYjM29IIJVhtepriGnFdT3mk93Oxbki3yMXnRQzfNSISlHh UYvdk623DOPyYGwKQpgb630OcU1QACrzuzqWnnohC9W2w01bNlwCemW6dRXdVDx91edV3jzJRsk 3xRGJdU0QkySU= X-Google-Smtp-Source: ABdhPJxjDEQfyxX1eXDM2OUB5O1Z6kIq+OSHjh0JcXwfp8mb6AZGS6ut0aJiwPfOXwm6//uoblRjeU7/Mi/f4wiX6g== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:28a:: with SMTP id 132mr38752095ybc.458.1627478170184; Wed, 28 Jul 2021 06:16:10 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:22 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.6.Id0842634d98a21fbdfa5cc72c76a462a98bf6f40@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 06/13] plugins: new plugin From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds an initial code for a new plugin admin_policy. Reviewed-by: Miao-chen Chou --- (no changes since v1) Makefile.plugins | 5 +++++ bootstrap-configure | 1 + configure.ac | 4 ++++ plugins/admin.c | 30 ++++++++++++++++++++++++++++++ plugins/admin_policy.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 plugins/admin.c create mode 100644 plugins/admin_policy.c diff --git a/Makefile.plugins b/Makefile.plugins index 4e6a72b0b..69fb01001 100644 --- a/Makefile.plugins +++ b/Makefile.plugins @@ -11,6 +11,11 @@ builtin_sources += plugins/autopair.c builtin_modules += policy builtin_sources += plugins/policy.c +if ADMIN +builtin_modules += admin +builtin_sources += plugins/admin.c +endif + if NFC builtin_modules += neard builtin_sources += plugins/neard.c diff --git a/bootstrap-configure b/bootstrap-configure index 0efd83abc..a34be8320 100755 --- a/bootstrap-configure +++ b/bootstrap-configure @@ -30,4 +30,5 @@ fi --enable-pie \ --enable-cups \ --enable-library \ + --enable-admin \ --disable-datafiles $* diff --git a/configure.ac b/configure.ac index a5afaea6c..0744860b8 100644 --- a/configure.ac +++ b/configure.ac @@ -364,6 +364,10 @@ AC_ARG_ENABLE(logger, AC_HELP_STRING([--enable-logger], [enable HCI logger service]), [enable_logger=${enableval}]) AM_CONDITIONAL(LOGGER, test "${enable_logger}" = "yes") +AC_ARG_ENABLE(admin, AC_HELP_STRING([--enable-admin], + [enable admin policy plugin]), [enable_admin=${enableval}]) +AM_CONDITIONAL(ADMIN, test "${enable_admin}" = "yes") + if (test "${prefix}" = "NONE"); then dnl no prefix and no localstatedir, so default to /var if (test "$localstatedir" = '${prefix}/var'); then diff --git a/plugins/admin.c b/plugins/admin.c new file mode 100644 index 000000000..42866bcf7 --- /dev/null +++ b/plugins/admin.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2021 Google LLC + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "src/log.h" +#include "src/plugin.h" + +static int admin_init(void) +{ + DBG(""); +} + +static void admin_exit(void) +{ + DBG(""); +} + +BLUETOOTH_PLUGIN_DEFINE(admin, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + admin_init, admin_exit) diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c new file mode 100644 index 000000000..dd8d89736 --- /dev/null +++ b/plugins/admin_policy.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2021 Google LLC + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "src/log.h" +#include "src/plugin.h" + +static int admin_policy_init(void) +{ + DBG(""); +} + +static void admin_policy_exit(void) +{ + DBG(""); +} + +BLUETOOTH_PLUGIN_DEFINE(admin_policy, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + admin_policy_init, admin_policy_exit) From patchwork Wed Jul 28 13:15:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405595 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 132FBC4338F for ; Wed, 28 Jul 2021 13:16:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EF73760295 for ; Wed, 28 Jul 2021 13:16:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236264AbhG1NQR (ORCPT ); Wed, 28 Jul 2021 09:16:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234771AbhG1NQR (ORCPT ); Wed, 28 Jul 2021 09:16:17 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D66C0C061757 for ; Wed, 28 Jul 2021 06:16:15 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id c63-20020a25e5420000b0290580b26e708aso2784580ybh.12 for ; Wed, 28 Jul 2021 06:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=A4c6MpYUECSKm/aYN6hFWhT7ehzXLCabu/7cA+6MNQk=; b=Ycc4bJag4XlHtgfPQSkhfYjseANQepcL3OR+OOIERLg+dnkDhpfat0FGrl7GU4Ag9y QJlNcxrf/xBLT+tgBCgatK1X7FoKei2m90NQOUPJcn6KXWDxkHaz3mqzHQUpY7GD9MSh 2ptkhXSy6UuRidV3FyWc231y9h7XzD3DlxPb6Rz7lVxlFR8QY2wrekhoTFiJJN13RNkZ SNEeCgAr0mUX07mFuiQ2TbbKme87+U9r6AnGK0hj42ByMZHcXBJlNvvVJDmThs/Wvjnz zsbs6aNpkTezCe+brltP+otMFhfs8idtSmWllopvU3rnwLgX0vHGSJsrdmMR3u91625o ttTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=A4c6MpYUECSKm/aYN6hFWhT7ehzXLCabu/7cA+6MNQk=; b=HHw/ZZa2AMkfabmWB555sZSA/y7xg0L4BknZmjV3QLe5B/K6Bo8xDK4CelN+7o3KrX ooZe/AX+jWyowHj5Mp061MpgHcWZmbJtCIHA/d0GTEmyeazyzlToyyiA2iTgw7QelsMm FaGQ4vS4E4q2TiP4jm5BLu4E2LXB83sA0BfvrWdYbTQOP66Bmz4yqmiloA2qCkP4yEiE WYWAhS40U8nXR0Blu0z9BoAKSMes/BQ1zDx14t/kYoeOOevHBdwKOywtTH2MbCxRXXlx OQIc8RMrG/m7Wg5D7WbLngzMz9heMgfyKIVYJrqRkHY7umafIA9yN/MAEDK71ulERAck XDcw== X-Gm-Message-State: AOAM532pLyfOFTzLX0aSnq7rlrHAMB46aGbh5vdUrJTpKmpT7TTjKP8a hI15XbMXVm9ekXEEId8cIWWbv+ZhnAFg3X6+daVmOOCpJ3vdRIkQc1L3/MXRZ77OLUcR88y5ELK WWrZNqW+UM44QVxdgbvsESM025x435iXS1/pnamX/EmR3JTm91y4VFQV+cbgAS9XYkPPKiQGC3E 5iOj/IQnTukAs= X-Google-Smtp-Source: ABdhPJxNwxaEiTxfMlpvWnXyKmudJ54YmM2st7OpEWxdlwf+wBeTuVu7xADDi9DM4zc9a7+R0N830749MZdJ1O0RBw== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:e747:: with SMTP id e68mr5293133ybh.364.1627478175050; Wed, 28 Jul 2021 06:16:15 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:23 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.7.I29607be7ac91b0a494ab51713ba14f583eb858ed@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 07/13] plugins/admin_policy: add admin_policy adapter driver From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds code to register admin_policy driver to adapter when admin_policy plugin is enabled. The following test steps were performed: 1. restart bluetoothd 2. check if "Admin Policy is enabled" in system log Reviewed-by: Miao-chen Chou --- (no changes since v1) plugins/admin.c | 67 ++++++++++++++++++++++++++++++++++++++++++ plugins/admin_policy.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/plugins/admin.c b/plugins/admin.c index 42866bcf7..923e08cb8 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -12,17 +12,84 @@ #include #endif +#include "lib/bluetooth.h" + +#include "src/adapter.h" +#include "src/error.h" #include "src/log.h" #include "src/plugin.h" +#include "src/shared/queue.h" + +/* |policy_data| has the same life cycle as btd_adapter */ +static struct btd_admin_policy { + struct btd_adapter *adapter; + uint16_t adapter_id; +} *policy_data = NULL; + +static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) +{ + struct btd_admin_policy *admin_policy = NULL; + + admin_policy = g_try_malloc(sizeof(*admin_policy)); + if (!admin_policy) { + btd_error(btd_adapter_get_index(adapter), + "Failed to allocate memory for admin_policy"); + return NULL; + } + + admin_policy->adapter = adapter; + admin_policy->adapter_id = btd_adapter_get_index(adapter); + + return admin_policy; +} + +static void admin_policy_free(void *data) +{ + struct btd_admin_policy *admin_policy = data; + + g_free(admin_policy); +} + +static int admin_policy_adapter_probe(struct btd_adapter *adapter) +{ + if (policy_data) { + btd_warn(policy_data->adapter_id, + "Policy data already exists"); + admin_policy_free(policy_data); + policy_data = NULL; + } + + policy_data = admin_policy_new(adapter); + if (!policy_data) + return -ENOMEM; + + btd_info(policy_data->adapter_id, "Admin Policy has been enabled"); + + return 0; +} + +static struct btd_adapter_driver admin_policy_driver = { + .name = "admin_policy", + .probe = admin_policy_adapter_probe, + .resume = NULL, +}; + static int admin_init(void) { DBG(""); + + return btd_register_adapter_driver(&admin_policy_driver); } static void admin_exit(void) { DBG(""); + + btd_unregister_adapter_driver(&admin_policy_driver); + + if (policy_data) + admin_policy_free(policy_data); } BLUETOOTH_PLUGIN_DEFINE(admin, VERSION, diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index dd8d89736..2ece87156 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -12,17 +12,84 @@ #include #endif +#include "lib/bluetooth.h" + +#include "src/adapter.h" +#include "src/error.h" #include "src/log.h" #include "src/plugin.h" +#include "src/shared/queue.h" + +/* |policy_data| has the same life cycle as btd_adapter */ +static struct btd_admin_policy { + struct btd_adapter *adapter; + uint16_t adapter_id; +} *policy_data = NULL; + +static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) +{ + struct btd_admin_policy *admin_policy = NULL; + + admin_policy = g_try_malloc(sizeof(*admin_policy)); + if (!admin_policy) { + btd_error(btd_adapter_get_index(adapter), + "Failed to allocate memory for admin_policy"); + return NULL; + } + + admin_policy->adapter = adapter; + admin_policy->adapter_id = btd_adapter_get_index(adapter); + + return admin_policy; +} + +static void admin_policy_free(void *data) +{ + struct btd_admin_policy *admin_policy = data; + + g_free(admin_policy); +} + +static int admin_policy_adapter_probe(struct btd_adapter *adapter) +{ + if (policy_data) { + btd_warn(policy_data->adapter_id, + "Policy data already exists"); + admin_policy_free(policy_data); + policy_data = NULL; + } + + policy_data = admin_policy_new(adapter); + if (!policy_data) + return -ENOMEM; + + btd_info(policy_data->adapter_id, "Admin Policy has been enabled"); + + return 0; +} + +static struct btd_adapter_driver admin_policy_driver = { + .name = "admin_policy", + .probe = admin_policy_adapter_probe, + .resume = NULL, +}; + static int admin_policy_init(void) { DBG(""); + + return btd_register_adapter_driver(&admin_policy_driver); } static void admin_policy_exit(void) { DBG(""); + + btd_unregister_adapter_driver(&admin_policy_driver); + + if (policy_data) + admin_policy_free(policy_data); } BLUETOOTH_PLUGIN_DEFINE(admin_policy, VERSION, From patchwork Wed Jul 28 13:15:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405599 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0B71C4338F for ; Wed, 28 Jul 2021 13:16:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 87F7E60295 for ; Wed, 28 Jul 2021 13:16:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236289AbhG1NQY (ORCPT ); Wed, 28 Jul 2021 09:16:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236269AbhG1NQX (ORCPT ); Wed, 28 Jul 2021 09:16:23 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4131DC061757 for ; Wed, 28 Jul 2021 06:16:21 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id c63-20020a25e5420000b0290580b26e708aso2784824ybh.12 for ; Wed, 28 Jul 2021 06:16:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=EZHXHeW6QUwWIBUrI08wm0jQYSXNMjXwILb0+Abndl8=; b=M98rCl1OPcSkbJ1gJwDM2jIrlV0KgJU5jdQOawnB7XBXjiRrVUQ0SfIgdap6V+nr2n 6MtaCeKLBe1jXxJvCXZirBfLTN87BVJKL8um79l5fxP0RCwe5zJO+BIykRHwbJkVAn7H GQCd35t1pATuQWp9+rA3Ypr/d+jnBTcruPTtY94mdgiUIGTRo4Gq2DwrPUOoGV2eqsim o5V7qU4WjD/d4pkHxpMm3R6ozFvlHu6jupYoUVQNv18GrMpVzZGuXMLaTEFvTxt0NHxk SGnAe++l7YBotDNrvr8dM5ilhc7/7aFK9JVHRM7ISfxcxihdhd6t4dgocdi/2Ba/1Ikk f++w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=EZHXHeW6QUwWIBUrI08wm0jQYSXNMjXwILb0+Abndl8=; b=N67Gk8dVr/UtupfgfJpkAlkv8JJkw/M6Ej9fDMfsL8ufpFNy+47CP4d9e8VC8614yi A4BFrXi7VdZyne5LvFd8aNUxSmNV+Lm1u2QbecL4fRGIErtk4Bc1P1qhRLZtM8YrJDMf SYHXCeUSwx0ztvBpuQ7pti/x2d0dgo65aGElIsC7O+SRcSsGI8EIVNKzrkKPrY/bwW3Y JrSHuHNPXEqPNlPb6+s70tTpIaiTDZ5Px8HPI8N9L5ViVzB3XYFNB0tquwNFXjQMPHkL xSoJ8pBYCJXu+dP2p00w3GXMD8Fn3hwgGy4M9BzlnSaK2lVTtR+whUrV8a8thJlTmlb9 sVYw== X-Gm-Message-State: AOAM530bpbCvXz01/239vFaiidP9BpWeoFhlQm7noPtMu9sv3lhahcFX 9a8U05wmDX9MknYPfWtWc7mVwnZdC7ba5gmCzC6R4gHeZMb5Jo7XvD3L8q8ClahcRm6OwHFEkHY proosdpHXBli5+Z8CCkcSbtgv4ScDQSRm/WvgPB3Ho2sfHRYKabqaZIZfe77+fIRtv6d8xp5rPR hmOYWLsgiUL7E= X-Google-Smtp-Source: ABdhPJxL5O/jVlLNyzwo6c30ziYA3j7F1YNqijnuS9JYVn1/dX+imBxlFLWX+tpJRrvJIzgMaq4KkdjW5asmMcp/kw== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a5b:286:: with SMTP id x6mr3100471ybl.59.1627478180440; Wed, 28 Jul 2021 06:16:20 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:24 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.8.Ifbb69dd6e371da3a914049a94615064479b9024b@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 08/13] plugins/admin_policy: add ServiceAllowList method From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds code to register interface org.bluez.AdminPolicySet1. The interface will provide methods to limit users to operate certain functions of bluez, such as allow/disallow user to taggle adapter power, or only allow users to connect services in the specified list, etc. This patch also implements ServiceAllowlist in org.bluez.AdminPolicySet1. Reviewed-by: Miao-chen Chou --- The following test steps were performed: 1. Set ServiceAllowList to ["1108","110A","110B","110C","110D","110E", "110F","1112","111E","111F","1203"] ( users are only allowed to connect headset ) 2. Turn on paired WF1000XM3, and listen music on Youtube. 3. Turn on paired K830 (LE device), press any key on keyboard. 4. Turn on paired Samsung Bluetooth Keyboard EE-BT550 (BREDR device), press any key on keyboard. 5. Set ServiceAllowList to ["1124","180A","180F","1812"] ( users are only allowed to connect HID devices ) 6. Turn on paired WF1000XM3, and listen music on Youtube. 7. Turn on paired K830 (LE device), press any key on keyboard. 8. Turn on paired Samsung Bluetooth Keyboard EE-BT550 (BREDR device), press any key on keyboard. 9. Set ServiceAllowList to [] ( users are only allowed to connect any device. ) 10. Turn on paired WF1000XM3, and listen music on Youtube. 11. Turn on paired K830 (LE device), press any key on keyboard. 12. Turn on paired Samsung Bluetooth Keyboard EE-BT550 (BREDR device), press any key on keyboard. Expected results: Step 2,7,8,9,10,11 should success, and step 3,4,6 should fail. (no changes since v1) plugins/admin.c | 127 ++++++++++++++++++++++++++++++++++++++++- plugins/admin_policy.c | 123 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 248 insertions(+), 2 deletions(-) diff --git a/plugins/admin.c b/plugins/admin.c index 923e08cb8..1fe2904d9 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -12,19 +12,29 @@ #include #endif +#include +#include + #include "lib/bluetooth.h" +#include "lib/uuid.h" #include "src/adapter.h" +#include "src/dbus-common.h" #include "src/error.h" #include "src/log.h" #include "src/plugin.h" #include "src/shared/queue.h" +#define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" + +static DBusConnection *dbus_conn; + /* |policy_data| has the same life cycle as btd_adapter */ static struct btd_admin_policy { struct btd_adapter *adapter; uint16_t adapter_id; + struct queue *service_allowlist; } *policy_data = NULL; static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) @@ -40,19 +50,120 @@ static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) admin_policy->adapter = adapter; admin_policy->adapter_id = btd_adapter_get_index(adapter); + admin_policy->service_allowlist = NULL; return admin_policy; } +static void free_service_allowlist(struct queue *q) +{ + queue_destroy(q, g_free); +} + static void admin_policy_free(void *data) { struct btd_admin_policy *admin_policy = data; + free_service_allowlist(admin_policy->service_allowlist); g_free(admin_policy); } +static struct queue *parse_allow_service_list(struct btd_adapter *adapter, + DBusMessage *msg) +{ + DBusMessageIter iter, arr_iter; + struct queue *uuid_list = NULL; + + dbus_message_iter_init(msg, &iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) + return NULL; + + uuid_list = queue_new(); + dbus_message_iter_recurse(&iter, &arr_iter); + do { + const int type = dbus_message_iter_get_arg_type(&arr_iter); + char *uuid_param; + bt_uuid_t *uuid; + + if (type == DBUS_TYPE_INVALID) + break; + + if (type != DBUS_TYPE_STRING) + goto failed; + + dbus_message_iter_get_basic(&arr_iter, &uuid_param); + + uuid = g_try_malloc(sizeof(*uuid)); + if (!uuid) + goto failed; + + if (bt_string_to_uuid(uuid, uuid_param)) { + g_free(uuid); + goto failed; + } + + queue_push_head(uuid_list, uuid); + + dbus_message_iter_next(&arr_iter); + } while (true); + + return uuid_list; + +failed: + queue_destroy(uuid_list, g_free); + return NULL; +} + +static bool service_allowlist_set(struct btd_admin_policy *admin_policy, + struct queue *uuid_list) +{ + struct btd_adapter *adapter = admin_policy->adapter; + + if (!btd_adapter_set_allowed_uuids(adapter, uuid_list)) + return false; + + free_service_allowlist(admin_policy->service_allowlist); + admin_policy->service_allowlist = uuid_list; + + return true; +} + +static DBusMessage *set_service_allowlist(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct btd_admin_policy *admin_policy = user_data; + struct btd_adapter *adapter = admin_policy->adapter; + struct queue *uuid_list = NULL; + const char *sender = dbus_message_get_sender(msg); + + DBG("sender %s", sender); + + /* Parse parameters */ + uuid_list = parse_allow_service_list(adapter, msg); + if (!uuid_list) { + btd_error(admin_policy->adapter_id, + "Failed on parsing allowed service list"); + return btd_error_invalid_args(msg); + } + + if (!service_allowlist_set(admin_policy, uuid_list)) { + free_service_allowlist(uuid_list); + return btd_error_failed(msg, "service_allowlist_set failed"); + } + + return dbus_message_new_method_return(msg); +} + +static const GDBusMethodTable admin_policy_adapter_methods[] = { + { GDBUS_METHOD("SetServiceAllowList", GDBUS_ARGS({ "UUIDs", "as" }), + NULL, set_service_allowlist) }, + { } +}; + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { + const char *adapter_path; + if (policy_data) { btd_warn(policy_data->adapter_id, "Policy data already exists"); @@ -64,8 +175,20 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) if (!policy_data) return -ENOMEM; - btd_info(policy_data->adapter_id, "Admin Policy has been enabled"); + adapter_path = adapter_get_path(adapter); + if (!g_dbus_register_interface(dbus_conn, adapter_path, + ADMIN_POLICY_SET_INTERFACE, + admin_policy_adapter_methods, NULL, + NULL, policy_data, admin_policy_free)) { + btd_error(policy_data->adapter_id, + "Admin Policy Set interface init failed on path %s", + adapter_path); + return -EINVAL; + } + + btd_info(policy_data->adapter_id, + "Admin Policy Set interface registered"); return 0; } @@ -79,6 +202,8 @@ static int admin_init(void) { DBG(""); + dbus_conn = btd_get_dbus_connection(); + return btd_register_adapter_driver(&admin_policy_driver); } diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index 2ece87156..242b8d5da 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -12,19 +12,29 @@ #include #endif +#include +#include + #include "lib/bluetooth.h" +#include "lib/uuid.h" #include "src/adapter.h" +#include "src/dbus-common.h" #include "src/error.h" #include "src/log.h" #include "src/plugin.h" #include "src/shared/queue.h" +#define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" + +static DBusConnection *dbus_conn; + /* |policy_data| has the same life cycle as btd_adapter */ static struct btd_admin_policy { struct btd_adapter *adapter; uint16_t adapter_id; + struct queue *service_allowlist; } *policy_data = NULL; static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) @@ -40,17 +50,116 @@ static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) admin_policy->adapter = adapter; admin_policy->adapter_id = btd_adapter_get_index(adapter); + admin_policy->service_allowlist = NULL; return admin_policy; } +static void free_service_allowlist(struct queue *q) +{ + queue_destroy(q, g_free); +} + static void admin_policy_free(void *data) { struct btd_admin_policy *admin_policy = data; + free_service_allowlist(admin_policy->service_allowlist); g_free(admin_policy); } +static struct queue *parse_allow_service_list(struct btd_adapter *adapter, + DBusMessage *msg) +{ + DBusMessageIter iter, arr_iter; + struct queue *uuid_list = NULL; + + dbus_message_iter_init(msg, &iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) + return NULL; + + uuid_list = queue_new(); + dbus_message_iter_recurse(&iter, &arr_iter); + do { + const int type = dbus_message_iter_get_arg_type(&arr_iter); + char *uuid_param; + bt_uuid_t *uuid; + + if (type == DBUS_TYPE_INVALID) + break; + + if (type != DBUS_TYPE_STRING) + goto failed; + + dbus_message_iter_get_basic(&arr_iter, &uuid_param); + + uuid = g_try_malloc(sizeof(*uuid)); + if (!uuid) + goto failed; + + if (bt_string_to_uuid(uuid, uuid_param)) { + g_free(uuid); + goto failed; + } + + queue_push_head(uuid_list, uuid); + + dbus_message_iter_next(&arr_iter); + } while (true); + + return uuid_list; + +failed: + queue_destroy(uuid_list, g_free); + return NULL; +} + +static bool service_allowlist_set(struct btd_admin_policy *admin_policy, + struct queue *uuid_list) +{ + struct btd_adapter *adapter = admin_policy->adapter; + + if (!btd_adapter_set_allowed_uuids(adapter, uuid_list)) + return false; + + free_service_allowlist(admin_policy->service_allowlist); + admin_policy->service_allowlist = uuid_list; + + return true; +} + +static DBusMessage *set_service_allowlist(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct btd_admin_policy *admin_policy = user_data; + struct btd_adapter *adapter = admin_policy->adapter; + struct queue *uuid_list = NULL; + const char *sender = dbus_message_get_sender(msg); + + DBG("sender %s", sender); + + /* Parse parameters */ + uuid_list = parse_allow_service_list(adapter, msg); + if (!uuid_list) { + btd_error(admin_policy->adapter_id, + "Failed on parsing allowed service list"); + return btd_error_invalid_args(msg); + } + + if (!service_allowlist_set(admin_policy, uuid_list)) { + free_service_allowlist(uuid_list); + return btd_error_failed(msg, "service_allowlist_set failed"); + } + + return dbus_message_new_method_return(msg); +} + +static const GDBusMethodTable admin_policy_adapter_methods[] = { + { GDBUS_METHOD("SetServiceAllowList", GDBUS_ARGS({ "UUIDs", "as" }), + NULL, set_service_allowlist) }, + { } +}; + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { if (policy_data) { @@ -64,8 +173,18 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) if (!policy_data) return -ENOMEM; - btd_info(policy_data->adapter_id, "Admin Policy has been enabled"); + if (!g_dbus_register_interface(dbus_conn, adapter_get_path(adapter), + ADMIN_POLICY_SET_INTERFACE, + admin_policy_adapter_methods, NULL, + NULL, policy_data, admin_policy_free)) { + btd_error(policy_data->adapter_id, + "Admin Policy Set interface init failed on path %s", + adapter_get_path(adapter)); + return -EINVAL; + } + btd_info(policy_data->adapter_id, + "Admin Policy Set interface registered"); return 0; } @@ -79,6 +198,8 @@ static int admin_policy_init(void) { DBG(""); + dbus_conn = btd_get_dbus_connection(); + return btd_register_adapter_driver(&admin_policy_driver); } From patchwork Wed Jul 28 13:15:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A0ABC4338F for ; Wed, 28 Jul 2021 13:16:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B18360240 for ; Wed, 28 Jul 2021 13:16:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236301AbhG1NQ2 (ORCPT ); Wed, 28 Jul 2021 09:16:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234771AbhG1NQ1 (ORCPT ); Wed, 28 Jul 2021 09:16:27 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67385C061757 for ; Wed, 28 Jul 2021 06:16:26 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id a188-20020a25cac50000b029055d47682463so2859858ybg.5 for ; Wed, 28 Jul 2021 06:16:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=waFPu4k2vBWMdVfD1NhijACyWe0PqH5dsXXL6RGsLDg=; b=uEfscM+v9nCyLwhZRBHT8z9aKuHG4/75NDQsREeqCuhkasTCI8emg0G0TmmdRahFz0 4BX4RtHnfSAO/f7eAiLFIEN0+Bebao07C4gr4C+fHU9jgVMHEY+isRsTfauOTECfIITA stWQP/BA4HzX8cqTurYCRJjuZxGAJ8gJ1koJywvaFWiTuFvyS114r4Gy1ioCsLayanDN ORArZi1tXfI+WjRbU78LKy779DADuN3qFbzg2gIWlpffK2kqacobOo4Bk+MsiK6dBGGl GFNyugzj79JDyxBcBnKUvClj6TPizHH+0BcJEk5mzjcvujg4rKJDh+tkt67qNMkRTrQ1 +Ljg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=waFPu4k2vBWMdVfD1NhijACyWe0PqH5dsXXL6RGsLDg=; b=BPW48c0nXjcMWUcRE6h2oIpWKauokcmuDwHQPdd915RJ87V0Wf2eljN7knnvy0QT1b s7j3BxjcNoG26NyhgSDWFSsnvLWgvn+wdRzerxtfP48EckVabGpQ0SewGfsHWbIxcJAK Z30oHGS8Yc3+ZbyCvvYZnwxD7Y1YvPkZsrvcNfbWHXKW0m9eWpA5dfToq3MJGUxdSAUQ YtQgknEZCc0stJhZKFrGjacYrkfMx89syFB81pUTt0gxqwSHp+giAP9ZaCjpJm+9rW9p rLuu1Qf499TPD1CQYwPrJuhEauaUHIpvGZYi4CnVBxVYWe2z2+HtUC8TzATwE4q1UvzW 79hQ== X-Gm-Message-State: AOAM532DQVw6F5zwCUPZRgM0DNf/4kjmhQ2iMGPAZe+pxpdKnRveI7uE lnDREqLnjIQBrBQj4lqu8o2LGmrP8ogj9ZzVQ2H7NMBJH4Cel5/c8ppA6IzaT0Hg5sfVr2+ABPr 3rGAAw27A9s5pBTV421MNBQ07Ih4CBr5skgPgivgI2ZpsrDmBR9Mdomk/HbhjxCIPUbJLMhOEJx U1IXY/NXCuT4k= X-Google-Smtp-Source: ABdhPJyH7FYc8z7J+WtOSigY444CYZjXKmHmEwnvu1SGti7H4MHN2QKLJV4rQpauKHOgb12NZ4GvnYio9eFciwYIvg== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:f503:: with SMTP id a3mr25898153ybe.501.1627478185545; Wed, 28 Jul 2021 06:16:25 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:25 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.9.I00fd6c348e4c93501de6de0eae0d23436fd3895b@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 09/13] plugins/admin_policy: add ServiceAllowList property From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds code to register interface org.bluez.AdminPolicyStatus. The interface will provide read-only properties to indicate the current settings of admin policies. We separate this from AdminPolicySet so that normal clients can check current policy settings while only a few clients can change policies. This patch also adds readonly property ServiceAllowlist to AdminPolicyStatus1, which indicates the current setting of service allowlist. Reviewed-by: Miao-chen Chou --- The following test steps were performed: 1. Set ServiceAllowList to ["1124","180A","180F","1812"] 2. Verify ServiceAllowList is ["1124","180A","180F","1812"] in UUID-128 form 3. Set ServiceAllowList to [] 4. Verify ServiceAllowList is [] (no changes since v1) plugins/admin.c | 58 ++++++++++++++++++++++++++++++++++++++++++ plugins/admin_policy.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/plugins/admin.c b/plugins/admin.c index 1fe2904d9..d89a77c8a 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -27,6 +27,7 @@ #include "src/shared/queue.h" #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" +#define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" static DBusConnection *dbus_conn; @@ -151,6 +152,11 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, return btd_error_failed(msg, "service_allowlist_set failed"); } + g_dbus_emit_property_changed(dbus_conn, + adapter_get_path(policy_data->adapter), + ADMIN_POLICY_STATUS_INTERFACE, + "ServiceAllowList"); + return dbus_message_new_method_return(msg); } @@ -160,6 +166,43 @@ static const GDBusMethodTable admin_policy_adapter_methods[] = { { } }; +void append_service_uuid(void *data, void *user_data) +{ + bt_uuid_t *uuid = data; + DBusMessageIter *entry = user_data; + char uuid_str[MAX_LEN_UUID_STR]; + const char *uuid_str_ptr = uuid_str; + + if (!uuid) { + error("Unexpected NULL uuid data in service_allowlist"); + return; + } + + bt_uuid_to_string(uuid, uuid_str, MAX_LEN_UUID_STR); + dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &uuid_str_ptr); +} + +static gboolean property_get_service_allowlist( + const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct btd_admin_policy *admin_policy = user_data; + DBusMessageIter entry; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &entry); + queue_foreach(admin_policy->service_allowlist, append_service_uuid, + &entry); + dbus_message_iter_close_container(iter, &entry); + + return TRUE; +} + +static const GDBusPropertyTable admin_policy_adapter_properties[] = { + { "ServiceAllowList", "as", property_get_service_allowlist }, + { } +}; + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { const char *adapter_path; @@ -189,6 +232,21 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) btd_info(policy_data->adapter_id, "Admin Policy Set interface registered"); + + if (!g_dbus_register_interface(dbus_conn, adapter_path, + ADMIN_POLICY_STATUS_INTERFACE, + NULL, NULL, + admin_policy_adapter_properties, + policy_data, admin_policy_free)) { + btd_error(policy_data->adapter_id, + "Admin Policy Status interface init failed on path %s", + adapter_path); + return -EINVAL; + } + + btd_info(policy_data->adapter_id, + "Admin Policy Status interface registered"); + return 0; } diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index 242b8d5da..270d42366 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -27,6 +27,7 @@ #include "src/shared/queue.h" #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" +#define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" static DBusConnection *dbus_conn; @@ -151,6 +152,11 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, return btd_error_failed(msg, "service_allowlist_set failed"); } + g_dbus_emit_property_changed(dbus_conn, + adapter_get_path(policy_data->adapter), + ADMIN_POLICY_STATUS_INTERFACE, + "ServiceAllowList"); + return dbus_message_new_method_return(msg); } @@ -160,6 +166,43 @@ static const GDBusMethodTable admin_policy_adapter_methods[] = { { } }; +void append_service_uuid(void *data, void *user_data) +{ + bt_uuid_t *uuid = data; + DBusMessageIter *entry = user_data; + char uuid_str[MAX_LEN_UUID_STR]; + const char *uuid_str_ptr = uuid_str; + + if (!uuid) { + error("Unexpected NULL uuid data in service_allowlist"); + return; + } + + bt_uuid_to_string(uuid, uuid_str, MAX_LEN_UUID_STR); + dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &uuid_str_ptr); +} + +static gboolean property_get_service_allowlist( + const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct btd_admin_policy *admin_policy = user_data; + DBusMessageIter entry; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &entry); + queue_foreach(admin_policy->service_allowlist, append_service_uuid, + &entry); + dbus_message_iter_close_container(iter, &entry); + + return TRUE; +} + +static const GDBusPropertyTable admin_policy_adapter_properties[] = { + { "ServiceAllowList", "as", property_get_service_allowlist }, + { } +}; + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { if (policy_data) { @@ -185,6 +228,21 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) btd_info(policy_data->adapter_id, "Admin Policy Set interface registered"); + + if (!g_dbus_register_interface(dbus_conn, adapter_get_path(adapter), + ADMIN_POLICY_STATUS_INTERFACE, + NULL, NULL, + admin_policy_adapter_properties, + policy_data, admin_policy_free)) { + btd_error(policy_data->adapter_id, + "Admin Policy Status interface init failed on path %s", + adapter_get_path(adapter)); + return -EINVAL; + } + + btd_info(policy_data->adapter_id, + "Admin Policy Status interface registered"); + return 0; } From patchwork Wed Jul 28 13:15:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-23.5 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2FF8C4338F for ; Wed, 28 Jul 2021 13:16:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ABB396101B for ; Wed, 28 Jul 2021 13:16:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235301AbhG1NQe (ORCPT ); Wed, 28 Jul 2021 09:16:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234771AbhG1NQd (ORCPT ); Wed, 28 Jul 2021 09:16:33 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4044EC061757 for ; Wed, 28 Jul 2021 06:16:32 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id f1-20020a17090a8e81b029017720af1cf6so2887615pjo.9 for ; Wed, 28 Jul 2021 06:16:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=sf2hFRH9KhY9MANhWW43U1DGfmGMe8ygbazwQW1fTsg=; b=bkffiG0dBy8I4LTd7imBfR4P/LkvNAxjP2G+UfDwly5UhLlqMR+lEFv0RfjURrxOZB +wkdVDA2FOMT3GdMyhBzGUgT1wSQ5K+ETMul+1mM+EdjelO2d1kurX4x/EmVKPBj69q2 QPnD+kXiqJ4jyTkl2y8iZxH60pwZUUfF0cvSqJm+OJBIkCvnmAiZI9+kd3hhGS/cAfzj Xk3uCXAfP6CwAIOl+WacOwd8kT18K7X2WKbzKShSHnoee6cx+7pqp7PuTbopSq19GAFS 7VOfP38kEcUr3hUKr2FePIfJsF6wkpC4w9d3+BRrW8Tz2IIOGg4ynl7uGTFYLjwXJ3E+ CqrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=sf2hFRH9KhY9MANhWW43U1DGfmGMe8ygbazwQW1fTsg=; b=U06GpnzXvaGbfBpL4bAs534OC8Ad3s0Zl1Cv16t2U1HvY3LSiGdsPDECKQFtRLJFgf k+2qmlyrgdJrmzWj4zRsCnJjx8hS2kT5bJ1DHRqR1m0GZqUuca9rZ1kiW7fITvO3vdCe MDaVAh+680PzzJCHKlyJ3Au//+65/P1zdscoya/8QgIWbQe+Ud522gcQ9XcWgT4XmBJS A/Zxy/Kp3DhyEcJQV86PpHkKqO71s7/oXC2cGfLBLQx4PrDL1W/SxClYT2DpGy48Ttul kpagP0JCwGbfmPOK7yuMRh0g1oOSm1f/9R/BeUimcs41jA1w3oJAypRNf/HrKNyS15TI f8eQ== X-Gm-Message-State: AOAM5325GQw4fVzfsFYQF7UsqqlCfqxNQ0XrBbQ3Ek7+emZZUquvY4Z/ rf6rQI0fVA6NLDfLltrIJpe6ZLUtpFYrp2MtaOGnO8IkWb0Wb/mcX+AgT47mK/fTnLgXso7/k4P SPILsTsODm9FJ5ugEk3vW/djkOKqVqI6qrnZ2S9EwouTp81azyQ7Nl4kc05ROFLUm5JC6J6TZjl GSpELLb87Sb3Q= X-Google-Smtp-Source: ABdhPJxDb53dAAr775CBGu8S2Odwp0aEQce6XSCFWmrZIBLBmZx/L0Tt2idLBu6rYnAzFkSIty1YHM5EJ2AXCegcxA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a17:902:eb54:b029:12c:3612:b6e0 with SMTP id i20-20020a170902eb54b029012c3612b6e0mr10198568pli.33.1627478191574; Wed, 28 Jul 2021 06:16:31 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:26 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.10.I517e5199ac8019b770c7ee8c92a294ec1c752748@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 10/13] plugins/admin_policy: add device callbacks From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds callbacks for device added and device removed. It is necessary for implementation of "AffectedByPolicy" property since it needs to register an interface for each device object and unregister it once the device gets removed. Reviewed-by: Miao-chen Chou --- The following test steps were performed: 1. start discovery using UI 2. verify device_data were added by checking system log 3. stop discovery 4. verify device_data were removed after a few seconds by checking system log (no changes since v1) plugins/admin.c | 78 +++++++++++++++++++++ plugins/admin_policy.c | 154 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 228 insertions(+), 4 deletions(-) diff --git a/plugins/admin.c b/plugins/admin.c index d89a77c8a..37dae77ac 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -20,6 +20,7 @@ #include "src/adapter.h" #include "src/dbus-common.h" +#include "src/device.h" #include "src/error.h" #include "src/log.h" #include "src/plugin.h" @@ -29,7 +30,11 @@ #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" #define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" +#define DBUS_BLUEZ_SERVICE "org.bluez" +#define BTD_DEVICE_INTERFACE "org.bluez.Device1" + static DBusConnection *dbus_conn; +static struct queue *devices; /* List of struct device_data objects */ /* |policy_data| has the same life cycle as btd_adapter */ static struct btd_admin_policy { @@ -38,6 +43,11 @@ static struct btd_admin_policy { struct queue *service_allowlist; } *policy_data = NULL; +struct device_data { + struct btd_device *device; + char *path; +}; + static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) { struct btd_admin_policy *admin_policy = NULL; @@ -203,6 +213,37 @@ static const GDBusPropertyTable admin_policy_adapter_properties[] = { { } }; +static bool device_data_match(const void *a, const void *b) +{ + const struct device_data *data = a; + const struct btd_device *dev = b; + + if (!data) { + error("Unexpected NULL device_data"); + return false; + } + + return data->device == dev; +} + +static void free_device_data(void *data) +{ + struct device_data *device_data = data; + + g_free(device_data->path); + g_free(device_data); +} + +static void remove_device_data(void *data) +{ + struct device_data *device_data = data; + + DBG("device_data for %s removing", device_data->path); + + queue_remove(devices, device_data); + free_device_data(device_data); +} + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { const char *adapter_path; @@ -250,10 +291,45 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) return 0; } +static void admin_policy_device_added(struct btd_adapter *adapter, + struct btd_device *device) +{ + struct device_data *data; + + if (queue_find(devices, device_data_match, device)) + return; + + data = g_new0(struct device_data, 1); + if (!data) { + btd_error(btd_adapter_get_index(adapter), + "Failed to allocate memory for device_data"); + return; + } + + data->device = device; + data->path = g_strdup(device_get_path(device)); + queue_push_tail(devices, data); + + DBG("device_data for %s added", data->path); +} + +static void admin_policy_device_removed(struct btd_adapter *adapter, + struct btd_device *device) +{ + struct device_data *data; + + data = queue_find(devices, device_data_match, device); + + if (data) + remove_device_data(data); +} + static struct btd_adapter_driver admin_policy_driver = { .name = "admin_policy", .probe = admin_policy_adapter_probe, .resume = NULL, + .device_added = admin_policy_device_added, + .device_removed = admin_policy_device_removed }; static int admin_init(void) @@ -261,6 +337,7 @@ static int admin_init(void) DBG(""); dbus_conn = btd_get_dbus_connection(); + devices = queue_new(); return btd_register_adapter_driver(&admin_policy_driver); } @@ -270,6 +347,7 @@ static void admin_exit(void) DBG(""); btd_unregister_adapter_driver(&admin_policy_driver); + queue_destroy(devices, free_device_data); if (policy_data) admin_policy_free(policy_data); diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index 270d42366..73d695ef9 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -20,6 +20,7 @@ #include "src/adapter.h" #include "src/dbus-common.h" +#include "src/device.h" #include "src/error.h" #include "src/log.h" #include "src/plugin.h" @@ -29,7 +30,12 @@ #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" #define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" +#define DBUS_BLUEZ_SERVICE "org.bluez" +#define BTD_DEVICE_INTERFACE "org.bluez.Device1" + static DBusConnection *dbus_conn; +static GDBusClient *dbus_client; +static struct queue *devices; /* List of struct device_data objects */ /* |policy_data| has the same life cycle as btd_adapter */ static struct btd_admin_policy { @@ -38,6 +44,11 @@ static struct btd_admin_policy { struct queue *service_allowlist; } *policy_data = NULL; +struct device_data { + struct btd_device *device; + char *path; +}; + static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) { struct btd_admin_policy *admin_policy = NULL; @@ -203,8 +214,122 @@ static const GDBusPropertyTable admin_policy_adapter_properties[] = { { } }; +static bool device_data_match(const void *a, const void *b) +{ + const struct device_data *data = a; + const struct btd_device *dev = b; + + if (!data) { + error("Unexpected NULL device_data"); + return false; + } + + return data->device == dev; +} + +static bool device_data_match_by_path(const void *a, const void *b) +{ + const struct device_data *data = a; + const char *path = b; + + if (!data) { + error("Unexpected NULL device_data"); + return false; + } + + return strcmp(data->path, b) == 0; +} + +static void free_device_data(void *data) +{ + struct device_data *device_data = data; + + g_free(device_data->path); + g_free(device_data); +} + +static void remove_device_data(void *data) +{ + struct device_data *device_data = data; + + DBG("device_data for %s removing", device_data->path); + + queue_remove(devices, device_data); + free_device_data(device_data); +} + +static void add_device_data(struct btd_device *device) +{ + struct btd_adapter *adapter = device_get_adapter(device); + struct device_data *data; + + if (queue_find(devices, device_data_match, device)) + return; + + data = g_new0(struct device_data, 1); + if (!data) { + btd_error(btd_adapter_get_index(adapter), + "Failed to allocate memory for device_data"); + return; + } + + data->device = device; + data->path = g_strdup(device_get_path(device)); + queue_push_tail(devices, data); + + DBG("device_data for %s added", data->path); +} + +static struct btd_device *find_device_by_proxy(GDBusProxy *proxy) +{ + const char *path = g_dbus_proxy_get_path(proxy); + const char *iface = g_dbus_proxy_get_interface(proxy); + struct btd_device *device; + + if (strcmp(iface, BTD_DEVICE_INTERFACE) != 0) + return NULL; + + device = btd_adapter_find_device_by_path(policy_data->adapter, path); + + if (!device) { + btd_warn(adapter_get_path(policy_data->adapter), + "Device path %s is not found", path); + } + + return device; +} + +static void object_added_cb(GDBusProxy *proxy, void *user_data) +{ + struct btd_device *device; + + device = find_device_by_proxy(proxy); + + if (!device) + return; + + add_device_data(device); +} + +static void object_removed_cb(GDBusProxy *proxy, void *user_data) +{ + const char *path = g_dbus_proxy_get_path(proxy); + const char *iface = g_dbus_proxy_get_interface(proxy); + struct device_data *data; + + if (strcmp(iface, BTD_DEVICE_INTERFACE) != 0) + return; + + data = queue_find(devices, device_data_match_by_path, path); + + if (data) + remove_device_data(data); +} + static int admin_policy_adapter_probe(struct btd_adapter *adapter) { + const char *adapter_path; + if (policy_data) { btd_warn(policy_data->adapter_id, "Policy data already exists"); @@ -216,33 +341,43 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) if (!policy_data) return -ENOMEM; - if (!g_dbus_register_interface(dbus_conn, adapter_get_path(adapter), + adapter_path = adapter_get_path(adapter); + + if (!g_dbus_register_interface(dbus_conn, adapter_path, ADMIN_POLICY_SET_INTERFACE, admin_policy_adapter_methods, NULL, NULL, policy_data, admin_policy_free)) { btd_error(policy_data->adapter_id, "Admin Policy Set interface init failed on path %s", - adapter_get_path(adapter)); + adapter_path); return -EINVAL; } btd_info(policy_data->adapter_id, "Admin Policy Set interface registered"); - if (!g_dbus_register_interface(dbus_conn, adapter_get_path(adapter), + if (!g_dbus_register_interface(dbus_conn, adapter_path, ADMIN_POLICY_STATUS_INTERFACE, NULL, NULL, admin_policy_adapter_properties, policy_data, admin_policy_free)) { btd_error(policy_data->adapter_id, "Admin Policy Status interface init failed on path %s", - adapter_get_path(adapter)); + adapter_path); return -EINVAL; } btd_info(policy_data->adapter_id, "Admin Policy Status interface registered"); + dbus_client = g_dbus_client_new(dbus_conn, DBUS_BLUEZ_SERVICE, + adapter_path); + + g_dbus_client_set_proxy_handlers(dbus_client, object_added_cb, + object_removed_cb, NULL, NULL); + + g_dbus_client_set_ready_watch(dbus_client, NULL, NULL); + return 0; } @@ -257,6 +392,7 @@ static int admin_policy_init(void) DBG(""); dbus_conn = btd_get_dbus_connection(); + devices = queue_new(); return btd_register_adapter_driver(&admin_policy_driver); } @@ -266,9 +402,19 @@ static void admin_policy_exit(void) DBG(""); btd_unregister_adapter_driver(&admin_policy_driver); + queue_destroy(devices, free_device_data); if (policy_data) admin_policy_free(policy_data); + + if (dbus_client) { + g_dbus_client_set_disconnect_watch(dbus_client, NULL, NULL); + g_dbus_client_set_proxy_handlers(dbus_client, NULL, NULL, NULL, + NULL); + g_dbus_client_set_ready_watch(dbus_client, NULL, NULL); + g_dbus_client_unref(dbus_client); + dbus_client = NULL; + } } BLUETOOTH_PLUGIN_DEFINE(admin_policy, VERSION, From patchwork Wed Jul 28 13:15:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405605 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F357DC4338F for ; Wed, 28 Jul 2021 13:16:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9DD860240 for ; Wed, 28 Jul 2021 13:16:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236310AbhG1NQj (ORCPT ); Wed, 28 Jul 2021 09:16:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234771AbhG1NQi (ORCPT ); Wed, 28 Jul 2021 09:16:38 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61089C061757 for ; Wed, 28 Jul 2021 06:16:37 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id j13-20020a0cf30d0000b029032dd803a7edso1941417qvl.2 for ; Wed, 28 Jul 2021 06:16:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ak/MLeitgxrnl9tWS1ibUYAvL7HQGK//m5OkSfh8Et0=; b=HllWjPmpRoM25oHc2ucNRRQjVYvJzTLAx7YwP9jadyz8rOZrltCN3e97ENKZhT5e2f IabWS8iLzTN0er66RbE32g4F/DDN1CNbdIwVegyycv3ConiGBY6IC05g2J/L4DeJbnbT pJM1XAMbePzercnP/3HazCDz/p3aE5kjd+9QkE61450NP9N4AeiS+ARd6824PLqANpJb dlOY6X+WdhZSOCM/3TmlZG2e+p0CTh34FrIJ/aaiLyPfILbqRLWZFVdbCF3P+vSWOTka DLA6UYhCTfjZMZ9n/ENndwUTHWKbluxyqc4vVhb/luPm5p75jg43cOb1YpWcxMcMgjRP MONw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ak/MLeitgxrnl9tWS1ibUYAvL7HQGK//m5OkSfh8Et0=; b=SF4KrErSPRDfj4jRJaPyT6fbeFlhgpY4lTUM2i0BoPJWMb1uw4JfOC0056DWpSOMhd gXanlxp4dbkjjJcGWnBACb5Eeo8nxisAVerpraPSUVYkMpHzpP2kPRCmkPpugnh0XMJW vywq/nYB9uT2RjrXxMTE+dj9EZ9tDmghrWQ+8p2PFX9/zepUUqdjvPbcCUzn3RBufZsi FIEYY4nGnP82ak1yoQSbBqbIR41qwa3pw4b5eHcE/60uNetMIVoJNr6achpepGK+GgmC 3/JY4HhFV4YdXaBgI+1N/oxwhokTlGO0EWuaqYVNnkMf+54ibYtZKyQeokwiM2MthlR8 7Ikg== X-Gm-Message-State: AOAM530jenYmTRKXS9fSQQ7CHe2cKvKz6p+NzmzlQWyGr90xKN3PE0wt 3vTuD9uB3N7retKthKr7sYWvPGaEUBR8MFhTsKWMWuXjimAE+UfsANgB8hqQ7grvgbDQNYg0m9e jowxfIxq6iVHg1B81ZfEsF2WoVkRTZ+pJaVY0o8x7G1exrA0t7iDiFQomE8RUx6FmfZc5C882LZ QCNzFtfOqgc9s= X-Google-Smtp-Source: ABdhPJyb3GaxDW1dcj6gRwMT5p39UBpkaId3i/Y5Ibzuj09/3vRwRdh6134fXJPEQ5DcoPaMP3b6/idXYcNYqs1XRA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a05:6214:1909:: with SMTP id er9mr20295872qvb.26.1627478196268; Wed, 28 Jul 2021 06:16:36 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:27 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.11.I570c860f59c8ed66ddb31aa54584ee08080aa10c@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 11/13] plugins/admin_policy: add AffectedByPolicy property From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds property to indicate if a device has any service that is being blocked by admin policy. Reviewed-by: Miao-chen Chou --- The following test steps were performed: 1. Set ServiceAllowList to [] 2. Verify AffectedByPolicy of K830 is False 3. Set ServiceAllowList to ["1800"] 4. Verify AffectedByPolicy of K830 is False 5. Set ServiceAllowList to ["1800","1801","180A","180F","1812"] 6. Verify AffectedByPolicy of K830 is True (no changes since v1) plugins/admin.c | 74 ++++++++++++++++++++++++++++++++++++++++-- plugins/admin_policy.c | 74 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/plugins/admin.c b/plugins/admin.c index 37dae77ac..2ad60f2fd 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -46,6 +46,7 @@ static struct btd_admin_policy { struct device_data { struct btd_device *device; char *path; + bool affected; }; static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) @@ -139,6 +140,27 @@ static bool service_allowlist_set(struct btd_admin_policy *admin_policy, return true; } +static void update_device_affected(void *data, void *user_data) +{ + struct device_data *dev_data = data; + bool affected; + + if (!dev_data) { + error("Unexpected NULL device_data when updating device"); + return; + } + + affected = !btd_device_all_services_allowed(dev_data->device); + + if (affected == dev_data->affected) + return; + + dev_data->affected = affected; + + g_dbus_emit_property_changed(dbus_conn, dev_data->path, + ADMIN_POLICY_STATUS_INTERFACE, "AffectedByPolicy"); +} + static DBusMessage *set_service_allowlist(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -167,6 +189,8 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, ADMIN_POLICY_STATUS_INTERFACE, "ServiceAllowList"); + queue_foreach(devices, update_device_affected, NULL); + return dbus_message_new_method_return(msg); } @@ -226,6 +250,29 @@ static bool device_data_match(const void *a, const void *b) return data->device == dev; } +static gboolean property_get_affected_by_policy( + const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct device_data *data = user_data; + dbus_bool_t affected; + + if (!data) { + error("Unexpected error: device_data is NULL"); + return FALSE; + } + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, + &data->affected); + + return TRUE; +} + +static const GDBusPropertyTable admin_policy_device_properties[] = { + { "AffectedByPolicy", "b", property_get_affected_by_policy }, + { } +}; + static void free_device_data(void *data) { struct device_data *device_data = data; @@ -308,11 +355,33 @@ static void admin_policy_device_added(struct btd_adapter *adapter, data->device = device; data->path = g_strdup(device_get_path(device)); + data->affected = !btd_device_all_services_allowed(data->device); + + if (!g_dbus_register_interface(dbus_conn, data->path, + ADMIN_POLICY_STATUS_INTERFACE, + NULL, NULL, + admin_policy_device_properties, + data, remove_device_data)) { + btd_error(btd_adapter_get_index(adapter), + "Admin Policy Status interface init failed on path %s", + device_get_path(device)); + free_device_data(data); + return; + } + queue_push_tail(devices, data); DBG("device_data for %s added", data->path); } +static void unregister_device_data(void *data, void *user_data) +{ + struct device_data *dev_data = data; + + g_dbus_unregister_interface(dbus_conn, dev_data->path, + ADMIN_POLICY_STATUS_INTERFACE); +} + static void admin_policy_device_removed(struct btd_adapter *adapter, struct btd_device *device) { @@ -321,7 +390,7 @@ static void admin_policy_device_removed(struct btd_adapter *adapter, data = queue_find(devices, device_data_match, device); if (data) - remove_device_data(data); + unregister_device_data(data, NULL); } static struct btd_adapter_driver admin_policy_driver = { @@ -347,7 +416,8 @@ static void admin_exit(void) DBG(""); btd_unregister_adapter_driver(&admin_policy_driver); - queue_destroy(devices, free_device_data); + queue_foreach(devices, unregister_device_data, NULL); + queue_destroy(devices, g_free); if (policy_data) admin_policy_free(policy_data); diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index 73d695ef9..3ce72b56b 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -47,6 +47,7 @@ static struct btd_admin_policy { struct device_data { struct btd_device *device; char *path; + bool affected; }; static struct btd_admin_policy *admin_policy_new(struct btd_adapter *adapter) @@ -140,6 +141,27 @@ static bool service_allowlist_set(struct btd_admin_policy *admin_policy, return true; } +static void update_device_affected(void *data, void *user_data) +{ + struct device_data *dev_data = data; + bool affected; + + if (!dev_data) { + error("Unexpected NULL device_data when updating device"); + return; + } + + affected = !btd_device_all_services_allowed(dev_data->device); + + if (affected == dev_data->affected) + return; + + dev_data->affected = affected; + + g_dbus_emit_property_changed(dbus_conn, dev_data->path, + ADMIN_POLICY_STATUS_INTERFACE, "AffectedByPolicy"); +} + static DBusMessage *set_service_allowlist(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -168,6 +190,8 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, ADMIN_POLICY_STATUS_INTERFACE, "ServiceAllowList"); + queue_foreach(devices, update_device_affected, NULL); + return dbus_message_new_method_return(msg); } @@ -240,6 +264,29 @@ static bool device_data_match_by_path(const void *a, const void *b) return strcmp(data->path, b) == 0; } +static gboolean property_get_affected_by_policy( + const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct device_data *data = user_data; + dbus_bool_t affected; + + if (!data) { + error("Unexpected error: device_data is NULL"); + return FALSE; + } + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, + &data->affected); + + return TRUE; +} + +static const GDBusPropertyTable admin_policy_device_properties[] = { + { "AffectedByPolicy", "b", property_get_affected_by_policy }, + { } +}; + static void free_device_data(void *data) { struct device_data *device_data = data; @@ -275,11 +322,33 @@ static void add_device_data(struct btd_device *device) data->device = device; data->path = g_strdup(device_get_path(device)); + data->affected = !btd_device_all_services_allowed(data->device); + + if (!g_dbus_register_interface(dbus_conn, data->path, + ADMIN_POLICY_STATUS_INTERFACE, + NULL, NULL, + admin_policy_device_properties, + data, remove_device_data)) { + btd_error(btd_adapter_get_index(adapter), + "Admin Policy Status interface init failed on path %s", + device_get_path(device)); + free_device_data(data); + return; + } + queue_push_tail(devices, data); DBG("device_data for %s added", data->path); } +static void unregister_device_data(void *data, void *user_data) +{ + struct device_data *dev_data = data; + + g_dbus_unregister_interface(dbus_conn, dev_data->path, + ADMIN_POLICY_STATUS_INTERFACE); +} + static struct btd_device *find_device_by_proxy(GDBusProxy *proxy) { const char *path = g_dbus_proxy_get_path(proxy); @@ -323,7 +392,7 @@ static void object_removed_cb(GDBusProxy *proxy, void *user_data) data = queue_find(devices, device_data_match_by_path, path); if (data) - remove_device_data(data); + unregister_device_data(data, NULL); } static int admin_policy_adapter_probe(struct btd_adapter *adapter) @@ -402,7 +471,8 @@ static void admin_policy_exit(void) DBG(""); btd_unregister_adapter_driver(&admin_policy_driver); - queue_destroy(devices, free_device_data); + queue_foreach(devices, unregister_device_data, NULL); + queue_destroy(devices, g_free); if (policy_data) admin_policy_free(policy_data); From patchwork Wed Jul 28 13:15:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-23.5 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF42FC4338F for ; Wed, 28 Jul 2021 13:16:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C852860240 for ; Wed, 28 Jul 2021 13:16:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234771AbhG1NQp (ORCPT ); Wed, 28 Jul 2021 09:16:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236209AbhG1NQn (ORCPT ); Wed, 28 Jul 2021 09:16:43 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CE6FC061757 for ; Wed, 28 Jul 2021 06:16:42 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id v71-20020a252f4a0000b029055b51419c7dso2732685ybv.23 for ; Wed, 28 Jul 2021 06:16:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=9m5S22NXiUW+VjjEnZGAPl9V6e1p2/iWayg/BhZIEE8=; b=Ah4tx76FOQy0W5cNrdh5IRTy6/sWf8HHi1yFKrtI+gt2HS3xk/nkXRxkFyC9BHoo2T nMrX8fY7NgAEbv7XCDKrHrdFD6bg2JGKGX8fprbH7VY2ZNYi4EGdo4uqqHV9li91v1vK DbnwUf1Xrt7c0CQgMclHuzOgkabLBo6GOOi/MhKqBUEEsybhWkbF04vWRjifN/7l++Nw KC94SqpGeuS/9UHKr+0eoXJnvoQk0yGMqLpChlIVdBOGob/L+NmPm7mIxKAxvsP1zTrg +ojirhnP+bO3mogYTzlLTdFdqJPxzIhCBPh3FZA1bCe22cFVfE28R+J3QBGsAaucjSP3 gKKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=9m5S22NXiUW+VjjEnZGAPl9V6e1p2/iWayg/BhZIEE8=; b=Qgbp+en+zPz3heNpgQoG9CR2nZsPtBLl9bhGpG6Iquj7trg66min4QhOcA99HYy4xk eF6NFz/byRvWQeDsa5OSZjuiUSsffRtYYHToFmnNgm1lSiJLDGuTaeZ2XJ+sceZj/123 y+2FXhd6jyw4qosqtIp05BFSHtc/is8FmRv1ilmy80T6q7g9Kt2dfr1CfSj1n/oEXK/C udC0nVB4KuMqk/JWCIf5mioHOzZwHvdXxnHJJryrilgQYx/XyIWRzdi0zALlWVDb4rXN VjjVnN0d1WoCPjsbR6kDBc9PmJ9f4r/hN5/tYrU6cC/e62zsbRX+oJAF+HBwR0CKu+Dj ohtg== X-Gm-Message-State: AOAM5306kaf03zSrpNoRDBQQNSLhZsv7EZNKmNcah/7FFL+TUuyGiv6X qpw5deru/LokwDd2mTcYfSSvD8k4nO+gDycRMozi7gvybHnK2Cm5XzCPBv121/Ro1wmkm91PsKL ox1m9giw2iqge5SNyfOKFfXQZzhD2WGmfHRbCDvzVqm82iDUYJuiiXrEpGISTrg5c49mMkkeOHQ gR62lGya0ASpw= X-Google-Smtp-Source: ABdhPJwomGtYMpfKv1ujYoVuxxeV/LGwlwJ3Yz28zBXWT3OJlVVevH0VZOVfLLgVfccivrEucdnw6N0YwB8kR7Q6hA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:a25:b9c7:: with SMTP id y7mr38677294ybj.78.1627478201331; Wed, 28 Jul 2021 06:16:41 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:28 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.12.Ib26c0abdbd417673a8b5788c175c06110726a68c@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 12/13] plugins/admin_policy: persist policy settings From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds code to store the ServiceAllowlist to file /var/lib/bluetooth/{MAC_ADDR}/admin_policy The stored settings will be loaded upon admin_policy initialized. Reviewed-by: Miao-chen Chou --- The following test steps were performed: 1. Set ServiceAllowlist to ["1124","180A","180F","1812", "1801"] 2. restart bluetoothd 3. Verify ServiceAllowlist is ["1124","180A","180F","1812","1801"] in UUID-128 form 4. Set ServiceAllowlist to [] 5. restart bluetoothd 6. Verify ServiceAllowlist is [] (no changes since v1) plugins/admin.c | 163 ++++++++++++++++++++++++++++++++++++++++- plugins/admin_policy.c | 163 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 324 insertions(+), 2 deletions(-) diff --git a/plugins/admin.c b/plugins/admin.c index 2ad60f2fd..82a8ae928 100644 --- a/plugins/admin.c +++ b/plugins/admin.c @@ -14,6 +14,8 @@ #include #include +#include +#include #include "lib/bluetooth.h" #include "lib/uuid.h" @@ -24,11 +26,13 @@ #include "src/error.h" #include "src/log.h" #include "src/plugin.h" +#include "src/textfile.h" #include "src/shared/queue.h" #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" #define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" +#define ADMIN_POLICY_STORAGE STORAGEDIR "/admin_policy_settings" #define DBUS_BLUEZ_SERVICE "org.bluez" #define BTD_DEVICE_INTERFACE "org.bluez.Device1" @@ -161,6 +165,8 @@ static void update_device_affected(void *data, void *user_data) ADMIN_POLICY_STATUS_INTERFACE, "AffectedByPolicy"); } +static void store_policy_settings(struct btd_admin_policy *admin_policy); + static DBusMessage *set_service_allowlist(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -179,7 +185,9 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, return btd_error_invalid_args(msg); } - if (!service_allowlist_set(admin_policy, uuid_list)) { + if (service_allowlist_set(admin_policy, uuid_list)) { + store_policy_settings(admin_policy); + } else { free_service_allowlist(uuid_list); return btd_error_failed(msg, "service_allowlist_set failed"); } @@ -237,6 +245,158 @@ static const GDBusPropertyTable admin_policy_adapter_properties[] = { { } }; +static void free_uuid_strings(char **uuid_strs, int num) +{ + gsize i; + + for (i = 0; i < num; i++) + g_free(uuid_strs[i]); + g_free(uuid_strs); +} + +static char **new_uuid_strings(struct queue *allowlist, gsize *num) +{ + const struct queue_entry *entry = NULL; + bt_uuid_t *uuid = NULL; + char **uuid_strs = NULL; + gsize i = 0, allowlist_num; + + allowlist_num = queue_length(allowlist); + uuid_strs = g_try_malloc_n(allowlist_num, sizeof(char *)); + if (!uuid_strs) + return NULL; + + for (entry = queue_get_entries(allowlist); entry != NULL; + entry = entry->next) { + uuid = entry->data; + uuid_strs[i] = g_try_malloc0(MAX_LEN_UUID_STR * sizeof(char)); + + if (!uuid_strs[i]) + goto failed; + + bt_uuid_to_string(uuid, uuid_strs[i], MAX_LEN_UUID_STR); + i++; + } + + *num = allowlist_num; + return uuid_strs; + +failed: + free_uuid_strings(uuid_strs, i); + + return NULL; +} + +static void store_policy_settings(struct btd_admin_policy *admin_policy) +{ + GKeyFile *key_file = NULL; + char *filename = ADMIN_POLICY_STORAGE; + char *key_file_data = NULL; + char **uuid_strs = NULL; + gsize length, num_uuids; + + key_file = g_key_file_new(); + + if (num_uuids) { + uuid_strs = new_uuid_strings(admin_policy->service_allowlist, + &num_uuids); + } + + if (!uuid_strs && num_uuids) { + btd_error(admin_policy->adapter_id, + "Failed to allocate uuid strings"); + goto failed; + } + + g_key_file_set_string_list(key_file, "General", "ServiceAllowlist", + (const gchar * const *)uuid_strs, + num_uuids); + + if (create_file(ADMIN_POLICY_STORAGE, 0600) < 0) { + btd_error(admin_policy->adapter_id, "create %s failed, %s", + filename, strerror(errno)); + goto failed; + } + + key_file_data = g_key_file_to_data(key_file, &length, NULL); + g_file_set_contents(ADMIN_POLICY_STORAGE, key_file_data, length, NULL); + + g_free(key_file_data); + free_uuid_strings(uuid_strs, num_uuids); + +failed: + g_key_file_free(key_file); +} + +static void key_file_load_service_allowlist(GKeyFile *key_file, + struct btd_admin_policy *admin_policy) +{ + GError *gerr = NULL; + struct queue *uuid_list = NULL; + gchar **uuids = NULL; + gsize num, i; + + uuids = g_key_file_get_string_list(key_file, "General", + "ServiceAllowlist", &num, &gerr); + + if (gerr) { + btd_error(admin_policy->adapter_id, + "Failed to load ServiceAllowlist"); + g_error_free(gerr); + return; + } + + uuid_list = queue_new(); + for (i = 0; i < num; i++) { + bt_uuid_t *uuid = g_try_malloc(sizeof(*uuid)); + + if (!uuid) + goto failed; + + if (bt_string_to_uuid(uuid, *uuids)) { + + btd_error(admin_policy->adapter_id, + "Failed to convert '%s' to uuid struct", + *uuids); + + g_free(uuid); + goto failed; + } + + queue_push_tail(uuid_list, uuid); + uuids++; + } + + if (!service_allowlist_set(admin_policy, uuid_list)) + goto failed; + + return; +failed: + free_service_allowlist(uuid_list); +} + +static void load_policy_settings(struct btd_admin_policy *admin_policy) +{ + GKeyFile *key_file; + char *filename = ADMIN_POLICY_STORAGE; + struct stat st; + + if (stat(filename, &st) < 0) { + btd_error(admin_policy->adapter_id, + "Failed to get file %s information", + filename); + return; + } + + key_file = g_key_file_new(); + + g_key_file_load_from_file(key_file, filename, 0, NULL); + + key_file_load_service_allowlist(key_file, admin_policy); + + g_key_file_free(key_file); +} + static bool device_data_match(const void *a, const void *b) { const struct device_data *data = a; @@ -306,6 +466,7 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) if (!policy_data) return -ENOMEM; + load_policy_settings(policy_data); adapter_path = adapter_get_path(adapter); if (!g_dbus_register_interface(dbus_conn, adapter_path, diff --git a/plugins/admin_policy.c b/plugins/admin_policy.c index 3ce72b56b..3a55d97b3 100644 --- a/plugins/admin_policy.c +++ b/plugins/admin_policy.c @@ -14,6 +14,8 @@ #include #include +#include +#include #include "lib/bluetooth.h" #include "lib/uuid.h" @@ -24,11 +26,13 @@ #include "src/error.h" #include "src/log.h" #include "src/plugin.h" +#include "src/textfile.h" #include "src/shared/queue.h" #define ADMIN_POLICY_SET_INTERFACE "org.bluez.AdminPolicySet1" #define ADMIN_POLICY_STATUS_INTERFACE "org.bluez.AdminPolicyStatus1" +#define ADMIN_POLICY_STORAGE STORAGEDIR "/admin_policy_settings" #define DBUS_BLUEZ_SERVICE "org.bluez" #define BTD_DEVICE_INTERFACE "org.bluez.Device1" @@ -162,6 +166,8 @@ static void update_device_affected(void *data, void *user_data) ADMIN_POLICY_STATUS_INTERFACE, "AffectedByPolicy"); } +static void store_policy_settings(struct btd_admin_policy *admin_policy); + static DBusMessage *set_service_allowlist(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -180,7 +186,9 @@ static DBusMessage *set_service_allowlist(DBusConnection *conn, return btd_error_invalid_args(msg); } - if (!service_allowlist_set(admin_policy, uuid_list)) { + if (service_allowlist_set(admin_policy, uuid_list)) { + store_policy_settings(admin_policy); + } else { free_service_allowlist(uuid_list); return btd_error_failed(msg, "service_allowlist_set failed"); } @@ -238,6 +246,158 @@ static const GDBusPropertyTable admin_policy_adapter_properties[] = { { } }; +static void free_uuid_strings(char **uuid_strs, int num) +{ + gsize i; + + for (i = 0; i < num; i++) + g_free(uuid_strs[i]); + g_free(uuid_strs); +} + +static char **new_uuid_strings(struct queue *allowlist, gsize *num) +{ + const struct queue_entry *entry = NULL; + bt_uuid_t *uuid = NULL; + char **uuid_strs = NULL; + gsize i = 0, allowlist_num; + + allowlist_num = queue_length(allowlist); + uuid_strs = g_try_malloc_n(allowlist_num, sizeof(char *)); + if (!uuid_strs) + return NULL; + + for (entry = queue_get_entries(allowlist); entry != NULL; + entry = entry->next) { + uuid = entry->data; + uuid_strs[i] = g_try_malloc0(MAX_LEN_UUID_STR * sizeof(char)); + + if (!uuid_strs[i]) + goto failed; + + bt_uuid_to_string(uuid, uuid_strs[i], MAX_LEN_UUID_STR); + i++; + } + + *num = allowlist_num; + return uuid_strs; + +failed: + free_uuid_strings(uuid_strs, i); + + return NULL; +} + +static void store_policy_settings(struct btd_admin_policy *admin_policy) +{ + GKeyFile *key_file = NULL; + char *filename = ADMIN_POLICY_STORAGE; + char *key_file_data = NULL; + char **uuid_strs = NULL; + gsize length, num_uuids; + + key_file = g_key_file_new(); + + if (num_uuids) { + uuid_strs = new_uuid_strings(admin_policy->service_allowlist, + &num_uuids); + } + + if (!uuid_strs && num_uuids) { + btd_error(admin_policy->adapter_id, + "Failed to allocate uuid strings"); + goto failed; + } + + g_key_file_set_string_list(key_file, "General", "ServiceAllowlist", + (const gchar * const *)uuid_strs, + num_uuids); + + if (create_file(ADMIN_POLICY_STORAGE, 0600) < 0) { + btd_error(admin_policy->adapter_id, "create %s failed, %s", + filename, strerror(errno)); + goto failed; + } + + key_file_data = g_key_file_to_data(key_file, &length, NULL); + g_file_set_contents(ADMIN_POLICY_STORAGE, key_file_data, length, NULL); + + g_free(key_file_data); + free_uuid_strings(uuid_strs, num_uuids); + +failed: + g_key_file_free(key_file); +} + +static void key_file_load_service_allowlist(GKeyFile *key_file, + struct btd_admin_policy *admin_policy) +{ + GError *gerr = NULL; + struct queue *uuid_list = NULL; + gchar **uuids = NULL; + gsize num, i; + + uuids = g_key_file_get_string_list(key_file, "General", + "ServiceAllowlist", &num, &gerr); + + if (gerr) { + btd_error(admin_policy->adapter_id, + "Failed to load ServiceAllowlist"); + g_error_free(gerr); + return; + } + + uuid_list = queue_new(); + for (i = 0; i < num; i++) { + bt_uuid_t *uuid = g_try_malloc(sizeof(*uuid)); + + if (!uuid) + goto failed; + + if (bt_string_to_uuid(uuid, *uuids)) { + + btd_error(admin_policy->adapter_id, + "Failed to convert '%s' to uuid struct", + *uuids); + + g_free(uuid); + goto failed; + } + + queue_push_tail(uuid_list, uuid); + uuids++; + } + + if (!service_allowlist_set(admin_policy, uuid_list)) + goto failed; + + return; +failed: + free_service_allowlist(uuid_list); +} + +static void load_policy_settings(struct btd_admin_policy *admin_policy) +{ + GKeyFile *key_file; + char *filename = ADMIN_POLICY_STORAGE; + struct stat st; + + if (stat(filename, &st) < 0) { + btd_error(admin_policy->adapter_id, + "Failed to get file %s information", + filename); + return; + } + + key_file = g_key_file_new(); + + g_key_file_load_from_file(key_file, filename, 0, NULL); + + key_file_load_service_allowlist(key_file, admin_policy); + + g_key_file_free(key_file); +} + static bool device_data_match(const void *a, const void *b) { const struct device_data *data = a; @@ -410,6 +570,7 @@ static int admin_policy_adapter_probe(struct btd_adapter *adapter) if (!policy_data) return -ENOMEM; + load_policy_settings(policy_data); adapter_path = adapter_get_path(adapter); if (!g_dbus_register_interface(dbus_conn, adapter_path, From patchwork Wed Jul 28 13:15:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 12405609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FBCDC4338F for ; Wed, 28 Jul 2021 13:16:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8433361019 for ; Wed, 28 Jul 2021 13:16:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236279AbhG1NQt (ORCPT ); Wed, 28 Jul 2021 09:16:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236209AbhG1NQs (ORCPT ); Wed, 28 Jul 2021 09:16:48 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 836BCC061757 for ; Wed, 28 Jul 2021 06:16:47 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id w19-20020a170902d113b029012c1505a89fso1957172plw.13 for ; Wed, 28 Jul 2021 06:16:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=NokkcDvovb9Lu8+jkbGkT+S9xqf5OeaAMMgso8G3IEE=; b=f8KOfVGu/IebllCksFxsfOIAhfTgY/TA/KIHbrUh07XrfGps6ZTbbNalYbBrJp+IQX K38t//ywPn+RFVsyG1gRHLRLXOHcgp2+rg5zExtGiHLx/S6IuDuq0Npwhd9sZSxoV3h8 lgt42Q5xLhcuKo4J1Y3LrQnZUlPuadEV5rt8nnHaSbZvJciX++b4bSSy8PaHdwb/L0W9 dFw+8ToAHfKoJGFO+371l+0CacrgIwFYiilD6Ertth4R973cRJDGhRjKLWNv1JsFmDWQ 6QRLhFBuAXA84RoAnFqLAXzkIU63Z2BPHx3QcoIfqwpxy1XEjlpGh/X2shqJnWsqOdYI /Mlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NokkcDvovb9Lu8+jkbGkT+S9xqf5OeaAMMgso8G3IEE=; b=UfFUe60u2uW2dR7hXG6IBfVjzkLNVTFRWJsKB6pTos7Aw/Jp6PIK1UT/sUQcBRBz+R Pb8NALB/GYV+dvodpVLL7dBObqQUul3h0pmcx4qlyvHG92I+Lt3MFyIiBYL+VqwgJeMk sqHBCjeiv+wJ2CKoQBOlyMNXsLuDzySXcs4jZg69C3TcXSXJ2xOE09UnvHaJWuu1Fnfq 73RFNN30YKJAyQhYpEYFiUDsa4QQVL5QhUk8hS/aoQTi0S4MRr4oHoNPmUqGoQVOGSZZ RztbQ/5w4tASr5O4SQK2McJ4MkARadPpSZKDWTmLuyGfzvd5Y8rH1APofoNwW7F0hfB8 FFSA== X-Gm-Message-State: AOAM532jtRf12/sNpPJ9SOjBwws8YIVqK0zP4vHbLr6U7jeWS4VEDpNr 7djT4PPxI6zSBuJDS4sySRJlysTGIEizhW8sHdGPaSF3+ncxaQ3+h/AWBwq2K0QjjrTXtcTKzor F8MHjEwU/KLXCF/OcqeXB2AZYho9UbvD/JqEWMhaBaNvyDwLtlAzvSIreEmiL6+ctEoceLRyYzT noyJmD0ReEhLI= X-Google-Smtp-Source: ABdhPJzYeMsPcVkyPJmIS1rex449Jy0KmUcbyxlSvmlxIlwMeSu2LeS0+Ki0axWezkH5TYuf9yjCBRsdyQdWAGZmug== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:9b6a:9d1f:2f3e:45de]) (user=howardchung job=sendgmr) by 2002:aa7:85da:0:b029:329:aacc:333e with SMTP id z26-20020aa785da0000b0290329aacc333emr28163383pfn.60.1627478206780; Wed, 28 Jul 2021 06:16:46 -0700 (PDT) Date: Wed, 28 Jul 2021 21:15:29 +0800 In-Reply-To: <20210728131529.3310558-1-howardchung@google.com> Message-Id: <20210728211405.Bluez.v3.13.I433ab6a7ac1d4f8f8dea496ac14bdbf3597015d3@changeid> Mime-Version: 1.0 References: <20210728131529.3310558-1-howardchung@google.com> X-Mailer: git-send-email 2.32.0.432.gabb21c7263-goog Subject: [Bluez PATCH v3 13/13] doc: add description of admin policy From: Howard Chung To: linux-bluetooth@vger.kernel.org, luiz.dentz@gmail.com Cc: Yun-Hao Chung , Miao-chen Chou Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Yun-Hao Chung This adds admin-pocliy-api.txt. Reviewed-by: Miao-chen Chou --- (no changes since v1) doc/admin-policy-api.txt | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 doc/admin-policy-api.txt diff --git a/doc/admin-policy-api.txt b/doc/admin-policy-api.txt new file mode 100644 index 000000000..3f116901d --- /dev/null +++ b/doc/admin-policy-api.txt @@ -0,0 +1,65 @@ +BlueZ D-Bus Admin Policy API description +*********************************** + +This API provides methods to control the behavior of bluez as an administrator. + +Interface AdminPolicySet1 provides methods to set policies. Once the policy is +set successfully, it will affect all clients and stay persistently even after +restarting Bluetooth Daemon. The only way to clear it is to overwrite the +policy with the same method. + +Interface AdminPolicyStatus1 provides readonly properties to indicate the +current values of admin policy. + + +Admin Policy Set hierarchy +================= + +Service org.bluez +Interface org.bluez.AdminPolicySet1 +Object path [variable prefix]/{hci0,hci1,...} + +Methods void SetServiceAllowList(array{string} UUIDs) + + This method sets the service allowlist by specifying + service UUIDs. + + When SetServiceAllowList is called, bluez will block + incoming and outgoing connections to the service not in + UUIDs for all of the clients. + + Any subsequent calls to this method will supersede any + previously set allowlist values. Calling this method + with an empty array will allow any service UUIDs to be + used. + + The default value is an empty array. + + Possible errors: org.bluez.Error.InvalidArguments + org.bluez.Error.Failed + + +Admin Policy Status hierarchy +================= + +Service org.bluez +Interface org.bluez.AdminPolicyStatus1 +Object path [variable prefix]/{hci0,hci1,...} + +Properties array{string} ServiceAllowList [readonly] + + Current value of service allow list. + + + +Admin Policy Status hierarchy +================= + +Service org.bluez +Interface org.bluez.AdminPolicyStatus1 +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Properties bool IsAffectedByPolicy [readonly] + + Indicate if there is any auto-connect profile in this + device is not allowed by admin policy.