mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
soliduiserver: use helper to mount/unmount
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
0bee712d44
commit
574a840200
4 changed files with 288 additions and 30 deletions
|
@ -1,5 +1,14 @@
|
|||
########### next target ###############
|
||||
|
||||
set(soliduiserver_helper_srcs
|
||||
soliduiserver_helper.cpp
|
||||
)
|
||||
|
||||
add_executable(soliduiserver_helper ${soliduiserver_helper_srcs})
|
||||
target_link_libraries(soliduiserver_helper PUBLIC ${KDE4_KDECORE_LIBS})
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(kded_soliduiserver_SRCS
|
||||
soliduiserver.cpp
|
||||
deviceactionsdialog.cpp
|
||||
|
@ -13,10 +22,13 @@ kde4_add_plugin(kded_soliduiserver ${kded_soliduiserver_SRCS})
|
|||
|
||||
target_link_libraries(kded_soliduiserver ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS})
|
||||
|
||||
install(TARGETS kded_soliduiserver DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install(TARGETS kded_soliduiserver DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
|
||||
|
||||
install(FILES soliduiserver.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR}/kded)
|
||||
|
||||
install(TARGETS soliduiserver_helper DESTINATION ${KDE4_LIBEXEC_INSTALL_DIR})
|
||||
|
||||
kde4_install_auth_helper_files(soliduiserver_helper org.kde.soliduiserver.mountunmounthelper root)
|
|
@ -26,6 +26,8 @@
|
|||
#include <klocale.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kdesktopfileactions.h>
|
||||
#include <kpassworddialog.h>
|
||||
#include <kauthaction.h>
|
||||
#include <kpluginfactory.h>
|
||||
#include <kpluginloader.h>
|
||||
#include <solid/block.h>
|
||||
|
@ -129,6 +131,43 @@ int SolidUiServer::mountDevice(const QString &udi)
|
|||
return int(Solid::ErrorType::InvalidOption);
|
||||
}
|
||||
|
||||
QString devicenode = block->device();
|
||||
if (storagevolume->usage() == Solid::StorageVolume::Encrypted) {
|
||||
KPasswordDialog passworddialog(0, KPasswordDialog::NoFlags);
|
||||
|
||||
QString label = device.vendor();
|
||||
if (!label.isEmpty()) {
|
||||
label += ' ';
|
||||
}
|
||||
label += device.product();
|
||||
|
||||
passworddialog.setPrompt(i18n("'%1' needs a password to be accessed. Please enter a password.", label));
|
||||
passworddialog.setPixmap(KIcon(device.icon()).pixmap(64, 64));
|
||||
if (!passworddialog.exec()) {
|
||||
return int(Solid::ErrorType::UserCanceled);
|
||||
}
|
||||
|
||||
KAuth::Action action("org.kde.soliduiserver.mountunmounthelper.cryptopen");
|
||||
action.setHelperID("org.kde.soliduiserver.mountunmounthelper");
|
||||
action.addArgument("device", block->device());
|
||||
action.addArgument("name", storagevolume->uuid());
|
||||
action.addArgument("password", passworddialog.password().toLocal8Bit().toHex());
|
||||
KAuth::ActionReply reply = action.execute();
|
||||
|
||||
// qDebug() << "cryptopen" << reply.errorCode() << reply.errorDescription() << reply.type();
|
||||
|
||||
if (reply == KAuth::ActionReply::UserCancelled) {
|
||||
return int(Solid::ErrorType::UserCanceled);
|
||||
} else if (reply == KAuth::ActionReply::AuthorizationDenied) {
|
||||
return int(Solid::ErrorType::UnauthorizedOperation);
|
||||
} else if (reply != KAuth::ActionReply::SuccessReply) {
|
||||
return int(Solid::ErrorType::OperationFailed);
|
||||
}
|
||||
|
||||
// NOTE: keep in sync with kdelibs/solid/solid/backends/udev/udevstorageaccess.cpp
|
||||
devicenode = QLatin1String("/dev/mapper/") + storagevolume->uuid();
|
||||
}
|
||||
|
||||
// permission denied on /run/mount so.. using base directory that is writable
|
||||
const QString mountbase = KGlobal::dirs()->saveLocation("tmp");
|
||||
const QString deviceuuid(storagevolume->uuid());
|
||||
|
@ -139,52 +178,67 @@ int SolidUiServer::mountDevice(const QString &udi)
|
|||
return int(Solid::ErrorType::OperationFailed);
|
||||
}
|
||||
|
||||
const QStringList mountargs = QStringList() << "mount" << block->device() << mountpoint;
|
||||
QProcess mountproc;
|
||||
mountproc.start("kdesudo", mountargs);
|
||||
mountproc.waitForStarted();
|
||||
while (mountproc.state() == QProcess::Running) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
KAuth::Action action("org.kde.soliduiserver.mountunmounthelper.mount");
|
||||
action.setHelperID("org.kde.soliduiserver.mountunmounthelper");
|
||||
action.addArgument("device", devicenode);
|
||||
action.addArgument("mountpoint", mountpoint);
|
||||
KAuth::ActionReply reply = action.execute();
|
||||
|
||||
if (mountproc.exitCode() == 0) {
|
||||
// qDebug() << "mount" << reply.errorCode() << reply.errorDescription() << reply.type();
|
||||
|
||||
if (reply == KAuth::ActionReply::SuccessReply) {
|
||||
return int(Solid::ErrorType::NoError);
|
||||
} else if (reply == KAuth::ActionReply::UserCancelled) {
|
||||
return int(Solid::ErrorType::UserCanceled);
|
||||
} else if (reply == KAuth::ActionReply::AuthorizationDenied) {
|
||||
return int(Solid::ErrorType::UnauthorizedOperation);
|
||||
}
|
||||
|
||||
QString mounterror = mountproc.readAllStandardError();
|
||||
if (mounterror.isEmpty()) {
|
||||
mounterror = mountproc.readAllStandardOutput();
|
||||
}
|
||||
kWarning() << "mount error" << mounterror;
|
||||
return int(Solid::ErrorType::OperationFailed);
|
||||
}
|
||||
|
||||
int SolidUiServer::unmountDevice(const QString &udi)
|
||||
{
|
||||
Solid::Device device(udi);
|
||||
Solid::StorageVolume *storagevolume = device.as<Solid::StorageVolume>();
|
||||
Solid::StorageAccess *storageaccess = device.as<Solid::StorageAccess>();
|
||||
if (!storageaccess) {
|
||||
if (!storagevolume || !storageaccess) {
|
||||
return int(Solid::ErrorType::InvalidOption);
|
||||
}
|
||||
|
||||
const QStringList umountargs = QStringList() << "umount" << storageaccess->filePath();
|
||||
QProcess umountproc;
|
||||
umountproc.start("kdesudo", umountargs);
|
||||
umountproc.waitForStarted();
|
||||
while (umountproc.state() == QProcess::Running) {
|
||||
QCoreApplication::processEvents();
|
||||
KAuth::Action action("org.kde.soliduiserver.mountunmounthelper.unmount");
|
||||
action.setHelperID("org.kde.soliduiserver.mountunmounthelper");
|
||||
action.addArgument("mountpoint", storageaccess->filePath());
|
||||
KAuth::ActionReply reply = action.execute();
|
||||
|
||||
// qDebug() << "unmount" << reply.errorCode() << reply.errorDescription();
|
||||
|
||||
if (reply == KAuth::ActionReply::UserCancelled) {
|
||||
return int(Solid::ErrorType::UserCanceled);
|
||||
} else if (reply == KAuth::ActionReply::AuthorizationDenied) {
|
||||
return int(Solid::ErrorType::UnauthorizedOperation);
|
||||
} else if (reply != KAuth::ActionReply::SuccessReply) {
|
||||
return int(Solid::ErrorType::OperationFailed);
|
||||
}
|
||||
|
||||
if (umountproc.exitCode() == 0) {
|
||||
return int(Solid::ErrorType::NoError);
|
||||
if (storagevolume->usage() == Solid::StorageVolume::Encrypted) {
|
||||
KAuth::Action action("org.kde.soliduiserver.mountunmounthelper.cryptclose");
|
||||
action.setHelperID("org.kde.soliduiserver.mountunmounthelper");
|
||||
action.addArgument("name", storagevolume->uuid());
|
||||
KAuth::ActionReply reply = action.execute();
|
||||
|
||||
// qDebug() << "cryptclose" << reply.errorCode() << reply.errorDescription() << reply.type();
|
||||
|
||||
if (reply == KAuth::ActionReply::UserCancelled) {
|
||||
return int(Solid::ErrorType::UserCanceled);
|
||||
} else if (reply == KAuth::ActionReply::AuthorizationDenied) {
|
||||
return int(Solid::ErrorType::UnauthorizedOperation);
|
||||
} else if (reply != KAuth::ActionReply::SuccessReply) {
|
||||
return int(Solid::ErrorType::OperationFailed);
|
||||
}
|
||||
}
|
||||
|
||||
QString umounterror = umountproc.readAllStandardError();
|
||||
if (umounterror.isEmpty()) {
|
||||
umounterror = umountproc.readAllStandardOutput();
|
||||
}
|
||||
kWarning() << "unmount error" << umounterror;
|
||||
return int(Solid::ErrorType::OperationFailed);
|
||||
return int(Solid::ErrorType::NoError);
|
||||
}
|
||||
|
||||
#include "moc_soliduiserver.cpp"
|
||||
|
|
154
soliduiserver/soliduiserver_helper.cpp
Normal file
154
soliduiserver/soliduiserver_helper.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "soliduiserver_helper.h"
|
||||
|
||||
#include <kauthhelpersupport.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
|
||||
KAuth::ActionReply SolidUiServerHelper::cryptopen(QVariantMap parameters)
|
||||
{
|
||||
if (!parameters.contains("device") || !parameters.contains("name") || !parameters.contains("password")) {
|
||||
return KAuth::ActionReply::HelperErrorReply;
|
||||
}
|
||||
|
||||
const QString cryptbin = KStandardDirs::findRootExe("cryptsetup");
|
||||
if (cryptbin.isEmpty()) {
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription("cryptsetup is missing");
|
||||
errorReply.setErrorCode(1);
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
const QString device = parameters.value("device").toString();
|
||||
const QString name = parameters.value("name").toString();
|
||||
const QByteArray password = QByteArray::fromHex(parameters.value("password").toByteArray());
|
||||
const QStringList cryptargs = QStringList() << "--batch-mode" << "--key-file=-" << "open" << device << name;
|
||||
QProcess cryptproc;
|
||||
cryptproc.start(cryptbin, cryptargs);
|
||||
cryptproc.waitForStarted();
|
||||
cryptproc.write(password);
|
||||
cryptproc.closeWriteChannel();
|
||||
cryptproc.waitForFinished();
|
||||
|
||||
if (cryptproc.exitCode() == 0) {
|
||||
return KAuth::ActionReply::SuccessReply;
|
||||
}
|
||||
QString crypterror = cryptproc.readAllStandardError();
|
||||
if (crypterror.isEmpty()) {
|
||||
crypterror = cryptproc.readAllStandardOutput();
|
||||
}
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription(crypterror);
|
||||
errorReply.setErrorCode(cryptproc.exitCode());
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
KAuth::ActionReply SolidUiServerHelper::cryptclose(QVariantMap parameters)
|
||||
{
|
||||
if (!parameters.contains("name")) {
|
||||
return KAuth::ActionReply::HelperErrorReply;
|
||||
}
|
||||
|
||||
const QString cryptbin = KStandardDirs::findRootExe("cryptsetup");
|
||||
if (cryptbin.isEmpty()) {
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription("cryptsetup is missing");
|
||||
errorReply.setErrorCode(1);
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
const QString name = parameters.value("name").toString();
|
||||
const QStringList cryptargs = QStringList() << "--batch-mode" << "close" << name;
|
||||
QProcess cryptproc;
|
||||
cryptproc.start(cryptbin, cryptargs);
|
||||
cryptproc.waitForStarted();
|
||||
cryptproc.waitForFinished();
|
||||
|
||||
if (cryptproc.exitCode() == 0) {
|
||||
return KAuth::ActionReply::SuccessReply;
|
||||
}
|
||||
QString crypterror = cryptproc.readAllStandardError();
|
||||
if (crypterror.isEmpty()) {
|
||||
crypterror = cryptproc.readAllStandardOutput();
|
||||
}
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription(crypterror);
|
||||
errorReply.setErrorCode(cryptproc.exitCode());
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
KAuth::ActionReply SolidUiServerHelper::mount(QVariantMap parameters)
|
||||
{
|
||||
if (!parameters.contains("device") || !parameters.contains("mountpoint")) {
|
||||
return KAuth::ActionReply::HelperErrorReply;
|
||||
}
|
||||
|
||||
const QString device = parameters.value("device").toString();
|
||||
const QString mountpoint = parameters.value("mountpoint").toString();
|
||||
const QStringList mountargs = QStringList() << device << mountpoint;
|
||||
QProcess mountproc;
|
||||
mountproc.start("mount", mountargs);
|
||||
mountproc.waitForStarted();
|
||||
mountproc.waitForFinished();
|
||||
|
||||
if (mountproc.exitCode() == 0) {
|
||||
return KAuth::ActionReply::SuccessReply;
|
||||
}
|
||||
QString mounterror = mountproc.readAllStandardError();
|
||||
if (mounterror.isEmpty()) {
|
||||
mounterror = mountproc.readAllStandardOutput();
|
||||
}
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription(mounterror);
|
||||
errorReply.setErrorCode(mountproc.exitCode());
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
KAuth::ActionReply SolidUiServerHelper::unmount(QVariantMap parameters)
|
||||
{
|
||||
if (!parameters.contains("mountpoint")) {
|
||||
return KAuth::ActionReply::HelperErrorReply;
|
||||
}
|
||||
|
||||
const QString mountpoint = parameters.value("mountpoint").toString();
|
||||
const QStringList umountargs = QStringList() << mountpoint;
|
||||
QProcess umountproc;
|
||||
umountproc.start("umount", umountargs);
|
||||
umountproc.waitForStarted();
|
||||
umountproc.waitForFinished();
|
||||
|
||||
if (umountproc.exitCode() == 0) {
|
||||
return KAuth::ActionReply::SuccessReply;
|
||||
}
|
||||
QString umounterror = umountproc.readAllStandardError();
|
||||
if (umounterror.isEmpty()) {
|
||||
umounterror = umountproc.readAllStandardOutput();
|
||||
}
|
||||
KAuth::ActionReply errorReply(KAuth::ActionReply::HelperError);
|
||||
errorReply.setErrorDescription(umounterror);
|
||||
errorReply.setErrorCode(umountproc.exitCode());
|
||||
return errorReply;
|
||||
}
|
||||
|
||||
KDE4_AUTH_HELPER_MAIN("org.kde.soliduiserver.mountunmounthelper", SolidUiServerHelper)
|
38
soliduiserver/soliduiserver_helper.h
Normal file
38
soliduiserver/soliduiserver_helper.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef SOLIDUISERVER_HELPER_H
|
||||
#define SOLIDUISERVER_HELPER_H
|
||||
|
||||
#include <kauthactionreply.h>
|
||||
#include <QObject>
|
||||
|
||||
// methods return type must be ActionReply otherwise QMetaObject::invokeMethod() fails
|
||||
using namespace KAuth;
|
||||
|
||||
class SolidUiServerHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public Q_SLOTS:
|
||||
ActionReply cryptopen(QVariantMap parameters);
|
||||
ActionReply cryptclose(QVariantMap parameters);
|
||||
ActionReply mount(QVariantMap parameters);
|
||||
ActionReply unmount(QVariantMap parameters);
|
||||
};
|
||||
|
||||
#endif // SOLIDUISERVER_HELPER_H
|
Loading…
Add table
Reference in a new issue