Require socket to be passed by systemd, don't create it on our own
[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,  /* path */
47          "*",   /* smackLabel label (not used, we rely on systemd) */
48          IFACE, /* InterfaceID */
49          false, /* useSendMsg */
50          true}, /* systemdOnly */
51     };
52 }
53
54 static bool getPeerID(int sock, uid_t &uid, pid_t &pid) {
55     struct ucred cr;
56     socklen_t len = sizeof(cr);
57
58     if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
59         uid = cr.uid;
60         pid = cr.pid;
61         return true;
62     }
63
64     return false;
65 }
66
67 bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
68                                   InterfaceID interfaceID)
69 {
70     LogDebug("Iteration begin. Interface = " << interfaceID);
71
72     //waiting for all data
73     if (!buffer.Ready()) {
74         return false;
75     }
76
77     MessageBuffer send;
78     bool retval = false;
79
80     uid_t uid;
81     pid_t pid;
82
83     if (!getPeerID(conn.sock, uid, pid)) {
84         LogError("Closing socket because of error: unable to get peer's uid and pid");
85         m_serviceManager->Close(conn);
86         return false;
87     }
88
89     if (IFACE == interfaceID) {
90         Try {
91             // deserialize API call type
92             int call_type_int;
93             Deserialization::Deserialize(buffer, call_type_int);
94             SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
95
96             switch (call_type) {
97                 case SecurityModuleCall::APP_INSTALL:
98                     LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
99                     processAppInstall(buffer, send, uid);
100                     break;
101                 case SecurityModuleCall::APP_UNINSTALL:
102                     LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
103                     processAppUninstall(buffer, send, uid);
104                     break;
105                 case SecurityModuleCall::APP_GET_PKGID:
106                     processGetPkgId(buffer, send);
107                     break;
108                 case SecurityModuleCall::APP_GET_GROUPS:
109                     processGetAppGroups(buffer, send, uid, pid);
110                     break;
111                 case SecurityModuleCall::USER_ADD:
112                     processUserAdd(buffer, send, uid);
113                     break;
114                 case SecurityModuleCall::USER_DELETE:
115                     processUserDelete(buffer, send, uid);
116                     break;
117                 default:
118                     LogError("Invalid call: " << call_type_int);
119                     Throw(ServiceException::InvalidAction);
120             }
121             // if we reach this point, the protocol is OK
122             retval = true;
123         } Catch (MessageBuffer::Exception::Base) {
124             LogError("Broken protocol.");
125         } Catch (ServiceException::Base) {
126             LogError("Broken protocol.");
127         } catch (const std::exception &e) {
128             LogError("STD exception " << e.what());
129         } catch (...) {
130             LogError("Unknown exception");
131         }
132     }
133     else {
134         LogError("Wrong interface");
135     }
136
137     if (retval) {
138         //send response
139         m_serviceManager->Write(conn, send.Pop());
140     } else {
141         LogError("Closing socket because of error");
142         m_serviceManager->Close(conn);
143     }
144
145     return retval;
146 }
147
148 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
149 {
150     app_inst_req req;
151
152     Deserialization::Deserialize(buffer, req.appId);
153     Deserialization::Deserialize(buffer, req.pkgId);
154     Deserialization::Deserialize(buffer, req.privileges);
155     Deserialization::Deserialize(buffer, req.appPaths);
156     Deserialization::Deserialize(buffer, req.uid);
157     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
158 }
159
160 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
161 {
162     std::string appId;
163
164     Deserialization::Deserialize(buffer, appId);
165     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
166 }
167
168 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
169 {
170     std::string appId;
171     std::string pkgId;
172     int ret;
173
174     Deserialization::Deserialize(buffer, appId);
175     ret = ServiceImpl::getPkgId(appId, pkgId);
176     Serialization::Serialize(send, ret);
177     if (ret == SECURITY_MANAGER_API_SUCCESS)
178         Serialization::Serialize(send, pkgId);
179 }
180
181 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
182 {
183     std::string appId;
184     std::unordered_set<gid_t> gids;
185     int ret;
186
187     Deserialization::Deserialize(buffer, appId);
188     ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
189     Serialization::Serialize(send, ret);
190     if (ret == SECURITY_MANAGER_API_SUCCESS) {
191         Serialization::Serialize(send, static_cast<int>(gids.size()));
192         for (const auto &gid : gids) {
193             Serialization::Serialize(send, gid);
194         }
195     }
196 }
197
198 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
199 {
200     int ret;
201     uid_t uidAdded;
202     int userType;
203
204     Deserialization::Deserialize(buffer, uidAdded);
205     Deserialization::Deserialize(buffer, userType);
206
207     ret = ServiceImpl::userAdd(uidAdded, userType, uid);
208     Serialization::Serialize(send, ret);
209 }
210
211 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
212 {
213     int ret;
214     uid_t uidRemoved;
215
216     Deserialization::Deserialize(buffer, uidRemoved);
217
218     ret = ServiceImpl::userDelete(uidRemoved, uid);
219     Serialization::Serialize(send, ret);
220 }
221
222
223 } // namespace SecurityManager