Set indirect request info
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 9 Apr 2018 08:16:43 +0000 (17:16 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 16 Apr 2018 06:37:56 +0000 (15:37 +0900)
While creating bundle data, the alarm-manager sets "indirect-request" info for
the amd. And then, the amd checks whether the caller has privilege or NOT
when getting the request from the alarm-manager.

Requires:
 - https://review.tizen.org/gerrit/#/c/175262/
 - https://review.tizen.org/gerrit/#/c/175212/
 - https://review.tizen.org/gerrit/#/c/175419/
 - https://review.tizen.org/gerrit/#/c/175210/

Change-Id: If53d98d0da64802e10dca2406c500a7d58a51ba6
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
alarm-manager.c

index a731664..2f35915 100644 (file)
@@ -34,6 +34,7 @@
 #include <aul.h>
 #include <aul_svc.h>
 #include <bundle.h>
+#include <bundle_internal.h>
 #include <vconf.h>
 #include <vconf-keys.h>
 #include <dlfcn.h>
@@ -164,6 +165,7 @@ void on_bus_name_owner_changed(GDBusConnection *connection, const gchar *sender_
                const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data);
 bool __get_caller_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid);
 static int __db_busyhandler(void *pData, int count);
+static notification_h __get_notification(guchar *data, int datalen);
 
 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
 static void __initialize_module_log(void);
@@ -855,6 +857,24 @@ static bool __alarm_update_due_time_of_all_items_in_list(double diff_time)
        return true;
 }
 
+static void __set_caller_info(bundle *b, int pid, uid_t uid,
+               const char *appid, const char *pkgid)
+{
+       char buf[12];
+
+       snprintf(buf, sizeof(buf), "%u", uid);
+       bundle_del(b, AUL_K_ORG_CALLER_UID);
+       bundle_add(b, AUL_K_ORG_CALLER_UID, buf);
+
+       bundle_del(b, AUL_K_ORG_CALLER_APPID);
+       bundle_add(b, AUL_K_ORG_CALLER_APPID, appid);
+
+       if (pkgid) {
+               bundle_del(b, AUL_K_ORG_CALLER_PKGID);
+               bundle_add(b, AUL_K_ORG_CALLER_PKGID, pkgid);
+       }
+}
+
 static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
                           long requested_interval, uid_t uid, int pid, char *bundle_data, int *error_code)
 {
@@ -917,6 +937,13 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
                pkgmgrinfo_appinfo_destroy_appinfo(callee_handle);
        }
 
+       if (b && caller_is_app) {
+               __set_caller_info(b, pid, uid, app_name,
+                               __alarm_info->caller_pkgid);
+               bundle_del(b, AUL_K_REQUEST_TYPE);
+               bundle_add(b, AUL_K_REQUEST_TYPE, "indirect-request");
+       }
+
        SECURE_LOGD("caller_pkgid = %s, callee_pkgid = %s",
                __alarm_info->caller_pkgid, __alarm_info->callee_pkgid);
 
@@ -1096,6 +1123,52 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
        return true;
 }
 
+static char *__create_new_noti_data(char *noti_data, pid_t pid, uid_t uid)
+{
+       GVariant *noti_gv;
+       guchar *decoded_data;
+       int decoded_datalen;
+       notification_h noti = NULL;
+       char *new_noti_data = NULL;
+       guchar* data = NULL;
+       int datalen;
+
+       decoded_data = g_base64_decode(noti_data, (gsize *)&decoded_datalen);
+       if (decoded_data == NULL)
+               return NULL;
+
+       noti = __get_notification(decoded_data, decoded_datalen);
+       if (noti == NULL)
+               goto end;
+
+       notification_set_indirect_request(noti, pid, uid);
+
+       noti_gv = notification_ipc_make_gvariant_from_noti(noti, false);
+       if (noti_gv == NULL)
+               goto end;
+
+       datalen = g_variant_get_size(noti_gv);
+       if (datalen < 0)
+               goto end;
+
+       data = malloc(datalen);
+       if (data == NULL)
+               goto end;
+
+       g_variant_store(noti_gv, data);
+       new_noti_data = g_base64_encode(data, datalen);
+
+end:
+       if (data)
+               free(data);
+       if (noti)
+               notification_free(noti);
+       if (decoded_data)
+               g_free(decoded_data);
+
+       return new_noti_data;
+}
+
 static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
                           long requested_interval, uid_t uid, int pid, char *noti_data, int *error_code)
 {
@@ -1107,6 +1180,7 @@ static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
        char *caller_pkgid = NULL;
        pkgmgrinfo_pkginfo_h caller_handle;
        bool caller_is_app = false;
+       char *new_noti_data = NULL;
 
        __alarm_info_t *__alarm_info = NULL;
 
@@ -1143,8 +1217,17 @@ static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
        SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null",
                __alarm_info->caller_pkgid);
 
-       if (noti_data)
-               __alarm_info->noti = strdup(noti_data);
+       if (noti_data) {
+               if (caller_is_app) {
+                       new_noti_data = __create_new_noti_data(noti_data, pid,
+                                       uid);
+               }
+
+               if (new_noti_data)
+                       __alarm_info->noti = new_noti_data;
+               else
+                       __alarm_info->noti = strdup(noti_data);
+       }
 
        __alarm_set_start_and_end_time(alarm_info, __alarm_info);
        memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t));
@@ -1619,31 +1702,34 @@ static int __find_login_user(uid_t *uid)
        return -1;
 }
 
-static int __post_notification(guchar *data, int datalen, uid_t uid)
+static notification_h __get_notification(guchar *data, int datalen)
 {
        int ret;
        GVariant *noti_gv = NULL;
        GVariant *body = NULL;
        notification_h noti;
 
+       if (data == NULL || datalen <= 0)
+               return NULL;
+
        noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"),
                        data, datalen, TRUE, NULL, NULL);
 
        if (noti_gv == NULL)
-               return -1;
+               return NULL;
 
        g_variant_get(noti_gv, "(v)", &body);
 
        if (body == NULL) {
                g_variant_unref(noti_gv);
-               return -1;
+               return NULL;
        }
 
        noti = notification_create(NOTIFICATION_TYPE_NOTI);
        if (noti == NULL) {
                g_variant_unref(body);
                g_variant_unref(noti_gv);
-               return -1;
+               return NULL;
        }
 
        ret = notification_ipc_make_noti_from_gvariant(noti, body);
@@ -1652,14 +1738,27 @@ static int __post_notification(guchar *data, int datalen, uid_t uid)
                g_variant_unref(body);
                g_variant_unref(noti_gv);
                notification_free(noti);
-               return -1;
+               return NULL;
        }
 
+       g_variant_unref(body);
+       g_variant_unref(noti_gv);
+
+       return noti;
+}
+
+static int __post_notification(guchar *data, int datalen, uid_t uid)
+{
+       int ret;
+       notification_h noti;
+
+       noti = __get_notification(data, datalen);
+       if (noti == NULL)
+               return -1;
+
        device_display_change_state(DISPLAY_STATE_NORMAL);
        ret = notification_post_for_uid(noti, uid);
 
-       g_variant_unref(body);
-       g_variant_unref(noti_gv);
        notification_free(noti);
 
        return ret;