Change not to construct classes in global
[platform/core/security/ode.git] / server / external-encryption.cpp
index 8363b6d..79001d3 100644 (file)
 #include <klay/file-user.h>
 #include <klay/filesystem.h>
 #include <klay/audit/logger.h>
+#include <klay/dbus/variant.h>
+#include <klay/dbus/connection.h>
 
+#include "vconf.h"
 #include "launchpad.h"
 #include "app-bundle.h"
+#include "progress-bar.h"
 #include "engine/ecryptfs-engine.h"
 #include "key-manager/key-manager.h"
-#include <klay/dbus/variant.h>
-#include <klay/dbus/connection.h>
 
 #include "rmi/external-encryption.h"
-#include "progress-bar.h"
-#include "progress-vconf-backend.h"
 
-#define EXTERNAL_STORAGE_PATH   "/opt/media/SDCardA1"
-#define DEFAULT_USER "owner"
+#define EXTERNAL_ENGINE        EcryptfsEngine
+#define EXTERNAL_PATH  "/opt/media/SDCardA1"
 #define EXTERNAL_STATE_VCONF_KEY VCONFKEY_SDE_CRYPTO_STATE
 #define EXTERNAL_OPTION_ONLY_NEW_FILE_VCONF_KEY VCONFKEY_SDE_ENCRYPT_NEWFILE
 #define EXTERNAL_OPTION_EXCEPT_FOR_MEDIA_FILE_VCONF_KEY VCONFKEY_SDE_EXCLUDE_MEDIAFILE
 
+#define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
+
 namespace ode {
 
 namespace {
 
-VConfBackend vconfBackend(VCONFKEY_SDE_ENCRYPT_PROGRESS);
-ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1));
-
-EcryptfsEngine engine(EXTERNAL_STORAGE_PATH, EXTERNAL_STORAGE_PATH, progressBar);
+std::unique_ptr<EXTERNAL_ENGINE> engine;
 
 void killDependedApplications()
 {
-       for (pid_t pid : runtime::FileUser::getList(EXTERNAL_STORAGE_PATH, true)) {
+       for (pid_t pid : runtime::FileUser::getList(EXTERNAL_PATH, true)) {
                INFO("Close process - " + std::to_string(pid));
                ::kill(pid, SIGKILL);
        }
@@ -63,33 +62,45 @@ void killDependedApplications()
 
 void externalCallback(dbus::Variant parameters)
 {
-       INFO("SD Card State Changed");
        int intparams[6];
        char* strparams[7];
 
        parameters.get("(issssssisibii)",
-                    &intparams[0], // block type: 0 - scsi, 1 : mmc
-                    &strparams[0], // devnode
-                    &strparams[1], // syspath
-                    &strparams[2], // usage
-                    &strparams[3], // fs type
-                    &strparams[4], // fs version
-                    &strparams[5], // fs uuid enc
-                    &intparams[1], // readonly: 0 - rw, 1 - ro
-                    &strparams[6], // mount point
-                    &intparams[2], // state: 0 - unmount, 1 - mount
-                    &intparams[3], // primary: 0 - flase, 1 - true
-                    &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
-                    &intparams[5]); // strage id
+               &intparams[0], // block type: 0 - scsi, 1 : mmc
+               &strparams[0], // devnode
+               &strparams[1], // syspath
+               &strparams[2], // usage
+               &strparams[3], // fs type
+               &strparams[4], // fs version
+               &strparams[5], // fs uuid enc
+               &intparams[1], // readonly: 0 - rw, 1 - ro
+               &strparams[6], // mount point
+               &intparams[2], // state: 0 - unmount, 1 - mount
+               &intparams[3], // primary: 0 - flase, 1 - true
+               &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly
+               &intparams[5]); // strage id
+
        if(intparams[2] == 0) {
-               INFO("Unmounted!!!");
+               INFO("Unmounted");
        } else {
-               INFO("Mounted!!!");
-               // TODO
-               // Password Popup
-//             std::string pw = "tizen";
-//             KeyManager::data data(pw.begin(), pw.end());
-//             engine.mount(keyManager.getDEK(data));
+               INFO("Mounted");
+               char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
+               if (value != NULL) {
+                       std::string valueStr(value);
+                       free(value);
+                       if (valueStr == "encrypted") {
+                               try {
+                                       INFO("Launch SD card password popup");
+                                       AppBundle bundle;
+                                       bundle.add("viewtype", "SD_CARD_PASSWORD");
+
+                                       Launchpad launchpad(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
+                                       launchpad.launch("org.tizen.ode", bundle);
+                               } catch (runtime::Exception &e) {
+                                       ERROR("Failed to launch SD card password popup");
+                               }
+                       }
+               }
        }
 }
 
@@ -98,10 +109,10 @@ void externalAddEventReceiver()
        dbus::Connection &systemDBus = dbus::Connection::getSystem();
 
        systemDBus.subscribeSignal("",
-                                                           "org.tizen.system.storage.BlockManager",
-                                                           "DeviceChanged",
-                                                           "/Org/Tizen/System/Storage/Block/Manager",
-                                                           externalCallback);
+                                                               "/Org/Tizen/System/Storage/Block/Manager",
+                                                               "org.tizen.system.storage.BlockManager",
+                                                               "DeviceChanged",
+                                                               externalCallback);
 }
 
 unsigned int getOptions()
@@ -148,17 +159,25 @@ void setOptions(unsigned int options)
 ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
        context(ctx)
 {
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::mount)(std::string));
-       context.registerNonparametricMethod(this, "", (int)(ExternalEncryption::umount));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::encrypt)(std::string, unsigned int));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::decrypt)(std::string));
-       context.registerNonparametricMethod(this, "", (int)(ExternalEncryption::isPasswordInitialized));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::initPassword)(std::string));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::cleanPassword)(std::string));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::changePassword)(std::string, std::string));
-       context.registerParametricMethod(this, "", (int)(ExternalEncryption::verifyPassword)(std::string));
-       context.registerNonparametricMethod(this, "", (int)(ExternalEncryption::getState));
-       context.registerNonparametricMethod(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::mount)(std::string));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::umount)());
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::encrypt)(std::string, unsigned int));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::decrypt)(std::string));
+       context.expose(this, "", (int)(ExternalEncryption::isPasswordInitialized)());
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::initPassword)(std::string));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::cleanPassword)(std::string));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::changePassword)(std::string, std::string));
+       context.expose(this, PRIVILEGE_PLATFORM, (int)(ExternalEncryption::verifyPassword)(std::string));
+       context.expose(this, "", (int)(ExternalEncryption::getState)());
+       context.expose(this, "", (unsigned int)(ExternalEncryption::getSupportedOptions)());
+
+       engine.reset(new EXTERNAL_ENGINE(
+               EXTERNAL_PATH, EXTERNAL_PATH,
+               ProgressBar([](int v) {
+               ::vconf_set_str(VCONFKEY_SDE_ENCRYPT_PROGRESS,
+                                               std::to_string(v).c_str());
+               })
+       ));
 
        externalAddEventReceiver();
 }
@@ -169,46 +188,64 @@ ExternalEncryption::~ExternalEncryption()
 
 int ExternalEncryption::mount(const std::string &password)
 {
+       if (getState() != State::Encrypted) {
+               return -1;
+       }
+
        KeyManager::data data(password.begin(), password.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (!keyManager.verifyPassword(data)) {
                return -2;
        }
 
-       engine.mount(keyManager.getMasterKey(data), getOptions());
+       engine->mount(keyManager.getMasterKey(data), getOptions());
        return 0;
 }
 
 int ExternalEncryption::umount()
 {
+       if (getState() != State::Encrypted) {
+               return -1;
+       }
+
        INFO("Close all applications using external storage...");
        killDependedApplications();
-       INFO("Umount internal storage...");
-       engine.umount();
+       INFO("Umount external storage...");
+       engine->umount();
 
        return 0;
 }
 
 int ExternalEncryption::encrypt(const std::string &password, unsigned int options)
 {
+       if (getState() != State::Unencrypted) {
+               return -1;
+       }
+
        KeyManager::data pwData(password.begin(), password.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (!keyManager.verifyPassword(pwData)) {
                return -2;
        }
 
        KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
-       auto encryptWorker = [&MasterKey, options, this]() {
-               INFO("Close all applications using external storage...");
-               killDependedApplications();
-               INFO("Encryption started...");
-               engine.encrypt(MasterKey, options);
-               setOptions(options & getSupportedOptions());
-               INFO("Sync disk...");
-               sync();
-               INFO("Encryption completed");
+       auto encryptWorker = [MasterKey, options, this]() {
+               try {
+                       INFO("Close all applications using external storage...");
+                       killDependedApplications();
+                       INFO("Encryption started...");
+                       ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
+                       engine->encrypt(MasterKey, options);
+                       setOptions(options & getSupportedOptions());
+                       INFO("Sync disk...");
+                       sync();
+                       INFO("Encryption completed");
+                       ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "encrypted");
+               } catch (runtime::Exception &e) {
+                       ERROR("Encryption failed - " + std::string(e.what()));
+               }
        };
 
        std::thread asyncWork(encryptWorker);
@@ -219,8 +256,12 @@ int ExternalEncryption::encrypt(const std::string &password, unsigned int option
 
 int ExternalEncryption::decrypt(const std::string &password)
 {
+       if (getState() != State::Encrypted) {
+               return -1;
+       }
+
        KeyManager::data pwData(password.begin(), password.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (!keyManager.verifyPassword(pwData)) {
                return -2;
@@ -228,18 +269,29 @@ int ExternalEncryption::decrypt(const std::string &password)
 
        KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
        auto decryptWorker = [MasterKey, this]() {
-               INFO("Close all applications using external storage...");
-               killDependedApplications();
-               INFO("Umount internal storage...");
                try {
-                       engine.umount();
-               } catch (runtime::Exception &e) {}
-
-               INFO("Decryption started...");
-               engine.decrypt(MasterKey, getOptions());
-               INFO("Sync disk...");
-               sync();
-               INFO("Decryption completed");
+                       INFO("Close all applications using external storage...");
+                       killDependedApplications();
+                       INFO("Umount external storage...");
+                       while (1) {
+                               try {
+                                       engine->umount();
+                                       break;
+                               } catch (runtime::Exception &e) {
+                                       killDependedApplications();
+                               }
+                       }
+
+                       INFO("Decryption started...");
+                       ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
+                       engine->decrypt(MasterKey, getOptions());
+                       INFO("Sync disk...");
+                       sync();
+                       INFO("Decryption completed");
+                       ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
+               } catch (runtime::Exception &e) {
+                       ERROR("Decryption failed - " + std::string(e.what()));
+               }
        };
 
        std::thread asyncWork(decryptWorker);
@@ -250,7 +302,7 @@ int ExternalEncryption::decrypt(const std::string &password)
 
 int ExternalEncryption::isPasswordInitialized()
 {
-       if (engine.isKeyMetaSet()) {
+       if (engine->isKeyMetaSet()) {
                return 1;
        }
        return 0;
@@ -262,20 +314,20 @@ int ExternalEncryption::initPassword(const std::string& password)
        KeyManager keyManager;
 
        keyManager.initPassword(pwData);
-       engine.setKeyMeta(keyManager.serialize());
+       engine->setKeyMeta(keyManager.serialize());
        return 0;
 }
 
 int ExternalEncryption::cleanPassword(const std::string& password)
 {
        KeyManager::data pwData(password.begin(), password.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (!keyManager.verifyPassword(pwData)) {
                return -2;
        }
 
-       engine.clearKeyMeta();
+       engine->clearKeyMeta();
        return 0;
 }
 
@@ -284,14 +336,14 @@ int ExternalEncryption::changePassword(const std::string &oldPassword,
 {
        KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end());
        KeyManager::data newPwData(newPassword.begin(), newPassword.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (!keyManager.verifyPassword(oldPwData)) {
                return -2;
        }
 
        keyManager.changePassword(oldPwData, newPwData);
-       engine.setKeyMeta(keyManager.serialize());
+       engine->setKeyMeta(keyManager.serialize());
 
        return 0;
 }
@@ -299,7 +351,7 @@ int ExternalEncryption::changePassword(const std::string &oldPassword,
 int ExternalEncryption::verifyPassword(const std::string& password)
 {
        KeyManager::data pwData(password.begin(), password.end());
-       KeyManager keyManager(engine.getKeyMeta());
+       KeyManager keyManager(engine->getKeyMeta());
 
        if (keyManager.verifyPassword(pwData)) {
                return 1;
@@ -307,8 +359,6 @@ int ExternalEncryption::verifyPassword(const std::string& password)
        return 0;
 }
 
-
-
 int ExternalEncryption::getState()
 {
        char *value = ::vconf_get_str(EXTERNAL_STATE_VCONF_KEY);
@@ -332,7 +382,7 @@ int ExternalEncryption::getState()
 
 unsigned int ExternalEncryption::getSupportedOptions()
 {
-       return engine.getSupportedOptions();
+       return engine->getSupportedOptions();
 }
 
 } // namespace ode