c40097a4cc3a9612ae1b6f2ae946cf74e47f608a
[platform/core/security/security-manager.git] / src / client / client-security-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Rafal Krypa <r.krypa@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  *
18  *      Security Manager library header
19  */
20 /*
21  * @file        client-security-manager.cpp
22  * @author      Pawel Polawski <p.polawski@samsung.com>
23  * @author      Rafal Krypa <r.krypa@samsung.com>
24  * @version     1.0
25  * @brief       This file contain client side implementation of security-manager API
26  */
27
28 #include <cstdio>
29 #include <utility>
30
31 #include <unistd.h>
32 #include <grp.h>
33 #include <sys/types.h>
34 #include <sys/smack.h>
35
36 #include <dpl/log/log.h>
37 #include <dpl/exception.h>
38
39 #include <message-buffer.h>
40 #include <client-common.h>
41 #include <protocols.h>
42 #include <smack-common.h>
43
44 #include <security-manager.h>
45
46
47
48 SECURITY_MANAGER_API
49 int security_manager_app_inst_req_new(app_inst_req **pp_req)
50 {
51     if (!pp_req)
52         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
53
54     try {
55         *pp_req = new app_inst_req;
56     } catch (std::bad_alloc& ex) {
57         return SECURITY_MANAGER_ERROR_MEMORY;
58     }
59
60
61     return SECURITY_MANAGER_SUCCESS;
62 }
63
64 SECURITY_MANAGER_API
65 void security_manager_app_inst_req_free(app_inst_req *p_req)
66 {
67     delete p_req;
68 }
69
70 SECURITY_MANAGER_API
71 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
72 {
73     if (!p_req || !app_id)
74         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
75
76     p_req->appId = app_id;
77
78     return SECURITY_MANAGER_SUCCESS;
79 }
80
81 SECURITY_MANAGER_API
82 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
83 {
84     if (!p_req || !pkg_id)
85         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
86
87     p_req->pkgId = pkg_id;
88
89     return SECURITY_MANAGER_SUCCESS;
90 }
91
92 SECURITY_MANAGER_API
93 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
94 {
95     if (!p_req || !privilege)
96         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
97
98     p_req->privileges.push_back(privilege);
99
100     return SECURITY_MANAGER_SUCCESS;
101 }
102
103 SECURITY_MANAGER_API
104 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
105 {
106     if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
107         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
108
109     p_req->appPaths.push_back(std::make_pair(path, path_type));
110
111     return SECURITY_MANAGER_SUCCESS;
112 }
113
114 SECURITY_MANAGER_API
115 int security_manager_app_install(const app_inst_req *p_req)
116 {
117     using namespace SecurityManager;
118     MessageBuffer send, recv;
119
120     return try_catch([&] {
121         //checking parameters
122         if (!p_req)
123             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
124         if (p_req->appId.empty() || p_req->pkgId.empty())
125             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
126
127         //put data into buffer
128         Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL);
129         Serialization::Serialize(send, p_req->appId);
130         Serialization::Serialize(send, p_req->pkgId);
131         Serialization::Serialize(send, p_req->privileges);
132         Serialization::Serialize(send, p_req->appPaths);
133
134         //send buffer to server
135         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
136         if (retval != SECURITY_MANAGER_API_SUCCESS) {
137             LogError("Error in sendToServer. Error code: " << retval);
138             return SECURITY_MANAGER_ERROR_UNKNOWN;
139         }
140
141         //receive response from server
142         Deserialization::Deserialize(recv, retval);
143         switch(retval) {
144             case SECURITY_MANAGER_API_SUCCESS:
145                 return SECURITY_MANAGER_SUCCESS;
146             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
147                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
148             default:
149                 return SECURITY_MANAGER_ERROR_UNKNOWN;
150         }
151
152     });
153 }
154
155 SECURITY_MANAGER_API
156 int security_manager_app_uninstall(const app_inst_req *p_req)
157 {
158     using namespace SecurityManager;
159     MessageBuffer send, recv;
160
161     return try_catch([&] {
162         //checking parameters
163         if (!p_req)
164             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
165         if (p_req->appId.empty())
166             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
167
168         //put data into buffer
169         Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
170         Serialization::Serialize(send, p_req->appId);
171
172         //send buffer to server
173         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
174         if (retval != SECURITY_MANAGER_API_SUCCESS) {
175             LogError("Error in sendToServer. Error code: " << retval);
176             return SECURITY_MANAGER_ERROR_UNKNOWN;
177         }
178
179         //receive response from server
180         Deserialization::Deserialize(recv, retval);
181         if (retval != SECURITY_MANAGER_API_SUCCESS)
182             return SECURITY_MANAGER_ERROR_UNKNOWN;
183
184         return SECURITY_MANAGER_SUCCESS;;
185     });
186 }
187
188 SECURITY_MANAGER_API
189 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
190 {
191     using namespace SecurityManager;
192     MessageBuffer send, recv;
193
194     LogDebug("security_manager_get_app_pkgid() called");
195
196     return try_catch([&] {
197         //checking parameters
198
199         if (app_id == NULL) {
200             LogError("security_manager_app_get_pkgid: app_id is NULL");
201             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
202         }
203
204         if (pkg_id == NULL) {
205             LogError("security_manager_app_get_pkgid: pkg_id is NULL");
206             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
207         }
208
209         //put data into buffer
210         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
211         Serialization::Serialize(send, std::string(app_id));
212
213         //send buffer to server
214         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
215         if (retval != SECURITY_MANAGER_API_SUCCESS) {
216             LogDebug("Error in sendToServer. Error code: " << retval);
217             return SECURITY_MANAGER_ERROR_UNKNOWN;
218         }
219
220         //receive response from server
221         Deserialization::Deserialize(recv, retval);
222         if (retval != SECURITY_MANAGER_API_SUCCESS)
223             return SECURITY_MANAGER_ERROR_UNKNOWN;
224
225         std::string pkgIdString;
226         Deserialization::Deserialize(recv, pkgIdString);
227         if (pkgIdString.empty()) {
228             LogError("Unexpected empty pkgId");
229             return SECURITY_MANAGER_ERROR_UNKNOWN;
230         }
231
232         *pkg_id = strdup(pkgIdString.c_str());
233         if (*pkg_id == NULL) {
234             LogError("Failed to allocate memory for pkgId");
235             return SECURITY_MANAGER_ERROR_MEMORY;
236         }
237
238         return SECURITY_MANAGER_SUCCESS;
239     });
240 }
241
242 SECURITY_MANAGER_API
243 int security_manager_set_process_label_from_binary(const char *path)
244 {
245     char *smack_label;
246     int ret;
247
248     LogDebug("security_manager_set_process_label_from_binary() called");
249
250     if (smack_smackfs_path() == NULL)
251         return SECURITY_MANAGER_SUCCESS;
252
253     if (path == NULL) {
254         LogError("security_manager_set_process_label_from_binary: path is NULL");
255         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
256     }
257
258     ret = SecurityManager::getSmackLabelFromBinary(&smack_label, path);
259     if (ret == SECURITY_MANAGER_SUCCESS && smack_label != NULL) {
260         if (smack_set_label_for_self(smack_label) != 0) {
261             ret = SECURITY_MANAGER_ERROR_UNKNOWN;
262             LogError("Failed to set smack label " << smack_label << " for current process");
263         }
264         free(smack_label);
265     }
266
267     return ret;
268 }
269
270 SECURITY_MANAGER_API
271 int security_manager_set_process_label_from_appid(const char *app_id)
272 {
273     char *pkg_id;
274     int ret;
275     std::string appLabel;
276
277     LogDebug("security_manager_set_process_label_from_appid() called");
278
279     if (smack_smackfs_path() == NULL)
280         return SECURITY_MANAGER_SUCCESS;
281
282     ret = security_manager_get_app_pkgid(&pkg_id, app_id);
283     if (ret != SECURITY_MANAGER_SUCCESS) {
284         return ret;
285     }
286
287     if (SecurityManager::generateAppLabel(std::string(pkg_id), appLabel)) {
288         if (smack_set_label_for_self(appLabel.c_str()) != 0) {
289             LogError("Failed to set smack label " << appLabel << " for current process");
290             ret = SECURITY_MANAGER_ERROR_UNKNOWN;
291         }
292     }
293     else {
294         ret = SECURITY_MANAGER_ERROR_UNKNOWN;
295     }
296
297     free(pkg_id);
298     return ret;
299 }
300
301 SECURITY_MANAGER_API
302 int security_manager_set_process_groups_from_appid(const char *app_id)
303 {
304     using namespace SecurityManager;
305     MessageBuffer send, recv;
306     int ret;
307
308     LogDebug("security_manager_set_process_groups_from_appid() called");
309
310     return try_catch([&] {
311         //checking parameters
312
313         if (app_id == nullptr) {
314             LogError("app_id is NULL");
315             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
316         }
317
318         //put data into buffer
319         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
320         Serialization::Serialize(send, std::string(app_id));
321
322         //send buffer to server
323         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
324         if (retval != SECURITY_MANAGER_API_SUCCESS) {
325             LogDebug("Error in sendToServer. Error code: " << retval);
326             return SECURITY_MANAGER_ERROR_UNKNOWN;
327         }
328
329         //receive response from server
330         Deserialization::Deserialize(recv, retval);
331         if (retval != SECURITY_MANAGER_API_SUCCESS)
332             return SECURITY_MANAGER_ERROR_UNKNOWN;
333
334         //How many new groups?
335         int newGroupsCnt;
336         Deserialization::Deserialize(recv, newGroupsCnt);
337
338         //And how many groups do we belong to already?
339         int oldGroupsCnt;
340         ret = getgroups(0, nullptr);
341         if (ret == -1) {
342             LogError("Unable to get list of current supplementary groups: " <<
343                 strerror(errno));
344             return SECURITY_MANAGER_ERROR_UNKNOWN;
345         }
346         oldGroupsCnt = ret;
347
348         //Allocate an array for both old and new groups gids
349         std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
350         if (!groups.get()) {
351             LogError("Memory allocation failed.");
352             return SECURITY_MANAGER_ERROR_MEMORY;
353         }
354
355         //Get the old groups from process
356         ret = getgroups(oldGroupsCnt, groups.get());
357         if (ret == -1) {
358             LogError("Unable to get list of current supplementary groups: " <<
359                 strerror(errno));
360             return SECURITY_MANAGER_ERROR_UNKNOWN;
361         }
362
363         //Get the new groups from server response
364         for (int i = 0; i < newGroupsCnt; ++i) {
365             gid_t gid;
366             Deserialization::Deserialize(recv, gid);
367             groups.get()[oldGroupsCnt + i] = gid;
368             LogDebug("Adding process to group " << gid);
369         }
370
371         //Apply the modified groups list
372         ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
373         if (ret == -1) {
374             LogError("Unable to get list of current supplementary groups: " <<
375                 strerror(errno));
376             return SECURITY_MANAGER_ERROR_UNKNOWN;
377         }
378
379         return SECURITY_MANAGER_SUCCESS;
380     });
381 }