Luks API implementation 91/154091/9
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 2 Oct 2017 08:43:39 +0000 (10:43 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 13 Oct 2017 15:52:26 +0000 (17:52 +0200)
- Client part, RMI & Server part with callback notifications
- Extend ClientContext class to support custom notification

Change-Id: I6f049283925b2ae1934bba01ed22c21053b65555

15 files changed:
lib/CMakeLists.txt
lib/client.cpp
lib/client.h
lib/luks.cpp [new file with mode: 0644]
lib/luks.h [new file with mode: 0644]
lib/ode/luks.cpp [new file with mode: 0644]
rmi/common.h [new file with mode: 0644]
rmi/luks.h [new file with mode: 0644]
server/CMakeLists.txt
server/engine/encryption/cryptsetup-engine.cpp
server/engine/encryption/cryptsetup-engine.h
server/luks.cpp [new file with mode: 0644]
server/luks.h [new file with mode: 0644]
server/server.cpp
server/server.h

index 5e2e94d..0e208ef 100755 (executable)
@@ -23,16 +23,19 @@ SET(SOURCES client.cpp
                        internal-encryption.cpp
                        external-encryption.cpp
                        extension-encryption.cpp
+                       luks.cpp
                        ode/secure-erase.cpp
                        ode/internal-encryption.cpp
                        ode/external-encryption.cpp
                        ode/extension-encryption.cpp
+                       ode/luks.cpp
 )
 
 SET(CAPI_INCLUDE_FILES  ode/common.h
                                                ode/secure-erase.h
                                                ode/internal-encryption.h
                                                ode/external-encryption.h
+                                               ode/luks.h
 )
 
 
index a548f1a..e998a34 100644 (file)
 
 namespace {
 
-const std::string SUBSCRIBER_REGISTER = "ServerContext::registerNotificationSubscriber";
-const std::string SUBSCRIBER_UNREGISTER = "ServerContext::unregisterNotificationSubscriber";
-
-
 const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
 
 } // namespace
index 7da3a6e..6667d0c 100644 (file)
@@ -28,6 +28,9 @@ typedef std::function<void(void*)> SignalListener;
 typedef std::unique_ptr<rmi::Client> RmiClientPtr;
 
 class ClientContext final {
+       const char* SUBSCRIBER_REGISTER = "ServerContext::registerNotificationSubscriber";
+       const char* SUBSCRIBER_UNREGISTER = "ServerContext::unregisterNotificationSubscriber";
+
 public:
        ClientContext() noexcept;
        ~ClientContext() noexcept;
@@ -36,9 +39,24 @@ public:
        int connect(const std::string& address) noexcept;
        void disconnect() noexcept;
 
+       /*
+        *  TODO use more generic subscription method below in internal/external
+        *  encryption and remove this one.
+        */
        int subscribeSignal(const std::string& name, const SignalListener& listener, void* data);
        int unsubscribeSignal(int subscriberId);
 
+       template<typename ...Args>
+       int subscribeSignal(const std::string& name, const std::function<void(Args...)>& listener)
+       {
+               try {
+                       return client->subscribe<Args...>(SUBSCRIBER_REGISTER, name, listener);
+               } catch (runtime::Exception& e) {
+                       std::cout << e.what() << std::endl;
+                       return -1;
+               }
+       }
+
        template<typename Interface, typename... Args>
        Interface createInterface(Args&&... args) noexcept
        {
diff --git a/lib/luks.cpp b/lib/luks.cpp
new file mode 100644 (file)
index 0000000..ea9104e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  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 "luks.h"
+
+namespace ode {
+
+LuksClient::LuksClient(RmiClientPtr& ctx) : context(ctx)
+{
+}
+
+LuksClient::~LuksClient()
+{
+}
+
+int LuksClient::format(const std::string& device, const std::string& password)
+{
+       try {
+               return context->methodCall<int>("LuksServer::format", device, password);
+       } catch (runtime::Exception& e) {
+               return -1;
+       }
+}
+
+int LuksClient::open(const std::string& device,
+                                        const std::string& password,
+                                        const std::string& mapping)
+{
+       try {
+               return context->methodCall<int>("LuksServer::open", device, password, mapping);
+       } catch (runtime::Exception& e) {
+               return -1;
+       }
+}
+
+int LuksClient::close(const std::string& mapping)
+{
+       try {
+               return context->methodCall<int>("LuksServer::close", mapping);
+       } catch (runtime::Exception& e) {
+               return -1;
+       }
+}
+
+} // namespace ode
diff --git a/lib/luks.h b/lib/luks.h
new file mode 100644 (file)
index 0000000..ef26679
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  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
+ */
+
+#ifndef __ODE_LUKS_CLIENT_H__
+#define __ODE_LUKS_CLIENT_H__
+
+#include "rmi/luks.h"
+#include "client.h"
+
+namespace ode {
+
+class LuksClient final: public Luks {
+public:
+       explicit LuksClient(RmiClientPtr& ctxt);
+       ~LuksClient();
+
+       int format(const std::string& device, const std::string& password);
+
+       int open(const std::string& device,
+                        const std::string& password,
+                        const std::string& mapping);
+
+       int close(const std::string& mapping);
+
+private:
+       RmiClientPtr& context;
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_CLIENT_H__
diff --git a/lib/ode/luks.cpp b/lib/ode/luks.cpp
new file mode 100644 (file)
index 0000000..4058ecf
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  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 <map>
+
+#include "debug.h"
+#include "luks.h"
+#include "client.h"
+#include "lib/luks.h"
+#include "rmi/common.h"
+
+using namespace ode;
+
+namespace {
+std::unique_ptr<ClientContext> luksEventCallbackContext;
+
+// TODO Extend it and make it common for whole API
+std::map<OdeError, int> ODE_ERROR_TO_API_ERROR = {
+               { OdeError::None, ODE_ERROR_NONE },
+               { OdeError::InvalidParameter, ODE_ERROR_INVALID_PARAMETER },
+               { OdeError::WrongPassword, ODE_ERROR_KEY_REJECTED },
+               { OdeError::OutOfMemory, ODE_ERROR_OUT_OF_MEMORY },
+               { OdeError::NoSuchFile, ODE_ERROR_NO_SUCH_FILE },
+               { OdeError::DeviceBusy, ODE_ERROR_RESOURCE_BUSY },
+               { OdeError::Unknown, ODE_ERROR_UNKNOWN }
+};
+} // anonymous namespace
+
+int ode_luks_format(const char* device, const char* password)
+{
+       RET_ON_FAILURE(device, ODE_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(password, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       LuksClient luks = client.createInterface<LuksClient>();
+
+       return luks.format(device, password);
+}
+
+int ode_luks_open(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);
+       RET_ON_FAILURE(mapping, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       LuksClient luks = client.createInterface<LuksClient>();
+
+       return luks.open(device, password, mapping);
+}
+
+int ode_luks_close(const char* mapping)
+{
+       RET_ON_FAILURE(mapping, ODE_ERROR_INVALID_PARAMETER);
+
+       ClientContext client;
+       RET_ON_FAILURE(client.connect() == 0, ODE_ERROR_CONNECTION_REFUSED);
+       LuksClient luks = client.createInterface<LuksClient>();
+
+       return luks.close(mapping);
+}
+
+int ode_luks_set_event_cb(ode_luks_event_cb callback, void *user_data)
+{
+       int ret;
+
+       RET_ON_FAILURE(callback, ODE_ERROR_INVALID_PARAMETER);
+
+       luksEventCallbackContext.reset(new ClientContext);
+       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);
+       };
+
+       ret = luksEventCallbackContext->subscribeSignal(Luks::NOTIFICATION, cb);
+       RET_ON_FAILURE(ret >= 0, ODE_ERROR_INVALID_PARAMETER);
+
+       return ODE_ERROR_NONE;
+}
+
+void ode_luks_unset_event_cb()
+{
+       luksEventCallbackContext.reset();
+}
+
diff --git a/rmi/common.h b/rmi/common.h
new file mode 100644 (file)
index 0000000..43336b0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  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
+ */
+/*
+ * @file       common.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef __ODE_COMMON_H__
+#define __ODE_COMMON_H__
+
+namespace ode {
+
+enum class OdeError {
+       None = 0,
+       InvalidParameter,
+       WrongPassword,
+       OutOfMemory,
+       NoSuchFile,
+       DeviceBusy,
+       Unknown
+};
+
+} // namespace ode
+
+#endif // __ODE_COMMON_H__
diff --git a/rmi/luks.h b/rmi/luks.h
new file mode 100644 (file)
index 0000000..d2a3c1b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  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
+ */
+
+#ifndef __ODE_LUKS_H__
+#define __ODE_LUKS_H__
+
+#include <string>
+
+namespace ode {
+
+/**
+ * This class provides APIs to perform luks operations.
+ */
+
+class Luks {
+public:
+       virtual int format(const std::string& device,
+                                          const std::string& password) = 0;
+
+       virtual int open(const std::string& device,
+                                        const std::string& password,
+                                        const std::string& mapping) = 0;
+
+       virtual int close(const std::string& mapping) = 0;
+
+       enum Operation {
+               Format = 1,
+               Open   = 2,
+               Close  = 3
+       };
+
+       static constexpr char* const NOTIFICATION = "LUKS_NOTIFICATION";
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_H__
index 9258da2..b06f2b5 100644 (file)
@@ -26,6 +26,7 @@ SET(SERVER_SRCS       main.cpp
                                internal-encryption.cpp
                                external-encryption.cpp
                                extension-encryption.cpp
+                               luks.cpp
                                engine/encryption/ext4-engine.cpp
                                engine/encryption/dmcrypt-engine.cpp
                                engine/encryption/ecryptfs-engine.cpp
index c8c9fde..ebce939 100644 (file)
@@ -27,8 +27,6 @@
 #include <cctype>
 #include <algorithm>
 
-#include <klay/exception.h>
-
 namespace ode {
 
 namespace {
@@ -93,7 +91,9 @@ void forkAndWrite(const char *const* argv, const CryptsetupEngine::data *d)
        }
        int ret = WEXITSTATUS(status);
        if (ret != 0) {
-               throw runtime::Exception(std::string(argv[0]) + " failed with: " + std::to_string(ret));
+               throw CryptsetupEngine::Exception(
+                               std::string(argv[0]) + " failed with: " + std::to_string(ret),
+                               ret);
        }
 }
 
index 55c4658..0f6b644 100644 (file)
@@ -20,6 +20,8 @@
 #include <string>
 #include <vector>
 
+#include <klay/exception.h>
+
 namespace ode {
 
 class CryptsetupEngine final {
@@ -29,6 +31,27 @@ public:
                LUKS,
        };
 
+       enum class ReturnCode {
+               SUCCESS = 0,
+               WRONG_PARAMS = 1,
+               NO_PERMISSION = 2,
+               OUT_OF_MEMORY = 3,
+               WRONG_DEVICE = 4,
+               DEVICE_BUSY = 5
+       };
+
+       class Exception : public runtime::Exception {
+       public:
+               Exception(const std::string& what, int r) :
+                       runtime::Exception(what),
+                       ret(static_cast<ReturnCode>(r))
+               {}
+
+               ReturnCode retCode() const { return ret; }
+       private:
+               ReturnCode ret;
+       };
+
        CryptsetupEngine(const std::string &devicePath);
        CryptsetupEngine(const CryptsetupEngine &) = delete;
        CryptsetupEngine(CryptsetupEngine &&) = delete;
diff --git a/server/luks.cpp b/server/luks.cpp
new file mode 100644 (file)
index 0000000..d8de637
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  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 <unistd.h>
+#include <thread>
+#include <klay/dbus/connection.h>
+#include <map>
+
+#include "logger.h"
+#include "luks.h"
+#include "key-manager/key-manager.h"
+#include "engine/encryption/cryptsetup-engine.h"
+#include "rmi/common.h"
+
+namespace ode {
+
+namespace {
+const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
+const size_t DEFAULT_KEY_SIZE = 64;
+
+std::map<Luks::Operation, std::string> OPERATION_NAME = {
+               { Luks::Format, "Formatting" },
+               { Luks::Open,   "Opening" },
+               { Luks::Close,  "Closing" },
+};
+
+std::map<CryptsetupEngine::ReturnCode, OdeError> CRYPTSETUP_ERROR_2_ODE_ERROR = {
+               { CryptsetupEngine::ReturnCode::SUCCESS, OdeError::None },
+               { CryptsetupEngine::ReturnCode::WRONG_PARAMS, OdeError::InvalidParameter },
+               { CryptsetupEngine::ReturnCode::NO_PERMISSION, OdeError::WrongPassword },
+               { CryptsetupEngine::ReturnCode::OUT_OF_MEMORY, OdeError::OutOfMemory },
+               { CryptsetupEngine::ReturnCode::WRONG_DEVICE, OdeError::NoSuchFile },
+               { CryptsetupEngine::ReturnCode::DEVICE_BUSY, OdeError::DeviceBusy }
+};
+
+} // anonymous namespace
+
+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.createNotification(NOTIFICATION);
+}
+
+LuksServer::~LuksServer()
+{
+}
+
+template <typename F>
+int LuksServer::asyncJob(Luks::Operation op, const F& job)
+{
+       auto worker = [=]() {
+               OdeError ret = OdeError::Unknown;
+               try {
+                       std::lock_guard<std::mutex> guardLock(opGuard);
+                       ret = job();
+               } catch (const CryptsetupEngine::Exception& e) {
+                       ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
+                                               std::string(e.what()));
+                       auto it = CRYPTSETUP_ERROR_2_ODE_ERROR.find(e.retCode());
+                       if (it != CRYPTSETUP_ERROR_2_ODE_ERROR.end())
+                               ret = it->second;
+               } catch (const std::exception& e) {
+                       ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
+                                       std::string(e.what()));
+                       ret = OdeError::Unknown;
+               } catch (...) {
+                       ERROR(SINK, OPERATION_NAME.at(op) +
+                                       " thread failed: unknown exception.");
+                       ret = OdeError::Unknown;
+               }
+               server.notify(NOTIFICATION, static_cast<int>(op), static_cast<int>(ret));
+       };
+
+       std::thread work(worker);
+       work.detach();
+       return 0;
+}
+
+int LuksServer::format(const std::string& device, const std::string& password)
+{
+       return asyncJob(Luks::Format, [=](){
+               KeyManager::data pwData(password.begin(), password.end());
+               KeyManager keyManager;
+               keyManager.initPassword(pwData, DEFAULT_KEY_SIZE);
+
+               CryptsetupEngine engine(device);
+               engine.setKeyMeta(keyManager.serialize());
+
+               engine.format(CryptsetupEngine::DeviceType::LUKS,
+                                         keyManager.getMasterKey(pwData));
+               return OdeError::None;
+       });
+}
+
+int LuksServer::open(const std::string& device,
+                                        const std::string& password,
+                                        const std::string& mapping)
+{
+       return asyncJob(Luks::Open, [=](){
+               CryptsetupEngine engine(device);
+
+               KeyManager::data pwData(password.begin(), password.end());
+               KeyManager keyManager(engine.getKeyMeta());
+
+               if (!keyManager.verifyPassword(pwData)) {
+                       ERROR(SINK, "Wrong password passed.");
+                       return OdeError::WrongPassword;
+               }
+
+               KeyManager::data masterKey = keyManager.getMasterKey(pwData);
+               engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, masterKey);
+               return OdeError::None;
+       });
+}
+
+int LuksServer::close(const std::string& mapping)
+{
+       return asyncJob(Luks::Close, [=](){
+               CryptsetupEngine::close(mapping);
+               return OdeError::None;
+       });
+}
+
+} // namespace ode
diff --git a/server/luks.h b/server/luks.h
new file mode 100644 (file)
index 0000000..8cc5a66
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  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
+ */
+
+#ifndef __ODE_LUKS_SERVER_H__
+#define __ODE_LUKS_SERVER_H__
+
+#include <string>
+#include <mutex>
+
+#include "rmi/luks.h"
+#include "server.h"
+
+namespace ode {
+
+class LuksServer final: public Luks {
+public:
+       explicit LuksServer(ServerContext& srv);
+       ~LuksServer();
+
+       int format(const std::string& device, const std::string& password);
+       int open(const std::string& device,
+                        const std::string& password,
+                        const std::string& mapping);
+       int close(const std::string& mapping);
+
+private:
+       template <typename F>
+       int asyncJob(Luks::Operation op, const F& job);
+
+       ServerContext& server;
+
+       std::mutex opGuard;
+};
+
+} // namespace ode
+
+#endif // __ODE_LUKS_SERVER_H__
index e69d3ea..0c2b453 100644 (file)
@@ -24,6 +24,7 @@
 #include "internal-encryption.h"
 #include "external-encryption.h"
 #include "extension-encryption.h"
+#include "luks.h"
 #include "key-manager/key-generator.h"
 #include "server.h"
 
@@ -56,6 +57,7 @@ ServerContext::ServerContext() : rmi::Service(ODE_MANAGER_ADDRESS)
        internalEncryption.reset(new InternalEncryptionServer(*this));
        externalEncryption.reset(new ExternalEncryptionServer(*this));
        extensionEncryption.reset(new ExtensionEncryptionServer(*this));
+       luks.reset(new LuksServer(*this));
 
        KeyGenerator::init();
 }
index fb12ab0..00b7f1f 100644 (file)
@@ -29,6 +29,7 @@ class SecureEraseServer;
 class InternalEncryptionServer;
 class ExternalEncryptionServer;
 class ExtensionEncryptionServer;
+class LuksServer;
 
 class ServerContext final: public rmi::Service {
 public:
@@ -45,6 +46,7 @@ private:
        std::unique_ptr<InternalEncryptionServer> internalEncryption;
        std::unique_ptr<ExternalEncryptionServer> externalEncryption;
        std::unique_ptr<ExtensionEncryptionServer> extensionEncryption;
+       std::unique_ptr<LuksServer> luks;
 };
 
 } // namespace ode