From 3f79ba1a8c45a90f5b028c2461d9db9a6269eb7d Mon Sep 17 00:00:00 2001 From: "Junghoon, Park" Date: Fri, 20 Nov 2015 08:35:24 +0900 Subject: [PATCH] Check the privilege for call operation. Change-Id: I168e152180725a007c6942fd2724088d740105da Signed-off-by: Junghoon, Park --- CMakeLists.txt | 1 + am_daemon/amd_cynara.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ am_daemon/amd_cynara.h | 19 ++++++++ am_daemon/amd_launch.c | 38 +++++++++++++++ am_daemon/amd_request.c | 93 +++--------------------------------- 5 files changed, 188 insertions(+), 86 deletions(-) create mode 100644 am_daemon/amd_cynara.c create mode 100644 am_daemon/amd_cynara.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bf22841..940ccc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..474c3bd --- /dev/null +++ b/am_daemon/amd_cynara.c @@ -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 +#include +#include +#include + +#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 index 0000000..869cc95 --- /dev/null +++ b/am_daemon/amd_cynara.h @@ -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); diff --git a/am_daemon/amd_launch.c b/am_daemon/amd_launch.c index f238d73..2a2b946 100644 --- a/am_daemon/amd_launch.c +++ b/am_daemon/amd_launch.c @@ -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); diff --git a/am_daemon/amd_request.c b/am_daemon/amd_request.c index b63025f..98a5305 100644 --- a/am_daemon/amd_request.c +++ b/am_daemon/amd_request.c @@ -35,9 +35,6 @@ #include #include #include -#include -#include -#include #include #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; } -- 2.7.4