From 075ad6399d6c8295a3f2d682146e5772b65754ac Mon Sep 17 00:00:00 2001 From: "sangwan.kwon" Date: Mon, 24 Jul 2017 18:05:14 +0900 Subject: [PATCH] Revert "Implementation of ExtensionEncryption with CryptsetupEngine" - Since arch64 build failed, this commit be reverted. This reverts commit e0ead75e1527aa73bf349ecaa306ba6fc4295930. Conflicts: server/extension-encryption.cpp server/external-encryption.cpp server/server.cpp Change-Id: I8958a4c572d3e21977e1ac638346edd64e490a13 --- rmi/extension-encryption.h | 67 ---- server/extension-encryption.cpp | 656 +--------------------------------------- server/external-encryption.cpp | 10 +- 3 files changed, 11 insertions(+), 722 deletions(-) diff --git a/rmi/extension-encryption.h b/rmi/extension-encryption.h index 7fdac84..cdcb2ab 100644 --- a/rmi/extension-encryption.h +++ b/rmi/extension-encryption.h @@ -18,9 +18,6 @@ #define __EXTENSION_ENCRYPTION_H__ #include -#include - -#include #include "context.h" @@ -55,71 +52,7 @@ public: int getState(); private: - enum Operation { - ADDED = 0, - CHANGED, - REMOVED, - - OPERATION_MAX - }; - - enum Device { - MMC = 0, - MAP, - - DEVICE_MAX - }; - - enum Request { - NONE = 0, - MOUNT, - UMOUNT - }; - - struct DevInfo { - std::string mntPath; - std::string fsType; - std::string sysPath; - bool mounted; - int storagedId; - - DevInfo() : mounted(false), storagedId(-1) {} - ~DevInfo() {} - - void clear() { - mntPath.clear(); - fsType.clear(); - sysPath.clear(); - mounted = false; - storagedId = -1; - } - }; - - void logStoragedEvent(Operation op, Device d); - void handleDevice(Operation op, - const std::vector &intparams, - const std::vector &strparams); - void parseVariant(Operation op, dbus::Variant parameters); - void queryStoraged(); - void subscribeToStoraged(); - void unsubscribeFromStoraged(); - - bool storagedMount(std::unique_lock &lock); - bool storagedUnmount(std::unique_lock &lock); - - int getStatePriv() const; - bool isInserted() const; - bool isOpened() const; - bool isMounted() const; - ODEControlContext& context; - - // currently inserted card information, empty if no card: - DevInfo info[DEVICE_MAX]; - - dbus::Connection::SubscriptionId subId[OPERATION_MAX]; - - Request currentReq; }; } // namespace ode diff --git a/server/extension-encryption.cpp b/server/extension-encryption.cpp index f23698f..e430d5e 100644 --- a/server/extension-encryption.cpp +++ b/server/extension-encryption.cpp @@ -13,700 +13,64 @@ * See the License for the specific language governing permissions and * limitations under the License */ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "logger.h" -#include "ext4-tool.h" -#include "engine/encryption/cryptsetup-engine.h" -#include "key-manager/key-manager.h" #include "rmi/extension-encryption.h" -#define EXTENSION_ENGINE CryptsetupEngine -#define EXTENSION_NAME_DEF "extension" - namespace ode { -namespace { - -const size_t DEFAULT_KEY_SIZE = 64; - -const char *EXTENSION_DEV_PATH = "/dev/mmcblk1p1"; -const char *EXTENSION_NAME = EXTENSION_NAME_DEF; -const char *EXTENSION_MAP_PATH = "/dev/mapper/" EXTENSION_NAME_DEF; -const char *EXTENSION_FS_TYPE = "crypto_LUKS"; - -const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform"; - -const char *STORAGED_DBUS_BUSNAME = "org.tizen.system.storage"; -const char *STORAGED_DBUS_OBJECT = "/Org/Tizen/System/Storage/Block/Manager"; -const char *STORAGED_DBUS_INTERFACE = "org.tizen.system.storage.BlockManager"; - -std::unique_ptr engine; - -std::mutex apiGuard; -std::mutex stateGuard; -std::condition_variable storagedCv; - -std::string findMntPath(const std::string &devPath) -{ - std::string ret; - - FILE* mtab = setmntent("/etc/mtab", "r"); - struct mntent* entry = NULL; - while ((entry = getmntent(mtab)) != NULL) { - if (devPath == entry->mnt_fsname) { - ret = entry->mnt_dir; - break; - } - } - endmntent(mtab); - - return ret; -} - -void killDependedApplications(const std::string &mntPath) -{ - for (pid_t pid : runtime::FileUser::getList(mntPath, true)) { - INFO(SINK, "Close process - " + std::to_string(pid)); - ::kill(pid, SIGKILL); - } -} - -bool findKillAndUmount(const std::string &devPath) -{ - std::string realMntPath = findMntPath(devPath); - if (!realMntPath.empty()) { - INFO(SINK, "Closing all applications using an SD card..."); - killDependedApplications(realMntPath); - - int ret = ::umount(realMntPath.c_str()); - if (ret != 0) { - ERROR(SINK, "The card is still mounted, umount failed with: " - + std::to_string(ret)); - return false; - } - } - - return true; -} - -} // namsepace - ExtensionEncryption::ExtensionEncryption(ODEControlContext &ctx) : - context(ctx), - currentReq(Request::NONE) + context(ctx) { - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::mount)(std::string)); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::umount)()); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::format)(std::string)); - context.expose(this, "", (int)(ExtensionEncryption::isPasswordInitialized)()); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::initPassword)(std::string)); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::cleanPassword)(std::string)); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::changePassword)(std::string, std::string)); - context.expose(this, PRIVILEGE_PLATFORM, (int)(ExtensionEncryption::verifyPassword)(std::string)); - context.expose(this, "", (int)(ExtensionEncryption::getState)()); - - context.createNotification("ExtensionEncryption::mount"); - - // TODO: think about handling more than one card / more than one engine - // it would require global API change to select which card is handled atm - engine.reset(new EXTENSION_ENGINE(EXTENSION_DEV_PATH)); - - queryStoraged(); - subscribeToStoraged(); } ExtensionEncryption::~ExtensionEncryption() { - unsubscribeFromStoraged(); } int ExtensionEncryption::mount(const std::string& password) { - std::lock_guard guardLock(apiGuard); - std::unique_lock stateLock(stateGuard); - - if (getStatePriv() != State::Encrypted) { - ERROR(SINK, "Cannot mount, card not inserted or corrupted"); - return -1; - } - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return -2; - } - - if (isMounted()) { - INFO(SINK, "Already mounted"); - return 0; - } - - KeyManager::data mountKey = keyManager.getMasterKey(pwData); - - INFO(SINK, "Mount extension storage..."); - - if (!isOpened()) { - // Storaged will mount MAP automatically when it appears, let's prepare - currentReq = Request::MOUNT; - - try { - INFO(SINK, "Open the MAP of an extension storage..."); - engine->open(CryptsetupEngine::DeviceType::LUKS, EXTENSION_NAME, mountKey); - } catch (runtime::Exception &e) { - ERROR(SINK, "Open failed: " + std::string(e.what())); - return -3; - } - - INFO(SINK, "Wait for the storaged to mount the MAP automatically..."); - if (!storagedCv.wait_for(stateLock, std::chrono::seconds(1), [this] { - return currentReq == Request::NONE; - })) { - ERROR(SINK, "Storaged timed out mounting the MAP."); - return -3; - } - } else { - INFO(SINK, "Ask storaged to mount extension storage..."); - if (!storagedMount(stateLock)) { - return -3; - } - } - - context.notify("ExtensionEncryption::mount"); - return 0; + return -1; } int ExtensionEncryption::umount() { - std::lock_guard guardLock(apiGuard); - std::unique_lock stateLock(stateGuard); - - if (getStatePriv() != State::Encrypted) { - ERROR(SINK, "Cannot umount, card not inserted or corrupted."); - return -1; - } - - if (!isMounted() && !isOpened()) { - INFO(SINK, "Already umounted."); - return 0; - } - - INFO(SINK, "Umount extension storage..."); - - if (isMounted()) { - INFO(SINK, "Close all applications using extension storage..."); - killDependedApplications(info[Device::MAP].mntPath); - - INFO(SINK, "Ask storaged to umount extension storage..."); - if (!storagedUnmount(stateLock)) { - return -3; - } - } - - if (isOpened()) { - INFO(SINK, "Close the MAP of an extension storage..."); - try { - CryptsetupEngine::close(EXTENSION_NAME); - } catch (runtime::Exception &e) { - ERROR(SINK, "Close failed: " + std::string(e.what())); - return -3; - } - } - - return 0; + return -1; } int ExtensionEncryption::format(const std::string &password) { - int status = 0; - std::condition_variable workerCv; - - auto formatWorker = [&, this]() { - try { - std::lock_guard guardLock(apiGuard); - std::unique_lock stateLock(stateGuard); - - if (!isInserted()) { - ERROR(SINK, "There is no card inserted."); - status = -1; - stateLock.unlock(); - workerCv.notify_one(); - return; - } - - if (isMounted() || isOpened()) { - ERROR(SINK, "The card is still mounted and/or opened, umount and close first."); - status = -1; - stateLock.unlock(); - workerCv.notify_one(); - return; - } - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - status = -2; - stateLock.unlock(); - workerCv.notify_one(); - return; - } - - // no error, let's notify the main thread it can return - status = 1; - stateLock.unlock(); - workerCv.notify_one(); - - KeyManager::data masterKey = keyManager.getMasterKey(pwData); - - // TODO: this probably needs a rework, some sort of communication - // and/or merge with External. The use case for it might be: - // 1. The mmc is mounted by something else, somewhere else. Do we care? - // 2. We take over the cd card from External. - if (!findKillAndUmount(EXTENSION_DEV_PATH)) - return; - - INFO(SINK, "Creating LUKS..."); - engine->format(CryptsetupEngine::DeviceType::LUKS, masterKey); - - INFO(SINK, "Opening LUKS..."); - std::string mappingPath = engine->open(CryptsetupEngine::DeviceType::LUKS, - EXTENSION_NAME, - masterKey); - - INFO(SINK, "Creating EXT4..."); - Ext4Tool::mkfs(mappingPath); - - INFO(SINK, "Closing up the operation..."); - CryptsetupEngine::close(EXTENSION_NAME); - sync(); - - INFO(SINK, "Formatting completed"); - } catch (runtime::Exception &e) { - ERROR(SINK, "Formatting thread failed: " + std::string(e.what())); - } - }; - - std::thread asyncWork(formatWorker); - asyncWork.detach(); - - std::unique_lock stateLock(stateGuard); - if(!workerCv.wait_for(stateLock, std::chrono::seconds(1), [&status] { - return status != 0; - })) { - ERROR(SINK, "Timed out waiting for format status."); - return -4; - } - - if (status < 0) - return status; - - return 0; + return -1; } int ExtensionEncryption::isPasswordInitialized() { - std::lock_guard guardLock(apiGuard); - - if (engine->isKeyMetaSet()) { - return 1; - } - - return 0; + return -1; } int ExtensionEncryption::initPassword(const std::string& password) { - std::lock_guard guardLock(apiGuard); - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager; - - keyManager.initPassword(pwData, DEFAULT_KEY_SIZE); - engine->setKeyMeta(keyManager.serialize()); - return 0; + return -1; } int ExtensionEncryption::cleanPassword(const std::string& password) { - std::lock_guard guardLock(apiGuard); - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(pwData)) { - ERROR(SINK, "Wrong password passed."); - return -2; - } - - engine->clearKeyMeta(); - return 0; + return -1; } int ExtensionEncryption::changePassword(const std::string &oldPassword, const std::string &newPassword) { - std::lock_guard guardLock(apiGuard); - - KeyManager::data oldPwData(oldPassword.begin(), oldPassword.end()); - KeyManager::data newPwData(newPassword.begin(), newPassword.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (!keyManager.verifyPassword(oldPwData)) { - ERROR(SINK, "Wrong password passed."); - return -2; - } - - keyManager.changePassword(oldPwData, newPwData); - engine->setKeyMeta(keyManager.serialize()); - - return 0; + return -1; } int ExtensionEncryption::verifyPassword(const std::string& password) { - std::lock_guard guardLock(apiGuard); - - KeyManager::data pwData(password.begin(), password.end()); - KeyManager keyManager(engine->getKeyMeta()); - - if (keyManager.verifyPassword(pwData)) { - return 1; - } - - return 0; + return -1; } int ExtensionEncryption::getState() { - std::lock_guard guardLock(apiGuard); - std::unique_lock stateLock(stateGuard); - - return getStatePriv(); -} - -void ExtensionEncryption::logStoragedEvent(Operation op, Device d) -{ - DEBUG(SINK, "Storaged event:"); - - switch(op) { - case Operation::ADDED: - DEBUG(SINK, " Operation: ADDED"); - break; - case Operation::CHANGED: - DEBUG(SINK, " Operation: CHANGED"); - break; - case Operation::REMOVED: - DEBUG(SINK, " Operation: REMOVED"); - break; - default: - break; - } - - switch(d) { - case Device::MMC: - DEBUG(SINK, " Device: MMC"); - break; - case Device::MAP: - DEBUG(SINK, " Device: MAP"); - break; - default: - break; - } - - DEBUG(SINK, " Mnt Path: " + info[d].mntPath); - DEBUG(SINK, " Fs Type: " + info[d].fsType); - DEBUG(SINK, " Sys path: " + info[d].sysPath); - DEBUG(SINK, " Mounted: " + std::to_string(info[d].mounted)); - DEBUG(SINK, " ID: " + std::to_string(info[d].storagedId)); -} - -void ExtensionEncryption::handleDevice(Operation op, - const std::vector &intparams, - const std::vector &strparams) -{ - Device d; - - if (std::string(strparams[0]) == EXTENSION_DEV_PATH && intparams[0] == 1) { - d = Device::MMC; - } else if (std::string(strparams[0]) == EXTENSION_MAP_PATH && intparams[0] == 2) { - d = Device::MAP; - } else { - DEBUG(SINK, "Storaged event: neither extension MMC nor extension mapping, ignoring"); - return; - } - - std::unique_lock stateLock(stateGuard); - - if (op == Operation::REMOVED) { - info[d].clear(); - } else { - info[d].mntPath = strparams[6]; - info[d].fsType = strparams[3]; - info[d].sysPath = strparams[1]; - info[d].mounted = intparams[2]; - info[d].storagedId = intparams[5]; - } - - logStoragedEvent(op, d); - - // removing/reformatting the SD card does not automatically close the DM crypt mapping - if (d == Device::MMC && (op == Operation::REMOVED || - (op == Operation::CHANGED && - info[d].fsType != EXTENSION_FS_TYPE))) { - if (isMounted()) { - INFO(SINK, "MMC card removed while still mounted, umounting."); - if (!findKillAndUmount(EXTENSION_MAP_PATH)) { - return; - } - } - - if (isOpened()) { - INFO(SINK, "MMC card removed while LUKS is still opened, closing."); - try { - CryptsetupEngine::close(EXTENSION_NAME); - } catch (runtime::Exception &e) { - ERROR(SINK, "Closing failed: " + std::string(e.what())); - return; - } - } - - return; - } - - if (d == Device::MMC && op == Operation::ADDED && - getStatePriv() == State::Encrypted) { - // TODO: when UI gets written it should be triggered here. - - return; - } - - if (d == Device::MAP && op == Operation::CHANGED) { - if ((currentReq == Request::MOUNT && info[Device::MAP].mounted) || - (currentReq == Request::UMOUNT && !info[Device::MAP].mounted)) { - - currentReq = Request::NONE; - stateLock.unlock(); - storagedCv.notify_one(); - - return; - } - } -} - -void ExtensionEncryption::parseVariant(Operation op, dbus::Variant parameters) -{ - std::vector intparams(6); - std::vector strparams(7); - - parameters.get("(issssssisibii)", - &intparams[0], // block type: 0 - scsi, 1 : mmc, 2 : mapper - &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 - false, 1 - true - &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly - &intparams[5]); // storage id - - handleDevice(op, intparams, strparams); -} - -void ExtensionEncryption::queryStoraged() -{ - INFO(SINK, "Querying the storaged for devices..."); - - dbus::VariantIterator vi; - - try { - dbus::Connection::getSystem().methodcall(STORAGED_DBUS_BUSNAME, - STORAGED_DBUS_OBJECT, - STORAGED_DBUS_INTERFACE, - "GetDeviceList", - -1, - "(a(issssssisibii))", - "(s)", - "all").get("(a(issssssisibii))", &vi); - } catch (runtime::Exception &e) { - ERROR(SINK, "Failed to query storaged: " + std::string(e.what())); - } - - std::vector intparams(6); - std::vector strparams(7); - - while(vi.get("(issssssisibii)", - &intparams[0], // block type: 0 - scsi, 1 : mmc, 2 : mapper - &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 - false, 1 - true - &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly - &intparams[5])) // storage id - { - handleDevice(Operation::ADDED, intparams, strparams); - } -} - -void ExtensionEncryption::subscribeToStoraged() -{ - dbus::Connection &systemDBus = dbus::Connection::getSystem(); - - auto subscribe = [&systemDBus, this](Operation op, const std::string &method) { - dbus::Connection::SignalCallback callback = - std::bind(&ExtensionEncryption::parseVariant, - this, - op, - std::placeholders::_1); - - subId[op] = systemDBus.subscribeSignal("", - STORAGED_DBUS_OBJECT, - STORAGED_DBUS_INTERFACE, - method.c_str(), - callback); - }; - - subscribe(Operation::ADDED, "DeviceAdded"); - subscribe(Operation::CHANGED, "DeviceChanged"); - subscribe(Operation::REMOVED, "DeviceRemoved"); -} - -void ExtensionEncryption::unsubscribeFromStoraged() -{ - dbus::Connection &systemDBus = dbus::Connection::getSystem(); - - systemDBus.unsubscribeSignal(subId[Operation::ADDED]); - systemDBus.unsubscribeSignal(subId[Operation::CHANGED]); - systemDBus.unsubscribeSignal(subId[Operation::REMOVED]); -} - -bool ExtensionEncryption::storagedMount(std::unique_lock &lock) -{ - currentReq = Request::MOUNT; - - int ret = -1; - try { - dbus::Connection::getSystem().methodcall(STORAGED_DBUS_BUSNAME, - STORAGED_DBUS_OBJECT, - STORAGED_DBUS_INTERFACE, - "Mount", - -1, - "(i)", - "(is)", - info[Device::MAP].storagedId, - info[Device::MAP].mntPath.c_str()).get("(i)", &ret); - } catch (runtime::Exception &e) { - ERROR(SINK, "Failed to call mount in storaged: " + std::string(e.what())); - currentReq = Request::NONE; - return false; - } - - if (ret != 0) { - ERROR(SINK, "Storaged failed to mount: " + std::to_string(ret)); - currentReq = Request::NONE; - return false; - } - - if (!storagedCv.wait_for(lock, std::chrono::seconds(1), [this] { - return currentReq == Request::NONE; - })) { - ERROR(SINK, "Storaged timed out mounting the MAP."); - currentReq = Request::NONE; - return false; - } - - return true; -} - -bool ExtensionEncryption::storagedUnmount(std::unique_lock &lock) -{ - currentReq = Request::UMOUNT; - - int ret = -1; - try { - dbus::Connection::getSystem().methodcall(STORAGED_DBUS_BUSNAME, - STORAGED_DBUS_OBJECT, - STORAGED_DBUS_INTERFACE, - "Unmount", - -1, - "(i)", - "(ii)", - info[Device::MAP].storagedId, - 0).get("(i)", &ret); - } catch (runtime::Exception &e) { - ERROR(SINK, "Failed to call unmount in storaged: " + std::string(e.what())); - currentReq = Request::NONE; - return false; - } - - if (ret != 0) { - ERROR(SINK, "Storaged failed to unmount: " + std::to_string(ret)); - currentReq = Request::NONE; - return false; - } - - if (!storagedCv.wait_for(lock, std::chrono::seconds(1), [this] { - return currentReq == Request::NONE; - })) { - ERROR(SINK, "Storaged timed out unmounting the MAP."); - currentReq = Request::NONE; - return false; - } - - return true; -} - -int ExtensionEncryption::getStatePriv() const -{ - if (!isInserted()) { - ERROR(SINK, "Cannot check state, card not inserted"); - return -1; - } - - if (info[Device::MMC].fsType == EXTENSION_FS_TYPE) - return State::Encrypted; - - return State::Corrupted; -} - -bool ExtensionEncryption::isInserted() const -{ - return info[Device::MMC].storagedId >= 0; -} - -bool ExtensionEncryption::isOpened() const -{ - return info[Device::MAP].storagedId >= 0; -} - -bool ExtensionEncryption::isMounted() const -{ - return info[Device::MAP].mounted; + return -1; } } // namespace ode diff --git a/server/external-encryption.cpp b/server/external-encryption.cpp index c8b96bd..984cbbe 100644 --- a/server/external-encryption.cpp +++ b/server/external-encryption.cpp @@ -67,7 +67,7 @@ void externalCallback(dbus::Variant parameters) char* strparams[7]; parameters.get("(issssssisibii)", - &intparams[0], // block type: 0 - scsi, 1 : mmc, 2 : mapper + &intparams[0], // block type: 0 - scsi, 1 : mmc &strparams[0], // devnode &strparams[1], // syspath &strparams[2], // usage @@ -81,14 +81,6 @@ void externalCallback(dbus::Variant parameters) &intparams[4], // flags: 1 - unmounted 2 - broken filesystem 4 - no filesystem 8 - not supported 16 - readonly &intparams[5]); // strage id - // TODO: this implementation probably would do better if it was on par with - // ExtensionEncryption in terms of how it detects and reacts to card events - if (intparams[0] != 1 || (std::string(strparams[3]) != "vfat" && - std::string(strparams[3]) != "ext4")) { - DEBUG(SINK, "Storaged says it's not a regular SD card. Ignoring."); - return; - } - if(intparams[2] == 0) { INFO(SINK, "Unmounted"); } else { -- 2.7.4