const std::string SUBSCRIBER_UNREGISTER = "Server::unregisterNotificationSubscriber";
-const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.socket";
+const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
} // namespace
%manifest ode.manifest
%defattr(644,root,root,755)
%attr(755,root,root) %{_bindir}/oded
-%attr(700,root,root) %{_sbindir}/ode-mount-external.sh
-%{_unitdir}/ode.socket
-%{_unitdir}/sockets.target.wants/ode.socket
%{_unitdir}/ode.service
%{_unitdir}/multi-user.target.wants/ode.service
-%{_unitdir}/ode-mount-external.path
-%{_unitdir}/ode-mount-external.service
-%{_unitdir}/multi-user.target.wants/ode-mount-external.path
-%{_unitdir}/ode-umount-internal.path
-%{_unitdir}/ode-umount-internal.service
-%{_unitdir}/multi-user.target.wants/ode-umount-internal.path
-%{_unitdir}/ode-progress-internal@*.path
-%{_unitdir}/ode-progress-internal@.service
-%{_unitdir}/multi-user.target.wants/ode-progress-internal@*.path
%attr(700,root,root) %{_sbindir}/ode-admin-cli
%{_datadir}/%{name}
%install
%make_install
-%install_service sockets.target.wants ode.socket
%install_service multi-user.target.wants ode.service
-%install_service multi-user.target.wants ode-mount-external.path
-%install_service multi-user.target.wants ode-umount-internal.path
-%install_service multi-user.target.wants ode-progress-internal@Decrypting.path
-%install_service multi-user.target.wants ode-progress-internal@Encrypting.path
%find_lang secure-erase
%find_lang ode
systemctl daemon-reload
if [ $1 = 1 ]; then
# installation
- systemctl start ode.socket \
- ode.service \
- ode-mount-external.path \
- ode-umount-internal.path \
- ode-progress-internal@Decrypting.path \
- ode-progress-internal@Encrypting.path
+ systemctl start ode.service
elif [ $1 = 2 ]; then
# update
- systemctl restart ode.socket \
- ode.service \
- ode-mount-external.path \
- ode-umount-internal.path\
- ode-progress-internal@Decrypting.path \
- ode-progress-internal@Encrypting.path
+ systemctl restart ode.service
fi
%preun
)
CONFIGURE_FILE(systemd/${PROJECT_NAME}.service.in systemd/${PROJECT_NAME}.service)
-CONFIGURE_FILE(systemd/${PROJECT_NAME}-mount-external.service.in systemd/${PROJECT_NAME}-mount-external.service)
-CONFIGURE_FILE(systemd/${PROJECT_NAME}-umount-internal.service.in systemd/${PROJECT_NAME}-umount-internal.service)
-CONFIGURE_FILE(systemd/${PROJECT_NAME}-progress-internal@.service.in systemd/${PROJECT_NAME}-progress-internal@.service)
INSTALL(TARGETS ${SERVER_NAME} DESTINATION ${BIN_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}.socket DESTINATION ${SYSTEMD_UNIT_DIR})
INSTALL(FILES systemd/${PROJECT_NAME}.service DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-mount-external.path DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-mount-external.service DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-umount-internal.path DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-umount-internal.service DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-progress-internal@Decrypting.path DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-progress-internal@Encrypting.path DESTINATION ${SYSTEMD_UNIT_DIR})
-INSTALL(FILES systemd/${PROJECT_NAME}-progress-internal@.service DESTINATION ${SYSTEMD_UNIT_DIR})
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/engine/encryption/dummy_password DESTINATION ${DATA_DIR}/${PROJECT_NAME}/)
#include <klay/exception.h>
#include <klay/filesystem.h>
-#include "../../key-manager/key-generator.h"
#include "../../kernel-keyring.h"
#include "../../file-footer.h"
#include "../../logger.h"
::memcpy(payload.token.password.sessionKeyEncryptionKey, key.data(),
payload.token.password.sessionKeyEncryptionKeySize);
- KeyGenerator::data sigdata = KeyGenerator::MD5(KeyGenerator::data(destination.begin(), destination.end()));
std::stringstream signature;
signature<< std::hex << std::setfill('0') << std::setw(2);
- for (unsigned int byte : sigdata) {
+ for (unsigned int byte : key) {
signature << byte;
}
-
for (int i = key.size(); i < ECRYPTFS_SIGNATURE_SIZE / 2; i++) {
signature << (unsigned int) 0;
}
mountOption = "ecryptfs_passthrough"
",ecryptfs_cipher=" CIPHER_MODE
+ ",smackfsroot=*,smackfsdef=*"
",ecryptfs_sig=" + std::string((char *)payload.token.password.signature) +
",ecryptfs_key_bytes=" + std::to_string(payload.token.password.sessionKeyEncryptionKeySize);
#include <fstream>
#include <sstream>
-#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mount.h>
#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 EXTERNAL_SYSTEMD_UNIT "ode-mount-external.service"
#define PRIVILEGE_PLATFORM "http://tizen.org/privilege/internal/default/platform"
));
externalAddEventReceiver();
-
- if (getState() == State::Encrypted) {
- context.ref();
- }
}
ExternalEncryption::~ExternalEncryption()
engine->mount(mountKey, getOptions());
mountKey.clear();
- //For smackfsroot, smackfsdef option without CAP_MAC_ADMIN
- runtime::File fileToTouch("/run/.ode-mount-external");
- try {
- fileToTouch.remove();
- } catch(runtime::Exception &e) {}
- fileToTouch.create(O_WRONLY);
-
context.notify("ExternalEncryption::mount");
return 0;
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto encryptWorker = [MasterKey, options, this]() {
- context.ref();
try {
INFO(SINK, "Close all applications using external storage...");
killDependedApplications();
sync();
INFO(SINK, "Encryption completed");
::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "encrypted");
-
- //For smackfsroot, smackfsdef option without CAP_MAC_ADMIN
- runtime::File fileToTouch("/run/.ode-mount-external");
- try {
- fileToTouch.remove();
- } catch(runtime::Exception &e) {}
- fileToTouch.create(O_WRONLY);
-
context.notify("ExternalEncryption::mount");
} catch (runtime::Exception &e) {
::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
ERROR(SINK, "Encryption failed - " + std::string(e.what()));
- context.unref();
}
};
sync();
INFO(SINK, "Decryption completed");
::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
- context.unref();
} catch (runtime::Exception &e) {
ERROR(SINK, "Decryption failed - " + std::string(e.what()));
}
#include <unistd.h>
#include <sys/mount.h>
#include <sys/reboot.h>
-#include <sys/inotify.h>
#include <vconf.h>
#include <tzplatform_config.h>
std::unique_ptr<INTERNAL_ENGINE> engine;
KeyManager::data mountKey;
-void stopDependedSystemdServices()
-{
- runtime::File fileToTouch("/run/.ode-umount-internal");
- try {
- fileToTouch.remove();
- } catch(runtime::Exception &e) {}
- fileToTouch.create(O_WRONLY);
+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(SINK, "Stop service - " + service);
+ systemDBus.methodcall("org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StopUnit",
+ -1, "", "(ss)", service.c_str(), "flush");
+ }
sleep(1);
}
-void killDependedProcesses()
+void stopDependedSystemdServices()
{
- 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));
+ 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(SINK, "Close process - " + std::to_string(pid));
+ ::kill(pid, SIGKILL);
}
- }
+ }
+
+ for (const std::string& service : servicesToStop) {
+ INFO(SINK, "Close service - " + service);
+ systemDBus.methodcall("org.freedesktop.systemd1",
+ service,
+ "org.freedesktop.systemd1.Unit",
+ "Stop",
+ -1, "", "(s)", "flush");
+ }
}
void showProgressUI(const std::string type) {
- runtime::File fileToTouch("/run/.ode-progress-internal@" + type);
+ ::tzplatform_set_user(::tzplatform_getuid(TZ_SYS_DEFAULT_USER));
+ std::string defaultUserHome(::tzplatform_getenv(TZ_USER_HOME));
+ ::tzplatform_reset_user();
+
try {
- fileToTouch.remove();
- } catch(runtime::Exception &e) {}
- fileToTouch.create(O_WRONLY);
+ 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(SINK, "Failed to set up elm configuration");
+ }
+
+ std::vector<std::string> args = {
+ "ode", "progress", type, "Internal"
+ };
+
+ runtime::Process proc("/usr/bin/ode", args);
+ proc.execute();
}
unsigned int getOptions()
return 0;
}
- INFO(SINK, "Close all processes that use internal storage...");
+ INFO(SINK, "Close all processes using internal storage...");
stopDependedSystemdServices();
- killDependedProcesses();
INFO(SINK, "Umount internal storage...");
engine->umount();
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto encryptWorker = [MasterKey, options, this]() {
- context.ref();
try {
- INFO(SINK, "Close all processes that use internal storage...");
+ INFO(SINK, "Close all user sessions...");
+ stopSystemdUserSessions();
+ INFO(SINK, "Close all processes using 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();
+ stopDependedSystemdServices();
}
showProgressUI("Encrypting");
::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
ERROR(SINK, "Encryption failed - " + std::string(e.what()));
}
- context.unref();
};
std::thread asyncWork(encryptWorker);
KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
auto decryptWorker = [MasterKey, this]() {
- context.ref();
try {
- INFO(SINK, "Umount internal storage...");
+ INFO(SINK, "Close all user sessions...");
+ stopSystemdUserSessions();
+ INFO(SINK, "Close all processes using internal storage...");
stopDependedSystemdServices();
- killDependedProcesses();
INFO(SINK, "Umount internal storage...");
while (1) {
try {
engine->umount();
break;
} catch (runtime::Exception& e) {
- killDependedProcesses();
+ stopDependedSystemdServices();
}
}
::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
ERROR(SINK, "Decryption failed - " + std::string(e.what()));
}
- context.unref();
};
std::thread asyncWork(decryptWorker);
namespace {
-const int ODE_MANAGER_ONDEMAND_TIMEOUT = 1000;
-const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.socket";
+const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
std::unique_ptr<ode::SecureErase> secureErase;
std::unique_ptr<ode::InternalEncryption> internalEncryption;
audit::LogSink *SINK = nullptr;
-Server::Server() :
- referenceCount(0)
+Server::Server()
{
_sink.reset(new audit::DlogLogSink("ODE"));
SINK = dynamic_cast<audit::LogSink*>((_sink).get());
void Server::run()
{
// Prepare execution environment
- service->start(true, ODE_MANAGER_ONDEMAND_TIMEOUT);
- while (referenceCount > 0) {
- service->mainloop.dispatch(ODE_MANAGER_ONDEMAND_TIMEOUT);
- }
+ service->start();
}
void Server::terminate()
runtime::FileDescriptor registerNotificationSubscriber(const std::string& name);
int unregisterNotificationSubscriber(const std::string& name, int id);
- void ref()
- {
- referenceCount++;
- }
-
- void unref()
- {
- referenceCount--;
- }
-
private:
std::string securityLabel;
- std::atomic<int> referenceCount;
std::unique_ptr<rmi::Service> service;
};
+++ /dev/null
-[Path]
-PathExists=/run/.ode-mount-external
+++ /dev/null
-[Unit]
-Description=@PROJECT_NAME@ mount for external encrypted storage
-After=@PROJECT_NAME@.service
-
-[Service]
-Type=oneshot
-SmackProcessLabel=System::Privileged
-ExecStart=/sbin/ode-mount-external.sh
-CapabilityBoundingSet=~CAP_MAC_OVERRIDE
+++ /dev/null
-[Unit]
-Description=@PROJECT_NAME@ progress UI
-After=oded.service
-
-[Service]
-Type=simple
-User=owner
-Group=users
-SmackProcessLabel=User::Pkg::org.tizen.ode
-ExecStart=@BIN_DIR@/@PROJECT_NAME@ progress %i Internal
-Restart=on-failure
-ExecReload=/bin/kill -HUP $MAINPID
-CapabilityBoundingSet=~CAP_MAC_ADMIN
-CapabilityBoundingSet=~CAP_MAC_OVERRIDE
-EnvironmentFile=/run/tizen-system-env
-EnvironmentFile=/run/xdg-root-env
-
-[Install]
-WantedBy=multi-user.target
+++ /dev/null
-[Path]
-PathExists=/run/.ode-progress-internal@Decrypting
+++ /dev/null
-[Path]
-PathExists=/run/.ode-progress-internal@Encrypting
+++ /dev/null
-[Path]
-PathExists=/run/.ode-umount-internal
+++ /dev/null
-[Unit]
-Description=Umount of internal storage
-After=@PROJECT_NAME@.service
-
-[Service]
-Type=oneshot
-SmackProcessLabel=System
-ExecStart=/usr/bin/systemctl stop user@* tlm resourced msg-server
-CapabilityBoundingSet=~CAP_MAC_ADMIN
-CapabilityBoundingSet=~CAP_MAC_OVERRIDE
[Service]
Type=simple
-User=security_fw
-Group=security_fw
-SmackProcessLabel=System
+SmackProcessLabel=System::Privileged
ExecStart=@BIN_DIR@/@PROJECT_NAME@d
Restart=on-failure
ExecReload=/bin/kill -HUP $MAINPID
-CapabilityBoundingSet=~CAP_MAC_ADMIN
CapabilityBoundingSet=~CAP_MAC_OVERRIDE
-Capabilities=cap_sys_admin,cap_dac_override,cap_sys_boot,cap_sys_ptrace,cap_kill=i
-SecureBits=keep-caps
+EnvironmentFile=/run/tizen-system-env
+EnvironmentFile=/run/xdg-root-env
[Install]
WantedBy=multi-user.target
+++ /dev/null
-[Unit]
-Description=ODE daemon socket
-Wants=ode.service
-Before=ode.service
-
-[Socket]
-ListenStream=/tmp/.ode.socket
-Service=ode.service
-SocketMode=0770
-SmackLabelIPIn=*
-SmackLabelIPOut=@
-
-[Install]
-WantedBy=sockets.target
int ODEStandAlone::run(int argc, char *argv[])
{
char *lang = nullptr;
+ ::setenv("HOME", "/opt/home/root", 1);
if (argc < 2) {
return -1;
}
TARGET_LINK_LIBRARIES(${CLI_NAME} ${CLI_DEPS_LIBRARIES} ${PROJECT_NAME} ode)
INSTALL(TARGETS ${CLI_NAME} DESTINATION sbin)
-INSTALL(FILES ${PROJECT_NAME}-mount-external.sh DESTINATION sbin)
+++ /dev/null
-#!/bin/bash
-PATH="/usr/bin:/bin:/usr/sbin:/sbin"
-
-STORAGE="/opt/media/SDCardA1"
-
-OPTION=`cat /proc/mounts | grep "${STORAGE} ${STORAGE} ecryptfs" | gawk '{print $4}'`
-
-KEY_DESC=`echo ${OPTION} | sed -e s/.*'ecryptfs_sig='// -e s/','.*//`
-KEY=`su security_fw -s /bin/keyctl search @u user ${KEY_DESC}`
-
-su security_fw -s /bin/keyctl setperm ${KEY} 0x3f111010
-keyctl link ${KEY} @u
-
-if [ -z ${OPTION} ]; then
- exit -1
-fi
-
-umount ${STORAGE}
-
-mount -t ecryptfs -o ${OPTION},smackfsroot=*,smackfsdef=* ${STORAGE} ${STORAGE}