55bfd117dd136142c192658393586cbcbf54411d
[platform/core/appfw/aul-1.git] / am_daemon / amd_request.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <dlfcn.h>
29 #include <poll.h>
30
31 #include <glib.h>
32
33 #include <aul.h>
34 #include <bundle.h>
35 #include <rua.h>
36 #include <tzplatform_config.h>
37 #include <cynara-client.h>
38 #include <cynara-creds-socket.h>
39 #include <cynara-session.h>
40 #include <systemd/sd-login.h>
41
42 #include "amd_config.h"
43 #include "simple_util.h"
44 #include "app_sock.h"
45 #include "aul_util.h"
46 #include "amd_request.h"
47 #include "amd_launch.h"
48 #include "amd_appinfo.h"
49 #include "amd_status.h"
50 #include "amd_app_group.h"
51
52 #define INHOUSE_UID     tzplatform_getuid(TZ_USER_NAME)
53 #define REGULAR_UID_MIN     5000
54
55 #define PRIVILEGE_APPMANAGER_LAUNCH "http://tizen.org/privilege/appmanager.launch"
56 #define PRIVILEGE_APPMANAGER_KILL "http://tizen.org/privilege/appmanager.kill"
57 #define PRIVILEGE_APPMANAGER_KILL_BGAPP "http://tizen.org/privilege/appmanager.kill.bgapp"
58
59 #define MAX_NR_OF_DESCRIPTORS 2
60 static GHashTable *__socket_pair_hash = NULL;
61
62 typedef int (*app_cmd_dispatch_func)(int clifd, const app_pkt_t *pkt, struct ucred *cr);
63
64 static cynara *r_cynara = NULL;
65
66 static int __send_result_to_client(int fd, int res);
67 static gboolean __request_handler(gpointer data);
68
69 static int __send_message(int sock, const struct iovec *vec, int vec_size, const int *desc, int nr_desc)
70 {
71         struct msghdr msg = {0};
72         int sndret;
73
74         if (vec == NULL || vec_size < 1)
75                 return -EINVAL;
76         if (nr_desc < 0 || nr_desc > MAX_NR_OF_DESCRIPTORS)
77                 return -EINVAL;
78         if (desc == NULL)
79                 nr_desc = 0;
80
81         msg.msg_iov = (struct iovec *)vec;
82         msg.msg_iovlen = vec_size;
83
84         /* sending ancillary data */
85         if (nr_desc > 0) {
86                 int desclen = 0;
87                 struct cmsghdr *cmsg = NULL;
88                 char buff[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)] = {0};
89
90                 msg.msg_control = buff;
91                 msg.msg_controllen = sizeof(buff);
92                 cmsg = CMSG_FIRSTHDR(&msg);
93                 if (cmsg == NULL)
94                         return -EINVAL;
95
96                 /* packing files descriptors */
97                 if (nr_desc > 0) {
98                         cmsg->cmsg_level = SOL_SOCKET;
99                         cmsg->cmsg_type = SCM_RIGHTS;
100                         desclen = cmsg->cmsg_len = CMSG_LEN(sizeof(int) * nr_desc);
101                         memcpy((int *)CMSG_DATA(cmsg), desc, sizeof(int) * nr_desc);
102                         cmsg = CMSG_NXTHDR(&msg, cmsg);
103
104                         _D("packing file descriptors done");
105                 }
106
107                 /* finished packing updating the corect length */
108                 msg.msg_controllen = desclen;
109         } else {
110                 msg.msg_control = NULL;
111                 msg.msg_controllen = 0;
112         }
113
114         sndret = sendmsg(sock, &msg, 0);
115
116         _D("sendmsg ret : %d", sndret);
117         if (sndret < 0)
118                 return -errno;
119         else
120                 return sndret;
121 }
122
123 static int __send_result_data(int fd, int cmd, unsigned char *kb_data, int datalen)
124 {
125         int len;
126         int sent = 0;
127         int res = 0;
128         app_pkt_t *pkt = NULL;
129
130         pkt = (app_pkt_t *)malloc(AUL_PKT_HEADER_SIZE + datalen);
131         if (NULL == pkt) {
132                 _E("Malloc Failed!");
133                 return -ENOMEM;
134         }
135
136         pkt->cmd = cmd;
137         pkt->len = datalen;
138         memcpy(pkt->data, kb_data, datalen);
139
140         while (sent != AUL_PKT_HEADER_SIZE + datalen) {
141                 len = send(fd, pkt, AUL_PKT_HEADER_SIZE + datalen - sent, 0);
142                 if (len <= 0) {
143                         _E("send error fd:%d (errno %d)", fd, errno);
144                         close(fd);
145                         free(pkt);
146                         return -ECOMM;
147                 }
148                 sent += len;
149         }
150
151         free(pkt);
152         close(fd);
153
154         return res;
155 }
156
157 extern int __app_dead_handler(int pid, uid_t user);
158 extern int __agent_dead_handler(uid_t user);
159
160 static int __send_result_to_client(int fd, int res)
161 {
162         if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
163                 if (errno == EPIPE)
164                         _E("send failed due to EPIPE.\n");
165                 _E("send fail to client");
166         }
167         close(fd);
168         return 0;
169 }
170
171 static void __real_send(int clifd, int ret)
172 {
173         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
174                 if (errno == EPIPE)
175                         _E("send failed due to EPIPE.\n");
176
177                 _E("send fail to client");
178         }
179
180         close(clifd);
181 }
182
183 static int __get_caller_pid(bundle *kb)
184 {
185         const char *pid_str;
186         int pid;
187
188         pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
189         if (pid_str)
190                 goto end;
191
192         pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
193         if (pid_str == NULL)
194                 return -1;
195
196 end:
197         pid = atoi(pid_str);
198         if (pid <= 1)
199                 return -1;
200
201         return pid;
202 }
203
204 static int __foward_cmd(int cmd, bundle *kb, int cr_pid)
205 {
206         int pid;
207         int pgid;
208         char tmp_pid[MAX_PID_STR_BUFSZ];
209         int datalen;
210         bundle_raw *kb_data;
211         int res;
212
213         if ((pid = __get_caller_pid(kb)) < 0)
214                         return AUL_R_ERROR;
215
216         pgid = getpgid(cr_pid);
217         if (pgid > 0) {
218                 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pgid);
219                 bundle_del(kb, AUL_K_CALLEE_PID);
220                 bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
221         }
222
223         bundle_encode(kb, &kb_data, &datalen);
224         if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
225                 res = AUL_R_ERROR;
226
227         free(kb_data);
228
229         return res;
230 }
231
232 static int __app_process_by_pid(int cmd,
233         const char *pkg_name, struct ucred *cr, int clifd)
234 {
235         int pid;
236         int ret;
237         int dummy;
238         char *appid;
239
240         if (pkg_name == NULL)
241                 return -1;
242
243         pid = atoi(pkg_name);
244         if (pid <= 1) {
245                 _E("invalid pid");
246                 return -1;
247         }
248
249         appid = _status_app_get_appid_bypid(pid);
250         if (appid == NULL) {
251                 _E("pid %d is not an app", pid);
252                 __real_send(clifd, -1);
253                 return -1;
254         }
255
256         switch (cmd) {
257         case APP_RESUME_BY_PID:
258                 ret = _resume_app(pid, clifd);
259                 break;
260         case APP_TERM_BY_PID:
261         case APP_TERM_BY_PID_WITHOUT_RESTART:
262                 ret = _term_app(pid, clifd);
263                 break;
264         case APP_TERM_BGAPP_BY_PID:
265                 ret = _term_bgapp(pid, clifd);
266                 break;
267         case APP_KILL_BY_PID:
268                 if ((ret = _send_to_sigkill(pid)) < 0)
269                         _E("fail to killing - %d\n", pid);
270                 __real_send(clifd, ret);
271                 break;
272         case APP_TERM_REQ_BY_PID:
273                 ret = _term_req_app(pid, clifd);
274                 break;
275         case APP_TERM_BY_PID_ASYNC:
276                 if ((ret = __app_send_raw_with_noreply(pid, cmd, (unsigned char *)&dummy, sizeof(int))) < 0)
277                         _D("terminate req packet send error");
278
279                 __real_send(clifd, ret);
280                 break;
281         case APP_PAUSE_BY_PID:
282                 ret = _pause_app(pid, clifd);
283                 break;
284         default:
285                 _E("unknown command: %d", cmd);
286                 ret = -1;
287         }
288
289         return ret;
290 }
291
292
293 static gboolean __add_history_handler(gpointer user_data)
294 {
295         struct rua_rec rec;
296         int ret;
297         char *app_path = NULL;
298         struct appinfo *ai;
299
300         rua_stat_pkt_t *pkt = (rua_stat_pkt_t *)user_data;
301
302         if (!pkt)
303                 return FALSE;
304
305         if (!pkt->is_group_app) {
306
307                 ai = (struct appinfo *)appinfo_find(pkt->uid, pkt->appid);;
308                 app_path = (char *)appinfo_get_value(ai, AIT_EXEC);
309
310                 memset((void *)&rec, 0, sizeof(rec));
311
312                 rec.pkg_name = pkt->appid;
313                 rec.app_path = app_path;
314
315                 if(pkt->len > 0)
316                         rec.arg = pkt->data;
317
318                 SECURE_LOGD("add rua history %s %s", rec.pkg_name, rec.app_path);
319
320                 ret = rua_add_history(&rec);
321                 if (ret == -1)
322                         _D("rua add history error");
323         }
324
325         if (pkt->stat_caller != NULL && pkt->stat_tag != NULL) {
326                 SECURE_LOGD("rua_stat_caller: %s, rua_stat_tag: %s", pkt->stat_caller, pkt->stat_tag);
327                 rua_stat_update(pkt->stat_caller, pkt->stat_tag);
328         }
329         if (pkt) {
330                 if (pkt->data)
331                         free(pkt->data);
332                 if (pkt->stat_caller)
333                         free(pkt->stat_caller);
334                 if (pkt->stat_tag)
335                         free(pkt->stat_tag);
336                 free(pkt);
337         }
338
339         return FALSE;
340 }
341
342
343 static int __release_srv(uid_t caller_uid, const char *appid)
344 {
345         int r;
346         const struct appinfo *ai;
347
348         ai = (struct appinfo *)appinfo_find(caller_uid, appid);
349         if (!ai) {
350                 SECURE_LOGE("release service: '%s' not found", appid);
351                 return -1;
352         }
353
354         r = appinfo_get_boolean(ai, AIT_RESTART);
355         if (r == 1) {
356                 /* Auto restart */
357                 SECURE_LOGD("Auto restart set: '%s'", appid);
358                 return _start_app_local(caller_uid, appid);
359         }
360
361         return 0;
362 }
363
364 static void __handle_agent_dead_signal(struct ucred *pcr)
365 {
366         /* TODO: check the credentials from the caller: must be the amd agent */
367
368         _D("AGENT_DEAD_SIGNAL : %d", pcr->uid);
369         __agent_dead_handler(pcr->uid);
370 }
371
372 static int __dispatch_get_socket_pair(int clifd, const app_pkt_t *pkt, struct ucred *cr)
373 {
374         char *caller;
375         char *callee;
376         char *socket_pair_key;
377         int socket_pair_key_len;
378         int *handles = NULL;
379         struct iovec vec[3];
380         int msglen = 0;
381         char buffer[1024];
382         struct sockaddr_un saddr;
383         char *datacontrol_type;
384         bundle *kb;
385
386         kb = bundle_decode(pkt->data, pkt->len);
387         caller = (char *)bundle_get_val(kb, AUL_K_CALLER_APPID);
388         callee = (char *)bundle_get_val(kb, AUL_K_CALLEE_APPID);
389         datacontrol_type = (char *)bundle_get_val(kb, "DATA_CONTOL_TYPE");
390
391         socket_pair_key_len = strlen(caller) + strlen(callee) + 2;
392
393         socket_pair_key = (char *)calloc(socket_pair_key_len, sizeof(char));
394         if (socket_pair_key == NULL) {
395                 _E("calloc fail");
396                 goto err_out;
397         }
398
399         snprintf(socket_pair_key, socket_pair_key_len, "%s_%s", caller, callee);
400         _E("socket pair key : %s", socket_pair_key);
401
402         handles = g_hash_table_lookup(__socket_pair_hash, socket_pair_key);
403         if (handles == NULL) {
404                 handles = (int *)calloc(2, sizeof(int));
405                 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) {
406                         _E("error create socket pair");
407                         __send_result_to_client(clifd, -1);
408                         goto err_out;
409                 }
410
411                 if (handles[0] == -1) {
412                         _E("error socket open");
413                         __send_result_to_client(clifd, -1);
414                         goto err_out;
415                 }
416                 g_hash_table_insert(__socket_pair_hash, strdup(socket_pair_key),
417                                 handles);
418
419                 _E("New socket pair insert done.");
420         }
421
422
423         memset(&saddr, 0, sizeof(saddr));
424         saddr.sun_family = AF_UNIX;
425
426         SECURE_LOGD("amd send fd : [%d, %d]", handles[0], handles[1]);
427         vec[0].iov_base = buffer;
428         vec[0].iov_len = strlen(buffer) + 1;
429
430         if (datacontrol_type != NULL) {
431                 _E("datacontrol_type : %s", datacontrol_type);
432                 if (strcmp(datacontrol_type, "consumer") == 0) {
433                         msglen = __send_message(clifd, vec, 1, &handles[0], 1);
434                         if (msglen < 0) {
435                                 _E("Error[%d]: while sending message\n", -msglen);
436                                 __send_result_to_client(clifd, -1);
437                                 goto err_out;
438                         }
439                         close(handles[0]);
440                         handles[0] = -1;
441                         if (handles[1] == -1) {
442                                 _E("remove from hash : %s", socket_pair_key);
443                                 g_hash_table_remove(__socket_pair_hash, socket_pair_key);
444                         }
445
446                 } else {
447                         msglen = __send_message(clifd, vec, 1, &handles[1], 1);
448                         if (msglen < 0) {
449                                 _E("Error[%d]: while sending message\n", -msglen);
450                                 __send_result_to_client(clifd, -1);
451                                 goto err_out;
452                         }
453                         close(handles[1]);
454                         handles[1] = -1;
455                         if (handles[0] == -1) {
456                                 _E("remove from hash : %s", socket_pair_key);
457                                 g_hash_table_remove(__socket_pair_hash, socket_pair_key);
458                         }
459                 }
460         }
461         SECURE_LOGD("send_message msglen : [%d]\n", msglen);
462
463         return 0;
464
465 err_out:
466         if (handles)
467                 free(handles);
468         if (socket_pair_key)
469                 free(socket_pair_key);
470
471         return -1;
472 }
473
474 static int __dispatch_app_group_get_window(int clifd, const app_pkt_t *pkt, struct ucred *cr)
475 {
476         bundle *b;
477         char *buf;
478         int pid;
479         int wid;
480
481         b = bundle_decode(pkt->data, pkt->len);
482         bundle_get_str(b, AUL_K_PID, &buf);
483         pid = atoi(buf);
484         bundle_free(b);
485         wid = app_group_get_window(pid);
486         __send_result_to_client(clifd, wid);
487
488         return 0;
489 }
490
491 static int __dispatch_app_group_set_window(int clifd, const app_pkt_t *pkt, struct ucred *cr)
492 {
493         bundle *b;
494         char *buf;
495         int wid;
496         int ret;
497
498         b = bundle_decode(pkt->data, pkt->len);
499         bundle_get_str(b, AUL_K_WID, &buf);
500         wid = atoi(buf);
501         bundle_free(b);
502         ret = app_group_set_window(cr->pid, wid);
503         __send_result_to_client(clifd, ret);
504
505         return ret;
506 }
507
508 static int __dispatch_app_group_get_fg_flag(int clifd, const app_pkt_t *pkt, struct ucred *cr)
509 {
510         bundle *b;
511         char *buf;
512         int pid;
513         int fg;
514
515         b = bundle_decode(pkt->data, pkt->len);
516         bundle_get_str(b, AUL_K_PID, &buf);
517         pid = atoi(buf);
518         bundle_free(b);
519         fg = app_group_get_fg_flag(pid);
520         __send_result_to_client(clifd, fg);
521
522         return 0;
523 }
524
525 static int __dispatch_app_group_clear_top(int clifd, const app_pkt_t *pkt, struct ucred *cr)
526 {
527         app_group_clear_top(cr->pid);
528         __send_result_to_client(clifd, 0);
529
530         return 0;
531 }
532
533 static int __dispatch_app_group_get_leader_pid(int clifd,
534                 const app_pkt_t *pkt, struct ucred *cr)
535 {
536         bundle *b;
537         char *buf;
538         int pid;
539         int lpid;
540
541         b = bundle_decode(pkt->data, pkt->len);
542         bundle_get_str(b, AUL_K_PID, &buf);
543         pid = atoi(buf);
544         bundle_free(b);
545         lpid = app_group_get_leader_pid(pid);
546         __send_result_to_client(clifd, lpid);
547
548         return 0;
549 }
550
551 static int __dispatch_app_group_get_leader_pids(int clifd,
552                 const app_pkt_t *pkt, struct ucred *cr)
553 {
554         int cnt;
555         int *pids;
556         unsigned char empty[1] = { 0 };
557
558         app_group_get_leader_pids(&cnt, &pids);
559
560         if (pids == NULL || cnt == 0) {
561                 __send_result_data(clifd, APP_GROUP_GET_LEADER_PIDS, empty, 0);
562         } else {
563                 __send_result_data(clifd, APP_GROUP_GET_LEADER_PIDS,
564                         (unsigned char *)pids, cnt * sizeof(int));
565         }
566         if (pids != NULL)
567                 free(pids);
568
569         return 0;
570 }
571
572 static int __dispatch_app_group_get_idle_pids(int clifd,
573                 const app_pkt_t *pkt, struct ucred *cr)
574 {
575         int cnt;
576         int *pids;
577         unsigned char empty[1] = { 0 };
578
579         app_group_get_idle_pids(&cnt, &pids);
580
581         if (pids == NULL || cnt == 0) {
582                 __send_result_data(clifd, APP_GROUP_GET_IDLE_PIDS, empty, 0);
583         } else {
584                 __send_result_data(clifd, APP_GROUP_GET_IDLE_PIDS,
585                         (unsigned char *)pids, cnt * sizeof(int));
586         }
587         if (pids != NULL)
588                 free(pids);
589
590         return 0;
591 }
592
593 static int __dispatch_app_group_get_group_pids(int clifd, const app_pkt_t *pkt, struct ucred *cr)
594 {
595         bundle *b;
596         char *buf;
597         int leader_pid;
598         int cnt;
599         int *pids;
600         unsigned char empty[1] = { 0 };
601
602         b = bundle_decode(pkt->data, pkt->len);
603         bundle_get_str(b, AUL_K_LEADER_PID, &buf);
604         leader_pid = atoi(buf);
605         bundle_free(b);
606
607         app_group_get_group_pids(leader_pid, &cnt, &pids);
608         if (pids == NULL || cnt == 0) {
609                 __send_result_data(clifd, APP_GROUP_GET_GROUP_PIDS, empty, 0);
610         } else {
611                 __send_result_data(clifd, APP_GROUP_GET_GROUP_PIDS,
612                         (unsigned char *)pids, cnt * sizeof(int));
613         }
614         if (pids != NULL)
615                 free(pids);
616
617         return 0;
618 }
619
620 static int __dispatch_app_group_lower(int clifd, const app_pkt_t *pkt, struct ucred *cr)
621 {
622         int ret = 0;
623
624         app_group_lower(cr->pid, &ret);
625         __send_result_to_client(clifd, ret);
626
627         return ret;
628 }
629
630 static int __dispatch_app_start(int clifd, const app_pkt_t *pkt, struct ucred *cr)
631 {
632         const char *appid;
633         const char *target_uid;
634         bundle *kb;
635         int ret = -1;
636         int t_uid;
637         char *state;
638         item_pkt_t *item = NULL;
639         char *stat_caller = NULL;
640         char *stat_tag = NULL;
641         rua_stat_pkt_t *rua_stat_item = NULL;
642
643         kb = bundle_decode(pkt->data, pkt->len);
644         if (kb == NULL) {
645                 close(clifd);
646                 return -1;
647         }
648
649         appid = bundle_get_val(kb, AUL_K_APPID);
650         if (cr->uid < REGULAR_UID_MIN) {
651                 target_uid = bundle_get_val(kb, AUL_K_TARGET_UID);
652                 if (target_uid != NULL) {
653                         t_uid = atoi(target_uid);
654                         sd_uid_get_state(t_uid, &state);
655                         if (strcmp(state, "offline") &&
656                             strcmp(state, "closing")) {
657                                 ret = _start_app(appid, kb, pkt->cmd, cr->pid,
658                                                 t_uid, clifd);
659                         } else {
660                                 _E("uid:%d session is %s", t_uid, state);
661                                 __real_send(clifd, AUL_R_ERROR);
662                                 goto error;
663                         }
664                 } else {
665                         _E("request from root, treat as global user");
666                         ret = _start_app(appid, kb, pkt->cmd, cr->pid,
667                                         GLOBAL_USER, clifd);
668                 }
669         } else {
670                 ret = _start_app(appid, kb, pkt->cmd, cr->pid, cr->uid, clifd);
671         }
672         if (ret > 0) {
673                 item = calloc(1, sizeof(item_pkt_t));
674                 if (item == NULL) {
675                         _E("out of memory");
676                         goto error;
677                 }
678                 item->pid = ret;
679                 item->uid = cr->uid;
680                 strncpy(item->appid, appid, 511);
681
682                 g_timeout_add(1200, __add_item_running_list, item);
683
684                 rua_stat_item = calloc(1, sizeof(rua_stat_pkt_t));
685                 if (rua_stat_item == NULL) {
686                         _E("out of memory");
687                         goto error;
688                 }
689
690                 if (pkt->len > 0) {
691                         rua_stat_item->data = (char *)calloc(pkt->len, sizeof(char));
692                         if (rua_stat_item->data == NULL) {
693                                 _E("out of memory");
694                                 goto error;
695                         }
696                         memcpy(rua_stat_item->data, pkt->data, pkt->len);
697                 }
698                 stat_caller = (char *)bundle_get_val(kb, AUL_SVC_K_RUA_STAT_CALLER);
699                 stat_tag = (char *)bundle_get_val(kb, AUL_SVC_K_RUA_STAT_TAG);
700
701                 rua_stat_item->len = pkt->len;
702                 if (stat_caller != NULL) {
703                         rua_stat_item->stat_caller = strdup(stat_caller);
704                         if (rua_stat_item->stat_caller == NULL) {
705                                 _E("Out of memory");
706                                 goto error;
707                         }
708                 }
709
710                 if (stat_tag != NULL) {
711                         rua_stat_item->stat_tag = strdup(stat_tag);
712                         if (rua_stat_item->stat_tag == NULL) {
713                                 _E("Out of memory");
714                                 goto error;
715                         }
716
717                 }
718                 rua_stat_item->uid = cr->uid;
719                 rua_stat_item->is_group_app = app_group_is_group_app(kb);
720                 strncpy(rua_stat_item->appid, appid, 511);
721
722                 g_timeout_add(1500, __add_history_handler, rua_stat_item);
723         }
724         bundle_free(kb);
725         return 0;
726
727 error:
728         if (kb)
729                 bundle_free(kb);
730         if (item)
731                 free(item);
732         if (rua_stat_item) {
733                 if (rua_stat_item->data)
734                         free(rua_stat_item->data);
735                 if (rua_stat_item->stat_caller)
736                         free(rua_stat_item->stat_caller);
737                 if (rua_stat_item->stat_tag)
738                         free(rua_stat_item->stat_tag);
739                 free(rua_stat_item);
740         }
741         return -1;
742 }
743
744 static int __dispatch_app_result(int clifd, const app_pkt_t *pkt, struct ucred *cr)
745 {
746         bundle *kb;
747
748         kb = bundle_decode(pkt->data, pkt->len);
749         if (kb == NULL) {
750                 close(clifd);
751                 return -1;
752         }
753
754         __foward_cmd(pkt->cmd, kb, cr->pid);
755         close(clifd);
756         bundle_free(kb);
757
758         return 0;
759 }
760
761 static int __dispatch_app_pause(int clifd, const app_pkt_t *pkt, struct ucred *cr)
762 {
763         char *appid;
764         bundle *kb;
765         int ret;
766
767         kb = bundle_decode(pkt->data, pkt->len);
768         if (kb == NULL) {
769                 close(clifd);
770                 return -1;
771         }
772
773         appid = (char *)bundle_get_val(kb, AUL_K_APPID);
774         ret = _status_app_is_running_v2(appid, cr->uid);
775         if (ret > 0) {
776                 ret = _pause_app(ret, clifd);
777         } else {
778                 _E("%s is not running", appid);
779                 close(clifd);
780         }
781         bundle_free(kb);
782
783         return 0;
784 }
785
786 static int __dispatch_app_process_by_pid(int clifd, const app_pkt_t *pkt, struct ucred *cr)
787 {
788         char *appid;
789         bundle *kb;
790
791         kb = bundle_decode(pkt->data, pkt->len);
792         if (kb == NULL) {
793                 close(clifd);
794                 return -1;
795         }
796
797         appid = (char *)bundle_get_val(kb, AUL_K_APPID);
798         __app_process_by_pid(pkt->cmd, appid, cr, clifd);
799         bundle_free(kb);
800
801         return 0;
802 }
803
804 static int __dispatch_app_term_async(int clifd, const app_pkt_t *pkt, struct ucred *cr)
805 {
806         char *appid;
807         bundle *kb;
808         char *term_pid;
809         struct appinfo *ai;
810
811         kb = bundle_decode(pkt->data, pkt->len);
812         if (kb == NULL) {
813                 close(clifd);
814                 return -1;
815         }
816
817         term_pid = (char *)bundle_get_val(kb, AUL_K_APPID);
818         appid = _status_app_get_appid_bypid(atoi(term_pid));
819         ai = appinfo_find(cr->uid, appid);
820         if (ai) {
821                 appinfo_set_value(ai, AIT_STATUS, "norestart");
822                 __app_process_by_pid(pkt->cmd, term_pid, cr, clifd);
823         } else {
824                 close(clifd);
825         }
826         bundle_free(kb);
827
828         return 0;
829 }
830
831 static int __dispatch_app_term(int clifd, const app_pkt_t *pkt, struct ucred *cr)
832 {
833         char *appid;
834         bundle *kb;
835
836         kb = bundle_decode(pkt->data, pkt->len);
837         if (kb == NULL) {
838                 close(clifd);
839                 return -1;
840         }
841
842         appid = (char *)bundle_get_val(kb, AUL_K_APPID);
843         __app_process_by_pid(pkt->cmd, appid, cr, clifd);
844         bundle_free(kb);
845
846         return 0;
847 }
848
849 static int __dispatch_app_running_info(int clifd, const app_pkt_t *pkt, struct ucred *cr)
850 {
851         _status_send_running_appinfo(clifd, cr->uid);
852         return 0;
853 }
854
855 static int __dispatch_app_is_running(int clifd, const app_pkt_t *pkt, struct ucred *cr)
856 {
857         char *appid = NULL;
858         int ret;
859
860         appid = malloc(MAX_PACKAGE_STR_SIZE);
861         if (appid == NULL) {
862                 _E("out of memory");
863                 __send_result_to_client(clifd, -1);
864                 return -1;
865         }
866         strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
867         ret = _status_app_is_running(appid, cr->uid);
868         SECURE_LOGD("APP_IS_RUNNING : %s : %d", appid, ret);
869         __send_result_to_client(clifd, ret);
870         free(appid);
871
872         return 0;
873 }
874
875 static int __dispatch_app_get_appid_by_pid(int clifd, const app_pkt_t *pkt, struct ucred *cr)
876 {
877         int pid;
878         int ret;
879
880         memcpy(&pid, pkt->data, pkt->len);
881         ret = _status_get_appid_bypid(clifd, pid);
882         _D("app_get_appid_bypid : %d : %d", pid, ret);
883         return 0;
884 }
885
886 static int __dispatch_app_get_pkgid_by_pid(int clifd, const app_pkt_t *pkt, struct ucred *cr)
887 {
888         int pid;
889         int ret;
890
891         memcpy(&pid, pkt->data, sizeof(int));
892         ret = _status_get_pkgid_bypid(clifd, pid);
893         _D("APP_GET_PKGID_BYPID : %d : %d", pid, ret);
894         return 0;
895 }
896
897 static int __dispatch_legacy_command(int clifd, const app_pkt_t *pkt, struct ucred *cr)
898 {
899         __send_result_to_client(clifd, 0);
900         return 0;
901 }
902
903 static int __dispatch_app_status_update(int clifd, const app_pkt_t *pkt, struct ucred *cr)
904 {
905         int *status;
906         char *appid;
907         struct appinfo *ai;
908
909         status = (int *)pkt->data;
910         if (*status == STATUS_NORESTART) {
911                 appid = _status_app_get_appid_bypid(cr->pid);
912                 ai = appinfo_find(cr->uid, appid);
913                 appinfo_set_value((struct appinfo *)ai, AIT_STATUS, "norestart");
914         } else {
915                 _status_update_app_info_list(cr->pid, *status, cr->uid);
916         }
917         close(clifd);
918
919         return 0;
920 }
921
922 static int __dispatch_app_get_status(int clifd, const app_pkt_t *pkt, struct ucred *cr)
923 {
924         int pid;
925         int ret;
926
927         memcpy(&pid, pkt->data, sizeof(int));
928         ret = _status_get_app_info_status(pid, 0);
929         __send_result_to_client(clifd, ret);
930
931         return 0;
932 }
933
934 static int __dispatch_app_released(int clifd, const app_pkt_t *pkt, struct ucred *cr)
935 {
936         char *appid;
937         int ret;
938
939         appid = malloc(MAX_PACKAGE_STR_SIZE);
940         if (appid == NULL) {
941                 _E("out of memory");
942                 __send_result_to_client(clifd, -1);
943                 return -1;
944         }
945         strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
946         ret = __release_srv(cr->uid, appid);
947         __send_result_to_client(clifd, ret);
948         free(appid);
949
950         return 0;
951 }
952
953 static int __dispatch_agent_dead_signal(int clifd, const app_pkt_t *pkt, struct ucred *cr)
954 {
955         _D("AMD_AGENT_DEAD_SIGNAL");
956         __handle_agent_dead_signal(cr);
957         close(clifd);
958
959         return 0;
960 }
961
962 static int __dispatch_amd_reload_appinfo(int clifd, const app_pkt_t *pkt, struct ucred *cr)
963 {
964         _D("AMD_RELOAD_APPINFO");
965         appinfo_reload();
966         __send_result_to_client(clifd, 0);
967
968         return 0;
969 }
970
971 static int __get_caller_info_from_cynara(int sockfd, char **client, char **user, char **session)
972 {
973         pid_t pid;
974         int r;
975         char buf[MAX_LOCAL_BUFSZ] = {0,};
976
977         r = cynara_creds_socket_get_pid(sockfd, &pid);
978         if (r != CYNARA_API_SUCCESS) {
979                 cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
980                 _E("cynara_creds_socket_get_pid failed: %s", buf);
981                 return -1;
982         }
983
984         *session = cynara_session_from_pid(pid);
985         if (*session == NULL) {
986                 _E("cynara_session_from_pid failed.");
987                 return -1;
988         }
989
990         r = cynara_creds_socket_get_user(sockfd, USER_METHOD_DEFAULT, user);
991         if (r != CYNARA_API_SUCCESS) {
992                 cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
993                 _E("cynara_cred_socket_get_user failed.");
994                 return -1;
995         }
996
997         r = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_DEFAULT, client);
998         if (r != CYNARA_API_SUCCESS) {
999                 cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
1000                 _E("cynara_creds_socket_get_client failed.");
1001                 return -1;
1002         }
1003
1004         return 0;
1005 }
1006
1007 static const char *__convert_cmd_to_privilege(int cmd)
1008 {
1009         switch (cmd) {
1010         case APP_OPEN:
1011         case APP_RESUME:
1012         case APP_START:
1013         case APP_START_RES:
1014                 return PRIVILEGE_APPMANAGER_LAUNCH;
1015         case APP_TERM_BY_PID_WITHOUT_RESTART:
1016         case APP_TERM_BY_PID_ASYNC:
1017         case APP_TERM_BY_PID:
1018         case APP_KILL_BY_PID:
1019                 return PRIVILEGE_APPMANAGER_KILL;
1020         case APP_TERM_BGAPP_BY_PID:
1021                 return PRIVILEGE_APPMANAGER_KILL_BGAPP;
1022         default:
1023                 return NULL;
1024         }
1025 }
1026
1027 static int __check_privilege_by_cynara(int sockfd, const char *privilege)
1028 {
1029         int r;
1030         int ret;
1031         char buf[MAX_LOCAL_BUFSZ] = {0,};
1032         char *client = NULL;
1033         char *session = NULL;
1034         char *user = NULL;
1035
1036         r = __get_caller_info_from_cynara(sockfd, &client, &user, &session);
1037         if (r < 0) {
1038                 ret = -1;
1039                 goto end;
1040         }
1041
1042         r = cynara_check(r_cynara, client, session, user, privilege);
1043         switch (r) {
1044         case CYNARA_API_ACCESS_ALLOWED:
1045                 _D("%s(%s) from user %s privilege %s allowed.", client, session, user, privilege);
1046                 ret = 0;
1047                 break;
1048         case CYNARA_API_ACCESS_DENIED:
1049                 _E("%s(%s) from user %s privilege %s denied.", client, session, user, privilege);
1050                 ret = -1;
1051                 break;
1052         default:
1053                 cynara_strerror(r, buf, MAX_LOCAL_BUFSZ);
1054                 _E("cynara_check failed: %s", buf);
1055                 ret = -1;
1056                 break;
1057         }
1058
1059 end:
1060         free(user);
1061         free(session);
1062         free(client);
1063
1064         return ret;
1065 }
1066
1067 static app_cmd_dispatch_func dispatch_table[APP_CMD_MAX] = {
1068         [APP_GET_SOCKET_PAIR] =  __dispatch_get_socket_pair,
1069         [APP_START] =  __dispatch_app_start,
1070         [APP_OPEN] = __dispatch_app_start,
1071         [APP_RESUME] = __dispatch_app_start,
1072         [APP_RESUME_BY_PID] = __dispatch_app_process_by_pid,
1073         [APP_TERM_BY_PID] = __dispatch_app_term,
1074         [APP_TERM_BY_PID_WITHOUT_RESTART] = __dispatch_app_term_async,
1075         [APP_RESULT] = __dispatch_app_result,
1076         [APP_START_RES] = __dispatch_app_start,
1077         [APP_CANCEL] = __dispatch_app_result,
1078         [APP_KILL_BY_PID] = __dispatch_app_term,
1079         [APP_ADD_HISTORY] = NULL,
1080         [APP_RUNNING_INFO] = __dispatch_app_running_info,
1081         [APP_RUNNING_INFO_RESULT] = NULL,
1082         [APP_IS_RUNNING] = __dispatch_app_is_running,
1083         [APP_GET_APPID_BYPID] = __dispatch_app_get_appid_by_pid,
1084         [APP_GET_PKGID_BYPID] = __dispatch_app_get_pkgid_by_pid,
1085         [APP_GET_INFO_OK] = NULL,
1086         [APP_GET_INFO_ERROR] = NULL,
1087         [APP_KEY_EVENT] = NULL,
1088         [APP_KEY_RESERVE] = __dispatch_legacy_command,
1089         [APP_KEY_RELEASE] = __dispatch_legacy_command,
1090         [APP_STATUS_UPDATE] = __dispatch_app_status_update,
1091         [APP_RELEASED] = __dispatch_app_released,
1092         [APP_RUNNING_LIST_UPDATE] = __dispatch_legacy_command,
1093         [APP_TERM_REQ_BY_PID] = __dispatch_app_process_by_pid,
1094         [APP_TERM_BY_PID_ASYNC] = __dispatch_app_term_async,
1095         [APP_TERM_BGAPP_BY_PID] = __dispatch_app_term,
1096         [APP_PAUSE] = __dispatch_app_pause,
1097         [APP_PAUSE_BY_PID] = __dispatch_app_process_by_pid,
1098         [APP_GROUP_GET_WINDOW] = __dispatch_app_group_get_window,
1099         [APP_GROUP_SET_WINDOW] = __dispatch_app_group_set_window,
1100         [APP_GROUP_GET_FG] = __dispatch_app_group_get_fg_flag,
1101         [APP_GROUP_GET_LEADER_PID] = __dispatch_app_group_get_leader_pid,
1102         [APP_GROUP_GET_LEADER_PIDS] = __dispatch_app_group_get_leader_pids,
1103         [APP_GROUP_GET_GROUP_PIDS] = __dispatch_app_group_get_group_pids,
1104         [APP_GROUP_GET_IDLE_PIDS] = __dispatch_app_group_get_idle_pids,
1105         [APP_GROUP_LOWER] = __dispatch_app_group_lower,
1106         [APP_GROUP_CLEAR_TOP] = __dispatch_app_group_clear_top,
1107         [APP_GET_STATUS] = __dispatch_app_get_status,
1108         [AMD_RELOAD_APPINFO] = __dispatch_amd_reload_appinfo,
1109         [AGENT_DEAD_SIGNAL] = __dispatch_agent_dead_signal,
1110 };
1111
1112 static gboolean __request_handler(gpointer data)
1113 {
1114         GPollFD *gpollfd = (GPollFD *) data;
1115         int fd = gpollfd->fd;
1116         app_pkt_t *pkt;
1117         int ret;
1118         int clifd;
1119         struct ucred cr;
1120         const char *privilege;
1121
1122         if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
1123                 _E("recv error");
1124                 return FALSE;
1125         }
1126
1127         if (cr.uid >= REGULAR_UID_MIN) {
1128                 privilege = __convert_cmd_to_privilege(pkt->cmd);
1129                 if (privilege) {
1130                         ret = __check_privilege_by_cynara(clifd, privilege);
1131                         if (ret < 0) {
1132                                 _E("request has been denied by smack");
1133                                 ret = -EILLEGALACCESS;
1134                                 __real_send(clifd, ret);
1135                                 free(pkt);
1136                                 return TRUE;
1137                         }
1138                 }
1139         }
1140
1141         if (pkt->cmd >= 0 && pkt->cmd < APP_CMD_MAX && dispatch_table[pkt->cmd]) {
1142                 if (dispatch_table[pkt->cmd](clifd, pkt, &cr) != 0)
1143                         _E("callback returns FALSE : %d", pkt->cmd);
1144         } else {
1145                 _E("Invalid packet or not supported command");
1146                 close(clifd);
1147         }
1148         free(pkt);
1149
1150         return TRUE;
1151 }
1152
1153 static gboolean __au_glib_check(GSource *src)
1154 {
1155         GSList *fd_list;
1156         GPollFD *tmp;
1157
1158         fd_list = src->poll_fds;
1159         do {
1160                 tmp = (GPollFD *) fd_list->data;
1161                 if ((tmp->revents & (POLLIN | POLLPRI)))
1162                         return TRUE;
1163                 fd_list = fd_list->next;
1164         } while (fd_list);
1165
1166         return FALSE;
1167 }
1168
1169 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
1170                 gpointer data)
1171 {
1172         callback(data);
1173         return TRUE;
1174 }
1175
1176 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
1177 {
1178         return FALSE;
1179 }
1180
1181 static GSourceFuncs funcs = {
1182         .prepare = __au_glib_prepare,
1183         .check = __au_glib_check,
1184         .dispatch = __au_glib_dispatch,
1185         .finalize = NULL
1186 };
1187
1188 int _request_init(void)
1189 {
1190         int fd;
1191         int r;
1192         GPollFD *gpollfd;
1193         GSource *src;
1194
1195         __socket_pair_hash = g_hash_table_new_full(g_str_hash,  g_str_equal, NULL, g_free);
1196
1197         fd = __create_sock_activation();
1198         if (fd == -1) {
1199                 _D("Create server socket without socket activation");
1200                 fd = __create_server_sock(AUL_UTIL_PID);
1201                 if (fd == -1) {
1202                         _E("Create server socket failed.");
1203                         return -1;
1204                 }
1205         }
1206
1207         r = cynara_initialize(&r_cynara, NULL);
1208         if (r != CYNARA_API_SUCCESS) {
1209                 _E("cynara initialize failed.");
1210                 close(fd);
1211                 return -1;
1212         }
1213
1214         src = g_source_new(&funcs, sizeof(GSource));
1215         if (!src) {
1216                 _E("out of memory");
1217                 cynara_finish(r_cynara);
1218                 close(fd);
1219                 return -1;
1220         }
1221
1222         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
1223         if (!gpollfd) {
1224                 _E("out of memory");
1225                 g_source_destroy(src);
1226                 cynara_finish(r_cynara);
1227                 close(fd);
1228                 return -1;
1229         }
1230
1231         gpollfd->events = POLLIN;
1232         gpollfd->fd = fd;
1233
1234         g_source_add_poll(src, gpollfd);
1235         g_source_set_callback(src, (GSourceFunc) __request_handler,
1236                         (gpointer) gpollfd, NULL);
1237         g_source_set_priority(src, G_PRIORITY_DEFAULT);
1238
1239         r = g_source_attach(src, NULL);
1240         if (r  == 0) {
1241                 g_free(gpollfd);
1242                 g_source_destroy(src);
1243                 cynara_finish(r_cynara);
1244                 close(fd);
1245                 return -1;
1246         }
1247         r = rua_init();
1248         r = rua_clear_history();
1249
1250         _D("rua_clear_history : %d", r);
1251
1252         return 0;
1253 }