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