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