Migrate from 2.4 code repo
[platform/core/context/context-service.git] / src / client_request.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <unistd.h>
18 #include <glib.h>
19 #include <security-server.h>
20 #include <app_manager.h>
21 #include <types_internal.h>
22 #include <dbus_server.h>
23 #include "zone_util_impl.h"
24 #include "dbus_server_impl.h"
25 #include "access_control/privilege.h"
26 #include "client_request.h"
27
28 ctx::client_request::client_request(int type, const char* client, int req_id, const char* subj, const char* desc, const char* cookie, GDBusMethodInvocation *inv)
29         : request_info(type, client, req_id, subj, desc)
30         , invocation(inv)
31 {
32         gsize size;
33         int client_pid;
34         char *decoded = NULL;
35         const char *zone_name = NULL;
36         char *pkg_id = NULL;
37
38         decoded = reinterpret_cast<char*>(g_base64_decode(cookie, &size));
39         IF_FAIL_CATCH_TAG(decoded, _E, "Cookie decoding failed");
40
41         raw_cookie = decoded;
42         client_pid = security_server_get_cookie_pid(decoded);
43         pkg_id = security_server_get_smacklabel_cookie(decoded);
44         g_free(decoded);
45         IF_FAIL_CATCH_TAG(client_pid > 0, _E, "Invalid PID (%d)", client_pid);
46
47         if (pkg_id == NULL) {
48                 _W(RED("security_server_get_smacklabel_cookie() failed"));
49                 char* app_id = NULL;
50                 app_manager_get_app_id(client_pid, &app_id);
51                 client_app_id = ctx::privilege_manager::get_pkg_id(app_id);
52                 g_free(app_id);
53         } else {
54                 //FIXME: Yes.. this is actually the package id
55                 client_app_id = pkg_id;
56                 g_free(pkg_id);
57         }
58
59         zone_name = ctx::zone_util::get_name_by_pid(client_pid);
60         IF_FAIL_CATCH_TAG(zone_name, _E, RED("Zone name retrieval failed"));
61         _zone_name = zone_name;
62
63         _SD(CYAN("Package: '%s' / Zone: '%s'"), client_app_id.c_str(), zone_name);
64         return;
65
66 CATCH:
67         invocation = NULL;
68         throw ERR_OPERATION_FAILED;
69 }
70
71 ctx::client_request::~client_request()
72 {
73         if (invocation)
74                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
75 }
76
77 const char* ctx::client_request::get_cookie()
78 {
79         return raw_cookie.c_str();
80 }
81
82 const char* ctx::client_request::get_app_id()
83 {
84         if (!client_app_id.empty())
85                 return client_app_id.c_str();
86
87         return NULL;
88 }
89
90 bool ctx::client_request::reply(int error)
91 {
92         IF_FAIL_RETURN(invocation, true);
93
94         _I("Reply %#x", error);
95
96         g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", error, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
97         invocation = NULL;
98         return true;
99 }
100
101 bool ctx::client_request::reply(int error, ctx::json& request_result)
102 {
103         IF_FAIL_RETURN(invocation, true);
104         IF_FAIL_RETURN(_type != REQ_READ_SYNC, true);
105
106         char *result = request_result.dup_cstr();
107         IF_FAIL_RETURN_TAG(result, false, _E, "Memory allocation failed");
108
109         _I("Reply %#x", error);
110         _SD("Result: %s", result);
111
112         g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", error, result, EMPTY_JSON_OBJECT));
113         invocation = NULL;
114
115         g_free(result);
116         return true;
117 }
118
119 bool ctx::client_request::reply(int error, ctx::json& request_result, ctx::json& data_read)
120 {
121         if (invocation == NULL) {
122                 return publish(error, data_read);
123         }
124
125         char *result = NULL;
126         char *data = NULL;
127
128         result = request_result.dup_cstr();
129         IF_FAIL_CATCH_TAG(result, _E, "Memory allocation failed");
130
131         data = data_read.dup_cstr();
132         IF_FAIL_CATCH_TAG(data, _E, "Memory allocation failed");
133
134         _I("Reply %#x", error);
135         _SD("Result: %s", result);
136         _SD("Data: %s", data);
137
138         g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", error, result, data));
139         invocation = NULL;
140
141         g_free(result);
142         g_free(data);
143         return true;
144
145 CATCH:
146         g_free(result);
147         g_free(data);
148         return false;
149 }
150
151 bool ctx::client_request::publish(int error, ctx::json& data)
152 {
153         char *data_str = data.dup_cstr();
154         IF_FAIL_RETURN_TAG(data_str, false, _E, "Memory allocation failed");
155
156         dbus_server::publish(_client.c_str(), _req_id, _subject.c_str(), error, data_str);
157         g_free(data_str);
158
159         return true;
160 }