Convert ServiceImpl namespace to a class
[platform/core/security/security-manager.git] / src / client / client-security-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2015 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 <functional>
30 #include <memory>
31 #include <utility>
32
33 #include <unistd.h>
34 #include <grp.h>
35 #include <dirent.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/xattr.h>
39 #include <sys/smack.h>
40 #include <sys/capability.h>
41
42 #include <dpl/log/log.h>
43 #include <dpl/exception.h>
44 #include <smack-labels.h>
45 #include <message-buffer.h>
46 #include <client-common.h>
47 #include <protocols.h>
48 #include <service_impl.h>
49 #include <connection.h>
50 #include <zone-utils.h>
51
52 #include <security-manager.h>
53 #include <client-offline.h>
54
55 static const char *EMPTY = "";
56
57 /**
58  * Mapping of lib_retcode error codes to theirs strings equivalents
59  */
60 static std::map<enum lib_retcode, std::string> lib_retcode_string_map = {
61     {SECURITY_MANAGER_SUCCESS, "Success"},
62     {SECURITY_MANAGER_ERROR_UNKNOWN, "Unknown error"},
63     {SECURITY_MANAGER_ERROR_INPUT_PARAM, "Invalid function parameter was given"},
64     {SECURITY_MANAGER_ERROR_MEMORY, "Memory allocation error"},
65     {SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, "Incomplete data in application request"},
66     {SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "User does not have sufficient "
67                                                    "rigths to perform an operation"},
68     {SECURITY_MANAGER_ERROR_ACCESS_DENIED, "Insufficient privileges"},
69 };
70
71 SECURITY_MANAGER_API
72 const char *security_manager_strerror(enum lib_retcode rc)
73 {
74     try {
75         return lib_retcode_string_map.at(rc).c_str();
76     } catch (const std::out_of_range &e) {
77         return "Unknown error code";
78     }
79 }
80
81 SECURITY_MANAGER_API
82 int security_manager_app_inst_req_new(app_inst_req **pp_req)
83 {
84     if (!pp_req)
85         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
86
87     try {
88         *pp_req = new app_inst_req;
89     } catch (std::bad_alloc& ex) {
90         return SECURITY_MANAGER_ERROR_MEMORY;
91     }
92     (*pp_req)->uid = geteuid();
93
94     return SECURITY_MANAGER_SUCCESS;
95 }
96
97 SECURITY_MANAGER_API
98 void security_manager_app_inst_req_free(app_inst_req *p_req)
99 {
100     delete p_req;
101 }
102
103 SECURITY_MANAGER_API
104 int security_manager_app_inst_req_set_uid(app_inst_req *p_req,
105                                           const uid_t uid)
106 {
107     if (!p_req)
108         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
109
110     p_req->uid = uid;
111
112     return SECURITY_MANAGER_SUCCESS;
113 }
114
115 SECURITY_MANAGER_API
116 int security_manager_app_inst_req_set_app_id(app_inst_req *p_req, const char *app_id)
117 {
118     if (!p_req || !app_id)
119         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
120
121     p_req->appId = app_id;
122
123     return SECURITY_MANAGER_SUCCESS;
124 }
125
126 SECURITY_MANAGER_API
127 int security_manager_app_inst_req_set_pkg_id(app_inst_req *p_req, const char *pkg_id)
128 {
129     if (!p_req || !pkg_id)
130         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
131
132     p_req->pkgId = pkg_id;
133
134     return SECURITY_MANAGER_SUCCESS;
135 }
136
137 SECURITY_MANAGER_API
138 int security_manager_app_inst_req_add_privilege(app_inst_req *p_req, const char *privilege)
139 {
140     if (!p_req || !privilege)
141         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
142
143     p_req->privileges.push_back(privilege);
144
145     return SECURITY_MANAGER_SUCCESS;
146 }
147
148 SECURITY_MANAGER_API
149 int security_manager_app_inst_req_add_path(app_inst_req *p_req, const char *path, const int path_type)
150 {
151     if (!p_req || !path || (path_type < 0) || (path_type >= SECURITY_MANAGER_ENUM_END))
152         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
153
154     p_req->appPaths.push_back(std::make_pair(path, path_type));
155
156     return SECURITY_MANAGER_SUCCESS;
157 }
158
159 SECURITY_MANAGER_API
160 int security_manager_app_install(const app_inst_req *p_req)
161 {
162     using namespace SecurityManager;
163
164     return try_catch([&] {
165         //checking parameters
166         if (!p_req)
167             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
168         if (p_req->appId.empty() || p_req->pkgId.empty())
169             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
170
171         int retval;
172         ClientOffline offlineMode;
173         if (offlineMode.isOffline()) {
174             retval = SecurityManager::ServiceImpl().appInstall(*p_req, geteuid(), false);
175         } else {
176             MessageBuffer send, recv;
177
178             //put data into buffer
179             Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL,
180                 p_req->appId, p_req->pkgId, p_req->privileges, p_req->appPaths, p_req->uid);
181
182             //send buffer to server
183             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
184             if (retval != SECURITY_MANAGER_API_SUCCESS) {
185                 LogError("Error in sendToServer. Error code: " << retval);
186                 return SECURITY_MANAGER_ERROR_UNKNOWN;
187             }
188
189             //receive response from server
190             Deserialization::Deserialize(recv, retval);
191         }
192         switch(retval) {
193             case SECURITY_MANAGER_API_SUCCESS:
194                 return SECURITY_MANAGER_SUCCESS;
195             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
196                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
197             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
198                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
199             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
200                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
201             default:
202                 return SECURITY_MANAGER_ERROR_UNKNOWN;
203         }
204
205     });
206 }
207
208 SECURITY_MANAGER_API
209 int security_manager_app_uninstall(const app_inst_req *p_req)
210 {
211     using namespace SecurityManager;
212     MessageBuffer send, recv;
213
214     return try_catch([&] {
215         //checking parameters
216         if (!p_req)
217             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
218         if (p_req->appId.empty())
219             return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
220
221         //put data into buffer
222         Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL,
223             p_req->appId);
224
225         //send buffer to server
226         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
227         if (retval != SECURITY_MANAGER_API_SUCCESS) {
228             LogError("Error in sendToServer. Error code: " << retval);
229             return SECURITY_MANAGER_ERROR_UNKNOWN;
230         }
231
232         //receive response from server
233         Deserialization::Deserialize(recv, retval);
234         if (retval != SECURITY_MANAGER_API_SUCCESS)
235             return SECURITY_MANAGER_ERROR_UNKNOWN;
236
237         return SECURITY_MANAGER_SUCCESS;;
238     });
239 }
240
241 SECURITY_MANAGER_API
242 int security_manager_get_app_pkgid(char **pkg_id, const char *app_id)
243 {
244     using namespace SecurityManager;
245     MessageBuffer send, recv;
246
247     LogDebug("security_manager_get_app_pkgid() called");
248
249     return try_catch([&] {
250         //checking parameters
251
252         if (app_id == NULL) {
253             LogError("security_manager_app_get_pkgid: app_id is NULL");
254             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
255         }
256
257         if (pkg_id == NULL) {
258             LogError("security_manager_app_get_pkgid: pkg_id is NULL");
259             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
260         }
261
262         //put data into buffer
263         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID),
264             std::string(app_id));
265
266         //send buffer to server
267         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
268         if (retval != SECURITY_MANAGER_API_SUCCESS) {
269             LogDebug("Error in sendToServer. Error code: " << retval);
270             return SECURITY_MANAGER_ERROR_UNKNOWN;
271         }
272
273         //receive response from server
274         Deserialization::Deserialize(recv, retval);
275         if (retval != SECURITY_MANAGER_API_SUCCESS)
276             return SECURITY_MANAGER_ERROR_UNKNOWN;
277
278         std::string pkgIdString;
279         Deserialization::Deserialize(recv, pkgIdString);
280         if (pkgIdString.empty()) {
281             LogError("Unexpected empty pkgId");
282             return SECURITY_MANAGER_ERROR_UNKNOWN;
283         }
284
285         *pkg_id = strdup(pkgIdString.c_str());
286         if (*pkg_id == NULL) {
287             LogError("Failed to allocate memory for pkgId");
288             return SECURITY_MANAGER_ERROR_MEMORY;
289         }
290
291         return SECURITY_MANAGER_SUCCESS;
292     });
293 }
294
295 static bool setup_smack(const char *label)
296 {
297     int labelSize = strlen(label);
298
299     // Set Smack label for open socket file descriptors
300
301     std::unique_ptr<DIR, std::function<int(DIR*)>> dir(
302         opendir("/proc/self/fd"), closedir);
303     if (!dir.get()) {
304         LogError("Unable to read list of open file descriptors: " <<
305             strerror(errno));
306         return SECURITY_MANAGER_ERROR_UNKNOWN;
307     }
308
309     do {
310         errno = 0;
311         struct dirent *dirEntry = readdir(dir.get());
312         if (dirEntry == nullptr) {
313             if (errno == 0) // NULL return value also signals end of directory
314                 break;
315
316             LogError("Unable to read list of open file descriptors: " <<
317                 strerror(errno));
318             return SECURITY_MANAGER_ERROR_UNKNOWN;
319         }
320
321         // Entries with numerical names specify file descriptors, ignore the rest
322         if (!isdigit(dirEntry->d_name[0]))
323             continue;
324
325         struct stat statBuf;
326         int fd = atoi(dirEntry->d_name);
327         int ret = fstat(fd, &statBuf);
328         if (ret != 0) {
329             LogWarning("fstat failed on file descriptor " << fd << ": " <<
330                 strerror(errno));
331             continue;
332         }
333         if (S_ISSOCK(statBuf.st_mode)) {
334             ret = fsetxattr(fd, XATTR_NAME_SMACKIPIN, label, labelSize, 0);
335             if (ret != 0) {
336                 LogError("Setting Smack label failed on file descriptor " <<
337                     fd << ": " << strerror(errno));
338                 return SECURITY_MANAGER_ERROR_UNKNOWN;
339             }
340
341             ret = fsetxattr(fd, XATTR_NAME_SMACKIPOUT, label, labelSize, 0);
342             if (ret != 0) {
343                 LogError("Setting Smack label failed on file descriptor " <<
344                     fd << ": " << strerror(errno));
345                 return SECURITY_MANAGER_ERROR_UNKNOWN;
346             }
347         }
348     } while (true);
349
350     // Set Smack label of current process
351     smack_set_label_for_self(label);
352
353     return SECURITY_MANAGER_SUCCESS;
354 }
355
356 SECURITY_MANAGER_API
357 int security_manager_set_process_label_from_appid(const char *app_id)
358 {
359     int ret;
360     std::string appLabel;
361
362     LogDebug("security_manager_set_process_label_from_appid() called");
363
364     if (smack_smackfs_path() == NULL)
365         return SECURITY_MANAGER_SUCCESS;
366
367     // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
368     //       are implemented.
369     std::string zoneId;
370     if (!getZoneIdFromPid(getpid(), zoneId)) {
371         LogError("Failed to get ID of zone");
372         return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
373     }
374
375     try {
376         appLabel = SecurityManager::zoneSmackLabelGenerate(
377                 SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
378
379     } catch (...) {
380         LogError("Failed to generate smack label for appId: " << app_id);
381         return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
382     }
383
384     if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
385         LogError("Failed to set smack label " << appLabel << " for current process");
386         return ret;
387     }
388
389     return SECURITY_MANAGER_SUCCESS;
390 }
391
392 SECURITY_MANAGER_API
393 int security_manager_set_process_groups_from_appid(const char *app_id)
394 {
395     using namespace SecurityManager;
396     MessageBuffer send, recv;
397     int ret;
398
399     LogDebug("security_manager_set_process_groups_from_appid() called");
400
401     return try_catch([&] {
402         //checking parameters
403
404         if (app_id == nullptr) {
405             LogError("app_id is NULL");
406             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
407         }
408
409         //put data into buffer
410         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS),
411             std::string(app_id));
412
413         //send buffer to server
414         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
415         if (retval != SECURITY_MANAGER_API_SUCCESS) {
416             LogDebug("Error in sendToServer. Error code: " << retval);
417             return SECURITY_MANAGER_ERROR_UNKNOWN;
418         }
419
420         //receive response from server
421         Deserialization::Deserialize(recv, retval);
422         if (retval != SECURITY_MANAGER_API_SUCCESS) {
423             LogError("Failed to get list of groups from security-manager service. Error code: " << retval);
424             return SECURITY_MANAGER_ERROR_UNKNOWN;
425         }
426
427         //How many new groups?
428         int newGroupsCnt;
429         Deserialization::Deserialize(recv, newGroupsCnt);
430
431         //And how many groups do we belong to already?
432         int oldGroupsCnt;
433         ret = getgroups(0, nullptr);
434         if (ret == -1) {
435             LogError("Unable to get list of current supplementary groups: " <<
436                 strerror(errno));
437             return SECURITY_MANAGER_ERROR_UNKNOWN;
438         }
439         oldGroupsCnt = ret;
440
441         //Allocate an array for both old and new groups gids
442         std::unique_ptr<gid_t[]> groups(new gid_t[oldGroupsCnt + newGroupsCnt]);
443         if (!groups.get()) {
444             LogError("Memory allocation failed.");
445             return SECURITY_MANAGER_ERROR_MEMORY;
446         }
447
448         //Get the old groups from process
449         ret = getgroups(oldGroupsCnt, groups.get());
450         if (ret == -1) {
451             LogError("Unable to get list of current supplementary groups: " <<
452                 strerror(errno));
453             return SECURITY_MANAGER_ERROR_UNKNOWN;
454         }
455
456         //Get the new groups from server response
457         for (int i = 0; i < newGroupsCnt; ++i) {
458             gid_t gid;
459             Deserialization::Deserialize(recv, gid);
460             groups.get()[oldGroupsCnt + i] = gid;
461             LogDebug("Adding process to group " << gid);
462         }
463
464         //Apply the modified groups list
465         ret = setgroups(oldGroupsCnt + newGroupsCnt, groups.get());
466         if (ret == -1) {
467             LogError("Unable to get list of current supplementary groups: " <<
468                 strerror(errno));
469             return SECURITY_MANAGER_ERROR_UNKNOWN;
470         }
471
472         return SECURITY_MANAGER_SUCCESS;
473     });
474 }
475
476 SECURITY_MANAGER_API
477 int security_manager_drop_process_privileges(void)
478 {
479     LogDebug("security_manager_drop_process_privileges() called");
480
481     int ret;
482     cap_t cap = cap_init();
483     if (!cap) {
484         LogError("Unable to allocate capability object");
485         return SECURITY_MANAGER_ERROR_MEMORY;
486     }
487
488     ret = cap_clear(cap);
489     if (ret) {
490         LogError("Unable to initialize capability object");
491         cap_free(cap);
492         return SECURITY_MANAGER_ERROR_UNKNOWN;
493     }
494
495     ret = cap_set_proc(cap);
496     if (ret) {
497         LogError("Unable to drop process capabilities");
498         cap_free(cap);
499         return SECURITY_MANAGER_ERROR_UNKNOWN;
500     }
501
502     cap_free(cap);
503     return SECURITY_MANAGER_SUCCESS;
504 }
505
506 SECURITY_MANAGER_API
507 int security_manager_prepare_app(const char *app_id)
508 {
509     LogDebug("security_manager_prepare_app() called");
510     int ret;
511
512     ret = security_manager_set_process_label_from_appid(app_id);
513     if (ret != SECURITY_MANAGER_SUCCESS)
514         return ret;
515
516     ret = security_manager_set_process_groups_from_appid(app_id);
517     if (ret != SECURITY_MANAGER_SUCCESS) {
518         LogWarning("Unable to setup process groups for application. Privileges with direct access to resources will not work.");
519         ret = SECURITY_MANAGER_SUCCESS;
520     }
521
522     ret = security_manager_drop_process_privileges();
523     return ret;
524 }
525
526 SECURITY_MANAGER_API
527 int security_manager_user_req_new(user_req **pp_req)
528 {
529     if (!pp_req)
530         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
531     try {
532         *pp_req = new user_req;
533     } catch (std::bad_alloc& ex) {
534         return SECURITY_MANAGER_ERROR_MEMORY;
535     }
536     return SECURITY_MANAGER_SUCCESS;
537 }
538
539 SECURITY_MANAGER_API
540 void security_manager_user_req_free(user_req *p_req)
541 {
542     delete p_req;
543 }
544
545 SECURITY_MANAGER_API
546 int security_manager_user_req_set_uid(user_req *p_req, uid_t uid)
547 {
548     if (!p_req)
549         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
550
551     p_req->uid = uid;
552
553     return SECURITY_MANAGER_SUCCESS;
554 }
555
556 SECURITY_MANAGER_API
557 int security_manager_user_req_set_user_type(user_req *p_req, security_manager_user_type utype)
558 {
559     if (!p_req)
560         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
561
562     p_req->utype = static_cast<int>(utype);
563
564     return SECURITY_MANAGER_SUCCESS;
565 }
566
567 SECURITY_MANAGER_API
568 int security_manager_user_add(const user_req *p_req)
569 {
570     using namespace SecurityManager;
571     if (!p_req)
572         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
573
574     return try_catch([&] {
575         int retval;
576         ClientOffline offlineMode;
577         if (offlineMode.isOffline()) {
578             retval = SecurityManager::ServiceImpl().userAdd(p_req->uid, p_req->utype, geteuid(),
579                                                            false);
580         } else {
581             MessageBuffer send, recv;
582             //server is working
583
584             //put data into buffer
585             Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD),
586                 p_req->uid, p_req->utype);
587
588             //send buffer to server
589             retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
590             if (retval != SECURITY_MANAGER_API_SUCCESS) {
591                 LogError("Error in sendToServer. Error code: " << retval);
592                 return SECURITY_MANAGER_ERROR_UNKNOWN;
593             }
594
595             //receive response from server
596             Deserialization::Deserialize(recv, retval);
597         }
598         switch(retval) {
599         case SECURITY_MANAGER_API_SUCCESS:
600             return SECURITY_MANAGER_SUCCESS;
601         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
602             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
603         default:
604             return SECURITY_MANAGER_ERROR_UNKNOWN;
605         }
606     });
607 }
608
609 SECURITY_MANAGER_API
610 int security_manager_user_delete(const user_req *p_req)
611 {
612     using namespace SecurityManager;
613     MessageBuffer send, recv;
614     if (!p_req)
615         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
616     return try_catch([&] {
617
618         //put data into buffer
619         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE),
620             p_req->uid);
621
622         //send buffer to server
623         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
624         if (retval != SECURITY_MANAGER_API_SUCCESS) {
625             LogError("Error in sendToServer. Error code: " << retval);
626             return SECURITY_MANAGER_ERROR_UNKNOWN;
627         }
628
629         //receive response from server
630         Deserialization::Deserialize(recv, retval);
631         switch(retval) {
632         case SECURITY_MANAGER_API_SUCCESS:
633             return SECURITY_MANAGER_SUCCESS;
634         case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
635             return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
636         default:
637             return SECURITY_MANAGER_ERROR_UNKNOWN;
638         }
639     });
640 }
641
642
643 /***************************POLICY***************************************/
644
645 SECURITY_MANAGER_API
646 int security_manager_policy_update_req_new(policy_update_req **pp_req)
647 {
648     if (!pp_req)
649         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
650
651     try {
652         *pp_req = new policy_update_req;
653     } catch (std::bad_alloc& ex) {
654         return SECURITY_MANAGER_ERROR_MEMORY;
655     }
656
657     return SECURITY_MANAGER_SUCCESS;
658 }
659
660 SECURITY_MANAGER_API
661 void security_manager_policy_update_req_free(policy_update_req *p_req)
662 {
663     delete p_req;
664 }
665
666 SECURITY_MANAGER_API
667 int security_manager_policy_update_send(policy_update_req *p_req)
668 {
669     using namespace SecurityManager;
670     MessageBuffer send, recv;
671
672     if (p_req == nullptr || p_req->units.size() == 0)
673         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
674
675     return try_catch([&] {
676
677         //put request into buffer
678         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE),
679             p_req->units);
680
681         //send it to server
682         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
683         if (retval != SECURITY_MANAGER_API_SUCCESS) {
684             LogError("Error in sendToServer. Error code: " << retval);
685             return SECURITY_MANAGER_ERROR_UNKNOWN;
686         }
687
688         //receive response from server
689         Deserialization::Deserialize(recv, retval);
690         switch(retval) {
691             case SECURITY_MANAGER_API_SUCCESS:
692                 return SECURITY_MANAGER_SUCCESS;
693             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
694                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
695             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
696                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
697             default:
698                 return SECURITY_MANAGER_ERROR_UNKNOWN;
699         }
700     });
701 }
702
703 static inline int security_manager_get_policy_internal(
704         SecurityManager::SecurityModuleCall call_type,
705         policy_entry *p_filter,
706         policy_entry ***ppp_privs_policy,
707         size_t *p_size)
708 {
709     using namespace SecurityManager;
710     MessageBuffer send, recv;
711
712     if (ppp_privs_policy == nullptr
713         || p_size == nullptr
714         || p_filter == nullptr)
715         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
716
717     return try_catch([&] {
718         //put request into buffer
719         Serialization::Serialize(send, static_cast<int>(call_type),
720             *p_filter);
721
722         //send it to server
723         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
724         if (retval != SECURITY_MANAGER_API_SUCCESS) {
725             LogError("Error in sendToServer. Error code: " << retval);
726             return SECURITY_MANAGER_ERROR_UNKNOWN;
727         }
728         //receive response from server
729         Deserialization::Deserialize(recv, retval);
730         switch (retval) {
731             case SECURITY_MANAGER_API_SUCCESS: {
732                 //extract and allocate buffers for privs policy entries
733                 int entriesCnt = 0;
734                 policy_entry **entries = nullptr;
735                 try {
736                     Deserialization::Deserialize(recv, entriesCnt);
737                     entries = new policy_entry*[entriesCnt]();
738                     for (int i = 0; i < entriesCnt; ++i) {
739                         entries[i] = new policy_entry;
740                         Deserialization::Deserialize(recv, entries[i]);
741                     };
742                 } catch (...) {
743                     LogError("Error while parsing server response");
744                     for (int i = 0; i < entriesCnt; ++i)
745                         delete(entries[i]);
746                     delete[] entries;
747                     return SECURITY_MANAGER_ERROR_UNKNOWN;
748                 }
749                 *p_size = entriesCnt;
750                 *ppp_privs_policy = entries;
751                 return SECURITY_MANAGER_SUCCESS;
752             }
753             case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
754                 return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
755
756             case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
757                 return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
758
759             default:
760                 return SECURITY_MANAGER_ERROR_UNKNOWN;
761         }
762     });
763 }
764
765 SECURITY_MANAGER_API
766 int security_manager_get_configured_policy_for_admin(
767         policy_entry *p_filter,
768         policy_entry ***ppp_privs_policy,
769         size_t *p_size)
770 {
771     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
772 }
773
774 SECURITY_MANAGER_API
775 int security_manager_get_configured_policy_for_self(
776         policy_entry *p_filter,
777         policy_entry ***ppp_privs_policy,
778         size_t *p_size)
779 {
780     return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
781 }
782
783 SECURITY_MANAGER_API
784 int security_manager_get_policy(
785         policy_entry *p_filter,
786         policy_entry ***ppp_privs_policy,
787         size_t *p_size)
788 {
789     return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
790 };
791
792 SECURITY_MANAGER_API
793 int security_manager_policy_entry_new(policy_entry **p_entry)
794 {
795     if (!p_entry)
796         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
797
798     try {
799         *p_entry = new policy_entry;
800     } catch (std::bad_alloc& ex) {
801         return SECURITY_MANAGER_ERROR_MEMORY;
802     }
803
804     return SECURITY_MANAGER_SUCCESS;
805 }
806
807 SECURITY_MANAGER_API
808 void security_manager_policy_entry_free(policy_entry *p_entry)
809 {
810     delete p_entry;
811 }
812
813 SECURITY_MANAGER_API
814 int security_manager_policy_entry_set_application(policy_entry *p_entry, const char *app_id)
815 {
816     if (!p_entry)
817         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
818     p_entry->appId = app_id;
819     return  SECURITY_MANAGER_SUCCESS;
820 }
821
822 SECURITY_MANAGER_API
823 int security_manager_policy_entry_set_user(policy_entry *p_entry, const char *user)
824 {
825     if (!p_entry)
826         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
827     p_entry->user = user;
828     return  SECURITY_MANAGER_SUCCESS;
829 }
830
831 SECURITY_MANAGER_API
832 int security_manager_policy_entry_set_privilege(policy_entry *p_entry, const char *privilege)
833 {
834     if (!p_entry)
835         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
836     p_entry->privilege = privilege;
837     return  SECURITY_MANAGER_SUCCESS;
838 }
839
840 SECURITY_MANAGER_API
841 int security_manager_policy_entry_set_level(policy_entry *p_entry, const char *policy_level)
842 {
843     if (!p_entry)
844         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
845     p_entry->currentLevel = policy_level;
846     p_entry->maxLevel = EMPTY;
847     return  SECURITY_MANAGER_SUCCESS;
848 }
849
850 SECURITY_MANAGER_API
851 int security_manager_policy_entry_admin_set_level(policy_entry *p_entry, const char *policy_level)
852 {
853     if (!p_entry)
854         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
855     p_entry->maxLevel = policy_level;
856     p_entry->currentLevel = EMPTY;
857     return  SECURITY_MANAGER_SUCCESS;
858 }
859
860 SECURITY_MANAGER_API
861 int security_manager_policy_update_req_add_entry(policy_update_req *p_req, const policy_entry *p_entry)
862 {
863     if (!p_entry || !p_req)
864         return  SECURITY_MANAGER_ERROR_INPUT_PARAM;
865     p_req->units.push_back(p_entry);
866
867     return  SECURITY_MANAGER_SUCCESS;
868 }
869
870 SECURITY_MANAGER_API
871 const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
872 {
873     return p_entry ? p_entry->user.c_str() : nullptr;
874 }
875
876 SECURITY_MANAGER_API
877 const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
878 {
879     return p_entry ? p_entry->appId.c_str() : nullptr;
880 }
881 SECURITY_MANAGER_API
882 const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
883 {
884     return p_entry ? p_entry->privilege.c_str() : nullptr;
885 }
886 SECURITY_MANAGER_API
887 const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
888 {
889     return p_entry ? p_entry->currentLevel.c_str() : nullptr;
890 }
891
892 SECURITY_MANAGER_API
893 const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
894 {
895     return p_entry ? p_entry->maxLevel.c_str() : nullptr;
896 }
897
898 SECURITY_MANAGER_API
899 void security_manager_policy_entries_free(policy_entry *p_entries, const size_t size)
900 {
901     for (size_t i = 0; i < size; i++) {
902         delete &p_entries[i];
903     }
904     delete [] p_entries;
905 }
906
907 SECURITY_MANAGER_API
908 int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
909 {
910     using namespace SecurityManager;
911     MessageBuffer send, recv;
912     if (!levels || !levels_count)
913         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
914     return try_catch([&] {
915
916         //put data into buffer
917         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
918
919         //send buffer to server
920         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
921         if (retval != SECURITY_MANAGER_API_SUCCESS) {
922             LogError("Error in sendToServer. Error code: " << retval);
923             return SECURITY_MANAGER_ERROR_UNKNOWN;
924         }
925
926         //receive response from server
927         Deserialization::Deserialize(recv, retval);
928
929         switch(retval) {
930             case SECURITY_MANAGER_API_SUCCESS:
931                 // success - continue
932                 break;
933             case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
934                 return SECURITY_MANAGER_ERROR_MEMORY;
935             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
936                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
937             default:
938                 return SECURITY_MANAGER_ERROR_UNKNOWN;
939         }
940
941         int count;
942         Deserialization::Deserialize(recv, count);
943         *levels_count = count;
944         LogInfo("Number of policy descriptions: " << *levels_count);
945
946         char **array = new char *[*levels_count];
947
948         for (unsigned int i = 0; i < *levels_count; ++i) {
949             std::string level;
950             Deserialization::Deserialize(recv, level);
951
952             if (level.empty()) {
953                 LogError("Unexpected empty level");
954                 return SECURITY_MANAGER_ERROR_UNKNOWN;
955             }
956
957             array[i] = strdup(level.c_str());
958             if (array[i] == nullptr)
959                 return SECURITY_MANAGER_ERROR_MEMORY;
960         }
961
962         *levels = array;
963
964         return SECURITY_MANAGER_SUCCESS;
965     });
966 }
967
968 SECURITY_MANAGER_API
969 void security_manager_policy_levels_free(char **levels, size_t levels_count)
970 {
971     for (unsigned int i = 0; i < levels_count; i++)
972         free(levels[i]);
973
974     delete[] levels;
975 }
976
977 lib_retcode get_privileges_mapping(const std::string &from_version,
978                                    const std::string &to_version,
979                                    const std::vector<std::string> &privileges,
980                                    char ***privileges_mappings,
981                                    size_t *mappings_count)
982 {
983     using namespace SecurityManager;
984     MessageBuffer send, recv;
985     Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GET_PRIVILEGES_MAPPING));
986     Serialization::Serialize(send, from_version);
987     Serialization::Serialize(send, to_version);
988     Serialization::Serialize(send, privileges);
989
990     //send buffer to server
991     int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
992     if (retval != SECURITY_MANAGER_API_SUCCESS) {
993         LogError("Error in sendToServer. Error code: " << retval);
994         return SECURITY_MANAGER_ERROR_UNKNOWN;
995     }
996
997     //receive response from server
998     Deserialization::Deserialize(recv, retval);
999
1000     switch(retval) {
1001         case SECURITY_MANAGER_API_SUCCESS:
1002             // success - continue
1003             break;
1004         case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1005             return SECURITY_MANAGER_ERROR_MEMORY;
1006         case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1007             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1008         default:
1009             return SECURITY_MANAGER_ERROR_UNKNOWN;
1010     }
1011
1012     unsigned int count;
1013     Deserialization::Deserialize(recv, count);
1014     LogInfo("Number of privilege mappings: " << count);
1015     size_t i = 0;
1016     auto free_mapping = std::bind(security_manager_privilege_mapping_free,
1017                                   std::placeholders::_1, std::ref(i));
1018     std::unique_ptr<char *[], decltype (free_mapping)> mappings_ptr(new char *[count], free_mapping);
1019
1020     for (; i < count; ++i) {
1021         std::string privilege_mapping;
1022         Deserialization::Deserialize(recv, privilege_mapping);
1023         if (privilege_mapping.empty()) {
1024             LogError("Unexpected empty privilege mapping");
1025             return SECURITY_MANAGER_ERROR_UNKNOWN;
1026         }
1027
1028         mappings_ptr.get()[i] = strdup(privilege_mapping.c_str());
1029         if (mappings_ptr.get()[i] == nullptr)
1030             return SECURITY_MANAGER_ERROR_MEMORY;
1031     }
1032
1033     *privileges_mappings = mappings_ptr.release();
1034     *mappings_count = count;
1035
1036     return SECURITY_MANAGER_SUCCESS;
1037 }
1038
1039 SECURITY_MANAGER_API
1040 int security_manager_get_privileges_mapping(const char *from_version,
1041                                              const char *to_version,
1042                                              char const * const *privileges,
1043                                              size_t privileges_count,
1044                                              char ***privileges_mappings,
1045                                              size_t *mappings_count)
1046 {
1047     if (from_version == nullptr || privileges_mappings == nullptr || mappings_count == nullptr) {
1048         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1049     }
1050     return try_catch([&] {
1051         std::vector<std::string> privilegesToMap;
1052         if (privileges != nullptr) {
1053             privilegesToMap.reserve(privileges_count);
1054             privilegesToMap.insert(privilegesToMap.end(), privileges, privileges + privileges_count);
1055         }
1056         if (to_version == nullptr)
1057             to_version = "";
1058         LogDebug("security_manager_get_privileges_mapping() called with :"
1059                  " from_version = " << from_version << " to_version = " << to_version <<
1060                  " privileges_count " << privilegesToMap.size());
1061
1062         return get_privileges_mapping(from_version, to_version, privilegesToMap,
1063                                       privileges_mappings, mappings_count);
1064
1065     });
1066 }
1067 SECURITY_MANAGER_API
1068 void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
1069 {
1070     for(size_t i = 0; i < mappings_count; i++)
1071         free(privileges_mappings[i]);
1072     delete [] privileges_mappings;
1073 }
1074
1075 SECURITY_MANAGER_API
1076 int security_manager_groups_get(char ***groups, size_t *groups_count)
1077 {
1078     using namespace SecurityManager;
1079     MessageBuffer send, recv;
1080     if (!groups || !groups_count)
1081         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1082     return try_catch([&] {
1083
1084         //put data into buffer
1085         Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GROUPS_GET));
1086
1087         //send buffer to server
1088         int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
1089         if (retval != SECURITY_MANAGER_API_SUCCESS) {
1090             LogError("Error in sendToServer. Error code: " << retval);
1091             return SECURITY_MANAGER_ERROR_UNKNOWN;
1092         }
1093
1094         //receive response from server
1095         Deserialization::Deserialize(recv, retval);
1096
1097         switch(retval) {
1098             case SECURITY_MANAGER_API_SUCCESS:
1099                 // success - continue
1100                 break;
1101             case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
1102                 return SECURITY_MANAGER_ERROR_MEMORY;
1103             case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
1104                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
1105             default:
1106                 return SECURITY_MANAGER_ERROR_UNKNOWN;
1107         }
1108
1109         std::vector<std::string> vgroups;
1110         Deserialization::Deserialize(recv, vgroups);
1111         const auto vgroups_size = vgroups.size();
1112         LogInfo("Number of groups: " << vgroups_size);
1113
1114         std::unique_ptr<char *, std::function<void(char **)>> array(
1115             static_cast<char **>(calloc(vgroups_size, sizeof(char *))),
1116             std::bind(security_manager_groups_free, std::placeholders::_1, vgroups_size));
1117
1118         if (array == nullptr)
1119             return SECURITY_MANAGER_ERROR_MEMORY;
1120
1121         for (size_t i = 0; i < vgroups_size; ++i) {
1122             const auto &group = vgroups.at(i);
1123
1124             if (group.empty()) {
1125                 LogError("Unexpected empty group");
1126                 return SECURITY_MANAGER_ERROR_UNKNOWN;
1127             }
1128
1129             array.get()[i] = strdup(group.c_str());
1130             if (array.get()[i] == nullptr)
1131                 return SECURITY_MANAGER_ERROR_MEMORY;
1132         }
1133
1134         *groups_count = vgroups_size;
1135         *groups = array.release();
1136
1137         return SECURITY_MANAGER_SUCCESS;
1138     });
1139 }
1140
1141 SECURITY_MANAGER_API
1142 void security_manager_groups_free(char **groups, size_t groups_count)
1143 {
1144     if (groups == nullptr)
1145         return;
1146
1147     for (size_t i = 0; i < groups_count; i++)
1148         free(groups[i]);
1149
1150     free(groups);
1151 }