Add configuration for systemd.
[framework/security/security-server.git] / src / server2 / service / exec-path.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        exec-path.cpp
20  * @author      Zofia Abramowska (z.abramowska@samsung.com)
21  * @version     1.0
22  * @brief       Implementation of api-exec-path service.
23  */
24
25 #include <string>
26
27 #include <unistd.h>
28 #include <sys/smack.h>
29
30 #include <dpl/log/log.h>
31 #include <dpl/serialization.h>
32
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>
38
39 namespace {
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.
46 //
47 // Please note: SocketManaged does not use it and
48 // does not check it in any way.
49 //
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;
54
55 } // namespace anonymous
56
57 namespace SecurityServer {
58
59 GenericSocketService::ServiceDescriptionVector ExecPathService::GetServiceDescription() {
60     ServiceDescription sd = {
61         "security-server",
62         SERVICE_SOCKET_ID,
63         SERVICE_SOCKET_EXEC_PATH
64     };
65     ServiceDescriptionVector v;
66     v.push_back(sd);
67     return v;
68 }
69
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);
74 }
75
76 void ExecPathService::write(const WriteEvent &event) {
77     LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
78         " Size: " << event.size << " Left: " << event.left);
79     if (event.left == 0)
80         m_serviceManager->Close(event.connectionID);
81 }
82
83 bool ExecPathService::processOne(const ConnectionID &conn, SocketBuffer &buffer) {
84     LogDebug("Processing message");
85
86     int pid = 0;
87     char *exe;
88
89     if (!buffer.Ready()) {
90         return false;
91     }
92
93     Try {
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);
99         return false;
100     }
101
102     SecurityServer::Serialization ser;
103     SocketBuffer sendBuffer;
104     int retVal;
105
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 : "");
111     free(exe);
112
113     if (exec_path.empty())
114     {
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());
119          return true;
120     }
121
122     retVal = SECURITY_SERVER_API_SUCCESS;
123     ser.Serialize(sendBuffer, retVal);
124     ser.Serialize(sendBuffer, exec_path);
125     m_serviceManager->Write(conn, sendBuffer.Pop());
126     return true;
127 }
128
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);
133
134     // We can get several requests in one package.
135     // Extract and process them all
136     while(processOne(event.connectionID, buffer));
137 }
138
139 void ExecPathService::close(const CloseEvent &event) {
140     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
141     m_socketBufferMap.erase(event.connectionID.counter);
142 }
143
144 void ExecPathService::error(const ErrorEvent &event) {
145     LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
146     m_serviceManager->Close(event.connectionID);
147 }
148
149 } // namespace SecurityServer
150