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
20 * @author Zofia Abramowska (z.abramowska@samsung.com)
22 * @brief Implementation of api-exec-path service.
28 #include <sys/smack.h>
30 #include <dpl/log/log.h>
31 #include <dpl/serialization.h>
33 #include <protocols.h>
34 #include <exec-path.h>
35 #include <security-server.h>
36 #include <security-server-util.h>
37 #include <smack-check.h>
40 // Service may open more than one socket.
41 // These ID's will be assigned to sockets
42 // and will be used only by service.
43 // When new connection arrives, AcceptEvent
44 // will be generated with proper ID to inform
45 // service about input socket.
47 // Please note: SocketManaged does not use it and
48 // does not check it in any way.
50 // If your service require only one socket
51 // (uses only one socket labeled with smack)
52 // you may ignore this ID (just pass 0)
53 const int SERVICE_SOCKET_ID = 0;
55 } // namespace anonymous
57 namespace SecurityServer {
59 GenericSocketService::ServiceDescriptionVector ExecPathService::GetServiceDescription() {
60 ServiceDescription sd = {
63 SERVICE_SOCKET_EXEC_PATH
65 ServiceDescriptionVector v;
70 void ExecPathService::accept(const AcceptEvent &event) {
71 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
72 << " ConnectionID.counter: " << event.connectionID.counter
73 << " ServiceID: " << event.interfaceID);
76 void ExecPathService::write(const WriteEvent &event) {
77 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
78 " Size: " << event.size << " Left: " << event.left);
80 m_serviceManager->Close(event.connectionID);
83 bool ExecPathService::processOne(const ConnectionID &conn, SocketBuffer &buffer) {
84 LogDebug("Processing message");
89 if (!buffer.Ready()) {
94 SecurityServer::Deserialization des;
95 des.Deserialize(buffer, pid);
96 } Catch (SocketBuffer::Exception::Base) {
97 LogDebug("Broken protocol. Closing socket.");
98 m_serviceManager->Close(conn);
102 SecurityServer::Serialization ser;
103 SocketBuffer sendBuffer;
106 // get executable path
107 exe = read_exe_path_from_proc(pid);
108 // quickly getting rid of allocated memory
109 // when read_exe_path_from_proc will rewritten this won't be required
110 std::string exec_path(exe ? exe : "");
113 if (exec_path.empty())
115 LogError("Server: Failed to read executable path for pid " << pid);
116 retVal = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
117 ser.Serialize(sendBuffer, retVal);
118 m_serviceManager->Write(conn, sendBuffer.Pop());
122 retVal = SECURITY_SERVER_API_SUCCESS;
123 ser.Serialize(sendBuffer, retVal);
124 ser.Serialize(sendBuffer, exec_path);
125 m_serviceManager->Write(conn, sendBuffer.Pop());
129 void ExecPathService::read(const ReadEvent &event) {
130 LogDebug("Read event for counter: " << event.connectionID.counter);
131 auto &buffer = m_socketBufferMap[event.connectionID.counter];
132 buffer.Push(event.rawBuffer);
134 // We can get several requests in one package.
135 // Extract and process them all
136 while(processOne(event.connectionID, buffer));
139 void ExecPathService::close(const CloseEvent &event) {
140 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
141 m_socketBufferMap.erase(event.connectionID.counter);
144 void ExecPathService::error(const ErrorEvent &event) {
145 LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
146 m_serviceManager->Close(event.connectionID);
149 } // namespace SecurityServer