Implement serialization of privilege mapping API
[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                 case SecurityModuleCall::GET_PRIVILEGES_MAPPING:
158                     processPrivilegesMappings(buffer, send);
159                     break;
160                 default:
161                     LogError("Invalid call: " << call_type_int);
162                     Throw(ServiceException::InvalidAction);
163             }
164             // if we reach this point, the protocol is OK
165             retval = true;
166         } Catch (MessageBuffer::Exception::Base) {
167             LogError("Broken protocol.");
168         } Catch (ServiceException::Base) {
169             LogError("Broken protocol.");
170         } catch (const std::exception &e) {
171             LogError("STD exception " << e.what());
172         } catch (...) {
173             LogError("Unknown exception");
174         }
175     }
176     else {
177         LogError("Wrong interface");
178     }
179
180     if (retval) {
181         //send response
182         m_serviceManager->Write(conn, send.Pop());
183     } else {
184         LogError("Closing socket because of error");
185         m_serviceManager->Close(conn);
186     }
187
188     return retval;
189 }
190
191 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
192 {
193     app_inst_req req;
194
195     Deserialization::Deserialize(buffer, req.appId);
196     Deserialization::Deserialize(buffer, req.pkgId);
197     Deserialization::Deserialize(buffer, req.privileges);
198     Deserialization::Deserialize(buffer, req.appPaths);
199     Deserialization::Deserialize(buffer, req.uid);
200     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid, m_isSlave));
201 }
202
203 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
204 {
205     std::string appId;
206
207     Deserialization::Deserialize(buffer, appId);
208     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid, m_isSlave));
209 }
210
211 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
212 {
213     std::string appId;
214     std::string pkgId;
215     int ret;
216
217     Deserialization::Deserialize(buffer, appId);
218     ret = ServiceImpl::getPkgId(appId, pkgId);
219     Serialization::Serialize(send, ret);
220     if (ret == SECURITY_MANAGER_API_SUCCESS)
221         Serialization::Serialize(send, pkgId);
222 }
223
224 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
225 {
226     std::string appId;
227     std::unordered_set<gid_t> gids;
228     int ret;
229
230     Deserialization::Deserialize(buffer, appId);
231     ret = ServiceImpl::getAppGroups(appId, uid, pid, m_isSlave, gids);
232     Serialization::Serialize(send, ret);
233     if (ret == SECURITY_MANAGER_API_SUCCESS) {
234         Serialization::Serialize(send, static_cast<int>(gids.size()));
235         for (const auto &gid : gids) {
236             Serialization::Serialize(send, gid);
237         }
238     }
239 }
240
241 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
242 {
243     int ret;
244     uid_t uidAdded;
245     int userType;
246
247     Deserialization::Deserialize(buffer, uidAdded);
248     Deserialization::Deserialize(buffer, userType);
249
250     ret = ServiceImpl::userAdd(uidAdded, userType, uid, m_isSlave);
251     Serialization::Serialize(send, ret);
252 }
253
254 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
255 {
256     int ret;
257     uid_t uidRemoved;
258
259     Deserialization::Deserialize(buffer, uidRemoved);
260
261     ret = ServiceImpl::userDelete(uidRemoved, uid, m_isSlave);
262     Serialization::Serialize(send, ret);
263 }
264
265 void Service::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
266 {
267     int ret;
268     std::vector<policy_entry> policyEntries;
269
270     Deserialization::Deserialize(buffer, policyEntries);
271
272     if (m_isSlave) {
273         ret = MasterReq::PolicyUpdate(policyEntries, uid, pid, smackLabel);
274     } else {
275         ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
276     }
277     Serialization::Serialize(send, ret);
278 }
279
280 void Service::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel, bool forAdmin)
281 {
282     int ret;
283     policy_entry filter;
284     Deserialization::Deserialize(buffer, filter);
285     std::vector<policy_entry> policyEntries;
286
287     if (m_isSlave) {
288         ret = MasterReq::GetConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
289     } else {
290         ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel,
291                                                policyEntries);
292     }
293
294     Serialization::Serialize(send, ret);
295     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
296     for (const auto &policyEntry : policyEntries) {
297         Serialization::Serialize(send, policyEntry);
298     };
299 }
300
301 void Service::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
302 {
303     int ret;
304     policy_entry filter;
305     Deserialization::Deserialize(buffer, filter);
306     std::vector<policy_entry> policyEntries;
307
308     if (m_isSlave) {
309         ret = MasterReq::GetPolicy(filter, uid, pid, smackLabel, policyEntries);
310     } else {
311         ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
312     }
313
314     Serialization::Serialize(send, ret);
315     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
316     for (const auto &policyEntry : policyEntries) {
317         Serialization::Serialize(send, policyEntry);
318     };
319 }
320
321 void Service::processPolicyGetDesc(MessageBuffer &send)
322 {
323     int ret;
324     std::vector<std::string> descriptions;
325
326     if (m_isSlave) {
327         ret = MasterReq::PolicyGetDesc(descriptions);
328     } else {
329         ret = ServiceImpl::policyGetDesc(descriptions);
330     }
331     Serialization::Serialize(send, ret);
332     if (ret == SECURITY_MANAGER_API_SUCCESS) {
333         Serialization::Serialize(send, static_cast<int>(descriptions.size()));
334
335         for(std::vector<std::string>::size_type i = 0; i != descriptions.size(); i++) {
336             Serialization::Serialize(send, descriptions[i]);
337         }
338     }
339 }
340
341 void Service::processPrivilegesMappings(MessageBuffer &recv, MessageBuffer &send)
342 {
343     std::vector<std::string> privileges;
344     std::string version_from, version_to;
345     Deserialization::Deserialize(recv, version_from);
346     Deserialization::Deserialize(recv, version_to);
347     Deserialization::Deserialize(recv, privileges);
348
349     int ret = SECURITY_MANAGER_API_SUCCESS;
350     std::vector<std::string> mappings;
351     Serialization::Serialize(send, ret);
352     Serialization::Serialize(send, mappings);
353 }
354
355 } // namespace SecurityManager