Applied Cynara privilege check 38/61738/1 accepted/tizen/common/20160311.201349 accepted/tizen/ivi/20160311.055401 accepted/tizen/mobile/20160311.055313 accepted/tizen/tv/20160311.055324 accepted/tizen/wearable/20160311.055343 submit/tizen/20160310.082015
authorYounho Park <younho.park@samsung.com>
Thu, 10 Mar 2016 08:00:24 +0000 (17:00 +0900)
committerYounho Park <younho.park@samsung.com>
Thu, 10 Mar 2016 08:00:24 +0000 (17:00 +0900)
Change-Id: I9d4455c9cd9cbf53d7c6d1552624685376514b65
Signed-off-by: Younho Park <younho.park@samsung.com>
api/client/include/dbus/dbus_client_storage.h
api/client/src/dbus/dbus_client_storage.c
api/client/src/service_adaptor_client_storage.c
packaging/service-adaptor.spec
server/CMakeLists.txt
server/inc/dbus/dbus-server.h
server/inc/dbus/dbus-util.h
server/src/dbus/dbus-server.c
server/src/dbus/dbus-storage-adaptor.c
server/src/dbus/dbus-util.c

index f3cda1f06ef30354e1e24df38e2171496641ae2a..c21510b137eeb858d43f207c0c22339ede67db4b 100644 (file)
@@ -256,6 +256,10 @@ int _dbus_resume_file_transfer(const char *service_name,
                                                service_adaptor_error_s *error);
 
 
+int _dbus_get_privilege_check_result(const char *service_name,
+                                               const char *privilege_name,
+                                               void **server_data,
+                                               service_adaptor_error_s *error);
 
 ///////////////////// private feature
 
index 2529f808e7afedf00bf26a945d7971bd92fd9ec1..d2d50e13b957bd74328699ee082471c7cb3c9bdc 100644 (file)
@@ -1546,6 +1546,40 @@ int _dbus_resume_file_transfer(const char *service_name,
        return ret;
 }
 
+int _dbus_get_privilege_check_result(const char *service_name,
+                                               const char *privilege_name,
+                                               void **server_data,
+                                               service_adaptor_error_s *error)
+{
+       int ret = SERVICE_ADAPTOR_ERROR_NONE;
+       GError *g_error = NULL;
+       GVariant *call_result = NULL;
+
+       GDBusProxy *sac_interface_proxy = _dbus_get_sac_interface_proxy();
+
+       ipc_check_proxy(sac_interface_proxy);
+
+       if ((NULL == service_name) || (NULL == privilege_name)) {
+               error->code = SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER;
+               error->msg = strdup("Invalid Param");
+               return SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER;
+       }
+
+       GVariant *request = g_variant_new("(" private_service_adaptor_privilege_check_req_s_type ")", __safe_add_string(service_name), __safe_add_string(privilege_name));
+
+       call_result = g_dbus_proxy_call_sync(sac_interface_proxy,
+                       PRIVATE_DBUS_GET_PRIVILEGE_CHECK_RESULT_METHOD,
+                       request,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       G_MAXINT,
+                       NULL,
+                       &g_error);
+
+       ret = _ipc_get_simple_result(call_result, g_error, error);
+
+       return ret;
+}
+
 
 /******************************************************************************
                                private feature
index 27cb483ff3192b3d65247886b477d2eb237e30e5..126945816e191277a3ca6f91b7407986e1105be5 100644 (file)
@@ -542,16 +542,15 @@ int service_storage_create_upload_task(service_plugin_h plugin,
                FUNC_STOP();
                return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
        }
-/*
+
        if (CLIENT_APP_TYPE_APPLICATION == plugin->app_type) {
                int privilege_ret = 0;
-               privilege_ret = privilege_checker_check_privilege(TIZEN_PRIVILEGE_NAME_INTERNET);
-               if (PRIVILEGE_CHECKER_ERR_NONE != privilege_ret) {
+               privilege_ret = _dbus_get_privilege_check_result(plugin->service_handle_name, TIZEN_PRIVILEGE_NAME_INTERNET, NULL, &error);
+               if (SERVICE_ADAPTOR_ERROR_NONE != privilege_ret) {
                        sac_error("Privilege check error (ret : %d)", privilege_ret);
                        return SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED;
                }
        }
-*/
 
        service_storage_task_h _task = (service_storage_task_h) calloc(1, sizeof(service_storage_task_t));
        if (NULL == _task) {
@@ -615,16 +614,16 @@ int service_storage_create_download_task(service_plugin_h plugin,
                FUNC_STOP();
                return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
        }
-/*
+
        if (CLIENT_APP_TYPE_APPLICATION == plugin->app_type) {
                int privilege_ret = 0;
-               privilege_ret = privilege_checker_check_privilege(TIZEN_PRIVILEGE_NAME_INTERNET);
-               if (PRIVILEGE_CHECKER_ERR_NONE != privilege_ret) {
+               privilege_ret = _dbus_get_privilege_check_result(plugin->service_handle_name, TIZEN_PRIVILEGE_NAME_INTERNET, NULL, &error);
+               if (SERVICE_ADAPTOR_ERROR_NONE != privilege_ret) {
                        sac_error("Privilege check error (ret : %d)", privilege_ret);
                        return SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED;
                }
        }
-*/
+
        service_storage_task_h _task = (service_storage_task_h) calloc(1, sizeof(service_storage_task_t));
        if (NULL == _task) {
                ret = SERVICE_ADAPTOR_ERROR_UNKNOWN;
@@ -686,16 +685,16 @@ int service_storage_create_download_thumbnail_task(service_plugin_h plugin,
                FUNC_STOP();
                return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
        }
-/*
+
        if (CLIENT_APP_TYPE_APPLICATION == plugin->app_type) {
                int privilege_ret = 0;
-               privilege_ret = privilege_checker_check_privilege(TIZEN_PRIVILEGE_NAME_INTERNET);
-               if (PRIVILEGE_CHECKER_ERR_NONE != privilege_ret) {
+               privilege_ret = _dbus_get_privilege_check_result(plugin->service_handle_name, TIZEN_PRIVILEGE_NAME_INTERNET, NULL, &error);
+               if (SERVICE_ADAPTOR_ERROR_NONE != privilege_ret) {
                        sac_error("Privilege check error (ret : %d)", privilege_ret);
                        return SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED;
                }
        }
-*/
+
        service_storage_task_h _task = (service_storage_task_h) calloc(1, sizeof(service_storage_task_t));
        int *t_size = (int *)calloc(1, sizeof(int));
        if ((NULL == _task) || (NULL == t_size)) {
@@ -1028,16 +1027,18 @@ int service_storage_get_file_list(service_plugin_h plugin,
                FUNC_STOP();
                return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
        }
-/*
+
        if (CLIENT_APP_TYPE_APPLICATION == plugin->app_type) {
                int privilege_ret = 0;
-               privilege_ret = privilege_checker_check_privilege(TIZEN_PRIVILEGE_NAME_INTERNET);
-               if (PRIVILEGE_CHECKER_ERR_NONE != privilege_ret) {
+               service_adaptor_error_s error;
+               error.msg = NULL;
+               privilege_ret = _dbus_get_privilege_check_result(plugin->service_handle_name, TIZEN_PRIVILEGE_NAME_INTERNET, NULL, &error);
+               if (SERVICE_ADAPTOR_ERROR_NONE != privilege_ret) {
                        sac_error("Privilege check error (ret : %d)", privilege_ret);
                        return SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED;
                }
        }
-*/
+
        struct __async_wrapper_context *params = NULL;
        params = (struct __async_wrapper_context *) calloc(1, sizeof(struct __async_wrapper_context));
 
@@ -1393,16 +1394,18 @@ int service_storage_remove(service_plugin_h plugin,
                FUNC_STOP();
                return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
        }
-/*
+
        if (CLIENT_APP_TYPE_APPLICATION == plugin->app_type) {
                int privilege_ret = 0;
-               privilege_ret = privilege_checker_check_privilege(TIZEN_PRIVILEGE_NAME_INTERNET);
-               if (PRIVILEGE_CHECKER_ERR_NONE != privilege_ret) {
+               service_adaptor_error_s error;
+               error.msg = NULL;
+               privilege_ret = _dbus_get_privilege_check_result(plugin->service_handle_name, TIZEN_PRIVILEGE_NAME_INTERNET, NULL, &error);
+               if (SERVICE_ADAPTOR_ERROR_NONE != privilege_ret) {
                        sac_error("Privilege check error (ret : %d)", privilege_ret);
                        return SERVICE_ADAPTOR_ERROR_PERMISSION_DENIED;
                }
        }
-*/
+
        struct __async_wrapper_context *params = NULL;
        params = (struct __async_wrapper_context *) calloc(1, sizeof(struct __async_wrapper_context));
 
@@ -1432,6 +1435,34 @@ int service_storage_remove(service_plugin_h plugin,
 }
 
 
+int service_storage_check_privilege(service_plugin_h handle,
+                                               const char *privilege_name)
+{
+       sac_api_start();
+       int ret = SERVICE_ADAPTOR_ERROR_NONE;
+       service_adaptor_error_s error;
+       error.msg = NULL;
+
+       if (NULL == handle) {
+               FUNC_STOP();
+               return SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == handle->service_handle_name) {
+               FUNC_STOP();
+               return SERVICE_ADAPTOR_ERROR_INVALID_STATE;
+       }
+
+       ret = _dbus_get_privilege_check_result(handle->service_handle_name, privilege_name, NULL, &error);
+
+       if (SERVICE_ADAPTOR_ERROR_NONE != ret) {
+               service_adaptor_set_last_result(error.code, error.msg);
+               free(error.msg);
+       }
+
+       sac_api_end(ret);
+       return ret;
+}
 
 
 /******************************** private feature */
index d97fc3c2e3945a35fdd893bbd353cb3a7e7a3ddb..18ac63a99d1325fec29b22e6449ddd60ad261dfa 100644 (file)
@@ -21,6 +21,9 @@ BuildRequires:  pkgconfig(capi-appfw-app-manager)
 BuildRequires:  pkgconfig(capi-appfw-package-manager)
 BuildRequires:  pkgconfig(capi-appfw-service-application)
 BuildRequires:  pkgconfig(json-glib-1.0)
+BuildRequires:  pkgconfig(cynara-client)
+BuildRequires:  pkgconfig(cynara-session)
+BuildRequires:  pkgconfig(cynara-creds-gdbus)
 
 %description
 Service Adaptor Framework Library/Binary package
index 84e09c317fafe00745edf2137626f5f0a65b02c4..2d8b552e014f16d4cce3d1b339b981e817eaad94 100644 (file)
@@ -48,7 +48,21 @@ INCLUDE_DIRECTORIES(
 )
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(main_pkgs REQUIRED glib-2.0 gobject-2.0 gio-2.0 gthread-2.0 dlog bundle capi-base-common capi-appfw-application capi-appfw-app-manager capi-appfw-package-manager)
+pkg_check_modules(main_pkgs REQUIRED
+        glib-2.0
+        gobject-2.0
+        gio-2.0
+        gthread-2.0
+        dlog
+        bundle
+        capi-base-common
+        capi-appfw-application
+        capi-appfw-app-manager
+        capi-appfw-package-manager
+        cynara-client
+        cynara-session
+        cynara-creds-gdbus
+)
 
 FOREACH(flag ${main_pkgs_CFLAGS})
         SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index bf2304f92c34cf3be4de226c66219c9717c60e65..cf1101a72e0f2d8a9fbffdbef54e9a724dbfa515 100644 (file)
        "i" /* int32 file_description */ \
        ")"
 
+#define private_service_adaptor_privilege_check_req_s_type_length 2
+#define private_service_adaptor_privilege_check_req_s_type \
+       "(" \
+       "s" /* char * service_name */ \
+       "s" /* char * privilege_name */ \
+       ")"
+
 #define private_service_adaptor_file_status_res_s_type_length 3
 #define private_service_adaptor_file_status_res_s_type \
        "(" \
 #define PRIVATE_DBUS_DOWNLOAD_FILE_PUBLISH_ASYNC_METHOD                DBUS_STORAGE_ADAPTOR "_private" "_download_file_publish_async"
 #define PRIVATE_DBUS_UPLOAD_FILE_PUBLISH_METHOD                        DBUS_STORAGE_ADAPTOR "_private" "_upload_file_publish"
 #define PRIVATE_DBUS_UPLOAD_FILE_PUBLISH_ASYNC_METHOD          DBUS_STORAGE_ADAPTOR "_private" "_upload_file_publish_async"
+#define PRIVATE_DBUS_GET_PRIVILEGE_CHECK_RESULT_METHOD          DBUS_STORAGE_ADAPTOR "_private" "_get_privilege_check_result"
 
 #define PRIVATE_DBUS_REPLY_CREATE_CHATROOM_SIGNAL              DBUS_MESSAGE_ADAPTOR "_private" "_reply_create_chatroom"
 #define PRIVATE_DBUS_REPLY_CHANGE_CHATROOM_META_SIGNAL         DBUS_MESSAGE_ADAPTOR "_private" "_reply_change_chatroom_meta"
index 69b019c297a18da9988ff4c5259a5b1d29251713..6670f78b72bd0fdd76486707dfa86163aaa96c7e 100644 (file)
@@ -18,6 +18,7 @@
 #define __DBUS_UTIL_H__
 
 #include <glib.h>
+#include <gio/gio.h>
 
 #define __safe_add_string(x)   (x==NULL)?"":x
 
@@ -26,4 +27,8 @@ void safe_g_variant_builder_add_string(GVariantBuilder *builder, const char *dat
 void safe_g_variant_builder_add_array_string(GVariantBuilder *builder, const char *data);
 char *ipc_g_variant_dup_string(GVariant *string);
 
+int sa_cynara_init(void);
+void sa_cynara_deinit(void);
+int sa_cynara_check(GDBusMethodInvocation *invocation, const char *privilege);
+
 #endif /* __DBUS_UTIL_H__ */
index 7f83588290524452127ac6f0aa0b235564fb5bc7..1779b5366009acb6b68cc40fc4074369b1132629 100644 (file)
@@ -338,6 +338,11 @@ static const gchar introspection_xml[] =
 "      <arg type='t' name='error_code' direction='out'/>"
 "      <arg type='s' name='error_msg' direction='out'/>"
 "    </method>"
+"    <method name='" PRIVATE_DBUS_GET_PRIVILEGE_CHECK_RESULT_METHOD "'>"
+"      <arg type='" private_service_adaptor_privilege_check_req_s_type "' name='req' direction='in'/>"
+"      <arg type='t' name='error_code' direction='out'/>"
+"      <arg type='s' name='error_msg' direction='out'/>"
+"    </method>"
 "    <signal name='" PRIVATE_DBUS_REPLY_CREATE_CHATROOM_SIGNAL "'>"
 "      <arg type='" private_service_adaptor_create_chatroom_res_s_type "' name='res' direction='out'/>"
 "      <arg type='t' name='error_code' direction='out'/>"
@@ -913,11 +918,17 @@ int dbus_server_init()
        }
 
        service_adaptor_debug("[End] %s", __FUNCTION__);
+
+       if (SERVICE_ADAPTOR_INTERNAL_ERROR_NONE != sa_cynara_init()) {
+               return -1;
+       }
        return 0;
 }
 
 void dbus_server_deinit()
 {
+       sa_cynara_deinit();
+
        if (NULL != thread_pool) {
                g_thread_pool_free(thread_pool, TRUE, TRUE);
        }
index d6cb54b66a9609e39931757da406fba97153c160..4ec5fe292ebfa988b180ab668115a375b46fa12a 100644 (file)
@@ -243,6 +243,26 @@ GVariant *__private_create_file_status_res_type(int64_t progress_size,
        return response;
 }
 
+void __private_get_privilege_check_req_type(GVariant *parameters,
+                                               char **service_name,
+                                               char **privilege_name)
+{
+       GVariant *in_parameters = g_variant_get_child_value(parameters, 0);
+       GVariant *req_struct[private_service_adaptor_privilege_check_req_s_type_length];
+
+       for (size_t j = 0; j < private_service_adaptor_privilege_check_req_s_type_length; j++) {
+               req_struct[j] = g_variant_get_child_value(in_parameters, j);
+       }
+
+       int idx = 0;
+       *service_name   = ipc_g_variant_dup_string(req_struct[idx++]);
+       *privilege_name = ipc_g_variant_dup_string(req_struct[idx++]);
+
+       for (size_t j = 0; j < private_service_adaptor_privilege_check_req_s_type_length; j++) {
+               g_variant_unref(req_struct[j]);
+       }
+}
+
 /* public feature */
 void __get_get_root_folder_path_req_type(GVariant *parameters,
                                                char **service_name)
@@ -1786,6 +1806,49 @@ void storage_adaptor_method_call(GDBusConnection *connection,
 
                __check_error_code();
 
+               g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)",
+                               (uint64_t) error_code->code, __safe_add_string(error_code->msg)));
+
+               if (error_code != &_error) {
+                       free(error_code->msg);
+                       free(error_code);
+                       error_code = NULL;
+               } else {
+                       free(_error.msg);
+               }
+               free(service_name);
+       } else if (0 == g_strcmp0(method_name, PRIVATE_DBUS_GET_PRIVILEGE_CHECK_RESULT_METHOD)) {
+               char *service_name = NULL;
+               char *privilege_name = NULL;
+               storage_adaptor_error_code_h error_code = NULL;
+               storage_adaptor_error_code_t _error;
+               _error.msg = NULL;
+
+               __private_get_privilege_check_req_type(parameters, &service_name, &privilege_name);
+
+               service_adaptor_debug("(%s)", service_name);
+
+               service_adaptor_h service_adaptor = service_adaptor_get_handle();
+               service_adaptor_service_context_h service =
+                               service_adaptor_get_service_context(service_adaptor, service_name);
+
+               if (NULL == service) {
+                       service_adaptor_error("Can not get service context: %s", service_name);
+                       error_code = &_error;
+                       error_code->code = STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+                       error_code->msg = strdup("Can not get service context");
+
+                       g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)",
+                                       (uint64_t) error_code->code, __safe_add_string(error_code->msg)));
+
+                       free(_error.msg);
+                       free(service_name);
+                       return;
+               }
+
+               ret_code = sa_cynara_check(invocation, privilege_name);
+               __check_error_code();
+
                g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)",
                                (uint64_t) error_code->code, __safe_add_string(error_code->msg)));
 
index 91c9614d1d60686e768d3f873d979635a012e746..109c4ffdc74a8466bf91cc93abe81c49a993a97c 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <dbus-util.h>
+#include <service-adaptor.h>
+#include <service-adaptor-log.h>
+
+/* Tizen 3.0 Privilege check with Cynara [--*/
+#include <cynara-client.h>
+#include <cynara-session.h>
+#include <cynara-creds-gdbus.h>
+static cynara *_cynara;
+/* --] Tizen 3.0 Privilege check with Cynara */
 
 /**
  * Free string memory
@@ -61,3 +70,100 @@ char *ipc_g_variant_dup_string(GVariant *string)
 
        return ret;
 }
+
+
+int sa_cynara_init()
+{
+       int ret;
+       ret = cynara_initialize(&_cynara, NULL);
+
+       if (CYNARA_API_SUCCESS != ret) {
+               service_adaptor_error("cynara_initialize() Fail(%d)", ret);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+       return SERVICE_ADAPTOR_INTERNAL_ERROR_NONE;
+}
+
+void sa_cynara_deinit()
+{
+       if (_cynara)
+               cynara_finish(_cynara);
+
+       _cynara = NULL;
+}
+
+
+int sa_cynara_check(GDBusMethodInvocation *invocation, const char *privilege)
+{
+       int ret;
+       pid_t pid;
+       char *user = NULL;
+       char *client = NULL;
+       char *session = NULL;
+       const char *sender = NULL;
+       GDBusConnection *conn = NULL;
+
+       conn = g_dbus_method_invocation_get_connection(invocation);
+       if (NULL == conn) {
+               service_adaptor_error("g_dbus_method_invocation_get_connection() return NULL");
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       sender = g_dbus_method_invocation_get_sender(invocation);
+       if (NULL == sender) {
+               service_adaptor_error("g_dbus_method_invocation_get_sender() return NULL");
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       ret = cynara_creds_gdbus_get_client(conn, sender, CLIENT_METHOD_SMACK, &client);
+       if (CYNARA_API_SUCCESS != ret) {
+               service_adaptor_error("cynara_creds_dbus_get_client() Fail(%d)", ret);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       ret = cynara_creds_gdbus_get_user(conn, sender, USER_METHOD_UID, &user);
+       if (CYNARA_API_SUCCESS != ret) {
+               service_adaptor_error("cynara_creds_dbus_get_user() Fail(%d)", ret);
+               free(client);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       ret = cynara_creds_gdbus_get_pid(conn, sender, &pid);
+       if (CYNARA_API_SUCCESS != ret) {
+               service_adaptor_error("cynara_creds_gdbus_get_pid() Fail(%d)", ret);
+               free(user);
+               free(client);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       session = cynara_session_from_pid(pid);
+       if (NULL == session) {
+               service_adaptor_error("cynara_session_from_pid() return NULL");
+               free(user);
+               free(client);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       service_adaptor_debug("privilege: %s, user: %s, client: %s", privilege, user, client);
+       ret = cynara_check(_cynara, client, session, user, privilege);
+       if (CYNARA_API_ACCESS_DENIED == ret) {
+               service_adaptor_error("Denied (%s)", privilege);
+               free(session);
+               free(user);
+               free(client);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_NOT_AUTHORIZED;
+       } else if (CYNARA_API_ACCESS_ALLOWED != ret) {
+               service_adaptor_error("cynara_check(%s) Fail(%d)", privilege, ret);
+               free(session);
+               free(user);
+               free(client);
+               return SERVICE_ADAPTOR_INTERNAL_ERROR_ADAPTOR_INTERNAL;
+       }
+
+       free(session);
+       free(user);
+       free(client);
+
+       return SERVICE_ADAPTOR_INTERNAL_ERROR_NONE;
+}
+