Synchronous API for LUKS 70/156870/4
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 20 Oct 2017 09:09:20 +0000 (11:09 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 23 Oct 2017 13:57:21 +0000 (13:57 +0000)
Change-Id: I30299af2cc523a5ee985fea87e331cf06f3bf96e

lib/luks.cpp
lib/luks.h
lib/ode/luks.cpp
lib/ode/luks.h
rmi/luks.h
server/luks.cpp
server/luks.h

index ea9104e..766a32b 100644 (file)
@@ -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<int>("LuksServer::format", device, password);
+               return context->methodCall<int>("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<int>("LuksServer::open", device, password, mapping);
+               return context->methodCall<int>("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<int>("LuksServer::close", mapping);
+               return context->methodCall<int>("LuksServer::close", sync, mapping);
        } catch (runtime::Exception& e) {
                return -1;
        }
index ef26679..c435f79 100644 (file)
@@ -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;
index 4058ecf..11390f6 100644 (file)
@@ -37,9 +37,17 @@ std::map<OdeError, int> 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<OdeError>(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<LuksClient>();
 
-       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<LuksClient>();
 
-       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<LuksClient>();
 
-       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::function<void(std::string, int, int)>cb = [callback, user_data](std::string, int op, int res) {
-               int ret = ODE_ERROR_UNKNOWN;
-               auto it = ODE_ERROR_TO_API_ERROR.find(static_cast<OdeError>(res));
-               if (it != ODE_ERROR_TO_API_ERROR.end())
-                       ret = it->second;
-
-               callback(static_cast<ode_luks_operation_e>(op), ret, user_data);
+               callback(static_cast<ode_luks_operation_e>(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);
+}
index 29ae394..d7e6073 100644 (file)
@@ -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
+ *              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);
 
@@ -215,6 +218,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);
+
+/**
  * @}
  */
 
index d2a3c1b..73ea15f 100644 (file)
@@ -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,
index d8de637..aea9b7e 100644 (file)
@@ -49,9 +49,9 @@ std::map<CryptsetupEngine::ReturnCode, OdeError> 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 <typename F>
-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<int>(op), static_cast<int>(ret));
+               if (sync) {
+                       return static_cast<int>(ret);
+               } else {
+                       server.notify(NOTIFICATION, static_cast<int>(op), static_cast<int>(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;
        });
index 8cc5a66..772a9b2 100644 (file)
@@ -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 <typename F>
-       int asyncJob(Luks::Operation op, const F& job);
+       int execute(bool sync, Luks::Operation op, const F& job);
 
        ServerContext& server;