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 privilege-by-pid.cpp
20 * @author Jan Cybulski (j.cybulski@samsung.com)
22 * @brief Implementation of check-privilege-by-pid service.
25 #include <sys/smack.h>
27 #include <dpl/log/log.h>
28 #include <dpl/serialization.h>
30 #include <protocols.h>
31 #include <privilege-by-pid.h>
33 #include <security-server.h>
34 #include <security-server-util.h>
35 #include <smack-check.h>
37 #include <privilege-control.h>
39 namespace SecurityServer {
41 GenericSocketService::ServiceDescriptionVector PrivilegeByPidService::GetServiceDescription() {
42 return ServiceDescriptionVector
43 {{SERVICE_SOCKET_PRIVILEGE_BY_PID, "security-server::api-privilege-by-pid" }};
46 void PrivilegeByPidService::accept(const AcceptEvent &event) {
47 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
48 << " ConnectionID.counter: " << event.connectionID.counter
49 << " ServiceID: " << event.interfaceID);
52 void PrivilegeByPidService::write(const WriteEvent &event) {
53 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
54 " Size: " << event.size << " Left: " << event.left);
56 m_serviceManager->Close(event.connectionID);
59 bool PrivilegeByPidService::processOne(const ConnectionID &conn, MessageBuffer &buffer) {
60 LogDebug("Iteration begin");
65 std::string access_rights;
66 char subject[SMACK_LABEL_LEN + 1] = {0};
68 int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
71 if (!buffer.Ready()) {
76 Deserialization::Deserialize(buffer, pid);
77 Deserialization::Deserialize(buffer, object);
78 Deserialization::Deserialize(buffer, access_rights);
79 } Catch (MessageBuffer::Exception::Base) {
80 LogDebug("Broken protocol. Closing socket.");
81 m_serviceManager->Close(conn);
86 retval = smack_pid_have_access(pid, object.c_str(), access_rights.c_str());
87 LogDebug("smack_pid_have_access returned " << retval);
89 if (get_smack_label_from_process(pid, subject) != PC_OPERATION_SUCCESS) {
90 // subject label is set to empty string
91 LogError("get_smack_label_from_process failed. Subject label has not been read.");
93 LogSecureDebug("Subject label of client PID " << pid << " is: " << subject);
96 LogDebug("SMACK is not available. Subject label has not been read.");
99 // char *path = read_exe_path_from_proc(pid);
102 // LogDebug("SS_SMACK: "
103 // << "caller_pid=" << pid
104 // << ", subject=" << subject
105 // << ", object=" << object
106 // << ", access=" << access_rights
107 // << ", result=" << retval
108 // << ", caller_path=" << path);
110 // LogError("SS_SMACK: "
111 // << "caller_pid=" << pid
112 // << ", subject=" << subject
113 // << ", object=" << object
114 // << ", access=" << access_rights
115 // << ", result=" << retval
116 // << ", caller_path=" << path);
122 if (retval == 1) //there is permission
123 retCode = SECURITY_SERVER_API_SUCCESS;
124 else //there is no permission
125 retCode = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
127 MessageBuffer sendBuffer;
128 Serialization::Serialize(sendBuffer, retCode);
129 m_serviceManager->Write(conn, sendBuffer.Pop());
132 char *path = read_exe_path_from_proc(pid);
134 LogSmackAudit("SS_SMACK: "
135 << "caller_pid=" << pid
136 << ", subject=" << subject
137 << ", object=" << object
138 << ", access=" << access_rights
139 << ", result=" << retval
140 << ", caller_path=" << (path ? path : ""));
148 void PrivilegeByPidService::process(const ReadEvent &event) {
149 LogDebug("Read event for counter: " << event.connectionID.counter);
150 auto &buffer = m_messageBufferMap[event.connectionID.counter];
151 buffer.Push(event.rawBuffer);
153 // We can get several requests in one package.
154 // Extract and process them all
155 while(processOne(event.connectionID, buffer));
158 void PrivilegeByPidService::close(const CloseEvent &event) {
159 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
160 m_messageBufferMap.erase(event.connectionID.counter);
163 } // namespace SecurityServer