From f4e1e11fe906429afadc72ddc988ae754cc952ad Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Thu, 18 Nov 2021 15:20:33 +0900 Subject: [PATCH] Add the logic for checking privilege to container Change-Id: Iffa438bd53b6ef0e5eee8165a5bb0f286f631898 --- bt-service/bluetooth-frwk-service.conf.in | 6 + bt-service/services/bt-request-handler.c | 151 ++++++++++++++++++++++- bt-service/services/bt-service-common.c | 59 +++++++++ bt-service/services/bt-service-main.c | 24 +++- bt-service/services/include/bt-request-handler.h | 4 + bt-service/services/include/bt-service-common.h | 4 + 6 files changed, 237 insertions(+), 11 deletions(-) diff --git a/bt-service/bluetooth-frwk-service.conf.in b/bt-service/bluetooth-frwk-service.conf.in index 20ddf7a..2913859 100644 --- a/bt-service/bluetooth-frwk-service.conf.in +++ b/bt-service/bluetooth-frwk-service.conf.in @@ -4,16 +4,20 @@ + + + + @@ -31,6 +35,8 @@ + + diff --git a/bt-service/services/bt-request-handler.c b/bt-service/services/bt-request-handler.c index 7c54dd0..69eff8b 100644 --- a/bt-service/services/bt-request-handler.c +++ b/bt-service/services/bt-request-handler.c @@ -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) { diff --git a/bt-service/services/bt-service-common.c b/bt-service/services/bt-service-common.c index 8578656..774890d 100644 --- a/bt-service/services/bt-service-common.c +++ b/bt-service/services/bt-service-common.c @@ -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; diff --git a/bt-service/services/bt-service-main.c b/bt-service/services/bt-service-main.c index 3f1d655..e72304be 100644 --- a/bt-service/services/bt-service-main.c +++ b/bt-service/services/bt-service-main.c @@ -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; diff --git a/bt-service/services/include/bt-request-handler.h b/bt-service/services/include/bt-request-handler.h index fa3a83b..374f7dc 100755 --- a/bt-service/services/include/bt-request-handler.h +++ b/bt-service/services/include/bt-request-handler.h @@ -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); diff --git a/bt-service/services/include/bt-service-common.h b/bt-service/services/include/bt-service-common.h index ad25eb3..0060f84 100644 --- a/bt-service/services/include/bt-service-common.h +++ b/bt-service/services/include/bt-service-common.h @@ -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); -- 2.7.4