2 * Copyright (c) 2016 Samsung Electronics Co.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 * @file src/notification-daemon/GuiRunner.h
18 * @author Oskar Ĺwitalski <o.switalski@samsung.com>
19 * @brief Definition of AskUserTalker class
22 #include "AskUserTalker.h"
27 #include <socket/Socket.h>
28 #include <socket/SelectRead.h>
29 #include <types/NotificationResponse.h>
30 #include <types/Protocol.h>
31 #include <types/NotificationRequest.h>
32 #include <exception/ErrnoException.h>
33 #include <exception/Exception.h>
34 #include <translator/Translator.h>
35 #include <config/Path.h>
36 #include <config/Limits.h>
38 #include <security-manager.h>
39 #include <privilegemgr/privilege_info.h>
44 namespace Notification {
48 inline void throwOnSecurityPrivilegeError(std::string err, int ret)
50 if (ret != SECURITY_MANAGER_SUCCESS)
51 throw Exception(err + " : " + std::to_string(ret));
54 void setSecurityLevel(const std::string &app, const std::string &perm, const std::string &level)
59 if (level != "Allow" && level != "Deny")
60 throw std::invalid_argument("Not allowed security level <" + level + ">");
62 ALOGD("SecurityManager: Setting security level to " << level);
64 policy_update_req *policyUpdateRequest = nullptr;
66 ret = security_manager_policy_update_req_new(&policyUpdateRequest);
67 throwOnSecurityPrivilegeError("security_manager_policy_update_req_new", ret);
69 std::unique_ptr<policy_update_req, decltype(security_manager_policy_update_req_free)*>
70 policyUpdateRequestPtr(policyUpdateRequest, security_manager_policy_update_req_free);
72 char* privacy_name = nullptr;
74 ret = privilege_info_get_privacy_by_privilege(perm.c_str(), &privacy_name);
75 if (ret != PRVMGR_ERR_NONE || !privacy_name) {
76 ALOGE("Unable to get privacy group for privilege: <" << perm << ">, err: <" << ret << ">");
77 throw Exception("Can't get privacy group name for privilege " + perm);
80 GList *privilege_list = nullptr;
82 ret = privilege_info_get_privilege_list_by_privacy(privacy_name, &privilege_list);
83 free(privacy_name); // not needed anymore below this place
85 if (ret != PRVMGR_ERR_NONE || !privilege_list) {
86 ALOGE("Unable to get privacy group list of privileges; err: <" << ret << ">" );
87 throw Exception("Unable to get privacy list of privielges");
90 auto list_deleter = [](GList* l) { g_list_free_full(l, free); };
91 std::unique_ptr<GList,
92 decltype(list_deleter)> privilge_listPtr(privilege_list, list_deleter);
93 std::vector<std::unique_ptr<policy_entry,
94 decltype(security_manager_policy_entry_free)*>> policyEntries;
96 for (GList *l = privilege_list; l != NULL; l = l->next) {
97 char *privilege_name = static_cast<char*>(l->data);
98 policy_entry *policyEntry = nullptr;
100 ret = security_manager_policy_entry_new(&policyEntry);
101 throwOnSecurityPrivilegeError("security_manager_policy_entry_new", ret);
103 policyEntries.push_back(std::unique_ptr<policy_entry,
104 decltype(security_manager_policy_entry_free)*>(policyEntry, security_manager_policy_entry_free));
106 char *pkg_name = nullptr;
107 char *app_name = nullptr;
109 ret = security_manager_identify_app_from_cynara_client(app.c_str(), &pkg_name, &app_name);
110 std::unique_ptr<char, decltype(free)*> pkg_name_p(pkg_name, free);
111 std::unique_ptr<char, decltype(free)*> app_name_p(app_name, free);
112 throwOnSecurityPrivilegeError("security_manager_identify_app_from_cynara_client", ret);
114 ret = security_manager_policy_entry_set_application(policyEntry, app_name);
115 throwOnSecurityPrivilegeError("security_manager_policy_entry_set_application", ret);
117 ret = security_manager_policy_entry_set_privilege(policyEntry, privilege_name);
118 throwOnSecurityPrivilegeError("security_manager_policy_entry_set_privilege", ret);
120 ret = security_manager_policy_entry_set_level(policyEntry, level.c_str());
121 throwOnSecurityPrivilegeError("security_manager_policy_entry_admin_set_level", ret);
123 ret = security_manager_policy_update_req_add_entry(policyUpdateRequest, policyEntry);
124 throwOnSecurityPrivilegeError("security_manager_policy_update_req_add_entry", ret);
127 ret = security_manager_policy_update_send(policyUpdateRequest);
128 throwOnSecurityPrivilegeError("security_manager_policy_update_send", ret);
130 ALOGD("SecurityManager: Setting level succeeded");
131 } catch (std::exception &e) {
132 ALOGE("SecurityManager: Failed <" << e.what() << ">");
139 AskUserTalker::AskUserTalker(GuiRunner *gui) : m_gui(gui) {
140 m_gui->setDropHandler([&](){return this->shouldDismiss();});
143 AskUserTalker::~AskUserTalker()
146 Socket::close(sockfd);
147 } catch (const std::exception &e) {
148 ALOGE(std::string("~AskUserTalker") + e.what());
150 ALOGE("~AskUserTalker: Unknow error");
154 void AskUserTalker::run()
156 sockfd = Socket::connect(Path::getSocketPath());
161 NotificationResponse response;
163 ALOGD("Waiting for request...");
165 if (!Socket::recv(sockfd, &size, sizeof(size))) {
166 ALOGI("Askuserd closed connection, closing...");
170 Limits::checkSizeLimit(size);
172 buf = new char[size];
174 if (!Socket::recv(sockfd, buf, size)) {
175 ALOGI("Askuserd closed connection, closing...");
179 NotificationRequest request = Translator::Gui::dataToNotificationRequest(buf);
181 ALOGD("Recieved data " << request.data.client << " " << request.data.privilege);
183 response.response = m_gui->popupRun(request.data.client, request.data.privilege);
184 response.id = request.id;
186 if (response.response == NResponseType::None) {
190 if (!Socket::send(sockfd, &response, sizeof(response))) {
191 ALOGI("Askuserd closed connection, closing...");
196 if (!Socket::recv(sockfd, &ack, sizeof(ack))) {
197 ALOGI("Askuserd closed connection, closing...");
201 if (ack != Protocol::ackCode)
202 throw Exception("Incorrect ack");
204 switch (response.response) {
205 case NResponseType::Error:
206 throw Exception(m_gui->getErrorMsg());
207 case NResponseType::Allow:
208 case NResponseType::Never:
209 setSecurityLevel(request.data.client, request.data.privilege,
210 Translator::Gui::responseToString(response.response));
217 void AskUserTalker::stop()
220 Socket::close(sockfd);
223 bool AskUserTalker::shouldDismiss()
225 Socket::SelectRead select;
227 if (select.exec() == 0)
231 Socket::recv(sockfd, &a, sizeof(a));
233 if (a != Protocol::dissmisCode)
234 throw Exception("Incorrect dismiss flag");
239 } /* namespace Notification */
241 } /* namespace AskUser */