Fix return value check from privilege_db_manager_get_mapped_privilege_list
[platform/core/security/askuser.git] / src / common / policy / PrivilegeInfo.cpp
1 /*
2  *  Copyright (c) 2016-2018 Samsung Electronics Co.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /**
17  * @file        src/agent/notification-daemon/Privilege.cpp
18  * @author      Zofia Grzelewska <z.abramowska@samsung.com>
19  * @brief       Implementation of Privilege Info wrappers
20  */
21
22 #include <cstdlib>
23 #include <memory>
24 #include <set>
25
26 #include "Policy.h"
27 #include "PrivilegeInfo.h"
28
29 #include <exception/Exception.h>
30 #include <log/alog.h>
31 #include <policy/AppInfo.h>
32
33 #include <privilegemgr/privilege_info.h>
34 #include <privilegemgr/privilege_db_manager.h>
35 #include <glib.h>
36
37 namespace AskUser {
38
39 namespace PrivilegeInfo {
40
41 namespace {
42
43 class GListWrap {
44 public:
45     GListWrap() : m_head(nullptr) {
46         m_head = g_list_alloc();
47         if (!m_head) {
48             ALOGE("Failed to allocate glib list");
49             // FIXME : throw
50         }
51     }
52
53     GListWrap(GList *_list) : m_head(_list) {}
54
55     ~GListWrap() { g_list_free(m_head);}
56
57     void append(gpointer data) {
58         GList *newHead = g_list_prepend(m_head, data);
59         if (newHead == nullptr) {
60             ALOGE("Failed to prepend the glib list");
61             return;
62         }
63         m_head = newHead;
64     }
65     GList * get() { return m_head; }
66
67 private:
68     GList *m_head;
69 };
70
71 Privacy getPrivacyName(const Privilege &privilege) {
72     char* privacyName = nullptr;
73     int ret = privilege_info_get_privacy_by_privilege(privilege.c_str(), &privacyName);
74     if (ret != PRVMGR_ERR_NONE || !privacyName) {
75         ALOGE("Unable to get privacy group for privilege: <" << privilege << ">, err: <" << ret << ">");
76         return privilege;
77     }
78
79     std::unique_ptr<char, decltype(free) *> privacyNamePtr(privacyName, free);
80     return std::string(privacyName);
81 }
82
83 } //namespace anonymous
84
85 std::vector<Privacy> getPrivilegesPrivacies(const std::vector<std::string> &corePrivileges) {
86     std::set<Privacy> privaciesSet;
87     for (auto &privilege : corePrivileges) {
88         ALOGD("Getting privacy for privilege : " << privilege);
89         if (!isPrivacy(privilege)) {
90             ALOGD("Privilege " << privilege << " is not privacy, skipping");
91             continue;
92         }
93         Privacy privacy = getPrivacyName(privilege);
94         if (privacy.empty()) {
95             // FIXME: should we abort whole request or ignore privilege which cannot be mapped to privacy?
96             ALOGE("Something went wrong with fetching privacy name for " << privilege << ", aborting");
97             return {};
98         } else {
99             ALOGD("Privilege belongs to privacy " << privacy);
100         }
101         privaciesSet.insert(privacy);
102     }
103     return std::vector<Privacy>(privaciesSet.begin(), privaciesSet.end());
104 }
105
106 std::vector<Privilege> getPrivilegeMapping(const std::string &appId, const Privilege &privilege) {
107     ALOGD("Mapping privilege " << privilege);
108     AppInfo app(appId, geteuid());
109     std::string version = app.apiVersion();
110     std::string type = app.type();
111
112     if (version.empty() || type.empty()) {
113         ALOGE("Failed to fetch application version and type");
114         return {};
115     }
116     ALOGD("App " << appId << " is of type " << type << " and version " << version);
117
118     privilege_manager_package_type_e pkgType;
119     if (type == "c++app" || type == "capp") {
120         pkgType = PRVMGR_PACKAGE_TYPE_CORE;
121     } else if (type == "webapp") {
122         pkgType = PRVMGR_PACKAGE_TYPE_WRT;
123     } else {
124         ALOGD("Application type not supported by mapping : " << type);
125         return {privilege};
126     }
127
128     GListWrap privList;
129     privList.append(const_cast<void*>(static_cast<const void *>(privilege.c_str())));
130
131     GList *privMapped = nullptr;
132     int ret = privilege_db_manager_get_mapped_privilege_list(version.c_str(), pkgType, privList.get(), &privMapped);
133     if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE || !privMapped) {
134         ALOGE("Unable to get mapping of privilege " << privilege << "; err: <" << ret <<  ">");
135         return {};
136     }
137
138     GListWrap privMappedWrap(privMapped);
139     std::vector<std::string> privMappedVector;
140     for (GList *l = privMappedWrap.get(); l != NULL; l = l->next) {
141         std::string corePriv = static_cast<char*>(l->data);
142         ALOGD("Privilege mapps to " << corePriv);
143         privMappedVector.push_back(std::move(corePriv));
144     }
145
146     return privMappedVector;
147 }
148
149 bool isPrivacy(const Privilege &privilege) {
150     return privilege_info_is_privacy(privilege.c_str()) == 1;
151 }
152
153 std::string getPrivacyDisplayName(const Privacy &privacy) {
154     char *displayName = nullptr;
155     int ret = privilege_info_get_privacy_display(privacy.c_str(), &displayName);
156     if (ret != PRVMGR_ERR_NONE || !displayName) {
157         ALOGE("Unable to get privacy display name for <" << privacy << ">, err: <" << ret << ">");
158         return privacy;
159     }
160     std::unique_ptr<char, decltype(free)*> displaNamePtr(displayName, free);
161     return std::string(displayName);
162 }
163
164 std::vector<Privilege> getPrivacyPrivileges(const Privacy &privacy) {
165     GList *privilegeList = nullptr;
166
167     int ret = privilege_info_get_privilege_list_by_privacy(privacy.c_str(), &privilegeList);
168     if (ret != PRVMGR_ERR_NONE || !privilegeList) {
169         ALOGE("Unable to get privacy group list of privileges; err: <" << ret <<  ">");
170         return {privacy};
171     }
172
173     GListWrap privList(privilegeList);
174     std::vector<Privilege> privVector;
175     for (GList *l = privList.get(); l != NULL; l = l->next) {
176         privVector.push_back(static_cast<char*>(l->data));
177     }
178     return privVector;
179 }
180
181 }
182 } /* namespace AskUser */