a8ff402238cdd910bd5916ff5c53fdd098ec0ea9
[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 #include <sys/smack.h>
31
32 #include "connection.h"
33 #include "protocols.h"
34 #include "service.h"
35 #include "service_impl.h"
36 #include "master-req.h"
37
38 namespace SecurityManager {
39
40 const InterfaceID IFACE = 1;
41
42 Service::Service(const bool isSlave):
43         m_isSlave(isSlave)
44 {
45 }
46
47 GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription()
48 {
49     if (m_isSlave)
50         return ServiceDescriptionVector {
51             {SLAVE_SERVICE_SOCKET,  /* path */
52              "*",   /* smackLabel label (not used, we rely on systemd) */
53              IFACE, /* InterfaceID */
54              false, /* useSendMsg */
55              true}, /* systemdOnly */
56         };
57     else
58         return ServiceDescriptionVector {
59             {SERVICE_SOCKET,  /* path */
60              "*",   /* smackLabel label (not used, we rely on systemd) */
61              IFACE, /* InterfaceID */
62              false, /* useSendMsg */
63              true}, /* systemdOnly */
64         };
65 }
66
67 static bool getPeerID(int sock, uid_t &uid, pid_t &pid, std::string &smackLabel)
68 {
69     struct ucred cr;
70     socklen_t len = sizeof(cr);
71
72     if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
73         char *smk;
74         ssize_t ret = smack_new_label_from_socket(sock, &smk);
75         if (ret < 0)
76             return false;
77         smackLabel = smk;
78         uid = cr.uid;
79         pid = cr.pid;
80         free(smk);
81         return true;
82     }
83
84     return false;
85 }
86
87 bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
88                                   InterfaceID interfaceID)
89 {
90     LogDebug("Iteration begin. Interface = " << interfaceID);
91
92     //waiting for all data
93     if (!buffer.Ready()) {
94         return false;
95     }
96
97     MessageBuffer send;
98     bool retval = false;
99
100     uid_t uid;
101     pid_t pid;
102     std::string smackLabel;
103
104     if (!getPeerID(conn.sock, uid, pid, smackLabel)) {
105         LogError("Closing socket because of error: unable to get peer's uid, pid or smack label");
106         m_serviceManager->Close(conn);
107         return false;
108     }
109
110     if (IFACE == interfaceID) {
111         Try {
112             // deserialize API call type
113             int call_type_int;
114             Deserialization::Deserialize(buffer, call_type_int);
115             SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
116
117             switch (call_type) {
118                 case SecurityModuleCall::NOOP:
119                     LogDebug("call_type: SecurityModuleCall::NOOP");
120                     Serialization::Serialize(send, SECURITY_MANAGER_API_SUCCESS);
121                     break;
122                 case SecurityModuleCall::APP_INSTALL:
123                     LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
124                     processAppInstall(buffer, send, uid);
125                     break;
126                 case SecurityModuleCall::APP_UNINSTALL:
127                     LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
128                     processAppUninstall(buffer, send, uid);
129                     break;
130                 case SecurityModuleCall::APP_GET_PKGID:
131                     processGetPkgId(buffer, send);
132                     break;
133                 case SecurityModuleCall::APP_GET_GROUPS:
134                     processGetAppGroups(buffer, send, uid, pid);
135                     break;
136                 case SecurityModuleCall::USER_ADD:
137                     processUserAdd(buffer, send, uid);
138                     break;
139                 case SecurityModuleCall::USER_DELETE:
140                     processUserDelete(buffer, send, uid);
141                     break;
142                 case SecurityModuleCall::POLICY_UPDATE:
143                     processPolicyUpdate(buffer, send, uid, pid, smackLabel);
144                     break;
145                 case SecurityModuleCall::GET_CONF_POLICY_ADMIN:
146                     processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, true);
147                     break;
148                 case SecurityModuleCall::GET_CONF_POLICY_SELF:
149                     processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, false);
150                     break;
151                 case SecurityModuleCall::GET_POLICY:
152                     processGetPolicy(buffer, send, uid, pid, smackLabel);
153                     break;
154                 case SecurityModuleCall::POLICY_GET_DESCRIPTIONS:
155                     processPolicyGetDesc(send);
156                     break;
157                 default:
158                     LogError("Invalid call: " << call_type_int);
159                     Throw(ServiceException::InvalidAction);
160             }
161             // if we reach this point, the protocol is OK
162             retval = true;
163         } Catch (MessageBuffer::Exception::Base) {
164             LogError("Broken protocol.");
165         } Catch (ServiceException::Base) {
166             LogError("Broken protocol.");
167         } catch (const std::exception &e) {
168             LogError("STD exception " << e.what());
169         } catch (...) {
170             LogError("Unknown exception");
171         }
172     }
173     else {
174         LogError("Wrong interface");
175     }
176
177     if (retval) {
178         //send response
179         m_serviceManager->Write(conn, send.Pop());
180     } else {
181         LogError("Closing socket because of error");
182         m_serviceManager->Close(conn);
183     }
184
185     return retval;
186 }
187
188 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
189 {
190     app_inst_req req;
191
192     Deserialization::Deserialize(buffer, req.appId);
193     Deserialization::Deserialize(buffer, req.pkgId);
194     Deserialization::Deserialize(buffer, req.privileges);
195     Deserialization::Deserialize(buffer, req.appPaths);
196     Deserialization::Deserialize(buffer, req.uid);
197     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid, m_isSlave));
198 }
199
200 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
201 {
202     std::string appId;
203
204     Deserialization::Deserialize(buffer, appId);
205     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid, m_isSlave));
206 }
207
208 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
209 {
210     std::string appId;
211     std::string pkgId;
212     int ret;
213
214     Deserialization::Deserialize(buffer, appId);
215     ret = ServiceImpl::getPkgId(appId, pkgId);
216     Serialization::Serialize(send, ret);
217     if (ret == SECURITY_MANAGER_API_SUCCESS)
218         Serialization::Serialize(send, pkgId);
219 }
220
221 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
222 {
223     std::string appId;
224     std::unordered_set<gid_t> gids;
225     int ret;
226
227     Deserialization::Deserialize(buffer, appId);
228     ret = ServiceImpl::getAppGroups(appId, uid, pid, m_isSlave, gids);
229     Serialization::Serialize(send, ret);
230     if (ret == SECURITY_MANAGER_API_SUCCESS) {
231         Serialization::Serialize(send, static_cast<int>(gids.size()));
232         for (const auto &gid : gids) {
233             Serialization::Serialize(send, gid);
234         }
235     }
236 }
237
238 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
239 {
240     int ret;
241     uid_t uidAdded;
242     int userType;
243
244     Deserialization::Deserialize(buffer, uidAdded);
245     Deserialization::Deserialize(buffer, userType);
246
247     ret = ServiceImpl::userAdd(uidAdded, userType, uid, m_isSlave);
248     Serialization::Serialize(send, ret);
249 }
250
251 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
252 {
253     int ret;
254     uid_t uidRemoved;
255
256     Deserialization::Deserialize(buffer, uidRemoved);
257
258     ret = ServiceImpl::userDelete(uidRemoved, uid, m_isSlave);
259     Serialization::Serialize(send, ret);
260 }
261
262 void Service::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
263 {
264     int ret;
265     std::vector<policy_entry> policyEntries;
266
267     Deserialization::Deserialize(buffer, policyEntries);
268
269     if (m_isSlave) {
270         ret = MasterReq::PolicyUpdate(policyEntries, uid, pid, smackLabel);
271     } else {
272         ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
273     }
274     Serialization::Serialize(send, ret);
275 }
276
277 void Service::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel, bool forAdmin)
278 {
279     int ret;
280     policy_entry filter;
281     Deserialization::Deserialize(buffer, filter);
282     std::vector<policy_entry> policyEntries;
283
284     if (m_isSlave) {
285         ret = MasterReq::GetConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
286     } else {
287         ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel,
288                                                policyEntries);
289     }
290
291     Serialization::Serialize(send, ret);
292     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
293     for (const auto &policyEntry : policyEntries) {
294         Serialization::Serialize(send, policyEntry);
295     };
296 }
297
298 void Service::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
299 {
300     int ret;
301     policy_entry filter;
302     Deserialization::Deserialize(buffer, filter);
303     std::vector<policy_entry> policyEntries;
304
305     if (m_isSlave) {
306         ret = MasterReq::GetPolicy(filter, uid, pid, smackLabel, policyEntries);
307     } else {
308         ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
309     }
310
311     Serialization::Serialize(send, ret);
312     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
313     for (const auto &policyEntry : policyEntries) {
314         Serialization::Serialize(send, policyEntry);
315     };
316 }
317
318 void Service::processPolicyGetDesc(MessageBuffer &send)
319 {
320     int ret;
321     std::vector<std::string> descriptions;
322
323     if (m_isSlave) {
324         ret = MasterReq::PolicyGetDesc(descriptions);
325     } else {
326         ret = ServiceImpl::policyGetDesc(descriptions);
327     }
328     Serialization::Serialize(send, ret);
329     if (ret == SECURITY_MANAGER_API_SUCCESS) {
330         Serialization::Serialize(send, static_cast<int>(descriptions.size()));
331
332         for(std::vector<std::string>::size_type i = 0; i != descriptions.size(); i++) {
333             Serialization::Serialize(send, descriptions[i]);
334         }
335     }
336 }
337
338 } // namespace SecurityManager