From: Sungbae Yoo Date: Tue, 21 Mar 2017 10:36:46 +0000 (+0900) Subject: Add APIs to wait the mount of storage X-Git-Tag: submit/tizen/20170322.105714~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=597f1311c2eceb108112f0f95bfc717cbd82baec;p=platform%2Fcore%2Fsecurity%2Fode.git Add APIs to wait the mount of storage Signed-off-by: Sungbae Yoo Change-Id: I15ba0826caaa601bdbb0894e8cb5d2b306b3bfad --- diff --git a/lib/client.cpp b/lib/client.cpp index b9fbd1e..25d8cb2 100644 --- a/lib/client.cpp +++ b/lib/client.cpp @@ -18,6 +18,10 @@ namespace { +const std::string SUBSCRIBER_REGISTER = "Server::registerNotificationSubscriber"; +const std::string SUBSCRIBER_UNREGISTER = "Server::unregisterNotificationSubscriber"; + + const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock"; } // namespace @@ -53,3 +57,25 @@ void ODEContext::disconnect() noexcept { client.reset(); } + +int ODEContext::subscribeSignal(const std::string& name, + const SignalListener& listener, + void* data) +{ + auto listenerDispatcher = [listener, data](std::string name) { + listener(data); + }; + + try { + return client->subscribe + (SUBSCRIBER_REGISTER, name, listenerDispatcher); + } catch (runtime::Exception& e) { + std::cout << e.what() << std::endl; + return -1; + } +} + +int ODEContext::unsubscribeSignal(int subscriberId) +{ + return client->unsubscribe(SUBSCRIBER_UNREGISTER, subscriberId); +} diff --git a/lib/client.h b/lib/client.h index a512821..70d7369 100644 --- a/lib/client.h +++ b/lib/client.h @@ -23,6 +23,8 @@ #include +typedef std::function SignalListener; + class ODEContext final { public: typedef std::unique_ptr ODEControlContext; @@ -34,6 +36,9 @@ public: int connect(const std::string& address) noexcept; void disconnect() noexcept; + int subscribeSignal(const std::string& name, const SignalListener& listener, void* data); + int unsubscribeSignal(int subscriberId); + template Interface createInterface(Args&&... args) noexcept { diff --git a/lib/ode/external-encryption.cpp b/lib/ode/external-encryption.cpp index e578c65..35fe505 100644 --- a/lib/ode/external-encryption.cpp +++ b/lib/ode/external-encryption.cpp @@ -164,3 +164,24 @@ int ode_external_encryption_get_supported_options(unsigned int* options) *options = external.getSupportedOptions(); return ODE_ERROR_NONE; } + +static void _ode_external_event_listener(void *user_data) { + std::mutex *pMtx = (std::mutex*)user_data; + pMtx->unlock(); +} + +int ode_external_encryption_wait_for_mount() +{ + ODEContext client; + RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED); + + std::mutex mtx; + mtx.lock(); + + int ret = client.subscribeSignal("ExternalEncryption::mount", _ode_external_event_listener, &mtx); + RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER); + + mtx.lock(); + + return ODE_ERROR_NONE; +} diff --git a/lib/ode/external-encryption.h b/lib/ode/external-encryption.h index 5ab67c3..b156f74 100644 --- a/lib/ode/external-encryption.h +++ b/lib/ode/external-encryption.h @@ -266,6 +266,20 @@ typedef enum { */ ODE_API int ode_external_encryption_get_supported_options(unsigned int* options); +/** + * @brief Wait for mount of external storage + * @details Services can use this API to wait for mount of external storage. + * @since_tizen 3.0 + * @return #ODE_ERROR_NONE on success, otherwise a negative value + * @retval #ODE_ERROR_NONE Successful + * @retval #ODE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ODE_ERROR_TIMED_OUT Time out + * @retval #ODE_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @see ode_external_encryption_mount() + */ +ODE_API int ode_external_encryption_wait_for_mount(); + /** * @} */ diff --git a/lib/ode/internal-encryption.cpp b/lib/ode/internal-encryption.cpp index 9c8aee8..527174d 100644 --- a/lib/ode/internal-encryption.cpp +++ b/lib/ode/internal-encryption.cpp @@ -164,3 +164,24 @@ int ode_internal_encryption_get_supported_options(unsigned int* options) *options = internal.getSupportedOptions(); return ODE_ERROR_NONE; } + +static void _ode_internal_event_listener(void *user_data) { + std::mutex *pMtx = (std::mutex*)user_data; + pMtx->unlock(); +} + +int ode_internal_encryption_wait_for_mount() +{ + ODEContext client; + RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED); + + std::mutex mtx; + mtx.lock(); + + int ret = client.subscribeSignal("InternalEncryption::mount", _ode_internal_event_listener, &mtx); + RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER); + + mtx.lock(); + + return ODE_ERROR_NONE; +} diff --git a/lib/ode/internal-encryption.h b/lib/ode/internal-encryption.h index 45b7bbd..94eb681 100644 --- a/lib/ode/internal-encryption.h +++ b/lib/ode/internal-encryption.h @@ -267,6 +267,19 @@ typedef enum { */ ODE_API int ode_internal_encryption_get_supported_options(unsigned int* options); +/** + * @brief Wait for mount of internal storage + * @details Services can use this API to wait for mount of internal storage. + * @since_tizen 3.0 + * @return #ODE_ERROR_NONE on success, otherwise a negative value + * @retval #ODE_ERROR_NONE Successful + * @retval #ODE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ODE_ERROR_TIMED_OUT Time out + * @retval #ODE_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @see ode_internal_encryption_mount() + */ +ODE_API int ode_internal_encryption_wait_for_mount(); /* * @} */ diff --git a/server/external-encryption.cpp b/server/external-encryption.cpp index 932b83e..82d2690 100644 --- a/server/external-encryption.cpp +++ b/server/external-encryption.cpp @@ -171,6 +171,8 @@ ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) : context.expose(this, "", (int)(ExternalEncryption::getState)()); context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)()); + context.createNotification("ExternalEncryption::mount"); + engine.reset(new EXTERNAL_ENGINE( EXTERNAL_PATH, EXTERNAL_PATH, ProgressBar([](int v) { @@ -200,6 +202,8 @@ int ExternalEncryption::mount(const std::string &password) } engine->mount(keyManager.getMasterKey(data), getOptions()); + context.notify("ExternalEncryption::mount"); + return 0; } diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index a5059ca..f1a1a0d 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -206,6 +206,8 @@ InternalEncryption::InternalEncryption(ODEControlContext& ctx) : context.expose(this, "", (int)(InternalEncryption::getState)()); context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)()); + context.createNotification("InternalEncryption::mount"); + engine.reset(new INTERNAL_ENGINE( INTERNAL_DEV, INTERNAL_PATH, ProgressBar([](int v) { @@ -233,6 +235,8 @@ int InternalEncryption::mount(const std::string& password) } engine->mount(keyManager.getMasterKey(pwData), getOptions()); + context.notify("InternalEncryption::mount"); + return 0; } diff --git a/server/server.cpp b/server/server.cpp index e948ebb..521826c 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -41,6 +41,9 @@ Server::Server() service->setPrivilegeChecker(std::bind(&Server::checkPeerPrivilege, this, _1, _2)); + service->expose(this, "", (runtime::FileDescriptor)(Server::registerNotificationSubscriber)(std::string)); + service->expose(this, "", (int)(Server::unregisterNotificationSubscriber)(std::string, int)); + secureErase.reset(new ode::SecureErase(*this)); internalEncryption.reset(new ode::InternalEncryption(*this)); externalEncryption.reset(new ode::ExternalEncryption(*this)); @@ -89,3 +92,15 @@ bool Server::checkPeerPrivilege(const rmi::Credentials& cred, const std::string& return true; } + +runtime::FileDescriptor Server::registerNotificationSubscriber(const std::string& name) +{ + INFO("registerNotificationSubscriber"); + INFO(name); + return runtime::FileDescriptor(service->subscribeNotification(name), true); +} + +int Server::unregisterNotificationSubscriber(const std::string& name, int id) +{ + return service->unsubscribeNotification(name, id); +} diff --git a/server/server.h b/server/server.h index 9b21e68..d7a439d 100644 --- a/server/server.h +++ b/server/server.h @@ -39,6 +39,12 @@ public: service->setMethodHandler(privilege, method, handler); } + template + void notify(const std::string& name, Args&&... args) + { + service->notify(name, std::forward(args)...); + } + uid_t getPeerUid() const { return service->getPeerUid(); @@ -56,6 +62,15 @@ public: bool checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege); + + void createNotification(const std::string& name) + { + service->createNotification(name); + } + + runtime::FileDescriptor registerNotificationSubscriber(const std::string& name); + int unregisterNotificationSubscriber(const std::string& name, int id); + private: std::string securityLabel; std::unique_ptr service; diff --git a/tools/cli/ode-admin-cli.cpp b/tools/cli/ode-admin-cli.cpp index 7d6f0d2..0b412a8 100644 --- a/tools/cli/ode-admin-cli.cpp +++ b/tools/cli/ode-admin-cli.cpp @@ -44,6 +44,7 @@ static inline int usage(const std::string name) << " -d, --decrypt=internal|external decrypt" << std::endl << " -p, --changepw=internal|external change password" << std::endl << " -s, --state=internal|external get state" << std::endl + << " -w, --waitmnt=internal|external wait for mount"<< std::endl << " -r, --erase=FILE|DIRECTORY secure-erase" << std::endl << " -c, --clean=DIRECTORY secure-clean" << std::endl << " -h, --help show this" << std::endl @@ -296,6 +297,29 @@ static inline int get_state(const std::string name) return ret; } +static inline int wait_for_mount(const std::string name) +{ + int ret; + + if (name == "internal") { + std::cout << "Wait for internal storage mount..." << std::endl; + ret = ode_internal_encryption_wait_for_mount(); + } else if (name == "external") { + std::cout << "Wait for external storage mount..." << std::endl; + ret = ode_external_encryption_wait_for_mount(); + } else { + printSelectableStorage(); + return -1; + } + + if (ret != 0) { + std::cerr << "Error : " << ret <