From: Krzysztof Jackiewicz Date: Wed, 15 Nov 2017 09:08:59 +0000 (+0100) Subject: Add executable for mounting internal memory during FOTA X-Git-Tag: submit/tizen/20171201.152910~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a12554c44dc48654ec4c00db901060202060c45a;p=platform%2Fcore%2Fsecurity%2Fode.git Add executable for mounting internal memory during FOTA Change-Id: Idb5f1ed392d3cb0a110242de76acb44f8db8e07a --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e6a5f1..2a6e621 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ SET(ODE_SERVER ${PROJECT_SOURCE_DIR}/server) SET(ODE_TOOLS ${PROJECT_SOURCE_DIR}/tools) SET(ODE_TESTS ${PROJECT_SOURCE_DIR}/tests) SET(ODE_DUMMY_KSP ${PROJECT_SOURCE_DIR}/dummy-ksp) +SET(ODE_FOTA ${PROJECT_SOURCE_DIR}/fota) IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) SET(CXX_STD "c++0x") @@ -71,6 +72,10 @@ IF(NOT DEFINED BIN_DIR) SET(BIN_DIR "${CMAKE_INSTALL_BINDIR}") ENDIF(NOT DEFINED BIN_DIR) +IF(NOT DEFINED SBIN_DIR) + SET(SBIN_DIR "${CMAKE_INSTALL_SBINDIR}") +ENDIF(NOT DEFINED SBIN_DIR) + IF(NOT DEFINED HOME_DIR) SET(HOME_DIR "/home") ENDIF(NOT DEFINED HOME_DIR) @@ -104,3 +109,4 @@ ADD_SUBDIRECTORY(${ODE_SERVER}) ADD_SUBDIRECTORY(${ODE_TOOLS}) ADD_SUBDIRECTORY(${ODE_TESTS}) ADD_SUBDIRECTORY(${ODE_DUMMY_KSP}) +ADD_SUBDIRECTORY(${ODE_FOTA}) diff --git a/fota/CMakeLists.txt b/fota/CMakeLists.txt new file mode 100755 index 0000000..f839bf2 --- /dev/null +++ b/fota/CMakeLists.txt @@ -0,0 +1,41 @@ +# +# Copyright (c) 2017 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. +# + +SET(PROJECT_NAME "ode-fota") + +PKG_CHECK_MODULES(FOTA_DEPS REQUIRED klay) + +SET(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/fota.cpp + ${ODE_SERVER}/upgrade-support.cpp + ${ODE_SERVER}/ext4-tool.cpp + ${ODE_SERVER}/misc.cpp + ${ODE_SERVER}/engine/encryption/dmcrypt-engine.cpp + ${ODE_SERVER}/internal-encryption-common.cpp +) + +SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES}) + +TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${ODE_SERVER}) +TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} SYSTEM PRIVATE ${FOTA_DEPS_INCLUDE_DIRS}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${FOTA_DEPS_LIBRARIES} dl) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-fPIE") +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-pie") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${SBIN_DIR}) \ No newline at end of file diff --git a/fota/fota.cpp b/fota/fota.cpp new file mode 100644 index 0000000..c747af7 --- /dev/null +++ b/fota/fota.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 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 + */ + +#include + +#include +#include + +#include + +#include +#include +#include + +audit::LogSink *SINK = nullptr; + +namespace ode { + +// dummy implementation +ProgressBar::ProgressBar(UpdateFunc const&) : updateValue(0) {} +ProgressBar::~ProgressBar() {} + +void ProgressBar::update(int) {} +void ProgressBar::update(int, int, int) {} +void ProgressBar::done(void) {} + +} // namespace ode + +namespace { + +const std::string MOUNT = "mount"; +const std::string REMOVE = "remove"; + +const std::string DEV_PATH = ode::findDevPath(); + +void usage() +{ + std::cout << + "Usage: ode-fota [Operation]" << std::endl << + std::endl << + "Operations :" << std::endl << + " mount Mount internal memory using stored master key" << std::endl << + " remove Remove stored internal memory master key" << std::endl; +} + +} // anonymous namespace + +int main(int argc, char* argv[]) +{ + try { + using namespace ode; + + if (argc < 2) { + usage(); + return EXIT_FAILURE; + } + + if (MOUNT == argv[1]) { + auto masterKey = UpgradeSupport::loadMasterKey(DEV_PATH); + + DMCryptEngine dmcrypt(DEV_PATH, INTERNAL_PATH, ProgressBar([](int){})); + + // mount options are ignored by mount() + dmcrypt.mount(masterKey, 0); + } else if (REMOVE == argv[1]) { + UpgradeSupport::removeMasterKey(DEV_PATH); + } else { + usage(); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + } catch (...) { + std::cerr << "Unknown exception occured" << std::endl; + } + + return EXIT_FAILURE; +} diff --git a/packaging/ode.spec b/packaging/ode.spec index bbd5c30..1220838 100755 --- a/packaging/ode.spec +++ b/packaging/ode.spec @@ -33,7 +33,8 @@ The ode package provides a daemon which is responsible for encrypting/decryption %attr(755,root,root) %{_bindir}/oded %{_unitdir}/ode.service %{_unitdir}/multi-user.target.wants/ode.service -%attr(700,root,root) %{_sbindir}/ode-admin-cli +%attr(700,root,root) %{TZ_SYS_SBIN}/ode-admin-cli +%attr(700,root,root) %{TZ_SYS_SBIN}/ode-fota %{_datadir}/%{name} %dir %{key_storage_plugin_dir} @@ -52,6 +53,7 @@ The ode package provides a daemon which is responsible for encrypting/decryption -DCMAKE_BUILD_TYPE=%{build_type} \ -DRUN_DIR=%{TZ_SYS_RUN} \ -DBIN_DIR=%{TZ_SYS_BIN} \ + -DSBIN_DIR=%{TZ_SYS_SBIN} \ -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DAPP_INSTALL_PREFIX="%{TZ_SYS_RO_APP}" \ -DAPP_SHARE_PACKAGES_DIR="%{TZ_SYS_RO_PACKAGES}" \ diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 2c115c9..0df5512 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -24,6 +24,7 @@ SET(SERVER_SRCS main.cpp progress-bar.cpp kernel-keyring.cpp internal-encryption.cpp + internal-encryption-common.cpp external-encryption.cpp luks.cpp key-server.cpp diff --git a/server/internal-encryption-common.cpp b/server/internal-encryption-common.cpp new file mode 100644 index 0000000..9953bbd --- /dev/null +++ b/server/internal-encryption-common.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015-2017 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 + */ + +#include "internal-encryption-common.h" + +#include +#include + +#include "logger.h" + +namespace ode { + +namespace { +const char *INTERNAL_DEV_PATH = "/dev/disk/by-partlabel"; +const char *INTERNAL_DEV_NAME = "USER"; +} // namespace anonymous + +const char *INTERNAL_PATH = "/opt/usr"; + +std::string findDevPath() +{ + std::string source = INTERNAL_DEV_PATH + std::string("/") + INTERNAL_DEV_NAME; + try { + runtime::DirectoryIterator iter(INTERNAL_DEV_PATH), end; + + while (iter != end) { + const std::string& path = (*iter).getPath(); + std::string name = path.substr(path.rfind('/') + 1); + std::string upper; + upper.reserve(name.size()); + for (char c : name) { + upper += std::toupper(c); + } + if (upper.compare(0, strlen(INTERNAL_DEV_NAME), INTERNAL_DEV_NAME) == 0) { + source = path; + break; + } + ++iter; + } + } catch (runtime::Exception &e) {} + + char *dev = ::realpath(source.c_str(), NULL); + if (dev == NULL) { + ERROR(SINK, "Failed to get device path."); + return ""; + } + + std::string devPath(dev); + free(dev); + + return devPath; +} + +} // namespace ode diff --git a/server/internal-encryption-common.h b/server/internal-encryption-common.h new file mode 100644 index 0000000..d41d0ba --- /dev/null +++ b/server/internal-encryption-common.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015-2017 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 + */ + +#ifndef __INTERNAL_ENCRYPTION_SERVER_COMMON_H__ +#define __INTERNAL_ENCRYPTION_SERVER_COMMON_H__ + +#include + +namespace ode { + +extern const char *INTERNAL_PATH; + +std::string findDevPath(); + +} // namespace ode + +#endif // __INTERNAL_ENCRYPTION_SERVER_COMMON_H__ diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index 814d90f..c542ddb 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -40,15 +40,12 @@ #include "rmi/common.h" #include "internal-encryption.h" +#include "internal-encryption-common.h" namespace ode { namespace { -const char *INTERNAL_DEV_PATH = "/dev/disk/by-partlabel"; -const char *INTERNAL_DEV_NAME = "USER"; -const char *INTERNAL_PATH = "/opt/usr"; - const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform"; // TODO: see recovery() @@ -63,40 +60,6 @@ const std::vector wipeCommand = { "com.samsung.factoryreset.start.setting" }; -std::string findDevPath() -{ - std::string source = INTERNAL_DEV_PATH + std::string("/") + INTERNAL_DEV_NAME; - try { - runtime::DirectoryIterator iter(INTERNAL_DEV_PATH), end; - - while (iter != end) { - const std::string& path = (*iter).getPath(); - std::string name = path.substr(path.rfind('/') + 1); - std::string upper; - upper.reserve(name.size()); - for (char c : name) { - upper += std::toupper(c); - } - if (upper.compare(0, strlen(INTERNAL_DEV_NAME), INTERNAL_DEV_NAME) == 0) { - source = path; - break; - } - ++iter; - } - } catch (runtime::Exception &e) {} - - char *dev = ::realpath(source.c_str(), NULL); - if (dev == NULL) { - ERROR(SINK, "Failed to get device path."); - return ""; - } - - std::string devPath(dev); - free(dev); - - return devPath; -} - void stopKnownSystemdServices() { std::vector knownSystemdServices; diff --git a/tools/cli/CMakeLists.txt b/tools/cli/CMakeLists.txt index ae42a87..0eeab63 100644 --- a/tools/cli/CMakeLists.txt +++ b/tools/cli/CMakeLists.txt @@ -34,4 +34,4 @@ PKG_CHECK_MODULES(CLI_DEPS REQUIRED INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${ODE_LIB}) TARGET_LINK_LIBRARIES(${CLI_NAME} ${CLI_DEPS_LIBRARIES} ${PROJECT_NAME} ode) -INSTALL(TARGETS ${CLI_NAME} DESTINATION sbin) +INSTALL(TARGETS ${CLI_NAME} DESTINATION ${SBIN_DIR})