From 6d2b32fa4ba9644c21e401d0aab0cdc716e7b12e Mon Sep 17 00:00:00 2001 From: gongheng Date: Wed, 20 May 2026 17:23:51 +0800 Subject: [PATCH] refactor: secure password transmission by QDBusUnixFileDescriptor Changed from using base64-encoded password strings to using QDBusUnixFileDescriptor for transmitting passwords during network mount operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Log: Enhanced security of password transmission in network mounting Influence: 1. Test network mount with password to ensure successful authentication 2. Verify anonymous mount still works without password 3. Validate password saving functionality when savePasswd is enabled 4. Test mount failure scenarios (wrong password, network error) to ensure error handling 5. Ensure compatibility with existing D-Bus service (MountControl) that expects file descriptor feat: 在网络挂载中使用文件描述符安全传输密码 将密码传输从 base64 编码字符串改为使用 QDBusUnixFileDescriptor Log: 改进了网络挂载中密码传输的安全性 Task: https://pms.uniontech.com/task-view-389921.html Influence: 1. 测试带密码的网络挂载,确保认证成功 2. 验证匿名挂载在无密码时仍能正常工作 3. 验证启用 savePasswd 时的密码保存功能 4. 测试挂载失败场景(错误密码、网络错误)以确保错误处理正常 5. 确保与现有 D-Bus 服务(MountControl)的兼容性,该服务期望接收文件描述符 --- src/dfm-mount/private/dnetworkmounter.cpp | 55 +++++++++++++++++------ 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/dfm-mount/private/dnetworkmounter.cpp b/src/dfm-mount/private/dnetworkmounter.cpp index b8baa08d..f4f6b828 100644 --- a/src/dfm-mount/private/dnetworkmounter.cpp +++ b/src/dfm-mount/private/dnetworkmounter.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2022 - 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -13,9 +13,12 @@ #include #include #include +#include #include +#include + DFM_MOUNT_USE_NS static constexpr char kDaemonService[] { "com.deepin.filemanager.daemon" }; @@ -148,9 +151,7 @@ QList DNetworkMounter::loginPasswd(const QString &address) if (err) qDebug() << "query password failed: " << passwd << err->message; else { - // since daemon accept base64-ed passwd to mount cifs, cleartext should be encoded with base64 - // see commit of dde-file-manager: 3b50664d4034754b15c1a516cfaab8c7fbdd3db9 - passwd.insert(kLoginPasswd, QString(QByteArray(pwd).toBase64())); + passwd.insert(kLoginPasswd, pwd); } } return passwds; @@ -471,12 +472,45 @@ void DNetworkMounter::mountByGvfsCallback(GObject *srcObj, GAsyncResult *res, gp delete finalize; } +static QVariant preparePasswd(const QString &passwd) +{ + if (passwd.isEmpty()) { + qCritical() << "Created empty QVariant for empty passwd"; + return QVariant(""); + } + + int fd = memfd_create("DBusFD", MFD_CLOEXEC); + if (fd < 0) { + qCritical() << "Failed to create memfd for data transfer"; + return QVariant(""); + } + + QByteArray byteData = passwd.toUtf8(); + ssize_t written = ::write(fd, byteData.constData(), byteData.size()); + if (written < 0 || static_cast(byteData.size()) != written) { + qCritical() << "Failed to write data to memfd"; + ::close(fd); + return QVariant(""); + } + + if (lseek(fd, 0, SEEK_SET) < 0) { + qCritical() << "Failed to seek memfd to beginning"; + ::close(fd); + return QVariant(""); + } + + QDBusUnixFileDescriptor dbusFd; + dbusFd.giveFileDescriptor(fd); + + return QVariant::fromValue(dbusFd); +} + DNetworkMounter::MountRet DNetworkMounter::mountWithUserInput(const QString &address, const MountPassInfo info) { QVariantMap param { { kLoginUser, info.userName }, { kLoginDomain, info.domain }, - { kLoginPasswd, info.passwd }, + { kLoginPasswd, preparePasswd(info.passwd) }, { kLoginTimeout, info.timeout }, { kMountFsType, "cifs" } }; @@ -495,13 +529,8 @@ DNetworkMounter::MountRet DNetworkMounter::mountWithUserInput(const QString &add if (ok) { err = DeviceError::kNoError; - if (!info.anonymous && info.savePasswd != NetworkMountPasswdSaveMode::kNeverSavePasswd) { - // since passwd from user input is base64-ed data, so the passwd should be decoded into cleartext for saving. - // associated commit of dde-file-manager: 3b50664d4034754b15c1a516cfaab8c7fbdd3db9 - auto _info = info; - _info.passwd = QByteArray::fromBase64(info.passwd.toLocal8Bit()); - savePasswd(address, _info); - } + if (!info.anonymous && info.savePasswd != NetworkMountPasswdSaveMode::kNeverSavePasswd) + savePasswd(address, info); } return { ok, err, mpt }; @@ -517,7 +546,7 @@ DNetworkMounter::MountRet DNetworkMounter::mountWithSavedInfos(const QString &ad for (const auto &login : infos) { QVariantMap param { { kLoginUser, login.value(kSchemaUser, "") }, { kLoginDomain, login.value(kSchemaDomain, "") }, - { kLoginPasswd, login.value(kLoginPasswd, "") }, + { kLoginPasswd, preparePasswd(login.value(kLoginPasswd, "").toString()) }, { kLoginTimeout, secs }, { kMountFsType, "cifs" } };