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