Revert "Fix security manager socket path."
[platform/core/security/security-server.git] / src / server / service / installer.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bartlomiej Grzelewski <b.grzelewski@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 /*
19  * @file        installer.cpp
20  * @author      Michal Witanowski (m.witanowski@samsung.com)
21  * @brief       Implementation of installer service for libprivilege-control encapsulation.
22  */
23
24 #include <dpl/log/log.h>
25 #include <dpl/serialization.h>
26
27 #include <privilege-control.h>
28 #include "installer.h"
29 #include "protocols.h"
30 #include "security-server.h"
31 #include "security-manager.h"
32
33 namespace SecurityServer {
34
35 namespace {
36
37 const InterfaceID INSTALLER_IFACE = 0;
38
39 /**
40  * Convert Security Mangager's API path type to libprivilege-control's API path type.
41  * @return true on success
42  */
43 bool TranslateAppPathType(const app_install_path_type path_type,
44                           app_path_type_t& lpc_path_type)
45 {
46     switch (path_type) {
47         case SECURITY_MANAGER_PATH_PRIVATE:
48             lpc_path_type = APP_PATH_PRIVATE;
49             break;
50         case SECURITY_MANAGER_PATH_PUBLIC:
51             lpc_path_type = APP_PATH_PUBLIC;
52             break;
53         case SECURITY_MANAGER_PATH_PUBLIC_RO:
54             lpc_path_type = APP_PATH_FLOOR;
55             break;
56         default:
57             return false;
58     };
59     return true;
60 }
61
62 } // namespace anonymous
63
64
65 InstallerService::InstallerService()
66 {
67 }
68
69 GenericSocketService::ServiceDescriptionVector InstallerService::GetServiceDescription()
70 {
71     return ServiceDescriptionVector {
72         {SERVICE_SOCKET_INSTALLER, "security-server::installer", INSTALLER_IFACE},
73     };
74 }
75
76 void InstallerService::accept(const AcceptEvent &event)
77 {
78     LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock <<
79              " ConnectionID.counter: " << event.connectionID.counter <<
80              " ServiceID: " << event.interfaceID);
81
82     auto &info = m_connectionInfoMap[event.connectionID.counter];
83     info.interfaceID = event.interfaceID;
84 }
85
86 void InstallerService::write(const WriteEvent &event)
87 {
88     LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
89              " Size: " << event.size <<
90              " Left: " << event.left);
91
92     if (event.left == 0)
93         m_serviceManager->Close(event.connectionID);
94 }
95
96 void InstallerService::process(const ReadEvent &event)
97 {
98     LogDebug("Read event for counter: " << event.connectionID.counter);
99     auto &info = m_connectionInfoMap[event.connectionID.counter];
100     info.buffer.Push(event.rawBuffer);
101
102     // We can get several requests in one package.
103     // Extract and process them all
104     while (processOne(event.connectionID, info.buffer, info.interfaceID));
105 }
106
107 void InstallerService::close(const CloseEvent &event)
108 {
109     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
110     m_connectionInfoMap.erase(event.connectionID.counter);
111 }
112
113 bool InstallerService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
114                                   InterfaceID interfaceID)
115 {
116     LogDebug("Iteration begin. Interface = " << interfaceID);
117
118     //waiting for all data
119     if (!buffer.Ready()) {
120         return false;
121     }
122
123     MessageBuffer send;
124     bool retval = false;
125
126     if (INSTALLER_IFACE == interfaceID) {
127         Try {
128             // deserialize API call type
129             int call_type_int;
130             Deserialization::Deserialize(buffer, call_type_int);
131             SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
132
133             switch (call_type) {
134                 case SecurityModuleCall::APP_INSTALL:
135                     processAppInstall(buffer, send);
136                     break;
137                 case SecurityModuleCall::APP_UNINSTALL:
138                     processAppUninstall(buffer, send);
139                     break;
140                 default:
141                     LogError("Invalid call: " << call_type_int);
142                     Throw(InstallerException::InvalidAction);
143             }
144             // if we reach this point, the protocol is OK
145             retval = true;
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());
152         } catch (...) {
153             LogError("Unknown exception");
154         }
155     }
156     else {
157         LogError("Wrong interface");
158     }
159
160     if (retval) {
161         //send response
162         m_serviceManager->Write(conn, send.Pop());
163     } else {
164         LogError("Closing socket because of error");
165         m_serviceManager->Close(conn);
166     }
167
168     return retval;
169 }
170
171 bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &send)
172 {
173     // deserialize request data
174     app_inst_req req;
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);
180
181     LogDebug("appId: " << req.appId);
182     LogDebug("pkgId: " << req.pkgId);
183
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();
189     }
190     pp_permissions[req.privileges.size()] = nullptr;
191
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);
198         return false;
199     }
200
201     /**
202      * TODO: use pkgId.
203      * This is a temporary solution: perm_app_* requires pkgId. We assume that pkgId == appId.
204      */
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
209         goto error_label;
210     }
211
212     // TODO: use pkgId.
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
218         goto error_label;
219     }
220
221     // register paths
222     for (const auto& appPath : req.appPaths) {
223         app_path_type_t path_type;
224         if (!TranslateAppPathType((app_install_path_type)appPath.second,
225                                   path_type)) {
226             LogError("Unrecognized path type: " << appPath.second);
227             goto error_label;
228         }
229         LogDebug("Adding path: " << appPath.first << " (type " << path_type << ")");
230
231         // TODO: use pkgId.
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);
236             goto error_label;
237         }
238     }
239
240     // finish database transaction
241     result = perm_end();
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);
246         return false;
247     }
248
249     // success
250     Serialization::Serialize(send, SECURITY_SERVER_API_SUCCESS);
251     return true;
252
253 error_label:
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);
258     return false;
259 }
260
261 bool InstallerService::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send)
262 {
263     // deserialize request data
264     std::string appId;
265     Deserialization::Deserialize(buffer, appId);
266     LogDebug("appId: " << appId);
267
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);
273         return false;
274     }
275
276     // TODO: use pkgId.
277     result = perm_app_uninstall(appId.c_str());
278     LogDebug("perm_app_uninstall() returned " << result);
279
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);
285         return false;
286     }
287
288     // finish database transaction
289     result = perm_end();
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);
294         return false;
295     }
296
297     // success
298     Serialization::Serialize(send, SECURITY_SERVER_API_SUCCESS);
299     return true;
300 }
301
302 } // namespace SecurityServer