*/
#include <fstream>
#include <sstream>
+#include <cstring>
#include <unistd.h>
#include <sys/mount.h>
bool isBootCompleted = false;
-const char *EXTERNAL_PATH = "/media/SDCardA1";
-const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
+constexpr const char *DEFAULT_EXTERNAL_PATH = "/media/SDCardA1";
+const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
void spawnUI()
{
}
}
+
+bool isEncrypted()
+{
+ char *cryptoState = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
+ if (cryptoState == NULL)
+ return false;
+
+ bool encrypted = (strcmp(cryptoState, "encrypted") == 0);
+ free(cryptoState);
+ return encrypted;
+}
+
void externalCallback(dbus::Variant parameters)
{
int intparams[6];
if(intparams[2] == 0) {
INFO(SINK, "SD card not mounted, ignoring.");
+ int ret = ::vconf_unset(VCONFKEY_SDE_MOUNT_POINT);
+ if (ret != 0)
+ ERROR(SINK, "vconf_unset() failed with " << ret);
} else {
INFO(SINK, "SD card mounted.");
- char *value = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
- if (value != NULL) {
- std::string valueStr(value);
- free(value);
- if (valueStr == "encrypted" && isBootCompleted) {
- spawnUI();
- }
+ int ret;
+ ret = ::vconf_set_str(VCONFKEY_SDE_MOUNT_POINT, DEFAULT_EXTERNAL_PATH);
+ if (ret != 0) {
+ ERROR(SINK, "vconf_set() failed with " << ret);
+ return;
}
+
+ if (isEncrypted() && isBootCompleted)
+ spawnUI();
}
}
sleep(8);
INFO(SINK, "Boot completed.");
-
- char *value = ::vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
- if (value != NULL) {
- std::string valueStr(value);
- free(value);
- if (valueStr == "encrypted") {
- spawnUI();
- }
+ int ret = ::vconf_set_str(VCONFKEY_SDE_MOUNT_POINT, DEFAULT_EXTERNAL_PATH);
+ if (ret != 0) {
+ ERROR(SINK, "vconf_set() failed with " << ret);
+ } else if (isEncrypted()) {
+ spawnUI();
}
isBootCompleted = true;
};
bootCompletionCallback);
}
+/*
+ * Introspection data for the exported object
+ *
+ * Test:
+ * dbus-send --system --type=method_call --print-reply --dest=org.tizen.ode
+ * /org/tizen/ode/ExternalEncryption org.freedesktop.DBus.Introspectable.Introspect
+ */
+const gchar introspectionXml[] =
+ "<node>"
+ " <interface name='org.tizen.ode.ExternalEncryption'>"
+ " <method name='UpdateCardStatus'>"
+ " <arg type='s' name='mountpoint' direction='in'/>"
+ " <arg type='i' name='status' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+void dbusMethodCall(GDBusConnection *,
+ const gchar *sender,
+ const gchar *object,
+ const gchar *interface,
+ const gchar *method,
+ GVariant *params,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ DEBUG(SINK, "dbusMethodCall sender: " << sender << ", object: " << object << ", interface: " <<
+ interface << ", method: " << method);
+
+ static_cast<ExternalEncryptionServer*>(user_data)->dbusMethodCall(method, params, invocation);
+}
+
unsigned int getOptions()
{
unsigned int result = 0;
::vconf_set_bool(VCONFKEY_SDE_ENCRYPT_NEWFILE, value);
}
-} // namsepace
+} // namespace
ExternalEncryptionServer::ExternalEncryptionServer(ServerContext &srv,
KeyServer& key) :
server.createNotification("ExternalEncryptionServer::mount");
- engine.reset(new EXTERNAL_ENGINE(EXTERNAL_PATH,
- EXTERNAL_PATH,
- ProgressBar(VCONFKEY_SDE_ENCRYPT_PROGRESS)));
-
externalAddEventReceiver();
}
{
RequestLifetime rl(server);
- return keyServer.get(engine->getSource(), password, mountKey);
+ return keyServer.get(getEngine().getSource(), password, mountKey);
}
int ExternalEncryptionServer::mount()
return error::NoSuchDevice;
}
- if (engine->isMounted()) {
+ auto& engine = getEngine();
+ if (engine.isMounted()) {
INFO(SINK, "SD card already mounted.");
return error::None;
}
INFO(SINK, "Mounting external storage.");
try {
- engine->mount(key, getOptions());
+ engine.mount(key, getOptions());
} catch (runtime::Exception &e) {
ERROR(SINK, "Failed to mount: " + std::string(e.what()));
return error::Unknown;
return error::NoSuchDevice;
}
- if (!engine->isMounted()) {
+ auto& engine = getEngine();
+ if (!engine.isMounted()) {
INFO(SINK, "SD card already umounted.");
return error::None;
}
INFO(SINK, "Closing all applications using external storage.");
- killDependentApplications(EXTERNAL_PATH);
+ killDependentApplications(engine.getDestination());
INFO(SINK, "Umounting external storage.");
try {
- engine->umount();
+ engine.umount();
} catch (runtime::Exception &e) {
ERROR(SINK, "Failed to umount: " + std::string(e.what()));
return error::Unknown;
}
BinaryData masterKey;
- int ret = keyServer.get(engine->getSource(), password, masterKey);
+ int ret = keyServer.get(getEngine().getSource(), password, masterKey);
if (ret != error::None)
return ret;
auto encryptWorker = [masterKey, options, this](RequestLifetime&& rl) {
try {
+ auto& engine = getEngine();
+
INFO(SINK, "Closing all applications using external storage.");
- killDependentApplications(EXTERNAL_PATH);
+ killDependentApplications(engine.getDestination());
INFO(SINK, "Encryption started.");
- engine->encrypt(masterKey, options);
- setOptions(options & engine->getSupportedOptions());
+ engine.encrypt(masterKey, options);
+ setOptions(options & engine.getSupportedOptions());
INFO(SINK, "Encryption completed.");
::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "encrypted");
}
BinaryData masterKey;
- int ret = keyServer.get(engine->getSource(), password, masterKey);
+ int ret = keyServer.get(getEngine().getSource(), password, masterKey);
if (ret != error::None)
return ret;
auto decryptWorker = [masterKey, this](RequestLifetime&& rl) {
try {
+ auto& engine = getEngine();
+
INFO(SINK, "Closing all applications using external storage.");
- killDependentApplications(EXTERNAL_PATH);
+ killDependentApplications(engine.getDestination());
INFO(SINK, "Umounting external storage.");
while (1) {
try {
- engine->umount();
+ engine.umount();
break;
} catch (runtime::Exception &e) {
- killDependentApplications(EXTERNAL_PATH);
+ killDependentApplications(engine.getDestination());
}
}
INFO(SINK, "Decryption started.");
::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "error_partially_decrypted");
- engine->decrypt(masterKey, getOptions());
+ engine.decrypt(masterKey, getOptions());
INFO(SINK, "Decryption completed.");
::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
return error::NoSuchDevice;
}
- for (runtime::DirectoryIterator iter(engine->getSource()), end;
+ auto& engine = getEngine();
+ for (runtime::DirectoryIterator iter(engine.getSource()), end;
iter != end; ++iter) {
iter->remove(true);
}
- keyServer.removePassword(engine->getSource());
+ keyServer.removePassword(engine.getSource());
::vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
return error::None;
int ExternalEncryptionServer::isPasswordInitialized()
{
- return keyServer.isInitialized(engine->getSource());
+ return keyServer.isInitialized(getEngine().getSource());
}
int ExternalEncryptionServer::initPassword(const std::string& password)
{
- return keyServer.init(engine->getSource(), password, Key::DEFAULT_256BIT);
+ return keyServer.init(getEngine().getSource(), password, Key::DEFAULT_256BIT);
}
int ExternalEncryptionServer::cleanPassword(const std::string& password)
{
- return keyServer.remove(engine->getSource(), password);
+ return keyServer.remove(getEngine().getSource(), password);
}
int ExternalEncryptionServer::changePassword(const std::string &oldPassword,
const std::string &newPassword)
{
- return keyServer.changePassword(engine->getSource(), oldPassword, newPassword);
+ return keyServer.changePassword(getEngine().getSource(), oldPassword, newPassword);
}
int ExternalEncryptionServer::verifyPassword(const std::string& password)
{
- return keyServer.verifyPassword(engine->getSource(), password);
+ return keyServer.verifyPassword(getEngine().getSource(), password);
}
int ExternalEncryptionServer::getState()
{
RequestLifetime rl(server);
- return engine->getSupportedOptions();
+ return getEngine().getSupportedOptions();
}
std::string ExternalEncryptionServer::getDevicePath() const
{
RequestLifetime rl(server);
- return engine->getSource();
+ return getEngine().getSource();
+}
+
+void ExternalEncryptionServer::dbusRegisterObject(GDBusConnection *connection)
+{
+ GError *err = NULL;
+ GDBusNodeInfo *dbusIntrospectionData = g_dbus_node_info_new_for_xml(introspectionXml, &err);
+ if (dbusIntrospectionData == NULL) {
+ ERROR(SINK, "Dbus introspection data creation failed: " << err->message);
+ return;
+ }
+
+ const GDBusInterfaceVTable interfaceVtable =
+ {
+ ode::dbusMethodCall,
+ NULL,
+ NULL
+ };
+
+ /*
+ * Test:
+ * dbus-send --system --type=method_call --print-reply --dest=org.tizen.ode
+ * /org/tizen/ode/ExternalEncryption org.tizen.ode.ExternalEncryption.UpdateCardStatus
+ * string:"/media/SDCardA1" int32:1
+ */
+ guint registrationId = g_dbus_connection_register_object(connection,
+ "/org/tizen/ode/ExternalEncryption",
+ dbusIntrospectionData->interfaces[0],
+ &interfaceVtable,
+ this,
+ NULL,
+ &err);
+ if (registrationId == 0)
+ ERROR(SINK, "Dbus object registration failed: " << err->message);
+
+ g_dbus_node_info_unref(dbusIntrospectionData);
+}
+
+void ExternalEncryptionServer::dbusMethodCall(const gchar *,
+ GVariant *params,
+ GDBusMethodInvocation *invocation)
+{
+ RequestLifetime rl(server);
+
+ const gchar *mountPoint;
+ gint32 cardStatus;
+
+ g_variant_get(params, "(&si)", &mountPoint, &cardStatus);
+
+ switch (cardStatus) {
+ case 0:
+ DEBUG(SINK, "Card unmounted " << mountPoint);
+ {
+ int ret = ::vconf_unset(VCONFKEY_SDE_MOUNT_POINT);
+ if (ret != 0)
+ ERROR(SINK, "vconf_set_str() failed with " << ret);
+
+ engine.reset();
+ }
+ break;
+ case 1:
+ DEBUG(SINK, "Card mounted " << mountPoint);
+ {
+ int ret = ::vconf_set_str(VCONFKEY_SDE_MOUNT_POINT, mountPoint);
+ if (ret != 0)
+ ERROR(SINK, "vconf_set_str() failed with " << ret);
+ else if (isEncrypted())
+ spawnUI();
+ }
+ break;
+ default:
+ ERROR(SINK, "Unsupported card status: " << cardStatus);
+ g_dbus_method_invocation_return_error(invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Unsupported card status");
+ return;
+ }
+ g_dbus_method_invocation_return_value(invocation, NULL);
}
int ExternalEncryptionServer::getStateInternal() const
return State::NotSupported;
}
+EXTERNAL_ENGINE& ExternalEncryptionServer::getEngine() const
+{
+ if (!engine) {
+ char *tmp = ::vconf_get_str(VCONFKEY_SDE_MOUNT_POINT);
+
+ static_assert(DEFAULT_EXTERNAL_PATH);
+
+ std::string mountPoint(tmp ? tmp : DEFAULT_EXTERNAL_PATH);
+ free(tmp);
+
+ runtime::File f(mountPoint);
+ mountPoint = f.readlink();
+
+ engine.reset(new EXTERNAL_ENGINE(mountPoint,
+ mountPoint,
+ ProgressBar(VCONFKEY_SDE_ENCRYPT_PROGRESS)));
+
+ }
+ return *engine;
+}
+
} // namespace ode