ca0bf528bd222c09788e07d3fa1b12960102db61
[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::NOOP:
98                     LogDebug("call_type: SecurityModuleCall::NOOP");
99                     Serialization::Serialize(send, SECURITY_MANAGER_API_SUCCESS);
100                     break;
101                 case SecurityModuleCall::APP_INSTALL:
102                     LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
103                     processAppInstall(buffer, send, uid);
104                     break;
105                 case SecurityModuleCall::APP_UNINSTALL:
106                     LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
107                     processAppUninstall(buffer, send, uid);
108                     break;
109                 case SecurityModuleCall::APP_GET_PKGID:
110                     processGetPkgId(buffer, send);
111                     break;
112                 case SecurityModuleCall::APP_GET_GROUPS:
113                     processGetAppGroups(buffer, send, uid, pid);
114                     break;
115                 case SecurityModuleCall::USER_ADD:
116                     processUserAdd(buffer, send, uid);
117                     break;
118                 case SecurityModuleCall::USER_DELETE:
119                     processUserDelete(buffer, send, uid);
120                     break;
121                 default:
122                     LogError("Invalid call: " << call_type_int);
123                     Throw(ServiceException::InvalidAction);
124             }
125             // if we reach this point, the protocol is OK
126             retval = true;
127         } Catch (MessageBuffer::Exception::Base) {
128             LogError("Broken protocol.");
129         } Catch (ServiceException::Base) {
130             LogError("Broken protocol.");
131         } catch (const std::exception &e) {
132             LogError("STD exception " << e.what());
133         } catch (...) {
134             LogError("Unknown exception");
135         }
136     }
137     else {
138         LogError("Wrong interface");
139     }
140
141     if (retval) {
142         //send response
143         m_serviceManager->Write(conn, send.Pop());
144     } else {
145         LogError("Closing socket because of error");
146         m_serviceManager->Close(conn);
147     }
148
149     return retval;
150 }
151
152 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
153 {
154     app_inst_req req;
155
156     Deserialization::Deserialize(buffer, req.appId);
157     Deserialization::Deserialize(buffer, req.pkgId);
158     Deserialization::Deserialize(buffer, req.privileges);
159     Deserialization::Deserialize(buffer, req.appPaths);
160     Deserialization::Deserialize(buffer, req.uid);
161     Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
162 }
163
164 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
165 {
166     std::string appId;
167
168     Deserialization::Deserialize(buffer, appId);
169     Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
170 }
171
172 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
173 {
174     std::string appId;
175     std::string pkgId;
176     int ret;
177
178     Deserialization::Deserialize(buffer, appId);
179     ret = ServiceImpl::getPkgId(appId, pkgId);
180     Serialization::Serialize(send, ret);
181     if (ret == SECURITY_MANAGER_API_SUCCESS)
182         Serialization::Serialize(send, pkgId);
183 }
184
185 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
186 {
187     std::string appId;
188     std::unordered_set<gid_t> gids;
189     int ret;
190
191     Deserialization::Deserialize(buffer, appId);
192     ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
193     Serialization::Serialize(send, ret);
194     if (ret == SECURITY_MANAGER_API_SUCCESS) {
195         Serialization::Serialize(send, static_cast<int>(gids.size()));
196         for (const auto &gid : gids) {
197             Serialization::Serialize(send, gid);
198         }
199     }
200 }
201
202 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
203 {
204     int ret;
205     uid_t uidAdded;
206     int userType;
207
208     Deserialization::Deserialize(buffer, uidAdded);
209     Deserialization::Deserialize(buffer, userType);
210
211     ret = ServiceImpl::userAdd(uidAdded, userType, uid);
212     Serialization::Serialize(send, ret);
213 }
214
215 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
216 {
217     int ret;
218     uid_t uidRemoved;
219
220     Deserialization::Deserialize(buffer, uidRemoved);
221
222     ret = ServiceImpl::userDelete(uidRemoved, uid);
223     Serialization::Serialize(send, ret);
224 }
225
226
227 } // namespace SecurityManager