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
21 #include <sys/mount.h>
24 #include <tzplatform_config.h>
26 #include <klay/file-user.h>
27 #include <klay/filesystem.h>
28 #include <klay/dbus/variant.h>
29 #include <klay/dbus/connection.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"
39 #include "rmi/external-encryption.h"
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
47 #define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
53 std::unique_ptr<EXTERNAL_ENGINE> engine;
54 KeyManager::data mountKey;
56 void killDependedApplications()
58 for (pid_t pid : runtime::FileUser::getList(EXTERNAL_PATH, true)) {
59 INFO(SINK, "Close process - " + std::to_string(pid));
64 void externalCallback(dbus::Variant parameters)
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
84 if(intparams[2] == 0) {
85 INFO(SINK, "Unmounted");
87 INFO(SINK, "Mounted");
88 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
90 std::string valueStr(value);
92 if (valueStr == "encrypted") {
94 INFO(SINK, "Launch SD card password popup");
96 bundle.add("viewtype", "SD_CARD_PASSWORD");
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");
108 void externalAddEventReceiver()
110 dbus::Connection &systemDBus = dbus::Connection::getSystem();
112 systemDBus.subscribeSignal("",
113 "/Org/Tizen/System/Storage/Block/Manager",
114 "org.tizen.system.storage.BlockManager",
119 unsigned int getOptions()
121 unsigned int result = 0;
125 ::vconf_get_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, &value);
127 result |= ExternalEncryption::Option::OnlyNewFile;
131 ::vconf_get_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, &value);
133 result |= ExternalEncryption::Option::ExceptForMediaFile;
139 void setOptions(unsigned int options)
143 if (options & ExternalEncryption::Option::OnlyNewFile) {
148 ::vconf_set_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, value);
150 if (options & ExternalEncryption::Option::ExceptForMediaFile) {
155 ::vconf_set_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, value);
160 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
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)());
176 context.createNotification("ExternalEncryption::mount");
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());
186 externalAddEventReceiver();
189 ExternalEncryption::~ExternalEncryption()
194 int ExternalEncryption::setMountPassword(const std::string& password)
196 KeyManager::data pwData(password.begin(), password.end());
197 KeyManager keyManager(engine->getKeyMeta());
198 if (!keyManager.verifyPassword(pwData)) {
202 ode::mountKey = keyManager.getMasterKey(pwData);
207 int ExternalEncryption::mount()
209 if (getState() != State::Encrypted) {
213 if (engine->isMounted()) {
214 INFO(SINK, "Already mounted");
218 engine->mount(mountKey, getOptions());
221 context.notify("ExternalEncryption::mount");
226 int ExternalEncryption::umount()
228 if (getState() != State::Encrypted) {
232 if (!engine->isMounted()) {
233 INFO(SINK, "Already umounted");
237 INFO(SINK, "Close all applications using external storage...");
238 killDependedApplications();
239 INFO(SINK, "Umount external storage...");
245 int ExternalEncryption::encrypt(const std::string &password, unsigned int options)
247 if (getState() != State::Unencrypted) {
251 KeyManager::data pwData(password.begin(), password.end());
252 KeyManager keyManager(engine->getKeyMeta());
254 if (!keyManager.verifyPassword(pwData)) {
258 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
259 auto encryptWorker = [MasterKey, options, this]() {
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...");
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()));
277 std::thread asyncWork(encryptWorker);
283 int ExternalEncryption::decrypt(const std::string &password)
285 if (getState() != State::Encrypted) {
289 KeyManager::data pwData(password.begin(), password.end());
290 KeyManager keyManager(engine->getKeyMeta());
292 if (!keyManager.verifyPassword(pwData)) {
296 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
297 auto decryptWorker = [MasterKey, this]() {
299 INFO(SINK, "Close all applications using external storage...");
300 killDependedApplications();
301 INFO(SINK, "Umount external storage...");
306 } catch (runtime::Exception &e) {
307 killDependedApplications();
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...");
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()));
323 std::thread asyncWork(decryptWorker);
329 int ExternalEncryption::recovery()
331 if (getState() == State::Unencrypted) {
335 for (runtime::DirectoryIterator iter(engine->getSource()), end;
336 iter != end; ++iter) {
340 engine->clearKeyMeta();
341 ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
346 int ExternalEncryption::isPasswordInitialized()
348 if (engine->isKeyMetaSet()) {
354 int ExternalEncryption::initPassword(const std::string& password)
356 KeyManager::data pwData(password.begin(), password.end());
357 KeyManager keyManager;
359 keyManager.initPassword(pwData);
360 engine->setKeyMeta(keyManager.serialize());
364 int ExternalEncryption::cleanPassword(const std::string& password)
366 KeyManager::data pwData(password.begin(), password.end());
367 KeyManager keyManager(engine->getKeyMeta());
369 if (!keyManager.verifyPassword(pwData)) {
373 engine->clearKeyMeta();
377 int ExternalEncryption::changePassword(const std::string &oldPassword,
378 const std::string &newPassword)
380 KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
381 KeyManager::data newPwData(newPassword.begin(), newPassword.end());
382 KeyManager keyManager(engine->getKeyMeta());
384 if (!keyManager.verifyPassword(oldPwData)) {
388 keyManager.changePassword(oldPwData, newPwData);
389 engine->setKeyMeta(keyManager.serialize());
394 int ExternalEncryption::verifyPassword(const std::string& password)
396 KeyManager::data pwData(password.begin(), password.end());
397 KeyManager keyManager(engine->getKeyMeta());
399 if (keyManager.verifyPassword(pwData)) {
405 int ExternalEncryption::getState()
407 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
409 throw runtime::Exception("Failed to get vconf value");
412 std::string valueStr(value);
415 if (valueStr == "encrypted") {
416 return State::Encrypted;
417 } else if (valueStr == "unencrypted") {
418 return State::Unencrypted;
420 return State::Corrupted;
426 unsigned int ExternalEncryption::getSupportedOptions()
428 return engine->getSupportedOptions();