2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
20 #include <sys/mount.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>
31 #include "launchpad.h"
32 #include "app-bundle.h"
33 #include "progress-bar.h"
34 #include "rmi/common.h"
35 #include "file-footer.h"
37 #include "external-encryption.h"
44 bool isBootCompleted = false;
46 const char *EXTERNAL_PATH = "/media/SDCardA1";
47 const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
51 INFO(SINK, "Launching SD card password popup.");
54 bundle.add("viewtype", "SD_CARD_PASSWORD");
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()));
63 void externalCallback(dbus::Variant parameters)
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
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.");
89 if(intparams[2] == 0) {
90 INFO(SINK, "SD card not mounted, ignoring.");
92 INFO(SINK, "SD card mounted.");
93 char *value = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
95 std::string valueStr(value);
97 if (valueStr == "encrypted" && isBootCompleted) {
104 void bootCompletionCallback(dbus::Variant parameters)
106 auto waitForHomescreen = []() {
107 //For a delay until homescreen is totally loaded
110 INFO(SINK, "Boot completed.");
112 char *value = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
114 std::string valueStr(value);
116 if (valueStr == "encrypted") {
120 isBootCompleted = true;
123 std::thread asyncWork(waitForHomescreen);
127 void externalAddEventReceiver()
129 dbus::Connection &systemDBus = dbus::Connection::getSystem();
131 systemDBus.subscribeSignal("",
132 "/Org/Tizen/System/Storage/Block/Manager",
133 "org.tizen.system.storage.BlockManager",
137 systemDBus.subscribeSignal("",
138 "/Org/Tizen/System/Pass/Core",
139 "org.tizen.system.pass.core",
141 bootCompletionCallback);
144 unsigned int getOptions()
146 unsigned int result = 0;
150 ::vconf_get_bool(VCONFKEY_SDE_EXCLUDE_MEDIAFILE, &value);
152 result |= ExternalEncryption::Option::OnlyNewFile;
156 ::vconf_get_bool(VCONFKEY_SDE_ENCRYPT_NEWFILE, &value);
158 result |= ExternalEncryption::Option::ExceptForMediaFile;
164 void setOptions(unsigned int options)
168 if (options & ExternalEncryption::Option::OnlyNewFile) {
173 ::vconf_set_bool(VCONFKEY_SDE_EXCLUDE_MEDIAFILE, value);
175 if (options & ExternalEncryption::Option::ExceptForMediaFile) {
180 ::vconf_set_bool(VCONFKEY_SDE_ENCRYPT_NEWFILE, value);
185 ExternalEncryptionServer::ExternalEncryptionServer(ServerContext &srv,
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)());
205 server.createNotification("ExternalEncryptionServer::mount");
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());
215 externalAddEventReceiver();
218 ExternalEncryptionServer::~ExternalEncryptionServer()
222 int ExternalEncryptionServer::setMountPassword(const std::string& password)
224 return keyServer.get(engine->getSource(), password, mountKey);
227 int ExternalEncryptionServer::mount()
229 if (mountKey.empty()) {
230 ERROR(SINK, "You need to call set_mount_password() first.");
231 return error::NoData;
234 BinaryData key = mountKey;
237 if (getState() != State::Encrypted) {
238 ERROR(SINK, "Cannot mount, SD card's state incorrect.");
239 return error::NoSuchDevice;
242 if (engine->isMounted()) {
243 INFO(SINK, "SD card already mounted.");
247 INFO(SINK, "Mounting external storage.");
249 engine->mount(key, getOptions());
250 } catch (runtime::Exception &e) {
251 ERROR(SINK, "Failed to mount: " + std::string(e.what()));
252 return error::Unknown;
255 server.notify("ExternalEncryptionServer::mount");
260 int ExternalEncryptionServer::umount()
262 if (getState() != State::Encrypted) {
263 ERROR(SINK, "Cannot umount, SD card's state incorrect.");
264 return error::NoSuchDevice;
267 if (!engine->isMounted()) {
268 INFO(SINK, "SD card already umounted.");
272 INFO(SINK, "Closing all applications using external storage.");
273 killDependentApplications(EXTERNAL_PATH);
275 INFO(SINK, "Umounting external storage.");
278 } catch (runtime::Exception &e) {
279 ERROR(SINK, "Failed to umount: " + std::string(e.what()));
280 return error::Unknown;
286 int ExternalEncryptionServer::encrypt(const std::string &password, unsigned int options)
288 if (getState() != State::Unencrypted) {
289 INFO(SINK, "Cannot encrypt, SD card's state incorrect.");
290 return error::NoSuchDevice;
293 BinaryData masterKey;
294 int ret = keyServer.get(engine->getSource(), password, masterKey);
295 if (ret != error::None)
298 auto encryptWorker = [masterKey, options, this]() {
300 INFO(SINK, "Closing all applications using external storage.");
301 killDependentApplications(EXTERNAL_PATH);
303 INFO(SINK, "Encryption started.");
304 engine->encrypt(masterKey, options);
305 setOptions(options & getSupportedOptions());
307 INFO(SINK, "Encryption completed.");
308 ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "encrypted");
309 server.notify("ExternalEncryptionServer::mount");
311 INFO(SINK, "Syncing disk.");
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()));
319 std::thread asyncWork(encryptWorker);
325 int ExternalEncryptionServer::decrypt(const std::string &password)
327 if (getState() != State::Encrypted) {
328 ERROR(SINK, "Cannot decrypt, SD card's state incorrect.");
329 return error::NoSuchDevice;
332 BinaryData masterKey;
333 int ret = keyServer.get(engine->getSource(), password, masterKey);
334 if (ret != error::None)
337 auto decryptWorker = [masterKey, this]() {
339 INFO(SINK, "Closing all applications using external storage.");
340 killDependentApplications(EXTERNAL_PATH);
342 INFO(SINK, "Umounting external storage.");
347 } catch (runtime::Exception &e) {
348 killDependentApplications(EXTERNAL_PATH);
352 INFO(SINK, "Decryption started.");
353 ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "error_partially_decrypted");
354 engine->decrypt(masterKey, getOptions());
356 INFO(SINK, "Decryption completed.");
357 ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
359 INFO(SINK, "Syncing disk.");
361 } catch (runtime::Exception &e) {
362 ERROR(SINK, "Decryption failed: " + std::string(e.what()));
366 std::thread asyncWork(decryptWorker);
372 int ExternalEncryptionServer::recovery()
374 if (getState() == State::Unencrypted) {
375 return error::NoSuchDevice;
378 for (runtime::DirectoryIterator iter(engine->getSource()), end;
379 iter != end; ++iter) {
383 keyServer.removePassword(engine->getSource());
384 ::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
389 int ExternalEncryptionServer::isPasswordInitialized()
391 return keyServer.isInitialized(engine->getSource());
394 int ExternalEncryptionServer::initPassword(const std::string& password)
396 return keyServer.init(engine->getSource(), password, Key::DEFAULT_256BIT);
399 int ExternalEncryptionServer::cleanPassword(const std::string& password)
401 return keyServer.remove(engine->getSource(), password);
404 int ExternalEncryptionServer::changePassword(const std::string &oldPassword,
405 const std::string &newPassword)
407 return keyServer.changePassword(engine->getSource(), oldPassword, newPassword);
410 int ExternalEncryptionServer::verifyPassword(const std::string& password)
412 return keyServer.verifyPassword(engine->getSource(), password);
415 int ExternalEncryptionServer::getState()
417 char *value = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
419 throw runtime::Exception("Failed to get vconf value.");
422 std::string valueStr(value);
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;
432 return State::Invalid;
435 unsigned int ExternalEncryptionServer::getSupportedOptions()
437 return engine->getSupportedOptions();
440 std::string ExternalEncryptionServer::getDevicePath() const
442 return engine->getSource();