2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bartlomiej Grzelewski <b.grzelewski@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 Michal Witanowski (m.witanowski@samsung.com)
21 * @brief Implementation of installer service for libprivilege-control encapsulation.
24 #include <dpl/log/log.h>
25 #include <dpl/serialization.h>
27 #include <privilege-control.h>
28 #include "installer.h"
29 #include "protocols.h"
30 #include "security-server.h"
31 #include "security-manager.h"
33 namespace SecurityServer {
37 const InterfaceID INSTALLER_IFACE = 0;
40 * Convert Security Mangager's API path type to libprivilege-control's API path type.
41 * @return true on success
43 bool TranslateAppPathType(const app_install_path_type path_type,
44 app_path_type_t& lpc_path_type)
47 case SECURITY_MANAGER_PATH_PRIVATE:
48 lpc_path_type = APP_PATH_PRIVATE;
50 case SECURITY_MANAGER_PATH_PUBLIC:
51 lpc_path_type = APP_PATH_PUBLIC;
53 case SECURITY_MANAGER_PATH_PUBLIC_RO:
54 lpc_path_type = APP_PATH_FLOOR;
62 } // namespace anonymous
65 InstallerService::InstallerService()
69 GenericSocketService::ServiceDescriptionVector InstallerService::GetServiceDescription()
71 return ServiceDescriptionVector {
72 {SERVICE_SOCKET_INSTALLER, "security-server::installer", INSTALLER_IFACE},
76 void InstallerService::accept(const AcceptEvent &event)
78 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock <<
79 " ConnectionID.counter: " << event.connectionID.counter <<
80 " ServiceID: " << event.interfaceID);
82 auto &info = m_connectionInfoMap[event.connectionID.counter];
83 info.interfaceID = event.interfaceID;
86 void InstallerService::write(const WriteEvent &event)
88 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
89 " Size: " << event.size <<
90 " Left: " << event.left);
93 m_serviceManager->Close(event.connectionID);
96 void InstallerService::process(const ReadEvent &event)
98 LogDebug("Read event for counter: " << event.connectionID.counter);
99 auto &info = m_connectionInfoMap[event.connectionID.counter];
100 info.buffer.Push(event.rawBuffer);
102 // We can get several requests in one package.
103 // Extract and process them all
104 while (processOne(event.connectionID, info.buffer, info.interfaceID));
107 void InstallerService::close(const CloseEvent &event)
109 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
110 m_connectionInfoMap.erase(event.connectionID.counter);
113 bool InstallerService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
114 InterfaceID interfaceID)
116 LogDebug("Iteration begin. Interface = " << interfaceID);
118 //waiting for all data
119 if (!buffer.Ready()) {
126 if (INSTALLER_IFACE == interfaceID) {
128 // deserialize API call type
130 Deserialization::Deserialize(buffer, call_type_int);
131 SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
134 case SecurityModuleCall::APP_INSTALL:
135 processAppInstall(buffer, send);
137 case SecurityModuleCall::APP_UNINSTALL:
138 processAppUninstall(buffer, send);
141 LogError("Invalid call: " << call_type_int);
142 Throw(InstallerException::InvalidAction);
144 // if we reach this point, the protocol is OK
146 } Catch (MessageBuffer::Exception::Base) {
147 LogError("Broken protocol.");
148 } Catch (InstallerException::Base) {
149 LogError("Broken protocol.");
150 } catch (std::exception &e) {
151 LogError("STD exception " << e.what());
153 LogError("Unknown exception");
157 LogError("Wrong interface");
162 m_serviceManager->Write(conn, send.Pop());
164 LogError("Closing socket because of error");
165 m_serviceManager->Close(conn);
171 bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &send)
173 // deserialize request data
175 Deserialization::Deserialize(buffer, req.appId);
176 Deserialization::Deserialize(buffer, req.pkgId);
177 Deserialization::Deserialize(buffer, req.allowedUsers);
178 Deserialization::Deserialize(buffer, req.privileges);
179 Deserialization::Deserialize(buffer, req.appPaths);
181 LogDebug("appId: " << req.appId);
182 LogDebug("pkgId: " << req.pkgId);
184 // create null terminated array of strigns for permissions
185 std::unique_ptr<const char *[]> pp_permissions(new const char* [req.privileges.size() + 1]);
186 for (size_t i = 0; i < req.privileges.size(); ++i) {
187 LogDebug("Permission = " << req.privileges[i]);
188 pp_permissions[i] = req.privileges[i].c_str();
190 pp_permissions[req.privileges.size()] = nullptr;
192 // start database transaction
193 int result = perm_begin();
194 LogDebug("perm_begin() returned " << result);
195 if (PC_OPERATION_SUCCESS != result) {
196 // libprivilege is locked
197 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
203 * This is a temporary solution: perm_app_* requires pkgId. We assume that pkgId == appId.
205 result = perm_app_install(req.appId.c_str());
206 LogDebug("perm_app_install() returned " << result);
207 if (PC_OPERATION_SUCCESS != result) {
208 // libprivilege error
213 result = perm_app_enable_permissions(req.appId.c_str(), APP_TYPE_WGT,
214 pp_permissions.get(), true);
215 LogDebug("perm_app_enable_permissions() returned " << result);
216 if (PC_OPERATION_SUCCESS != result) {
217 // libprivilege error
222 for (const auto& appPath : req.appPaths) {
223 app_path_type_t path_type;
224 if (!TranslateAppPathType((app_install_path_type)appPath.second,
226 LogError("Unrecognized path type: " << appPath.second);
229 LogDebug("Adding path: " << appPath.first << " (type " << path_type << ")");
232 result = perm_app_setup_path(req.appId.c_str(), appPath.first.c_str(), path_type);
233 if (PC_OPERATION_SUCCESS != result) {
234 // libprivilege error
235 LogDebug("perm_app_setup_path() returned " << result);
240 // finish database transaction
242 LogDebug("perm_end() returned " << result);
243 if (PC_OPERATION_SUCCESS != result) {
244 // error in libprivilege-control
245 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
250 Serialization::Serialize(send, SECURITY_SERVER_API_SUCCESS);
254 // rollback failed transaction before exiting
255 result = perm_rollback();
256 LogDebug("perm_rollback() returned " << result);
257 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
261 bool InstallerService::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send)
263 // deserialize request data
265 Deserialization::Deserialize(buffer, appId);
266 LogDebug("appId: " << appId);
268 int result = perm_begin();
269 LogDebug("perm_begin() returned " << result);
270 if (PC_OPERATION_SUCCESS != result) {
271 // libprivilege is locked
272 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
277 result = perm_app_uninstall(appId.c_str());
278 LogDebug("perm_app_uninstall() returned " << result);
280 if (PC_OPERATION_SUCCESS != result) {
281 // error in libprivilege-control
282 result = perm_rollback();
283 LogDebug("perm_rollback() returned " << result);
284 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
288 // finish database transaction
290 LogDebug("perm_end() returned " << result);
291 if (PC_OPERATION_SUCCESS != result) {
292 // error in libprivilege-control
293 Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_SERVER_ERROR);
298 Serialization::Serialize(send, SECURITY_SERVER_API_SUCCESS);
302 } // namespace SecurityServer