Check permission for launch and terminate requests 14/47714/5 tizen_3.0.m1_mobile tizen_3.0.m1_tv accepted/tizen/mobile/20150909.055055 accepted/tizen/mobile/20150909.140938 accepted/tizen/tv/20150909.055108 accepted/tizen/tv/20150909.140304 accepted/tizen/wearable/20150909.055121 submit/tizen/20150908.235449 submit/tizen_common/20151015.190624 submit/tizen_common/20151019.135620 submit/tizen_common/20151023.083358 submit/tizen_common/20151026.085049 submit/tizen_mobile/20150909.021024 submit/tizen_tv/20150909.021039 submit/tizen_tv/20150909.042240 tizen_3.0.m1_mobile_release tizen_3.0.m1_tv_release
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 8 Sep 2015 06:47:25 +0000 (15:47 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 8 Sep 2015 08:26:25 +0000 (17:26 +0900)
Change-Id: I9b4f3ce2b8ad41c2a5c9af7a340a530a4e420d19
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
am_daemon/amd_request.c
packaging/aul.spec

index f72f3c6..8ddbf24 100644 (file)
@@ -13,7 +13,7 @@ ENDIF (with_x11)
 
 # Set required packages
 INCLUDE(FindPkgConfig)
-SET(AUL-1_LIB_PKG_CHECK_MODULES dlog bundle dbus-glib-1 xdgmime libtzplatform-config pkgmgr-info libsystemd-daemon security-manager)
+SET(AUL-1_LIB_PKG_CHECK_MODULES dlog bundle dbus-glib-1 xdgmime libtzplatform-config pkgmgr-info libsystemd-daemon security-manager cynara-client cynara-creds-socket cynara-session)
 IF (with_wayland)
        pkg_check_modules(libpkgs REQUIRED ${AUL-1_LIB_PKG_CHECK_MODULES} wayland-client tizen-extension-client)
 ENDIF (with_wayland)
index 614161d..5b49fc4 100644 (file)
@@ -33,6 +33,9 @@
 #include <aul.h>
 #include <bundle.h>
 #include <tzplatform_config.h>
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
 
 #include "amd_config.h"
 #include "simple_util.h"
 
 #define INHOUSE_UID     tzplatform_getuid(TZ_USER_NAME)
 
+#define PRIVILEGE_APPMANAGER_LAUNCH "http://tizen.org/privilege/appmanager.launch"
+#define PRIVILEGE_APPMANAGER_KILL "http://tizen.org/privilege/appmanager.kill"
+#define PRIVILEGE_APPMANAGER_KILL_BGAPP "http://tizen.org/privilege/appmanager.kill.bgapp"
+
+static cynara *r_cynara = NULL;
+
 static int __send_result_to_client(int fd, int res);
 static gboolean __request_handler(gpointer data);
 
@@ -399,6 +408,102 @@ static void __dispatch_app_group_get_group_pids(int clifd, const app_pkt_t *pkt)
                free(pids);
 }
 
+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) {
+       case APP_OPEN:
+       case APP_RESUME:
+       case APP_START:
+       case APP_START_RES:
+               return PRIVILEGE_APPMANAGER_LAUNCH;
+       case APP_TERM_BY_PID_WITHOUT_RESTART:
+       case APP_TERM_BY_PID_ASYNC:
+       case APP_TERM_BY_PID:
+       case APP_KILL_BY_PID:
+               return PRIVILEGE_APPMANAGER_KILL;
+       case APP_TERM_BGAPP_BY_PID:
+               return PRIVILEGE_APPMANAGER_KILL_BGAPP;
+       default:
+               return NULL;
+       }
+}
+
+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 gboolean __request_handler(gpointer data)
 {
        GPollFD *gpollfd = (GPollFD *) data;
@@ -414,12 +519,25 @@ static gboolean __request_handler(gpointer data)
        bundle *kb = NULL;
        item_pkt_t *item;
        struct appinfo *ai;
+       const char *privilege;
 
        if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
                _E("recv error");
                return FALSE;
        }
 
+       privilege = __convert_cmd_to_privilege(pkt->cmd);
+       if (privilege) {
+               ret = __check_privilege_by_cynara(clifd, privilege);
+               if (ret < 0) {
+                       _E("request has been denied by smack");
+                       ret = -EILLEGALACCESS;
+                       __real_send(clifd, ret);
+                       free(pkt);
+                       return TRUE;
+               }
+       }
+
        switch (pkt->cmd) {
                case APP_OPEN:
                case APP_RESUME:
@@ -476,7 +594,6 @@ static gboolean __request_handler(gpointer data)
                        break;
                case APP_TERM_BY_PID_WITHOUT_RESTART:
                case APP_TERM_BY_PID_ASYNC:
-                       /* TODO: check caller's privilege */
                        kb = bundle_decode(pkt->data, pkt->len);
                        term_pid = (char *)bundle_get_val(kb, AUL_K_APPID);
                        appid = _status_app_get_appid_bypid(atoi(term_pid));
@@ -491,13 +608,11 @@ static gboolean __request_handler(gpointer data)
                        break;
                case APP_TERM_BY_PID:
                case APP_KILL_BY_PID:
-                       /* TODO: check caller's privilege */
                        kb = bundle_decode(pkt->data, pkt->len);
                        appid = (char *)bundle_get_val(kb, AUL_K_APPID);
                        ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
                        break;
                case APP_TERM_BGAPP_BY_PID:
-                       /* TODO: check caller's privilege */
                        kb = bundle_decode(pkt->data, pkt->len);
                        appid = (char *)bundle_get_val(kb, AUL_K_APPID);
                        ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
@@ -678,11 +793,36 @@ int _requset_init(void)
        if (fd == -1) {
                _D("Create server socket without socket activation");
                fd = __create_server_sock(AUL_UTIL_PID);
+               if (fd == -1) {
+                       _E("Create server socket failed.");
+                       return -1;
+               }
+       }
+
+       r = cynara_initialize(&r_cynara, NULL);
+       if (r != CYNARA_API_SUCCESS) {
+               _E("cynara initialize failed.");
+               close(fd);
+               return -1;
        }
 
        src = g_source_new(&funcs, sizeof(GSource));
+       if (!src) {
+               _E("out of memory");
+               cynara_finish(r_cynara);
+               close(fd);
+               return -1;
+       }
 
        gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
+       if (!gpollfd) {
+               _E("out of memory");
+               g_source_destroy(src);
+               cynara_finish(r_cynara);
+               close(fd);
+               return -1;
+       }
+
        gpollfd->events = POLLIN;
        gpollfd->fd = fd;
 
@@ -692,13 +832,13 @@ int _requset_init(void)
        g_source_set_priority(src, G_PRIORITY_DEFAULT);
 
        r = g_source_attach(src, NULL);
-       if (r  == 0)
-       {
-               /* TODO: error handle*/
+       if (r  == 0) {
+               g_free(gpollfd);
+               g_source_destroy(src);
+               cynara_finish(r_cynara);
+               close(fd);
                return -1;
        }
 
        return 0;
 }
-
-
index 3c4c2e9..4f075d1 100644 (file)
@@ -35,6 +35,9 @@ BuildRequires:  pkgconfig(pkgmgr)
 BuildRequires:  libattr-devel
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(libsystemd-daemon)
+BuildRequires:  pkgconfig(cynara-client)
+BuildRequires:  pkgconfig(cynara-creds-socket)
+BuildRequires:  pkgconfig(cynara-session)
 %if %{with wayland}
 BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(tizen-extension-client)