c6f32f8f0dd7401cae5d2fcf6f8a8a4030c6b54f
[framework/security/security-server.git] / src / server2 / service / data-share.cpp
1 /*
2  *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bumjin Im <bj.im@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        data-share.cpp
20  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
21  * @version     1.0
22  * @brief       Implementation of api-data-share service.
23  */
24
25 #include <sys/smack.h>
26
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
29
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>
35
36 namespace {
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.
43 //
44 // Please note: SocketManaged does not use it and
45 // does not check it in any way.
46 //
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;
51
52 } // namespace anonymous
53
54 namespace SecurityServer {
55
56 GenericSocketService::ServiceDescriptionVector SharedMemoryService::GetServiceDescription() {
57     ServiceDescription sd = {
58         "security-server::api-data-share",
59         SERVICE_SOCKET_ID,
60         SERVICE_SOCKET_SHARED_MEMORY
61     };
62     ServiceDescriptionVector v;
63     v.push_back(sd);
64     return v;
65 }
66
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);
71 }
72
73 void SharedMemoryService::write(const WriteEvent &event) {
74     LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
75         " Size: " << event.size << " Left: " << event.left);
76     if (event.left == 0)
77         m_serviceManager->Close(event.connectionID);
78 }
79
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;
86     int clientPid = 0;
87     int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
88     struct smack_accesses *smack = NULL;
89
90     if (!buffer.Ready()) {
91         LogDebug("Got part of message. Service is waiting for the rest.");
92         return false;
93     }
94
95     Try {
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);
102         return false;
103     }
104
105     if (smack_check()) {
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;
109             goto end;
110         }
111
112         if (!util_smack_label_is_valid(clientLabel.c_str())) {
113             LogDebug("Invalid smack label: " << clientLabel);
114             retCode = SECURITY_SERVER_API_ERROR_BAD_REQUEST;
115             goto end;
116         }
117
118         if (smack_accesses_new(&smack)) {
119             LogDebug("Error in smack_accesses_new");
120             goto end;
121         }
122
123         if (smack_accesses_add_modify(smack, clientLabel.c_str(), providerLabel,
124               permissions, revoke))
125         {
126             LogDebug("Error in smack_accesses_add_modify");
127             goto end;
128         }
129
130         if (smack_accesses_apply(smack)) {
131             LogDebug("Error in smack_accesses_apply");
132             retCode = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
133             goto end;
134         }
135         LogDebug("Access granted. Subject: " << clientLabel << " Provider: " << providerLabel);
136     }
137     retCode = SECURITY_SERVER_API_SUCCESS;
138 end:
139     free(providerLabel);
140     smack_accesses_free(smack);
141
142     SecurityServer::Serialization ser;
143     SocketBuffer sendBuffer;
144     ser.Serialize(sendBuffer, retCode);
145     m_serviceManager->Write(conn, sendBuffer.Pop());
146     return true;
147 }
148
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);
153
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));
158 }
159
160 void SharedMemoryService::close(const CloseEvent &event) {
161     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
162     m_socketBufferMap.erase(event.connectionID.counter);
163 }
164
165 void SharedMemoryService::error(const ErrorEvent &event) {
166     LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
167     m_serviceManager->Close(event.connectionID);
168 }
169
170 } // namespace SecurityServer
171