Add checking return value
[platform/core/security/ode.git] / server / luks.cpp
1 /*
2  *  Copyright (c) 2017 - 2019 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                 RequestLifetime rl(server);
68
69                 int ret = error::Unknown;
70                 try {
71                         std::lock_guard<std::mutex> guardLock(opGuard);
72                         ret = job();
73                 } catch (const CryptsetupEngine::Exception& e) {
74                         ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
75                                                 std::string(e.what()));
76                         auto it = CRYPTSETUP_ERROR_2_ODE_ERROR.find(e.retCode());
77                         if (it != CRYPTSETUP_ERROR_2_ODE_ERROR.end())
78                                 ret = it->second;
79                 } catch (const std::exception& e) {
80                         ERROR(SINK, OPERATION_NAME.at(op) + " thread failed: " +
81                                         std::string(e.what()));
82                         ret = error::Unknown;
83                 } catch (...) {
84                         ERROR(SINK, OPERATION_NAME.at(op) +
85                                         " thread failed: unknown exception.");
86                         ret = error::Unknown;
87                 }
88                 if (sync) {
89                         return ret;
90                 } else {
91                         server.notify(NOTIFICATION, static_cast<int>(op), ret);
92                         return error::None;
93                 }
94         };
95
96         if (sync) {
97                 return worker();
98         } else {
99                 std::thread work(worker);
100                 work.detach();
101                 return error::None;
102         }
103 }
104
105 int LuksServer::format(bool sync,
106                                            const std::string& device,
107                                            const std::string& password)
108 {
109         return execute(sync, Luks::Format, [=](){
110                 BinaryData key;
111                 int ret = keyServer.initAndGet(device, password, Key::DEFAULT_512BIT, key);
112                 if (ret != error::None)
113                         return ret;
114
115                 CryptsetupEngine engine(device);
116                 engine.format(CryptsetupEngine::DeviceType::LUKS, key);
117                 return error::None;
118         });
119 }
120
121 int LuksServer::open(bool sync,
122                                          const std::string& device,
123                                          const std::string& password,
124                                          const std::string& mapping)
125 {
126         return execute(sync, Luks::Open, [=](){
127                 CryptsetupEngine engine(device);
128
129                 BinaryData key;
130                 int ret = keyServer.get(device, password, key);
131                 if (ret != error::None)
132                         return ret;
133
134                 engine.open(CryptsetupEngine::DeviceType::LUKS, mapping, key);
135                 return error::None;
136         });
137 }
138
139 int LuksServer::close(bool sync,
140                                           const std::string& mapping)
141 {
142         return execute(sync, Luks::Close, [=](){
143                 CryptsetupEngine::close(mapping);
144                 return error::None;
145         });
146 }
147
148 } // namespace ode