From 0ab42ed2a6e66d6f5e8a85b5f8ce6b24d233a02e Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sun, 2 Jun 2024 23:34:05 +0300 Subject: [PATCH] kdesudo: rework it to use new program for password prompt on a side note git and ssh do not use the environment variables (GIT_ASKPASS and SSH_ASKPASS) for refernece: https://ivailo-monev.atlassian.net/browse/KDE-9 Signed-off-by: Ivailo Monev kdesudo: asd Signed-off-by: Ivailo Monev --- kdesudo/CMakeLists.txt | 22 ++- kdesudo/kaskpass.cpp | 104 ++++++++++ kdesudo/kdesudo.cpp | 270 +++++++++++++++----------- kdesudo/kdesudo.h | 24 +-- kdesudo/main.cpp | 150 -------------- kwin/effects/dimscreen/dimscreen.kcfg | 2 +- 6 files changed, 285 insertions(+), 287 deletions(-) create mode 100644 kdesudo/kaskpass.cpp delete mode 100644 kdesudo/main.cpp diff --git a/kdesudo/CMakeLists.txt b/kdesudo/CMakeLists.txt index 530e3add..986aae3c 100644 --- a/kdesudo/CMakeLists.txt +++ b/kdesudo/CMakeLists.txt @@ -9,22 +9,32 @@ add_feature_info("pr_set_dumpable" HAVE_PR_SET_DUMPABLE "Used to disallow proces check_symbol_exists(procctl "sys/procctl.h" HAVE_PROCCTL) add_feature_info("procctl" HAVE_PROCCTL "Used to disallow process tracing") -configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) +configure_file( + config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/config.h +) add_definitions(-DKDE_DEFAULT_DEBUG_AREA=900) -set(KDESUDO_SRC - main.cpp +set(kdesudo_SRC kdesudo.cpp ) -add_executable(kdesudo ${KDESUDO_SRC}) - +add_executable(kdesudo ${kdesudo_SRC}) target_link_libraries(kdesudo KDE4::kdeui ) +set(kaskpass_SRC + kaskpass.cpp +) + +add_executable(kaskpass ${kaskpass_SRC}) +target_link_libraries(kaskpass + KDE4::kdeui +) + install( - TARGETS kdesudo + TARGETS kdesudo kaskpass DESTINATION ${KDE4_BIN_INSTALL_DIR} ) diff --git a/kdesudo/kaskpass.cpp b/kdesudo/kaskpass.cpp new file mode 100644 index 00000000..4c12fbe2 --- /dev/null +++ b/kdesudo/kaskpass.cpp @@ -0,0 +1,104 @@ +/* + This file is part of the KDE project + Copyright (C) 2024 Ivailo Monev + + 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 "config.h" + +#include +#include +#include +#include +#include + +#include + +#if defined(HAVE_PR_SET_DUMPABLE) +# include +#elif defined(HAVE_PROCCTL) +# include +# include +#endif + +static QString kLocalString(const QByteArray &bytes) +{ + return QString::fromLocal8Bit(bytes.constData(), bytes.size()); +} + +static QByteArray kLocalBytes(const QString &string) +{ + return string.toLocal8Bit(); +} + +int main(int argc, char **argv) +{ +#if defined(HAVE_PR_SET_DUMPABLE) + prctl(PR_SET_DUMPABLE, 0); +#elif defined(HAVE_PROCCTL) + int ctldata = PROC_TRACE_CTL_DISABLE; + procctl(P_PID, ::getpid(), PROC_TRACE_CTL, &ctldata); +#endif + + KAboutData about( + "kaskpass", 0, ki18n("KAskPass"), + "1.0.0", ki18n("Password prompt for KDE"), + KAboutData::License_GPL, + ki18n("(C) 2024 Ivailo Monev") + ); + KCmdLineArgs::init(&about); + + KApplication app; + app.disableSessionManagement(); + + KPasswordDialog dialog; + dialog.setDefaultButton(KDialog::Ok); + const QByteArray winid = qgetenv("KASKPASS_MAINWINDOW"); + if (!winid.isEmpty()) { + KWindowSystem::setMainWindow(&dialog, static_cast(winid.toULong())); + } + const QByteArray icon = qgetenv("KASKPASS_ICON"); + if (!icon.isEmpty()) { + dialog.setPixmap(QPixmap(kLocalString(icon))); + } + const QByteArray label0 = qgetenv("KASKPASS_LABEL0"); + if (!label0.isEmpty()) { + const QByteArray comment0 = qgetenv("KASKPASS_COMMENT0"); + dialog.addCommentLine(kLocalString(label0), kLocalString(comment0)); + } + const QByteArray label1 = qgetenv("KASKPASS_LABEL1"); + if (!label1.isEmpty()) { + const QByteArray comment1 = qgetenv("KASKPASS_COMMENT1"); + dialog.addCommentLine(kLocalString(label1), kLocalString(comment1)); + } + QByteArray prompt = qgetenv("KASKPASS_PROMPT"); + if (prompt.isEmpty()) { + // in case it is used by something other than kdesudo + prompt = qgetenv("SSH_ASKPASS_PROMPT"); + } + if (!prompt.isEmpty()) { + dialog.setPrompt(kLocalString(prompt)); + } + + const int result = dialog.exec(); + if (result == QDialog::Accepted) { + const QByteArray pass = kLocalBytes(dialog.password()); + fprintf(stdout, "%s\n", pass.constData()); + fflush(stdout); + return 0; + } + return 1; +} diff --git a/kdesudo/kdesudo.cpp b/kdesudo/kdesudo.cpp index 9222ba31..e384d792 100644 --- a/kdesudo/kdesudo.cpp +++ b/kdesudo/kdesudo.cpp @@ -21,32 +21,37 @@ * * ***************************************************************************/ +#include "config.h" #include "kdesudo.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include #include #include -#include -#include +#include #include #include -#include #include +#include #include -#include -#include -#include +#if defined(HAVE_PR_SET_DUMPABLE) +# include +#elif defined(HAVE_PROCCTL) +# include +# include +#endif KdeSudo::KdeSudo(const QString &icon, const QString &appname) : QObject(), @@ -61,7 +66,6 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) bool changeUID = true; QString runas = args->getOption("u"); QString cmd; - bool attach = args->isSet("attach"); if (!args->isSet("c") && !args->count()) { KMessageBox::information( @@ -75,21 +79,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) exit(0); } - m_dialog = new KPasswordDialog(); - m_dialog->setDefaultButton(KDialog::Ok); - - if (attach) { - const WId winid = args->getOption("attach").toULong(); - KWindowSystem::setMainWindow(m_dialog, winid); - } - m_process = new QProcess(this); - /* load the icon */ - m_dialog->setPixmap(icon); - - // Parsins args - /* Get the comment out of cli args */ QString comment = args->getOption("comment"); @@ -116,26 +107,10 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) } } - connect(m_process, SIGNAL(readyReadStandardOutput()), - this, SLOT(parseOutput())); - - connect(m_process, SIGNAL(readyReadStandardError()), - this, SLOT(parseOutput())); - - connect(m_process, SIGNAL(finished(int)), - this, SLOT(procExited(int))); - - connect(m_dialog, SIGNAL(gotPassword(const QString & , bool)), - this, SLOT(pushPassword(const QString &))); - - connect(m_dialog, SIGNAL(rejected()), - this, SLOT(slotCancel())); - - // Generate the xauth cookie and put it in a tempfile - // set the environment variables to reflect that. - // Default cookie-timeout is 60 sec. . - // 'man xauth' for more info on xauth cookies. - m_tmpName = KTemporaryFile::filePath("/tmp/kdesudo-XXXXXXXXXX-xauth"); + connect( + m_process, SIGNAL(finished(int)), + this, SLOT(procExited(int)) + ); const QString disp = QString::fromLocal8Bit(qgetenv("DISPLAY")); if (disp.isEmpty()) { @@ -143,6 +118,20 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) exit(1); } + const QString kaskpass = KStandardDirs::findExe("kaskpass"); + if (kaskpass.isEmpty()) { + error(i18n("Could not find kaskpass program")); + // no application loop yet + exit(1); + return; + } + + // Generate the xauth cookie and put it in a tempfile + // set the environment variables to reflect that. + // Default cookie-timeout is 60 sec. . + // 'man xauth' for more info on xauth cookies. + m_tmpName = KTemporaryFile::filePath("/tmp/kdesudo-XXXXXXXXXX-xauth"); + // Create two processes, one for each xauth call QProcess xauth_ext; QProcess xauth_merge; @@ -184,7 +173,11 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) processEnv.insert("LC_ALL", "C"); processEnv.insert("DISPLAY", disp); processEnv.insert("XAUTHORITY", m_tmpName); - m_process->setProcessEnvironment(processEnv); + processEnv.insert("SUDO_ASKPASS", kaskpass); + processEnv.insert("KASKPASS_ICON", icon); + if (args->isSet("attach")) { + processEnv.insert("KASKPASS_MAINWINDOW", args->getOption("attach")); + } QStringList processArgs; { @@ -193,8 +186,12 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) // potentially in such a way that it uses the cached credentials of a // previously kdesudo run in that same scope. processArgs << "-k"; + // Preserve all possible kaskpass environment variables + processArgs << "--preserve-env=KASKPASS_ICON,KASKPASS_MAINWINDOW,KASKPASS_LABEL0,KASKPASS_COMMENT0,KASKPASS_LABEL1,KASKPASS_COMMENT1,KASKPASS_PROMPT"; + // Always use kaskpass + processArgs << "-A"; if (changeUID) { - processArgs << "-H" << "-S" << "-p" << "passprompt"; + processArgs << "-H"; if (!runas.isEmpty()) { processArgs << "-u" << runas; @@ -204,8 +201,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) if (realtime) { processArgs << "nice" << "-n" << "10"; - m_dialog->addCommentLine(i18n("Priority:"), i18n("realtime:") + - QChar(' ') + QString("50/100")); + processEnv.insert("KASKPASS_LABEL0", i18n("Priority:")); + processEnv.insert("KASKPASS_COMMENT0", QString::fromLatin1("50/100")); processArgs << "--"; } else if (priority) { QString n = args->getOption("p"); @@ -213,7 +210,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) intn = (intn * 40 / 100) - (20 + 0.5); processArgs << "nice" << "-n" << QString::number(intn); - m_dialog->addCommentLine(i18n("Priority:"), n + QString("/100")); + processEnv.insert("KASKPASS_LABEL0", i18n("Priority:")); + processEnv.insert("KASKPASS_COMMENT0", QString::fromLatin1("%1/100").arg(n)); processArgs << "--"; } @@ -227,9 +225,7 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) processArgs << "sh"; processArgs << "-c"; processArgs << command; - } - - else if (args->count()) { + } else if (args->count()) { for (int i = 0; i < args->count(); i++) { if ((!args->isSet("c")) && (i == 0)) { QStringList argsSplit = KShell::splitArgs(args->arg(i)); @@ -249,7 +245,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) } // strcmd needs to be defined if (showCommand && !cmd.isEmpty()) { - m_dialog->addCommentLine(i18n("Command:"), cmd); + processEnv.insert("KASKPASS_LABEL1", i18n("Command:")); + processEnv.insert("KASKPASS_COMMENT1", cmd); } } @@ -263,22 +260,21 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname) } if (!appname.isEmpty()) { - m_dialog->setPrompt(defaultComment.arg(appname)); + processEnv.insert("KASKPASS_PROMPT", defaultComment.arg(appname)); } else { - m_dialog->setPrompt(defaultComment.arg(cmd)); + processEnv.insert("KASKPASS_PROMPT", defaultComment.arg(cmd)); } } else { - m_dialog->setPrompt(comment); + processEnv.insert("KASKPASS_PROMPT", comment); } - m_process->setProcessChannelMode(QProcess::MergedChannels); + m_process->setProcessEnvironment(processEnv); m_process->start("sudo", processArgs); } KdeSudo::~KdeSudo() { - delete m_dialog; if (m_process) { m_process->terminate(); m_process->waitForFinished(3000); @@ -295,43 +291,6 @@ void KdeSudo::error(const QString &msg) KApplication::kApplication()->exit(1); } -void KdeSudo::parseOutput() -{ - QString strOut = m_process->readAllStandardOutput(); - - static int badpass = 0; - - if (strOut.contains("try again")) { - badpass++; - if (badpass == 1) { - m_dialog->addCommentLine(i18n("Warning: "), i18n("Incorrect password, please try again.")); - m_dialog->show(); - } else if (badpass == 2) { - m_dialog->show(); - } else { - error(i18n("Wrong password! Exiting...")); - } - // NOTE: "command not found" comes from `sudo` while "No such file or directory" comes from - // either `nice` or `dbus-run-session` - } else if (strOut.contains("command not found") || strOut.contains("No such file or directory")) { - error(i18n("Command not found!")); - } else if (strOut.contains("is not in the sudoers file")) { - error(i18n("Your username is unknown to sudo!")); - } else if (strOut.contains("is not allowed to execute")) { - error(i18n("Your user is not allowed to run the specified command!")); - } else if (strOut.contains("is not allowed to run sudo on")) { - error(i18n("Your user is not allowed to run sudo on this host!")); - } else if (strOut.contains("may not run sudo on")) { - error(i18n("Your user is not allowed to run sudo on this host!")); - } else if (strOut.contains("passprompt") || strOut.contains("PIN (CHV2)")) { - m_dialog->setPassword(QString()); - m_dialog->show(); - } else { - const QByteArray bytesOut = strOut.toLocal8Bit(); - fprintf(stdout, "%s", bytesOut.constData()); - } -} - void KdeSudo::procExited(int exitCode) { if (!m_error) { @@ -339,16 +298,6 @@ void KdeSudo::procExited(int exitCode) } } -void KdeSudo::pushPassword(const QString &pwd) -{ - m_process->write(pwd.toLocal8Bit() + "\n"); -} - -void KdeSudo::slotCancel() -{ - KApplication::kApplication()->exit(1); -} - QString KdeSudo::validArg(QString arg) { QChar firstChar = arg.at(0); @@ -360,3 +309,108 @@ QString KdeSudo::validArg(QString arg) } return arg; } + +int main(int argc, char **argv) +{ + // Disable tracing to prevent arbitrary apps reading password out of memory. +#if defined(HAVE_PR_SET_DUMPABLE) + prctl(PR_SET_DUMPABLE, 0); +#elif defined(HAVE_PROCCTL) + int ctldata = PROC_TRACE_CTL_DISABLE; + procctl(P_PID, ::getpid(), PROC_TRACE_CTL, &ctldata); +#endif + + KAboutData about( + "kdesudo", 0, ki18n("KdeSudo"), + "3.4.2.3", ki18n("Sudo frontend for KDE"), + KAboutData::License_GPL, + ki18n("(C) 2007 - 2008 Anthony Mercatante") + ); + + about.addAuthor(ki18n("Robert Gruber"), KLocalizedString(), + "rgruber@users.sourceforge.net", "http://test.com"); + about.addAuthor(ki18n("Anthony Mercatante"), KLocalizedString(), + "tonio@ubuntu.com"); + about.addAuthor(ki18n("Martin Böhm"), KLocalizedString(), + "martin.bohm@kubuntu.org"); + about.addAuthor(ki18n("Jonathan Riddell"), KLocalizedString(), + "jriddell@ubuntu.com"); + about.addAuthor(ki18n("Harald Sitter"), KLocalizedString(), + "apachelogger@ubuntu.com"); + + KCmdLineArgs::init(argc, argv, &about); + + KCmdLineOptions options; + options.add("u ", ki18n("sets a runas user")); + options.add("c ", ki18n("The command to execute")); + options.add("i ", ki18n("Specify icon to use in the password dialog")); + options.add("d", ki18n("Do not show the command to be run in the dialog")); + options.add("p ", ki18n("Process priority, between 0 and 100, 0 the lowest [50]")); + options.add("r", ki18n("Use realtime scheduling")); + options.add("f ", ki18n("Use target UID if is not writeable")); + options.add("nodbus", ki18n("Do not start a message bus")); + options.add("comment ", ki18n("The comment that should be " + "displayed in the dialog")); + options.add("attach ", ki18n("Makes the dialog transient for an X app specified by winid")); + options.add("desktop ", ki18n("Manual override for automatic desktop file detection")); + + options.add("+command", ki18n("The command to execute")); + + KCmdLineArgs::addCmdLineOptions(options); + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + KApplication a; + a.disableSessionManagement(); + + QString executable; + QStringList executableList; + KDesktopFile *desktopFile = nullptr; + + if (args->isSet("c")) { + executable = args->getOption("c"); + } + + if (args->count() && executable.isEmpty()) { + QString command = args->arg(0); + QStringList commandlist = command.split(" "); + executable = commandlist[0]; + } + + /* Have to make sure the executable is only the binary name */ + executableList = executable.split(" "); + executable = executableList[0]; + + executableList = executable.split("/"); + executable = executableList[executableList.count() - 1]; + + /* Kubuntu has a bug in it - this is a workaround for it */ + KGlobal::dirs()->addResourceDir("apps", "/usr/share/applications/kde4"); + KGlobal::dirs()->addResourceDir("apps", "/usr/share/kde4/services"); + KGlobal::dirs()->addResourceDir("apps", "/usr/share/applications"); + + QString path = getenv("PATH"); + QStringList pathList = path.split(":"); + for (int i = 0; i < pathList.count(); i++) { + executable.remove(pathList[i]); + } + + if (args->isSet("desktop")) { + desktopFile = new KDesktopFile(args->getOption("desktop")); + } else { + desktopFile = new KDesktopFile(executable + ".desktop"); + } + + /* icon parsing */ + QString icon; + if (args->isSet("i")) { + icon = args->getOption("i"); + } else { + QString iconName = desktopFile->readIcon(); + KIconLoader *loader = KIconLoader::global(); + icon = loader->iconPath(iconName, -1 * KIconLoader::StdSizes(KIconLoader::SizeHuge), true); + } + + a.setQuitOnLastWindowClosed(false); + KdeSudo kdesudo(icon, desktopFile->readName()); + return a.exec(); +} diff --git a/kdesudo/kdesudo.h b/kdesudo/kdesudo.h index 41901899..113c8c41 100644 --- a/kdesudo/kdesudo.h +++ b/kdesudo/kdesudo.h @@ -24,15 +24,11 @@ #include #include -#include -#include - /* * KdeSudo is the base class of the project * * @version 3.1 */ - class KdeSudo : QObject { Q_OBJECT @@ -40,35 +36,19 @@ public: KdeSudo(const QString &icon, const QString &appname); ~KdeSudo(); -private slots: - /** - * This slot gets executed if sudo creates some output - * -- well, in theory it should. Even though the code - * seems to be doing what the API says, it doesn't - * yet do what we need. - **/ - void parseOutput(); - +private Q_SLOTS: /** * This slot gets exectuted when sudo exits **/ void procExited(int exitCode); - /** - * This slot overrides the slot from KPasswordDialog - * @see KPasswordDialog - **/ - void pushPassword(const QString &); - void slotCancel(); - private: static QString validArg(QString arg); - void error(const QString &); + void error(const QString &msg); QProcess *m_process; bool m_error; QString m_tmpName; - KPasswordDialog *m_dialog; }; #endif // KDESUDO_H diff --git a/kdesudo/main.cpp b/kdesudo/main.cpp deleted file mode 100644 index ec4a4472..00000000 --- a/kdesudo/main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************** - kdesudo.cpp - description - ------------------- - begin : Sam Feb 15 15:42:12 CET 2003 - copyright : (C) 2003 by Robert Gruber - - (C) 2007 by Martin Böhm - Anthony Mercatante - Canonical Ltd (Jonathan Riddell - ) - (C) 2009-2015 by Harald Sitter - - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if defined(HAVE_PR_SET_DUMPABLE) -# include -#elif defined(HAVE_PROCCTL) -# include -# include -#endif - -#include "kdesudo.h" - -int main(int argc, char **argv) -{ - // Disable tracing to prevent arbitrary apps reading password out of memory. -#if defined(HAVE_PR_SET_DUMPABLE) - prctl(PR_SET_DUMPABLE, 0); -#elif defined(HAVE_PROCCTL) - int ctldata = PROC_TRACE_CTL_DISABLE; - procctl(P_PID, ::getpid(), PROC_TRACE_CTL, &ctldata); -#endif - - KAboutData about( - "kdesudo", 0, ki18n("KdeSudo"), - "3.4.2.3", ki18n("Sudo frontend for KDE"), - KAboutData::License_GPL, - ki18n("(C) 2007 - 2008 Anthony Mercatante") - ); - - about.addAuthor(ki18n("Robert Gruber"), KLocalizedString(), - "rgruber@users.sourceforge.net", "http://test.com"); - about.addAuthor(ki18n("Anthony Mercatante"), KLocalizedString(), - "tonio@ubuntu.com"); - about.addAuthor(ki18n("Martin Böhm"), KLocalizedString(), - "martin.bohm@kubuntu.org"); - about.addAuthor(ki18n("Jonathan Riddell"), KLocalizedString(), - "jriddell@ubuntu.com"); - about.addAuthor(ki18n("Harald Sitter"), KLocalizedString(), - "apachelogger@ubuntu.com"); - - KCmdLineArgs::init(argc, argv, &about); - - KCmdLineOptions options; - options.add("u ", ki18n("sets a runas user")); - options.add("c ", ki18n("The command to execute")); - options.add("i ", ki18n("Specify icon to use in the password dialog")); - options.add("d", ki18n("Do not show the command to be run in the dialog")); - options.add("p ", ki18n("Process priority, between 0 and 100, 0 the lowest [50]")); - options.add("r", ki18n("Use realtime scheduling")); - options.add("f ", ki18n("Use target UID if is not writeable")); - options.add("nodbus", ki18n("Do not start a message bus")); - options.add("comment ", ki18n("The comment that should be " - "displayed in the dialog")); - options.add("attach ", ki18n("Makes the dialog transient for an X app specified by winid")); - options.add("desktop ", ki18n("Manual override for automatic desktop file detection")); - - options.add("+command", ki18n("The command to execute")); - - KCmdLineArgs::addCmdLineOptions(options); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - KApplication a; - a.disableSessionManagement(); - - QString executable; - QStringList executableList; - KDesktopFile *desktopFile = nullptr; - - if (args->isSet("c")) { - executable = args->getOption("c"); - } - - if (args->count() && executable.isEmpty()) { - QString command = args->arg(0); - QStringList commandlist = command.split(" "); - executable = commandlist[0]; - } - - /* Have to make sure the executable is only the binary name */ - executableList = executable.split(" "); - executable = executableList[0]; - - executableList = executable.split("/"); - executable = executableList[executableList.count() - 1]; - - /* Kubuntu has a bug in it - this is a workaround for it */ - KGlobal::dirs()->addResourceDir("apps", "/usr/share/applications/kde4"); - KGlobal::dirs()->addResourceDir("apps", "/usr/share/kde4/services"); - KGlobal::dirs()->addResourceDir("apps", "/usr/share/applications"); - - QString path = getenv("PATH"); - QStringList pathList = path.split(":"); - for (int i = 0; i < pathList.count(); i++) { - executable.remove(pathList[i]); - } - - if (args->isSet("desktop")) { - desktopFile = new KDesktopFile(args->getOption("desktop")); - } else { - desktopFile = new KDesktopFile(executable + ".desktop"); - } - - /* icon parsing */ - QString icon; - if (args->isSet("i")) { - icon = args->getOption("i"); - } else { - QString iconName = desktopFile->readIcon(); - KIconLoader *loader = KIconLoader::global(); - icon = loader->iconPath(iconName, -1 * KIconLoader::StdSizes(KIconLoader::SizeHuge), true); - } - - a.setQuitOnLastWindowClosed(false); - KdeSudo kdesudo(icon, desktopFile->readName()); - return a.exec(); -} diff --git a/kwin/effects/dimscreen/dimscreen.kcfg b/kwin/effects/dimscreen/dimscreen.kcfg index 8ed72e96..be6fe960 100644 --- a/kwin/effects/dimscreen/dimscreen.kcfg +++ b/kwin/effects/dimscreen/dimscreen.kcfg @@ -6,7 +6,7 @@ - kdesu,kdesudo,polkit-kde-manager,polkit-kde-authentication-agent-1,pinentry + kdesu,kdesudo,polkit-kde-manager,polkit-kde-authentication-agent-1,pinentry,kaskpass