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