a11d4c47878b2f47b025695c5ea8463f45da915f
[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 <dirent.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/xattr.h>
37 #include <sys/smack.h>
38 #include <sys/capability.h>
39
40 #include <dpl/log/log.h>
41 #include <dpl/exception.h>
42 #include <smack-labels.h>
43 #include <message-buffer.h>
44 #include <client-common.h>
45 #include <protocols.h>
46 #include <service_impl.h>
47 #include <file-lock.h>
48
49 #include <security-manager.h>
50
51 /**
52  * Mapping of lib_retcode error codes to theirs strings equivalents
53  */
54 static std::map<enum lib_retcode, std::string> lib_retcode_string_map = {
55     {SECURITY_MANAGER_SUCCESS, "Success"},
56     {SECURITY_MANAGER_ERROR_UNKNOWN, "Unknown error"},
57     {SECURITY_MANAGER_ERROR_INPUT_PARAM, "Invalid function parameter was given"},
58     {SECURITY_MANAGER_ERROR_MEMORY, "Memory allocation error"},
59     {SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, "Incomplete data in application request"},
60     {SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "User does not have sufficient "
61                                                    "rigths to perform an operation"}
62 };
63
64 SECURITY_MANAGER_API
65 const char *security_manager_strerror(enum lib_retcode rc)
66 {
67     try {
68         return lib_retcode_string_map.at(rc).c_str();
69     } catch (const std::out_of_range &e) {
70         return "Unknown error code";
71     }
72 }
73
74 SECURITY_MANAGER_API
75 int security_manager_app_inst_req_new(app_inst_req **pp_req)
76 {
77     if (!pp_req)
78         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
79
80     try {
81         *pp_req = new app_inst_req;
82     } catch (std::bad_alloc& ex) {
83         return SECURITY_MANAGER_ERROR_MEMORY;
84     }
85     (*pp_req)->uid = geteuid();
86
87     return SECURITY_MANAGER_SUCCESS;
88 }
89
90 SECURITY_MANAGER_API
91 void security_manager_app_inst_req_free(app_inst_req *p_req)
92 {
93     delete p_req;
94 }
95
96 SECURITY_MANAGER_API
97 int security_manager_app_inst_req_set_uid(app_inst_req *p_req,
98                                           const uid_t uid)
99 {
100     if (!p_req)
101         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
102
103     p_req->uid = uid;
104
105     return SECURITY_MANAGER_SUCCESS;
106 }
107
108 SECURITY_MANAGER_API
109 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
110 {
111     if (!p_req || !app_id)
112         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
113
114     p_req->appId = app_id;
115
116     return SECURITY_MANAGER_SUCCESS;
117 }
118
119 SECURITY_MANAGER_API
120 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
121 {
122     if (!p_req || !pkg_id)
123         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
124
125     p_req->pkgId = pkg_id;
126
127     return SECURITY_MANAGER_SUCCESS;
128 }
129
130 SECURITY_MANAGER_API
131 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
132 {
133     if (!p_req || !privilege)
134         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
135
136     p_req->privileges.push_back(privilege);
137
138     return SECURITY_MANAGER_SUCCESS;
139 }
140
141 SECURITY_MANAGER_API
142 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
143 {
144     if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
145         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
146
147     p_req->appPaths.push_back(std::make_pair(path, path_type));
148
149     return SECURITY_MANAGER_SUCCESS;
150 }
151
152 SECURITY_MANAGER_API
153 int security_manager_app_install(const app_inst_req *p_req)
154 {
155     using namespace SecurityManager;
156
157     return try_catch([&] {
158         //checking parameters
159         if (!p_req)
160             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
161         if (p_req->appId.empty() || p_req->pkgId.empty())
162             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
163
164         bool offlineMode;
165         int retval;
166
167         try {
168             SecurityManager::FileLocker serviceLock(SecurityManager::SERVICE_LOCK_FILE);
169             if ((offlineMode = serviceLock.Locked())) {
170                 LogInfo("Working in offline mode.");
171                 retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid());
172             }
173         } catch (const SecurityManager::FileLocker::Exception::Base &e) {
174             offlineMode = false;
175         }
176         if (!offlineMode) {
177             MessageBuffer send, recv;
178
179             //put data into buffer
180             Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL);
181             Serialization::Serialize(send, p_req->appId);
182             Serialization::Serialize(send, p_req->pkgId);
183             Serialization::Serialize(send, p_req->privileges);
184             Serialization::Serialize(send, p_req->appPaths);
185             Serialization::Serialize(send, p_req->uid);
186
187             //send buffer to server
188             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
189             if (retval != SECURITY_MANAGER_API_SUCCESS) {
190                 LogError("Error in sendToServer. Error code: " << retval);
191                 return SECURITY_MANAGER_ERROR_UNKNOWN;
192             }
193
194             //receive response from server
195             Deserialization::Deserialize(recv, retval);
196         }
197         switch(retval) {
198             case SECURITY_MANAGER_API_SUCCESS:
199                 return SECURITY_MANAGER_SUCCESS;
200             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
201                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
202             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
203                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
204             default:
205                 return SECURITY_MANAGER_ERROR_UNKNOWN;
206         }
207
208     });
209 }
210
211 SECURITY_MANAGER_API
212 int security_manager_app_uninstall(const app_inst_req *p_req)
213 {
214     using namespace SecurityManager;
215     MessageBuffer send, recv;
216
217     return try_catch([&] {
218         //checking parameters
219         if (!p_req)
220             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
221         if (p_req->appId.empty())
222             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
223
224         //put data into buffer
225         Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
226         Serialization::Serialize(send, p_req->appId);
227
228         //send buffer to server
229         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
230         if (retval != SECURITY_MANAGER_API_SUCCESS) {
231             LogError("Error in sendToServer. Error code: " << retval);
232             return SECURITY_MANAGER_ERROR_UNKNOWN;
233         }
234
235         //receive response from server
236         Deserialization::Deserialize(recv, retval);
237         if (retval != SECURITY_MANAGER_API_SUCCESS)
238             return SECURITY_MANAGER_ERROR_UNKNOWN;
239
240         return SECURITY_MANAGER_SUCCESS;;
241     });
242 }
243
244 SECURITY_MANAGER_API
245 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
246 {
247     using namespace SecurityManager;
248     MessageBuffer send, recv;
249
250     LogDebug("security_manager_get_app_pkgid() called");
251
252     return try_catch([&] {
253         //checking parameters
254
255         if (app_id == NULL) {
256             LogError("security_manager_app_get_pkgid: app_id is NULL");
257             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
258         }
259
260         if (pkg_id == NULL) {
261             LogError("security_manager_app_get_pkgid: pkg_id is NULL");
262             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
263         }
264
265         //put data into buffer
266         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
267         Serialization::Serialize(send, std::string(app_id));
268
269         //send buffer to server
270         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
271         if (retval != SECURITY_MANAGER_API_SUCCESS) {
272             LogDebug("Error in sendToServer. Error code: " << retval);
273             return SECURITY_MANAGER_ERROR_UNKNOWN;
274         }
275
276         //receive response from server
277         Deserialization::Deserialize(recv, retval);
278         if (retval != SECURITY_MANAGER_API_SUCCESS)
279             return SECURITY_MANAGER_ERROR_UNKNOWN;
280
281         std::string pkgIdString;
282         Deserialization::Deserialize(recv, pkgIdString);
283         if (pkgIdString.empty()) {
284             LogError("Unexpected empty pkgId");
285             return SECURITY_MANAGER_ERROR_UNKNOWN;
286         }
287
288         *pkg_id = strdup(pkgIdString.c_str());
289         if (*pkg_id == NULL) {
290             LogError("Failed to allocate memory for pkgId");
291             return SECURITY_MANAGER_ERROR_MEMORY;
292         }
293
294         return SECURITY_MANAGER_SUCCESS;
295     });
296 }
297
298 static bool setup_smack(const char *label)
299 {
300     int labelSize = strlen(label);
301
302     // Set Smack label for open socket file descriptors
303
304     std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
305         opendir("/proc/self/fd"), closedir);
306     if (!dir.get()) {
307         LogError("Unable to read list of open file descriptors: " <<
308             strerror(errno));
309         return SECURITY_MANAGER_ERROR_UNKNOWN;
310     }
311
312     do {
313         errno = 0;
314         struct dirent *dirEntry = readdir(dir.get());
315         if (dirEntry == nullptr) {
316             if (errno == 0) // NULL return value also signals end of directory
317                 break;
318
319             LogError("Unable to read list of open file descriptors: " <<
320                 strerror(errno));
321             return SECURITY_MANAGER_ERROR_UNKNOWN;
322         }
323
324         // Entries with numerical names specify file descriptors, ignore the rest
325         if (!isdigit(dirEntry->d_name[0]))
326             continue;
327
328         struct stat statBuf;
329         int fd = atoi(dirEntry->d_name);
330         int ret = fstat(fd, &statBuf);
331         if (ret != 0) {
332             LogWarning("fstat failed on file descriptor " << fd << ": " <<
333                 strerror(errno));
334             continue;
335         }
336         if (S_ISSOCK(statBuf.st_mode)) {
337             ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
338             if (ret != 0) {
339                 LogError("Setting Smack label failed on file descriptor " <<
340                     fd << ": " << strerror(errno));
341                 return SECURITY_MANAGER_ERROR_UNKNOWN;
342             }
343
344             ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
345             if (ret != 0) {
346                 LogError("Setting Smack label failed on file descriptor " <<
347                     fd << ": " << strerror(errno));
348                 return SECURITY_MANAGER_ERROR_UNKNOWN;
349             }
350         }
351     } while (true);
352
353     // Set Smack label of current process
354     smack_set_label_for_self(label);
355
356     return SECURITY_MANAGER_SUCCESS;
357 }
358
359 SECURITY_MANAGER_API
360 int security_manager_set_process_label_from_appid(const char *app_id)
361 {
362     int ret;
363     std::string appLabel;
364
365     LogDebug("security_manager_set_process_label_from_appid() called");
366
367     if (smack_smackfs_path() == NULL)
368         return SECURITY_MANAGER_SUCCESS;
369
370     if (SecurityManager::generateAppLabel(std::string(app_id), appLabel) == false) {
371         LogError("Failed to generate smack label for appId: " << app_id);
372         return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
373     }
374
375     if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
376         LogError("Failed to set smack label " << appLabel << " for current process");
377         return ret;
378     }
379
380     return SECURITY_MANAGER_SUCCESS;
381 }
382
383 SECURITY_MANAGER_API
384 int security_manager_set_process_groups_from_appid(const char *app_id)
385 {
386     using namespace SecurityManager;
387     MessageBuffer send, recv;
388     int ret;
389
390     LogDebug("security_manager_set_process_groups_from_appid() called");
391
392     return try_catch([&] {
393         //checking parameters
394
395         if (app_id == nullptr) {
396             LogError("app_id is NULL");
397             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
398         }
399
400         //put data into buffer
401         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
402         Serialization::Serialize(send, std::string(app_id));
403
404         //send buffer to server
405         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
406         if (retval != SECURITY_MANAGER_API_SUCCESS) {
407             LogDebug("Error in sendToServer. Error code: " << retval);
408             return SECURITY_MANAGER_ERROR_UNKNOWN;
409         }
410
411         //receive response from server
412         Deserialization::Deserialize(recv, retval);
413         if (retval != SECURITY_MANAGER_API_SUCCESS)
414             return SECURITY_MANAGER_ERROR_UNKNOWN;
415
416         //How many new groups?
417         int newGroupsCnt;
418         Deserialization::Deserialize(recv, newGroupsCnt);
419
420         //And how many groups do we belong to already?
421         int oldGroupsCnt;
422         ret = getgroups(0, nullptr);
423         if (ret == -1) {
424             LogError("Unable to get list of current supplementary groups: " <<
425                 strerror(errno));
426             return SECURITY_MANAGER_ERROR_UNKNOWN;
427         }
428         oldGroupsCnt = ret;
429
430         //Allocate an array for both old and new groups gids
431         std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
432         if (!groups.get()) {
433             LogError("Memory allocation failed.");
434             return SECURITY_MANAGER_ERROR_MEMORY;
435         }
436
437         //Get the old groups from process
438         ret = getgroups(oldGroupsCnt, groups.get());
439         if (ret == -1) {
440             LogError("Unable to get list of current supplementary groups: " <<
441                 strerror(errno));
442             return SECURITY_MANAGER_ERROR_UNKNOWN;
443         }
444
445         //Get the new groups from server response
446         for (int i = 0; i < newGroupsCnt; ++i) {
447             gid_t gid;
448             Deserialization::Deserialize(recv, gid);
449             groups.get()[oldGroupsCnt + i] = gid;
450             LogDebug("Adding process to group " << gid);
451         }
452
453         //Apply the modified groups list
454         ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
455         if (ret == -1) {
456             LogError("Unable to get list of current supplementary groups: " <<
457                 strerror(errno));
458             return SECURITY_MANAGER_ERROR_UNKNOWN;
459         }
460
461         return SECURITY_MANAGER_SUCCESS;
462     });
463 }
464
465 SECURITY_MANAGER_API
466 int security_manager_drop_process_privileges(void)
467 {
468     LogDebug("security_manager_drop_process_privileges() called");
469
470     int ret;
471     cap_t cap = cap_init();
472     if (!cap) {
473         LogError("Unable to allocate capability object");
474         return SECURITY_MANAGER_ERROR_MEMORY;
475     }
476
477     ret = cap_clear(cap);
478     if (ret) {
479         LogError("Unable to initialize capability object");
480         cap_free(cap);
481         return SECURITY_MANAGER_ERROR_UNKNOWN;
482     }
483
484     ret = cap_set_proc(cap);
485     if (ret) {
486         LogError("Unable to drop process capabilities");
487         cap_free(cap);
488         return SECURITY_MANAGER_ERROR_UNKNOWN;
489     }
490
491     cap_free(cap);
492     return SECURITY_MANAGER_SUCCESS;
493 }
494
495 SECURITY_MANAGER_API
496 int security_manager_prepare_app(const char *app_id)
497 {
498     LogDebug("security_manager_prepare_app() called");
499     int ret;
500
501     ret = security_manager_set_process_label_from_appid(app_id);
502     if (ret != SECURITY_MANAGER_SUCCESS)
503         return ret;
504
505     ret = security_manager_set_process_groups_from_appid(app_id);
506     if (ret != SECURITY_MANAGER_SUCCESS)
507         return ret;
508
509     ret = security_manager_drop_process_privileges();
510     return ret;
511 }
512
513 SECURITY_MANAGER_API
514 int security_manager_user_req_new(user_req **pp_req)
515 {
516     if (!pp_req)
517         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
518     try {
519         *pp_req = new user_req;
520     } catch (std::bad_alloc& ex) {
521         return SECURITY_MANAGER_ERROR_MEMORY;
522     }
523     return SECURITY_MANAGER_SUCCESS;
524 }
525
526 SECURITY_MANAGER_API
527 void security_manager_user_req_free(user_req *p_req)
528 {
529     delete p_req;
530 }
531
532 SECURITY_MANAGER_API
533 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
534 {
535     if (!p_req)
536         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
537
538     p_req->uid = uid;
539
540     return SECURITY_MANAGER_SUCCESS;
541 }
542
543 SECURITY_MANAGER_API
544 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
545 {
546     if (!p_req)
547         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
548
549     p_req->utype = static_cast<int>(utype);
550
551     return SECURITY_MANAGER_SUCCESS;
552 }
553
554 SECURITY_MANAGER_API
555 int security_manager_user_add(const user_req *p_req)
556 {
557     using namespace SecurityManager;
558     bool offlineMode;
559     MessageBuffer send, recv;
560     if (!p_req)
561         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
562     return try_catch([&] {
563         int retval;
564         try {
565             SecurityManager::FileLocker serviceLock(SecurityManager::SERVICE_LOCK_FILE);
566             if ((offlineMode = serviceLock.Locked())) {
567                 LogInfo("Working in offline mode.");
568                 retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid());
569             }
570         } catch (const SecurityManager::FileLocker::Exception::Base &e) {
571             offlineMode = false;
572         }
573         if (!offlineMode) {
574             //server is working
575
576             //put data into buffer
577             Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD));
578
579             Serialization::Serialize(send, p_req->uid);
580             Serialization::Serialize(send, p_req->utype);
581
582             //send buffer to server
583             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
584             if (retval != SECURITY_MANAGER_API_SUCCESS) {
585                 LogError("Error in sendToServer. Error code: " << retval);
586                 return SECURITY_MANAGER_ERROR_UNKNOWN;
587             }
588
589             //receive response from server
590             Deserialization::Deserialize(recv, retval);
591         }
592         switch(retval) {
593         case SECURITY_MANAGER_API_SUCCESS:
594             return SECURITY_MANAGER_SUCCESS;
595         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
596             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
597         default:
598             return SECURITY_MANAGER_ERROR_UNKNOWN;
599         }
600     });
601 }
602
603 SECURITY_MANAGER_API
604 int security_manager_user_delete(const user_req *p_req)
605 {
606     using namespace SecurityManager;
607     MessageBuffer send, recv;
608     if (!p_req)
609         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
610     return try_catch([&] {
611
612         //put data into buffer
613         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE));
614
615         Serialization::Serialize(send, p_req->uid);
616
617
618         //send buffer to server
619         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
620         if (retval != SECURITY_MANAGER_API_SUCCESS) {
621             LogError("Error in sendToServer. Error code: " << retval);
622             return SECURITY_MANAGER_ERROR_UNKNOWN;
623         }
624
625         //receive response from server
626         Deserialization::Deserialize(recv, retval);
627         switch(retval) {
628         case SECURITY_MANAGER_API_SUCCESS:
629             return SECURITY_MANAGER_SUCCESS;
630         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
631             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
632         default:
633             return SECURITY_MANAGER_ERROR_UNKNOWN;
634         }
635     });
636 }
637
638
639 /***************************POLICY***************************************/
640
641 SECURITY_MANAGER_API
642 int security_manager_policy_update_req_new(policy_update_req **pp_req)
643 {
644     if (!pp_req)
645         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
646
647     try {
648         *pp_req = new policy_update_req;
649     } catch (std::bad_alloc& ex) {
650         return SECURITY_MANAGER_ERROR_MEMORY;
651     }
652
653     return SECURITY_MANAGER_SUCCESS;
654 }
655
656 SECURITY_MANAGER_API
657 void security_manager_policy_update_req_free(policy_update_req *p_req)
658 {
659     delete p_req;
660 }
661
662 SECURITY_MANAGER_API
663 int security_manager_policy_update_send(policy_update_req *p_req)
664 {
665     using namespace SecurityManager;
666     MessageBuffer send, recv;
667
668     if (p_req == nullptr || p_req->units.size() == 0)
669         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
670
671     return try_catch([&] {
672
673         //put request into buffer
674         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
675         Serialization::Serialize(send, p_req->units);
676
677         //send it to server
678         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
679         if (retval != SECURITY_MANAGER_API_SUCCESS) {
680             LogError("Error in sendToServer. Error code: " << retval);
681             return SECURITY_MANAGER_ERROR_UNKNOWN;
682         }
683
684         //receive response from server
685         Deserialization::Deserialize(recv, retval);
686         switch(retval) {
687             case SECURITY_MANAGER_API_SUCCESS:
688                 return SECURITY_MANAGER_SUCCESS;
689             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
690                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
691             default:
692                 return SECURITY_MANAGER_ERROR_UNKNOWN;
693         }
694     });
695 }
696
697 static inline int security_manager_get_policy_internal(
698         SecurityManager::SecurityModuleCall call_type,
699         policy_entry *p_filter,
700         policy_entry **pp_privs_policy,
701         size_t *p_size)
702 {
703     using namespace SecurityManager;
704     MessageBuffer send, recv;
705
706     if (pp_privs_policy == nullptr || p_size == nullptr)
707         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
708
709     return try_catch([&] {
710         //put request into buffer
711         Serialization::Serialize(send, static_cast<int>(call_type));
712         Serialization::Serialize(send, *p_filter);
713         //send it to server
714         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
715         if (retval != SECURITY_MANAGER_API_SUCCESS) {
716             LogError("Error in sendToServer. Error code: " << retval);
717             return SECURITY_MANAGER_ERROR_UNKNOWN;
718         }
719         //receive response from server
720         Deserialization::Deserialize(recv, retval);
721         switch(retval) {
722             case SECURITY_MANAGER_API_SUCCESS: {
723                 //extract and allocate buffers for privs policy entries
724                 size_t entriesCnt = 0;
725                 policy_entry **entries = nullptr;
726                 Deserialization::Deserialize(recv, entriesCnt);
727                 try {
728                     entries = new policy_entry*[entriesCnt]();
729                     for (size_t i = 0; i < entriesCnt; ++i)
730                         Deserialization::Deserialize(recv, entries[i]);
731                 } catch (...) {
732                     LogError("Error while parsing server response");
733                     for (size_t i = 0; i < entriesCnt; ++i)
734                         delete(entries[i]);
735                     delete entries;
736                     return SECURITY_MANAGER_ERROR_UNKNOWN;
737                 }
738                 *p_size = entriesCnt;
739                 pp_privs_policy = entries;
740                 return SECURITY_MANAGER_SUCCESS;
741             }
742             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
743                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
744
745             default:
746                 return SECURITY_MANAGER_ERROR_UNKNOWN;
747         }
748     });
749 }
750
751 SECURITY_MANAGER_API
752 int security_manager_get_configured_policy_for_admin(
753         policy_entry *p_filter,
754         policy_entry **pp_privs_policy,
755         size_t *p_size)
756 {
757     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, pp_privs_policy, p_size);
758 }
759
760 SECURITY_MANAGER_API
761 int security_manager_get_configured_policy_for_self(
762         policy_entry *p_filter,
763         policy_entry **pp_privs_policy,
764         size_t *p_size)
765 {
766     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, pp_privs_policy, p_size);
767 }
768
769 SECURITY_MANAGER_API
770 int security_manager_get_policy(
771         policy_entry *p_filter,
772         policy_entry **pp_privs_policy,
773         size_t *p_size)
774 {
775     return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, pp_privs_policy, p_size);
776 };
777
778 SECURITY_MANAGER_API
779 int security_manager_policy_entry_new(policy_entry **p_entry)
780 {
781     if (!p_entry)
782         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
783
784     try {
785         *p_entry = new policy_entry;
786     } catch (std::bad_alloc& ex) {
787         return SECURITY_MANAGER_ERROR_MEMORY;
788     }
789
790     return SECURITY_MANAGER_SUCCESS;
791 }
792
793 SECURITY_MANAGER_API
794 void security_manager_policy_entry_free(policy_entry *p_entry)
795 {
796     delete p_entry;
797 }
798
799 SECURITY_MANAGER_API
800 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
801 {
802     if (!p_entry)
803         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
804     p_entry->appId = app_id;
805     return  SECURITY_MANAGER_SUCCESS;
806 }
807
808 SECURITY_MANAGER_API
809 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
810 {
811     if (!p_entry)
812         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
813     p_entry->user = user;
814     return  SECURITY_MANAGER_SUCCESS;
815 }
816
817 SECURITY_MANAGER_API
818 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
819 {
820     if (!p_entry)
821         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
822     p_entry->privilege = privilege;
823     return  SECURITY_MANAGER_SUCCESS;
824 }
825
826 SECURITY_MANAGER_API
827 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
828 {
829     if (!p_entry)
830         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
831     p_entry->currentLevel = policy_level;
832     return  SECURITY_MANAGER_SUCCESS;
833 }
834
835 SECURITY_MANAGER_API
836 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
837 {
838     if (!p_entry)
839         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
840     p_entry->maxLevel = policy_level;
841     return  SECURITY_MANAGER_SUCCESS;
842 }
843
844 SECURITY_MANAGER_API
845 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
846 {
847     if (!p_entry || !p_req)
848         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
849     p_req->units.push_back(p_entry);
850
851     return  SECURITY_MANAGER_SUCCESS;
852 }
853
854 SECURITY_MANAGER_API
855 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
856 {
857     if (p_entry)
858         return strdup(p_entry->user.c_str());
859     else
860         return nullptr;
861 }
862
863 SECURITY_MANAGER_API
864 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
865 {
866     if (p_entry)
867         return strdup(p_entry->appId.c_str());
868     else
869         return nullptr;
870 }
871 SECURITY_MANAGER_API
872 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
873 {
874     if (p_entry)
875         return strdup(p_entry->privilege.c_str());
876     else
877         return nullptr;
878 }
879 SECURITY_MANAGER_API
880 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
881 {
882     if (p_entry)
883         return strdup(p_entry->currentLevel.c_str());
884     else
885         return nullptr;
886 }
887
888 SECURITY_MANAGER_API
889 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
890 {
891     if (p_entry)
892         return strdup(p_entry->maxLevel.c_str());
893     else
894         return nullptr;
895 }
896
897 SECURITY_MANAGER_API
898 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
899 {
900     for (size_t i = 0; i < size; i++) {
901         delete &p_entries[i];
902     }
903     delete [] p_entries;
904 }
905
906 SECURITY_MANAGER_API
907 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
908 {
909     (void)levels;
910     (void)levels_count;
911
912     return 0;
913 }
914
915 SECURITY_MANAGER_API
916 void security_manager_policy_levels_free(char **levels, size_t levels_count)
917 {
918     (void)levels;
919     (void)levels_count;
920 }