X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=server%2Finternal-encryption.cpp;h=ae410c574b333e0d2bfcb7c97446b403cd45f6b7;hb=77b2f360ee6b9eb35bbf2418ed818c4e981fded1;hp=a8f3ad60990cb1cef5651cf6737ecf810f10d123;hpb=6eda55903490acb16a2286ad08cc4263140d6387;p=platform%2Fcore%2Fsecurity%2Fode.git diff --git a/server/internal-encryption.cpp b/server/internal-encryption.cpp index a8f3ad6..ae410c5 100644 --- a/server/internal-encryption.cpp +++ b/server/internal-encryption.cpp @@ -14,75 +14,86 @@ * limitations under the License */ #include +#include +#include #include #include #include #include +#include #include +#include #include #include #include #include -#include -#include "engine/dmcrypt-engine.h" +#include "vconf.h" +#include "logger.h" +#include "progress-bar.h" +#include "engine/encryption/dmcrypt-engine.h" #include "key-manager/key-manager.h" #include "rmi/internal-encryption.h" -#define INTERNAL_STORAGE_PATH "/opt/usr" -#define INTERNAL_STATE_VCONF_KEY VCONFKEY_ODE_CRYPTO_STATE -#define INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY VCONFKEY_ODE_FAST_ENCRYPTION +#define INTERNAL_ENGINE DMCryptEngine +#define INTERNAL_DEV_PATH "/dev/disk/by-partlabel" +#define INTERNAL_DEV_NAME "USER" +#define INTERNAL_PATH "/opt/usr" +#define INTERNAL_STATE_VCONF_KEY VCONFKEY_ODE_CRYPTO_STATE +#define INTERNAL_OPTION_ONLY_USED_REGION_VCONF_KEY VCONFKEY_ODE_FAST_ENCRYPTION + +#define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform" + +const std::string PROG_FACTORY_RESET = "/usr/bin/dbus-send"; +const std::vector wipeCommand = { + PROG_FACTORY_RESET, + "--system", + "--type=signal", + "--print-reply", + "--dest=com.samsung.factoryreset", + "/com/samsung/factoryreset", + "com.samsung.factoryreset.start.setting" +}; namespace ode { namespace { -VConfBackend vconfBackend(VCONFKEY_ODE_ENCRYPT_PROGRESS); -ProgressBar progressBar(std::bind(&VConfBackend::update, &vconfBackend, std::placeholders::_1)); - -DMCryptEngine engine("/dev/mmcblk0p25", INTERNAL_STORAGE_PATH, progressBar); +std::unique_ptr engine; +KeyManager::data mountKey; void stopDependedSystemdServices() { - dbus::Connection& systemDBus = dbus::Connection::getSystem(); - std::set servicesToStop; + runtime::File fileToTouch("/tmp/.ode-umount-internal"); + try { + fileToTouch.remove(); + } catch(runtime::Exception &e) {} + fileToTouch.create(O_WRONLY); - for (pid_t pid : runtime::FileUser::getList(INTERNAL_STORAGE_PATH, true)) { - try { - char *service; - systemDBus.methodcall("org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnitByPID", - -1, "(o)", "(u)", (unsigned int)pid) - .get("(o)", &service); - servicesToStop.insert(service); - } catch (runtime::Exception &e) { - INFO("Close process - " + std::to_string(pid)); - ::kill(pid, SIGKILL); - } - } + sleep(1); +} - for (const std::string& service : servicesToStop) { - INFO("Close service - " + service); - systemDBus.methodcall("org.freedesktop.systemd1", - service, - "org.freedesktop.systemd1.Unit", - "Stop", - -1, "", "(s)", "flush"); - } +void killDependedProcesses() +{ + INFO(SINK, "killDependedProcesses"); + for (pid_t pid : runtime::FileUser::getList(INTERNAL_PATH, true)) { + INFO(SINK, "Close process - " + std::to_string(pid)); + int ret = ::kill(pid, SIGKILL); + if (ret != 0) { + ERROR(SINK, "Failed to kill process " + std::to_string(pid)); + } + } } void showProgressUI(const std::string type) { - std::vector args = { - "ode", "progress", type, "Internal" - }; - - runtime::Process proc("/usr/bin/ode", args); - proc.execute(); + runtime::File fileToTouch("/tmp/.ode-progress-internal@" + type); + try { + fileToTouch.remove(); + } catch(runtime::Exception &e) {} + fileToTouch.create(O_WRONLY); } unsigned int getOptions() @@ -116,37 +127,86 @@ void setOptions(unsigned int options) InternalEncryption::InternalEncryption(ODEControlContext& ctx) : context(ctx) { - context.registerParametricMethod(this, "", (int)(InternalEncryption::mount)(std::string)); - context.registerNonparametricMethod(this, "", (int)(InternalEncryption::umount)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::encrypt)(std::string, unsigned int)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::decrypt)(std::string)); - context.registerNonparametricMethod(this, "", (int)(InternalEncryption::isPasswordInitialized)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::initPassword)(std::string)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::cleanPassword)(std::string)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::changePassword)(std::string, std::string)); - context.registerParametricMethod(this, "", (int)(InternalEncryption::verifyPassword)(std::string)); - context.registerNonparametricMethod(this, "", (int)(InternalEncryption::getState)); - context.registerNonparametricMethod(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::setMountPassword)(std::string)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::mount)()); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::umount)()); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::encrypt)(std::string, unsigned int)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::decrypt)(std::string)); + context.expose(this, "", (int)(InternalEncryption::isPasswordInitialized)()); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::initPassword)(std::string)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::cleanPassword)(std::string)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::changePassword)(std::string, std::string)); + context.expose(this, PRIVILEGE_PLATFORM, (int)(InternalEncryption::verifyPassword)(std::string)); + context.expose(this, "", (int)(InternalEncryption::getState)()); + context.expose(this, "", (unsigned int)(InternalEncryption::getSupportedOptions)()); + + context.createNotification("InternalEncryption::mount"); + + std::string source = INTERNAL_DEV_PATH "/" INTERNAL_DEV_NAME; + try { + runtime::DirectoryIterator iter(INTERNAL_DEV_PATH), end; + + while (iter != end) { + const std::string& path = (*iter).getPath(); + std::string name = path.substr(path.rfind('/') + 1); + std::string upper; + upper.reserve(name.size()); + for (char c : name) { + upper += std::toupper(c); + } + if (upper == INTERNAL_DEV_NAME) { + source = path; + break; + } + ++iter; + } + } catch (runtime::Exception &e) {} + + engine.reset(new INTERNAL_ENGINE( + source, INTERNAL_PATH, + ProgressBar([](int v) { + ::vconf_set_str(VCONFKEY_ODE_ENCRYPT_PROGRESS, + std::to_string(v).c_str()); + }) + )); } InternalEncryption::~InternalEncryption() { } -int InternalEncryption::mount(const std::string& password) +int InternalEncryption::setMountPassword(const std::string& password) +{ + KeyManager::data pwData(password.begin(), password.end()); + KeyManager keyManager(engine->getKeyMeta()); + if (!keyManager.verifyPassword(pwData)) { + return -2; + } + + ode::mountKey = keyManager.getMasterKey(pwData); + + return 0; +} + +int InternalEncryption::mount() { if (getState() != State::Encrypted) { return -1; } - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine.getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - return -2; + if (engine->isMounted()) { + INFO(SINK, "Already mounted"); + return 0; } - engine.mount(keyManager.getMasterKey(pwData), getOptions()); + engine->mount(mountKey, getOptions()); + mountKey.clear(); + + context.notify("InternalEncryption::mount"); + + runtime::File("/tmp/.lazy_mount").create(O_WRONLY); + runtime::File("/tmp/.unlock_mnt").create(O_WRONLY); + return 0; } @@ -156,10 +216,16 @@ int InternalEncryption::umount() return -1; } - INFO("Close all processes using internal storage..."); + if (!engine->isMounted()) { + INFO(SINK, "Already umounted"); + return 0; + } + + INFO(SINK, "Close all processes that use internal storage..."); stopDependedSystemdServices(); - INFO("Umount internal storage..."); - engine.umount(); + killDependedProcesses(); + INFO(SINK, "Umount internal storage..."); + engine->umount(); return 0; } @@ -171,35 +237,42 @@ int InternalEncryption::encrypt(const std::string& password, unsigned int option } 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]() { - showProgressUI("Encrypting"); - - INFO("Close all processes using internal storage..."); - stopDependedSystemdServices(); - INFO("Umount internal storage..."); - while (::umount(INTERNAL_STORAGE_PATH) == -1) { - if (errno != EBUSY) { - break; + auto encryptWorker = [MasterKey, options, this]() { + try { + INFO(SINK, "Close all processes that use internal storage..."); + stopDependedSystemdServices(); + killDependedProcesses(); + INFO(SINK, "Umount internal storage..."); + while (::umount(INTERNAL_PATH) == -1) { + if (errno != EBUSY) { + throw runtime::Exception("Umount error - " + std::to_string(errno)); + } + killDependedProcesses(); } - } - INFO("Encryption started..."); - ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted"); - engine.encrypt(MasterKey, options); - setOptions(options & getSupportedOptions()); - INFO("Sync disk..."); - sync(); - INFO("Encryption completed"); + showProgressUI("Encrypting"); + + INFO(SINK, "Encryption started..."); + engine->encrypt(MasterKey, options); + setOptions(options & getSupportedOptions()); + INFO(SINK, "Sync disk..."); + sync(); + INFO(SINK, "Encryption completed"); - ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "encrypted"); - ::reboot(RB_AUTOBOOT); + ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "encrypted"); + context.notify("InternalEncryption::mount"); + ::reboot(RB_AUTOBOOT); + } catch (runtime::Exception &e) { + ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted"); + ERROR(SINK, "Encryption failed - " + std::string(e.what())); + } }; std::thread asyncWork(encryptWorker); @@ -215,7 +288,7 @@ int InternalEncryption::decrypt(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; @@ -223,24 +296,34 @@ int InternalEncryption::decrypt(const std::string& password) KeyManager::data MasterKey = keyManager.getMasterKey(pwData); auto decryptWorker = [MasterKey, this]() { - showProgressUI("Decrypting"); - - INFO("Close all processes using internal storage..."); - stopDependedSystemdServices(); - INFO("Umount internal storage..."); try { - engine.umount(); - } catch (runtime::Exception& e) {} - - INFO("Decryption started..."); - ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted"); - engine.decrypt(MasterKey, getOptions()); - INFO("Sync disk..."); - sync(); - INFO("Decryption completed"); - - ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "unencrypted"); - ::reboot(RB_AUTOBOOT); + INFO(SINK, "Umount internal storage..."); + stopDependedSystemdServices(); + killDependedProcesses(); + INFO(SINK, "Umount internal storage..."); + while (1) { + try { + engine->umount(); + break; + } catch (runtime::Exception& e) { + killDependedProcesses(); + } + } + + showProgressUI("Decrypting"); + + INFO(SINK, "Decryption started..."); + engine->decrypt(MasterKey, getOptions()); + INFO(SINK, "Sync disk..."); + sync(); + INFO(SINK, "Decryption completed"); + + ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "unencrypted"); + ::reboot(RB_AUTOBOOT); + } catch (runtime::Exception &e) { + ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted"); + ERROR(SINK, "Decryption failed - " + std::string(e.what())); + } }; std::thread asyncWork(decryptWorker); @@ -249,9 +332,25 @@ int InternalEncryption::decrypt(const std::string& password) return 0; } +int InternalEncryption::recovery() +{ + if (getState() != State::Unencrypted) { + return -1; + } + + //TODO + runtime::Process proc(PROG_FACTORY_RESET, wipeCommand); + if (proc.execute() == -1) { + ERROR(SINK, "Failed to launch factory-reset"); + return -2; + } + + return 0; +} + int InternalEncryption::isPasswordInitialized() { - if (engine.isKeyMetaSet()) { + if (engine->isKeyMetaSet()) { return 1; } return 0; @@ -263,20 +362,20 @@ int InternalEncryption::initPassword(const std::string& password) KeyManager keyManager; keyManager.initPassword(pwData); - engine.setKeyMeta(keyManager.serialize()); + engine->setKeyMeta(keyManager.serialize()); return 0; } int InternalEncryption::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; } @@ -285,14 +384,14 @@ int InternalEncryption::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; } @@ -300,7 +399,7 @@ int InternalEncryption::changePassword(const std::string& oldPassword, int InternalEncryption::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; @@ -308,8 +407,6 @@ int InternalEncryption::verifyPassword(const std::string& password) return 0; } - - int InternalEncryption::getState() { char *value = ::vconf_get_str(INTERNAL_STATE_VCONF_KEY); @@ -333,7 +430,7 @@ int InternalEncryption::getState() unsigned int InternalEncryption::getSupportedOptions() { - return engine.getSupportedOptions(); + return engine->getSupportedOptions(); } } // namespace ode