-# 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.
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)
/**
- * 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.
//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/"
%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
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
enum ControlCommand : uint32_t {
CTL_SET_PORT,
-};
-
-enum ControlCommandReply : uint32_t {
CTL_SET_PORT_REPLY,
CTL_INVALID_CMD_REPLY,
};
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;
};
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 */
/*-----------------------------------------------------------------------------
* 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
#include <cstdint>
#include <boost/asio.hpp>
#include "ConnectionSession.h"
+#include "ControlCommand.h"
/*-----------------------------------------------------------------------------
* Member functions
* Template instantiation for external files
*-----------------------------------------------------------------------------*/
template class ConnectionSession<int8_t>;
+template class ConnectionSession<ControlCommand>;
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:
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",
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()
/**
- * 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.
/*-----------------------------------------------------------------------------
* Include files
*-----------------------------------------------------------------------------*/
+#include <memory>
#include "SimulatorDaemonServer.h"
#include <systemd/sd-daemon.h>
#include <config.h>
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
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());
* 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();
}
SmackLabelIPIn=*
SmackLabelIPOut=@
+[Socket]
+ListenStream=/var/run/simdaemonctl
+SocketMode=0770
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
[Install]
WantedBy=sockets.target