ffbec87aadc82889c204e9b72c54bd4bfc863b89
[platform/core/security/ode.git] / server / luks.cpp
1 /*
2  *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 #include <unistd.h>
17 #include <thread>
18 #include <klay/dbus/connection.h>
19 #include <map>
20
21 #include "logger.h"
22 #include "luks.h"
23 #include "engine/encryption/cryptsetup-engine.h"
24 #include "rmi/common.h"
25
26 namespace ode {
27
28 namespace {
29 const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
30
31 std::map<Luks::Operation, std::string> OPERATION_NAME = {
32         { Luks::Format, "Formatting" },
33         { Luks::Open,   "Opening" },
34         { Luks::Close,  "Closing" },
35 };
36
37 std::map<CryptsetupEngine::ReturnCode, int> CRYPTSETUP_ERROR_2_ODE_ERROR = {
38         { CryptsetupEngine::ReturnCode::SUCCESS, error::None },
39         { CryptsetupEngine::ReturnCode::WRONG_PARAMS, error::InvalidParameter },
40         { CryptsetupEngine::ReturnCode::NO_PERMISSION, error::WrongPassword },
41         { CryptsetupEngine::ReturnCode::OUT_OF_MEMORY, error::OutOfMemory },
42         { CryptsetupEngine::ReturnCode::WRONG_DEVICE, error::NoSuchFile },
43         { CryptsetupEngine::ReturnCode::DEVICE_BUSY, error::DeviceBusy }
44 };
45
46 } // anonymous namespace
47
48 LuksServer::LuksServer(ServerContext &srv, KeyServer& key) :
49         server(srv),
50         keyServer(key)
51 {
52         server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::format)(bool, std::string, std::string));
53         server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::open)(bool, std::string, std::string, std::string));
54         server.expose(this, PRIVILEGE_PLATFORM, (int)(LuksServer::close)(bool, std::string));
55
56         server.createNotification(NOTIFICATION);
57 }
58
59 LuksServer::~LuksServer()
60 {
61 }
62
63 template <typename F>
64 int LuksServer::execute(bool sync, Luks::Operation op, const F& job)
65 {
66         auto worker = [=]() {
67                 int ret = error::Unknown;
68                 try {
69                         std::lock_guard<std::mutex> guardLock(opGuard);
70                         ret = job();
71                 } catch (const CryptsetupEngine::Exception& e) {
72                         ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
73                                                 std::string(e.what()));
74                         auto it = CRYPTSETUP_ERROR_2_ODE_ERROR.find(e.retCode());
75                         if (it != CRYPTSETUP_ERROR_2_ODE_ERROR.end())
76                                 ret = it->second;
77                 } catch (const std::exception& e) {
78                         ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
79                                         std::string(e.what()));
80                         ret = error::Unknown;
81                 } catch (...) {
82                         ERROR(SINK, OPERATION_NAME.at(op) +
83                                         " thread failed: unknown exception.");
84                         ret = error::Unknown;
85                 }
86                 if (sync) {
87                         return ret;
88                 } else {
89                         server.notify(NOTIFICATION, static_cast<int>(op), ret);
90                         return error::None;
91                 }
92         };
93
94         if (sync) {
95                 return worker();
96         } else {
97                 std::thread work(worker);
98                 work.detach();
99                 return error::None;
100         }
101 }
102
103 int LuksServer::format(bool sync,
104                                            const std::string& device,
105                                            const std::string& password)
106 {
107         return execute(sync, Luks::Format, [=](){
108                 BinaryData key;
109                 int ret = keyServer.initAndGet(device, password, Key::DEFAULT_512BIT, key);
110                 if (ret != error::None)
111                         return ret;
112
113                 CryptsetupEngine engine(device);
114                 engine.format(CryptsetupEngine::DeviceType::LUKS, key);
115                 return error::None;
116         });
117 }
118
119 int LuksServer::open(bool sync,
120                                          const std::string& device,
121                                          const std::string& password,
122                                          const std::string& mapping)
123 {
124         return execute(sync, Luks::Open, [=](){
125                 CryptsetupEngine engine(device);
126
127                 BinaryData key;
128                 int ret = keyServer.get(device, password, key);
129                 if (ret != error::None)
130                         return ret;
131
132                 engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, key);
133                 return error::None;
134         });
135 }
136
137 int LuksServer::close(bool sync,
138                                           const std::string& mapping)
139 {
140         return execute(sync, Luks::Close, [=](){
141                 CryptsetupEngine::close(mapping);
142                 return error::None;
143         });
144 }
145
146 } // namespace ode