Revert "Revert "Add CryptsetupEngine""
[platform/core/security/ode.git] / server / external-encryption.cpp
1 /*
2  *  Copyright (c) 2015 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 <fstream>
17 #include <sstream>
18
19 #include <signal.h>
20 #include <unistd.h>
21 #include <sys/mount.h>
22
23 #include <vconf.h>
24 #include <tzplatform_config.h>
25
26 #include <klay/file-user.h>
27 #include <klay/filesystem.h>
28 #include <klay/dbus/variant.h>
29 #include <klay/dbus/connection.h>
30
31 #include "vconf.h"
32 #include "logger.h"
33 #include "launchpad.h"
34 #include "app-bundle.h"
35 #include "progress-bar.h"
36 #include "engine/encryption/ecryptfs-engine.h"
37 #include "key-manager/key-manager.h"
38
39 #include "rmi/external-encryption.h"
40
41 #define EXTERNAL_ENGINE EcryptfsEngine
42 #define EXTERNAL_PATH   "/opt/media/SDCardA1"
43 #define EXTERNAL_STATE_VCONF_KEY VCONFKEY_SDE_CRYPTO_STATE
44 #define EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY VCONFKEY_SDE_ENCRYPT_NEWFILE
45 #define EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY VCONFKEY_SDE_EXCLUDE_MEDIAFILE
46
47 #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
48
49 namespace ode {
50
51 namespace {
52
53 std::unique_ptr<EXTERNAL_ENGINE> engine;
54 KeyManager::data mountKey;
55
56 void killDependedApplications()
57 {
58         for (pid_t pid : runtime::FileUser::getList(EXTERNAL_PATH, true)) {
59                 INFO(SINK, "Close process - " + std::to_string(pid));
60                 ::kill(pid, SIGKILL);
61         }
62 }
63
64 void externalCallback(dbus::Variant parameters)
65 {
66         int intparams[6];
67         char* strparams[7];
68
69         parameters.get("(issssssisibii)",
70                 &intparams[0], // block type: 0 - scsi, 1 : mmc
71                 &strparams[0], // devnode
72                 &strparams[1], // syspath
73                 &strparams[2], // usage
74                 &strparams[3], // fs type
75                 &strparams[4], // fs version
76                 &strparams[5], // fs uuid enc
77                 &intparams[1], // readonly: 0 - rw, 1 - ro
78                 &strparams[6], // mount point
79                 &intparams[2], // state: 0 - unmount, 1 - mount
80                 &intparams[3], // primary: 0 - flase, 1 - true
81                 &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
82                 &intparams[5]); // strage id
83
84         if(intparams[2] == 0) {
85                 INFO(SINK, "Unmounted");
86         } else {
87                 INFO(SINK, "Mounted");
88                 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
89                 if (value != NULL) {
90                         std::string valueStr(value);
91                         free(value);
92                         if (valueStr == "encrypted") {
93                                 try {
94                                         INFO(SINK, "Launch SD card password popup");
95                                         AppBundle bundle;
96                                         bundle.add("viewtype", "SD_CARD_PASSWORD");
97
98                                         Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
99                                         launchpad.launch("org.tizen.ode", bundle);
100                                 } catch (runtime::Exception &e) {
101                                         ERROR(SINK, "Failed to launch SD card password popup");
102                                 }
103                         }
104                 }
105         }
106 }
107
108 void externalAddEventReceiver()
109 {
110         dbus::Connection &systemDBus = dbus::Connection::getSystem();
111
112         systemDBus.subscribeSignal("",
113                                                                 "/Org/Tizen/System/Storage/Block/Manager",
114                                                                 "org.tizen.system.storage.BlockManager",
115                                                                 "DeviceChanged",
116                                                                 externalCallback);
117 }
118
119 unsigned int getOptions()
120 {
121         unsigned int result = 0;
122         int value;
123
124         value = 0;
125         ::vconf_get_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, &value);
126         if (value) {
127                 result |= ExternalEncryption::Option::OnlyNewFile;
128         }
129
130         value = 0;
131         ::vconf_get_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, &value);
132         if (value) {
133                 result |= ExternalEncryption::Option::ExceptForMediaFile;
134         }
135
136         return result;
137 }
138
139 void setOptions(unsigned int options)
140 {
141         bool value;
142
143         if (options & ExternalEncryption::Option::OnlyNewFile) {
144                 value = true;
145         } else {
146                 value = false;
147         }
148         ::vconf_set_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, value);
149
150         if (options & ExternalEncryption::Option::ExceptForMediaFile) {
151                 value = true;
152         } else {
153                 value = false;
154         }
155         ::vconf_set_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, value);
156 }
157
158 } // namsepace
159
160 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
161         context(ctx)
162 {
163         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::setMountPassword)(std::string));
164         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::mount)());
165         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::umount)());
166         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::encrypt)(std::string, unsigned int));
167         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::decrypt)(std::string));
168         context.expose(this, "", (int)(ExternalEncryption::isPasswordInitialized)());
169         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::initPassword)(std::string));
170         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::cleanPassword)(std::string));
171         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::changePassword)(std::string, std::string));
172         context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::verifyPassword)(std::string));
173         context.expose(this, "", (int)(ExternalEncryption::getState)());
174         context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
175
176         context.createNotification("ExternalEncryption::mount");
177
178         engine.reset(new EXTERNAL_ENGINE(
179                 EXTERNAL_PATH, EXTERNAL_PATH,
180                 ProgressBar([](int v) {
181                 ::vconf_set_str(VCONFKEY_SDE_ENCRYPT_PROGRESS,
182                                                 std::to_string(v).c_str());
183                 })
184         ));
185
186         externalAddEventReceiver();
187 }
188
189 ExternalEncryption::~ExternalEncryption()
190 {
191 }
192
193
194 int ExternalEncryption::setMountPassword(const std::string& password)
195 {
196         KeyManager::data pwData(password.begin(), password.end());
197         KeyManager keyManager(engine->getKeyMeta());
198         if (!keyManager.verifyPassword(pwData)) {
199                 return -2;
200         }
201
202         ode::mountKey = keyManager.getMasterKey(pwData);
203
204         return 0;
205 }
206
207 int ExternalEncryption::mount()
208 {
209         if (getState() != State::Encrypted) {
210                 return -1;
211         }
212
213         if (engine->isMounted()) {
214                 INFO(SINK, "Already mounted");
215                 return 0;
216         }
217
218         engine->mount(mountKey, getOptions());
219         mountKey.clear();
220
221         context.notify("ExternalEncryption::mount");
222
223         return 0;
224 }
225
226 int ExternalEncryption::umount()
227 {
228         if (getState() != State::Encrypted) {
229                 return -1;
230         }
231
232         if (!engine->isMounted()) {
233                 INFO(SINK, "Already umounted");
234                 return 0;
235         }
236
237         INFO(SINK, "Close all applications using external storage...");
238         killDependedApplications();
239         INFO(SINK, "Umount external storage...");
240         engine->umount();
241
242         return 0;
243 }
244
245 int ExternalEncryption::encrypt(const std::string &password, unsigned int options)
246 {
247         if (getState() != State::Unencrypted) {
248                 return -1;
249         }
250
251         KeyManager::data pwData(password.begin(), password.end());
252         KeyManager keyManager(engine->getKeyMeta());
253
254         if (!keyManager.verifyPassword(pwData)) {
255                 return -2;
256         }
257
258         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
259         auto encryptWorker = [MasterKey, options, this]() {
260                 try {
261                         INFO(SINK, "Close all applications using external storage...");
262                         killDependedApplications();
263                         INFO(SINK, "Encryption started...");
264                         engine->encrypt(MasterKey, options);
265                         setOptions(options & getSupportedOptions());
266                         INFO(SINK, "Sync disk...");
267                         sync();
268                         INFO(SINK, "Encryption completed");
269                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "encrypted");
270                         context.notify("ExternalEncryption::mount");
271                 } catch (runtime::Exception &e) {
272                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
273                         ERROR(SINK, "Encryption failed - " + std::string(e.what()));
274                 }
275         };
276
277         std::thread asyncWork(encryptWorker);
278         asyncWork.detach();
279
280         return 0;
281 }
282
283 int ExternalEncryption::decrypt(const std::string &password)
284 {
285         if (getState() != State::Encrypted) {
286                 return -1;
287         }
288
289         KeyManager::data pwData(password.begin(), password.end());
290         KeyManager keyManager(engine->getKeyMeta());
291
292         if (!keyManager.verifyPassword(pwData)) {
293                 return -2;
294         }
295
296         KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
297         auto decryptWorker = [MasterKey, this]() {
298                 try {
299                         INFO(SINK, "Close all applications using external storage...");
300                         killDependedApplications();
301                         INFO(SINK, "Umount external storage...");
302                         while (1) {
303                                 try {
304                                         engine->umount();
305                                         break;
306                                 } catch (runtime::Exception &e) {
307                                         killDependedApplications();
308                                 }
309                         }
310
311                         INFO(SINK, "Decryption started...");
312                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
313                         engine->decrypt(MasterKey, getOptions());
314                         INFO(SINK, "Sync disk...");
315                         sync();
316                         INFO(SINK, "Decryption completed");
317                         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
318                 } catch (runtime::Exception &e) {
319                         ERROR(SINK, "Decryption failed - " + std::string(e.what()));
320                 }
321         };
322
323         std::thread asyncWork(decryptWorker);
324         asyncWork.detach();
325
326         return 0;
327 }
328
329 int ExternalEncryption::recovery()
330 {
331         if (getState() == State::Unencrypted) {
332                 return -1;
333         }
334
335         for (runtime::DirectoryIterator iter(engine->getSource()), end;
336                         iter != end; ++iter) {
337                 iter->remove(true);
338         }
339
340         engine->clearKeyMeta();
341         ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
342
343         return 0;
344 }
345
346 int ExternalEncryption::isPasswordInitialized()
347 {
348         if (engine->isKeyMetaSet()) {
349                 return 1;
350         }
351         return 0;
352 }
353
354 int ExternalEncryption::initPassword(const std::string& password)
355 {
356         KeyManager::data pwData(password.begin(), password.end());
357         KeyManager keyManager;
358
359         keyManager.initPassword(pwData);
360         engine->setKeyMeta(keyManager.serialize());
361         return 0;
362 }
363
364 int ExternalEncryption::cleanPassword(const std::string& password)
365 {
366         KeyManager::data pwData(password.begin(), password.end());
367         KeyManager keyManager(engine->getKeyMeta());
368
369         if (!keyManager.verifyPassword(pwData)) {
370                 return -2;
371         }
372
373         engine->clearKeyMeta();
374         return 0;
375 }
376
377 int ExternalEncryption::changePassword(const std::string &oldPassword,
378                                                                            const std::string &newPassword)
379 {
380         KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
381         KeyManager::data newPwData(newPassword.begin(), newPassword.end());
382         KeyManager keyManager(engine->getKeyMeta());
383
384         if (!keyManager.verifyPassword(oldPwData)) {
385                 return -2;
386         }
387
388         keyManager.changePassword(oldPwData, newPwData);
389         engine->setKeyMeta(keyManager.serialize());
390
391         return 0;
392 }
393
394 int ExternalEncryption::verifyPassword(const std::string& password)
395 {
396         KeyManager::data pwData(password.begin(), password.end());
397         KeyManager keyManager(engine->getKeyMeta());
398
399         if (keyManager.verifyPassword(pwData)) {
400                 return 1;
401         }
402         return 0;
403 }
404
405 int ExternalEncryption::getState()
406 {
407         char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
408         if (value == NULL) {
409                 throw runtime::Exception("Failed to get vconf value");
410         }
411
412         std::string valueStr(value);
413         free(value);
414
415         if (valueStr == "encrypted") {
416                 return State::Encrypted;
417         } else if (valueStr == "unencrypted") {
418                 return State::Unencrypted;
419         } else {
420                 return State::Corrupted;
421         }
422
423         return 0;
424 }
425
426 unsigned int ExternalEncryption::getSupportedOptions()
427 {
428         return engine->getSupportedOptions();
429 }
430
431 } // namespace ode