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/audit/logger.h>
30 #include "launchpad.h"
31 #include "app-bundle.h"
32 #include "engine/ecryptfs-engine.h"
33 #include "key-manager/key-manager.h"
34 #include <klay/dbus/variant.h>
35 #include <klay/dbus/connection.h>
37 #include "rmi/external-encryption.h"
38 #include "progress-bar.h"
39 #include "progress-vconf-backend.h"
41 #define EXTERNAL_STORAGE_PATH "/opt/media/SDCardA1"
42 #define DEFAULT_USER "owner"
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 VConfBackend vconfBackend(VCONFKEY_SDE_ENCRYPT_PROGRESS);
54 ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
56 EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH, progressBar);
58 void killDependedApplications()
60 for (pid_t pid : runtime::FileUser::getList(EXTERNAL_STORAGE_PATH, true)) {
61 INFO("Close process - " + std::to_string(pid));
66 void externalCallback(dbus::Variant parameters)
71 parameters.get("(issssssisibii)",
72 &intparams[0], // block type: 0 - scsi, 1 : mmc
73 &strparams[0], // devnode
74 &strparams[1], // syspath
75 &strparams[2], // usage
76 &strparams[3], // fs type
77 &strparams[4], // fs version
78 &strparams[5], // fs uuid enc
79 &intparams[1], // readonly: 0 - rw, 1 - ro
80 &strparams[6], // mount point
81 &intparams[2], // state: 0 - unmount, 1 - mount
82 &intparams[3], // primary: 0 - flase, 1 - true
83 &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
84 &intparams[5]); // strage id
86 if(intparams[2] == 0) {
90 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
92 std::string valueStr(value);
94 if (valueStr == "encrypted") {
96 INFO("Launch SD card password popup");
98 bundle.add("viewtype", "SD_CARD_PASSWORD");
100 Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
101 launchpad.launch("org.tizen.ode", bundle);
102 } catch (runtime::Exception &e) {
103 ERROR("Failed to launch SD card password popup");
110 void externalAddEventReceiver()
112 dbus::Connection &systemDBus = dbus::Connection::getSystem();
114 systemDBus.subscribeSignal("",
115 "/Org/Tizen/System/Storage/Block/Manager",
116 "org.tizen.system.storage.BlockManager",
121 unsigned int getOptions()
123 unsigned int result = 0;
127 ::vconf_get_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, &value);
129 result |= ExternalEncryption::Option::OnlyNewFile;
133 ::vconf_get_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, &value);
135 result |= ExternalEncryption::Option::ExceptForMediaFile;
141 void setOptions(unsigned int options)
145 if (options & ExternalEncryption::Option::OnlyNewFile) {
150 ::vconf_set_bool(EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY, value);
152 if (options & ExternalEncryption::Option::ExceptForMediaFile) {
157 ::vconf_set_bool(EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY, value);
162 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
165 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::mount)(std::string));
166 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::umount)());
167 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::encrypt)(std::string, unsigned int));
168 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::decrypt)(std::string));
169 context.expose(this, "", (int)(ExternalEncryption::isPasswordInitialized)());
170 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::initPassword)(std::string));
171 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::cleanPassword)(std::string));
172 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::changePassword)(std::string, std::string));
173 context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::verifyPassword)(std::string));
174 context.expose(this, "", (int)(ExternalEncryption::getState)());
175 context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
177 externalAddEventReceiver();
180 ExternalEncryption::~ExternalEncryption()
184 int ExternalEncryption::mount(const std::string &password)
186 if (getState() != State::Encrypted) {
190 KeyManager::data data(password.begin(), password.end());
191 KeyManager keyManager(engine.getKeyMeta());
193 if (!keyManager.verifyPassword(data)) {
197 engine.mount(keyManager.getMasterKey(data), getOptions());
201 int ExternalEncryption::umount()
203 if (getState() != State::Encrypted) {
207 INFO("Close all applications using external storage...");
208 killDependedApplications();
209 INFO("Umount external storage...");
215 int ExternalEncryption::encrypt(const std::string &password, unsigned int options)
217 if (getState() != State::Unencrypted) {
221 KeyManager::data pwData(password.begin(), password.end());
222 KeyManager keyManager(engine.getKeyMeta());
224 if (!keyManager.verifyPassword(pwData)) {
228 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
229 auto encryptWorker = [MasterKey, options, this]() {
231 INFO("Close all applications using external storage...");
232 killDependedApplications();
233 INFO("Encryption started...");
234 ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
235 engine.encrypt(MasterKey, options);
236 setOptions(options & getSupportedOptions());
237 INFO("Sync disk...");
239 INFO("Encryption completed");
240 ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "encrypted");
241 } catch (runtime::Exception &e) {
242 ERROR("Encryption failed - " + std::string(e.what()));
246 std::thread asyncWork(encryptWorker);
252 int ExternalEncryption::decrypt(const std::string &password)
254 if (getState() != State::Encrypted) {
258 KeyManager::data pwData(password.begin(), password.end());
259 KeyManager keyManager(engine.getKeyMeta());
261 if (!keyManager.verifyPassword(pwData)) {
265 KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
266 auto decryptWorker = [MasterKey, this]() {
268 INFO("Close all applications using external storage...");
269 killDependedApplications();
270 INFO("Umount external storage...");
275 } catch (runtime::Exception &e) {
276 killDependedApplications();
280 INFO("Decryption started...");
281 ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
282 engine.decrypt(MasterKey, getOptions());
283 INFO("Sync disk...");
285 INFO("Decryption completed");
286 ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
287 } catch (runtime::Exception &e) {
288 ERROR("Decryption failed - " + std::string(e.what()));
292 std::thread asyncWork(decryptWorker);
298 int ExternalEncryption::isPasswordInitialized()
300 if (engine.isKeyMetaSet()) {
306 int ExternalEncryption::initPassword(const std::string& password)
308 KeyManager::data pwData(password.begin(), password.end());
309 KeyManager keyManager;
311 keyManager.initPassword(pwData);
312 engine.setKeyMeta(keyManager.serialize());
316 int ExternalEncryption::cleanPassword(const std::string& password)
318 KeyManager::data pwData(password.begin(), password.end());
319 KeyManager keyManager(engine.getKeyMeta());
321 if (!keyManager.verifyPassword(pwData)) {
325 engine.clearKeyMeta();
329 int ExternalEncryption::changePassword(const std::string &oldPassword,
330 const std::string &newPassword)
332 KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
333 KeyManager::data newPwData(newPassword.begin(), newPassword.end());
334 KeyManager keyManager(engine.getKeyMeta());
336 if (!keyManager.verifyPassword(oldPwData)) {
340 keyManager.changePassword(oldPwData, newPwData);
341 engine.setKeyMeta(keyManager.serialize());
346 int ExternalEncryption::verifyPassword(const std::string& password)
348 KeyManager::data pwData(password.begin(), password.end());
349 KeyManager keyManager(engine.getKeyMeta());
351 if (keyManager.verifyPassword(pwData)) {
357 int ExternalEncryption::getState()
359 char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
361 throw runtime::Exception("Failed to get vconf value");
364 std::string valueStr(value);
367 if (valueStr == "encrypted") {
368 return State::Encrypted;
369 } else if (valueStr == "unencrypted") {
370 return State::Unencrypted;
372 return State::Corrupted;
378 unsigned int ExternalEncryption::getSupportedOptions()
380 return engine.getSupportedOptions();