ADD_SUBDIRECTORY(pkgconfig)
ADD_SUBDIRECTORY(simulatordaemon)
ADD_SUBDIRECTORY(ssflib)
+ADD_SUBDIRECTORY(systemd)
ADD_SUBDIRECTORY(TEECLib)
ADD_SUBDIRECTORY(TEEStub)
BuildRequires: pkgconfig(cynara-creds-socket)
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(security-manager)
+BuildRequires: pkgconfig(libsystemd-daemon)
+
+%{?systemd_requires}
%define bin_dir %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:%_bindir}
%define sbin_dir %{?TZ_SYS_SBIN:%TZ_SYS_SBIN}%{!?TZ_SYS_SBIN:%_sbindir}
%define build_data_dir %{buildroot}%{data_dir}
%define build_include_dir %{buildroot}%{include_dir}
%define build_tastore_dir %{buildroot}%{tastore_dir}
+%define build_unit_dir %{buildroot}%{_unitdir}
+
+%define smack_domain_name System
%description
TEF Simulator provides a TrustZone simulated environment
-DDATA_DIR=%{build_data_dir} \
-DINCLUDE_DIR=%{build_include_dir} \
-DTASTORE_DIR=%{build_tastore_dir} \
+ -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \
+ -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \
-DPKGCFG_LIB_DIR=%{lib_dir} \
-DPKGCFG_PREFIX=/usr \
- -DPKGCFG_VERSION=%{version}
+ -DPKGCFG_VERSION=%{version} \
+ -DSMACK_DOMAIN_NAME=%{smack_domain_name}
make %{?jobs:-j%jobs}
%install
%{bin_dir}/tef-simulator-daemon
%{lib_dir}/libtef-simulator-ssflib.so
%{sbin_dir}/tef-simulator-update-uuid-list.sh
+%{_unitdir}/tef-simulator.service
+%{_unitdir}/tef-simulator.socket
+%{_unitdir}/tef-simulator.target
%files -n %{name}-client
%{lib_dir}/libteec.so
cynara-client
cynara-creds-socket
security-manager
+ libsystemd-daemon
)
FIND_PACKAGE(Threads REQUIRED)
*-----------------------------------------------------------------------------*/
class SimulatorDaemonServer {
public:
- SimulatorDaemonServer(boost::asio::io_service& io_service,
- const std::string& file);
+ // 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);
+
private:
- void startAccept(void);
- void handleAccept(ConnectionSession::session_ptr new_session,
- const boost::system::error_code& error);
+ void startAccept();
+ void handleAccept(ConnectionSession::session_ptr session,
+ const boost::system::error_code& error);
boost::asio::io_service& mem_io_service;
stream_protocol::acceptor acceptor;
};
#include "path.h"
#include "SimulatorDaemonServer.h"
+#include <systemd/sd-daemon.h>
+
/*-----------------------------------------------------------------------------
* Local functions
*-----------------------------------------------------------------------------*/
io_service.stop();
}
+/**
+ * Acquire systemd emulator socket
+ */
+int getSystemdSocket(const std::string& path) {
+ int n = sd_listen_fds(0);
+
+ if (n < 0) {
+ LOGE(SIM_DAEMON, "Error while getting sockets from systemd: %d", n);
+ return n;
+ }
+
+ if (n == 0) {
+ LOGE(SIM_DAEMON, "No usable systemd socket found");
+ 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;
+ }
+
+ LOGE(SIM_DAEMON, "Found systemd socket is not an UNIX socket.");
+ return 0;
+}
+
/**
* main function for Simulator Daemon
* @return
LOGD(SIM_DAEMON, "Entry");
uint32_t result = 0;
try {
- ::unlink(SIMDAEMON_PATH);
+ int sockFD = getSystemdSocket(SIMDAEMON_PATH);
+
//initializeShm();
- SimulatorDaemonServer s(ioService::getInstance(), SIMDAEMON_PATH);
- // Once the server is started, it exits only after the
- // connection is lost or gracefully disconnected.
- startServer(ioService::getInstance());
+ 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_PATH);
+ startServer(ioService::getInstance());
+ }
+
syslog(LOG_INFO | LOG_USER, "Daemon stopped");
} catch (std::exception& e) {
syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what());
* @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)) {
+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();
}
/**
- * Method to start accepting a new connection
- * @param none
+ * Creates a server based on already opened socket FD
+ * @param io_service provides OS abstraction for async communication
+ * @param sock opened socket file descriptor (ex. provided by systemd)
*/
-void SimulatorDaemonServer::startAccept() {
- LOGD(SIM_DAEMON, "Entry");
- ConnectionSession::session_ptr new_session = ConnectionSession::create(
- acceptor.get_io_service());
+SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, int sockfd)
+ : mem_io_service(io_service)
+ , acceptor(io_service)
+{
+ acceptor.assign(stream_protocol(), sockfd);
+ startAccept();
+}
+
+void SimulatorDaemonServer::startAccept()
+{
+ ConnectionSession::session_ptr newSession = ConnectionSession::create(acceptor.get_io_service());
- acceptor.async_accept(new_session->socket(),
- boost::bind(&SimulatorDaemonServer::handleAccept, this, new_session,
- boost::asio::placeholders::error));
+ acceptor.async_accept(newSession->socket(),
+ boost::bind(&SimulatorDaemonServer::handleAccept, this, newSession,
+ boost::asio::placeholders::error));
}
/**
* @param error error code if any occurred
*/
void SimulatorDaemonServer::handleAccept(
- ConnectionSession::session_ptr new_session,
- const boost::system::error_code& error) {
-
+ ConnectionSession::session_ptr session,
+ const boost::system::error_code& error)
+{
const string privelege("http://tizen.org/privilege/account.read");
LOGD(SIM_DAEMON, "Entry");
// TODO reenable after refactor
}*/
if (!error) {
- new_session->start();
+ session->start();
}
startAccept();
}
--- /dev/null
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service.in
+ ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service @ONLY)
+
+INSTALL(FILES
+ ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service
+ ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.target
+ ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.socket
+ DESTINATION
+ ${SYSTEMD_UNIT_DIR}
+)
+
--- /dev/null
+[Unit]
+Description=TEF Simulator Daemon
+DefaultDependencies=no
+
+[Service]
+User=root
+Group=root
+SmackProcessLabel=@SMACK_DOMAIN_NAME@
+ExecStart=@SYSTEMD_CFG_BIN_DIR@/tef-simulator-daemon
+Sockets=tef-simulator.socket
+RuntimeDirectory=@SERVICE_NAME@
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+[Socket]
+ListenStream=/tmp/simdaemon
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=tef-simulator.service
+
+[Unit]
+Wants=tef-simulator.target
+Before=tef-simulator.target
+
+[Install]
+WantedBy=sockets.target
--- /dev/null
+[Unit]
+Description=TEF Simulator socket
+DefaultDependencies=true
+