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
19 * @file master-service.cpp
20 * @author Lukasz Kostyra <l.kostyra@samsung.com>
21 * @author Rafal Krypa <r.krypa@samsung.com>
22 * @brief Implementation of security-manager master service.
25 #include <generic-socket-manager.h>
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
30 #include "protocols.h"
31 #include "zone-utils.h"
33 #include "master-service.h"
34 #include "smack-rules.h"
35 #include "smack-labels.h"
36 #include "service_impl.h"
38 namespace SecurityManager {
40 const InterfaceID IFACE = 1;
42 MasterService::MasterService()
46 GenericSocketService::ServiceDescriptionVector MasterService::GetServiceDescription()
48 return ServiceDescriptionVector {
49 {MASTER_SERVICE_SOCKET, "security-manager-master", IFACE},
53 bool MasterService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
54 InterfaceID interfaceID)
56 LogDebug("Iteration begin. Interface = " << interfaceID);
58 //waiting for all data
59 if (!buffer.Ready()) {
68 std::string smackLabel;
70 if (!getPeerID(conn.sock, uid, pid, smackLabel)) {
71 LogError("Closing socket because of error: unable to get peer's uid and pid");
72 m_serviceManager->Close(conn);
76 // FIXME this part needs to be updated when Vasum is added to OBS. See zone-utils.h
77 std::string vsmZoneId;
78 if (!getZoneIdFromPid(pid, vsmZoneId)) {
79 LogError("Failed to extract Zone ID! Closing socket.");
80 m_serviceManager->Close(conn);
84 if (vsmZoneId == ZONE_HOST) {
85 LogError("Connection came from host - in master mode this should not happen! Closing.");
86 m_serviceManager->Close(conn);
90 LogInfo("Connection came from Zone " << vsmZoneId);
92 if (IFACE == interfaceID) {
94 // deserialize API call type
96 Deserialization::Deserialize(buffer, call_type_int);
97 MasterSecurityModuleCall call_type = static_cast<MasterSecurityModuleCall>(call_type_int);
100 case MasterSecurityModuleCall::CYNARA_UPDATE_POLICY:
101 LogDebug("call type MasterSecurityModuleCall::CYNARA_UPDATE_POLICY");
102 processCynaraUpdatePolicy(buffer, send, vsmZoneId);
104 case MasterSecurityModuleCall::CYNARA_USER_INIT:
105 LogDebug("call type MasterSecurityModuleCall::CYNARA_USER_INIT");
106 processCynaraUserInit(buffer, send);
108 case MasterSecurityModuleCall::CYNARA_USER_REMOVE:
109 LogDebug("call type MasterSecurityModuleCall::CYNARA_USER_REMOVE");
110 processCynaraUserRemove(buffer, send);
112 case MasterSecurityModuleCall::POLICY_UPDATE:
113 LogDebug("call type MasterSecurityModuleCall::POLICY_UPDATE");
114 processPolicyUpdate(buffer, send);
116 case MasterSecurityModuleCall::GET_CONFIGURED_POLICY:
117 LogDebug("call type MasterSecurityModuleCall::GET_CONFIGURED_POLICY");
118 processGetConfiguredPolicy(buffer, send);
120 case MasterSecurityModuleCall::GET_POLICY:
121 LogDebug("call type MasterSecurityModuleCall::GET_POLICY");
122 processGetPolicy(buffer, send);
124 case MasterSecurityModuleCall::POLICY_GET_DESC:
125 LogDebug("call type MasterSecurityModuleCall::POLICY_GET_DESC");
126 processPolicyGetDesc(send);
128 case MasterSecurityModuleCall::SMACK_INSTALL_RULES:
129 LogDebug("call type MasterSecurityModuleCall::SMACK_INSTALL_RULES");
130 processSmackInstallRules(buffer, send, vsmZoneId);
132 case MasterSecurityModuleCall::SMACK_UNINSTALL_RULES:
133 LogDebug("call type MasterSecurityModuleCall::SMACK_UNINSTALL_RULES");
134 processSmackUninstallRules(buffer, send, vsmZoneId);
137 LogError("Invalid call: " << call_type_int);
138 Throw(MasterServiceException::InvalidAction);
140 // if we reach this point, the protocol is OK
142 } Catch (MessageBuffer::Exception::Base) {
143 LogError("Broken protocol.");
144 } Catch (MasterServiceException::Base) {
145 LogError("Broken protocol.");
146 } catch (const std::exception &e) {
147 LogError("STD exception " << e.what());
149 LogError("Unknown exception");
153 LogError("Wrong interface");
158 m_serviceManager->Write(conn, send.Pop());
160 LogError("Closing socket because of error");
161 m_serviceManager->Close(conn);
167 void MasterService::processCynaraUpdatePolicy(MessageBuffer &buffer, MessageBuffer &send,
168 const std::string &zoneId)
170 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
173 std::vector<std::string> oldAppPrivileges, newAppPrivileges;
174 std::string appLabel, newLabel;
176 Deserialization::Deserialize(buffer, appId);
177 Deserialization::Deserialize(buffer, uidstr);
178 Deserialization::Deserialize(buffer, oldAppPrivileges);
179 Deserialization::Deserialize(buffer, newAppPrivileges);
181 appLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(appId), zoneId);
184 CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, uidstr, oldAppPrivileges,
186 } catch (const CynaraException::Base &e) {
187 LogError("Error while setting Cynara rules for application: " << e.DumpToString());
189 } catch (const std::bad_alloc &e) {
190 LogError("Memory allocation while setting Cynara rules for application: " << e.what());
191 ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
195 ret = SECURITY_MANAGER_API_SUCCESS;
198 Serialization::Serialize(send, ret);
201 void MasterService::processCynaraUserInit(MessageBuffer &buffer, MessageBuffer &send)
203 int ret = SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
207 Deserialization::Deserialize(buffer, uidAdded);
208 Deserialization::Deserialize(buffer, userType);
211 CynaraAdmin::getInstance().UserInit(uidAdded,
212 static_cast<security_manager_user_type>(userType));
213 } catch (CynaraException::InvalidParam &e) {
217 ret = SECURITY_MANAGER_API_SUCCESS;
219 Serialization::Serialize(send, ret);
222 void MasterService::processCynaraUserRemove(MessageBuffer &buffer, MessageBuffer &send)
224 int ret = SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
227 Deserialization::Deserialize(buffer, uidDeleted);
230 CynaraAdmin::getInstance().UserRemove(uidDeleted);
231 } catch (CynaraException::InvalidParam &e) {
235 ret = SECURITY_MANAGER_API_SUCCESS;
237 Serialization::Serialize(send, ret);
240 void MasterService::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send)
242 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
243 std::vector<policy_entry> policyEntries;
246 std::string smackLabel;
248 Deserialization::Deserialize(buffer, policyEntries);
249 Deserialization::Deserialize(buffer, uid);
250 Deserialization::Deserialize(buffer, pid);
251 Deserialization::Deserialize(buffer, smackLabel);
253 ret = serviceImpl.policyUpdate(policyEntries, uid, pid, smackLabel);
254 Serialization::Serialize(send, ret);
257 void MasterService::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send)
259 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
264 std::string smackLabel;
265 std::vector<policy_entry> policyEntries;
267 Deserialization::Deserialize(buffer, forAdmin);
268 Deserialization::Deserialize(buffer, filter);
269 Deserialization::Deserialize(buffer, uid);
270 Deserialization::Deserialize(buffer, pid);
271 Deserialization::Deserialize(buffer, smackLabel);
273 ret = serviceImpl.getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
274 Serialization::Serialize(send, ret);
275 if (ret == SECURITY_MANAGER_API_SUCCESS)
276 Serialization::Serialize(send, policyEntries);
279 void MasterService::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send)
282 int ret = SECURITY_MANAGER_API_ERROR_BAD_REQUEST;
284 // FIXME getPolicy is not ready to work in Master mode. Uncomment below code when getPolicy will
285 // be implemented for Master.
290 std::string smackLabel;
291 std::vector<policy_entry> policyEntries;
293 Deserialization::Deserialize(buffer, filter);
294 Deserialization::Deserialize(buffer, uid);
295 Deserialization::Deserialize(buffer, pid);
296 Deserialization::Deserialize(buffer, smackLabel);
298 ret = serviceImpl.getPolicy(filter, uid, pid, smackLabel, policyEntries);*/
299 Serialization::Serialize(send, ret);
300 /*if (ret == SECURITY_MANAGER_API_SUCCESS)
301 Serialization::Serialize(send, policyEntries);*/
304 void MasterService::processPolicyGetDesc(MessageBuffer &send)
306 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
307 std::vector<std::string> descriptions;
309 ret = serviceImpl.policyGetDesc(descriptions);
310 Serialization::Serialize(send, ret);
311 if (ret == SECURITY_MANAGER_API_SUCCESS)
312 Serialization::Serialize(send, descriptions);
315 void MasterService::processSmackInstallRules(MessageBuffer &buffer, MessageBuffer &send,
316 const std::string &zoneId)
318 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
319 std::string appId, pkgId;
320 std::vector<std::string> pkgContents;
322 Deserialization::Deserialize(buffer, appId);
323 Deserialization::Deserialize(buffer, pkgId);
324 Deserialization::Deserialize(buffer, pkgContents);
327 LogDebug("Adding Smack rules for new appId: " << appId << " with pkgId: "
328 << pkgId << ". Applications in package: " << pkgContents.size());
329 SmackRules::installApplicationRules(appId, pkgId, pkgContents, zoneId);
331 // FIXME implement zoneSmackLabelMap and check if works when Smack Namespaces are implemented
332 std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
333 std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
334 std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
335 std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
337 if (!zoneSmackLabelMap(hostAppLabel, zoneId, zoneAppLabel)) {
338 LogError("Failed to apply Smack label mapping for application " << appId);
342 if (!zoneSmackLabelMap(hostPkgLabel, zoneId, zonePkgLabel)) {
343 LogError("Failed to apply Smack label mapping for package " << pkgId);
346 } catch (const SmackException::Base &e) {
347 LogError("Error while adding Smack rules for application: " << e.DumpToString());
348 ret = SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
350 } catch (const std::bad_alloc &e) {
351 LogError("Memory allocation error: " << e.what());
352 ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
356 ret = SECURITY_MANAGER_API_SUCCESS;
358 Serialization::Serialize(send, ret);
361 void MasterService::processSmackUninstallRules(MessageBuffer &buffer, MessageBuffer &send,
362 const std::string &zoneId)
364 int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
365 std::string appId, pkgId;
366 std::vector<std::string> pkgContents;
367 bool removePkg = false;
369 Deserialization::Deserialize(buffer, appId);
370 Deserialization::Deserialize(buffer, pkgId);
371 Deserialization::Deserialize(buffer, pkgContents);
372 Deserialization::Deserialize(buffer, removePkg);
376 LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
377 SmackRules::uninstallPackageRules(pkgId);
380 LogDebug ("Removing smack rules for deleted appId " << appId);
381 SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
383 // FIXME implement zoneSmackLabelUnmap and check if works when Smack Namespaces are implemented
384 std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
385 std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
386 std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
387 std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
389 if (!zoneSmackLabelUnmap(hostAppLabel, zoneId)) {
390 LogError("Failed to unmap Smack labels for application " << appId);
395 if (!zoneSmackLabelUnmap(hostPkgLabel, zoneId)) {
396 LogError("Failed to unmap Smack label for package " << pkgId);
400 } catch (const SmackException::Base &e) {
401 LogError("Error while removing Smack rules for application: " << e.DumpToString());
402 ret = SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
404 } catch (const std::bad_alloc &e) {
405 LogError("Memory allocation error: " << e.what());
406 ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
410 ret = SECURITY_MANAGER_API_SUCCESS;
412 Serialization::Serialize(send, ret);
415 } // namespace SecurityManager