From c029d171a8d62c47ebab62d2f60ed9d6883b63f3 Mon Sep 17 00:00:00 2001 From: Igor Kotrasinski Date: Thu, 7 Dec 2017 14:13:08 +0100 Subject: [PATCH] Add handle socket for simulator control The control daemon will be used to change some simulator behaviours with regard to e.g. launching TAs; for now it will be used to toggle TA remote debugging and their remote debugging ports. Change-Id: I5c82c6082d07ffd378914db42d3c9d0383f1b5a3 Signed-off-by: Igor Kotrasinski --- CMakeLists.txt | 3 +- include/include/config.h | 4 +- packaging/tef-simulator.spec | 1 + simulatordaemon/CMakeLists.txt | 3 + .../daemonctl/inc/ControlCommand.h | 9 ++- .../inc/ControlConnectionHandler.h | 2 +- simulatordaemon/inc/SimulatorDaemonServer.h | 26 ++++--- simulatordaemon/src/ConnectionSession.cpp | 2 + .../src/ControlConnectionHandler.cpp | 18 +++-- simulatordaemon/src/SimulatorDaemon.cpp | 61 ++++++++++------- simulatordaemon/src/SimulatorDaemonServer.cpp | 67 ++++++++++++------- systemd/tef-simulator.socket | 6 ++ 12 files changed, 131 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 147e771..8e4c4e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -74,6 +74,7 @@ SET(TARGET_TEF_SIMULATOR tef-simulator) SET(TARGET_TEF_SIMULATOR_LOG ${TARGET_TEF_SIMULATOR}-log) SET(TARGET_TEF_SIMULATOR_OSAL ${TARGET_TEF_SIMULATOR}-osal) SET(TARGET_TEF_SIMULATOR_DAEMON ${TARGET_TEF_SIMULATOR}-daemon) +SET(TARGET_TEF_SIMULATOR_DAEMONCTL ${TARGET_TEF_SIMULATOR}-daemonctl) SET(TARGET_TEF_SIMULATOR_SSFLIB ${TARGET_TEF_SIMULATOR}-ssflib) # below targets need different names due to linking with CAs and TAs (libteec for client) diff --git a/include/include/config.h b/include/include/config.h index 32c8bf3..4489365 100644 --- a/include/include/config.h +++ b/include/include/config.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ //keep in sync with systemd/tef-simulator.socket #define SIMDAEMON_SOCK_PATH "/var/run/simdaemon" - +#define SIMDAEMON_CTL_PATH "/var/run/simdaemonctl" //TEEStub must have write access in this directory (creating socket per TA) #define TEE_TASOCK_ROOT "/var/run/" diff --git a/packaging/tef-simulator.spec b/packaging/tef-simulator.spec index d9cdf79..38e0cee 100644 --- a/packaging/tef-simulator.spec +++ b/packaging/tef-simulator.spec @@ -143,6 +143,7 @@ fi %license LICENSE.Krb5-MIT %manifest tef-simulator.manifest %attr(111,security_fw,security_fw) %{bin_dir}/tef-simulator-daemon +%attr(111,security_fw,security_fw) %{bin_dir}/tef-simulator-daemonctl %{lib_dir}/libtef-simulator-ssflib.so %attr(770,root,security_fw) %{tastore_dir} %attr(444,security_fw,security_fw) %{_unitdir}/tef-simulator.service diff --git a/simulatordaemon/CMakeLists.txt b/simulatordaemon/CMakeLists.txt index 725c12b..2f5e89f 100644 --- a/simulatordaemon/CMakeLists.txt +++ b/simulatordaemon/CMakeLists.txt @@ -36,8 +36,11 @@ PKG_CHECK_MODULES(DAEMON_LIBTEEC_DEP REQUIRED FIND_PACKAGE(Threads REQUIRED) +SET(DAEMONCTL_PATH ${DAEMON_PATH}/daemonctl) + SET(DAEMON_SOURCES ${DAEMON_PATH}/src/ConnectionSession.cpp + ${DAEMON_PATH}/src/ControlConnectionHandler.cpp ${DAEMON_PATH}/src/ioService.cpp ${DAEMON_PATH}/src/SecurityContext.cpp ${DAEMON_PATH}/src/Session.cpp diff --git a/simulatordaemon/daemonctl/inc/ControlCommand.h b/simulatordaemon/daemonctl/inc/ControlCommand.h index 5b5d32c..0eb416e 100644 --- a/simulatordaemon/daemonctl/inc/ControlCommand.h +++ b/simulatordaemon/daemonctl/inc/ControlCommand.h @@ -28,9 +28,6 @@ enum ControlCommand : uint32_t { CTL_SET_PORT, -}; - -enum ControlCommandReply : uint32_t { CTL_SET_PORT_REPLY, CTL_INVALID_CMD_REPLY, }; @@ -38,14 +35,16 @@ enum ControlCommandReply : uint32_t { enum ControlReplyStatus : uint32_t { CTL_REPLY_SUCCESS, CTL_REPLY_TA_NOT_FOUND, + CTL_REPLY_INTERNAL_ERROR, }; -struct SetPortControlCommand { + +struct __attribute__((packed)) SetPortControlCommand { TEEC_UUID uuid; uint32_t port; }; -struct SetPortControlCommandReply { +struct __attribute__((packed)) SetPortControlCommandReply { enum ControlReplyStatus status; }; diff --git a/simulatordaemon/inc/ControlConnectionHandler.h b/simulatordaemon/inc/ControlConnectionHandler.h index 474104a..df46ef7 100644 --- a/simulatordaemon/inc/ControlConnectionHandler.h +++ b/simulatordaemon/inc/ControlConnectionHandler.h @@ -40,10 +40,10 @@ public: void handleReadError(boost::system::error_code e) override; private: TABinaryManager *getBinaryManager(); - IConnectionWriter *m_writer; void handleSetPortCommand(std::vector &data); void handleInvalidCommand(); void handleConnectionClosed(); + IConnectionWriter *m_writer= nullptr; }; #endif /* _CONTROLCONNECTIONHANDLER_H */ diff --git a/simulatordaemon/inc/SimulatorDaemonServer.h b/simulatordaemon/inc/SimulatorDaemonServer.h index d5ebf2e..b3cee79 100644 --- a/simulatordaemon/inc/SimulatorDaemonServer.h +++ b/simulatordaemon/inc/SimulatorDaemonServer.h @@ -27,25 +27,35 @@ /*----------------------------------------------------------------------------- * Include files *-----------------------------------------------------------------------------*/ +#include +#include #include "ConnectionSession.h" +#include "ControlCommand.h" + +using boost::asio::local::stream_protocol; /*----------------------------------------------------------------------------- * Class definitions *-----------------------------------------------------------------------------*/ class SimulatorDaemonServer { public: - // create a server and a socket - SimulatorDaemonServer(boost::asio::io_service& io_service, const std::string& file); - - // create a server based on an existing socket fd - SimulatorDaemonServer(boost::asio::io_service& io_service, int sockfd); + typedef std::unique_ptr acceptor_ptr; + SimulatorDaemonServer(boost::asio::io_service& io_service, + acceptor_ptr tee_acceptor, + acceptor_ptr ctl_acceptor); + ~SimulatorDaemonServer() = default; private: - void startAccept(); - void handleAccept(ConnectionSession::session_ptr session, + void startTEEAccept(); + void startCtlAccept(); + void handleTEEAccept(ConnectionSession::session_ptr session, const boost::system::error_code& error); + void handleCtlAccept(ConnectionSession::session_ptr session, + const boost::system::error_code& error); + boost::asio::io_service& mem_io_service; - stream_protocol::acceptor acceptor; + acceptor_ptr m_tee_acceptor; + acceptor_ptr m_ctl_acceptor; }; #endif //_SIMULATORDAEMONSERVER_H diff --git a/simulatordaemon/src/ConnectionSession.cpp b/simulatordaemon/src/ConnectionSession.cpp index 941f92b..a94572a 100644 --- a/simulatordaemon/src/ConnectionSession.cpp +++ b/simulatordaemon/src/ConnectionSession.cpp @@ -28,6 +28,7 @@ #include #include #include "ConnectionSession.h" +#include "ControlCommand.h" /*----------------------------------------------------------------------------- * Member functions @@ -170,3 +171,4 @@ ConnectionSession::~ConnectionSession() { * Template instantiation for external files *-----------------------------------------------------------------------------*/ template class ConnectionSession; +template class ConnectionSession; diff --git a/simulatordaemon/src/ControlConnectionHandler.cpp b/simulatordaemon/src/ControlConnectionHandler.cpp index 7daa776..20ec75f 100644 --- a/simulatordaemon/src/ControlConnectionHandler.cpp +++ b/simulatordaemon/src/ControlConnectionHandler.cpp @@ -39,7 +39,7 @@ void ControlConnectionHandler::handleConnect(int sock) int32_t ControlConnectionHandler::getDataSize(enum ControlCommand cmd) { LOGD(SIM_DAEMON, "Control command received: %d", (uint32_t)cmd); - switch(cmdData) { + switch(cmd) { case CTL_SET_PORT: return sizeof(SetPortControlCommand); default: @@ -81,12 +81,18 @@ void ControlConnectionHandler::handleSetPortCommand(std::vector &data) TABinaryManager *binaryManager; int ret; - std::memcpy(&cmd, data.data(), sizeof(cmd)); - std::string portString = std::to_string(cmd.port); binaryManager = getBinaryManager(); - std::string uuidString = binaryManager.getUUIDAsString(data.uuid); + if (binaryManager == nullptr) { + reply.status = CTL_REPLY_INTERNAL_ERROR; + LOGE(SIM_DAEMON, "Setting UUID debug port failed - binary manager not found"); + m_writer->write(CTL_SET_PORT_REPLY, (char *) &reply, sizeof(reply)); + return; + } - ret = binaryManager.setPort(uuidString, portString); + std::memcpy(&cmd, data.data(), sizeof(cmd)); + std::string portString = std::to_string(cmd.port); + std::string uuidString = binaryManager->getUUIDAsString(cmd.uuid); + ret = binaryManager->setPort(uuidString, portString); if (!ret) { reply.status = CTL_REPLY_SUCCESS; LOGI(SIM_DAEMON, "Set debug port of UUID %s to %s", @@ -96,7 +102,7 @@ void ControlConnectionHandler::handleSetPortCommand(std::vector &data) LOGE(SIM_DAEMON, "Failed to set debug port of UUID %s to %s - TA not found", uuidString.c_str(), portString.c_str()); } - m_writer->write(CTL_SET_PORT_REPLY, (char *) reply, sizeof(reply)); + m_writer->write(CTL_SET_PORT_REPLY, (char *) &reply, sizeof(reply)); } void ControlConnectionHandler::handleInvalidCommand() diff --git a/simulatordaemon/src/SimulatorDaemon.cpp b/simulatordaemon/src/SimulatorDaemon.cpp index a8bd820..d662262 100644 --- a/simulatordaemon/src/SimulatorDaemon.cpp +++ b/simulatordaemon/src/SimulatorDaemon.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ /*----------------------------------------------------------------------------- * Include files *-----------------------------------------------------------------------------*/ +#include #include "SimulatorDaemonServer.h" #include #include @@ -70,22 +71,39 @@ int getSystemdSocket(const std::string& path) { return 0; } - if (n > 1) { - LOGI(SIM_DAEMON, "Received %d sockets. Only first one will be used.", n); - } - - int fd = SD_LISTEN_FDS_START; - int ret = sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0); - if (ret > 0) { - LOGI(SIM_DAEMON, "Acquired systemd socket %d", fd); - sd_notify(0, "READY=1"); - return fd; + for (int i = 0; i < n; i++) { + int fd = SD_LISTEN_FDS_START + i; + int ret = sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0); + if (ret > 0) { + LOGI(SIM_DAEMON, "Acquired systemd socket %d", fd); + return fd; + } } - LOGE(SIM_DAEMON, "Found systemd socket is not an UNIX socket."); + LOGE(SIM_DAEMON, "No found systemd socket is a matching UNIX socket."); return 0; } +SimulatorDaemonServer::acceptor_ptr getSocketAcceptor( + boost::asio::io_service &io, const std::string &path) { + SimulatorDaemonServer::acceptor_ptr acceptor; + int sockfd = getSystemdSocket(path); + if (sockfd > 0) { + LOGI(SIM_DAEMON, "Using existing systemd socket %d", sockfd); + acceptor = SimulatorDaemonServer::acceptor_ptr( + new stream_protocol::acceptor(io)); + acceptor->assign(stream_protocol(), sockfd); + } else { + LOGI(SIM_DAEMON, "No systemd socket available for %s - creating own one", + path.c_str()); + + acceptor = SimulatorDaemonServer::acceptor_ptr( + new stream_protocol::acceptor( + io, stream_protocol::endpoint(path))); + } + return acceptor; +} + /** * main function for Simulator Daemon * @return @@ -94,18 +112,13 @@ int main() { LOGD(SIM_DAEMON, "Entry"); uint32_t result = 0; try { - int sockFD = getSystemdSocket(SIMDAEMON_SOCK_PATH); - - if (sockFD > 0) { - LOGI(SIM_DAEMON, "Using existing systemd socket %d", sockFD); - SimulatorDaemonServer s(ioService::getInstance(), sockFD); - startServer(ioService::getInstance()); - } else { - LOGI(SIM_DAEMON, "No systemd socket available - creating own one"); - SimulatorDaemonServer s(ioService::getInstance(), SIMDAEMON_SOCK_PATH); - startServer(ioService::getInstance()); - } - + SimulatorDaemonServer::acceptor_ptr tee_acceptor, ctl_acceptor; + boost::asio::io_service &io = ioService::getInstance(); + tee_acceptor = getSocketAcceptor(io, SIMDAEMON_SOCK_PATH); + ctl_acceptor = getSocketAcceptor(io, SIMDAEMON_CTL_PATH); + sd_notify(0, "READY=1"); + SimulatorDaemonServer s(io, std::move(tee_acceptor), std::move(ctl_acceptor)); + startServer(io); syslog(LOG_INFO | LOG_USER, "Daemon stopped"); } catch (std::exception& e) { syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what()); diff --git a/simulatordaemon/src/SimulatorDaemonServer.cpp b/simulatordaemon/src/SimulatorDaemonServer.cpp index cf6d4ad..0cb6c13 100644 --- a/simulatordaemon/src/SimulatorDaemonServer.cpp +++ b/simulatordaemon/src/SimulatorDaemonServer.cpp @@ -25,62 +25,81 @@ * Include files *-----------------------------------------------------------------------------*/ #include +#include #include #include "SimulatorDaemonServer.h" #include "SecurityContext.h" #include "TEEConnectionHandler.h" #include "ConnectionSession.h" +#include "ControlCommand.h" +#include "ControlConnectionHandler.h" /*----------------------------------------------------------------------------- * Member functions *-----------------------------------------------------------------------------*/ -/** - * Accepts a new connection from local machine on a UDS - * @param io_service provides OS abstraction for async communication - * @param file path to Unix Domain Socket represented by a local file - */ -SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, const std::string& file) - : mem_io_service(io_service) - , acceptor(io_service, stream_protocol::endpoint(file)) -{ - startAccept(); -} /** - * Creates a server based on already opened socket FD + * Creates a server based on provided acceptors * @param io_service provides OS abstraction for async communication * @param sock opened socket file descriptor (ex. provided by systemd) */ -SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, int sockfd) +SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, + acceptor_ptr tee_acceptor, + acceptor_ptr ctl_acceptor) : mem_io_service(io_service) - , acceptor(io_service) + , m_tee_acceptor(std::move(tee_acceptor)) + , m_ctl_acceptor(std::move(ctl_acceptor)) { - acceptor.assign(stream_protocol(), sockfd); - startAccept(); + startTEEAccept(); + startCtlAccept(); } -void SimulatorDaemonServer::startAccept() +void SimulatorDaemonServer::startTEEAccept() { - boost::shared_ptr teeHandler(new TEEConnectionHandler()); - ConnectionSession::session_ptr newSession = ConnectionSession::create( - acceptor.get_io_service(), teeHandler); + boost::shared_ptr teeHandler( + new TEEConnectionHandler()); + ConnectionSession::session_ptr newSession = + ConnectionSession::create( + m_tee_acceptor->get_io_service(), teeHandler); - acceptor.async_accept(newSession->socket(), - boost::bind(&SimulatorDaemonServer::handleAccept, this, newSession, + m_tee_acceptor->async_accept(newSession->socket(), + boost::bind(&SimulatorDaemonServer::handleTEEAccept, this, newSession, boost::asio::placeholders::error)); } +void SimulatorDaemonServer::startCtlAccept() +{ + boost::shared_ptr ctlHandler( + new ControlConnectionHandler()); + ConnectionSession::session_ptr newSession = + ConnectionSession::create( + m_ctl_acceptor->get_io_service(), ctlHandler); + + m_ctl_acceptor->async_accept(newSession->socket(), + boost::bind(&SimulatorDaemonServer::handleCtlAccept, this, newSession, + boost::asio::placeholders::error)); +} /** * Call back for boost acceptor.async_accept() to handle a new connection * @param new_session a pointer to a session * @param error error code if any occurred */ -void SimulatorDaemonServer::handleAccept( +void SimulatorDaemonServer::handleTEEAccept( ConnectionSession::session_ptr session, const boost::system::error_code& error) { if (!error) { session->start(); } - startAccept(); + startTEEAccept(); +} + +void SimulatorDaemonServer::handleCtlAccept( + ConnectionSession::session_ptr session, + const boost::system::error_code& error) +{ + if (!error) { + session->start(); + } + startCtlAccept(); } diff --git a/systemd/tef-simulator.socket b/systemd/tef-simulator.socket index 7995aaa..bf0d590 100644 --- a/systemd/tef-simulator.socket +++ b/systemd/tef-simulator.socket @@ -4,5 +4,11 @@ SocketMode=0777 SmackLabelIPIn=* SmackLabelIPOut=@ +[Socket] +ListenStream=/var/run/simdaemonctl +SocketMode=0770 +SmackLabelIPIn=* +SmackLabelIPOut=@ + [Install] WantedBy=sockets.target -- 2.34.1