diff --git a/.gitignore b/.gitignore new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +autotests/passwords.h diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,4 +82,6 @@ DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel ) +add_subdirectory(autotests) + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/autotests/CMakeLists.txt @@ -0,0 +1,3 @@ +include(ECMAddTests) +find_package(Qt5Test REQUIRED) +ecm_add_test(kdesutest.cpp ${ARGV1} TEST_NAME kdesutest LINK_LIBRARIES Qt5::Test KF5::Su KF5::CoreAddons KF5::Service) diff --git a/autotests/kdesutest.cpp b/autotests/kdesutest.cpp new file mode 100644 --- /dev/null +++ b/autotests/kdesutest.cpp @@ -0,0 +1,74 @@ + +#include +#include +#include <../src/suprocess.h> +#include + +#include +#include +#include + +// add this yourself, should include +// #define MYPASSWORD "foo" +// #define ROOTPASSWORD "bar" +#include "passwords.h" + +namespace KDESu +{ + +class KdeSuTest: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() { + } + void sudoGoodPassword() { + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup group(config, "super-user-command"); + group.writeEntry("super-user-command", "sudo"); + + KDESu::SuProcess* suProcess = new KDESu::SuProcess("root", "ls"); + QString suapp = suProcess->superUserCommand(); + QVERIFY(suapp==QLatin1String("sudo")); + int result = suProcess->exec(MYPASSWORD, 0); + QVERIFY(result == KDESu::SuProcess::ok); + } + void sudoBadPassword() { + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup group(config, "super-user-command"); + group.writeEntry("super-user-command", "sudo"); + + KDESu::SuProcess* suProcess = new KDESu::SuProcess("root", "ls"); + QString suapp = suProcess->superUserCommand(); + QVERIFY(suapp==QLatin1String("sudo")); + int result2 = suProcess->exec("broken", 0); + QVERIFY(result2 == KDESu::SuProcess::SuIncorrectPassword); + } + void suGoodPassword() { + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup group(config, "super-user-command"); + group.writeEntry("super-user-command", "su"); + + KDESu::SuProcess* suProcess = new KDESu::SuProcess("root", "ls"); + QString suapp = suProcess->superUserCommand(); + QVERIFY(suapp==QLatin1String("su")); + int result2 = suProcess->exec(ROOTPASSWORD, 0); + QVERIFY(result2 == KDESu::SuProcess::ok); + } + void suBadPassword() { + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup group(config, "super-user-command"); + group.writeEntry("super-user-command", "su"); + + KDESu::SuProcess* suProcess = new KDESu::SuProcess("root", "ls"); + QString suapp = suProcess->superUserCommand(); + QVERIFY(suapp==QLatin1String("su")); + int result2 = suProcess->exec("broken", 0); + QVERIFY(result2 == KDESu::SuProcess::SuIncorrectPassword); + } +}; +} + +#include +QTEST_MAIN(KDESu::KdeSuTest) + diff --git a/src/suprocess.h b/src/suprocess.h --- a/src/suprocess.h +++ b/src/suprocess.h @@ -72,6 +72,7 @@ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; private: + friend class KdeSuTest; enum SuErrors { error = -1, ok = 0, diff --git a/src/suprocess.cpp b/src/suprocess.cpp --- a/src/suprocess.cpp +++ b/src/suprocess.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #ifdef KDESU_USE_SUDO_DEFAULT # define DEFAULT_SUPER_USER_COMMAND QStringLiteral("sudo") @@ -41,6 +43,8 @@ QString superUserCommand; }; +static QLoggingCategory category("org.kde.kdesu"); + SuProcess::SuProcess(const QByteArray &user, const QByteArray &command) : d(new SuProcessPrivate) { @@ -203,7 +207,8 @@ QByteArray line; while (true) { line = readLine(); - if (line.isNull()) { + // return if problem. sudo checks for a second prompt || su gets a blank line + if ((line.contains(':') && state != WaitForPrompt) || line.isNull()) { return (state == HandleStub ? notauthorized : error); }