Check the privilege for call operation. 54/51954/7
authorJunghoon, Park <jh9216.park@samsung.com>
Thu, 19 Nov 2015 23:35:24 +0000 (08:35 +0900)
committerJunghoon, Park <jh9216.park@samsung.com>
Thu, 19 Nov 2015 23:35:24 +0000 (08:35 +0900)
Change-Id: I168e152180725a007c6942fd2724088d740105da
Signed-off-by: Junghoon, Park <jh9216.park@samsung.com>
CMakeLists.txt
am_daemon/amd_cynara.c [new file with mode: 0644]
am_daemon/amd_cynara.h [new file with mode: 0644]
am_daemon/amd_launch.c
am_daemon/amd_request.c

index bf22841..940ccc9 100644 (file)
@@ -84,6 +84,7 @@ ADD_EXECUTABLE(amd
        am_daemon/amd_launch.c
        am_daemon/amd_status.c
        am_daemon/amd_app_group.c
+       am_daemon/amd_cynara.c
        )
 TARGET_LINK_LIBRARIES(amd aul_mods aul ${pkgs_LDFLAGS})
 INSTALL(TARGETS amd DESTINATION bin)
diff --git a/am_daemon/amd_cynara.c b/am_daemon/amd_cynara.c
new file mode 100644 (file)
index 0000000..474c3bd
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <malloc.h>
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
+
+#include "simple_util.h"
+
+static cynara *r_cynara = NULL;
+
+static int _get_caller_info_from_cynara(int sockfd, char **client, char **user, char **session)
+{
+       pid_t pid;
+       int r;
+       char buf[MAX_LOCAL_BUFSZ] = {0,};
+
+       r = cynara_creds_socket_get_pid(sockfd, &pid);
+       if (r != CYNARA_API_SUCCESS) {
+               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+               _E("cynara_creds_socket_get_pid failed: %s", buf);
+               return -1;
+       }
+
+       *session = cynara_session_from_pid(pid);
+       if (*session == NULL) {
+               _E("cynara_session_from_pid failed.");
+               return -1;
+       }
+
+       r = cynara_creds_socket_get_user(sockfd, USER_METHOD_DEFAULT, user);
+       if (r != CYNARA_API_SUCCESS) {
+               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+               _E("cynara_cred_socket_get_user failed.");
+               return -1;
+       }
+
+       r = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_DEFAULT, client);
+       if (r != CYNARA_API_SUCCESS) {
+               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+               _E("cynara_creds_socket_get_client failed.");
+               return -1;
+       }
+
+       return 0;
+}
+
+int check_privilege_by_cynara(int sockfd, const char *privilege)
+{
+       int r;
+       int ret;
+       char buf[MAX_LOCAL_BUFSZ] = {0,};
+       char *client = NULL;
+       char *session = NULL;
+       char *user = NULL;
+
+       r = _get_caller_info_from_cynara(sockfd, &client, &user, &session);
+       if (r < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       r = cynara_check(r_cynara, client, session, user, privilege);
+       switch (r) {
+       case CYNARA_API_ACCESS_ALLOWED:
+               _D("%s(%s) from user %s privilege %s allowed.", client, session, user, privilege);
+               ret = 0;
+               break;
+       case CYNARA_API_ACCESS_DENIED:
+               _E("%s(%s) from user %s privilege %s denied.", client, session, user, privilege);
+               ret = -1;
+               break;
+       default:
+               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
+               _E("cynara_check failed: %s", buf);
+               ret = -1;
+               break;
+       }
+
+end:
+       if (user)
+               free(user);
+       if (session)
+               free(session);
+       if (client)
+               free(client);
+
+       return ret;
+}
+
+int init_cynara(void)
+{
+       int ret;
+
+       ret  = cynara_initialize(&r_cynara, NULL);
+       if (ret != CYNARA_API_SUCCESS) {
+               _E("cynara initialize failed.");
+               return ret;
+       }
+
+       return 0;
+}
+
+void finish_cynara(void)
+{
+       if (r_cynara)
+               cynara_finish(r_cynara);
+       r_cynara = NULL;
+}
diff --git a/am_daemon/amd_cynara.h b/am_daemon/amd_cynara.h
new file mode 100644 (file)
index 0000000..869cc95
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+int init_cynara(void);
+void finish_cynara(void);
+int check_privilege_by_cynara(int sockfd, const char *privilege);
index f238d73..2a2b946 100644 (file)
@@ -45,6 +45,9 @@
 #include "simple_util.h"
 #include "launch.h"
 #include "app_signal.h"
+#include "aul_svc.h"
+#include "aul_svc_priv_key.h"
+#include "amd_cynara.h"
 
 #define DAC_ACTIVATE
 
@@ -710,6 +713,30 @@ static void __send_mount_request(const struct appinfo *ai, const char *tep_name,
        }
 }
 
+static int __check_app_control_privilege(int fd, const char *operation)
+{
+       int ret = 0;
+
+       if (operation == NULL || fd < 0)
+               return 0;
+
+       if (!strcmp(operation, AUL_SVC_OPERATION_DOWNLOAD)) {
+               ret = check_privilege_by_cynara(fd, "http://tizen.org/privilege/download");
+               if (ret != 0) {
+                       _E("no privilege for DOWNLOAD operation");
+                       return -EILLEGALACCESS;
+               }
+       } else if (!strcmp(operation, AUL_SVC_OPERATION_CALL)) {
+               ret = check_privilege_by_cynara(fd, "http://tizen.org/privilege/call");
+               if (ret != 0) {
+                       _E("no privilege for CALL operation");
+                       return -EILLEGALACCESS;
+               }
+       }
+
+       return 0;
+}
+
 int _start_app(const char* appid, bundle* kb, int cmd, int caller_pid,
                uid_t caller_uid, int fd)
 {
@@ -723,6 +750,7 @@ int _start_app(const char* appid, bundle* kb, int cmd, int caller_pid,
        const char *component_type = NULL;
        const char *process_pool = NULL;
        const char *tep_name = NULL;
+       const char *operation = NULL;
        int pid = -1;
        char tmpbuf[MAX_PID_STR_BUFSZ];
        const char *hwacc;
@@ -780,6 +808,16 @@ int _start_app(const char* appid, bundle* kb, int cmd, int caller_pid,
        if ((ret = __compare_signature(ai, cmd, caller_uid, appid, caller_appid, fd)) != 0)
                return ret;
 
+       /* check privilege */
+       operation = bundle_get_val(kb, AUL_SVC_K_OPERATION);
+       if (operation) {
+               ret = __check_app_control_privilege(fd, operation);
+               if (ret != 0) {
+                       __real_send(fd, ret);
+                       return ret;
+               }
+       }
+
        multiple = appinfo_get_value(ai, AIT_MULTI);
        if (!multiple || strncmp(multiple, "false", 5) == 0)
                pid = _status_app_is_running(appid, caller_uid);
index b63025f..98a5305 100644 (file)
@@ -35,9 +35,6 @@
 #include <rua.h>
 #include <rua_stat.h>
 #include <tzplatform_config.h>
-#include <cynara-client.h>
-#include <cynara-creds-socket.h>
-#include <cynara-session.h>
 #include <systemd/sd-login.h>
 
 #include "amd_config.h"
@@ -49,6 +46,7 @@
 #include "amd_appinfo.h"
 #include "amd_status.h"
 #include "amd_app_group.h"
+#include "amd_cynara.h"
 
 #define INHOUSE_UID     tzplatform_getuid(TZ_USER_NAME)
 #define REGULAR_UID_MIN     5000
@@ -62,7 +60,6 @@ static GHashTable *__socket_pair_hash = NULL;
 
 typedef int (*app_cmd_dispatch_func)(int clifd, const app_pkt_t *pkt, struct ucred *cr);
 
-static cynara *r_cynara = NULL;
 
 static int __send_result_to_client(int fd, int res);
 static gboolean __request_handler(gpointer data);
@@ -927,42 +924,6 @@ static int __dispatch_amd_reload_appinfo(int clifd, const app_pkt_t *pkt, struct
        return 0;
 }
 
-static int __get_caller_info_from_cynara(int sockfd, char **client, char **user, char **session)
-{
-       pid_t pid;
-       int r;
-       char buf[MAX_LOCAL_BUFSZ] = {0,};
-
-       r = cynara_creds_socket_get_pid(sockfd, &pid);
-       if (r != CYNARA_API_SUCCESS) {
-               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
-               _E("cynara_creds_socket_get_pid failed: %s", buf);
-               return -1;
-       }
-
-       *session = cynara_session_from_pid(pid);
-       if (*session == NULL) {
-               _E("cynara_session_from_pid failed.");
-               return -1;
-       }
-
-       r = cynara_creds_socket_get_user(sockfd, USER_METHOD_DEFAULT, user);
-       if (r != CYNARA_API_SUCCESS) {
-               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
-               _E("cynara_cred_socket_get_user failed.");
-               return -1;
-       }
-
-       r = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_DEFAULT, client);
-       if (r != CYNARA_API_SUCCESS) {
-               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
-               _E("cynara_creds_socket_get_client failed.");
-               return -1;
-       }
-
-       return 0;
-}
-
 static const char *__convert_cmd_to_privilege(int cmd)
 {
        switch (cmd) {
@@ -983,46 +944,6 @@ static const char *__convert_cmd_to_privilege(int cmd)
        }
 }
 
-static int __check_privilege_by_cynara(int sockfd, const char *privilege)
-{
-       int r;
-       int ret;
-       char buf[MAX_LOCAL_BUFSZ] = {0,};
-       char *client = NULL;
-       char *session = NULL;
-       char *user = NULL;
-
-       r = __get_caller_info_from_cynara(sockfd, &client, &user, &session);
-       if (r < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       r = cynara_check(r_cynara, client, session, user, privilege);
-       switch (r) {
-       case CYNARA_API_ACCESS_ALLOWED:
-               _D("%s(%s) from user %s privilege %s allowed.", client, session, user, privilege);
-               ret = 0;
-               break;
-       case CYNARA_API_ACCESS_DENIED:
-               _E("%s(%s) from user %s privilege %s denied.", client, session, user, privilege);
-               ret = -1;
-               break;
-       default:
-               cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
-               _E("cynara_check failed: %s", buf);
-               ret = -1;
-               break;
-       }
-
-end:
-       free(user);
-       free(session);
-       free(client);
-
-       return ret;
-}
-
 static app_cmd_dispatch_func dispatch_table[APP_CMD_MAX] = {
        [APP_GET_SOCKET_PAIR] =  __dispatch_get_socket_pair,
        [APP_START] =  __dispatch_app_start,
@@ -1085,7 +1006,7 @@ static gboolean __request_handler(gpointer data)
        if (cr.uid >= REGULAR_UID_MIN) {
                privilege = __convert_cmd_to_privilege(pkt->cmd);
                if (privilege) {
-                       ret = __check_privilege_by_cynara(clifd, privilege);
+                       ret = check_privilege_by_cynara(clifd, privilege);
                        if (ret < 0) {
                                _E("request has been denied by smack");
                                ret = -EILLEGALACCESS;
@@ -1162,8 +1083,8 @@ int _request_init(void)
                }
        }
 
-       r = cynara_initialize(&r_cynara, NULL);
-       if (r != CYNARA_API_SUCCESS) {
+       r = init_cynara();
+       if (r != 0) {
                _E("cynara initialize failed.");
                close(fd);
                return -1;
@@ -1172,7 +1093,7 @@ int _request_init(void)
        src = g_source_new(&funcs, sizeof(GSource));
        if (!src) {
                _E("out of memory");
-               cynara_finish(r_cynara);
+               finish_cynara();
                close(fd);
                return -1;
        }
@@ -1181,7 +1102,7 @@ int _request_init(void)
        if (!gpollfd) {
                _E("out of memory");
                g_source_destroy(src);
-               cynara_finish(r_cynara);
+               finish_cynara();
                close(fd);
                return -1;
        }
@@ -1198,7 +1119,7 @@ int _request_init(void)
        if (r  == 0) {
                g_free(gpollfd);
                g_source_destroy(src);
-               cynara_finish(r_cynara);
+               finish_cynara();
                close(fd);
                return -1;
        }