2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
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.
26 #include <sys/socket.h>
28 #include <dpl/log/log.h>
29 #include <dpl/serialization.h>
31 #include "protocols.h"
33 #include "service_impl.h"
35 namespace SecurityManager {
37 const InterfaceID IFACE = 1;
43 GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription()
45 return ServiceDescriptionVector {
46 {SERVICE_SOCKET, "security-manager", IFACE},
50 void Service::accept(const AcceptEvent &event)
52 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock <<
53 " ConnectionID.counter: " << event.connectionID.counter <<
54 " ServiceID: " << event.interfaceID);
56 auto &info = m_connectionInfoMap[event.connectionID.counter];
57 info.interfaceID = event.interfaceID;
60 void Service::write(const WriteEvent &event)
62 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
63 " Size: " << event.size <<
64 " Left: " << event.left);
67 m_serviceManager->Close(event.connectionID);
70 void Service::process(const ReadEvent &event)
72 LogDebug("Read event for counter: " << event.connectionID.counter);
73 auto &info = m_connectionInfoMap[event.connectionID.counter];
74 info.buffer.Push(event.rawBuffer);
76 // We can get several requests in one package.
77 // Extract and process them all
78 while (processOne(event.connectionID, info.buffer, info.interfaceID));
81 void Service::close(const CloseEvent &event)
83 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
84 m_connectionInfoMap.erase(event.connectionID.counter);
87 static bool getPeerID(int sock, uid_t &uid, pid_t &pid) {
89 socklen_t len = sizeof(cr);
91 if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
100 bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
101 InterfaceID interfaceID)
103 LogDebug("Iteration begin. Interface = " << interfaceID);
105 //waiting for all data
106 if (!buffer.Ready()) {
116 if(!getPeerID(conn.sock, uid, pid)) {
117 LogError("Closing socket because of error: unable to get peer's uid and pid");
118 m_serviceManager->Close(conn);
122 if (IFACE == interfaceID) {
124 // deserialize API call type
126 Deserialization::Deserialize(buffer, call_type_int);
127 SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
130 case SecurityModuleCall::APP_INSTALL:
131 LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
132 processAppInstall(buffer, send, uid);
134 case SecurityModuleCall::APP_UNINSTALL:
135 LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
136 processAppUninstall(buffer, send, uid);
138 case SecurityModuleCall::APP_GET_PKGID:
139 processGetPkgId(buffer, send);
141 case SecurityModuleCall::APP_GET_GROUPS:
142 processGetAppGroups(buffer, send, uid, pid);
144 case SecurityModuleCall::USER_ADD:
145 processUserAdd(buffer, send, uid);
147 case SecurityModuleCall::USER_DELETE:
148 processUserDelete(buffer, send, uid);
151 LogError("Invalid call: " << call_type_int);
152 Throw(ServiceException::InvalidAction);
154 // if we reach this point, the protocol is OK
156 } Catch (MessageBuffer::Exception::Base) {
157 LogError("Broken protocol.");
158 } Catch (ServiceException::Base) {
159 LogError("Broken protocol.");
160 } catch (std::exception &e) {
161 LogError("STD exception " << e.what());
163 LogError("Unknown exception");
167 LogError("Wrong interface");
172 m_serviceManager->Write(conn, send.Pop());
174 LogError("Closing socket because of error");
175 m_serviceManager->Close(conn);
181 void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
185 Deserialization::Deserialize(buffer, req.appId);
186 Deserialization::Deserialize(buffer, req.pkgId);
187 Deserialization::Deserialize(buffer, req.privileges);
188 Deserialization::Deserialize(buffer, req.appPaths);
189 Deserialization::Deserialize(buffer, req.uid);
190 Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
193 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
197 Deserialization::Deserialize(buffer, appId);
198 Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
201 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
207 Deserialization::Deserialize(buffer, appId);
208 ret = ServiceImpl::getPkgId(appId, pkgId);
209 Serialization::Serialize(send, ret);
210 if (ret == SECURITY_MANAGER_API_SUCCESS)
211 Serialization::Serialize(send, pkgId);
214 void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid)
217 std::unordered_set<gid_t> gids;
220 Deserialization::Deserialize(buffer, appId);
221 ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
222 Serialization::Serialize(send, ret);
223 if (ret == SECURITY_MANAGER_API_SUCCESS) {
224 Serialization::Serialize(send, static_cast<int>(gids.size()));
225 for (const auto &gid : gids) {
226 Serialization::Serialize(send, gid);
231 void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
237 Deserialization::Deserialize(buffer, uidAdded);
238 Deserialization::Deserialize(buffer, userType);
240 ret = ServiceImpl::userAdd(uidAdded, userType, uid);
241 Serialization::Serialize(send, ret);
244 void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
249 Deserialization::Deserialize(buffer, uidRemoved);
251 ret = ServiceImpl::userDelete(uidRemoved, uid);
252 Serialization::Serialize(send, ret);
256 } // namespace SecurityManager