2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * @author Rafal Krypa <r.krypa@samsung.com>
21 * @brief Wrapper class for Cynara interface
27 #include <dpl/log/log.h>
29 namespace SecurityManager {
32 CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user,
33 const std::string &privilege, Operation operation,
34 const std::string &bucket)
36 this->client = strdup(client.c_str());
37 this->user = strdup(user.c_str());
38 this->privilege = strdup(privilege.c_str());
39 this->bucket = strdup(bucket.c_str());
41 if (this->bucket == nullptr || this->client == nullptr ||
42 this->user == nullptr || this->privilege == nullptr) {
46 free(this->privilege);
47 ThrowMsg(CynaraException::OutOfMemory,
48 std::string("Error in CynaraAdminPolicy allocation."));
51 this->result = static_cast<int>(operation);
52 this->result_extra = nullptr;
55 CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user,
56 const std::string &privilege, const std::string &goToBucket,
57 const std::string &bucket)
59 this->bucket = strdup(bucket.c_str());
60 this->client = strdup(client.c_str());
61 this->user = strdup(user.c_str());
62 this->privilege = strdup(privilege.c_str());
63 this->result_extra = strdup(goToBucket.c_str());
64 this->result = CYNARA_ADMIN_BUCKET;
66 if (this->bucket == nullptr || this->client == nullptr ||
67 this->user == nullptr || this->privilege == nullptr ||
68 this->result_extra == nullptr) {
72 free(this->privilege);
73 free(this->result_extra);
74 ThrowMsg(CynaraException::OutOfMemory,
75 std::string("Error in CynaraAdminPolicy allocation."));
79 CynaraAdminPolicy::CynaraAdminPolicy(CynaraAdminPolicy &&that)
84 privilege = that.privilege;
85 result_extra = that.result_extra;
88 that.bucket = nullptr;
89 that.client = nullptr;
91 that.privilege = nullptr;
92 that.result_extra = nullptr;
95 CynaraAdminPolicy::~CynaraAdminPolicy()
100 free(this->privilege);
101 free(this->result_extra);
104 static bool checkCynaraError(int result, const std::string &msg)
107 case CYNARA_API_SUCCESS:
108 case CYNARA_API_ACCESS_ALLOWED:
110 case CYNARA_API_ACCESS_DENIED:
112 case CYNARA_API_OUT_OF_MEMORY:
113 ThrowMsg(CynaraException::OutOfMemory, msg);
114 case CYNARA_API_INVALID_PARAM:
115 ThrowMsg(CynaraException::InvalidParam, msg);
116 case CYNARA_API_SERVICE_NOT_AVAILABLE:
117 ThrowMsg(CynaraException::ServiceNotAvailable, msg);
119 ThrowMsg(CynaraException::UnknownError, msg);
123 CynaraAdmin::CynaraAdmin()
126 cynara_admin_initialize(&m_CynaraAdmin),
127 "Cannot connect to Cynara administrative interface.");
130 CynaraAdmin::~CynaraAdmin()
132 cynara_admin_finish(m_CynaraAdmin);
135 CynaraAdmin &CynaraAdmin::getInstance()
137 static CynaraAdmin cynaraAdmin;
141 void CynaraAdmin::SetPolicies(const std::vector<CynaraAdminPolicy> &policies)
143 std::vector<const struct cynara_admin_policy *> pp_policies(policies.size() + 1);
145 LogDebug("Sending " << policies.size() << " policies to Cynara");
146 for (std::size_t i = 0; i < policies.size(); ++i) {
147 pp_policies[i] = static_cast<const struct cynara_admin_policy *>(&policies[i]);
148 LogDebug("policies[" << i << "] = {" <<
149 ".bucket = " << pp_policies[i]->bucket << ", " <<
150 ".client = " << pp_policies[i]->client << ", " <<
151 ".user = " << pp_policies[i]->user << ", " <<
152 ".privilege = " << pp_policies[i]->privilege << ", " <<
153 ".result = " << pp_policies[i]->result << ", " <<
154 ".result_extra = " << pp_policies[i]->result_extra << "}");
157 pp_policies[policies.size()] = nullptr;
160 cynara_admin_set_policies(m_CynaraAdmin, pp_policies.data()),
161 "Error while updating Cynara policy.");
164 void CynaraAdmin::UpdateAppPolicy(
165 const std::string &label,
166 const std::string &user,
167 const std::vector<std::string> &oldPrivileges,
168 const std::vector<std::string> &newPrivileges)
170 std::vector<CynaraAdminPolicy> policies;
172 // Perform sort-merge join on oldPrivileges and newPrivileges.
173 // Assume that they are already sorted and without duplicates.
174 auto oldIter = oldPrivileges.begin();
175 auto newIter = newPrivileges.begin();
177 while (oldIter != oldPrivileges.end() && newIter != newPrivileges.end()) {
178 int compare = oldIter->compare(*newIter);
180 LogDebug("(user = " << user << " label = " << label << ") " <<
181 "keeping privilege " << *newIter);
185 } else if (compare < 0) {
186 LogDebug("(user = " << user << " label = " << label << ") " <<
187 "removing privilege " << *oldIter);
188 policies.push_back(CynaraAdminPolicy(label, user, *oldIter,
189 CynaraAdminPolicy::Operation::Delete));
192 LogDebug("(user = " << user << " label = " << label << ") " <<
193 "adding privilege " << *newIter);
194 policies.push_back(CynaraAdminPolicy(label, user, *newIter,
195 CynaraAdminPolicy::Operation::Allow));
200 for (; oldIter != oldPrivileges.end(); ++oldIter) {
201 LogDebug("(user = " << user << " label = " << label << ") " <<
202 "removing privilege " << *oldIter);
203 policies.push_back(CynaraAdminPolicy(label, user, *oldIter,
204 CynaraAdminPolicy::Operation::Delete));
207 for (; newIter != newPrivileges.end(); ++newIter) {
208 LogDebug("(user = " << user << " label = " << label << ") " <<
209 "adding privilege " << *newIter);
210 policies.push_back(CynaraAdminPolicy(label, user, *newIter,
211 CynaraAdminPolicy::Operation::Allow));
214 SetPolicies(policies);
220 cynara_initialize(&m_Cynara, nullptr),
221 "Cannot connect to Cynara policy interface.");
226 cynara_finish(m_Cynara);
229 Cynara &Cynara::getInstance()
231 static Cynara cynara;
235 bool Cynara::check(const std::string &label, const std::string &privilege,
236 const std::string &user, const std::string &session)
238 return checkCynaraError(
239 cynara_check(m_Cynara,
240 label.c_str(), session.c_str(), user.c_str(), privilege.c_str()),
241 "Cannot check permission with Cynara.");
244 } // namespace SecurityManager