2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
18 * Security Manager library header
21 * @file client-security-manager.cpp
22 * @author Pawel Polawski <p.polawski@samsung.com>
23 * @author Rafal Krypa <r.krypa@samsung.com>
25 * @brief This file contain client side implementation of security-manager API
33 #include <sys/types.h>
34 #include <sys/smack.h>
36 #include <dpl/log/log.h>
37 #include <dpl/exception.h>
39 #include <message-buffer.h>
40 #include <client-common.h>
41 #include <protocols.h>
42 #include <smack-common.h>
44 #include <security-manager.h>
49 int security_manager_app_inst_req_new(app_inst_req **pp_req)
52 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
55 *pp_req = new app_inst_req;
56 } catch (std::bad_alloc& ex) {
57 return SECURITY_MANAGER_ERROR_MEMORY;
61 return SECURITY_MANAGER_SUCCESS;
65 void security_manager_app_inst_req_free(app_inst_req *p_req)
71 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
73 if (!p_req || !app_id)
74 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
76 p_req->appId = app_id;
78 return SECURITY_MANAGER_SUCCESS;
82 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
84 if (!p_req || !pkg_id)
85 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
87 p_req->pkgId = pkg_id;
89 return SECURITY_MANAGER_SUCCESS;
93 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
95 if (!p_req || !privilege)
96 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
98 p_req->privileges.push_back(privilege);
100 return SECURITY_MANAGER_SUCCESS;
104 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
106 if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
107 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
109 p_req->appPaths.push_back(std::make_pair(path, path_type));
111 return SECURITY_MANAGER_SUCCESS;
115 int security_manager_app_install(const app_inst_req *p_req)
117 using namespace SecurityManager;
118 MessageBuffer send, recv;
120 return try_catch([&] {
121 //checking parameters
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;
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);
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;
141 //receive response from server
142 Deserialization::Deserialize(recv, 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;
149 return SECURITY_MANAGER_ERROR_UNKNOWN;
156 int security_manager_app_uninstall(const app_inst_req *p_req)
158 using namespace SecurityManager;
159 MessageBuffer send, recv;
161 return try_catch([&] {
162 //checking parameters
164 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
165 if (p_req->appId.empty())
166 return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
168 //put data into buffer
169 Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
170 Serialization::Serialize(send, p_req->appId);
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;
179 //receive response from server
180 Deserialization::Deserialize(recv, retval);
181 if (retval != SECURITY_MANAGER_API_SUCCESS)
182 return SECURITY_MANAGER_ERROR_UNKNOWN;
184 return SECURITY_MANAGER_SUCCESS;;
189 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
191 using namespace SecurityManager;
192 MessageBuffer send, recv;
194 LogDebug("security_manager_get_app_pkgid() called");
196 return try_catch([&] {
197 //checking parameters
199 if (app_id == NULL) {
200 LogError("security_manager_app_get_pkgid: app_id is NULL");
201 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
204 if (pkg_id == NULL) {
205 LogError("security_manager_app_get_pkgid: pkg_id is NULL");
206 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
209 //put data into buffer
210 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
211 Serialization::Serialize(send, std::string(app_id));
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;
220 //receive response from server
221 Deserialization::Deserialize(recv, retval);
222 if (retval != SECURITY_MANAGER_API_SUCCESS)
223 return SECURITY_MANAGER_ERROR_UNKNOWN;
225 std::string pkgIdString;
226 Deserialization::Deserialize(recv, pkgIdString);
227 if (pkgIdString.empty()) {
228 LogError("Unexpected empty pkgId");
229 return SECURITY_MANAGER_ERROR_UNKNOWN;
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;
238 return SECURITY_MANAGER_SUCCESS;
243 int security_manager_set_process_label_from_binary(const char *path)
248 LogDebug("security_manager_set_process_label_from_binary() called");
250 if (smack_smackfs_path() == NULL)
251 return SECURITY_MANAGER_SUCCESS;
254 LogError("security_manager_set_process_label_from_binary: path is NULL");
255 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
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");
271 int security_manager_set_process_label_from_appid(const char *app_id)
275 std::string appLabel;
277 LogDebug("security_manager_set_process_label_from_appid() called");
279 if (smack_smackfs_path() == NULL)
280 return SECURITY_MANAGER_SUCCESS;
282 ret = security_manager_get_app_pkgid(&pkg_id, app_id);
283 if (ret != SECURITY_MANAGER_SUCCESS) {
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;
294 ret = SECURITY_MANAGER_ERROR_UNKNOWN;
302 int security_manager_set_process_groups_from_appid(const char *app_id)
304 using namespace SecurityManager;
305 MessageBuffer send, recv;
308 LogDebug("security_manager_set_process_groups_from_appid() called");
310 return try_catch([&] {
311 //checking parameters
313 if (app_id == nullptr) {
314 LogError("app_id is NULL");
315 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
318 //put data into buffer
319 Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
320 Serialization::Serialize(send, std::string(app_id));
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;
329 //receive response from server
330 Deserialization::Deserialize(recv, retval);
331 if (retval != SECURITY_MANAGER_API_SUCCESS)
332 return SECURITY_MANAGER_ERROR_UNKNOWN;
334 //How many new groups?
336 Deserialization::Deserialize(recv, newGroupsCnt);
338 //And how many groups do we belong to already?
340 ret = getgroups(0, nullptr);
342 LogError("Unable to get list of current supplementary groups: " <<
344 return SECURITY_MANAGER_ERROR_UNKNOWN;
348 //Allocate an array for both old and new groups gids
349 std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
351 LogError("Memory allocation failed.");
352 return SECURITY_MANAGER_ERROR_MEMORY;
355 //Get the old groups from process
356 ret = getgroups(oldGroupsCnt, groups.get());
358 LogError("Unable to get list of current supplementary groups: " <<
360 return SECURITY_MANAGER_ERROR_UNKNOWN;
363 //Get the new groups from server response
364 for (int i = 0; i < newGroupsCnt; ++i) {
366 Deserialization::Deserialize(recv, gid);
367 groups.get()[oldGroupsCnt + i] = gid;
368 LogDebug("Adding process to group " << gid);
371 //Apply the modified groups list
372 ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
374 LogError("Unable to get list of current supplementary groups: " <<
376 return SECURITY_MANAGER_ERROR_UNKNOWN;
379 return SECURITY_MANAGER_SUCCESS;