046dd20cb70f5564b81f8017dcebcc7474a491c8
[platform/core/security/security-manager.git] / src / server / service / service.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Rafal Krypa <r.krypa@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        service.cpp
20  * @author      Michal Witanowski <m.witanowski@samsung.com>
21  * @author      Jacek Bukarewicz <j.bukarewicz@samsung.com>
22  * @author      Rafal Krypa <r.krypa@samsung.com>
23  * @brief       Implementation of security-manager service.
24  */
25
26 #include <sys/socket.h>
27
28 #include <dpl/log/log.h>
29 #include <dpl/serialization.h>
30
31 #include "protocols.h"
32 #include "service.h"
33 #include "service_impl.h"
34
35 namespace SecurityManager {
36
37 const InterfaceID IFACE = 1;
38
39 Service::Service()
40 {
41 }
42
43 GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription()
44 {
45     return ServiceDescriptionVector {
46         {SERVICE_SOCKET, "security-manager", IFACE},
47     };
48 }
49
50 void Service::accept(const AcceptEvent &event)
51 {
52     LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock <<
53              " ConnectionID.counter: " << event.connectionID.counter <<
54              " ServiceID: " << event.interfaceID);
55
56     auto &info = m_connectionInfoMap[event.connectionID.counter];
57     info.interfaceID = event.interfaceID;
58 }
59
60 void Service::write(const WriteEvent &event)
61 {
62     LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
63              " Size: " << event.size <<
64              " Left: " << event.left);
65
66     if (event.left == 0)
67         m_serviceManager->Close(event.connectionID);
68 }
69
70 void Service::process(const ReadEvent &event)
71 {
72     LogDebug("Read event for counter: " << event.connectionID.counter);
73     auto &info = m_connectionInfoMap[event.connectionID.counter];
74     info.buffer.Push(event.rawBuffer);
75
76     // We can get several requests in one package.
77     // Extract and process them all
78     while (processOne(event.connectionID, info.buffer, info.interfaceID));
79 }
80
81 void Service::close(const CloseEvent &event)
82 {
83     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
84     m_connectionInfoMap.erase(event.connectionID.counter);
85 }
86
87 static bool getPeerID(int sock, uid_t &uid, pid_t &pid) {
88     struct ucred cr;
89     socklen_t len = sizeof(cr);
90
91     if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
92         uid = cr.uid;
93         pid = cr.pid;
94         return true;
95     }
96
97     return false;
98 }
99
100 bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
101                                   InterfaceID interfaceID)
102 {
103     LogDebug("Iteration begin. Interface = " << interfaceID);
104
105     //waiting for all data
106     if (!buffer.Ready()) {
107         return false;
108     }
109
110     MessageBuffer send;
111     bool retval = false;
112
113     uid_t uid;
114     pid_t pid;
115
116     if(!getPeerID(conn.sock, uid, pid)) {
117         LogError("Closing socket because of error: unable to get peer's uid and pid");
118         m_serviceManager->Close(conn);
119         return false;
120     }
121
122     if (IFACE == interfaceID) {
123         Try {
124             // deserialize API call type
125             int call_type_int;
126             Deserialization::Deserialize(buffer, call_type_int);
127             SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
128
129             switch (call_type) {
130                 case SecurityModuleCall::APP_INSTALL:
131                     LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
132                     processAppInstall(buffer, send, uid);
133                     break;
134                 case SecurityModuleCall::APP_UNINSTALL:
135                     LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
136                     processAppUninstall(buffer, send, uid);
137                     break;
138                 case SecurityModuleCall::APP_GET_PKGID:
139                     processGetPkgId(buffer, send);
140                     break;
141                 case SecurityModuleCall::APP_GET_GROUPS:
142                     processGetAppGroups(buffer, send, uid, pid);
143                     break;
144                 case SecurityModuleCall::USER_ADD:
145                     processUserAdd(buffer, send, uid);
146                     break;
147                 case SecurityModuleCall::USER_DELETE:
148                     processUserDelete(buffer, send, uid);
149                     break;
150                 default:
151                     LogError("Invalid call: " << call_type_int);
152                     Throw(ServiceException::InvalidAction);
153             }
154             // if we reach this point, the protocol is OK
155             retval = true;
156         } Catch (MessageBuffer::Exception::Base) {
157             LogError("Broken protocol.");
158         } Catch (ServiceException::Base) {
159             LogError("Broken protocol.");
160         } catch (std::exception &e) {
161             LogError("STD exception " << e.what());
162         } catch (...) {
163             LogError("Unknown exception");
164         }
165     }
166     else {
167         LogError("Wrong interface");
168     }
169
170     if (retval) {
171         //send response
172         m_serviceManager->Write(conn, send.Pop());
173     } else {
174         LogError("Closing socket because of error");
175         m_serviceManager->Close(conn);
176     }
177
178     return retval;
179 }
180
181 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
182 {
183     app_inst_req req;
184
185     Deserialization::Deserialize(buffer, req.appId);
186     Deserialization::Deserialize(buffer, req.pkgId);
187     Deserialization::Deserialize(buffer, req.privileges);
188     Deserialization::Deserialize(buffer, req.appPaths);
189     Deserialization::Deserialize(buffer, req.uid);
190     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
191 }
192
193 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
194 {
195     std::string appId;
196
197     Deserialization::Deserialize(buffer, appId);
198     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
199 }
200
201 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
202 {
203     std::string appId;
204     std::string pkgId;
205     int ret;
206
207     Deserialization::Deserialize(buffer, appId);
208     ret = ServiceImpl::getPkgId(appId, pkgId);
209     Serialization::Serialize(send, ret);
210     if (ret == SECURITY_MANAGER_API_SUCCESS)
211         Serialization::Serialize(send, pkgId);
212 }
213
214 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
215 {
216     std::string appId;
217     std::unordered_set<gid_t> gids;
218     int ret;
219
220     Deserialization::Deserialize(buffer, appId);
221     ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
222     Serialization::Serialize(send, ret);
223     if (ret == SECURITY_MANAGER_API_SUCCESS) {
224         Serialization::Serialize(send, static_cast<int>(gids.size()));
225         for (const auto &gid : gids) {
226             Serialization::Serialize(send, gid);
227         }
228     }
229 }
230
231 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
232 {
233     int ret;
234     uid_t uidAdded;
235     int userType;
236
237     Deserialization::Deserialize(buffer, uidAdded);
238     Deserialization::Deserialize(buffer, userType);
239
240     ret = ServiceImpl::userAdd(uidAdded, userType, uid);
241     Serialization::Serialize(send, ret);
242 }
243
244 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
245 {
246     int ret;
247     uid_t uidRemoved;
248
249     Deserialization::Deserialize(buffer, uidRemoved);
250
251     ret = ServiceImpl::userDelete(uidRemoved, uid);
252     Serialization::Serialize(send, ret);
253 }
254
255
256 } // namespace SecurityManager