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