From: Krzysztof Jackiewicz Date: Tue, 28 Oct 2014 11:33:51 +0000 (+0100) Subject: Add file lock to key-manager server X-Git-Tag: accepted/tizen/common/20150416.164946~81 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=414843221f0392502f777513bfa3b810fee462af;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git Add file lock to key-manager server [Verification] Try to run 2 instances of key-manager. It should fail. key-manager-listener should not start key-manager. Change-Id: Ifa0d6244738b4a48b153e066d5b49fbd967a316a --- diff --git a/src/listener/listener-daemon.cpp b/src/listener/listener-daemon.cpp index 28a2bb0..e5f4839 100644 --- a/src/listener/listener-daemon.cpp +++ b/src/listener/listener-daemon.cpp @@ -22,6 +22,10 @@ #define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state" #endif +namespace { +const char* const CKM_LOCK = "/var/run/key-manager.pid"; +}; + void daemonize() { // Let's operate in background @@ -85,9 +89,24 @@ void daemonize() SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", str); } +bool isCkmRunning() +{ + int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR)); + if (lock == -1) + return false; + + int ret = lockf(lock, F_TEST, 0); + close(lock); + + // if lock test fails because of an error assume ckm is running + return (0 != ret); +} + void callUpdateCCMode() { - // TODO make it call ckm only if it's already running (lock file) + if(!isCkmRunning()) + return; + auto control = CKM::Control::create(); int ret = control->updateCCMode(); diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt index 83daa5e..a6b7526 100644 --- a/src/manager/CMakeLists.txt +++ b/src/manager/CMakeLists.txt @@ -23,6 +23,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/common/key-impl.cpp ${COMMON_PATH}/common/pkcs12-impl.cpp ${COMMON_PATH}/common/descriptor-set.cpp + ${COMMON_PATH}/common/file-lock.cpp ${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp ${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp ${COMMON_PATH}/dpl/log/src/log.cpp diff --git a/src/manager/common/file-lock.cpp b/src/manager/common/file-lock.cpp new file mode 100644 index 0000000..11aa562 --- /dev/null +++ b/src/manager/common/file-lock.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2000 - 2014 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 file-lock.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "file-lock.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace CKM { + +namespace { + +// TODO replace it with custom exception when they are implemented +template +std::runtime_error io_exception(const Args&... args) +{ + return std::runtime_error(stringify(args...)); +}; + +} // namespace anonymous + +FileLock::FileLock(const char* const file) +{ + // Open lock file + m_lockFd = TEMP_FAILURE_RETRY(creat(file, 0644)); + if (m_lockFd == -1) { + throw io_exception("Cannot open lock file. Errno: ", strerror(errno)); + } + + if (-1 == lockf(m_lockFd, F_TLOCK, 0)) { + if (errno == EACCES || errno == EAGAIN) + throw io_exception("Can't acquire lock. Another instance must be running."); + else + throw io_exception("Can't acquire lock. Errno: ", strerror(errno)); + } + + std::string pid = std::to_string(getpid()); + + ssize_t written = TEMP_FAILURE_RETRY(write(m_lockFd, pid.c_str(), pid.size())); + if (-1 == written || static_cast(pid.size()) > written) + throw io_exception("Can't write file lock. Errno: ", strerror(errno)); + + int ret = fsync(m_lockFd); + if (-1 == ret) + throw io_exception("Fsync failed. Errno: ",strerror(errno)); +} + +FileLock::~FileLock() +{ + // this will also release the lock + close(m_lockFd); +} + +} /* namespace CKM */ diff --git a/src/manager/common/file-lock.h b/src/manager/common/file-lock.h new file mode 100644 index 0000000..b56e29a --- /dev/null +++ b/src/manager/common/file-lock.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 - 2014 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 file-lock.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include + +namespace CKM { + +class FileLock +{ +public: + explicit FileLock(const char* const file); + ~FileLock(); + + NONCOPYABLE(FileLock); + + FileLock(FileLock&&) = default; + FileLock& operator=(FileLock&&) = default; + +private: + int m_lockFd; +}; + +} /* namespace CKM */ diff --git a/src/manager/main/key-manager-main.cpp b/src/manager/main/key-manager-main.cpp index a2d43b0..f878cd2 100644 --- a/src/manager/main/key-manager-main.cpp +++ b/src/manager/main/key-manager-main.cpp @@ -38,6 +38,7 @@ #include #include +#include IMPLEMENT_SAFE_SINGLETON(CKM::Log::LogSystem); @@ -72,6 +73,14 @@ int main(void) { { CKM::Singleton::Instance().SetTag("CKM"); + int retCode = CKM::FileSystem::init(); + if (retCode) { + LogError("Fatal error in FileSystem::init()"); + return 1; + } + + CKM::FileLock fl = CKM::FileSystem::lock(); + sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); @@ -80,7 +89,7 @@ int main(void) { LogError("Error in pthread_sigmask"); return 1; } - LogInfo("Init external liblaries SKMM and openssl"); + LogInfo("Init external libraries SKMM and openssl"); SSL_load_error_strings(); SSL_library_init(); @@ -106,6 +115,10 @@ int main(void) { EVP_cleanup(); ERR_free_strings(); } + catch (const std::runtime_error& e) + { + LogError(e.what()); + } UNHANDLED_EXCEPTION_HANDLER_END return 0; } diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 5db4540..137f77f 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -46,12 +46,6 @@ namespace CKM { CKMLogic::CKMLogic() : m_ccMode(false) { - int retCode = FileSystem::init(); - // TODO what can I do when init went wrong? exit(-1) ?? - if (retCode) { - LogError("Fatal error in FileSystem::init()"); - } - if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) { LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work"); } diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index 3bdb74f..299fb29 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -32,6 +32,7 @@ #include #include #include +#include namespace CKM { @@ -208,6 +209,7 @@ private: std::map m_userDataMap; CertificateStore m_certStore; bool m_ccMode; + //FileLock m_lock; }; } // namespace CKM diff --git a/src/manager/service/file-system.cpp b/src/manager/service/file-system.cpp index 6580a34..3145ed8 100644 --- a/src/manager/service/file-system.cpp +++ b/src/manager/service/file-system.cpp @@ -37,11 +37,12 @@ namespace { -static const std::string CKM_DATA_PATH = "/opt/data/ckm/"; -static const std::string CKM_KEY_PREFIX = "key-"; -static const std::string CKM_DB_KEY_PREFIX = "db-key-"; -static const std::string CKM_DB_PREFIX = "db-"; -static const std::string CKM_REMOVED_APP_PREFIX = "removed-app-"; +const std::string CKM_DATA_PATH = "/opt/data/ckm/"; +const std::string CKM_KEY_PREFIX = "key-"; +const std::string CKM_DB_KEY_PREFIX = "db-key-"; +const std::string CKM_DB_PREFIX = "db-"; +const std::string CKM_REMOVED_APP_PREFIX = "removed-app-"; +const std::string CKM_LOCK_FILE = "/var/run/key-manager.pid"; } // namespace anonymous @@ -233,5 +234,11 @@ int FileSystem::removeUserData() const { return retCode; } +FileLock FileSystem::lock() +{ + FileLock fl(CKM_LOCK_FILE.c_str()); + return fl; +} + } // namespace CKM diff --git a/src/manager/service/file-system.h b/src/manager/service/file-system.h index 53561d6..694ccde 100644 --- a/src/manager/service/file-system.h +++ b/src/manager/service/file-system.h @@ -23,6 +23,7 @@ #include #include +#include namespace CKM { @@ -51,6 +52,7 @@ public: static int init(); static UidVector getUIDsFromDBFile(); + static FileLock lock(); virtual ~FileSystem(){} protected: