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