ln -s ../security-server-data-share.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-data-share.socket
ln -s ../security-server-get-gid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-get-gid.socket
ln -s ../security-server-privilege-by-pid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
+ln -s ../security-server-exec-path.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-exec-path.socket
%clean
rm -rf %{buildroot}
%attr(-,root,root) /usr/lib/systemd/system/security-server-get-gid.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-privilege-by-pid.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-exec-path.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-exec-path.socket
%{_datadir}/license/%{name}
${SERVER2_PATH}/service/echo.cpp
${SERVER2_PATH}/service/get-gid.cpp
${SERVER2_PATH}/service/privilege-by-pid.cpp
+ ${SERVER2_PATH}/service/exec-path.cpp
)
SET_SOURCE_FILES_PROPERTIES(
${SECURITY_SERVER_PATH}/server2/client/client-shared-memory.cpp
${SECURITY_SERVER_PATH}/server2/client/client-get-gid.cpp
${SECURITY_SERVER_PATH}/server2/client/client-privilege-by-pid.cpp
+ ${SECURITY_SERVER_PATH}/server2/client/client-socket-privilege.cpp
${SECURITY_SERVER_PATH}/client/security-server-client.c
${SECURITY_SERVER_PATH}/communication/security-server-comm.c
${SECURITY_SERVER_PATH}/util/smack-check.c
return err_code;
}
-static int send_exec_path_request(int sock_fd, pid_t pid)
-{
- basic_header hdr;
- int retval;
- unsigned char buf[sizeof(hdr) + sizeof(pid)];
-
- /* Assemble header */
- hdr.version = SECURITY_SERVER_MSG_VERSION;
- hdr.msg_id = SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST;
- hdr.msg_len = sizeof(pid);
-
- memcpy(buf, &hdr, sizeof(hdr));
- memcpy(buf + sizeof(hdr), &pid, sizeof(pid));
-
- /* Check poll */
- retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
- if (retval == SECURITY_SERVER_ERROR_POLL)
- {
- SEC_SVR_ERR("%s", "poll() error");
- return SECURITY_SERVER_ERROR_SEND_FAILED;
- }
- if (retval == SECURITY_SERVER_ERROR_TIMEOUT)
- {
- SEC_SVR_ERR("%s", "poll() timeout");
- return SECURITY_SERVER_ERROR_SEND_FAILED;
- }
-
- /* Send to server */
- retval = TEMP_FAILURE_RETRY(write(sock_fd, buf, sizeof(buf)));
- if (retval < (ssize_t)sizeof(buf))
- {
- /* Write error */
- SEC_SVR_ERR("Error on write(): %d", retval);
- return SECURITY_SERVER_ERROR_SEND_FAILED;
- }
- return SECURITY_SERVER_SUCCESS;
-}
-
-static int recv_exec_path_response(int sockfd, response_header *hdr, char **path)
-{
- size_t size = 0;
- char *buf = NULL;
- int retval;
-
- if (*path)
- {
- SEC_SVR_ERR("path should be NULL");
- return SECURITY_SERVER_ERROR_INPUT_PARAM;
- }
-
- retval = recv_generic_response(sockfd, hdr);
- if (retval != SECURITY_SERVER_SUCCESS)
- {
- SEC_SVR_ERR("Failed to get response: %d", retval);
- return return_code_to_error_code(hdr->return_code);
- }
-
- retval = TEMP_FAILURE_RETRY(read(sockfd, &size, sizeof(size_t)));
- if (retval < (ssize_t)sizeof(size_t) || size == 0 || size > MESSAGE_MAX_LEN)
- {
- /* Error on socket */
- SEC_SVR_ERR("read() failed: %d", retval);
- return SECURITY_SERVER_ERROR_RECV_FAILED;
- }
- buf = (char*)malloc((size + 1) * sizeof(char));
- if (!buf)
- {
- SEC_SVR_ERR("malloc() failed. Size requested: %d", size * sizeof(char));
- return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
- }
-
- retval = TEMP_FAILURE_RETRY(read(sockfd, buf, size));
- if (retval < (ssize_t)size)
- {
- /* Error on socket */
- SEC_SVR_ERR("read() failed: %d", retval);
- free(buf);
- return SECURITY_SERVER_ERROR_RECV_FAILED;
- }
- // terminate string
- buf[size] = '\0';
-
- *path = buf;
- return SECURITY_SERVER_SUCCESS;
-}
-
-static int get_exec_path(pid_t pid, char **exe)
-{
- int sockfd = -1;
- int ret = 0;
- char *path = NULL;
- response_header hdr;
- if (SECURITY_SERVER_SUCCESS != connect_to_server(&sockfd))
- goto out;
-
- ret = send_exec_path_request(sockfd, pid);
- if (ret != SECURITY_SERVER_SUCCESS)
- {
- /* Error on socket */
- SEC_SVR_ERR("Client: Send failed: %d", ret);
- goto out;
- }
-
- ret = recv_exec_path_response(sockfd, &hdr, &path);
- if (ret != SECURITY_SERVER_SUCCESS)
- {
- SEC_SVR_ERR("Client: Recv failed: %d", ret);
- goto out;
- }
-
- ret = return_code_to_error_code(hdr.return_code);
- if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
- SEC_SVR_ERR("Client: Error has been received. return code:%d", hdr.return_code);
- else if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE)
- {
- SEC_SVR_ERR("Client: Wrong response type.");
- ret = SECURITY_SERVER_ERROR_BAD_RESPONSE;
- }
-
-out:
- if (sockfd != -1)
- close(sockfd);
-
- if (ret == SECURITY_SERVER_SUCCESS)
- {
- *exe = path;
- path = NULL;
- }
- free(path);
- return ret;
-}
-
-
// SECURITY_SERVER_API
// int security_server_get_gid(const char *object)
// {
// return retval;
// }
-
-
-
SECURITY_SERVER_API
int security_server_get_object_name(gid_t gid, char *object, size_t max_object_size)
{
}
SECURITY_SERVER_API
-int security_server_check_privilege_by_sockfd(int sockfd,
- const char *object,
- const char *access_rights)
-{
- char *subject;
- int ret;
- char *path = NULL;
-
- //for get socket options
- struct ucred cr;
- unsigned int len = sizeof(cr);
-
- //SMACK runtime check
- if (!smack_runtime_check())
- {
- SEC_SVR_DBG("%s","No SMACK support on device");
- return SECURITY_SERVER_API_SUCCESS;
- }
-
- ret = smack_new_label_from_socket(sockfd, &subject);
- if (ret != 0)
- return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
-
- len = sizeof(cr);
- ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
- if (ret < 0) {
- SEC_SVR_ERR("Error in getsockopt(). Errno: %s", strerror(errno));
- ret = 0;
- goto err;
- }
- ret = get_exec_path(cr.pid, &path);
- if (SECURITY_SERVER_SUCCESS != ret)
- SEC_SVR_ERR("Failed to read executable path for process %d", cr.pid);
-
- ret = security_server_check_privilege_by_pid(cr.pid, object, access_rights);
- if (ret == SECURITY_SERVER_RETURN_CODE_SUCCESS)
- ret = 1;
- else
- ret = 0;
-
-err:
-
- SECURE_SLOGD("security_server_check_privilege_by_pid returned %d", ret);
- if (ret > 0)
- SECURE_SLOGD("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s", cr.pid, subject, object, access_rights, ret, path);
- else
- SECURE_SLOGW("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s", cr.pid, subject, object, access_rights, ret, path);
-
- free(path);
- free(subject);
- if (ret == 1)
- {
- return SECURITY_SERVER_API_SUCCESS;
- }
- else
- {
- return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
- }
-}
-
-
-SECURITY_SERVER_API
int security_server_get_cookie_size(void)
{
return SECURITY_SERVER_COOKIE_LEN;
}
-
SECURITY_SERVER_API
int security_server_get_cookie_pid(const char *cookie)
{
return NULL;
}
-SECURITY_SERVER_API
-char *security_server_get_smacklabel_sockfd(int fd)
-{
- char *label = NULL;
-
- if (!smack_check())
- {
- SEC_SVR_DBG("%s","No SMACK support on device");
- label = (char*) malloc(1);
- if (label) label[0] = '\0';
- return label;
- }
-
- if (smack_new_label_from_socket(fd, &label) != 0)
- {
- SEC_SVR_ERR("Client ERROR: Unable to get socket SMACK label");
- return NULL;
- }
-
- return label;
-}
#ifdef USE_SEC_SRV1_FOR_CHECK_PRIVILEGE_BY_PID
SECURITY_SERVER_API
#define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_REQUEST 0x21
#define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_RESPONSE 0x22
#endif
-#define SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST 0x23
-#define SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE 0x24
#define SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE 0xff
/* Return code */
}
-/* Send exe path response to client
- *
- * Get exe path response packet format
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * |---------------------------------------------------------------|
- * | version=0x01 |MessageID=0x24 |Message Length = 4+path length |
- * |---------------------------------------------------------------|
- * | return code | Path length | Path |
- * |---------------------------------------------------------------|
-
-*/
-int send_exe_path_response(int sockfd, const char *path)
-{
- response_header hdr;
- unsigned char *msg = NULL;
- unsigned char *ptr = NULL;
- int ret;
- size_t path_len = 0;
- unsigned short msg_len = 0;
-
- if (!path) {
- SEC_SVR_ERR("Path is NULL");
- return SECURITY_SERVER_ERROR_INPUT_PARAM;
- }
-
- path_len = strlen(path);
- msg_len = sizeof(hdr) + sizeof(size_t) + path_len;
- msg = (unsigned char*)malloc(msg_len * sizeof(unsigned char));
- if (!msg) {
- SEC_SVR_ERR("malloc failed");
- return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
- }
-
- /* Assemble header */
- hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
- hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE;
- hdr.basic_hdr.msg_len = sizeof(size_t) + path_len;
- hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
-
- /* Prepare packet */
- ptr = msg;
- memcpy(ptr, &hdr, sizeof(hdr));
- ptr += sizeof(hdr);
- memcpy(ptr, &path_len, sizeof(size_t));
- ptr += sizeof(size_t);
- memcpy(ptr, path, path_len);
-
- /* Check poll */
- ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
- if (ret == SECURITY_SERVER_ERROR_POLL)
- {
- SEC_SVR_ERR("%s", "poll() error");
- ret = SECURITY_SERVER_ERROR_SEND_FAILED;
- goto out;
- }
- if (ret == SECURITY_SERVER_ERROR_TIMEOUT)
- {
- SEC_SVR_ERR("%s", "poll() timeout");
- ret = SECURITY_SERVER_ERROR_SEND_FAILED;
- goto out;
- }
-
- /* Send it */
- ret = TEMP_FAILURE_RETRY(write(sockfd, msg, msg_len));
- if (ret < msg_len)
- {
- SEC_SVR_ERR("Error on write(): %d", ret);
- ret = SECURITY_SERVER_ERROR_SEND_FAILED;
- goto out;
- }
- ret = SECURITY_SERVER_SUCCESS;
-
-out:
- free(msg);
- return ret;
-}
-
-
-int process_exe_path_request(int sockfd)
-{
- pid_t pid;
- int retval;
- char *exe = NULL;
-
- // read pid
- retval = TEMP_FAILURE_RETRY(read(sockfd, &pid, sizeof(pid_t)));
- if (retval < (ssize_t) sizeof(pid_t))
- {
- SEC_SVR_ERR("Server Error: recieve failed: %d", retval);
- retval = send_generic_response(
- sockfd,
- SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE,
- SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
-
- if (retval != SECURITY_SERVER_SUCCESS)
- SEC_SVR_ERR("Server ERROR: Cannot send generic response: %d", retval);
- goto error;
- }
-
- SEC_SVR_DBG("Server: Get exe path request for pid %d", pid);
-
- // get executable path
- exe = read_exe_path_from_proc(pid);
- if (!exe)
- {
- SEC_SVR_ERR("Server: Failed to read executable path for pid %d", pid);
- retval = send_generic_response(
- sockfd,
- SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE,
- SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
-
- if (retval != SECURITY_SERVER_SUCCESS)
- SEC_SVR_ERR("Server ERROR: Cannot send generic response: %d", retval);
- goto error;
- }
-
- // send response
- retval = send_exe_path_response(sockfd, exe);
- if (retval != SECURITY_SERVER_SUCCESS)
- SEC_SVR_ERR("ERROR: Cannot send exe path response: %d", retval);
-
-error:
- free(exe);
- return retval;
-}
-
int client_has_access(int sockfd, const char *object)
{
char *label = NULL;
process_set_pwd_validity_request(client_sockfd);
break;
- case SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST:
- SEC_SVR_DBG("Server: get executable path by pid request received");
- process_exe_path_request(client_sockfd);
- break;
-
/************************************************************************************************/
/* Just for test. This code must be removed on release */
case SECURITY_SERVER_MSG_TYPE_GET_ALL_COOKIES_REQUEST:
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file client-socket-privilege.cpp
+ * @author Zofia Abramowska (z.abramowska@samsung.com)
+ * @version 1.0
+ * @brief This file constains implementation of socket privilege api.
+ */
+#include <memory>
+
+#include <sys/socket.h>
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+#include <smack-check.h>
+
+#include <security-server.h>
+#include <security-server-common.h>
+
+static int get_exec_path(pid_t pid, std::string &exe)
+{
+ using namespace SecurityServer;
+
+ try{
+ SocketBuffer send, recv;
+ Serialization ser;
+ ser.Serialize(send, pid);
+
+ int result = sendToServer(
+ SERVICE_SOCKET_EXEC_PATH,
+ send.Pop(),
+ recv);
+ if(result != SECURITY_SERVER_API_SUCCESS)
+ return result;
+
+ Deserialization des;
+ des.Deserialize(recv, result);
+ if(result != SECURITY_SERVER_API_SUCCESS)
+ return result;
+
+ des.Deserialize(recv, exe);
+ return result;
+ } catch (SocketBuffer::Exception::Base &e) {
+ LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+ } catch (std::exception &e) {
+ LogDebug("STD exception " << e.what());
+ } catch (...) {
+ LogDebug("Unknown exception occured");
+ }
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
+SECURITY_SERVER_API
+int security_server_check_privilege_by_sockfd(int sockfd,
+ const char *object,
+ const char *access_rights)
+{
+ char *subject;
+ int ret;
+ std::string path;
+ std::unique_ptr<char> subject_p;
+
+ //for get socket options
+ struct ucred cr;
+ unsigned int len = sizeof(struct ucred);
+
+ //SMACK runtime check
+ if (!smack_runtime_check())
+ {
+ LogDebug("No SMACK support on device");
+ return SECURITY_SERVER_API_SUCCESS;
+ }
+
+ ret = smack_new_label_from_socket(sockfd, &subject);
+ if (ret == 0) {
+ //after allocation we move ownership to smart pointer to let it do the cleanup
+ subject_p.reset(subject);
+
+ } else {
+ ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ goto exit;
+ }
+
+ ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
+ if (ret < 0) {
+ LogError("Error in getsockopt(). Errno: " << strerror(errno));
+ ret = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
+ goto exit;
+ }
+
+ ret = security_server_check_privilege_by_pid(cr.pid, object, access_rights);
+
+ SECURE_LOGD("security_server_check_privilege_by_pid returned %d", ret);
+
+exit:
+ //Getting path for logs
+ if (SECURITY_SERVER_API_SUCCESS != get_exec_path(cr.pid, path))
+ //If this is only for logs, do we want to log it as error?
+ LogError("Failed to read executable path for process " << cr.pid);
+ if (ret == SECURITY_SERVER_API_SUCCESS)
+ SECURE_LOGD("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s",
+ cr.pid, subject_p.get() ? subject_p.get() : "NULL", object, access_rights, ret, path.c_str());
+ else
+ SECURE_LOGW("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s",
+ cr.pid, subject_p.get() ? subject_p.get() : "NULL", object, access_rights, ret, path.c_str());
+
+ return ret;
+}
+
+SECURITY_SERVER_API
+char *security_server_get_smacklabel_sockfd(int fd)
+{
+ char *label = NULL;
+
+ if (!smack_check())
+ {
+ LogDebug("No SMACK support on device");
+ label = (char*) malloc(1);
+ if (label) label[0] = '\0';
+ return label;
+ }
+
+ if (smack_new_label_from_socket(fd, &label) != 0)
+ {
+ LogError("Client ERROR: Unable to get socket SMACK label");
+ return NULL;
+ }
+
+ return label;
+}
"/tmp/.security-server-api-get-gid.sock";
char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID =
"/tmp/.security-server-api-privilege-by-pid";
+char const * const SERVICE_SOCKET_EXEC_PATH =
+ "/tmp/.security-server-api-exec-path.sock";
+
} // namespace SecurityServer
extern char const * const SERVICE_SOCKET_ECHO;
extern char const * const SERVICE_SOCKET_GET_GID;
extern char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID;
+extern char const * const SERVICE_SOCKET_EXEC_PATH;
} // namespace SecuritySever
#include <data-share.h>
#include <get-gid.h>
#include <privilege-by-pid.h>
+#include <exec-path.h>
#include <echo.h>
IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
SecurityServer::PrivilegeByPidService *privByPidService = new SecurityServer::PrivilegeByPidService;
privByPidService->Create();
manager.RegisterSocketService(privByPidService);
+
+ SecurityServer::ExecPathService *execService = new SecurityServer::ExecPathService;
+ execService->Create();
+ manager.RegisterSocketService(execService);
manager.MainLoop();
}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file exec-path.cpp
+ * @author Zofia Abramowska (z.abramowska@samsung.com)
+ * @version 1.0
+ * @brief Implementation of api-exec-path service.
+ */
+
+#include <string>
+
+#include <unistd.h>
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <exec-path.h>
+#include <security-server.h>
+#include <security-server-util.h>
+#include <smack-check.h>
+
+namespace {
+// Service may open more than one socket.
+// These ID's will be assigned to sockets
+// and will be used only by service.
+// When new connection arrives, AcceptEvent
+// will be generated with proper ID to inform
+// service about input socket.
+//
+// Please note: SocketManaged does not use it and
+// does not check it in any way.
+//
+// If your service require only one socket
+// (uses only one socket labeled with smack)
+// you may ignore this ID (just pass 0)
+const int SERVICE_SOCKET_ID = 0;
+
+} // namespace anonymous
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector ExecPathService::GetServiceDescription() {
+ ServiceDescription sd = {
+ "security-server",
+ SERVICE_SOCKET_ID,
+ SERVICE_SOCKET_EXEC_PATH
+ };
+ ServiceDescriptionVector v;
+ v.push_back(sd);
+ return v;
+}
+
+void ExecPathService::accept(const AcceptEvent &event) {
+ LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+ << " ConnectionID.counter: " << event.connectionID.counter
+ << " ServiceID: " << event.interfaceID);
+}
+
+void ExecPathService::write(const WriteEvent &event) {
+ LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+ " Size: " << event.size << " Left: " << event.left);
+ if (event.left == 0)
+ m_serviceManager->Close(event.connectionID);
+}
+
+bool ExecPathService::processOne(const ConnectionID &conn, SocketBuffer &buffer) {
+ LogDebug("Processing message");
+
+ int pid = 0;
+ char *exe;
+
+ if (!buffer.Ready()) {
+ LogDebug("Got part of message. Service is waiting for the rest.");
+ return false;
+ }
+
+ Try {
+ SecurityServer::Deserialization des;
+ des.Deserialize(buffer, pid);
+ } Catch (SocketBuffer::Exception::Base) {
+ LogDebug("Broken protocol. Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
+ SecurityServer::Serialization ser;
+ SocketBuffer sendBuffer;
+ int retVal;
+
+ // get executable path
+ exe = read_exe_path_from_proc(pid);
+ // quickly getting rid of allocated memory
+ // when read_exe_path_from_proc will rewritten this won't be required
+ std::string exec_path(exe ? exe : "");
+ free(exe);
+
+ if (exec_path.empty())
+ {
+ LogError("Server: Failed to read executable path for pid " << pid);
+ retVal = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ ser.Serialize(sendBuffer, retVal);
+ m_serviceManager->Write(conn, sendBuffer.Pop());
+ return true;
+ }
+
+ retVal = SECURITY_SERVER_API_SUCCESS;
+ ser.Serialize(sendBuffer, retVal);
+ ser.Serialize(sendBuffer, exec_path);
+ m_serviceManager->Write(conn, sendBuffer.Pop());
+ return true;
+}
+
+void ExecPathService::read(const ReadEvent &event) {
+ LogDebug("Read event for counter: " << event.connectionID.counter);
+ auto &buffer = m_socketBufferMap[event.connectionID.counter];
+ buffer.Push(event.rawBuffer);
+
+ LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
+ // We can get several requests in one package.
+ // Extract and process them all
+ while(processOne(event.connectionID, buffer));
+}
+
+void ExecPathService::close(const CloseEvent &event) {
+ LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+ m_socketBufferMap.erase(event.connectionID.counter);
+}
+
+void ExecPathService::error(const ErrorEvent &event) {
+ LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+ m_serviceManager->Close(event.connectionID);
+}
+
+} // namespace SecurityServer
+
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file exec-path.h
+ * @author Zofia Abramowska (z.abramowska@samsung.com)
+ * @version 1.0
+ * @brief Implementation of api-exec-path
+ */
+
+#ifndef _SECURITY_SERVER_EXEC_PATH_
+#define _SECURITY_SERVER_EXEC_PATH_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <socket-buffer.h>
+
+namespace SecurityServer {
+
+class ExecPathService
+ : public SecurityServer::GenericSocketService
+ , public SecurityServer::ServiceThread<ExecPathService>
+{
+public:
+ typedef std::map<int, SocketBuffer> SocketBufferMap;
+
+ ServiceDescriptionVector GetServiceDescription();
+
+ DECLARE_THREAD_EVENT(AcceptEvent, accept)
+ DECLARE_THREAD_EVENT(WriteEvent, write)
+ DECLARE_THREAD_EVENT(ReadEvent, read)
+ DECLARE_THREAD_EVENT(CloseEvent, close)
+ DECLARE_THREAD_EVENT(ErrorEvent, error)
+
+ void accept(const AcceptEvent &event);
+ void write(const WriteEvent &event);
+ void read(const ReadEvent &event);
+ void close(const CloseEvent &event);
+ void error(const ErrorEvent &event);
+private:
+ bool processOne(const ConnectionID &conn, SocketBuffer &buffer);
+ SocketBufferMap m_socketBufferMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_EXEC_PATH_
${CMAKE_SOURCE_DIR}/systemd/security-server-data-share.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-get-gid.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-privilege-by-pid.socket
+ ${CMAKE_SOURCE_DIR}/systemd/security-server-exec-path.socket
DESTINATION
/usr/lib/systemd/system
)
--- /dev/null
+[Socket]
+ListenStream=/tmp/.security-server-api-exec-path.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target
Sockets=security-server-data-share.socket
Sockets=security-server-get-gid.socket
Sockets=security-server-privilege-by-pid.socket
+Sockets=security-server-exec-path.socket
[Install]
WantedBy=multi-user.target