d26165bbafdd80a7ef0d367a5fdd0937a2bd6d87
[platform/core/appfw/pkgmgr-server.git] / src / request.c
1 #include <sys/types.h>
2 #include <sys/time.h>
3
4 #include <glib.h>
5 #include <gio/gio.h>
6
7 #include "comm_config.h"
8 #include "pm-queue.h"
9 #include "pkgmgr-server.h"
10 #include "package-manager.h"
11 #include "package-manager-debug.h"
12
13 static const char instropection_xml[] =
14         "<node>"
15         "  <interface name='org.tizen.pkgmgr'>"
16         "    <method name='install'>"
17         "      <arg type='u' name='uid' direction='in'/>"
18         "      <arg type='s' name='pkgtype' direction='in'/>"
19         "      <arg type='s' name='pkgpath' direction='in'/>"
20         "      <arg type='as' name='args' direction='in'/>"
21         "      <arg type='i' name='ret' direction='out'/>"
22         "      <arg type='s' name='reqkey' direction='out'/>"
23         "    </method>"
24         "    <method name='reinstall'>"
25         "      <arg type='u' name='uid' direction='in'/>"
26         "      <arg type='s' name='pkgtype' direction='in'/>"
27         "      <arg type='s' name='pkgid' direction='in'/>"
28         "      <arg type='i' name='ret' direction='out'/>"
29         "      <arg type='s' name='reqkey' direction='out'/>"
30         "    </method>"
31         "    <method name='uninstall'>"
32         "      <arg type='u' name='uid' direction='in'/>"
33         "      <arg type='s' name='pkgtype' direction='in'/>"
34         "      <arg type='s' name='pkgid' direction='in'/>"
35         "      <arg type='i' name='ret' direction='out'/>"
36         "      <arg type='s' name='reqkey' direction='out'/>"
37         "    </method>"
38         "    <method name='move'>"
39         "      <arg type='u' name='uid' direction='in'/>"
40         "      <arg type='s' name='pkgtype' direction='in'/>"
41         "      <arg type='s' name='pkgid' direction='in'/>"
42         "      <arg type='i' name='ret' direction='out'/>"
43         "      <arg type='s' name='reqkey' direction='out'/>"
44         "    </method>"
45         "    <method name='enable_pkg'>"
46         "      <arg type='u' name='uid' direction='in'/>"
47         "      <arg type='s' name='pkgtype' direction='in'/>"
48         "      <arg type='s' name='pkgid' direction='in'/>"
49         "      <arg type='i' name='ret' direction='out'/>"
50         "    </method>"
51         "    <method name='disable_pkg'>"
52         "      <arg type='u' name='uid' direction='in'/>"
53         "      <arg type='s' name='pkgtype' direction='in'/>"
54         "      <arg type='s' name='pkgid' direction='in'/>"
55         "      <arg type='i' name='ret' direction='out'/>"
56         "    </method>"
57         "    <method name='enable_app'>"
58         "      <arg type='u' name='uid' direction='in'/>"
59         "      <arg type='s' name='appid' direction='in'/>"
60         "      <arg type='i' name='ret' direction='out'/>"
61         "      <arg type='s' name='reqkey' direction='out'/>"
62         "    </method>"
63         "    <method name='disable_app'>"
64         "      <arg type='u' name='uid' direction='in'/>"
65         "      <arg type='s' name='appid' direction='in'/>"
66         "      <arg type='i' name='ret' direction='out'/>"
67         "      <arg type='s' name='reqkey' direction='out'/>"
68         "    </method>"
69         "    <method name='enable_global_app_for_uid'>"
70         "      <arg type='u' name='uid' direction='in'/>"
71         "      <arg type='s' name='appid' direction='in'/>"
72         "      <arg type='i' name='ret' direction='out'/>"
73         "      <arg type='s' name='reqkey' direction='out'/>"
74         "    </method>"
75         "    <method name='disable_global_app_for_uid'>"
76         "      <arg type='u' name='uid' direction='in'/>"
77         "      <arg type='s' name='appid' direction='in'/>"
78         "      <arg type='i' name='ret' direction='out'/>"
79         "      <arg type='s' name='reqkey' direction='out'/>"
80         "    </method>"
81         "    <method name='getsize'>"
82         "      <arg type='u' name='uid' direction='in'/>"
83         "      <arg type='s' name='pkgid' direction='in'/>"
84         "      <arg type='i' name='get_type' direction='in'/>"
85         "      <arg type='i' name='ret' direction='out'/>"
86         "      <arg type='s' name='reqkey' direction='out'/>"
87         "    </method>"
88         "    <method name='cleardata'>"
89         "      <arg type='u' name='uid' direction='in'/>"
90         "      <arg type='s' name='pkgtype' direction='in'/>"
91         "      <arg type='s' name='pkgid' direction='in'/>"
92         "      <arg type='i' name='ret' direction='out'/>"
93         "    </method>"
94         "    <method name='clearcache'>"
95         "      <arg type='u' name='uid' direction='in'/>"
96         "      <arg type='s' name='pkgid' direction='in'/>"
97         "      <arg type='i' name='ret' direction='out'/>"
98         "    </method>"
99         "    <method name='kill'>"
100         "      <arg type='u' name='uid' direction='in'/>"
101         "      <arg type='s' name='pkgid' direction='in'/>"
102         "      <arg type='i' name='ret' direction='out'/>"
103         "    </method>"
104         "    <method name='check'>"
105         "      <arg type='u' name='uid' direction='in'/>"
106         "      <arg type='s' name='pkgid' direction='in'/>"
107         "      <arg type='i' name='ret' direction='out'/>"
108         "    </method>"
109         "    <method name='generate_license_request'>"
110         "      <arg type='s' name='resp_data' direction='in'/>"
111         "      <arg type='i' name='ret' direction='out'/>"
112         "      <arg type='s' name='req_data' direction='out'/>"
113         "      <arg type='s' name='license_url' direction='out'/>"
114         "    </method>"
115         "    <method name='register_license'>"
116         "      <arg type='s' name='resp_data' direction='in'/>"
117         "      <arg type='i' name='ret' direction='out'/>"
118         "    </method>"
119         "    <method name='decrypt_package'>"
120         "      <arg type='s' name='drm_file_path' direction='in'/>"
121         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
122         "      <arg type='i' name='ret' direction='out'/>"
123         "    </method>"
124         "    <method name='add_blacklist'>"
125         "      <arg type='u' name='uid' direction='in'/>"
126         "      <arg type='s' name='pkgid' direction='in'/>"
127         "      <arg type='i' name='ret' direction='out'/>"
128         "    </method>"
129         "    <method name='remove_blacklist'>"
130         "      <arg type='u' name='uid' direction='in'/>"
131         "      <arg type='s' name='pkgid' direction='in'/>"
132         "      <arg type='i' name='ret' direction='out'/>"
133         "    </method>"
134         "    <method name='check_blacklist'>"
135         "      <arg type='u' name='uid' direction='in'/>"
136         "      <arg type='s' name='pkgid' direction='in'/>"
137         "      <arg type='i' name='result' direction='out'/>"
138         "      <arg type='i' name='ret' direction='out'/>"
139         "    </method>"
140         "  </interface>"
141         "</node>";
142 static GDBusNodeInfo *instropection_data;
143 static guint reg_id;
144 static guint owner_id;
145 static GHashTable *req_table;
146
147 static char *__generate_reqkey(const char *pkgid)
148 {
149         struct timeval tv;
150         long curtime;
151         char timestr[MAX_PKG_ARGS_LEN];
152         char *str_req_key;
153         int size;
154
155         gettimeofday(&tv, NULL);
156         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
157         snprintf(timestr, sizeof(timestr), "%ld", curtime);
158
159         size = strlen(pkgid) + strlen(timestr) + 2;
160         str_req_key = (char *)calloc(size, sizeof(char));
161         if (str_req_key == NULL) {
162                 DBG("calloc failed");
163                 return NULL;
164         }
165         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
166
167         return str_req_key;
168 }
169
170 static int __handle_request_install(uid_t uid,
171                 GDBusMethodInvocation *invocation, GVariant *parameters)
172 {
173         uid_t target_uid = (uid_t)-1;
174         char *pkgtype = NULL;
175         char *pkgpath = NULL;
176         char *args = NULL;
177         char *reqkey = NULL;
178         gchar **tmp_args = NULL;
179         gsize args_count;
180         int ret = -1;
181         GVariant *value;
182         int i = 0;
183         int len = 0;
184
185         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath, &value);
186         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
187
188         for (i = 0; i < args_count; i++)
189                 len = len + strlen(tmp_args[i]) + 1;
190
191         args = (char *)calloc(len, sizeof(char));
192         if (args == NULL) {
193                 ERR("calloc failed");
194                 ret =  -1;
195                 goto catch;
196         }
197
198         for (i = 0; i < args_count; i++) {
199                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
200                 strncat(args, " ", strlen(" "));
201         }
202
203         if (target_uid == (uid_t)-1 || pkgtype == NULL) {
204                 g_dbus_method_invocation_return_value(invocation,
205                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
206                 ret = -1;
207                 goto catch;
208         }
209
210         if (pkgpath == NULL) {
211                 g_dbus_method_invocation_return_value(invocation,
212                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
213                 ret = -1;
214                 goto catch;
215         }
216
217         reqkey = __generate_reqkey(pkgpath);
218         if (reqkey == NULL) {
219                 ret = -1;
220                 goto catch;
221         }
222
223         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_INSTALL, pkgtype,
224                                 pkgpath, args)) {
225                 g_dbus_method_invocation_return_value(invocation,
226                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
227                 ret = -1;
228                 goto catch;
229         }
230
231         g_dbus_method_invocation_return_value(invocation,
232                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
233
234         ret = 0;
235
236 catch:
237         if (reqkey)
238                 free(reqkey);
239
240         if (args)
241                 free(args);
242
243         return ret;
244 }
245
246 static int __handle_request_reinstall(uid_t uid,
247                 GDBusMethodInvocation *invocation, GVariant *parameters)
248 {
249         uid_t target_uid = (uid_t)-1;
250         char *pkgtype = NULL;
251         char *pkgid = NULL;
252         char *reqkey;
253
254         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
255         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
256                 g_dbus_method_invocation_return_value(invocation,
257                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
258                 return -1;
259         }
260
261         reqkey = __generate_reqkey(pkgid);
262         if (reqkey == NULL)
263                 return -1;
264         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_REINSTALL, pkgtype,
265                                 pkgid, "")) {
266                 g_dbus_method_invocation_return_value(invocation,
267                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
268                 free(reqkey);
269                 return -1;
270         }
271
272         g_dbus_method_invocation_return_value(invocation,
273                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
274         free(reqkey);
275
276         return 0;
277 }
278
279 static int __handle_request_uninstall(uid_t uid,
280                 GDBusMethodInvocation *invocation, GVariant *parameters)
281 {
282         uid_t target_uid = (uid_t)-1;
283         char *pkgtype = NULL;
284         char *pkgid = NULL;
285         char *reqkey;
286
287         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
288         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
289                 g_dbus_method_invocation_return_value(invocation,
290                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
291                 return -1;
292         }
293
294         reqkey = __generate_reqkey(pkgid);
295         if (reqkey == NULL)
296                 return -1;
297         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_UNINSTALL, pkgtype,
298                                 pkgid, "")) {
299                 g_dbus_method_invocation_return_value(invocation,
300                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
301                 free(reqkey);
302                 return -1;
303         }
304
305         g_dbus_method_invocation_return_value(invocation,
306                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
307         free(reqkey);
308
309         return 0;
310 }
311
312 static int __handle_request_move(uid_t uid,
313                 GDBusMethodInvocation *invocation, GVariant *parameters)
314 {
315         uid_t target_uid = (uid_t)-1;
316         char *pkgtype = NULL;
317         char *pkgid = NULL;
318         char *reqkey;
319
320         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
321         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
322                 g_dbus_method_invocation_return_value(invocation,
323                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
324                 return -1;
325         }
326
327         reqkey = __generate_reqkey(pkgid);
328         if (reqkey == NULL)
329                 return -1;
330         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_MOVE, pkgtype,
331                                 pkgid, "")) {
332                 g_dbus_method_invocation_return_value(invocation,
333                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
334                 free(reqkey);
335                 return -1;
336         }
337
338         g_dbus_method_invocation_return_value(invocation,
339                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
340         free(reqkey);
341
342         return 0;
343 }
344
345 static int __handle_request_enable_pkg(uid_t uid,
346                 GDBusMethodInvocation *invocation, GVariant *parameters)
347 {
348         uid_t target_uid = (uid_t)-1;
349         char *pkgtype = NULL;
350         char *pkgid = NULL;
351
352         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
353         if (target_uid == (uid_t)-1 || pkgid == NULL) {
354                 g_dbus_method_invocation_return_value(invocation,
355                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
356                 return -1;
357         }
358
359         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_ENABLE_PKG, &pkgtype,
360                                 pkgid, "")) {
361                 g_dbus_method_invocation_return_value(invocation,
362                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
363                 return -1;
364         }
365
366         g_dbus_method_invocation_return_value(invocation,
367                         g_variant_new("(i)", PKGMGR_R_OK));
368
369         return 0;
370 }
371
372 static int __handle_request_disable_pkg(uid_t uid,
373                 GDBusMethodInvocation *invocation, GVariant *parameters)
374 {
375         uid_t target_uid = (uid_t)-1;
376         char *pkgtype = NULL;
377         char *pkgid = NULL;
378
379         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
380         if (target_uid == (uid_t)-1 || pkgid == NULL) {
381                 g_dbus_method_invocation_return_value(invocation,
382                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
383                 return -1;
384         }
385
386         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_DISABLE_PKG, &pkgtype,
387                                 pkgid, "")) {
388                 g_dbus_method_invocation_return_value(invocation,
389                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
390                 return -1;
391         }
392
393         g_dbus_method_invocation_return_value(invocation,
394                         g_variant_new("(i)", PKGMGR_R_OK));
395
396         return 0;
397 }
398
399 static int __handle_request_enable_app(uid_t uid,
400                 GDBusMethodInvocation *invocation, GVariant *parameters)
401 {
402         uid_t target_uid = (uid_t)-1;
403         char *appid = NULL;
404         char *reqkey = NULL;
405         int ret = -1;
406
407         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
408         if (target_uid == (uid_t)-1 || appid == NULL) {
409                 g_dbus_method_invocation_return_value(invocation,
410                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
411                 return -1;
412         }
413
414         reqkey = __generate_reqkey(appid);
415         if (reqkey == NULL) {
416                 ret = -1;
417                 goto catch;
418         }
419
420         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_APP, "default",
421                                 appid, "")) {
422                 g_dbus_method_invocation_return_value(invocation,
423                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
424                 ret = -1;
425                 goto catch;
426         }
427
428         g_dbus_method_invocation_return_value(invocation,
429                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
430
431         ret = 0;
432
433 catch:
434         if(reqkey)
435                 free(reqkey);
436
437         return ret;
438 }
439
440 static int __handle_request_disable_app(uid_t uid,
441                 GDBusMethodInvocation *invocation, GVariant *parameters)
442 {
443         uid_t target_uid = (uid_t)-1;
444         char *appid = NULL;
445         char *reqkey = NULL;
446         int ret = -1;
447
448         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
449         if (target_uid == (uid_t)-1 || appid == NULL) {
450                 g_dbus_method_invocation_return_value(invocation,
451                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
452                 return -1;
453         }
454
455         reqkey = __generate_reqkey(appid);
456         if (reqkey == NULL) {
457                 ret = -1;
458                 goto catch;
459         }
460
461         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_APP, "default",
462                                 appid, "")) {
463                 g_dbus_method_invocation_return_value(invocation,
464                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
465                 ret = -1;
466                 goto catch;
467         }
468
469         g_dbus_method_invocation_return_value(invocation,
470                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
471
472         ret = 0;
473
474 catch:
475         if (reqkey)
476                 free(reqkey);
477
478         return ret;
479 }
480
481 static int __handle_request_enable_global_app_for_uid(uid_t uid,
482                 GDBusMethodInvocation *invocation, GVariant *parameters)
483 {
484         uid_t target_uid = (uid_t)-1;
485         char *appid = NULL;
486         char *reqkey = NULL;
487         int ret = -1;
488
489         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
490         if (target_uid == (uid_t)-1 || appid == NULL) {
491                 g_dbus_method_invocation_return_value(invocation,
492                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
493                 return -1;
494         }
495
496         reqkey = __generate_reqkey(appid);
497         if (reqkey == NULL) {
498                 ret = -1;
499                 goto catch;
500         }
501
502         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID, "default",
503                                 appid, "")) {
504                 g_dbus_method_invocation_return_value(invocation,
505                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
506                 ret = -1;
507                 goto catch;
508         }
509
510         g_dbus_method_invocation_return_value(invocation,
511                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
512
513         ret = 0;
514
515 catch:
516         if (reqkey)
517                 free(reqkey);
518
519         return ret;
520 }
521
522 static int __handle_request_disable_global_app_for_uid(uid_t uid,
523                 GDBusMethodInvocation *invocation, GVariant *parameters)
524 {
525         uid_t target_uid = (uid_t)-1;
526         char *appid = NULL;
527         char *reqkey = NULL;
528         int ret = -1;
529
530         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
531         if (target_uid == (uid_t)-1 || appid == NULL) {
532                 g_dbus_method_invocation_return_value(invocation,
533                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
534                 return -1;
535         }
536
537         reqkey = __generate_reqkey(appid);
538         if (reqkey == NULL) {
539                 ret = -1;
540                 goto catch;
541         }
542
543         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID, "default",
544                                 appid, "")) {
545                 g_dbus_method_invocation_return_value(invocation,
546                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
547                 ret = -1;
548                 goto catch;
549         }
550
551         g_dbus_method_invocation_return_value(invocation,
552                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
553
554         ret = 0;
555
556 catch:
557         if (reqkey)
558                 free(reqkey);
559
560         return ret;
561 }
562
563 static int __handle_request_getsize(uid_t uid,
564                 GDBusMethodInvocation *invocation, GVariant *parameters)
565 {
566         uid_t target_uid = (uid_t)-1;
567         char *pkgid = NULL;
568         int get_type = -1;
569         char *reqkey;
570         char buf[4];
571
572         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
573         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
574                 g_dbus_method_invocation_return_value(invocation,
575                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
576                 return -1;
577         }
578
579         reqkey = __generate_reqkey(pkgid);
580         if (reqkey == NULL)
581                 return -1;
582
583         snprintf(buf, sizeof(buf), "%d", get_type);
584         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_GETSIZE, "pkgtool",
585                                 pkgid, buf)) {
586                 g_dbus_method_invocation_return_value(invocation,
587                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
588                 free(reqkey);
589                 return -1;
590         }
591
592         g_dbus_method_invocation_return_value(invocation,
593                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
594         free(reqkey);
595
596         return 0;
597 }
598
599 static int __handle_request_cleardata(uid_t uid,
600                 GDBusMethodInvocation *invocation, GVariant *parameters)
601 {
602         uid_t target_uid = (uid_t)-1;
603         char *pkgtype = NULL;
604         char *pkgid = NULL;
605
606         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
607         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
608                 g_dbus_method_invocation_return_value(invocation,
609                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
610                 return -1;
611         }
612
613         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARDATA, "pkgtool",
614                                 pkgid, "")) {
615                 g_dbus_method_invocation_return_value(invocation,
616                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
617                 return -1;
618         }
619
620         g_dbus_method_invocation_return_value(invocation,
621                         g_variant_new("(i)", PKGMGR_R_OK));
622
623         return 0;
624 }
625
626 static int __handle_request_clearcache(uid_t uid,
627                 GDBusMethodInvocation *invocation, GVariant *parameters)
628 {
629         uid_t target_uid = (uid_t)-1;
630         char *pkgid = NULL;
631
632         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
633         if (target_uid == (uid_t)-1 || pkgid == NULL) {
634                 g_dbus_method_invocation_return_value(invocation,
635                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
636                 return -1;
637         }
638
639         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARCACHE,
640                                 "pkgtool",  pkgid, "")) {
641                 g_dbus_method_invocation_return_value(invocation,
642                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
643                 return -1;
644         }
645
646         g_dbus_method_invocation_return_value(invocation,
647                         g_variant_new("(i)", PKGMGR_R_OK));
648
649         return 0;
650 }
651
652 static int __handle_request_kill(uid_t uid,
653                 GDBusMethodInvocation *invocation, GVariant *parameters)
654 {
655         uid_t target_uid = (uid_t)-1;
656         char *pkgid = NULL;
657
658         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
659         if (target_uid == (uid_t)-1 || pkgid == NULL) {
660                 g_dbus_method_invocation_return_value(invocation,
661                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
662                 return -1;
663         }
664
665         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_KILL, "default",
666                                 pkgid, "")) {
667                 g_dbus_method_invocation_return_value(invocation,
668                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
669                 return -1;
670         }
671
672         g_dbus_method_invocation_return_value(invocation,
673                         g_variant_new("(i)", PKGMGR_R_OK));
674
675         return 0;
676 }
677
678 static int __handle_request_check(uid_t uid,
679                 GDBusMethodInvocation *invocation, GVariant *parameters)
680 {
681         uid_t target_uid = (uid_t)-1;
682         char *pkgid = NULL;
683
684         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
685         if (target_uid == (uid_t)-1 || pkgid == NULL) {
686                 g_dbus_method_invocation_return_value(invocation,
687                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
688                 return -1;
689         }
690
691         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CHECK, "default",
692                                 pkgid, "")) {
693                 g_dbus_method_invocation_return_value(invocation,
694                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
695                 return -1;
696         }
697
698         g_dbus_method_invocation_return_value(invocation,
699                         g_variant_new("(i)", PKGMGR_R_OK));
700
701         return 0;
702 }
703
704 static int __handle_request_generate_license_request(uid_t uid,
705                 GDBusMethodInvocation *invocation, GVariant *parameters)
706 {
707         char *reqkey;
708         char *resp_data = NULL;
709
710         g_variant_get(parameters, "(&s)", &resp_data);
711         if (resp_data == NULL) {
712                 g_dbus_method_invocation_return_value(invocation,
713                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
714                 return -1;
715         }
716
717         reqkey = __generate_reqkey("drm");
718         if (reqkey == NULL) {
719                 g_dbus_method_invocation_return_value(invocation,
720                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
721                                         ""));
722                 return -1;
723         }
724
725         if (_pm_queue_push(uid, reqkey,
726                                 PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
727                                 "default", "", resp_data)) {
728                 g_dbus_method_invocation_return_value(invocation,
729                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
730                                         ""));
731                 free(reqkey);
732                 return -1;
733         }
734
735         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
736                                 (gpointer)invocation))
737                 ERR("reqkey already exists");
738
739         return 0;
740 }
741
742 static int __handle_request_register_license(uid_t uid,
743                 GDBusMethodInvocation *invocation, GVariant *parameters)
744 {
745         char *reqkey;
746         char *resp_data = NULL;
747
748         g_variant_get(parameters, "(&s)", &resp_data);
749         if (resp_data == NULL) {
750                 g_dbus_method_invocation_return_value(invocation,
751                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
752                 return -1;
753         }
754
755         reqkey = __generate_reqkey("drm");
756         if (reqkey == NULL) {
757                 g_dbus_method_invocation_return_value(invocation,
758                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
759                 return -1;
760         }
761
762         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_REGISTER_LICENSE,
763                                 "default", "", resp_data)) {
764                 g_dbus_method_invocation_return_value(invocation,
765                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
766                 free(reqkey);
767                 return -1;
768         }
769
770         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
771                                 (gpointer)invocation))
772                 ERR("reqkey already exists");
773
774         return 0;
775 }
776
777 static int __handle_request_decrypt_package(uid_t uid,
778                 GDBusMethodInvocation *invocation, GVariant *parameters)
779 {
780         char *reqkey;
781         char *drm_file_path = NULL;
782         char *decrypted_file_path = NULL;
783
784         g_variant_get(parameters, "(&s&s)", &drm_file_path,
785                         &decrypted_file_path);
786         if (drm_file_path == NULL || decrypted_file_path == NULL) {
787                 g_dbus_method_invocation_return_value(invocation,
788                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
789                 return -1;
790         }
791
792         reqkey = __generate_reqkey("drm");
793         if (reqkey == NULL) {
794                 g_dbus_method_invocation_return_value(invocation,
795                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
796                 return -1;
797         }
798
799         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE,
800                                 "default", drm_file_path, decrypted_file_path)) {
801                 g_dbus_method_invocation_return_value(invocation,
802                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
803                 free(reqkey);
804                 return -1;
805         }
806
807         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
808                                 (gpointer)invocation))
809                 ERR("reqkey already exists");
810
811         return 0;
812 }
813
814 static int __handle_request_add_blacklist(uid_t uid,
815                 GDBusMethodInvocation *invocation, GVariant *parameters)
816 {
817         uid_t target_uid = (uid_t)-1;
818         char *reqkey;
819         char *pkgid = NULL;
820
821         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
822         if (target_uid == (uid_t)-1 || pkgid == NULL) {
823                 g_dbus_method_invocation_return_value(invocation,
824                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
825                 return -1;
826         }
827
828         reqkey = __generate_reqkey("blacklist");
829         if (reqkey == NULL) {
830                 g_dbus_method_invocation_return_value(invocation,
831                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
832                 return -1;
833         }
834
835         if (_pm_queue_push(target_uid, reqkey,
836                                 PKGMGR_REQUEST_TYPE_ADD_BLACKLIST,
837                                 "default",  pkgid, "")) {
838                 g_dbus_method_invocation_return_value(invocation,
839                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
840                 free(reqkey);
841                 return -1;
842         }
843
844         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
845                                 (gpointer)invocation))
846                 ERR("reqkey already exists");
847
848         return 0;
849 }
850
851 static int __handle_request_remove_blacklist(uid_t uid,
852                 GDBusMethodInvocation *invocation, GVariant *parameters)
853 {
854         uid_t target_uid = (uid_t)-1;
855         char *reqkey;
856         char *pkgid = NULL;
857
858         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
859         if (target_uid == (uid_t)-1 || pkgid == NULL) {
860                 g_dbus_method_invocation_return_value(invocation,
861                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
862                 return -1;
863         }
864
865         reqkey = __generate_reqkey("blacklist");
866         if (reqkey == NULL) {
867                 g_dbus_method_invocation_return_value(invocation,
868                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
869                 return -1;
870         }
871
872         if (_pm_queue_push(target_uid, reqkey,
873                                 PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST,
874                                 "default", pkgid, "")) {
875                 g_dbus_method_invocation_return_value(invocation,
876                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
877                 free(reqkey);
878                 return -1;
879         }
880
881         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
882                                 (gpointer)invocation))
883                 ERR("reqkey already exists");
884
885         return 0;
886 }
887
888 static int __handle_request_check_blacklist(uid_t uid,
889                 GDBusMethodInvocation *invocation, GVariant *parameters)
890 {
891         uid_t target_uid = (uid_t)-1;
892         char *reqkey;
893         char *pkgid = NULL;
894
895         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
896         if (target_uid == (uid_t)-1 || pkgid == NULL) {
897                 g_dbus_method_invocation_return_value(invocation,
898                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, -1));
899                 return -1;
900         }
901
902         reqkey = __generate_reqkey("blacklist");
903         if (reqkey == NULL) {
904                 g_dbus_method_invocation_return_value(invocation,
905                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, -1));
906                 return -1;
907         }
908
909         if (_pm_queue_push(target_uid, reqkey,
910                                 PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST,
911                                 "default", pkgid, "")) {
912                 g_dbus_method_invocation_return_value(invocation,
913                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, -1));
914                 free(reqkey);
915                 return -1;
916         }
917
918         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
919                                 (gpointer)invocation))
920                 ERR("reqkey already exists");
921
922         return 0;
923 }
924
925 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
926 {
927         GError *err = NULL;
928         GVariant *result;
929         uid_t uid;
930
931         result = g_dbus_connection_call_sync(connection,
932                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
933                         "org.freedesktop.DBus", "GetConnectionUnixUser",
934                         g_variant_new("(s)", name), NULL,
935                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
936         if (result == NULL) {
937                 ERR("failed to get caller uid: %s", err->message);
938                 g_error_free(err);
939                 return (uid_t)-1;
940         }
941
942         g_variant_get(result, "(u)", &uid);
943
944         return uid;
945 }
946
947 static void __handle_method_call(GDBusConnection *connection,
948                 const gchar *sender, const gchar *object_path,
949                 const gchar *interface_name, const gchar *method_name,
950                 GVariant *parameters, GDBusMethodInvocation *invocation,
951                 gpointer user_data)
952 {
953         int ret;
954         uid_t uid;
955
956         uid = __get_caller_uid(connection,
957                 g_dbus_method_invocation_get_sender(invocation));
958         if (uid == (uid_t)-1)
959                 return;
960
961         if (g_strcmp0(method_name, "install") == 0)
962                 ret = __handle_request_install(uid, invocation, parameters);
963         else if (g_strcmp0(method_name, "reinstall") == 0)
964                 ret = __handle_request_reinstall(uid, invocation, parameters);
965         else if (g_strcmp0(method_name, "uninstall") == 0)
966                 ret = __handle_request_uninstall(uid, invocation, parameters);
967         else if (g_strcmp0(method_name, "cleardata") == 0)
968                 ret = __handle_request_cleardata(uid, invocation, parameters);
969         else if (g_strcmp0(method_name, "move") == 0)
970                 ret = __handle_request_move(uid, invocation, parameters);
971         else if (g_strcmp0(method_name, "enable") == 0)
972                 ret = __handle_request_enable_pkg(uid, invocation, parameters);
973         else if (g_strcmp0(method_name, "disable") == 0)
974                 ret = __handle_request_disable_pkg(uid, invocation, parameters);
975         else if (g_strcmp0(method_name, "getsize") == 0)
976                 ret = __handle_request_getsize(uid, invocation, parameters);
977         else if (g_strcmp0(method_name, "clearcache") == 0)
978                 ret = __handle_request_clearcache(uid, invocation, parameters);
979         else if (g_strcmp0(method_name, "enable_app") == 0)
980                 ret = __handle_request_enable_app(uid, invocation, parameters);
981         else if (g_strcmp0(method_name, "disable_app") == 0)
982                 ret = __handle_request_disable_app(uid, invocation, parameters);
983         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
984                 ret = __handle_request_enable_global_app_for_uid(uid, invocation, parameters);
985         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
986                 ret = __handle_request_disable_global_app_for_uid(uid, invocation, parameters);
987         else if (g_strcmp0(method_name, "kill") == 0)
988                 ret = __handle_request_kill(uid, invocation, parameters);
989         else if (g_strcmp0(method_name, "check") == 0)
990                 ret = __handle_request_check(uid, invocation, parameters);
991         else if (g_strcmp0(method_name, "generate_license_request") == 0)
992                 ret = __handle_request_generate_license_request(uid, invocation,
993                                 parameters);
994         else if (g_strcmp0(method_name, "register_license") == 0)
995                 ret = __handle_request_register_license(uid, invocation,
996                                 parameters);
997         else if (g_strcmp0(method_name, "decrypt_package") == 0)
998                 ret = __handle_request_decrypt_package(uid, invocation,
999                                 parameters);
1000         else if (g_strcmp0(method_name, "add_blacklist") == 0)
1001                 ret = __handle_request_add_blacklist(uid, invocation,
1002                                 parameters);
1003         else if (g_strcmp0(method_name, "remove_blacklist") == 0)
1004                 ret = __handle_request_remove_blacklist(uid, invocation,
1005                                 parameters);
1006         else if (g_strcmp0(method_name, "check_blacklist") == 0)
1007                 ret = __handle_request_check_blacklist(uid, invocation,
1008                                 parameters);
1009         else
1010                 ret = -1;
1011
1012         if (ret == 0)
1013                 g_idle_add(queue_job, NULL);
1014 }
1015
1016 int __return_value_to_caller(const char *req_key, GVariant *result)
1017 {
1018         GDBusMethodInvocation *invocation;
1019
1020         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1021                         (gpointer)req_key);
1022         if (invocation == NULL) {
1023                 ERR("no such request id");
1024                 return -1;
1025         }
1026
1027         g_dbus_method_invocation_return_value(invocation, result);
1028         g_hash_table_remove(req_table, (gpointer)req_key);
1029
1030         return 0;
1031 }
1032
1033 static const GDBusInterfaceVTable interface_vtable =
1034 {
1035         __handle_method_call,
1036         NULL,
1037         NULL,
1038 };
1039
1040 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1041                 gpointer user_data)
1042 {
1043         GError *err = NULL;
1044
1045         DBG("on bus acquired");
1046
1047         reg_id = g_dbus_connection_register_object(connection,
1048                         COMM_PKGMGR_DBUS_OBJECT_PATH,
1049                         instropection_data->interfaces[0],
1050                         &interface_vtable, NULL, NULL, &err);
1051
1052         if (reg_id == 0) {
1053                 ERR("failed to register object: %s", err->message);
1054                 g_error_free(err);
1055         }
1056 }
1057
1058 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1059                 gpointer user_data)
1060 {
1061         DBG("on name acquired: %s", name);
1062 }
1063
1064 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1065                 gpointer user_data)
1066 {
1067         DBG("on name lost: %s", name);
1068 }
1069
1070 int __init_request_handler(void)
1071 {
1072         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL);
1073
1074         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE,
1075                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1076                         __on_name_acquired, __on_name_lost, NULL, NULL);
1077
1078         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1079                         free, NULL);
1080         if (req_table == NULL)
1081                 return -1;
1082
1083         return 0;
1084 }
1085
1086 void __fini_request_handler(void)
1087 {
1088         g_hash_table_destroy(req_table);
1089         g_bus_unown_name(owner_id);
1090         g_dbus_node_info_unref(instropection_data);
1091 }