diff --git a/mate-screensaver.spec b/mate-screensaver.spec index 75e51d1..3ebf4c6 100644 --- a/mate-screensaver.spec +++ b/mate-screensaver.spec @@ -15,7 +15,7 @@ Name: mate-screensaver Version: %{branch}.0 %if 0%{?rel_build} -Release: 1%{?dist} +Release: 2%{?dist} %else Release: 0.15%{?git_rel}%{?dist} %endif @@ -29,6 +29,11 @@ URL: http://pub.mate-desktop.org # Source for snapshot-builds. %{!?rel_build:Source0: http://git.mate-desktop.org/%{name}/snapshot/%{name}-%{commit}.tar.xz#/%{git_tar}} +# https://github.com/mate-desktop/mate-screensaver/commit/ec813df +Patch1: mate-screensaver_0001-A-prompt-driven-authentication-helper.patch +# https://github.com/mate-desktop/mate-screensaver/pull/262 +Patch2: mate-screensaver_0001-gs-theme-manager-reload-on-menu_tree-changed.patch + Requires: redhat-menus Requires: system-logos Requires: gnome-keyring-pam @@ -82,6 +87,9 @@ Development files for mate-screensaver NOCONFIGURE=1 ./autogen.sh %endif # 0%{?rel_build} +# Patch1 +NOCONFIGURE=1 ./autogen.sh + %build %configure \ --with-x \ @@ -148,6 +156,11 @@ mv %{buildroot}%{_datadir}/doc/mate-screensaver-%{version}/mate-screensaver.html %changelog +* Sat Nov 13 2021 Wolfgang Ulbrich - 1.26.0-2 +- use https://github.com/mate-desktop/mate-screensaver/commit/ec813df +- use https://github.com/mate-desktop/mate-screensaver/pull/262 +- fix rhbz (#1997852) + * Thu Aug 05 2021 Wolfgang Ulbrich - 1.26.0-1 - update to 1.26.0 diff --git a/mate-screensaver_0001-A-prompt-driven-authentication-helper.patch b/mate-screensaver_0001-A-prompt-driven-authentication-helper.patch new file mode 100644 index 0000000..1886abe --- /dev/null +++ b/mate-screensaver_0001-A-prompt-driven-authentication-helper.patch @@ -0,0 +1,1106 @@ +From 5c3a0e87bb90fbf08cc668d9338bd5870aac5368 Mon Sep 17 00:00:00 2001 +From: Paul Wolneykien +Date: Wed, 10 Mar 2021 16:08:53 +0300 +Subject: [PATCH] A prompt-driven authentication helper + +By the term "prompt-driven" I mean two-way conversation between the +screensaver dialog and the PAM stack. As you probably know, PAM works +by conversation with a dialog program asking the user to enter +something in answer to each message it sends. In the most conventional +case, the only question is "Password:" and the password is the only +data the user enters. But in general, the number of questions and +messages are not limited to that. + +The previous support of PAM helper (gs-auth-helper.c) was written and +worked for the mentioned "only password" authentication scheme. For +other schemes it wasn't enough. New implementation fixes that +limitation. + +Same as the previous version of gs-auth-helper.c, the new version uses +pipe interface for interprocess communication and synchronization. +However, unlike the previous version, new version uses two pipes +instead of a single pipe: the first one is used to transfer +prompt text from PAM via the helper to the screensaver dialog, and the +second one is used to transfer the user input from the dialog to +helper (and then the helper replies with it back to PAM). Having that +bidirectional prompt/reply channel it is possible to make as many +prompt/reply passes as required by PAM. + +The present helper program (see the helper/ dir) is based on the +helper written by okir@suse.de, which is in turn loosely based on +unix_chkpwd by Andrew Morgan. + +All new code is untabified under the assumption the tab width is 8. + +Signed-off-by: Paul Wolneykien +--- + Makefile.am | 7 +- + configure.ac | 25 +++- + helper/Makefile.am | 27 ++++ + helper/helper_proto.c | 167 ++++++++++++++++++++++++ + helper/helper_proto.h | 53 ++++++++ + helper/pam-helper.c | 289 ++++++++++++++++++++++++++++++++++++++++++ + src/Makefile.am | 16 ++- + src/gs-auth-helper.c | 202 ++++++++++++++--------------- + src/gs-auth-pam.c | 28 +--- + src/gs-auth-pam.h | 54 ++++++++ + 10 files changed, 733 insertions(+), 135 deletions(-) + create mode 100644 helper/Makefile.am + create mode 100644 helper/helper_proto.c + create mode 100644 helper/helper_proto.h + create mode 100644 helper/pam-helper.c + create mode 100644 src/gs-auth-pam.h + +diff --git a/Makefile.am b/Makefile.am +index 7bc464b..eca9048 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -10,7 +10,12 @@ DISTCHECK_CONFIGURE_FLAGS = \ + --enable-compile-warnings=no \ + CFLAGS='-Wno-deprecated-declarations' + +-SUBDIRS = \ ++SUBDIRS = ++if BUILTIN_HELPER ++SUBDIRS += helper ++endif ++ ++SUBDIRS += \ + po \ + src \ + savers \ +diff --git a/configure.ac b/configure.ac +index 65325cd..7c203ed 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -816,30 +816,29 @@ fi + # all in xscreensaver itself; the external program just does auth.) + + have_passwd_helper=no +-with_passwd_helper_req=unspecified ++builtin_helper=no + + AC_ARG_WITH(passwd-helper, + [ --with-passwd-helper Include support for an external password + verification helper program.], +- [with_passwd_helper="$withval"; with_passwd_helper_req="$withval"],[with_passwd_helper=no]) ++ [with_passwd_helper="$withval"],[with_passwd_helper=no]) + # no HANDLE_X_PATH_ARG for this one + + if test "$enable_locking" = no ; then +- with_passwd_helper_req=no + with_passwd_helper=no ++ builtin_helper=no + fi + + case "$with_passwd_helper" in + ""|no) : ;; + /*) + AC_DEFINE_UNQUOTED(PASSWD_HELPER_PROGRAM, "$with_passwd_helper", [Full pathname of password helper application]) ++ builtin_helper=no + have_passwd_helper=yes;; + *) + echo "error: --with-passwd-helper needs full pathname of helper (not '$with_passwd_helper')." >&2 + exit 1 + esac +-AM_CONDITIONAL(HAVE_PASSWD_HELPER, test x$have_passwd_helper = xyes) +-AC_SUBST(HAVE_PASSWD_HELPER) + + if test "$need_setuid" = yes -a "$have_pam" != yes ; then + NEED_SETUID=yes +@@ -863,7 +862,9 @@ if test x$enable_authentication_scheme = xpam -a x$have_pam = xno ; then + AC_MSG_ERROR(PAM support requested but not available) + fi + if test x$enable_authentication_scheme = xhelper -a x$have_passwd_helper = xno ; then +- AC_MSG_ERROR(Password helper support requested but not available) ++ builtin_helper=yes ++ have_passwd_helper=yes ++ AC_DEFINE_UNQUOTED(PASSWD_HELPER_PROGRAM, [PKGLIBEXECDIR "/mate-screensaver-pam-helper"], [Full pathname of password helper application]) + fi + if test x$enable_authentication_scheme = xbsdauth -a x$have_bsdauth = xno ; then + AC_MSG_ERROR(bsd_auth(3) support requested but not available) +@@ -892,6 +893,9 @@ else + fi + + AC_SUBST(AUTH_SCHEME) ++AM_CONDITIONAL(HAVE_PASSWD_HELPER, test x$have_passwd_helper = xyes) ++AM_CONDITIONAL(BUILTIN_HELPER, test x$builtin_helper = xyes) ++AC_SUBST(HAVE_PASSWD_HELPER) + + dnl --------------------------------------------------------------------------- + dnl ConsoleKit +@@ -1000,6 +1004,14 @@ if test "x$have_libnotify" = "xyes"; then + AC_DEFINE(WITH_LIBNOTIFY, 1, [Define for libnotify support]) + fi + ++dnl --------------------------------------------------------------------------- ++dnl glib headers for pam-helper ++dnl --------------------------------------------------------------------------- ++ ++PKG_CHECK_MODULES(PAM_HELPER, ++ glib-2.0 >= $GLIB_REQUIRED_VERSION) ++AC_SUBST(PAM_HELPER_CFLAGS) ++ + dnl --------------------------------------------------------------------------- + dnl Finish + dnl --------------------------------------------------------------------------- +@@ -1117,6 +1129,7 @@ data/images/cosmos/Makefile + savers/Makefile + doc/Makefile + doc/mate-screensaver.xml ++helper/Makefile + ]) + + echo " +diff --git a/helper/Makefile.am b/helper/Makefile.am +new file mode 100644 +index 0000000..7a0ab0a +--- /dev/null ++++ b/helper/Makefile.am +@@ -0,0 +1,27 @@ ++## We require new-style dependency handling. ++AUTOMAKE_OPTIONS = 1.7 ++ ++noinst_LIBRARIES = libhelper-proto.a ++ ++libhelper_proto_a_CFLAGS = \ ++ $(PAM_HELPER_CFLAGS) \ ++ -I$(top_srcdir)/src ++ ++libhelper_proto_a_SOURCES = \ ++ helper_proto.h \ ++ helper_proto.c ++ ++pkglibexec_PROGRAMS = mate-screensaver-pam-helper ++ ++mate_screensaver_pam_helper_CFLAGS = \ ++ $(PAM_HELPER_CFLAGS) \ ++ -I$(top_srcdir)/src ++ ++mate_screensaver_pam_helper_SOURCES = \ ++ pam-helper.c ++ ++mate_screensaver_pam_helper_LDADD = \ ++ libhelper-proto.a ++ ++mate_screensaver_pam_helper_LDFLAGS = \ ++ $(AUTH_LIBS) +diff --git a/helper/helper_proto.c b/helper/helper_proto.c +new file mode 100644 +index 0000000..3abe263 +--- /dev/null ++++ b/helper/helper_proto.c +@@ -0,0 +1,167 @@ ++/* Part of mate-screensaver. ++ * ++ * Copyright (c) 2019-2021 Paul Wolneykien ++ * ++ * 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. ++ * ++ * 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 ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301, USA. ++ */ ++ ++/* Provides functions for two-way communication between the screensaver ++ * and the helper program. The idea of helper program is to be able to ++ * run mate-screensaver-dialog without any setuid bits. ++ */ ++ ++#include "config.h" ++ ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif ++ ++#include "helper_proto.h" ++ ++static ssize_t ++read_all (int fd, void *buf, size_t count) ++{ ++ ssize_t rd, t_rd = 0; ++ ++ if (0 == count) ++ return 0; ++ ++ while (t_rd < count) ++ { ++ rd = read (fd, buf + t_rd, count - t_rd); ++ if (0 == rd) ++ break; ++ if (rd < 0) ++ return rd; ++ t_rd += rd; ++ } ++ ++ return t_rd; ++} ++ ++ssize_t ++read_msg (int fd, char *buf, size_t length) ++{ ++ size_t msg_len; ++ ssize_t rd; ++ ++ rd = read_all (fd, &msg_len, sizeof msg_len); ++ if (rd < 0) ++ return HELPER_IO_ERR; ++ if (rd > 0 && rd != sizeof msg_len) ++ return HELPER_LENGTH_READ_ERR; ++ ++ if (msg_len >= length) ++ return HELPER_TOO_LONG_ERR; ++ ++ if (msg_len > 0) ++ { ++ rd = read_all (fd, buf, msg_len); ++ if (rd < 0) ++ return HELPER_IO_ERR; ++ if (rd != msg_len) ++ return HELPER_MSG_READ_ERR; ++ } ++ else ++ rd = 0; ++ buf[rd] = '\0'; ++ ++ return rd; ++} ++ ++int ++read_prompt (int fd, char *buf, size_t *length) ++{ ++ int msg_type, rd; ++ ++ rd = read_all (fd, &msg_type, sizeof msg_type); ++ if (0 == rd) ++ return 0; ++ if (rd < 0) ++ return HELPER_IO_ERR; ++ if (rd > 0 && rd != sizeof msg_type) ++ return HELPER_TYPE_READ_ERR; ++ ++ rd = read_msg (fd, buf, *length); ++ if (rd < 0) ++ return rd; ++ ++ *length = rd; ++ return msg_type; ++} ++ ++static ssize_t ++write_all (int fd, const void *buf, size_t count) ++{ ++ ssize_t wt, t_wt = 0; ++ ++ if (0 == count) ++ return 0; ++ ++ while (t_wt < count) ++ { ++ wt = write (fd, buf + t_wt, count - t_wt); ++ if (0 == wt) ++ break; ++ if (wt < 0) ++ return wt; ++ t_wt += wt; ++ } ++ ++ return t_wt; ++} ++ ++ssize_t ++write_msg (int fd, const void *buf, size_t length) ++{ ++ ssize_t wt; ++ ++ wt = write_all (fd, &length, sizeof length); ++ if (wt < 0) ++ return HELPER_IO_ERR; ++ if (wt > 0 && wt != sizeof length) ++ return HELPER_LENGTH_WRITE_ERR; ++ ++ if (length > 0) ++ { ++ wt = write_all (fd, buf, length); ++ if (wt < 0) ++ return HELPER_IO_ERR; ++ if (wt != length) ++ return HELPER_MSG_WRITE_ERR; ++ } ++ else ++ wt = 0; ++ ++ return wt; ++} ++ ++int ++write_prompt (int fd, int msg_type, const void *buf, size_t length) ++{ ++ ssize_t wt; ++ ++ wt = write_all (fd, &msg_type, sizeof msg_type); ++ if (wt < 0) ++ return HELPER_IO_ERR; ++ if (wt > 0 && wt != sizeof msg_type) ++ return HELPER_TYPE_WRITE_ERR; ++ ++ wt = write_msg (fd, buf, length); ++ ++ return wt; ++} +diff --git a/helper/helper_proto.h b/helper/helper_proto.h +new file mode 100644 +index 0000000..b815b52 +--- /dev/null ++++ b/helper/helper_proto.h +@@ -0,0 +1,53 @@ ++/* Part of mate-screensaver. ++ * ++ * Copyright (c) 2019-2021 Paul Wolneykien ++ * ++ * 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. ++ * ++ * 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 ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301, USA. ++ */ ++ ++/* Provides functions for two-way communication between the screensaver ++ * and the helper program. The idea of helper program is to be able to ++ * run mate-screensaver-dialog without any setuid bits. ++ */ ++ ++#ifndef __HELPER_PROTO_H ++#define __HELPER_PROTO_H ++ ++#include "config.h" ++ ++#include ++#ifdef HAVE_UNISTD_H ++# include ++#endif ++ ++#define HELPER_IO_ERR -1 ++ ++#define HELPER_LENGTH_READ_ERR -2 ++#define HELPER_TOO_LONG_ERR -3 ++#define HELPER_MSG_READ_ERR -4 ++#define HELPER_TYPE_READ_ERR -5 ++ ++ssize_t read_msg (int fd, char *buf, size_t length); ++int read_prompt (int fd, char *buf, size_t *length); ++ ++#define HELPER_LENGTH_WRITE_ERR -6 ++#define HELPER_MSG_WRITE_ERR -7 ++#define HELPER_TYPE_WRITE_ERR -8 ++ ++ssize_t write_msg (int fd, const void *buf, size_t length); ++int write_prompt (int fd, int msg_type, const void *buf, size_t length); ++ ++#endif /* __HELPER_PROTO_H */ +diff --git a/helper/pam-helper.c b/helper/pam-helper.c +new file mode 100644 +index 0000000..c2bd837 +--- /dev/null ++++ b/helper/pam-helper.c +@@ -0,0 +1,289 @@ ++/* Part of mate-screensaver. ++ * ++ * Copyright (C) 2002 SuSE Linux AG. ++ * Copyright (c) 2019-2021 Paul Wolneykien ++ * ++ * 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. ++ * ++ * 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 ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301, USA. ++ */ ++ ++/* ++ * Set*id helper program for PAM authentication. ++ * ++ * It is supposed to be called from mate-screensaver ++ * in order to communicate with Linux PAM as a privileged proxy. ++ * The conversation messages from the PAM stack is transmitted to ++ * mate-screensaver dialog via stdout and the received user replies ++ * read from stdin are sent back to PAM. ++ * ++ * Based on the helper written by okir@suse.de, loosely based on ++ * unix_chkpwd by Andrew Morgan. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "helper_proto.h" ++#include "gs-auth-pam.h" ++ ++#define MAXLEN 1024 ++ ++enum { ++ UNIX_PASSED = 0, ++ UNIX_FAILED = 1 ++}; ++ ++static char * program_name; ++ ++/* ++ * Log error messages ++ */ ++static void ++_log_err(int err, const char *format,...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ openlog(program_name, LOG_CONS | LOG_PID, LOG_AUTH); ++ vsyslog(err, format, args); ++ va_end(args); ++ closelog(); ++} ++ ++static void ++su_sighandler(int sig) ++{ ++ if (sig > 0) { ++ _log_err(LOG_NOTICE, "caught signal %d.", sig); ++ exit(sig); ++ } ++} ++ ++/* ++ * Setup signal handlers ++ */ ++static void ++setup_signals(void) ++{ ++ struct sigaction action; ++ ++ memset((void *) &action, 0, sizeof(action)); ++ action.sa_handler = su_sighandler; ++ action.sa_flags = SA_RESETHAND; ++ sigaction(SIGILL, &action, NULL); ++ sigaction(SIGTRAP, &action, NULL); ++ sigaction(SIGBUS, &action, NULL); ++ sigaction(SIGSEGV, &action, NULL); ++ action.sa_handler = SIG_IGN; ++ action.sa_flags = 0; ++ sigaction(SIGTERM, &action, NULL); ++ sigaction(SIGHUP, &action, NULL); ++ sigaction(SIGINT, &action, NULL); ++ sigaction(SIGQUIT, &action, NULL); ++ sigaction(SIGALRM, &action, NULL); ++} ++ ++static int ++_converse(int num_msg, const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ struct pam_response *reply = NULL; ++ char buf[MAXLEN]; ++ int num; ++ int ret = PAM_SUCCESS; ++ ++ if (!(reply = malloc(sizeof(*reply) * num_msg))) ++ return PAM_CONV_ERR; ++ ++ for (num = 0; num < num_msg; num++) { ++ ssize_t wt, rd; ++ size_t msg_len = strlen(msg[num]->msg); ++ wt = write_prompt (STDOUT_FILENO, ++ pam_style_to_gs_style (msg[num]->msg_style), ++ msg[num]->msg, msg_len); ++ if (wt < 0 || wt != msg_len) { ++ _log_err(LOG_ERR, "error writing promt"); ++ ret = PAM_CONV_ERR; ++ break; ++ } ++ ++ rd = read_msg (STDIN_FILENO, buf, sizeof (buf)); ++ if (rd < 0) { ++ _log_err(LOG_ERR, "error reading reply"); ++ ret = PAM_CONV_ERR; ++ break; ++ } ++ ++ reply[num].resp = malloc (rd + 1); ++ if (!reply[num].resp) ++ ret = PAM_BUF_ERR; ++ else { ++ reply[num].resp_retcode = 0; ++ memcpy (reply[num].resp, buf, rd); ++ reply[num].resp[rd] = '\0'; ++ } ++ } ++ ++ if (ret != PAM_SUCCESS && reply != NULL) { ++ for (num = 0; num < num_msg; num++) ++ free (reply[num].resp); ++ free (reply); ++ *resp = NULL; ++ } else ++ *resp = reply; ++ ++ return ret; ++} ++ ++static int ++_authenticate(const char *service, const char *user) ++{ ++ struct pam_conv conv = { _converse, NULL }; ++ pam_handle_t *pamh; ++ int err; ++ ++ err = pam_start(service, user, &conv, &pamh); ++ if (err != PAM_SUCCESS) { ++ _log_err(LOG_ERR, "pam_start(%s, %s) failed (errno %d)", ++ service, user, err); ++ return UNIX_FAILED; ++ } ++ ++ err = pam_authenticate(pamh, 0); ++ if (err != PAM_SUCCESS) ++ _log_err(LOG_ERR, "pam_authenticate(%s, %s): %s", ++ service, user, ++ pam_strerror(pamh, err)); ++ ++ if (err == PAM_SUCCESS) ++ { ++ int err2 = pam_setcred(pamh, PAM_REFRESH_CRED); ++ if (err2 != PAM_SUCCESS) ++ _log_err(LOG_ERR, "pam_setcred(%s, %s): %s", ++ service, user, ++ pam_strerror(pamh, err2)); ++ /* ++ * ignore errors on refresh credentials. ++ * If this did not work we use the old once. ++ */ ++ } ++ ++ pam_end(pamh, err); ++ ++ if (err != PAM_SUCCESS) ++ return UNIX_FAILED; ++ return UNIX_PASSED; ++} ++ ++static char * ++getuidname(uid_t uid) ++{ ++ struct passwd *pw; ++ static char username[32]; ++ ++ pw = getpwuid(uid); ++ if (pw == NULL) ++ return NULL; ++ ++ strncpy(username, pw->pw_name, sizeof(username)); ++ username[sizeof(username) - 1] = '\0'; ++ ++ endpwent(); ++ return username; ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ const char *program_name; ++ char *service, *user; ++ int fd; ++ uid_t uid; ++ ++ uid = getuid(); ++ ++ /* ++ * Make sure standard file descriptors are connected. ++ */ ++ while ((fd = open("/dev/null", O_RDWR)) <= 2) ++ ; ++ close(fd); ++ ++ /* ++ * Get the program name ++ */ ++ if ((program_name = strrchr(argv[0], '/')) != NULL) ++ program_name++; ++ else ++ program_name = argv[0]; ++ ++ /* ++ * Catch or ignore as many signal as possible. ++ */ ++ setup_signals(); ++ ++ /* ++ * Check argument list ++ */ ++ if (argc < 2 || argc > 3) { ++ _log_err(LOG_NOTICE, "Bad number of arguments (%d)", argc); ++ return UNIX_FAILED; ++ } ++ ++ /* ++ * Get the service name. ++ */ ++ service = argv[1]; ++ ++ /* ++ * Discourage users messing around (fat chance) ++ */ ++ if (isatty(STDIN_FILENO) && uid != 0) { ++ _log_err(LOG_NOTICE, ++ "Inappropriate use of Unix helper binary [UID=%d]", ++ uid); ++ fprintf(stderr, ++ "This binary is not designed for running in this way\n" ++ "-- the system administrator has been informed\n"); ++ sleep(10); /* this should discourage/annoy the user */ ++ return UNIX_FAILED; ++ } ++ ++ /* ++ * determine the caller's user name ++ */ ++ user = getuidname(uid); ++ if (argc == 3 && strcmp(user, argv[2])) { ++ user = argv[2]; ++ /* Discourage use of this program as a ++ * password cracker */ ++ if (uid != 0) ++ sleep(5); ++ } ++ return _authenticate(service, user); ++} +diff --git a/src/Makefile.am b/src/Makefile.am +index f26612b..244b653 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = 1.7 + + NULL = + +-saverdir = $(libexecdir)/mate-screensaver ++saverdir = $(pkglibexecdir) + themesdir = $(pkgdatadir)/themes + + AM_CPPFLAGS = \ +@@ -21,6 +21,7 @@ AM_CPPFLAGS = \ + -DDATADIR=\""$(datadir)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DMATELOCALEDIR=\""$(datadir)/locale"\" \ ++ -DPKGLIBEXECDIR=\""$(pkglibexecdir)"\" \ + -DSAVERDIR=\""$(saverdir)"\" \ + -DTHEMESDIR=\""$(themesdir)"\" \ + -DGTKBUILDERDIR=\"$(pkgdatadir)\" \ +@@ -69,6 +70,7 @@ mate_screensaver_command_LDADD = \ + + AUTH_SOURCES = \ + gs-auth.h \ ++ gs-auth-pam.h \ + gs-auth-@AUTH_SCHEME@.c \ + $(NULL) + +@@ -99,6 +101,11 @@ test_passwd_LDADD = \ + $(AUTH_LIBS) \ + $(NULL) + ++if HAVE_PASSWD_HELPER ++test_passwd_LDADD += \ ++ ../helper/libhelper-proto.a ++endif ++ + test_watcher_SOURCES = \ + test-watcher.c \ + gs-watcher.h \ +@@ -161,6 +168,13 @@ mate_screensaver_dialog_LDADD = \ + $(LIBNOTIFY_LIBS) \ + $(NULL) + ++if HAVE_PASSWD_HELPER ++mate_screensaver_dialog_LDADD += \ ++ ../helper/libhelper-proto.a ++../helper/libhelper-proto.a: ++ $(MAKE) -C ../helper ++endif ++ + BUILT_SOURCES = \ + gs-marshal.c \ + gs-marshal.h \ +diff --git a/src/gs-auth-helper.c b/src/gs-auth-helper.c +index acc6958..8396135 100644 +--- a/src/gs-auth-helper.c ++++ b/src/gs-auth-helper.c +@@ -51,6 +51,9 @@ + #include "gs-auth.h" + #include "subprocs.h" + ++#include "../helper/helper_proto.h" ++#define MAXLEN 1024 ++ + static gboolean verbose_enabled = FALSE; + + GQuark +@@ -79,85 +82,105 @@ gs_auth_get_verbose (void) + + static gboolean + ext_run (const char *user, +- const char *typed_passwd, +- gboolean verbose) ++ GSAuthMessageFunc func, ++ gpointer data) + { +- int pfd[2], status; +- pid_t pid; +- +- if (pipe (pfd) < 0) +- { +- return 0; +- } +- +- if (verbose) +- { +- g_message ("ext_run (%s, %s)", +- PASSWD_HELPER_PROGRAM, user); +- } +- +- block_sigchld (); +- +- if ((pid = fork ()) < 0) +- { +- close (pfd [0]); +- close (pfd [1]); +- return FALSE; +- } +- +- if (pid == 0) +- { +- close (pfd [1]); +- if (pfd [0] != 0) +- { +- dup2 (pfd [0], 0); +- } +- +- /* Helper is invoked as helper service-name [user] */ +- execlp (PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM, "mate-screensaver", user, NULL); +- if (verbose) +- { +- g_message ("%s: %s", PASSWD_HELPER_PROGRAM, g_strerror (errno)); +- } +- +- exit (1); +- } +- +- close (pfd [0]); +- +- /* Write out password to helper process */ +- if (!typed_passwd) +- { +- typed_passwd = ""; +- } +- write (pfd [1], typed_passwd, strlen (typed_passwd)); +- close (pfd [1]); +- +- while (waitpid (pid, &status, 0) < 0) +- { +- if (errno == EINTR) +- { +- continue; +- } +- +- if (verbose) +- { +- g_message ("ext_run: waitpid failed: %s\n", +- g_strerror (errno)); +- } +- +- unblock_sigchld (); +- return FALSE; +- } +- +- unblock_sigchld (); +- +- if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) +- { +- return FALSE; +- } +- +- return TRUE; ++ int pfd[2], r_pfd[2], status; ++ pid_t pid; ++ gboolean verbose = gs_auth_get_verbose (); ++ ++ if (pipe (pfd) < 0 || pipe (r_pfd) < 0) ++ { ++ return FALSE; ++ } ++ ++ if (verbose) ++ { ++ g_message ("ext_run (%s, %s)", ++ PASSWD_HELPER_PROGRAM, user); ++ } ++ ++ block_sigchld (); ++ ++ if ((pid = fork ()) < 0) ++ { ++ close (pfd [0]); ++ close (pfd [1]); ++ close (r_pfd [0]); ++ close (r_pfd [1]); ++ return FALSE; ++ } ++ ++ if (pid == 0) ++ { ++ close (pfd [1]); ++ close (r_pfd [0]); ++ if (pfd [0] != 0) ++ { ++ dup2 (pfd [0], 0); ++ } ++ if (r_pfd [1] != 1) ++ { ++ dup2 (r_pfd [1], 1); ++ } ++ ++ /* Helper is invoked as helper service-name [user] */ ++ execlp (PASSWD_HELPER_PROGRAM, PASSWD_HELPER_PROGRAM, "mate-screensaver", user, NULL); ++ if (verbose) ++ { ++ g_message ("%s: %s", PASSWD_HELPER_PROGRAM, g_strerror (errno)); ++ } ++ ++ exit (1); ++ } ++ ++ close (pfd [0]); ++ close (r_pfd [1]); ++ ++ gboolean ret = FALSE; ++ while (waitpid (pid, &status, WNOHANG) == 0) ++ { ++ int msg_type; ++ char buf[MAXLEN]; ++ size_t msg_len = MAXLEN; ++ ++ msg_type = read_prompt (r_pfd [0], buf, &msg_len); ++ if (0 == msg_type) continue; ++ if (msg_type < 0) ++ { ++ g_message ("Error reading prompt (%d)", msg_type); ++ ret = FALSE; ++ goto exit; ++ } ++ ++ char *input = NULL; ++ func (msg_type, buf, &input, data); ++ ++ unsigned int input_len = input ? strlen (input) : 0; ++ ssize_t wt; ++ ++ wt = write_msg (pfd [1], input, input_len); ++ if (wt < 0) ++ { ++ g_message ("Error writing prompt reply (%li)", wt); ++ ret = FALSE; ++ goto exit; ++ } ++ } ++ ++ close (pfd [1]); ++ close (r_pfd [0]); ++ unblock_sigchld (); ++ ++ if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) ++ { ++ ret = FALSE; ++ } ++ else ++ ret = TRUE; ++ ++ exit: ++ return ret; + } + + gboolean +@@ -167,28 +190,7 @@ gs_auth_verify_user (const char *username, + gpointer data, + GError **error) + { +- gboolean res = FALSE; +- char *password; +- +- password = NULL; +- +- /* ask for the password for user */ +- if (func != NULL) +- { +- func (GS_AUTH_MESSAGE_PROMPT_ECHO_OFF, +- "Password: ", +- &password, +- data); +- } +- +- if (password == NULL) +- { +- return FALSE; +- } +- +- res = ext_run (username, password, gs_auth_get_verbose ()); +- +- return res; ++ return ext_run (username, func, data); + } + + gboolean +diff --git a/src/gs-auth-pam.c b/src/gs-auth-pam.c +index bad98af..734b80c 100644 +--- a/src/gs-auth-pam.c ++++ b/src/gs-auth-pam.c +@@ -46,6 +46,7 @@ + #include + + #include "gs-auth.h" ++#include "gs-auth-pam.h" + + #include "subprocs.h" + +@@ -126,33 +127,6 @@ gs_auth_get_verbose (void) + return verbose_enabled; + } + +-static GSAuthMessageStyle +-pam_style_to_gs_style (int pam_style) +-{ +- GSAuthMessageStyle style; +- +- switch (pam_style) +- { +- case PAM_PROMPT_ECHO_ON: +- style = GS_AUTH_MESSAGE_PROMPT_ECHO_ON; +- break; +- case PAM_PROMPT_ECHO_OFF: +- style = GS_AUTH_MESSAGE_PROMPT_ECHO_OFF; +- break; +- case PAM_ERROR_MSG: +- style = GS_AUTH_MESSAGE_ERROR_MSG; +- break; +- case PAM_TEXT_INFO: +- style = GS_AUTH_MESSAGE_TEXT_INFO; +- break; +- default: +- g_assert_not_reached (); +- break; +- } +- +- return style; +-} +- + static gboolean + auth_message_handler (GSAuthMessageStyle style, + const char *msg, +diff --git a/src/gs-auth-pam.h b/src/gs-auth-pam.h +new file mode 100644 +index 0000000..1d8a66f +--- /dev/null ++++ b/src/gs-auth-pam.h +@@ -0,0 +1,54 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (c) 2019 Paul Wolneykien ++ * ++ * 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. ++ * ++ * 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 ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301, USA. ++ * ++ */ ++ ++#ifndef __GS_AUTH_PAM_H ++#define __GS_AUTH_PAM_H ++ ++#include "gs-auth.h" ++ ++G_BEGIN_DECLS ++ ++static inline GSAuthMessageStyle ++pam_style_to_gs_style (int pam_style) ++{ ++ GSAuthMessageStyle style; ++ ++ switch (pam_style) ++ { ++ case PAM_PROMPT_ECHO_ON: ++ style = GS_AUTH_MESSAGE_PROMPT_ECHO_ON; ++ break; ++ case PAM_PROMPT_ECHO_OFF: ++ style = GS_AUTH_MESSAGE_PROMPT_ECHO_OFF; ++ break; ++ case PAM_ERROR_MSG: ++ style = GS_AUTH_MESSAGE_ERROR_MSG; ++ break; ++ default /* PAM_TEXT_INFO */: ++ style = GS_AUTH_MESSAGE_TEXT_INFO; ++ } ++ ++ return style; ++} ++ ++G_END_DECLS ++ ++#endif /* __GS_AUTH_PAM_H */ +-- +2.31.1 + diff --git a/mate-screensaver_0001-gs-theme-manager-reload-on-menu_tree-changed.patch b/mate-screensaver_0001-gs-theme-manager-reload-on-menu_tree-changed.patch new file mode 100644 index 0000000..52eda0f --- /dev/null +++ b/mate-screensaver_0001-gs-theme-manager-reload-on-menu_tree-changed.patch @@ -0,0 +1,43 @@ +From 38107f9928e632cd73e17814760d99189d67a873 Mon Sep 17 00:00:00 2001 +From: rbuj +Date: Tue, 2 Nov 2021 18:11:21 +0100 +Subject: [PATCH] gs-theme-manager: reload on menu_tree changed + +--- + src/gs-theme-manager.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/gs-theme-manager.c b/src/gs-theme-manager.c +index 6033563..da622a9 100644 +--- a/src/gs-theme-manager.c ++++ b/src/gs-theme-manager.c +@@ -392,12 +392,26 @@ get_themes_tree (void) + return themes_tree; + } + ++static void ++on_applications_changed (MateMenuTree *menu_tree) ++{ ++ GError *error = NULL; ++ ++ if (!matemenu_tree_load_sync (menu_tree, &error)) { ++ g_debug ("Load matemenu tree got error: %s\n", error->message); ++ g_error_free (error); ++ } ++} ++ + static void + gs_theme_manager_init (GSThemeManager *theme_manager) + { + theme_manager->priv = gs_theme_manager_get_instance_private (theme_manager); + + theme_manager->priv->menu_tree = get_themes_tree (); ++ g_signal_connect (theme_manager->priv->menu_tree, "changed", ++ G_CALLBACK (on_applications_changed), ++ NULL); + } + + static void +-- +2.31.1 +