From: Igor Kotrasinski Date: Fri, 15 Dec 2017 14:43:55 +0000 (+0100) Subject: Add a simulator control client X-Git-Tag: submit/tizen/20180412.092951~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a22c6b8fc068a7ab53b993b2188b28e6ff06f2b;p=platform%2Fcore%2Fsecurity%2Ftef-simulator.git Add a simulator control client Change-Id: I8ef2c5543f9e5723b614fd0d191b58894c2e4478 Signed-off-by: Igor Kotrasinski --- diff --git a/simulatordaemon/CMakeLists.txt b/simulatordaemon/CMakeLists.txt index f223a11..e842dc2 100644 --- a/simulatordaemon/CMakeLists.txt +++ b/simulatordaemon/CMakeLists.txt @@ -110,7 +110,7 @@ TARGET_LINK_LIBRARIES(${TARGET_TEF_SIMULATOR_DAEMON} ${DAEMON_DEPS_LIBRARIES} ${TARGET_TEF_SIMULATOR_LOG} ${TARGET_TEF_SIMULATOR_OSAL} - boost_system boost_filesystem + boost_system boost_filesystem boost_regex ) INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMON} DESTINATION ${BIN_DIR}) @@ -118,3 +118,5 @@ INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMON} DESTINATION ${BIN_DIR}) INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${TASTORE_DIR}) INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${EXTRACT_DIR}) INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${STORAGE_DIR}) + +ADD_SUBDIRECTORY(daemonctl) diff --git a/simulatordaemon/daemonctl/CMakeLists.txt b/simulatordaemon/daemonctl/CMakeLists.txt new file mode 100644 index 0000000..544f843 --- /dev/null +++ b/simulatordaemon/daemonctl/CMakeLists.txt @@ -0,0 +1,40 @@ +# 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. +# 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 +# @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com) +# @brief CMakeLists for tef-simulator daemon control binary +# + +SET(DAEMONCTL_SOURCES + ${DAEMONCTL_PATH}/src/SimulatorDaemonCtl.cpp + ${DAEMONCTL_PATH}/src/handlers/DebugPortHandler.cpp + ${DAEMON_PATH}/src/UUIDUtils.cpp + ) + +ADD_EXECUTABLE(${TARGET_TEF_SIMULATOR_DAEMONCTL} + ${DAEMONCTL_SOURCES} + ) + +INCLUDE_DIRECTORIES( + ${DAEMON_PATH}/inc + ${DAEMONCTL_PATH}/inc + ${DAEMONCTL_PATH}/inc/handlers + ) + +TARGET_LINK_LIBRARIES(${TARGET_TEF_SIMULATOR_DAEMONCTL} + boost_system boost_program_options boost_regex + ) + +INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMONCTL} DESTINATION ${BIN_DIR}) diff --git a/simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h b/simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h new file mode 100644 index 0000000..eb8253a --- /dev/null +++ b/simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h @@ -0,0 +1,37 @@ +/** + * 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. + * 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 + * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com) + * @brief Common daemonctl code and main method + */ + +#ifndef _SIMULATOR_DAEMON_CTL_H +#define _SIMULATOR_DAEMON_CTL_H + +#include +#include + +#include "ControlCommand.h" + +extern std::map controlErrors; +int communicateWithDaemon(ControlCommand outHeader, + void *outBuf, size_t outBufSize, + ControlCommand inHeader, + void *inBuf, size_t inBufSize); + +#endif /* _SIMULATOR_DAEMON_CTL_H */ diff --git a/simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h b/simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h new file mode 100644 index 0000000..863ab5b --- /dev/null +++ b/simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h @@ -0,0 +1,48 @@ +/** + * 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. + * 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 + * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com) + * @brief Common daemonctl code and main method + */ + +#include +#include +#include +#include "tee_client_api.h" +#include "ControlCommand.h" + +#ifndef _DEBUG_PORT_HANDLER_H +#define _DEBUG_PORT_HANDLER_H + +class DebugPortHandler +{ +public: + DebugPortHandler(); + int handle(int argc, char *argv[]); +private: + boost::program_options::options_description m_desc; + boost::program_options::variables_map m_opts; + void readOptions(int argc, char *argv[]); + void readOptionsPermissively(int argc, char *argv[]); + void parseCommandlineArgs(int argc, char *argv[]); + void checkExactlyOneMainFlag(); + bool handleCommandlineArgs( + int argc, char *argv[], SetPortControlCommand &cmd); +}; + +#endif /* _DEBUG_PORT_HANDLER_H */ diff --git a/simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp b/simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp new file mode 100644 index 0000000..65b8686 --- /dev/null +++ b/simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp @@ -0,0 +1,93 @@ +/** + * 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. + * 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 + * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com) + * @brief Common daemonctl code and main method + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tee_client_api.h" + +#include +#include "ControlCommand.h" +#include "DebugPortHandler.h" +#include "SimulatorDaemonCtl.h" + +#define USAGE_STRING \ + "USAGE: tef-simulator-ctl \n" \ + "Available commands:\n" \ + "\n" \ + "debugport - set a gdb debugging port for a TA UUID\n" + + +std::map controlErrors = { + {CTL_REPLY_SUCCESS, "Success"}, + {CTL_REPLY_TA_NOT_FOUND, "TA not found"}, + {CTL_REPLY_INTERNAL_ERROR, "Internal error"}, +}; + +static void printUsage() { + printf(USAGE_STRING); +} + +int communicateWithDaemon(ControlCommand outHeader, + void *outBuf, size_t outBufSize, + ControlCommand inHeader, + void *inBuf, size_t inBufSize) +{ + boost::asio::io_service io; + boost::asio::local::stream_protocol::socket sock(io); + + try { + sock.connect(SIMDAEMON_CTL_PATH); + boost::asio::write(sock, boost::asio::buffer(&outHeader, + sizeof(outHeader))); + boost::asio::write(sock, boost::asio::buffer(outBuf, outBufSize)); + boost::asio::read(sock, boost::asio::buffer(&inHeader, + sizeof(inHeader))); + boost::asio::read(sock, boost::asio::buffer(inBuf, inBufSize)); + } catch (boost::system::system_error &e) { + std::cerr << "Failed to communicate with simulator daemon:" + << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + printUsage(); + return 1; + } + if (strcmp(argv[1], "debugport") == 0) { + DebugPortHandler handler{}; + handler.handle(argc - 1, argv + 1); + } else { + printUsage(); + return 1; + } +} diff --git a/simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp b/simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp new file mode 100644 index 0000000..2d7bb0f --- /dev/null +++ b/simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp @@ -0,0 +1,154 @@ +/** + * 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. + * 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 + * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com) + * @brief Common daemonctl code and main method + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "UUIDUtils.h" +#include "ControlCommand.h" +#include "SimulatorDaemonCtl.h" +#include "DebugPortHandler.h" + + +DebugPortHandler::DebugPortHandler() + : m_desc("Debugport options") +{ + m_desc.add_options() + ("help,h", "Display this help message") + ("uuid,u", boost::program_options::value(), + "TA UUID to set port for") + ("port,p", boost::program_options::value(), + "Port number"); +} + +void DebugPortHandler::readOptions(int argc, char *argv[]) { + boost::program_options::store( + boost::program_options::parse_command_line( + argc, argv, m_desc), m_opts); + boost::program_options::notify(m_opts); +} + +void DebugPortHandler::readOptionsPermissively(int argc, char *argv[]) +{ + auto parser = boost::program_options::command_line_parser(argc, argv) + .options(m_desc) + .allow_unregistered() + .run(); + boost::program_options::store(parser, m_opts); + boost::program_options::notify(m_opts); +} + +void DebugPortHandler::checkExactlyOneMainFlag() +{ + std::vector mainOptions = { "port" }; + auto optionCount = [this](std::string &s) { return m_opts.count(s) > 0; }; + bool mainOptionCount = std::count_if(mainOptions.begin(), + mainOptions.end(), + optionCount); + if (mainOptionCount != 1) { + std::stringstream errStr; + errStr << "Expected exactly one of:"; + for (std::string option: mainOptions) + errStr << " --" << option; + throw boost::program_options::error(errStr.str()); + } +} + +void DebugPortHandler::parseCommandlineArgs( + int argc, char *argv[]) +{ + /* Avoid complaining about bad parameters if --help was passed */ + readOptionsPermissively(argc, argv); + if (m_opts.count("help")) + return; + checkExactlyOneMainFlag(); + if (!m_opts.count("uuid")) + throw boost::program_options::required_option("uuid"); +} + +bool DebugPortHandler::handleCommandlineArgs( + int argc, char *argv[], SetPortControlCommand &cmd) +{ + int ret; + + parseCommandlineArgs(argc, argv); + if (m_opts.count("help")) { + std::cout << m_desc; + return false; + } + + if (m_opts.count("port")) { + cmd.port = m_opts["port"].as(); + if (cmd.port < 0) + throw boost::program_options::error( + "Port number cannot be negative!"); + } + + TEEC_UUID taUuid; + ret = uuidStringToUuid(m_opts["uuid"].as(), taUuid); + if (ret) + throw boost::program_options::error( + "Invalid UUID format, expected x{8}-x{4}-x{4}-x{4}-x{12}"); + cmd.uuid = taUuid; + return true; +} + +int DebugPortHandler::handle(int argc, char *argv[]) +{ + int ret; + bool shouldCommunicate; + SetPortControlCommand cmd; + SetPortControlCommandReply reply; + + try { + shouldCommunicate = handleCommandlineArgs(argc, argv, cmd); + } catch (boost::program_options::error &e) { + std::cerr << "Commandline parsing error: " << e.what() << std::endl; + std::cerr << m_desc; + return 1; + } + if (!shouldCommunicate) + return 0; + + ret = communicateWithDaemon(CTL_SET_PORT, &cmd, sizeof(cmd), + CTL_SET_PORT_REPLY, &reply, sizeof(reply)); + if (ret) + return ret; + + if (reply.status != CTL_REPLY_SUCCESS) { + std::cerr << "Command failed: " << controlErrors[reply.status] << std::endl; + return 1; + } + + return 0; +} diff --git a/simulatordaemon/inc/UUIDUtils.h b/simulatordaemon/inc/UUIDUtils.h index 9a6083e..f17b923 100644 --- a/simulatordaemon/inc/UUIDUtils.h +++ b/simulatordaemon/inc/UUIDUtils.h @@ -27,6 +27,7 @@ #include "tee_client_api.h" std::string UUIDToString(TEEC_UUID uuid); +int uuidStringToUuid(std::string uuidStr, TEEC_UUID &uuid); class UUIDComparator { public: diff --git a/simulatordaemon/src/UUIDUtils.cpp b/simulatordaemon/src/UUIDUtils.cpp index fd6ef7a..366f9e1 100644 --- a/simulatordaemon/src/UUIDUtils.cpp +++ b/simulatordaemon/src/UUIDUtils.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "tee_client_api.h" @@ -43,3 +45,37 @@ std::string UUIDToString(TEEC_UUID uuid) { } return strStream.str(); } + + +int uuidStringToUuid(std::string uuidStr, TEEC_UUID &uuid) +{ + bool formatIsCorrect; + + /* Format as specified by RFC 4122 */ + auto hexGroup = [](int n) { return "([0-9a-fA-F]{" + std::to_string(n) + "})"; }; + std::vector uuidRegexParts = { + hexGroup(8), + hexGroup(4), + hexGroup(4), + hexGroup(4), + hexGroup(12), + }; + boost::regex uuidRegex { boost::algorithm::join(uuidRegexParts, "-") }; + boost::smatch uuidParts; + + formatIsCorrect = boost::regex_match(uuidStr, uuidParts, uuidRegex); + if (!formatIsCorrect) + return 1; + + auto toHex = [](std::string part) { return std::strtol(part.c_str(), nullptr, 16); }; + uuid.timeLow = toHex(std::string(uuidParts[1])); + uuid.timeMid = toHex(std::string(uuidParts[2])); + uuid.timeHiAndVersion = toHex(std::string(uuidParts[3])); + + std::string seqPart = std::string(uuidParts[4]) + std::string(uuidParts[5]); + for (int i = 0; i < 8 ; i++) { + std::string seqSegment = seqPart.substr(i * 2, 2); + uuid.clockSeqAndNode[i] = toHex(std::string(seqSegment)); + } + return 0; +}