Compare commits

..

No commits in common. "ubuntu/questing" and "upstream/0.9.0" have entirely different histories.

26 changed files with 716 additions and 547 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

84
CMakeLists.txt Normal file
View File

@ -0,0 +1,84 @@
cmake_minimum_required(VERSION 2.8.11)
project(lxqt-sudo)
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. C++11 support is required")
endif()
find_package(Qt5Widgets REQUIRED QUIET)
find_package(lxqt REQUIRED QUIET)
include(${LXQT_USE_FILE})
include(LXQtTranslate)
include_directories (
${CMAKE_CURRENT_BINARY_DIR}
${LXQT_INCLUDE_DIRS}
)
add_definitions("-DLXQTSUDO_INSTALL_DIR=\"${CMAKE_INSTALL_PREFIX}/bin\""
"-DLXQTSUDO_SUDO=\"sudo\""
"-DLXQTSUDO=\"lxqt-sudo\""
"-DLXQT_VERSION=\"${LXQT_VERSION}\""
)
set ( HDRS
passworddialog.h
)
set ( SRCS
passworddialog.cpp
main.cpp
)
set ( MOCS
passworddialog.h
)
set( UIS
passworddialog.ui
)
qt5_wrap_cpp(MOC_OBJECTS ${MOCS})
qt5_wrap_ui(UI_HEADERS ${UIS})
# Translations **********************************
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
SOURCES
${HDRS}
${SRCS}
${UIS}
INSTALL_DIR
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
)
lxqt_app_translation_loader(SRCS ${PROJECT_NAME})
#************************************************
add_executable(lxqt-sudo
${SRCS}
${UI_HEADERS}
${MOC_OBJECTS}
${DESKTOP_FILES}
${QM_FILES}
)
target_link_libraries(lxqt-sudo
Qt5::Widgets
${LXQT_LIBRARIES}
)
install(TARGETS lxqt-sudo RUNTIME DESTINATION bin)
install(FILES ${DESKTOP_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
install(FILES man/lxqt-sudo.1 DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1")

6
debian/.gitignore vendored
View File

@ -1,6 +0,0 @@
/*.debhelper
/*.log
/*.substvars
/files
/lxqt-sudo/

278
debian/changelog vendored
View File

@ -1,278 +0,0 @@
lxqt-sudo (2.2.0-0ubuntu1) questing; urgency=medium
* New upstream release.
- Update build dependencies.
* Update copyright file.
* Update Standards-Version to 4.7.2, no changes needed.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 31 Jul 2025 16:30:59 -0500
lxqt-sudo (2.1.0-0ubuntu3) plucky; urgency=medium
* Update Standards-Version to 4.7.1, no changes needed.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 21 Feb 2025 16:53:25 -0600
lxqt-sudo (2.1.0-0ubuntu2) plucky; urgency=medium
* No-change rebuild for lxqt-build-tools C++17 -> C++20.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 03 Jan 2025 03:59:31 -0600
lxqt-sudo (2.1.0-0ubuntu1) plucky; urgency=medium
* New upstream version.
- Bump build dependencies.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 15 Nov 2024 15:33:17 -0600
lxqt-sudo (2.0.0-0ubuntu2) plucky; urgency=medium
* Update the patch to pass through env vars.
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 16 Oct 2024 17:09:37 -0500
lxqt-sudo (2.0.0-0ubuntu1) oracular; urgency=medium
* New upstream release.
* Update copyright file.
* Drop enable-bidirectional-communication.patch, applied upstream.
* Bump Standards-Version to 4.7.0, no changes necessary.
* Adjust dependencies.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 15 Aug 2024 16:43:15 -0500
lxqt-sudo (1.4.0-0ubuntu2) noble; urgency=medium
* Patch in bidirectional communication support (see
https://github.com/lxqt/lxqt-sudo/pull/210)
* Updated copyright file.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 11 Jan 2024 19:26:41 +0000
lxqt-sudo (1.4.0-0ubuntu1) noble; urgency=medium
* New upstream release.
* Bump build dependencies.
* Update copyright years.
-- Simon Quigley <tsimonq2@ubuntu.com> Sun, 12 Nov 2023 19:13:47 -0600
lxqt-sudo (1.3.0-0ubuntu1.1) mantic; urgency=medium
* Add a -E option, exposing all environment variables (LP: #2039093).
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 11 Oct 2023 12:02:21 -0500
lxqt-sudo (1.3.0-0ubuntu1) mantic; urgency=medium
* New upstream release.
* Bump build dependencies.
* Install new lxqtdoas binary.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 11 Aug 2023 09:51:31 -0500
lxqt-sudo (1.2.0-1ubuntu1) lunar; urgency=medium
* Reverted a sync from Debian.
* Bumped Standards-Version to 4.6.2, no changes necessary.
* Removed obsolete 'override_dh_missing' section from debian/rules.
* Updated copyright file.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 16 Feb 2023 20:20:33 -0600
lxqt-sudo (1.2.0-0ubuntu1) lunar; urgency=medium
* New upstream release.
* Fix the watch file, for real this time.
* Lubuntuify the package slightly, to make debhelper happy.
* Bump build dependencies in debian/control.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 18 Nov 2022 18:51:41 -0600
lxqt-sudo (1.1.0-1) experimental; urgency=medium
* New upstream release.
* Removed trailing whitespace from changelog.
* Ran wrap-and-sort.
* Upstreamed packaging changes from Ubuntu, modifying the following files:
- control
- copyright
- rules
- upstream/*
-- Aaron Rainbolt <arraybolt3@gmail.com> Wed, 13 Jul 2022 19:57:33 -0500
lxqt-sudo (0.16.0-1) unstable; urgency=medium
[ Alf Gaida ]
* Switched to gbp
* Bumped Standards-Version to 4.4.0, no changes needed
[ Andrew Lee (李健秋) ]
* New upstream release. (Closes: #978214)
-- Andrew Lee (李健秋) <ajqlee@debian.org> Wed, 06 Jan 2021 18:17:56 +0800
lxqt-sudo (0.14.1-2) unstable; urgency=medium
* Set HOME right, don't strip TERM (Closes: #928941)
-- Alf Gaida <agaida@siduction.org> Mon, 13 May 2019 19:56:39 +0200
lxqt-sudo (0.14.1-1) unstable; urgency=medium
* Cherry-picking new upstream version 0.14.1.
* Bumped minimum version liblxqt0-dev (>= 0.14.1~)
* Extended package description a bit
-- Alf Gaida <agaida@siduction.org> Sun, 24 Feb 2019 22:25:49 +0100
lxqt-sudo (0.14.0-1) unstable; urgency=medium
* Cherry-picking new upstream version 0.14.0.
* Bumped Standards to 4.3.0, no changes needed
* Dropped d/compat, use debhelper-compat = 12, no changes needed
* Fixed years in d/copyright
* Bumped minimum version liblxqt0-dev (>= 0.14.0~)
* Removed obsolete PULL_TRANSLATIONS= OFF from dh_auto_configure
* Added l10n-package, moved from lxqt-l10n
* Added d/upstream/metadata
-- Alf Gaida <agaida@siduction.org> Sun, 27 Jan 2019 19:32:15 +0100
lxqt-sudo (0.13.0-1) unstable; urgency=medium
* Cherry-picking new upstream version 0.13.0.
* Bumped build dependency liblxqt0-dev to >= 0.13.0~
* Bumped year in copyright
-- Alf Gaida <agaida@siduction.org> Fri, 25 May 2018 00:02:41 +0200
lxqt-sudo (0.12.0-4) unstable; urgency=medium
* Bumped compat to 11
* Bumped debhelper to >= 11~
* Bumped Standards to 4.1.4, no changes needed
* Changed VCS fields for salsa
* Changed Homepage, Source and watch to lxqt
* Bumped years in copyright
* Removed trailing whitespaces from changelog
-- Alf Gaida <agaida@siduction.org> Sat, 28 Apr 2018 16:40:26 +0200
lxqt-sudo (0.12.0-3) unstable; urgency=medium
* Bumped Standards to 4.1.2
* Removed branch from VCS fields
* Removed debian/gbp.conf
-- Alf Gaida <agaida@siduction.org> Thu, 14 Dec 2017 23:17:19 +0100
lxqt-sudo (0.12.0-2) unstable; urgency=medium
* Transition to unstable
-- Alf Gaida <agaida@siduction.org> Tue, 05 Dec 2017 01:26:56 +0100
lxqt-sudo (0.12.0-1) experimental; urgency=medium
* Cherry-picking upstream release 0.12.0.
* Bumped Standards to 4.1.1 - no changes needed
* Bumped liblxqt dependency to >= 0.12.0
-- Alf Gaida <agaida@siduction.org> Tue, 24 Oct 2017 21:33:45 +0200
lxqt-sudo (0.11.1-2) unstable; urgency=medium
* Bumped Standards to 4.0.0 - no changes needed
* Added lxqt-qtplugin to Recommends. (Closes: #866345)
-- Alf Gaida <agaida@siduction.org> Sun, 02 Jul 2017 16:17:20 +0200
lxqt-sudo (0.11.1-1) unstable; urgency=medium
* Cherry-picking upstream release 0.11.1.
* Removed some build dependencies:
- cmake
- libqt5xdg-dev
- libqt5xdgiconloader-dev
- libx11-dev
- pkg-config
- qttools5-dev
- qttools5-dev-tools
* Bumped build dependency liblxqt0-dev (>= 0.11.1)
* Bumped years in d/copyright
* Fixed d/gbp.conf
-- Alf Gaida <agaida@siduction.org> Mon, 02 Jan 2017 16:54:12 +0100
lxqt-sudo (0.11.0-2) unstable; urgency=medium
* Cherry-picking upstream release 0.11.0
* Synced debian foo with experimental
* Bumped Standards to 3.9.8, no changes needed
* Bumped compat to 10
* Removed --parallel from rules, standard in compat 10
* Bumped minimum version debhelper (>= 10)
* Bumped minimum version liblxqt-dev (>= 0.11.0)
* Bumped minimum version libqtxdg-dev (>= 2.0.0)
* Added build dependency libqt5svg5-dev
* Added build dependency libqt5xdgiconloader-dev
* Added Recommends lxqt-sudo-l10n
* Added README.md to docs
* Fixed VCS fields, using https and plain /git/
* Fixed copyrights Format field to https
* Bumped years in copyrights
* Added translation control to rules
* Set CMAKE_BUILD_TYPE=RelWithDebInfo
* Exported LC_ALL=C.UTF-8, make builds reproducible
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 19:54:08 +0200
lxqt-sudo (0.10.0-3) unstable; urgency=medium
* Remove dbg package in favor of dbgsym.
-- Alf Gaida <agaida@siduction.org> Sun, 27 Dec 2015 00:00:04 +0100
lxqt-sudo (0.10.0-2) unstable; urgency=medium
* Merge to unstable.
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 15 Nov 2015 20:58:46 +0800
lxqt-sudo (0.10.0-1) experimental; urgency=medium
* Cherry-picking upstream version 0.10.0.
* Set minimum version for liblxqt.
-- Alf Gaida <agaida@siduction.org> Tue, 03 Nov 2015 02:29:04 +0100
lxqt-sudo (0.9.0+20151029-1) experimental; urgency=medium
* Cherry-picked upstream version 0.9.0+20151024.
* set new minimum versions for liblxqt and libqxtg
-- Alf Gaida <agaida@siduction.org> Sat, 31 Oct 2015 11:26:51 +0100
lxqt-sudo (0.9.0+20150908-2) experimental; urgency=medium
* Added minimum version for liblxqt0-dev (>= 0.9.0+20150911)
-- Alf Gaida <agaida@siduction.org> Wed, 07 Oct 2015 17:33:24 +0200
lxqt-sudo (0.9.0+20150908-1) experimental; urgency=medium
[ Alf Gaida ]
* Cherry-picked upstream version 0.9.0+20150908.
* Fixed .gitignore
* Added upstream signing key and use it in watch file
* Added docs
* Fixed control with cme fix dpkg-control
* Switched to experimental because of LXQt namespace change
[ ChangZhuo Chen (陳昌倬) ]
* Initial release (Closes:#795801)
-- Alf Gaida <agaida@siduction.org> Wed, 23 Sep 2015 00:06:05 +0200

43
debian/control vendored
View File

@ -1,43 +0,0 @@
Source: lxqt-sudo
Maintainer: Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
Original-Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
Uploaders: Alf Gaida <agaida@siduction.org>,
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
Andrew Lee (李健秋) <ajqlee@debian.org>,
Simon Quigley <tsimonq2@debian.org>,
Aaron Rainbolt <arraybolt3@gmail.com>
Section: x11
Priority: optional
Build-Depends: debhelper-compat (= 13),
libkf6windowsystem-dev,
liblxqt2-dev (>= 2.2.0),
libx11-dev,
qt6-svg-dev (>= 6.6.0)
Standards-Version: 4.7.2
Vcs-Browser: https://git.lubuntu.me/Lubuntu/lxqt-sudo-packaging
Vcs-Git: https://git.lubuntu.me/Lubuntu/lxqt-sudo-packaging.git
Debian-Vcs-Browser: https://salsa.debian.org/cgit/pkg-team/lxqt-sudo
Debian-Vcs-Git: https://salsa.debian.org/lxqt-team/lxqt-sudo.git
Homepage: https://github.com/lxqt/lxqt-sudo
Rules-Requires-Root: no
Package: lxqt-sudo
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}
Recommends: lxqt-qtplugin, lxqt-sudo-l10n
Description: Graphical Qt frontend for plain sudo
lxqt-sudo is a graphical Qt frontend for plain sudo(8) (for requesting
optional password in GUI fashion). When invoked it simply spawns child sudo
process with requested command (and arguments). If sudo requests user's
password, the GUI password dialog is shown and (after submit) the password is
provided to sudo.
Package: lxqt-sudo-l10n
Architecture: all
Multi-Arch: foreign
Section: localization
Depends: qt6-translations-l10n, ${misc:Depends}
Description: Language package for lxqt-sudo
The l10n files for lxqt-sudo.
.
This package contains the l10n files needed by lxqt-sudo.

31
debian/copyright vendored
View File

@ -1,31 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: lxqt-sudo
Source: https://github.com/lxqt/lxqt-sudo
Files: *
Copyright: 2015-2025 LXQt team
2015-2018 Palo Kisa <palo.kisa@gmail.com>
License: LGPL-2.1+
Files: debian/*
Copyright: 2021-2025 Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
2015-2019 Alf Gaida <agaida@siduction.org>
2015 Andrew Lee (李健秋) <ajqlee@debian.org>
2015 ChangZhuo Chen (陳昌倬) <czchen@debian.org>
2025 Aaron Rainbolt <arraybolt3@ubuntu.com>
License: LGPL-2.1+
License: LGPL-2.1+
This program or library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
.
This program 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
Lesser General Public License for more details.
.
On Debian systems, the complete text of the GNU Lesser General
Public License version 2.1 can be found in
"/usr/share/common-licenses/LGPL-2.1".

2
debian/docs vendored
View File

@ -1,2 +0,0 @@
AUTHORS
README.md

6
debian/gbp.conf vendored
View File

@ -1,6 +0,0 @@
[DEFAULT]
debian-branch = debian/sid
upstream-branch = upstream/latest
pristine-tar = True
compression = xz

View File

@ -1 +0,0 @@
usr/share/lxqt/translations/lxqt-sudo

View File

@ -1,8 +0,0 @@
usr/bin/lxdoas
usr/bin/lxqt-sudo
usr/bin/lxsu
usr/bin/lxsudo
usr/share/man/man1/lxdoas.1
usr/share/man/man1/lxqt-sudo.1
usr/share/man/man1/lxsu.1
usr/share/man/man1/lxsudo.1

View File

@ -1,82 +0,0 @@
Description: Add a -E option, exposing all environment variables
Some system tools (such as ubuntu-release-upgrader) read XDG* (etc.), so allow the user to opt-in to preserving those.
Author: Simon Quigley <tsimonq2@lubuntu.me>
Origin: upstream
Forwarded: https://github.com/lxqt/lxqt-sudo/pull/204
Last-Update: 2023-10-11
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/sudo.cpp
+++ b/sudo.cpp
@@ -84,6 +84,7 @@ namespace
" -s|--su Use %3(1) as backend.\n"
" -d|--sudo Use %2(8) as backend.\n"
" -a|--doas Use %4(1) as backend.\n"
+ " -E|--keep-env Preserve all existing environment variables.\n"
" command Command to run.\n"
" arguments Optional arguments for command.\n\n").arg(app_master).arg(sudo_prog).arg(su_prog).arg(doas_prog);
if (!err.isEmpty())
@@ -114,8 +115,13 @@ namespace
};
assert_helper h;
- inline std::string env_workarounds()
+ inline std::string env_workarounds(bool preserveEnv)
{
+ if (preserveEnv) {
+ std::cerr << LXQTSUDO << ": Preserving all environment variables.\n";
+ return "";
+ }
+
std::cerr << LXQTSUDO << ": Stripping child environment except for: ";
std::ostringstream left_env_params;
std::copy(ALLOWED_VARS, ALLOWED_END - 1, std::ostream_iterator<const char *>{left_env_params, ","});
@@ -196,6 +202,10 @@ int Sudo::main()
{
mBackend = BACK_DOAS;
mArgs.removeAt(0);
+ } else if (QStringLiteral("-E") == arg1 || QStringLiteral("--keep-env") == arg1)
+ {
+ mPreserveEnv = true;
+ mArgs.removeAt(0);
}
}
//any other arguments we simply forward to su/sudo
@@ -287,11 +297,13 @@ void Sudo::child()
switch (mBackend)
{
case BACK_SUDO:
- preserve_env_param = "--preserve-env=";
-
- preserve_env_param += env_workarounds();
-
- *(param_arg++) = preserve_env_param.c_str(); //preserve environment
+ if(!mPreserveEnv) {
+ preserve_env_param = "--preserve-env=";
+ preserve_env_param += env_workarounds(mPreserveEnv);
+ } else {
+ preserve_env_param = "--preserve-env";
+ }
+ *(param_arg++) = preserve_env_param.c_str();
*(param_arg++) = "/bin/sh";
break;
case BACK_DOAS:
@@ -299,7 +311,7 @@ void Sudo::child()
[[fallthrough]];
case BACK_SU:
case BACK_NONE:
- env_workarounds();
+ env_workarounds(mPreserveEnv);
break;
}
--- a/sudo.h
+++ b/sudo.h
@@ -81,6 +81,7 @@ private:
int mChildPid;
int mPwdFd;
int mRet;
+ bool mPreserveEnv = false;
};
#endif //SUDO_H

View File

@ -1 +0,0 @@
bypass-envvar-allowlist.patch

13
debian/rules vendored
View File

@ -1,13 +0,0 @@
#!/usr/bin/make -f
# export DH_VERBOSE=1
export LC_ALL=C.UTF-8
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh ${@} --buildsystem cmake
override_dh_auto_configure:
dh_auto_configure -- \
-DUPDATE_TRANSLATIONS=OFF \
-DCMAKE_BUILD_TYPE=RelWithDebInfo

12
debian/salsa-ci.yml vendored
View File

@ -1,12 +0,0 @@
# For more information on what jobs are run see:
# https://salsa.debian.org/salsa-ci-team/pipeline
#
# To enable the jobs, go to your repository (at salsa.debian.org)
# and click over Settings > CI/CD > Expand (in General pipelines).
# In "Custom CI config path" write debian/salsa-ci.yml and click
# in "Save Changes". The CI tests will run after the next commit.
---
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml

View File

@ -1 +0,0 @@
3.0 (quilt)

View File

@ -1 +0,0 @@
tar-ignore=.gitignore

View File

@ -1,5 +0,0 @@
Name: lxqt-sudo
Bug-Database: https://github.com/lxqt/lxqt-sudo/issues
Bug-Submit: https://github.com/lxqt/lxqt-sudo/issues/new
Changelog: https://github.com/lxqt/lxqt-sudo/blob/master/CHANGELOG
Repository: https://github.com/lxqt/lxqt-sudo

View File

@ -1,52 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
sw==
=gSIv
-----END PGP PUBLIC KEY BLOCK-----

5
debian/watch vendored
View File

@ -1,5 +0,0 @@
version=4
opts="searchmode=plain, \
pgpsigurlmangle=s/$/.asc/, \
uversionmangle=s/(\d+\.\d+\.\d+).*/$1/" \
https://api.github.com/repos/lxqt/@PACKAGE@/releases https:\/\/github.com\/lxqt\/@PACKAGE@\/releases\/download\/@ANY_VERSION@\/@PACKAGE@-@ANY_VERSION@.tar.xz

193
main.cpp Normal file
View File

@ -0,0 +1,193 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include <LXQt/Application>
#include "passworddialog.h"
#include <QFileInfo>
#include <QDir>
#include <QProcess>
#include <QTimer>
#include <QMessageBox>
#include <QSocketNotifier>
#include <signal.h>
#include <sstream>
#include <QDebug>
const QString app_master{QStringLiteral(LXQTSUDO)};
const QString app_version{QStringLiteral(LXQT_VERSION)};
const QString install_dir{QStringLiteral(LXQTSUDO_INSTALL_DIR)};
const QString sudo_prog{QStringLiteral(LXQTSUDO_SUDO)};
const QString sudo_pwd_prompt{QStringLiteral("Password:\n")};
void termSignalHandler(int signal)
{
if (QApplication::instance())
QApplication::instance()->quit();
}
void usage(QString const & err = QString())
{
if (!err.isEmpty())
QTextStream(stderr) << err << '\n';
QTextStream(stdout)
<< QObject::tr("Usage: %1 command [arguments...]\n\n"
"GUI frontend for %2\n\n"
"Arguments:\n"
" command Command to run.\n"
" arguments Optional arguments for command.\n\n").arg(app_master).arg(sudo_prog);
if (!err.isEmpty())
QMessageBox(QMessageBox::Critical, app_master, err, QMessageBox::Ok).exec();
}
void version()
{
QTextStream(stdout)
<< QObject::tr("%1 version %2\n").arg(app_master).arg(app_version);
}
int master(int argc, char **argv)
{
//master
LxQt::Application app(argc, argv);
app.setQuitOnLastWindowClosed(false);
if (1 >= argc)
{
usage(QObject::tr("%1: no command to run provided!").arg(app_master));
return 1;
} else
{
//simple help check
std::string arg1(argv[1]);
if ("-h" == arg1 || "--help" == arg1)
{
usage();
return 0;
} else if ("-v" == arg1 || "--version" == arg1)
{
version();
return 0;
}
//any other arguments we simply forward to sudo
}
QStringList args = app.arguments();
//check for provided command is done before
args.removeAt(0);
PasswordDialog dlg(args);
dlg.setModal(true);
app.setActiveWindow(&dlg);
QScopedPointer<QProcess> sudo{new QProcess};
QObject::connect(&dlg, &QDialog::finished, [&sudo, &dlg] (int result)
{
if (QDialog::Accepted == result)
{
sudo->write(QByteArray{}.append(dlg.password().append('\n')));
} else
{
sudo->terminate();
if (!sudo->waitForFinished(1000))
sudo->kill();
}
});
//start background process -> sudo
sudo->setProcessChannelMode(QProcess::ForwardedOutputChannel);
sudo->setReadChannel(QProcess::StandardError);
QString last_line;
int ret;
QObject::connect(sudo.data(), static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)
, [&app, &ret, &last_line, &dlg] (int exitCode, QProcess::ExitStatus exitStatus)
{
ret = QProcess::NormalExit == exitStatus ? exitCode : 255;
if (0 != ret && last_line.startsWith(QStringLiteral("%1:").arg(sudo_prog)))
QMessageBox(QMessageBox::Critical, dlg.windowTitle()
, QObject::tr("Child '%1' process failed!\n%2").arg(sudo_prog).arg(last_line), QMessageBox::Ok).exec();
app.quit();
});
QObject::connect(sudo.data(), &QProcess::readyReadStandardError, [&sudo, &dlg, &last_line]
{
QByteArray err = sudo->readAllStandardError();
if (sudo_pwd_prompt == err.constData())
{
dlg.show();
return;
}
QTextStream{stderr, QIODevice::WriteOnly} << err;
int nl_pos = err.lastIndexOf('\n');
if (-1 == nl_pos)
last_line += err;
else
{
if (err.endsWith('\n'))
err.remove(err.size() - 1, 1);
nl_pos = err.lastIndexOf('\n');
if (-1 != nl_pos)
err.remove(0, nl_pos + 1);
last_line = err;
}
});
//forward all stdin to child
QTextStream std_in{stdin, QIODevice::ReadOnly};
QSocketNotifier stdin_watcher{0/*stdin*/, QSocketNotifier::Read};
QObject::connect(&stdin_watcher, &QSocketNotifier::activated, [&std_in, &sudo]
{
QString line{std_in.readLine()};
if (!std_in.atEnd())
line += QLatin1Char('\n');
sudo->write(line.toStdString().c_str());
if (std_in.atEnd())
sudo->closeWriteChannel();
});
sudo->start(sudo_prog, QStringList() << QStringLiteral("-S")
<< QStringLiteral("-p") << sudo_pwd_prompt
<< args);
app.exec();
sudo->waitForFinished(-1);
return ret;
}
int main(int argc, char **argv)
{
// Quit gracefully
::signal(SIGALRM, termSignalHandler);
::signal(SIGTERM, termSignalHandler);
::signal(SIGINT, termSignalHandler);
::signal(SIGQUIT, termSignalHandler);
::signal(SIGHUP, termSignalHandler);
::signal(SIGSTOP, termSignalHandler);
::signal(SIGTSTP, termSignalHandler);
return master(argc, argv);
}

17
man/lxqt-sudo.1 Normal file
View File

@ -0,0 +1,17 @@
.TH lxqt-sudo 1 "" "" "LXQt\ Module"
.SH NAME
\fBlxqt-sudo\fR \- execute a command as privileged user
.SH SYNOPSIS
\fBlxqt-sudo\fR \fIcommand\fR [\fIarguments\fR]
.SH DESCRIPTION
\fBlxqt-sudo\fR is a graphical QT frontend for plain \fBsudo(8)\fR (for requesting optional password in GUI fashion).
.br
When invoked it simply spawns child \fIsudo\fR process with requested \fIcommand\fR (and \fIarguments\fR). If \fIsudo\fR requests user's password,
the GUI password dialog is shown and (after submit) the password is provided to \fIsudo\fR.
.SH "REPORTING BUGS"
Report bugs to https://github.com/lxde/lxqt/issues
.SH "SEE ALSO"
\fBsudo(8)\fR
.SH AUTHOR
This manual page was created by \fBPalo Kisa\fR \fI<palo.kisa@gmail.com>\fR
for \fBLXQt\fR project.

62
passworddialog.cpp Normal file
View File

@ -0,0 +1,62 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include "passworddialog.h"
#include "ui_passworddialog.h"
PasswordDialog::PasswordDialog(QStringList argv
, QWidget * parent/* = 0*/
, Qt::WindowFlags f/* = 0*/)
: QDialog(parent, f)
, ui(new Ui::PasswordDialog)
{
ui->setupUi(this);
ui->commandL->setText(argv.join(QStringLiteral(" ")));
QString cmd;
if (0 < argv.size())
cmd = argv[0];
ui->descriptionL->setText(tr("<b>%1</b> needs administrative privileges.\nPlease enter your password.").arg(cmd));
ui->iconL->setPixmap(QIcon::fromTheme("dialog-password").pixmap(64, 64));
setWindowIcon(QIcon::fromTheme("security-high"));
}
PasswordDialog::~PasswordDialog()
{
}
void PasswordDialog::showEvent(QShowEvent * event)
{
ui->errorL->setText(tr("Attempt #%1").arg(++mAttempt));
return QDialog::showEvent(event);
}
QString PasswordDialog::password() const
{
return ui->passwordLE->text();
}

59
passworddialog.h Normal file
View File

@ -0,0 +1,59 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxqt.org
*
* Copyright: 2015 LXQt team
* Authors:
* Palo Kisa <palo.kisa@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef PASSWORDDIALOG_H
#define PASSWORDDIALOG_H
#include <QDialog>
namespace Ui {
class PasswordDialog;
}
class Communication;
class QProcess;
class PasswordDialog : public QDialog
{
Q_OBJECT
public:
PasswordDialog(QStringList argv
, QWidget * parent = 0
, Qt::WindowFlags f = 0);
~PasswordDialog();
virtual void showEvent(QShowEvent * event) override;
QString password() const;
private:
QScopedPointer<Ui::PasswordDialog> ui;
int mAttempt = 0;
};
#endif // PASSWORDDIALOG_H

151
passworddialog.ui Normal file
View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PasswordDialog</class>
<widget class="QDialog" name="PasswordDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>LXQt sudo</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QLabel" name="iconL">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" alignment="Qt::AlignVCenter">
<widget class="QLabel" name="descriptionL">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="errorL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="commandL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="descCommandL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Command:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="descPasswordL">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordLE">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PasswordDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PasswordDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

69
translations/lxqt-sudo.ts Normal file
View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
<context>
<name>PasswordDialog</name>
<message>
<location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="43"/>
<source>&lt;b&gt;%1&lt;/b&gt; needs administrative privileges.
Please enter your password.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="../main.cpp" line="57"/>
<source>Usage: %1 command [arguments...]
GUI frontend for %2
Arguments:
command Command to run.
arguments Optional arguments for command.
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
<context>
<name>PasswordDialog</name>
<message>
<location filename="../passworddialog.ui" line="20"/>
<location filename="../build/ui_passworddialog.h" line="129"/>
<source>LXQt sudo</source>
<translation>LXQt sudo</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="77"/>
<location filename="../build/ui_passworddialog.h" line="134"/>
<source>Command:</source>
<translation>Príkaz:</translation>
</message>
<message>
<location filename="../passworddialog.ui" line="84"/>
<location filename="../build/ui_passworddialog.h" line="135"/>
<source>Password:</source>
<translation>Heslo:</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="43"/>
<source>&lt;b&gt;%1&lt;/b&gt; needs administrative privileges.
Please enter your password.</source>
<translation>&lt;b&gt;%1&lt;/b&gt; vyžaduje práva administrátora.
Prosím, zadajte svoje heslo.</translation>
</message>
<message>
<location filename="../passworddialog.cpp" line="54"/>
<source>Attempt #%1</source>
<translation>Pokus č. %1</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
<location filename="../main.cpp" line="57"/>
<source>Usage: %1 command [arguments...]
GUI frontend for %2
Arguments:
command Command to run.
arguments Optional arguments for command.
</source>
<translation>Použitie: %1 command [arguments...]
GUI frontend pre %2
Parametre:
command Príkaz na spustenie.
arguments Parametre príkazu.
</translation>
</message>
<message>
<location filename="../main.cpp" line="69"/>
<source>%1 version %2
</source>
<translation>%1 verzia %2
</translation>
</message>
<message>
<location filename="../main.cpp" line="80"/>
<source>%1: no command to run provided!</source>
<translation>%1: žiaden príkaz na spustenie!</translation>
</message>
<message>
<location filename="../main.cpp" line="131"/>
<source>Child &apos;%1&apos; process failed!
%2</source>
<translation>Dcérsky &apos;%1&apos; process zlyhal!
%2</translation>
</message>
</context>
</TS>