mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 10:22:49 +00:00
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 <xakepa10@gmail.com> kdesudo: asd Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
02ab55bdb7
commit
0ab42ed2a6
6 changed files with 285 additions and 287 deletions
|
@ -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)
|
check_symbol_exists(procctl "sys/procctl.h" HAVE_PROCCTL)
|
||||||
add_feature_info("procctl" HAVE_PROCCTL "Used to disallow process tracing")
|
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)
|
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=900)
|
||||||
|
|
||||||
set(KDESUDO_SRC
|
set(kdesudo_SRC
|
||||||
main.cpp
|
|
||||||
kdesudo.cpp
|
kdesudo.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(kdesudo ${KDESUDO_SRC})
|
add_executable(kdesudo ${kdesudo_SRC})
|
||||||
|
|
||||||
target_link_libraries(kdesudo
|
target_link_libraries(kdesudo
|
||||||
KDE4::kdeui
|
KDE4::kdeui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(kaskpass_SRC
|
||||||
|
kaskpass.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(kaskpass ${kaskpass_SRC})
|
||||||
|
target_link_libraries(kaskpass
|
||||||
|
KDE4::kdeui
|
||||||
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS kdesudo
|
TARGETS kdesudo kaskpass
|
||||||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||||
)
|
)
|
||||||
|
|
104
kdesudo/kaskpass.cpp
Normal file
104
kdesudo/kaskpass.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
Copyright (C) 2024 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 "config.h"
|
||||||
|
|
||||||
|
#include <kapplication.h>
|
||||||
|
#include <kcmdlineargs.h>
|
||||||
|
#include <kaboutdata.h>
|
||||||
|
#include <kpassworddialog.h>
|
||||||
|
#include <kwindowsystem.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_PR_SET_DUMPABLE)
|
||||||
|
# include <sys/prctl.h>
|
||||||
|
#elif defined(HAVE_PROCCTL)
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <sys/procctl.h>
|
||||||
|
#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<WId>(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;
|
||||||
|
}
|
|
@ -21,32 +21,37 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "kdesudo.h"
|
#include "kdesudo.h"
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
#include <QFile>
|
||||||
#include <QtCore/QDir>
|
#include <QFileInfo>
|
||||||
#include <QtCore/QFile>
|
#include <QProcess>
|
||||||
#include <QtCore/QProcess>
|
#include <QString>
|
||||||
#include <QtCore/QString>
|
#include <QStringList>
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
|
#include <kiconloader.h>
|
||||||
|
#include <kicontheme.h>
|
||||||
|
#include <kglobal.h>
|
||||||
#include <kapplication.h>
|
#include <kapplication.h>
|
||||||
#include <kcmdlineargs.h>
|
#include <kcmdlineargs.h>
|
||||||
#include <kdebug.h>
|
#include <kaboutdata.h>
|
||||||
#include <klocale.h>
|
#include <klocale.h>
|
||||||
#include <kmessagebox.h>
|
#include <kmessagebox.h>
|
||||||
#include <kpassworddialog.h>
|
#include <kdesktopfile.h>
|
||||||
#include <kpushbutton.h>
|
|
||||||
#include <kshell.h>
|
#include <kshell.h>
|
||||||
#include <kstandarddirs.h>
|
#include <kstandarddirs.h>
|
||||||
#include <kwindowsystem.h>
|
|
||||||
#include <ktemporaryfile.h>
|
#include <ktemporaryfile.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <cstdio>
|
#if defined(HAVE_PR_SET_DUMPABLE)
|
||||||
#include <cstdlib>
|
# include <sys/prctl.h>
|
||||||
|
#elif defined(HAVE_PROCCTL)
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <sys/procctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
: QObject(),
|
: QObject(),
|
||||||
|
@ -61,7 +66,6 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
bool changeUID = true;
|
bool changeUID = true;
|
||||||
QString runas = args->getOption("u");
|
QString runas = args->getOption("u");
|
||||||
QString cmd;
|
QString cmd;
|
||||||
bool attach = args->isSet("attach");
|
|
||||||
|
|
||||||
if (!args->isSet("c") && !args->count()) {
|
if (!args->isSet("c") && !args->count()) {
|
||||||
KMessageBox::information(
|
KMessageBox::information(
|
||||||
|
@ -75,21 +79,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
exit(0);
|
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);
|
m_process = new QProcess(this);
|
||||||
|
|
||||||
/* load the icon */
|
|
||||||
m_dialog->setPixmap(icon);
|
|
||||||
|
|
||||||
// Parsins args
|
|
||||||
|
|
||||||
/* Get the comment out of cli args */
|
/* Get the comment out of cli args */
|
||||||
QString comment = args->getOption("comment");
|
QString comment = args->getOption("comment");
|
||||||
|
|
||||||
|
@ -116,26 +107,10 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_process, SIGNAL(readyReadStandardOutput()),
|
connect(
|
||||||
this, SLOT(parseOutput()));
|
m_process, SIGNAL(finished(int)),
|
||||||
|
this, SLOT(procExited(int))
|
||||||
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");
|
|
||||||
|
|
||||||
const QString disp = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
const QString disp = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
||||||
if (disp.isEmpty()) {
|
if (disp.isEmpty()) {
|
||||||
|
@ -143,6 +118,20 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
exit(1);
|
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
|
// Create two processes, one for each xauth call
|
||||||
QProcess xauth_ext;
|
QProcess xauth_ext;
|
||||||
QProcess xauth_merge;
|
QProcess xauth_merge;
|
||||||
|
@ -184,7 +173,11 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
processEnv.insert("LC_ALL", "C");
|
processEnv.insert("LC_ALL", "C");
|
||||||
processEnv.insert("DISPLAY", disp);
|
processEnv.insert("DISPLAY", disp);
|
||||||
processEnv.insert("XAUTHORITY", m_tmpName);
|
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;
|
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
|
// potentially in such a way that it uses the cached credentials of a
|
||||||
// previously kdesudo run in that same scope.
|
// previously kdesudo run in that same scope.
|
||||||
processArgs << "-k";
|
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) {
|
if (changeUID) {
|
||||||
processArgs << "-H" << "-S" << "-p" << "passprompt";
|
processArgs << "-H";
|
||||||
|
|
||||||
if (!runas.isEmpty()) {
|
if (!runas.isEmpty()) {
|
||||||
processArgs << "-u" << runas;
|
processArgs << "-u" << runas;
|
||||||
|
@ -204,8 +201,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
|
|
||||||
if (realtime) {
|
if (realtime) {
|
||||||
processArgs << "nice" << "-n" << "10";
|
processArgs << "nice" << "-n" << "10";
|
||||||
m_dialog->addCommentLine(i18n("Priority:"), i18n("realtime:") +
|
processEnv.insert("KASKPASS_LABEL0", i18n("Priority:"));
|
||||||
QChar(' ') + QString("50/100"));
|
processEnv.insert("KASKPASS_COMMENT0", QString::fromLatin1("50/100"));
|
||||||
processArgs << "--";
|
processArgs << "--";
|
||||||
} else if (priority) {
|
} else if (priority) {
|
||||||
QString n = args->getOption("p");
|
QString n = args->getOption("p");
|
||||||
|
@ -213,7 +210,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
intn = (intn * 40 / 100) - (20 + 0.5);
|
intn = (intn * 40 / 100) - (20 + 0.5);
|
||||||
|
|
||||||
processArgs << "nice" << "-n" << QString::number(intn);
|
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 << "--";
|
processArgs << "--";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,9 +225,7 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
processArgs << "sh";
|
processArgs << "sh";
|
||||||
processArgs << "-c";
|
processArgs << "-c";
|
||||||
processArgs << command;
|
processArgs << command;
|
||||||
}
|
} else if (args->count()) {
|
||||||
|
|
||||||
else if (args->count()) {
|
|
||||||
for (int i = 0; i < args->count(); i++) {
|
for (int i = 0; i < args->count(); i++) {
|
||||||
if ((!args->isSet("c")) && (i == 0)) {
|
if ((!args->isSet("c")) && (i == 0)) {
|
||||||
QStringList argsSplit = KShell::splitArgs(args->arg(i));
|
QStringList argsSplit = KShell::splitArgs(args->arg(i));
|
||||||
|
@ -249,7 +245,8 @@ KdeSudo::KdeSudo(const QString &icon, const QString &appname)
|
||||||
}
|
}
|
||||||
// strcmd needs to be defined
|
// strcmd needs to be defined
|
||||||
if (showCommand && !cmd.isEmpty()) {
|
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()) {
|
if (!appname.isEmpty()) {
|
||||||
m_dialog->setPrompt(defaultComment.arg(appname));
|
processEnv.insert("KASKPASS_PROMPT", defaultComment.arg(appname));
|
||||||
} else {
|
} else {
|
||||||
m_dialog->setPrompt(defaultComment.arg(cmd));
|
processEnv.insert("KASKPASS_PROMPT", defaultComment.arg(cmd));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_dialog->setPrompt(comment);
|
processEnv.insert("KASKPASS_PROMPT", comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_process->setProcessChannelMode(QProcess::MergedChannels);
|
m_process->setProcessEnvironment(processEnv);
|
||||||
|
|
||||||
m_process->start("sudo", processArgs);
|
m_process->start("sudo", processArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
KdeSudo::~KdeSudo()
|
KdeSudo::~KdeSudo()
|
||||||
{
|
{
|
||||||
delete m_dialog;
|
|
||||||
if (m_process) {
|
if (m_process) {
|
||||||
m_process->terminate();
|
m_process->terminate();
|
||||||
m_process->waitForFinished(3000);
|
m_process->waitForFinished(3000);
|
||||||
|
@ -295,43 +291,6 @@ void KdeSudo::error(const QString &msg)
|
||||||
KApplication::kApplication()->exit(1);
|
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("<b>Warning: </b>"), i18n("<b>Incorrect password, please try again.</b>"));
|
|
||||||
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)
|
void KdeSudo::procExited(int exitCode)
|
||||||
{
|
{
|
||||||
if (!m_error) {
|
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)
|
QString KdeSudo::validArg(QString arg)
|
||||||
{
|
{
|
||||||
QChar firstChar = arg.at(0);
|
QChar firstChar = arg.at(0);
|
||||||
|
@ -360,3 +309,108 @@ QString KdeSudo::validArg(QString arg)
|
||||||
}
|
}
|
||||||
return 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 <runas>", ki18n("sets a runas user"));
|
||||||
|
options.add("c <command>", ki18n("The command to execute"));
|
||||||
|
options.add("i <icon name>", 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 <priority>", ki18n("Process priority, between 0 and 100, 0 the lowest [50]"));
|
||||||
|
options.add("r", ki18n("Use realtime scheduling"));
|
||||||
|
options.add("f <file>", ki18n("Use target UID if <file> is not writeable"));
|
||||||
|
options.add("nodbus", ki18n("Do not start a message bus"));
|
||||||
|
options.add("comment <dialog text>", ki18n("The comment that should be "
|
||||||
|
"displayed in the dialog"));
|
||||||
|
options.add("attach <winid>", ki18n("Makes the dialog transient for an X app specified by winid"));
|
||||||
|
options.add("desktop <desktop file>", 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();
|
||||||
|
}
|
||||||
|
|
|
@ -24,15 +24,11 @@
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <kpassworddialog.h>
|
|
||||||
#include <knewpassworddialog.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KdeSudo is the base class of the project
|
* KdeSudo is the base class of the project
|
||||||
*
|
*
|
||||||
* @version 3.1
|
* @version 3.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class KdeSudo : QObject
|
class KdeSudo : QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -40,35 +36,19 @@ public:
|
||||||
KdeSudo(const QString &icon, const QString &appname);
|
KdeSudo(const QString &icon, const QString &appname);
|
||||||
~KdeSudo();
|
~KdeSudo();
|
||||||
|
|
||||||
private slots:
|
private Q_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();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This slot gets exectuted when sudo exits
|
* This slot gets exectuted when sudo exits
|
||||||
**/
|
**/
|
||||||
void procExited(int exitCode);
|
void procExited(int exitCode);
|
||||||
|
|
||||||
/**
|
|
||||||
* This slot overrides the slot from KPasswordDialog
|
|
||||||
* @see KPasswordDialog
|
|
||||||
**/
|
|
||||||
void pushPassword(const QString &);
|
|
||||||
void slotCancel();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString validArg(QString arg);
|
static QString validArg(QString arg);
|
||||||
void error(const QString &);
|
void error(const QString &msg);
|
||||||
|
|
||||||
QProcess *m_process;
|
QProcess *m_process;
|
||||||
bool m_error;
|
bool m_error;
|
||||||
QString m_tmpName;
|
QString m_tmpName;
|
||||||
KPasswordDialog *m_dialog;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KDESUDO_H
|
#endif // KDESUDO_H
|
||||||
|
|
150
kdesudo/main.cpp
150
kdesudo/main.cpp
|
@ -1,150 +0,0 @@
|
||||||
/***************************************************************************
|
|
||||||
kdesudo.cpp - description
|
|
||||||
-------------------
|
|
||||||
begin : Sam Feb 15 15:42:12 CET 2003
|
|
||||||
copyright : (C) 2003 by Robert Gruber
|
|
||||||
<rgruber@users.sourceforge.net>
|
|
||||||
(C) 2007 by Martin Böhm <martin.bohm@kubuntu.org>
|
|
||||||
Anthony Mercatante <tonio@kubuntu.org>
|
|
||||||
Canonical Ltd (Jonathan Riddell
|
|
||||||
<jriddell@ubuntu.com>)
|
|
||||||
(C) 2009-2015 by Harald Sitter <sitter@kde.org>
|
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* 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 <kcmdlineargs.h>
|
|
||||||
#include <kaboutdata.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kmessagebox.h>
|
|
||||||
#include <kdesktopfile.h>
|
|
||||||
#include <kiconloader.h>
|
|
||||||
#include <kicontheme.h>
|
|
||||||
#include <kglobal.h>
|
|
||||||
#include <kstandarddirs.h>
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <kapplication.h>
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_PR_SET_DUMPABLE)
|
|
||||||
# include <sys/prctl.h>
|
|
||||||
#elif defined(HAVE_PROCCTL)
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <sys/procctl.h>
|
|
||||||
#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 <runas>", ki18n("sets a runas user"));
|
|
||||||
options.add("c <command>", ki18n("The command to execute"));
|
|
||||||
options.add("i <icon name>", 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 <priority>", ki18n("Process priority, between 0 and 100, 0 the lowest [50]"));
|
|
||||||
options.add("r", ki18n("Use realtime scheduling"));
|
|
||||||
options.add("f <file>", ki18n("Use target UID if <file> is not writeable"));
|
|
||||||
options.add("nodbus", ki18n("Do not start a message bus"));
|
|
||||||
options.add("comment <dialog text>", ki18n("The comment that should be "
|
|
||||||
"displayed in the dialog"));
|
|
||||||
options.add("attach <winid>", ki18n("Makes the dialog transient for an X app specified by winid"));
|
|
||||||
options.add("desktop <desktop file>", 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();
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@
|
||||||
<kcfgfile name="kwinrc"/>
|
<kcfgfile name="kwinrc"/>
|
||||||
<group name="Effect-DimScreen">
|
<group name="Effect-DimScreen">
|
||||||
<entry name="WindowClasses" type="StringList">
|
<entry name="WindowClasses" type="StringList">
|
||||||
<default>kdesu,kdesudo,polkit-kde-manager,polkit-kde-authentication-agent-1,pinentry</default>
|
<default>kdesu,kdesudo,polkit-kde-manager,polkit-kde-authentication-agent-1,pinentry,kaskpass</default>
|
||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
</kcfg>
|
</kcfg>
|
||||||
|
|
Loading…
Add table
Reference in a new issue