Apply the security policy 20/37920/7 accepted/tizen/common/20150521.125353 accepted/tizen/mobile/20150420.084928 accepted/tizen/tv/20150420.084816 accepted/tizen/wearable/20150420.063510 submit/tizen_common/20150520.888882 submit/tizen_mobile/20150415.104705 submit/tizen_mobile/20150417.050528 submit/tizen_mobile/20150417.071159 submit/tizen_mobile/20150420.045515 submit/tizen_tv/20150415.104711 submit/tizen_tv/20150417.050536 submit/tizen_tv/20150417.071202 submit/tizen_tv/20150420.045531 submit/tizen_wearable/20150415.104715 submit/tizen_wearable/20150417.050541 submit/tizen_wearable/20150417.071207 submit/tizen_wearable/20150420.045539
authorDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 8 Apr 2015 10:43:52 +0000 (19:43 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 15 Apr 2015 01:46:43 +0000 (10:46 +0900)
Using cynara API we can check the client's privelege.

Change-Id: I758e4b74e181c21361aa25db504ac6a4231b972f
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
bt-api/bt-request-sender.c
bt-service/CMakeLists.txt
bt-service/bt-request-handler.c
bt-service/bt-service-main.c
bt-service/include/bt-request-handler.h
bt-service/include/bt-service-common.h
packaging/bluetooth-frwk.spec

index 78f2dd3..44fc216 100644 (file)
@@ -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;
index 6dae5f9..9e762cf 100644 (file)
@@ -65,6 +65,8 @@ SET(PKG_MODULES
        pkgmgr
 #      journal
        libprivilege-control
+       cynara-client
+       cynara-creds-dbus
 )
 
 IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_NETWORK_TETHERING_ENABLE")
index c237493..7a35ec5 100644 (file)
@@ -27,6 +27,8 @@
 #include <dbus/dbus-glib-lowlevel.h>
 #include <glib.h>
 #include <dlog.h>
+#include <cynara-client.h>
+#include <cynara-creds-dbus.h>
 
 #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;
+}
+
index 555125a..794d14d 100644 (file)
@@ -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");
index 83296dd..e29a80e 100644 (file)
@@ -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 */
index 22f5822..5715cca 100644 (file)
@@ -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
index 10037ba..e5ceac7 100644 (file)
@@ -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