Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[nemo-qml-plugin-systemsettings] Support formatting encrypted partiti…
…ons. Contributes to JB#42527
  • Loading branch information
Chris Adams authored and rainemak committed Aug 24, 2018
1 parent 5772467 commit e612557
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/partitionmanager.cpp
Expand Up @@ -291,12 +291,12 @@ void PartitionManagerPrivate::unmount(const Partition &partition)
}
}

void PartitionManagerPrivate::format(const Partition &partition, const QString &type, const QString &label)
void PartitionManagerPrivate::format(const Partition &partition, const QString &type, const QString &label, const QString &passphrase)
{
qCInfo(lcMemoryCardLog) << "Can format:" << externalMedia.match(partition.deviceName()).hasMatch() << partition.deviceName();

if (externalMedia.match(partition.deviceName()).hasMatch()) {
m_udisksMonitor->instance()->format(partition.deviceName(), type, label);
m_udisksMonitor->instance()->format(partition.deviceName(), type, label, passphrase);
} else {
qCWarning(lcMemoryCardLog) << "Formatting allowed only for external memory cards," << partition.devicePath() << "is not allowed";
}
Expand Down
2 changes: 1 addition & 1 deletion src/partitionmanager_p.h
Expand Up @@ -68,7 +68,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData

void mount(const Partition &partition);
void unmount(const Partition &partition);
void format(const Partition &partition, const QString &type, const QString &label);
void format(const Partition &partition, const QString &type, const QString &label, const QString &passphrase);

QStringList supportedFileSystems() const;

Expand Down
4 changes: 2 additions & 2 deletions src/partitionmodel.cpp
Expand Up @@ -136,13 +136,13 @@ void PartitionModel::unmount(const QString &deviceName)
}
}

void PartitionModel::format(const QString &deviceName, const QString &type, const QString &label)
void PartitionModel::format(const QString &deviceName, const QString &type, const QString &label, const QString &passphrase)
{
qCInfo(lcMemoryCardLog) << Q_FUNC_INFO << deviceName << type << label << m_partitions.count();

for (const Partition &partition : m_partitions) {
if (deviceName == partition.deviceName()) {
m_manager->format(partition, type, label);
m_manager->format(partition, type, label, passphrase);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/partitionmodel.h
Expand Up @@ -121,7 +121,7 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel

Q_INVOKABLE void mount(const QString &deviceName);
Q_INVOKABLE void unmount(const QString &deviceName);
Q_INVOKABLE void format(const QString &deviceName, const QString &type, const QString &label);
Q_INVOKABLE void format(const QString &deviceName, const QString &type, const QString &label, const QString &passphrase = QString());

QHash<int, QByteArray> roleNames() const;

Expand Down
3 changes: 2 additions & 1 deletion src/udisks2defines.h
Expand Up @@ -42,6 +42,7 @@

// Interfaces
#define UDISKS2_MANAGER_INTERFACE QLatin1String("org.freedesktop.UDisks2.Manager")
#define UDISKS2_ENCRYPTED_INTERFACE QLatin1String("org.freedesktop.UDisks2.Encrypted")
#define UDISKS2_BLOCK_INTERFACE QLatin1String("org.freedesktop.UDisks2.Block")
#define UDISKS2_FILESYSTEM_INTERFACE QLatin1String("org.freedesktop.UDisks2.Filesystem")
#define UDISKS2_PARTITION_INTERFACE QLatin1String("org.freedesktop.UDisks2.Partition")
Expand All @@ -57,7 +58,7 @@
#define UDISKS2_JOB_KEY_OPERATION QLatin1String("Operation")
#define UDISKS2_JOB_KEY_OBJECTS QLatin1String("Objects")

// Mount, Unmount, Format
// Lock, Unlock, Mount, Unmount, Format
#define UDISKS2_BLOCK_DEVICE_PATH QString(QLatin1String("/org/freedesktop/UDisks2/block_devices/%1"))
#define UDISKS2_BLOCK_FORMAT QLatin1String("Format")
#define UDISKS2_FILESYSTEM_MOUNT QLatin1String("Mount")
Expand Down
38 changes: 37 additions & 1 deletion src/udisks2monitor.cpp
Expand Up @@ -144,7 +144,7 @@ void UDisks2::Monitor::unmount(const QString &deviceName)
startMountOperation(UDISKS2_FILESYSTEM_UNMOUNT, deviceName, arguments);
}

void UDisks2::Monitor::format(const QString &deviceName, const QString &type, const QString &label)
void UDisks2::Monitor::format(const QString &deviceName, const QString &type, const QString &label, const QString &passphrase)
{
if (deviceName.isEmpty()) {
qCCritical(lcMemoryCardLog) << "Cannot format without device name";
Expand All @@ -161,6 +161,9 @@ void UDisks2::Monitor::format(const QString &deviceName, const QString &type, co
arguments.insert(QStringLiteral("label"), QString(label));
arguments.insert(QStringLiteral("no-block"), true);
arguments.insert(QStringLiteral("update-partition-type"), true);
if (!passphrase.isEmpty()) {
arguments.insert(QStringLiteral("encrypt.passphrase"), passphrase);
}

PartitionManagerPrivate::Partitions affectedPartions;
lookupPartitions(affectedPartions, QStringList() << UDISKS2_BLOCK_DEVICE_PATH.arg(deviceName));
Expand Down Expand Up @@ -515,10 +518,43 @@ void UDisks2::Monitor::doFormat(const QString &deviceName, const QString &type,

QDBusPendingCall pendingCall = blockDeviceInterface.asyncCall(UDISKS2_BLOCK_FORMAT, type, arguments);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, [this, deviceName, arguments](QDBusPendingCallWatcher *watcher) {
if (watcher->isValid() && watcher->isFinished()) {
if (arguments.contains(QStringLiteral("encrypt.passphrase"))) {
// after formatting a partition as crypto_LUKS+ext4, the LUKS
// volume with ext4 filesystem is not immediately linked to the parent
// block device. So, manually enumerate via GetBlockDevices().
QDBusInterface managerInterface(UDISKS2_SERVICE,
UDISKS2_MANAGER_PATH,
UDISKS2_MANAGER_INTERFACE,
QDBusConnection::systemBus());
QDBusPendingCall pendingCall = managerInterface.asyncCallWithArgumentList(
QStringLiteral("GetBlockDevices"),
QVariantList() << QVariantMap());
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, [this, deviceName](QDBusPendingCallWatcher *watcher) {
if (watcher->isValid() && watcher->isFinished()) {
QDBusPendingReply<QList<QDBusObjectPath> > reply = *watcher;
const QList<QDBusObjectPath> blockDevicePaths = reply.argumentAt<0>();
for (auto bdp : blockDevicePaths) {
if (bdp.path().startsWith(QStringLiteral("/org/freedesktop/UDisks2/block_devices/dm"))) {
// this is likely a dm-crypt (LUKS) volume which may have been added.
createBlockDevice(bdp.path(), QVariantMap());
}
}
} else if (watcher->isError()) {
QDBusError error = watcher->error();
qCWarning(lcMemoryCardLog) << "Unable to enumerate block devices after formatting:" << error.name() << error.message();
}
// we might not have been able to enumerate the block devices
// but formatting succeeded earlier.
emit status(deviceName, Partition::Formatted);
});
} else {
emit status(deviceName, Partition::Formatted);
}
} else if (watcher->isError()) {
QDBusError error = watcher->error();
QByteArray errorData = error.name().toLocal8Bit();
Expand Down
2 changes: 1 addition & 1 deletion src/udisks2monitor_p.h
Expand Up @@ -81,7 +81,7 @@ class Monitor : public QObject
void mount(const QString &deviceName);
void unmount(const QString &deviceName);

void format(const QString &deviceName, const QString &type, const QString &label);
void format(const QString &deviceName, const QString &type, const QString &label, const QString &passphrase);

signals:
void status(const QString &deviceName, Partition::Status);
Expand Down

0 comments on commit e612557

Please sign in to comment.