From cd1801de6d85970de04d280a5b65fdb4348fbfaa Mon Sep 17 00:00:00 2001 From: DoHyun Pyun Date: Wed, 8 Apr 2015 19:43:52 +0900 Subject: [PATCH] Apply the security policy Using cynara API we can check the client's privelege. Change-Id: I758e4b74e181c21361aa25db504ac6a4231b972f Signed-off-by: DoHyun Pyun --- bt-api/bt-request-sender.c | 1 - bt-service/CMakeLists.txt | 2 + bt-service/bt-request-handler.c | 279 ++++++++++++++++++++++++++++++++ bt-service/bt-service-main.c | 8 + bt-service/include/bt-request-handler.h | 5 + bt-service/include/bt-service-common.h | 4 +- packaging/bluetooth-frwk.spec | 3 +- 7 files changed, 298 insertions(+), 4 deletions(-) diff --git a/bt-api/bt-request-sender.c b/bt-api/bt-request-sender.c index 78f2dd3..44fc216 100644 --- a/bt-api/bt-request-sender.c +++ b/bt-api/bt-request-sender.c @@ -366,7 +366,6 @@ int _bt_sync_send_request(int service_type, int service_function, GError *error = NULL; GArray *in_param5 = NULL; GArray *out_param2 = NULL; - GDBusProxy *proxy; GVariant *ret; GVariant *param1; diff --git a/bt-service/CMakeLists.txt b/bt-service/CMakeLists.txt index 6dae5f9..9e762cf 100644 --- a/bt-service/CMakeLists.txt +++ b/bt-service/CMakeLists.txt @@ -65,6 +65,8 @@ SET(PKG_MODULES pkgmgr # journal libprivilege-control + cynara-client + cynara-creds-dbus ) IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_NETWORK_TETHERING_ENABLE") diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c index c237493..7a35ec5 100644 --- a/bt-service/bt-request-handler.c +++ b/bt-service/bt-request-handler.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "bluetooth-api.h" #include "bt-service-common.h" @@ -53,6 +55,9 @@ DBusGConnection *bt_service_conn; BtService *service_object; +cynara *p_cynara; +cynara_configuration *conf; + GType bt_service_get_type(void); G_DEFINE_TYPE(BtService, bt_service, G_TYPE_OBJECT); @@ -1510,6 +1515,232 @@ static int __bt_core_request(int function_name, return result; } +gboolean __bt_service_check_privilege(int function_name, + int service_type, + const char *unique_name) +{ + int ret_val; + gboolean result = TRUE; + char *client_creds = NULL; + char *user_creds = NULL; + char *client_session = ""; + DBusConnection *conn = NULL; + int client_creds_method = CLIENT_METHOD_SMACK; + int user_creds_method = USER_METHOD_UID; + char err_msg[256] = {0, }; + + retv_if(unique_name == NULL, FALSE); + + BT_DBG("unique_name: %s", unique_name); + + if (bt_service_conn) + conn = dbus_g_connection_get_connection(bt_service_conn); + + retv_if(conn == NULL, FALSE); + + ret_val = cynara_creds_get_default_client_method(&client_creds_method); + if (ret_val != CYNARA_API_SUCCESS) { + cynara_strerror(ret_val, err_msg, sizeof(err_msg)); + BT_ERR("Fail to get default client method: %s", err_msg); + return FALSE; + } + + ret_val = cynara_creds_get_default_user_method(&user_creds_method); + if (ret_val != CYNARA_API_SUCCESS) { + cynara_strerror(ret_val, err_msg, sizeof(err_msg)); + BT_ERR("Fail to get default user method: %s", err_msg); + return FALSE; + } + + ret_val = cynara_creds_dbus_get_client(conn, unique_name, client_creds_method, &client_creds); + if (ret_val != CYNARA_API_SUCCESS) { + cynara_strerror(ret_val, err_msg, sizeof(err_msg)); + BT_ERR("Fail to get client credential: %s", err_msg); + return FALSE; + } + + BT_DBG("client_creds: %s", client_creds); + + ret_val = cynara_creds_dbus_get_user(conn, unique_name, user_creds_method, &user_creds); + if (ret_val != CYNARA_API_SUCCESS) { + cynara_strerror(ret_val, err_msg, sizeof(err_msg)); + BT_ERR("Fail to get user credential: %s", err_msg); + if (client_creds) + free(client_creds); + return FALSE; + } + + BT_DBG("user_creds: %s", user_creds); + + switch (function_name) { + case BT_SET_LOCAL_NAME: + case BT_START_DISCOVERY: + case BT_START_CUSTOM_DISCOVERY: + case BT_CANCEL_DISCOVERY: + case BT_OOB_ADD_REMOTE_DATA: + case BT_OOB_REMOVE_REMOTE_DATA: + case BT_SET_ADVERTISING: + case BT_SET_CUSTOM_ADVERTISING: + case BT_START_LE_DISCOVERY: + case BT_STOP_LE_DISCOVERY: + + case BT_BOND_DEVICE: + case BT_CANCEL_BONDING: + case BT_UNBOND_DEVICE: + case BT_SET_ALIAS: + case BT_SET_AUTHORIZATION: + case BT_UNSET_AUTHORIZATION: + case BT_SEARCH_SERVICE: + + case BT_RFCOMM_CLIENT_CONNECT: + case BT_RFCOMM_CLIENT_CANCEL_CONNECT: + case BT_RFCOMM_SOCKET_DISCONNECT: + case BT_RFCOMM_SOCKET_WRITE: + case BT_RFCOMM_CREATE_SOCKET: + case BT_RFCOMM_REMOVE_SOCKET: + + case BT_OPP_PUSH_FILES: + case BT_OPP_CANCEL_PUSH: + + case BT_OBEX_SERVER_ACCEPT_CONNECTION: + case BT_OBEX_SERVER_REJECT_CONNECTION: + case BT_OBEX_SERVER_ACCEPT_FILE: + case BT_OBEX_SERVER_REJECT_FILE: + case BT_OBEX_SERVER_SET_PATH: + case BT_OBEX_SERVER_SET_ROOT: + case BT_OBEX_SERVER_CANCEL_TRANSFER: + case BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS: + + case BT_AUDIO_CONNECT: + case BT_AUDIO_DISCONNECT: + case BT_AG_CONNECT: + case BT_AG_DISCONNECT: + case BT_AV_CONNECT: + case BT_AV_DISCONNECT: + case BT_AVRCP_CONTROL_CONNECT: + case BT_AVRCP_CONTROL_DISCONNECT: + case BT_HF_CONNECT: + case BT_HF_DISCONNECT: + + case BT_HID_CONNECT: + case BT_HID_DISCONNECT: + + case BT_CONNECT_LE: + case BT_DISCONNECT_LE: + + case BT_SET_ADVERTISING_DATA: + case BT_SET_SCAN_RESPONSE_DATA: + + case BT_HDP_CONNECT: + case BT_HDP_DISCONNECT: + case BT_HDP_SEND_DATA: + + case BT_NETWORK_ACTIVATE: + case BT_NETWORK_DEACTIVATE: + case BT_NETWORK_CONNECT: + case BT_NETWORK_DISCONNECT: + case BT_NETWORK_SERVER_DISCONNECT: + + case BT_GATT_GET_PRIMARY_SERVICES: + case BT_GATT_DISCOVER_CHARACTERISTICS: + case BT_GATT_SET_PROPERTY_REQUEST: + case BT_GATT_READ_CHARACTERISTIC: + case BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR: + ret_val = cynara_check(p_cynara, client_creds, client_session, user_creds, + BT_PRIVILEGE_PUBLIC); + + if (ret_val != CYNARA_API_ACCESS_ALLOWED) { + BT_ERR("Fail to access: %s", BT_PRIVILEGE_PUBLIC); + result = FALSE; + } + break; + + case BT_ENABLE_ADAPTER: + case BT_DISABLE_ADAPTER: + case BT_RESET_ADAPTER: + case BT_RECOVER_ADAPTER: + case BT_ENABLE_ADAPTER_LE: + case BT_DISABLE_ADAPTER_LE: + case BT_SET_CONNECTABLE: + case BT_SET_DISCOVERABLE_MODE: + case BT_ADD_WHITE_LIST: + case BT_REMOVE_WHITE_LIST: + case BT_CLEAR_WHITE_LIST: + case BT_SET_MANUFACTURER_DATA: + case BT_SET_SCAN_PARAMETERS: + + case BT_CANCEL_SEARCH_SERVICE: + case BT_ENABLE_RSSI: + + case BT_RFCOMM_ACCEPT_CONNECTION: + case BT_RFCOMM_REJECT_CONNECTION: + case BT_RFCOMM_LISTEN: + + case BT_AVRCP_SET_TRACK_INFO: + case BT_AVRCP_SET_PROPERTY: + case BT_AVRCP_SET_PROPERTIES: + case BT_AVRCP_HANDLE_CONTROL: + case BT_AVRCP_CONTROL_SET_PROPERTY: + case BT_AVRCP_CONTROL_GET_PROPERTY: + case BT_AVRCP_GET_TRACK_INFO: + + case BT_SET_CONTENT_PROTECT: + case BT_BOND_DEVICE_BY_TYPE: + case BT_SET_LE_PRIVACY: + case BT_LE_CONN_UPDATE: + ret_val = cynara_check(p_cynara, client_creds, client_session, user_creds, + BT_PRIVILEGE_PLATFORM); + + if (ret_val != CYNARA_API_ACCESS_ALLOWED) { + BT_ERR("Fail to access: %s", BT_PRIVILEGE_PLATFORM); + result = FALSE; + } + break; + + case BT_CHECK_ADAPTER: + case BT_GET_RSSI: + + case BT_GET_LOCAL_NAME: + case BT_GET_LOCAL_ADDRESS: + case BT_GET_LOCAL_VERSION: + case BT_IS_SERVICE_USED: + case BT_GET_DISCOVERABLE_MODE: + case BT_GET_DISCOVERABLE_TIME: + case BT_IS_DISCOVERYING: + case BT_IS_LE_DISCOVERYING: + case BT_IS_CONNECTABLE: + case BT_GET_BONDED_DEVICES: + case BT_GET_BONDED_DEVICE: + case BT_IS_DEVICE_CONNECTED: + case BT_GET_SPEAKER_GAIN: + case BT_SET_SPEAKER_GAIN: + case BT_OOB_READ_LOCAL_DATA: + case BT_RFCOMM_CLIENT_IS_CONNECTED: + case BT_RFCOMM_IS_UUID_AVAILABLE: + case BT_GET_ADVERTISING_DATA: + case BT_GET_SCAN_RESPONSE_DATA: + case BT_IS_ADVERTISING: + + case BT_OBEX_SERVER_ALLOCATE: + case BT_OBEX_SERVER_DEALLOCATE: + + /* Non-privilege control */ + break; + default: + BT_ERR("Unknown function!"); + result = FALSE; + break; + } + + if (client_creds) + free(client_creds); + + if (user_creds) + free(user_creds); + + return result; +} + gboolean bt_service_request( BtService *service, int service_type, @@ -1528,12 +1759,21 @@ gboolean bt_service_request( int request_id = -1; GArray *out_param1 = NULL; GArray *out_param2 = NULL; + char *sender = NULL; out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar)); out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar)); + sender = dbus_g_method_get_sender(context); + 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) { + BT_ERR("Client don't have the privilege to excute this function"); + + result = BLUETOOTH_ERROR_PERMISSION_DEINED; + goto fail; } if (request_type == BT_ASYNC_REQ @@ -1603,6 +1843,7 @@ gboolean bt_service_request( g_array_free(out_param1, TRUE); g_array_free(out_param2, TRUE); + g_free(sender); return TRUE; fail: @@ -1612,6 +1853,7 @@ fail: g_array_free(out_param1, TRUE); g_array_free(out_param2, TRUE); + g_free(sender); if (request_type == BT_ASYNC_REQ) _bt_delete_request_id(request_id); @@ -1693,3 +1935,40 @@ void _bt_service_unregister(void) } } +int _bt_service_cynara_init(void) +{ + int result; + char err_msg[256] = {0, }; + + retv_if(p_cynara != NULL, BLUETOOTH_ERROR_ALREADY_INITIALIZED); + + result = cynara_initialize(&p_cynara, conf); + + if (result != CYNARA_API_SUCCESS) { + cynara_strerror(result, err_msg, sizeof(err_msg)); + BT_ERR("Fail to initialize cynara: [%s]", err_msg); + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + +void _bt_service_cynara_deinit(void) +{ + int result; + char err_msg[256] = {0, }; + + ret_if(p_cynara == NULL); + + result = cynara_finish(p_cynara); + + if (result != CYNARA_API_SUCCESS) { + cynara_strerror(result, err_msg, sizeof(err_msg)); + BT_ERR("Fail to finish cynara: [%s]", err_msg); + return; + } + + p_cynara = NULL; + conf = NULL; +} + diff --git a/bt-service/bt-service-main.c b/bt-service/bt-service-main.c index 555125a..794d14d 100644 --- a/bt-service/bt-service-main.c +++ b/bt-service/bt-service-main.c @@ -52,6 +52,8 @@ static void __bt_release_service(void) _bt_clear_request_list(); + _bt_service_cynara_deinit(); + BT_DBG("Terminating the bt-service daemon"); } @@ -211,6 +213,12 @@ int main(void) g_type_init(); + /* Security Initialization */ + if (_bt_service_cynara_init() != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to init cynara"); + return EXIT_FAILURE; + } + /* Event reciever Init */ if (_bt_init_service_event_receiver() != BLUETOOTH_ERROR_NONE) { BT_ERR("Fail to init event reciever"); diff --git a/bt-service/include/bt-request-handler.h b/bt-service/include/bt-request-handler.h index 83296dd..e29a80e 100644 --- a/bt-service/include/bt-request-handler.h +++ b/bt-service/include/bt-request-handler.h @@ -67,6 +67,11 @@ int _bt_service_register(void); void _bt_service_unregister(void); +int _bt_service_cynara_init(void); + +void _bt_service_cynara_deinit(void); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bt-service/include/bt-service-common.h b/bt-service/include/bt-service-common.h index 22f5822..5715cca 100644 --- a/bt-service/include/bt-service-common.h +++ b/bt-service/include/bt-service-common.h @@ -226,8 +226,8 @@ extern "C" { #define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb" /* Privilege */ -#define BT_PRIVILEGE_PUBLIC "bt-service::public" -#define BT_PRIVILEGE_PLATFORM "bt-service::platform" +#define BT_PRIVILEGE_PUBLIC "http://tizen.org/privilege/bluetooth" +#define BT_PRIVILEGE_PLATFORM "http://tizen.org/privilege/bluetooth.admin" /* BD Address type */ #define BDADDR_BREDR 0x00 diff --git a/packaging/bluetooth-frwk.spec b/packaging/bluetooth-frwk.spec index 10037ba..e5ceac7 100644 --- a/packaging/bluetooth-frwk.spec +++ b/packaging/bluetooth-frwk.spec @@ -47,9 +47,10 @@ BuildRequires: pkgconfig(capi-content-mime-type) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(pkgmgr) #BuildRequires: pkgconfig(journal) - BuildRequires: cmake BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(cynara-client) +BuildRequires: pkgconfig(cynara-creds-dbus) Requires(post): /usr/bin/vconftool Requires(post): /sbin/ldconfig -- 2.7.4