Add handle socket for simulator control 96/174796/3
authorIgor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Thu, 7 Dec 2017 13:13:08 +0000 (14:13 +0100)
committerTomasz Swierczek <t.swierczek@samsung.com>
Thu, 12 Apr 2018 06:56:54 +0000 (06:56 +0000)
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 <i.kotrasinsk@partner.samsung.com>
12 files changed:
CMakeLists.txt
include/include/config.h
packaging/tef-simulator.spec
simulatordaemon/CMakeLists.txt
simulatordaemon/daemonctl/inc/ControlCommand.h
simulatordaemon/inc/ControlConnectionHandler.h
simulatordaemon/inc/SimulatorDaemonServer.h
simulatordaemon/src/ConnectionSession.cpp
simulatordaemon/src/ControlConnectionHandler.cpp
simulatordaemon/src/SimulatorDaemon.cpp
simulatordaemon/src/SimulatorDaemonServer.cpp
systemd/tef-simulator.socket

index 147e771..8e4c4e1 100644 (file)
@@ -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)
index 32c8bf3..4489365 100644 (file)
@@ -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/"
 
index d9cdf79..38e0cee 100644 (file)
@@ -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
index 725c12b..2f5e89f 100644 (file)
@@ -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
index 5b5d32c..0eb416e 100644 (file)
@@ -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;
 };
 
index 474104a..df46ef7 100644 (file)
@@ -40,10 +40,10 @@ public:
        void handleReadError(boost::system::error_code e) override;
 private:
        TABinaryManager *getBinaryManager();
-       IConnectionWriter<enum ControlCommand> *m_writer;
        void handleSetPortCommand(std::vector<char> &data);
        void handleInvalidCommand();
        void handleConnectionClosed();
+       IConnectionWriter<enum ControlCommand> *m_writer= nullptr;
 };
 
 #endif /* _CONTROLCONNECTIONHANDLER_H */
index d5ebf2e..b3cee79 100644 (file)
 /*-----------------------------------------------------------------------------
  *  Include files
  *-----------------------------------------------------------------------------*/
+#include <cstdint>
+#include <boost/asio.hpp>
 #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<stream_protocol::acceptor> 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<int8_t>::session_ptr session,
+       void startTEEAccept();
+       void startCtlAccept();
+       void handleTEEAccept(ConnectionSession<int8_t>::session_ptr session,
                const boost::system::error_code& error);
+       void handleCtlAccept(ConnectionSession<enum ControlCommand>::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
index 941f92b..a94572a 100644 (file)
@@ -28,6 +28,7 @@
 #include <cstdint>
 #include <boost/asio.hpp>
 #include "ConnectionSession.h"
+#include "ControlCommand.h"
 
 /*-----------------------------------------------------------------------------
  *  Member functions
@@ -170,3 +171,4 @@ ConnectionSession<header_t>::~ConnectionSession() {
  *  Template instantiation for external files
  *-----------------------------------------------------------------------------*/
 template class ConnectionSession<int8_t>;
+template class ConnectionSession<ControlCommand>;
index 7daa776..20ec75f 100644 (file)
@@ -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<char> &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<char> &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()
index a8bd820..d662262 100644 (file)
@@ -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 <memory>
 #include "SimulatorDaemonServer.h"
 #include <systemd/sd-daemon.h>
 #include <config.h>
@@ -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());
index cf6d4ad..0cb6c13 100644 (file)
  *  Include files
  *-----------------------------------------------------------------------------*/
 #include <cstdint>
+#include <memory>
 #include <boost/shared_ptr.hpp>
 #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<TEEConnectionHandler> teeHandler(new TEEConnectionHandler());
-       ConnectionSession<int8_t>::session_ptr newSession = ConnectionSession<int8_t>::create(
-                       acceptor.get_io_service(), teeHandler);
+       boost::shared_ptr<TEEConnectionHandler> teeHandler(
+                       new TEEConnectionHandler());
+       ConnectionSession<int8_t>::session_ptr newSession =
+               ConnectionSession<int8_t>::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<ControlConnectionHandler> ctlHandler(
+                       new ControlConnectionHandler());
+       ConnectionSession<enum ControlCommand>::session_ptr newSession =
+               ConnectionSession<enum ControlCommand>::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<int8_t>::session_ptr session,
        const boost::system::error_code& error)
 {
        if (!error) {
                session->start();
        }
-       startAccept();
+       startTEEAccept();
+}
+
+void SimulatorDaemonServer::handleCtlAccept(
+       ConnectionSession<enum ControlCommand>::session_ptr session,
+       const boost::system::error_code& error)
+{
+       if (!error) {
+               session->start();
+       }
+       startCtlAccept();
 }
index 7995aaa..bf0d590 100644 (file)
@@ -4,5 +4,11 @@ SocketMode=0777
 SmackLabelIPIn=*
 SmackLabelIPOut=@
 
+[Socket]
+ListenStream=/var/run/simdaemonctl
+SocketMode=0770
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
 [Install]
 WantedBy=sockets.target