Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions assets/dbus/org.deepin.Filemanager.DiskEncrypt.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,14 @@
</method>
<method name="Decryption">
<arg type="b" direction="out"/>
<arg name="args" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
<arg name="credentialsFd" type="h" direction="in"/>
</method>
<method name="ChangePassphrase">
<arg type="b" direction="out"/>
<arg name="args" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
<arg name="credentialsFd" type="h" direction="in"/>
</method>
<method name="SetupAuthArgs">
<arg name="args" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
<arg name="credentialsFd" type="h" direction="in"/>
</method>
<method name="IgnoreAuthSetup">
</method>
Expand Down
2 changes: 1 addition & 1 deletion debian/dde-file-manager-services-plugins.install
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ usr/share/dbus-1/system-services/*.service
usr/share/dbus-1/system.d/org.deepin.filemanager.diskencrypt.conf
usr/share/dbus-1/services/org.deepin.Filemanager.TextIndex.service
etc/systemd/system/deepin-service-group@.service.d/*
etc/polkit-1/localauthority/10-vendor.d/99-dde-file-manager-encrypt.pkla
usr/share/polkit-1/rules.d/99-dde-file-manager-encrypt.rules
etc/udev/rules.d/*.rules
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@
#include <QDBusInterface>
#include <QDBusReply>
#include <QApplication>
#include <QJsonDocument>

Check warning on line 26 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QJsonDocument> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 26 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QJsonDocument> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QJsonObject>

Check warning on line 27 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QJsonObject> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 27 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QJsonObject> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QJsonParseError>

Check warning on line 28 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QJsonParseError> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 28 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QJsonParseError> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusUnixFileDescriptor>

Check warning on line 29 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusUnixFileDescriptor> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 29 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QDBusUnixFileDescriptor> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDataStream>

Check warning on line 30 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDataStream> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 30 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QDataStream> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <ddialog.h>

Check warning on line 32 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <ddialog.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 32 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <ddialog.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dconfig.h>

Check warning on line 33 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dconfig.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 33 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dconfig.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <fstab.h>

Check warning on line 35 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <fstab.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 35 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <fstab.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unistd.h>

Check warning on line 36 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <unistd.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 36 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <unistd.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

DFMBASE_USE_NAMESPACE
using namespace dfmplugin_diskenc;
Expand Down Expand Up @@ -395,23 +398,24 @@
kDaemonBusPath,
kDaemonBusIface,
QDBusConnection::systemBus());
if (iface.isValid()) {
QVariantMap params {
{ encrypt_param_keys::kKeyDevice, param.devDesc },
{ encrypt_param_keys::kKeyPassphrase, toBase64(param.key) },
{ encrypt_param_keys::kKeyExportToPath, param.exportPath },
};
if (!tpmToken.isEmpty()) params.insert(encrypt_param_keys::kKeyTPMToken, tpmToken);

fmDebug() << "Starting device re-encryption";
QDBusReply<bool> ret = iface.call("SetupAuthArgs", params);
if (ret.value()) {
QApplication::setOverrideCursor(Qt::WaitCursor);
} else {
fmCritical() << "Re-encryption setup failed";
}
} else {
if (!iface.isValid()) {
fmCritical() << "Failed to create D-Bus interface for re-encryption";
return;
}

// Prepare credentials data
QVariantMap params {
{ encrypt_param_keys::kKeyDevice, param.devDesc },
{ encrypt_param_keys::kKeyPassphrase, toBase64(param.key) },
{ encrypt_param_keys::kKeyExportToPath, param.exportPath },
};
if (!tpmToken.isEmpty())
params.insert(encrypt_param_keys::kKeyTPMToken, tpmToken);

// Send credentials via fd
fmDebug() << "Starting device re-encryption via fd";
if (sendCredentialsViaFd(iface, "SetupAuthArgs", params, true)) {
QApplication::setOverrideCursor(Qt::WaitCursor);
}
}

Expand All @@ -421,25 +425,26 @@
kDaemonBusPath,
kDaemonBusIface,
QDBusConnection::systemBus());
if (iface.isValid()) {
QVariantMap params {
{ encrypt_param_keys::kKeyJobType, param.jobType },
{ encrypt_param_keys::kKeyDevice, param.devDesc },
{ encrypt_param_keys::kKeyDeviceName, param.deviceDisplayName },
{ encrypt_param_keys::kKeyPassphrase, toBase64(param.key) }
};
if (!iface.isValid()) {
fmCritical() << "Failed to create D-Bus interface for decryption";
return;
}

fmDebug() << "Calling Decryption D-Bus method";
QDBusReply<bool> ret = iface.call("Decryption", params);
if (ret.value()) {
QApplication::setOverrideCursor(Qt::WaitCursor);
} else {
fmCritical() << "Decryption failed to start";
}
// Prepare credentials data
QVariantMap params {
{ encrypt_param_keys::kKeyJobType, param.jobType },
{ encrypt_param_keys::kKeyDevice, param.devDesc },
{ encrypt_param_keys::kKeyDeviceName, param.deviceDisplayName },
{ encrypt_param_keys::kKeyPassphrase, toBase64(param.key) }
};

// Send credentials via fd
fmDebug() << "Calling Decryption D-Bus method via fd";
if (sendCredentialsViaFd(iface, "Decryption", params, false)) {
QApplication::setOverrideCursor(Qt::WaitCursor);
EventsHandler::instance()->autoStartDFM();
} else {
fmCritical() << "Failed to create D-Bus interface for decryption";
fmCritical() << "Decryption failed to start";
}
}

Expand Down Expand Up @@ -474,6 +479,16 @@
kDaemonBusIface,
QDBusConnection::systemBus());
if (iface.isValid()) {
// Create anonymous pipe for secure credential transmission
int pipefd[2];
if (pipe(pipefd) == -1) {
fmCritical() << "Failed to create anonymous pipe for credentials";
return;
}

// Prepare credentials data using QDataStream for reliable serialization
QByteArray credentials;
QDataStream stream(&credentials, QIODevice::WriteOnly);
QVariantMap params {
{ encrypt_param_keys::kKeyDevice, param.devDesc },
{ encrypt_param_keys::kKeyPassphrase, toBase64(param.newKey) },
Expand All @@ -482,14 +497,36 @@
{ encrypt_param_keys::kKeyTPMToken, token },
{ encrypt_param_keys::kKeyDeviceName, param.deviceDisplayName }
};
stream << params;

// Write credentials to pipe and close write end immediately
ssize_t written = write(pipefd[1], credentials.constData(), credentials.size());
close(pipefd[1]); // Close write end immediately after writing

if (written != credentials.size()) {
fmCritical() << "Failed to write credentials to pipe, written:" << written << "expected:" << credentials.size();
close(pipefd[0]);
return;
}
Comment on lines +502 to +510
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: No retry or partial write handling for pipe write.

write() may not write all bytes at once, especially with large buffers. Loop until all bytes are written to guarantee complete transmission.

Suggested change
// Write credentials to pipe and close write end immediately
ssize_t written = write(pipefd[1], credentials.constData(), credentials.size());
close(pipefd[1]); // Close write end immediately after writing
if (written != credentials.size()) {
fmCritical() << "Failed to write credentials to pipe, written:" << written << "expected:" << credentials.size();
close(pipefd[0]);
return;
}
// Write credentials to pipe and close write end immediately
const char* buf = credentials.constData();
qint64 totalWritten = 0;
qint64 toWrite = credentials.size();
while (totalWritten < toWrite) {
ssize_t written = write(pipefd[1], buf + totalWritten, toWrite - totalWritten);
if (written < 0) {
fmCritical() << "Error writing credentials to pipe:" << strerror(errno);
close(pipefd[1]);
close(pipefd[0]);
return;
}
totalWritten += written;
}
close(pipefd[1]); // Close write end immediately after writing
if (totalWritten != credentials.size()) {
fmCritical() << "Failed to write all credentials to pipe, written:" << totalWritten << "expected:" << credentials.size();
close(pipefd[0]);
return;
}


// Create file descriptor for D-Bus transmission
QDBusUnixFileDescriptor fd(pipefd[0]);
if (!fd.isValid()) {
fmCritical() << "Failed to create valid file descriptor from pipe";
close(pipefd[0]);
return;
}

fmDebug() << "Calling ChangePassphrase D-Bus method";
QDBusReply<bool> ret = iface.call("ChangePassphrase", params);
fmDebug() << "Calling ChangePassphrase D-Bus method via fd";
QDBusReply<bool> ret = iface.call("ChangePassphrase", QVariant::fromValue(fd));
if (ret.value()) {
QApplication::setOverrideCursor(Qt::WaitCursor);
} else {
fmCritical() << "Passphrase change failed to start";
}

// Close read end (D-Bus service will have its own copy)
close(pipefd[0]);
} else {
fmCritical() << "Failed to create D-Bus interface for passphrase change";
}
Expand Down Expand Up @@ -563,6 +600,54 @@
return QString(contents.toBase64());
}

bool DiskEncryptMenuScene::sendCredentialsViaFd(QDBusInterface &iface, const QString &method,
const QVariantMap &params, bool asyncCall)
{
// Create anonymous pipe for secure credential transmission
int pipefd[2];
if (pipe(pipefd) == -1) {
fmCritical() << "[sendCredentialsViaFd] Failed to create anonymous pipe for credentials";
return false;
}

// Prepare credentials data using QDataStream for reliable serialization
QByteArray credentials;
QDataStream stream(&credentials, QIODevice::WriteOnly);
stream << params;

// Write credentials to pipe and close write end immediately
ssize_t written = write(pipefd[1], credentials.constData(), credentials.size());
close(pipefd[1]); // Close write end immediately after writing

if (written != credentials.size()) {
fmCritical() << "[sendCredentialsViaFd] Failed to write credentials to pipe, written:" << written << "expected:" << credentials.size();
close(pipefd[0]);
return false;
}

// Create file descriptor for D-Bus transmission
QDBusUnixFileDescriptor fd(pipefd[0]);
if (!fd.isValid()) {
fmCritical() << "[sendCredentialsViaFd] Failed to create valid file descriptor from pipe";
close(pipefd[0]);
return false;
}

// Call D-Bus method with file descriptor
fmDebug() << "[sendCredentialsViaFd] Calling D-Bus method:" << method << "via fd";
if (asyncCall) {
iface.asyncCall(method, QVariant::fromValue(fd));
} else {
QDBusReply<bool> reply = iface.call(method, QVariant::fromValue(fd));
close(pipefd[0]);
return reply.value();
}

// Close read end (D-Bus service will have its own copy)
close(pipefd[0]);
return true;
}

void DiskEncryptMenuScene::onUnlocked(bool ok, dfmmount::OperationErrorInfo info, QString clearDev)
{
QApplication::restoreOverrideCursor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
#include <dfm-base/interfaces/abstractmenuscene.h>
#include <dfm-base/interfaces/abstractscenecreator.h>

#include <dfm-mount/dmount.h>

Check warning on line 13 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-mount/dmount.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 13 in src/plugins/filemanager/dfmplugin-disk-encrypt-entry/menu/diskencryptmenuscene.h

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-mount/dmount.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <QUrl>
#include <QDBusInterface>

class QAction;

Expand Down Expand Up @@ -60,6 +61,10 @@
static QString generateTPMToken(const QString &device, bool pin);
static QString getBase64Of(const QString &fileName);

// Send credentials via file descriptor for secure D-Bus transmission
static bool sendCredentialsViaFd(QDBusInterface &iface, const QString &method,
const QVariantMap &params, bool asyncCall = false);

static void onUnlocked(bool ok, dfmmount::OperationErrorInfo, QString);
static void onMounted(bool ok, dfmmount::OperationErrorInfo, QString);

Expand Down
8 changes: 6 additions & 2 deletions src/services/diskencrypt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ install(FILES org.deepin.Filemanager.DiskEncrypt.service DESTINATION share/dbus-
install(FILES ${CMAKE_SOURCE_DIR}/assets/rules/99-dfm-encrypt.rules DESTINATION /etc/udev/rules.d)

set(PolicyDir "${CMAKE_INSTALL_PREFIX}/share/polkit-1/actions")
set(RulesDir "${CMAKE_INSTALL_PREFIX}/share/polkit-1/rules.d")

install(FILES polkit/policy/org.deepin.filemanager.diskencrypt.policy
DESTINATION ${PolicyDir})
install(FILES polkit/rules/99-dde-file-manager-encrypt.pkla
DESTINATION /etc/polkit-1/localauthority/10-vendor.d)

# Install polkit rules (JavaScript format, replaces deprecated .pkla)
install(FILES polkit/rules/99-dde-file-manager-encrypt.rules
DESTINATION ${RulesDir})
Loading
Loading