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