* limitations under the License
*/
#include <set>
+#include <algorithm>
+#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/reboot.h>
+#include <sys/inotify.h>
#include <vconf.h>
#include <tzplatform_config.h>
#include <klay/file-user.h>
#include <klay/filesystem.h>
#include <klay/dbus/connection.h>
-#include <klay/audit/logger.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_ENGINE DMCryptEngine
-#define INTERNAL_DEV "/dev/mmcblk0p25"
-#define INTERNAL_PATH "/opt/usr"
+#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
std::unique_ptr<INTERNAL_ENGINE> engine;
KeyManager::data mountKey;
-void stopSystemdUserSessions() {
- std::vector<std::string> userSessionServices;
- dbus::Connection& systemDBus = dbus::Connection::getSystem();
- dbus::VariantIterator iter;
-
- systemDBus.methodcall("org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "ListUnits",
- -1, "(a(ssssssouso))", "")
- .get("(a(ssssssouso))", &iter);
-
- while (1) {
- unsigned int dataUint;
- char *dataStr[9];
- int ret;
-
- ret = iter.get("(ssssssouso)", dataStr, dataStr + 1, dataStr + 2,
- dataStr + 3, dataStr + 4, dataStr + 5,
- dataStr + 6, &dataUint, dataStr + 7,
- dataStr + 8);
-
- if (!ret) {
- break;
- }
-
- std::string service(dataStr[0]);
- if (service.compare(0, 5, "user@") == 0) {
- userSessionServices.push_back(service);
- }
- }
-
- for (const std::string& service : userSessionServices) {
- INFO("Stop service - " + service);
- systemDBus.methodcall("org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StopUnit",
- -1, "", "(ss)", service.c_str(), "flush");
- }
+void stopDependedSystemdServices()
+{
+ runtime::File fileToTouch("/tmp/.ode-umount-internal");
+ try {
+ fileToTouch.remove();
+ } catch(runtime::Exception &e) {}
+ fileToTouch.create(O_WRONLY);
sleep(1);
}
-void stopDependedSystemdServices()
+void killDependedProcesses()
{
- dbus::Connection& systemDBus = dbus::Connection::getSystem();
- std::set<std::string> servicesToStop;
-
- for (pid_t pid : runtime::FileUser::getList(INTERNAL_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);
+ 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));
}
- }
-
- 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 showProgressUI(const std::string type) {
- ::tzplatform_set_user(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
- std::string defaultUserHome(::tzplatform_getenv(TZ_USER_HOME));
- ::tzplatform_reset_user();
-
+ runtime::File fileToTouch("/tmp/.ode-progress-internal@" + type);
try {
- runtime::File shareDirectory("/opt/home/root/share");
- if (!shareDirectory.exists()) {
- shareDirectory.makeDirectory(true);
- }
-
- runtime::File elmConfigDir(shareDirectory.getPath() + "/.elementary");
- if (!elmConfigDir.exists()) {
- runtime::File defaultElmConfigDir(defaultUserHome + "/share/.elementary");
- defaultElmConfigDir.copyTo(shareDirectory.getPath());
- }
- } catch (runtime::Exception &e) {
- ERROR("Failed to set up elm configuration");
- }
-
- std::vector<std::string> args = {
- "ode", "progress", type, "Internal"
- };
-
- runtime::Process proc("/usr/bin/ode", args);
- proc.execute();
+ fileToTouch.remove();
+ } catch(runtime::Exception &e) {}
+ fileToTouch.create(O_WRONLY);
}
unsigned int getOptions()
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(
- INTERNAL_DEV, INTERNAL_PATH,
+ source, INTERNAL_PATH,
ProgressBar([](int v) {
::vconf_set_str(VCONFKEY_ODE_ENCRYPT_PROGRESS,
std::to_string(v).c_str());
}
if (engine->isMounted()) {
- INFO("Already mounted");
+ INFO(SINK, "Already mounted");
return 0;
}
context.notify("InternalEncryption::mount");
+ runtime::File("/tmp/.lazy_mount").create(O_WRONLY);
+ runtime::File("/tmp/.unlock_mnt").create(O_WRONLY);
+
return 0;
}
}
if (!engine->isMounted()) {
- INFO("Already umounted");
+ INFO(SINK, "Already umounted");
return 0;
}
- INFO("Close all processes using internal storage...");
+ INFO(SINK, "Close all processes that use internal storage...");
stopDependedSystemdServices();
- INFO("Umount internal storage...");
+ killDependedProcesses();
+ INFO(SINK, "Umount internal storage...");
engine->umount();
return 0;
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto encryptWorker = [MasterKey, options, this]() {
try {
- INFO("Close all user sessions...");
- stopSystemdUserSessions();
- INFO("Close all processes using internal storage...");
+ INFO(SINK, "Close all processes that use internal storage...");
stopDependedSystemdServices();
- INFO("Umount internal storage...");
+ killDependedProcesses();
+ INFO(SINK, "Umount internal storage...");
while (::umount(INTERNAL_PATH) == -1) {
if (errno != EBUSY) {
throw runtime::Exception("Umount error - " + std::to_string(errno));
}
- stopDependedSystemdServices();
+ killDependedProcesses();
}
showProgressUI("Encrypting");
- INFO("Encryption started...");
+ INFO(SINK, "Encryption started...");
engine->encrypt(MasterKey, options);
setOptions(options & getSupportedOptions());
- INFO("Sync disk...");
+ INFO(SINK, "Sync disk...");
sync();
- INFO("Encryption completed");
+ INFO(SINK, "Encryption completed");
::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("Encryption failed - " + std::string(e.what()));
+ ERROR(SINK, "Encryption failed - " + std::string(e.what()));
}
};
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto decryptWorker = [MasterKey, this]() {
try {
- INFO("Close all user sessions...");
- stopSystemdUserSessions();
- INFO("Close all processes using internal storage...");
+ INFO(SINK, "Umount internal storage...");
stopDependedSystemdServices();
- INFO("Umount internal storage...");
+ killDependedProcesses();
+ INFO(SINK, "Umount internal storage...");
while (1) {
try {
engine->umount();
break;
} catch (runtime::Exception& e) {
- stopDependedSystemdServices();
+ killDependedProcesses();
}
}
showProgressUI("Decrypting");
- INFO("Decryption started...");
+ INFO(SINK, "Decryption started...");
engine->decrypt(MasterKey, getOptions());
- INFO("Sync disk...");
+ INFO(SINK, "Sync disk...");
sync();
- INFO("Decryption completed");
+ 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("Decryption failed - " + std::string(e.what()));
+ ERROR(SINK, "Decryption failed - " + std::string(e.what()));
}
};
//TODO
runtime::Process proc(PROG_FACTORY_RESET, wipeCommand);
if (proc.execute() == -1) {
- ERROR("Failed to launch factory-reset");
+ ERROR(SINK, "Failed to launch factory-reset");
return -2;
}