Add the logic for checking privilege to container 64/266864/1
authorWootak Jung <wootak.jung@samsung.com>
Thu, 18 Nov 2021 06:20:33 +0000 (15:20 +0900)
committerWootak Jung <wootak.jung@samsung.com>
Mon, 22 Nov 2021 01:30:49 +0000 (10:30 +0900)
Change-Id: Iffa438bd53b6ef0e5eee8165a5bb0f286f631898

bt-service/bluetooth-frwk-service.conf.in
bt-service/services/bt-request-handler.c
bt-service/services/bt-service-common.c
bt-service/services/bt-service-main.c
bt-service/services/include/bt-request-handler.h
bt-service/services/include/bt-service-common.h

index 20ddf7a..2913859 100644 (file)
@@ -4,16 +4,20 @@
     <policy user="root">
         <allow own="org.projectx.bt"/>
         <allow own="org.projectx.bt.mesh"/>
+        <allow own="org.projectx.bt.container"/>
         <allow send_destination="org.projectx.bt"/>
         <allow send_destination="org.projectx.bt.mesh"/>
+        <allow send_destination="org.projectx.bt.container"/>
         <allow own="org.bluez.obex"/>
         <allow send_destination="org.bluez.obex"/>
     </policy>
     <policy group="network_fw">
         <allow own="org.projectx.bt"/>
         <allow own="org.projectx.bt.mesh"/>
+        <allow own="org.projectx.bt.container"/>
         <allow send_destination="org.projectx.bt"/>
         <allow send_destination="org.projectx.bt.mesh"/>
+        <allow send_destination="org.projectx.bt.container"/>
         <allow own="org.bluez.obex"/>
         <allow send_destination="org.bluez.obex"/>
         <allow own="org.projectx.bluetooth.share"/>
@@ -31,6 +35,8 @@
         <deny send_destination="org.bluez.obex" send_type="method_call"/>
         <deny own="org.projectx.bt.mesh"/>
         <deny send_destination="org.projectx.bt.mesh" send_type="method_call"/>
+        <deny own="org.projectx.bt.container"/>
+        <deny send_destination="org.projectx.bt.container" send_type="method_call"/>
         <allow send_destination="org.projectx.bt" send_interface="org.projectx.bt"/>
         <allow send_destination="org.projectx.bt" send_interface="org.freedesktop.DBus.Properties" send_member="GetAll"/>
         <check send_destination="org.projectx.bt" send_interface="org.bluez.Agent1" privilege="http://tizen.org/privilege/bluetooth.admin"/>
index 7c54dd0..69eff8b 100644 (file)
@@ -337,6 +337,7 @@ static void __bt_service_method(GDBusConnection *connection,
                GVariant *temp = NULL;
                int result = 0;
                int request_id = -1;
+               const char *unique_name = NULL;
 
                g_variant_get(parameters, "(iii@ay@ay@ay@ay@ay)", &service_type,
                                &service_function, &request_type,
@@ -344,10 +345,22 @@ static void __bt_service_method(GDBusConnection *connection,
 
                out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+               /* In case of the bt-service in container, only privilege check request is coming
+                * from the bt-service in host. At this time, the original sender's privilege
+                * should be checked not bt-service's privilege */
+               if (_bt_service_is_container() == TRUE)
+                       unique_name = g_variant_get_data(param1);
+               else
+                       unique_name = sender;
+#else
+               unique_name = sender;
+#endif
+
                if (service_type == BT_CORE_SERVICE) {
                        BT_DBG("No need to check privilege from bt-core");
                } else if (__bt_service_check_privilege(service_function,
-                                       service_type, (const char *)sender) == FALSE) {
+                                       service_type, unique_name) == FALSE) {
                        BT_ERR("Client don't have the privilege to excute this function");
                        result = BLUETOOTH_ERROR_PERMISSION_DEINED;
                        goto fail;
@@ -5088,6 +5101,79 @@ out:
 }
 #endif
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+static gboolean __bt_service_check_privilege_in_container(int function_name,
+               const char *unique_name)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       GError *error = NULL;
+       GDBusProxy *proxy;
+       GArray *in_param1, *in_param2, *in_param3, *in_param4, *in_param5;
+       GVariant *param1, *param2, *param3, *param4, *param5, *out_param;
+
+       proxy = _bt_get_container_proxy();
+       if (proxy == NULL) {
+               BT_ERR("container proxy is NULL");
+               return FALSE;
+       }
+
+       in_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
+       in_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
+       in_param3 = g_array_new(TRUE, TRUE, sizeof(gchar));
+       in_param4 = g_array_new(TRUE, TRUE, sizeof(gchar));
+       in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
+
+       /* The sender's privilege should be checked not bt-service in container */
+       g_array_append_vals(in_param1, unique_name, strlen(unique_name));
+
+       param1 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param1->data, in_param1->len, TRUE, NULL, NULL);
+       param2 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param2->data, in_param2->len, TRUE, NULL, NULL);
+       param3 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param3->data, in_param3->len, TRUE, NULL, NULL);
+       param4 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param4->data, in_param4->len, TRUE, NULL, NULL);
+       param5 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param5->data, in_param5->len, TRUE, NULL, NULL);
+
+       BT_DBG("This request is from container. Privilege will be checked in container. unique_name: %s", unique_name);
+
+       GVariant *ret = g_dbus_proxy_call_sync(proxy, "service_request",
+                       g_variant_new("(iii@ay@ay@ay@ay@ay)",
+                                       BT_CHECK_PRIVILEGE, function_name,
+                                       BT_SYNC_REQ, param1, param2,
+                                       param3, param4, param5),
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &error);
+       if (ret == NULL) {
+               BT_ERR("dBUS-RPC is failed");
+
+               if (error != NULL) {
+                       BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                       error->code, error->message);
+                       g_clear_error(&error);
+               } else {
+                       BT_ERR("error returned was NULL");
+               }
+
+               result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               g_variant_get(ret, "(iv)", &result, &out_param);
+               g_variant_unref(out_param);
+               g_variant_unref(ret);
+       }
+
+       g_array_free(in_param1, TRUE);
+       g_array_free(in_param2, TRUE);
+       g_array_free(in_param3, TRUE);
+       g_array_free(in_param4, TRUE);
+       g_array_free(in_param5, TRUE);
+
+       return (result == BLUETOOTH_ERROR_NONE) ? TRUE : FALSE;
+}
+#endif
+
 gboolean __bt_service_check_privilege(int function_name,
                                        int service_type,
                                        const char *unique_name)
@@ -5105,11 +5191,9 @@ gboolean __bt_service_check_privilege(int function_name,
        retv_if(bt_service_conn == NULL, FALSE);
 
 #ifdef TIZEN_FEATURE_BT_CONTAINER
-       /* Privilege will be checked in container if the request is from container */
-       if (__bt_service_is_container_request(unique_name)) {
-               BT_DBG("This request is from container, temporarily allow");
-               return TRUE;
-       }
+       if (_bt_service_is_container() == FALSE)
+               if (__bt_service_is_container_request(unique_name) == TRUE)
+                       return __bt_service_check_privilege_in_container(function_name, unique_name);
 #endif
 
        ret_val = cynara_creds_get_default_client_method(&client_creds_method);
@@ -5681,6 +5765,11 @@ static void __bt_service_name_acquired_handler(GDBusConnection *connection,
 {
        BT_INFO("name acquired");
        name_acquired = TRUE;
+
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (_bt_service_is_container() == TRUE)
+               __bt_service_bus_acquired_handler(connection, name, user_data);
+#endif
 }
 
 static void __bt_service_name_lost_handler(GDBusConnection *connection,
@@ -5746,6 +5835,56 @@ fail:
        return BLUETOOTH_ERROR_INTERNAL;
 }
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+int _bt_service_register_in_container(void)
+{
+       GDBusConnection *conn;
+       GError *err = NULL;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       /* Register dbus name because systemd will down bt-service
+        * if we don't reigster the dbus name in container */
+       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+                               BT_SERVICE_NAME,
+                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                               NULL, NULL, NULL, NULL, NULL);
+       BT_DBG("owner_id is [%d]", owner_id);
+       if (owner_id == 0)
+               goto fail;
+
+       conn = g_dbus_connection_new_for_address_sync(
+                       DBUS_HOST_SYSTEM_BUS_ADDRESS,
+                       G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
+                       NULL, NULL, &err);
+       retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+       bt_service_conn = conn;
+
+       /* Register to host dbus connection to call
+        * the method toward container in host bt-service */
+       owner_id = g_bus_own_name_on_connection(conn,
+                               BT_SERVICE_CONTAINER_NAME,
+                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                               __bt_service_name_acquired_handler,
+                               __bt_service_name_lost_handler,
+                               NULL, NULL);
+       BT_DBG("owner_id is [%d]", owner_id);
+       if (owner_id == 0)
+               goto fail;
+
+       return BLUETOOTH_ERROR_NONE;
+
+fail:
+       if (bt_service_conn) {
+               g_object_unref(bt_service_conn);
+               bt_service_conn = NULL;
+       }
+
+       return BLUETOOTH_ERROR_INTERNAL;
+}
+#endif
+
 void _bt_service_unregister(void)
 {
        if (bt_service_conn) {
index 8578656..774890d 100644 (file)
@@ -51,6 +51,14 @@ static GSList *osp_server_list;
 #ifdef TIZEN_FEATURE_BT_IPSP
 static GDBusProxy *ipsp_proxy;
 #endif
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+struct container_info_t {
+       bool valid;
+       bool is_container;
+};
+struct container_info_t container_info;
+static GDBusProxy *container_proxy;
+#endif
 static GDBusConnection *system_conn;
 static GDBusConnection *session_conn;
 static GDBusProxy *manager_proxy_g;
@@ -151,6 +159,7 @@ static GDBusProxy *__bt_init_adapter_proxy(void)
 
        return proxy;
 }
+
 #ifdef TIZEN_FEATURE_BT_IPSP
 static GDBusProxy *__bt_init_ipsp_proxy(void)
 {
@@ -172,6 +181,29 @@ static GDBusProxy *__bt_init_ipsp_proxy(void)
        return proxy;
 }
 #endif
+
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+static GDBusProxy *__bt_init_container_proxy(void)
+{
+       BT_DBG("+");
+
+       GDBusConnection *g_conn;
+       GDBusProxy *proxy;
+       g_conn = _bt_gdbus_get_system_gconn();
+       retv_if(g_conn == NULL, NULL);
+       proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+                                                               NULL, BT_SERVICE_CONTAINER_NAME,
+                                                               BT_SERVICE_PATH, BT_SERVICE_NAME,  NULL, NULL);
+       if (!proxy) {
+               BT_ERR("Unable to get proxy");
+               return NULL;
+       }
+       container_proxy = proxy;
+       BT_DBG("-");
+       return proxy;
+}
+#endif
+
 static GDBusProxy *__bt_init_adapter_properties_proxy(void)
 {
        GDBusProxy *manager_proxy;
@@ -254,6 +286,7 @@ GDBusProxy *_bt_get_manager_proxy(void)
        }
        return  __bt_init_manager_proxy();
 }
+
 #ifdef TIZEN_FEATURE_BT_IPSP
 GDBusProxy *_bt_get_ipsp_proxy(void)
 {
@@ -269,6 +302,32 @@ GDBusProxy *_bt_get_ipsp_proxy(void)
 }
 #endif
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+GDBusProxy *_bt_get_container_proxy(void)
+{
+       if (container_proxy) {
+               const char *path =  g_dbus_proxy_get_object_path(container_proxy);
+               if (path == NULL) {
+                       BT_ERR("Already proxy released hence creating new proxy");
+                       return  __bt_init_container_proxy();
+               }
+               return container_proxy;
+       }
+       return  __bt_init_container_proxy();
+}
+
+gboolean _bt_service_is_container()
+{
+       if (container_info.valid)
+               return container_info.is_container;
+
+       container_info.is_container = (access(CONTAINER_FILE, F_OK) == 0) ? TRUE : FALSE;
+       BT_INFO("bt-service launched in %s", container_info.is_container ? "Container" : "Host");
+       container_info.valid = true;
+       return container_info.is_container;
+}
+#endif
+
 static void *__bt_init_net_conn(void)
 {
        int result;
index 5ce987f..0bb88a1 100644 (file)
@@ -278,7 +278,12 @@ static gboolean __bt_check_bt_service(void *data)
 
                        if ((status != BT_ACTIVATING && status != BT_ACTIVATED) &&
                                        (le_status != BT_LE_ACTIVATING && le_status != BT_LE_ACTIVATED)) {
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+                               if (_bt_service_is_container() == FALSE)
+                                       _bt_terminate_service(NULL);
+#else
                                _bt_terminate_service(NULL);
+#endif
                        }
                }
        }
@@ -298,6 +303,20 @@ int _bt_service_initialize(void)
                return EXIT_FAILURE;
        }
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (_bt_service_is_container() == TRUE) {
+               /* Only dbus initialization is required in container to check privilege */
+               ret = _bt_service_register_in_container();
+               if (ret != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to register service");
+                       return ret;
+               }
+
+               is_initialized = TRUE;
+               return BLUETOOTH_ERROR_NONE;
+       }
+#endif
+
        /* Flight mode handler */
        _bt_service_register_vconf_handler();
 
@@ -378,11 +397,6 @@ int main(void)
                return 0;
        }
 
-       if (access(CONTAINER_FILE, F_OK) == 0) {
-               BT_INFO("bt-service is not running in container");
-               return 0;
-       }
-
        memset(&sa, 0, sizeof(sa));
        sa.sa_sigaction = __bt_sigterm_handler;
        sa.sa_flags = SA_SIGINFO;
index fa3a83b..374f7dc 100755 (executable)
@@ -30,6 +30,7 @@ extern "C" {
 #endif
 
 #define BT_SERVICE_NAME "org.projectx.bt"
+#define BT_SERVICE_CONTAINER_NAME "org.projectx.bt.container"
 #define BT_SERVICE_PATH "/org/projectx/bt_service"
 
 /* Invocation information structure for API's
@@ -53,6 +54,9 @@ void _bt_free_info_from_invocation_list(invocation_info_t *req_info);
 void _bt_service_unref_connection(void);
 
 int _bt_service_register(void);
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+int _bt_service_register_in_container(void);
+#endif
 
 void _bt_service_unregister(void);
 
index ad25eb3..0060f84 100644 (file)
@@ -360,6 +360,10 @@ GDBusProxy *_bt_get_adapter_proxy(void);
 #ifdef TIZEN_FEATURE_BT_IPSP
 GDBusProxy *_bt_get_ipsp_proxy(void);
 #endif
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+gboolean _bt_service_is_container(void);
+GDBusProxy *_bt_get_container_proxy(void);
+#endif
 GDBusProxy *_bt_get_adapter_properties_proxy(void);
 
 char *_bt_get_device_object_path(char *address);