From: Krzysztof Jackiewicz Date: Fri, 20 Oct 2017 09:09:20 +0000 (+0200) Subject: Synchronous API for LUKS X-Git-Tag: submit/tizen/20171023.130046~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf424af0d061bc2455b45a5baafad32c334f8875;p=platform%2Fcore%2Fsecurity%2Fode.git Synchronous API for LUKS Change-Id: I30299af2cc523a5ee985fea87e331cf06f3bf96e --- diff --git a/lib/luks.cpp b/lib/luks.cpp index ea9104e..766a32b 100644 --- a/lib/luks.cpp +++ b/lib/luks.cpp @@ -17,7 +17,8 @@ namespace ode { -LuksClient::LuksClient(RmiClientPtr& ctx) : context(ctx) +LuksClient::LuksClient(RmiClientPtr& ctx) : + context(ctx) { } @@ -25,30 +26,40 @@ LuksClient::~LuksClient() { } -int LuksClient::format(const std::string& device, const std::string& password) +int LuksClient::format(bool sync, + const std::string& device, + const std::string& password) { try { - return context->methodCall("LuksServer::format", device, password); + return context->methodCall("LuksServer::format", + sync, + device, + password); } catch (runtime::Exception& e) { return -1; } } -int LuksClient::open(const std::string& device, +int LuksClient::open(bool sync, + const std::string& device, const std::string& password, const std::string& mapping) { try { - return context->methodCall("LuksServer::open", device, password, mapping); + return context->methodCall("LuksServer::open", + sync, + device, + password, + mapping); } catch (runtime::Exception& e) { return -1; } } -int LuksClient::close(const std::string& mapping) +int LuksClient::close(bool sync, const std::string& mapping) { try { - return context->methodCall("LuksServer::close", mapping); + return context->methodCall("LuksServer::close", sync, mapping); } catch (runtime::Exception& e) { return -1; } diff --git a/lib/luks.h b/lib/luks.h index ef26679..c435f79 100644 --- a/lib/luks.h +++ b/lib/luks.h @@ -27,13 +27,16 @@ public: explicit LuksClient(RmiClientPtr& ctxt); ~LuksClient(); - int format(const std::string& device, const std::string& password); + int format(bool sync, + const std::string& device, + const std::string& password); - int open(const std::string& device, + int open(bool sync, + const std::string& device, const std::string& password, const std::string& mapping); - int close(const std::string& mapping); + int close(bool sync, const std::string& mapping); private: RmiClientPtr& context; diff --git a/lib/ode/luks.cpp b/lib/ode/luks.cpp index 4058ecf..11390f6 100644 --- a/lib/ode/luks.cpp +++ b/lib/ode/luks.cpp @@ -37,9 +37,17 @@ std::map ODE_ERROR_TO_API_ERROR = { { OdeError::DeviceBusy, ODE_ERROR_RESOURCE_BUSY }, { OdeError::Unknown, ODE_ERROR_UNKNOWN } }; -} // anonymous namespace -int ode_luks_format(const char* device, const char* password) +int toApiError(int error) +{ + int ret = ODE_ERROR_UNKNOWN; + auto it = ODE_ERROR_TO_API_ERROR.find(static_cast(error)); + if (it != ODE_ERROR_TO_API_ERROR.end()) + ret = it->second; + return ret; +} + +int luks_format_internal(bool sync, const char* device, const char* password) { RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER); RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER); @@ -48,10 +56,13 @@ int ode_luks_format(const char* device, const char* password) RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED); LuksClient luks = client.createInterface(); - return luks.format(device, password); + return luks.format(sync, device, password); } -int ode_luks_open(const char* device, const char* password, const char* mapping) +int luks_open_internal(bool sync, + const char* device, + const char* password, + const char* mapping) { RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER); RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER); @@ -61,10 +72,10 @@ int ode_luks_open(const char* device, const char* password, const char* mapping) RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED); LuksClient luks = client.createInterface(); - return luks.open(device, password, mapping); + return luks.open(sync, device, password, mapping); } -int ode_luks_close(const char* mapping) +int luks_close_internal(bool sync, const char* mapping) { RET_ON_FAILURE(mapping, ODE_ERROR_INVALID_PARAMETER); @@ -72,7 +83,24 @@ int ode_luks_close(const char* mapping) RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED); LuksClient luks = client.createInterface(); - return luks.close(mapping); + return luks.close(sync, mapping); +} + +} // anonymous namespace + +int ode_luks_format(const char* device, const char* password) +{ + return luks_format_internal(false, device, password); +} + +int ode_luks_open(const char* device, const char* password, const char* mapping) +{ + return luks_open_internal(false, device, password, mapping); +} + +int ode_luks_close(const char* mapping) +{ + return luks_close_internal(false, mapping); } int ode_luks_set_event_cb(ode_luks_event_cb callback, void *user_data) @@ -85,12 +113,7 @@ int ode_luks_set_event_cb(ode_luks_event_cb callback, void *user_data) RET_ON_FAILURE(luksEventCallbackContext->connect() == 0, ODE_ERROR_CONNECTION_REFUSED); std::functioncb = [callback, user_data](std::string, int op, int res) { - int ret = ODE_ERROR_UNKNOWN; - auto it = ODE_ERROR_TO_API_ERROR.find(static_cast(res)); - if (it != ODE_ERROR_TO_API_ERROR.end()) - ret = it->second; - - callback(static_cast(op), ret, user_data); + callback(static_cast(op), toApiError(res), user_data); }; ret = luksEventCallbackContext->subscribeSignal(Luks::NOTIFICATION, cb); @@ -104,3 +127,20 @@ void ode_luks_unset_event_cb() luksEventCallbackContext.reset(); } +int ode_luks_format_sync(const char* device, const char* password) +{ + int err = luks_format_internal(true, device, password); + return toApiError(err); +} + +int ode_luks_open_sync(const char* device, const char* password, const char* mapping) +{ + int err = luks_open_internal(true, device, password, mapping); + return toApiError(err); +} + +int ode_luks_close_sync(const char* mapping) +{ + int err = luks_close_internal(true, mapping); + return toApiError(err); +} diff --git a/lib/ode/luks.h b/lib/ode/luks.h index 29ae394..d7e6073 100644 --- a/lib/ode/luks.h +++ b/lib/ode/luks.h @@ -62,9 +62,9 @@ typedef void(*ode_luks_event_cb)(ode_luks_operation_e operation, /** * @brief Formats given device as LUKS using given password. * - * @details The device will be formatted as LUKS but the password will be - * stored in internal storage. This function is asynchronous. If a - * callback was registered using ode_luks_set_event_cb() then it + * @details The device will be formatted as LUKS but the encryption key will + * be stored in internal storage. This function is asynchronous. If + * a callback was registered using ode_luks_set_event_cb() then it * will be invoked when the operation is finished. * * @since_tizen 4.0 @@ -96,6 +96,7 @@ typedef void(*ode_luks_event_cb)(ode_luks_operation_e operation, * * @see ode_luks_open() * @see ode_luks_set_event_cb() + * @see ode_luks_format_sync() */ ODE_API int ode_luks_format(const char* device, const char* password); @@ -140,6 +141,7 @@ ODE_API int ode_luks_format(const char* device, const char* password); * @see ode_luks_format() * @see ode_luks_close() * @see ode_luks_set_event_cb() + * @see ode_luks_open_sync() */ ODE_API int ode_luks_open(const char* device, const char* password, @@ -178,6 +180,7 @@ ODE_API int ode_luks_open(const char* device, * @see ode_luks_format() * @see ode_luks_open() * @see ode_luks_set_event_cb() + * @see ode_luks_close_sync() */ ODE_API int ode_luks_close(const char* mapping); @@ -214,6 +217,101 @@ ODE_API int ode_luks_set_event_cb(ode_luks_event_cb callback, void *user_data); */ ODE_API void ode_luks_unset_event_cb(); +/** + * @brief Formats given device as LUKS using given password. + * + * @details The device will be formatted as LUKS but the encryption key will + * be stored in internal storage. This function is synchronous. + * + * @since_tizen 4.0 + * + * @param[in] device The device to be formatted + * @param[in] password The password used for formatting + * + * @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_CONNECTION_REFUSED Connection to the server failed + * @retval #ODE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #ODE_ERROR_NO_SUCH_FILE Wrong device + * @retval #ODE_ERROR_RESOURCE_BUSY Device is busy + * @retval #ODE_ERROR_UNKNOWN Unknown error + * + * @pre The @a device must be present and neither mapped nor mounted. + * + * @post Formatted device can be later opened using ode_luks_open(). The + * mapping will not contain a valid file system. It needs to be + * formatted. + * + * @see ode_luks_open_sync() + * @see ode_luks_format() + */ +ODE_API int ode_luks_format_sync(const char* device, const char* password); + +/** + * @brief Creates a mapping with given name backed by a LUKS device. + * + * @details This function is synchronous. + * + * @since_tizen 4.0 + * + * @param[in] device The device to be used + * @param[in] password The password used for mapping creation that was used + * for formatting. + * @param[in] mapping The desired name of the mapping + * + * @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_CONNECTION_REFUSED Connection to the server failed + * @retval #ODE_ERROR_KEY_REJECTED Wrong password + * @retval #ODE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #ODE_ERROR_NO_SUCH_FILE Wrong device or mapping + * @retval #ODE_ERROR_RESOURCE_BUSY Device is busy + * @retval #ODE_ERROR_UNKNOWN Unknown error + * + * @pre The @a device must be a LUKS device formatted with + * ode_luks_format(). The mapping must not exist. + * + * @post The created mapping can be later mounted to access the encrypted + * storage. + * @post To close the mapping call ode_luks_close() + * + * @see ode_luks_format_sync() + * @see ode_luks_close_sync() + * @see ode_luks_open() + */ +ODE_API int ode_luks_open_sync(const char* device, + const char* password, + const char* mapping); + +/** + * @brief Removes a mapping with given name backed by a LUKS device. + * + * @details This function is synchronous. + * + * @since_tizen 4.0 + * + * @param[in] mapping The name of the mapping to be closed + * + * @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_CONNECTION_REFUSED Connection to the server failed + * @retval #ODE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #ODE_ERROR_NO_SUCH_FILE Wrong mapping + * @retval #ODE_ERROR_RESOURCE_BUSY Device is busy + * @retval #ODE_ERROR_UNKNOWN Unknown error + * + * @pre The mapping must be created by a call to ode_luks_open(). + * The mapping must not be mounted. + * + * @see ode_luks_format_sync() + * @see ode_luks_open_sync() + * @see ode_luks_close() + */ +ODE_API int ode_luks_close_sync(const char* mapping); + /** * @} */ diff --git a/rmi/luks.h b/rmi/luks.h index d2a3c1b..73ea15f 100644 --- a/rmi/luks.h +++ b/rmi/luks.h @@ -27,14 +27,16 @@ namespace ode { class Luks { public: - virtual int format(const std::string& device, + virtual int format(bool sync, + const std::string& device, const std::string& password) = 0; - virtual int open(const std::string& device, + virtual int open(bool sync, + const std::string& device, const std::string& password, const std::string& mapping) = 0; - virtual int close(const std::string& mapping) = 0; + virtual int close(bool sync, const std::string& mapping) = 0; enum Operation { Format = 1, diff --git a/server/luks.cpp b/server/luks.cpp index d8de637..aea9b7e 100644 --- a/server/luks.cpp +++ b/server/luks.cpp @@ -49,9 +49,9 @@ std::map CRYPTSETUP_ERROR_2_ODE_ERROR = LuksServer::LuksServer(ServerContext &srv) : server(srv) { - server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::format)(std::string, std::string)); - server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::open)(std::string, std::string, std::string)); - server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::close)(std::string)); + server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::format)(bool, std::string, std::string)); + server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::open)(bool, std::string, std::string, std::string)); + server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::close)(bool, std::string)); server.createNotification(NOTIFICATION); } @@ -61,7 +61,7 @@ LuksServer::~LuksServer() } template -int LuksServer::asyncJob(Luks::Operation op, const F& job) +int LuksServer::execute(bool sync, Luks::Operation op, const F& job) { auto worker = [=]() { OdeError ret = OdeError::Unknown; @@ -83,17 +83,28 @@ int LuksServer::asyncJob(Luks::Operation op, const F& job) " thread failed: unknown exception."); ret = OdeError::Unknown; } - server.notify(NOTIFICATION, static_cast(op), static_cast(ret)); + if (sync) { + return static_cast(ret); + } else { + server.notify(NOTIFICATION, static_cast(op), static_cast(ret)); + return 0; + } }; - std::thread work(worker); - work.detach(); - return 0; + if (sync) { + return worker(); + } else { + std::thread work(worker); + work.detach(); + return 0; + } } -int LuksServer::format(const std::string& device, const std::string& password) +int LuksServer::format(bool sync, + const std::string& device, + const std::string& password) { - return asyncJob(Luks::Format, [=](){ + return execute(sync, Luks::Format, [=](){ KeyManager::data pwData(password.begin(), password.end()); KeyManager keyManager; keyManager.initPassword(pwData, DEFAULT_KEY_SIZE); @@ -107,11 +118,12 @@ int LuksServer::format(const std::string& device, const std::string& password) }); } -int LuksServer::open(const std::string& device, +int LuksServer::open(bool sync, + const std::string& device, const std::string& password, const std::string& mapping) { - return asyncJob(Luks::Open, [=](){ + return execute(sync, Luks::Open, [=](){ CryptsetupEngine engine(device); KeyManager::data pwData(password.begin(), password.end()); @@ -128,9 +140,10 @@ int LuksServer::open(const std::string& device, }); } -int LuksServer::close(const std::string& mapping) +int LuksServer::close(bool sync, + const std::string& mapping) { - return asyncJob(Luks::Close, [=](){ + return execute(sync, Luks::Close, [=](){ CryptsetupEngine::close(mapping); return OdeError::None; }); diff --git a/server/luks.h b/server/luks.h index 8cc5a66..772a9b2 100644 --- a/server/luks.h +++ b/server/luks.h @@ -30,15 +30,20 @@ public: explicit LuksServer(ServerContext& srv); ~LuksServer(); - int format(const std::string& device, const std::string& password); - int open(const std::string& device, + int format(bool sync, + const std::string& device, + const std::string& password); + + int open(bool sync, + const std::string& device, const std::string& password, const std::string& mapping); - int close(const std::string& mapping); + + int close(bool sync, const std::string& mapping); private: template - int asyncJob(Luks::Operation op, const F& job); + int execute(bool sync, Luks::Operation op, const F& job); ServerContext& server;