2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@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 data-share.cpp
20 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
22 * @brief Implementation of api-data-share service.
25 #include <sys/smack.h>
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
30 #include <protocols.h>
31 #include <data-share.h>
32 #include <security-server.h>
33 #include <security-server-util.h>
34 #include <smack-check.h>
37 // Service may open more than one socket.
38 // These ID's will be assigned to sockets
39 // and will be used only by service.
40 // When new connection arrives, AcceptEvent
41 // will be generated with proper ID to inform
42 // service about input socket.
44 // Please note: SocketManaged does not use it and
45 // does not check it in any way.
47 // If your service require only one socket
48 // (uses only one socket labeled with smack)
49 // you may ignore this ID (just pass 0)
50 const int SERVICE_SOCKET_ID = 0;
52 } // namespace anonymous
54 namespace SecurityServer {
56 GenericSocketService::ServiceDescriptionVector SharedMemoryService::GetServiceDescription() {
57 ServiceDescription sd = {
58 "security-server::api-data-share",
60 SERVICE_SOCKET_SHARED_MEMORY
62 ServiceDescriptionVector v;
67 void SharedMemoryService::accept(const AcceptEvent &event) {
68 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
69 << " ConnectionID.counter: " << event.connectionID.counter
70 << " ServiceID: " << event.interfaceID);
73 void SharedMemoryService::write(const WriteEvent &event) {
74 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
75 " Size: " << event.size << " Left: " << event.left);
77 m_serviceManager->Close(event.connectionID);
80 bool SharedMemoryService::readOne(const ConnectionID &conn, SocketBuffer &buffer) {
81 LogDebug("Iteration begin");
82 static const char * const revoke = "-----";
83 static const char * const permissions = "rwxat";
84 char *providerLabel = NULL;
85 std::string clientLabel;
87 int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
88 struct smack_accesses *smack = NULL;
90 if (!buffer.Ready()) {
91 LogDebug("Got part of message. Service is waiting for the rest.");
96 SecurityServer::Deserialization des;
97 des.Deserialize(buffer, clientLabel);
98 des.Deserialize(buffer, clientPid);
99 } Catch (SocketBuffer::Exception::Base) {
100 LogDebug("Broken protocol. Closing socket.");
101 m_serviceManager->Close(conn);
106 if (0 != smack_new_label_from_socket(conn.sock, &providerLabel)) {
107 LogDebug("Error in smack_new_label_from_socket");
108 retCode = SECURITY_SERVER_API_ERROR_BAD_REQUEST;
112 if (!util_smack_label_is_valid(clientLabel.c_str())) {
113 LogDebug("Invalid smack label: " << clientLabel);
114 retCode = SECURITY_SERVER_API_ERROR_BAD_REQUEST;
118 if (smack_accesses_new(&smack)) {
119 LogDebug("Error in smack_accesses_new");
123 if (smack_accesses_add_modify(smack, clientLabel.c_str(), providerLabel,
124 permissions, revoke))
126 LogDebug("Error in smack_accesses_add_modify");
130 if (smack_accesses_apply(smack)) {
131 LogDebug("Error in smack_accesses_apply");
132 retCode = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
135 LogDebug("Access granted. Subject: " << clientLabel << " Provider: " << providerLabel);
137 retCode = SECURITY_SERVER_API_SUCCESS;
140 smack_accesses_free(smack);
142 SecurityServer::Serialization ser;
143 SocketBuffer sendBuffer;
144 ser.Serialize(sendBuffer, retCode);
145 m_serviceManager->Write(conn, sendBuffer.Pop());
149 void SharedMemoryService::read(const ReadEvent &event) {
150 LogDebug("Read event for counter: " << event.connectionID.counter);
151 auto &buffer = m_socketBufferMap[event.connectionID.counter];
152 buffer.Push(event.rawBuffer);
154 LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
155 // We can get several requests in one package.
156 // Extract and process them all
157 while(readOne(event.connectionID, buffer));
160 void SharedMemoryService::close(const CloseEvent &event) {
161 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
162 m_socketBufferMap.erase(event.connectionID.counter);
165 void SharedMemoryService::error(const ErrorEvent &event) {
166 LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
167 m_serviceManager->Close(event.connectionID);
170 } // namespace SecurityServer