a71087151b9a441d293dbe7be00a4842d7c75c5f
[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                 default:
143                     LogError("Invalid call: " << call_type_int);
144                     Throw(ServiceException::InvalidAction);
145             }
146             // if we reach this point, the protocol is OK
147             retval = true;
148         } Catch (MessageBuffer::Exception::Base) {
149             LogError("Broken protocol.");
150         } Catch (ServiceException::Base) {
151             LogError("Broken protocol.");
152         } catch (const std::exception &e) {
153             LogError("STD exception " << e.what());
154         } catch (...) {
155             LogError("Unknown exception");
156         }
157     }
158     else {
159         LogError("Wrong interface");
160     }
161
162     if (retval) {
163         //send response
164         m_serviceManager->Write(conn, send.Pop());
165     } else {
166         LogError("Closing socket because of error");
167         m_serviceManager->Close(conn);
168     }
169
170     return retval;
171 }
172
173 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
174 {
175     app_inst_req req;
176
177     Deserialization::Deserialize(buffer, req.appId);
178     Deserialization::Deserialize(buffer, req.pkgId);
179     Deserialization::Deserialize(buffer, req.privileges);
180     Deserialization::Deserialize(buffer, req.appPaths);
181     Deserialization::Deserialize(buffer, req.uid);
182     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
183 }
184
185 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
186 {
187     std::string appId;
188
189     Deserialization::Deserialize(buffer, appId);
190     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
191 }
192
193 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
194 {
195     std::string appId;
196     std::string pkgId;
197     int ret;
198
199     Deserialization::Deserialize(buffer, appId);
200     ret = ServiceImpl::getPkgId(appId, pkgId);
201     Serialization::Serialize(send, ret);
202     if (ret == SECURITY_MANAGER_API_SUCCESS)
203         Serialization::Serialize(send, pkgId);
204 }
205
206 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
207 {
208     std::string appId;
209     std::unordered_set<gid_t> gids;
210     int ret;
211
212     Deserialization::Deserialize(buffer, appId);
213     ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
214     Serialization::Serialize(send, ret);
215     if (ret == SECURITY_MANAGER_API_SUCCESS) {
216         Serialization::Serialize(send, static_cast<int>(gids.size()));
217         for (const auto &gid : gids) {
218             Serialization::Serialize(send, gid);
219         }
220     }
221 }
222
223 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
224 {
225     int ret;
226     uid_t uidAdded;
227     int userType;
228
229     Deserialization::Deserialize(buffer, uidAdded);
230     Deserialization::Deserialize(buffer, userType);
231
232     ret = ServiceImpl::userAdd(uidAdded, userType, uid);
233     Serialization::Serialize(send, ret);
234 }
235
236 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
237 {
238     int ret;
239     uid_t uidRemoved;
240
241     Deserialization::Deserialize(buffer, uidRemoved);
242
243     ret = ServiceImpl::userDelete(uidRemoved, uid);
244     Serialization::Serialize(send, ret);
245 }
246
247 void Service::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
248 {
249     int ret;
250     std::vector<policy_entry> policyEntries;
251
252     Deserialization::Deserialize(buffer, policyEntries);
253
254     ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
255     Serialization::Serialize(send, ret);
256 }
257
258 void Service::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel, bool forAdmin)
259 {
260     int ret;
261     policy_entry filter;
262     Deserialization::Deserialize(buffer, filter);
263     std::vector<policy_entry> policyEntries;
264     ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
265     Serialization::Serialize(send, ret);
266     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
267     for (const auto &policyEntry : policyEntries) {
268         Serialization::Serialize(send, policyEntry);
269     };
270 }
271
272 void Service::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
273 {
274     int ret;
275     policy_entry filter;
276     Deserialization::Deserialize(buffer, filter);
277     std::vector<policy_entry> policyEntries;
278     ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
279     Serialization::Serialize(send, ret);
280     Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
281     for (const auto &policyEntry : policyEntries) {
282         Serialization::Serialize(send, policyEntry);
283     };
284 }
285
286 } // namespace SecurityManager