Hello community, here is the log from the commit of package pam_kwallet for openSUSE:Factory checked in at 2017-08-23 11:55:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pam_kwallet (Old) and /work/SRC/openSUSE:Factory/.pam_kwallet.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pam_kwallet" Wed Aug 23 11:55:23 2017 rev:13 rq:518277 version:5.10.5 Changes: -------- --- /work/SRC/openSUSE:Factory/pam_kwallet/pam_kwallet.changes 2017-07-19 12:22:21.252970211 +0200 +++ /work/SRC/openSUSE:Factory/.pam_kwallet.new/pam_kwallet.changes 2017-08-23 11:55:41.806259749 +0200 @@ -1,0 +2,31 @@ +Tue Aug 22 19:11:31 CEST 2017 - fab...@ritter-vogt.de + +- Update to 5.10.5 + * New bugfix release + * For more details please see: + * https://www.kde.org/announcements/plasma-5.10.5.php +- Changes since 5.10.4: + * None +- Enable pam-config integration on TW + +------------------------------------------------------------------- +Wed Aug 9 08:39:00 UTC 2017 - fab...@ritter-vogt.de + +- Add various patches (pending upstream review) to fix several + issues: + * 0001-Several-cleanups.patch + * 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch + * 0003-Check-for-a-graphical-session.patch + +------------------------------------------------------------------- +Wed Aug 2 08:48:28 UTC 2017 - fab...@ritter-vogt.de + +- Split into pam_kwallet and pam_kwallet common to allow -32bit pkg + necessary for pam-config integration +- Add baselibs.conf for -32bit pkg +- Register with pam-config automatically (boo#1029942) +- Only use pam-config on TW, where it will be available soon +- Disable pam-config for now, kwallet-pam needs some upstream + discussions first before it's viable to use... + +------------------------------------------------------------------- Old: ---- kwallet-pam-5.10.4.tar.xz New: ---- 0001-Several-cleanups.patch 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch 0003-Check-for-a-graphical-session.patch baselibs.conf kwallet-pam-5.10.5.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pam_kwallet.spec ++++++ --- /var/tmp/diff_new_pack.8ysBNq/_old 2017-08-23 11:55:42.718131385 +0200 +++ /var/tmp/diff_new_pack.8ysBNq/_new 2017-08-23 11:55:42.734129133 +0200 @@ -17,28 +17,50 @@ Name: pam_kwallet -Version: 5.10.4 +Version: 5.10.5 Release: 0 -Summary: A PAM Module for kwallet signing +Summary: A PAM Module for KWallet signing License: LGPL-2.1 and GPL-2.0+ and GPL-3.0 Group: System/GUI/KDE Url: http://www.kde.org/ -Source: http://download.kde.org/stable/plasma/%{version}/kwallet-pam-%{version}.tar.xz +Source0: http://download.kde.org/stable/plasma/%{version}/kwallet-pam-%{version}.tar.xz +Source1: baselibs.conf +# PATCH-FIX-UPSTREAM +Patch1: 0001-Several-cleanups.patch +# PATCH-FIX-UPSTREAM +Patch2: 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch +# PATCH-FIX-UPSTREAM +Patch3: 0003-Check-for-a-graphical-session.patch BuildRequires: extra-cmake-modules >= 1.2.0 BuildRequires: kf5-filesystem BuildRequires: libgcrypt-devel >= 1.5.0 BuildRequires: pam-devel BuildRequires: socat BuildRequires: xz -Requires: kwalletd5 -Requires: socat +Requires: %{name}-common = %{version} +%if 0%{?suse_version} >= 1330 +Requires(postun): coreutils pam pam-config +%endif %description This PAM module allows you to automatically open your kwallet when signing into your account. +%package common +Summary: Support files for the KWallet PAM module +Group: System/GUI/KDE +Requires: kwalletd5 +Requires: socat + +%description common +This package contains support files used by the KWallet PAM +module. + %prep %setup -q -n kwallet-pam-%{version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build %cmake_kf5 -d build -- -DLIBEXEC_INSTALL_DIR=%{_kf5_libexecdir} -DCMAKE_INSTALL_PREFIX=/ @@ -47,11 +69,27 @@ %install %kf5_makeinstall -C build +%if 0%{?suse_version} >= 1330 +# Due to boo#728586 it is necessary to duplicate this in the 32bit variant. +# So you need to edit baselibs.conf if you change this. +%post + %{_sbindir}/pam-config -a --kwallet5 || : + +%postun + if [ "$1" = "0" ]; then + %{_sbindir}/pam-config -d --kwallet5 || : + fi +%endif + %files %defattr(-,root,root) %doc COPYING* +/%{_lib}/security/pam_kwallet5.so + +%files common +%defattr(-,root,root) +%doc COPYING* %config %{_kf5_configdir}/autostart/pam_kwallet_init.desktop %{_kf5_libexecdir}/pam_kwallet_init -/%{_lib}/security/pam_kwallet5.so %changelog ++++++ 0001-Several-cleanups.patch ++++++ >From a6369519e080b741fea731ab42bb19e84c6e6fdb Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fab...@ritter-vogt.de> Date: Thu, 3 Aug 2017 09:02:14 +0200 Subject: [PATCH 1/3] Several cleanups - No cppcheck warnings anymore - Use snprintf everywhere - Avoid pointless multiplication with sizeof(char) - Avoid memory leaks --- pam_kwallet.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/pam_kwallet.c b/pam_kwallet.c index d88c5e0..cba57e7 100644 --- a/pam_kwallet.c +++ b/pam_kwallet.c @@ -151,13 +151,14 @@ static int set_env(pam_handle_t *pamh, const char *name, const char *value) //We do not return because pam_putenv might work } - char *pamEnv = malloc(strlen(name) + strlen(value) + 2); //2 is for = and \0 + size_t pamEnvSize = strlen(name) + strlen(value) + 2; //2 is for = and \0 + char *pamEnv = malloc(pamEnvSize); if (!pamEnv) { pam_syslog(pamh, LOG_WARNING, "%s: Impossible to allocate memory for pamEnv", logPrefix); return -1; } - sprintf (pamEnv, "%s=%s", name, value); + snprintf (pamEnv, pamEnvSize, "%s=%s", name, value); int ret = pam_putenv(pamh, pamEnv); free(pamEnv); @@ -240,6 +241,11 @@ cleanup: return result; } +static void cleanup_free(pam_handle_t *pamh, void *ptr, int error_status) +{ + free(ptr); +} + PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { pam_syslog(pamh, LOG_INFO, "%s: pam_sm_authenticate\n", logPrefix); @@ -297,14 +303,17 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons return PAM_IGNORE; } - char *key = malloc(sizeof(char) * KWALLET_PAM_KEYSIZE); - if (kwallet_hash(password, userInfo, key) != 0) { + char *key = malloc(KWALLET_PAM_KEYSIZE); + if (!key || kwallet_hash(password, userInfo, key) != 0) { + free(key); pam_syslog(pamh, LOG_ERR, "%s: Fail into creating the hash", logPrefix); return PAM_IGNORE; } - result = pam_set_data(pamh, kwalletPamDataKey, key, NULL); + result = pam_set_data(pamh, kwalletPamDataKey, key, cleanup_free); + if (result != PAM_SUCCESS) { + free(key); pam_syslog(pamh, LOG_ERR, "%s: Impossible to store the hashed password: %s", logPrefix , pam_strerror(pamh, result)); return PAM_IGNORE; @@ -385,9 +394,8 @@ cleanup: static int better_write(int fd, const char *buffer, int len) { size_t writtenBytes = 0; - int result; while(writtenBytes < len) { - result = write(fd, buffer + writtenBytes, len - writtenBytes); + int result = write(fd, buffer + writtenBytes, len - writtenBytes); if (result < 0) { if (errno != EAGAIN && errno != EINTR) { return -1; @@ -450,6 +458,7 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha if (result != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "%s: Impossible to set %s env, %s", logPrefix, envVar, pam_strerror(pamh, result)); + free(fullSocket); return; } @@ -459,12 +468,15 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha if (strlen(fullSocket) > sizeof(local.sun_path)) { pam_syslog(pamh, LOG_ERR, "%s: socket path %s too long to open", logPrefix, fullSocket); + free(fullSocket); return; } strcpy(local.sun_path, fullSocket); + free(fullSocket); + fullSocket = NULL; unlink(local.sun_path);//Just in case it exists from a previous login - pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, fullSocket); + pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, local.sun_path); size_t len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { @@ -477,7 +489,7 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha return; } - if (chown(fullSocket, userInfo->pw_uid, userInfo->pw_gid) == -1) { + if (chown(local.sun_path, userInfo->pw_uid, userInfo->pw_gid) == -1) { pam_syslog(pamh, LOG_INFO, "%s: Couldn't change ownership of the socket", logPrefix); return; } @@ -655,7 +667,8 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) #else char *fixpath = "share/apps/kwallet/kdewallet.salt"; #endif - char *path = (char*) malloc(strlen(userInfo->pw_dir) + strlen(kdehome) + strlen(fixpath) + 3);//3 == / and \0 + size_t pathSize = strlen(userInfo->pw_dir) + strlen(kdehome) + strlen(fixpath) + 3;//3 == /, / and \0 + char *path = (char*) malloc(pathSize); sprintf(path, "%s/%s/%s", userInfo->pw_dir, kdehome, fixpath); struct stat info; @@ -666,21 +679,26 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) FILE *fd = fopen(path, "r"); if (fd == NULL) { syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); + free(path); return 1; } - salt = (char*) malloc(sizeof(char) * KWALLET_PAM_SALTSIZE); + salt = (char*) malloc(KWALLET_PAM_SALTSIZE); memset(salt, '\0', KWALLET_PAM_SALTSIZE); fread(salt, KWALLET_PAM_SALTSIZE, 1, fd); fclose(fd); } + free(path); + if (salt == NULL) { syslog(LOG_ERR, "%s-kwalletd: Couldn't create or read the salt file", logPrefix); return 1; } gcry_error_t error; + error = gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0); if (error != 0) { + free(salt); syslog(LOG_ERR, "%s-kwalletd: Can't get secure memory: %d", logPrefix, error); return 1; } @@ -691,5 +709,7 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) GCRY_KDF_PBKDF2, GCRY_MD_SHA512, salt, KWALLET_PAM_SALTSIZE, KWALLET_PAM_ITERATIONS,KWALLET_PAM_KEYSIZE, key); - return 0; + + free(salt); + return (int) error; // gcry_kdf_derive returns 0 on success } -- 2.13.2 ++++++ 0002-Avoid-dropping-privileges-by-initializing-gcrypt-sec.patch ++++++ >From a8153375a5006f5ca766b58a1a8f488699314a74 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fab...@ritter-vogt.de> Date: Thu, 3 Aug 2017 09:27:10 +0200 Subject: [PATCH 2/3] Avoid dropping privileges by initializing gcrypt secmem It's a documented side effect that initialization of secure memory in gcrypt drops privileges if getuid() != geteuid(). This results in breaking setuid callers, like sudo or su. --- pam_kwallet.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pam_kwallet.c b/pam_kwallet.c index cba57e7..dc61115 100644 --- a/pam_kwallet.c +++ b/pam_kwallet.c @@ -696,12 +696,18 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) gcry_error_t error; + /* We cannot call GCRYCTL_INIT_SECMEM as it drops privileges if getuid() != geteuid(). + * PAM modules are in many cases executed through setuid binaries, which this call + * would break. + * It was never effective anyway as neither key nor passphrase are in secure memory, + * which is a prerequisite for secure operation... error = gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0); if (error != 0) { free(salt); syslog(LOG_ERR, "%s-kwalletd: Can't get secure memory: %d", logPrefix, error); return 1; } + */ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); -- 2.13.2 ++++++ 0003-Check-for-a-graphical-session.patch ++++++ >From f5f27799e1b6875be7f34edac3a9f98a2b550b2c Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fab...@ritter-vogt.de> Date: Thu, 3 Aug 2017 09:50:30 +0200 Subject: [PATCH 3/3] Check for a graphical session Avoid running if it detects a text session. This can be overridden by adding "force_run" as argument. --- pam_kwallet.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pam_kwallet.c b/pam_kwallet.c index dc61115..34bc045 100644 --- a/pam_kwallet.c +++ b/pam_kwallet.c @@ -72,6 +72,7 @@ const static char *kwalletd = NULL; const static char *socketPath = NULL; const static char *kwalletPamDataKey = NULL; const static char *logPrefix = NULL; +static int force_run = 0; #ifdef KWALLET5 const static char *envVar = "PAM_KWALLET5_LOGIN"; @@ -98,6 +99,8 @@ static void parseArguments(int argc, const char **argv) kwalletd = argv[x] + 9; } else if (strstr(argv[x], "socketPath=") != NULL) { socketPath= argv[x] + 11; + } else if (strcmp(argv[x], "force_run") == 0) { + force_run = 1; } } #ifdef KWALLET5 @@ -241,6 +244,24 @@ cleanup: return result; } +static int is_graphical_session(pam_handle_t *pamh) +{ + //Detect a graphical session + const char *pam_tty = NULL, *pam_xdisplay = NULL, + *xdg_session_type = NULL, *display = NULL; + + pam_get_item(pamh, PAM_TTY, (const void**) &pam_tty); +#ifdef PAM_XDISPLAY + pam_get_item(pamh, PAM_XDISPLAY, (const void**) &pam_xdisplay); +#endif + xdg_session_type = get_env(pamh, "XDG_SESSION_TYPE"); + + return (pam_xdisplay && strlen(pam_xdisplay) != 0) + || (pam_tty && pam_tty[0] == ':') + || (xdg_session_type && strcmp(xdg_session_type, "x11") == 0) + || (xdg_session_type && strcmp(xdg_session_type, "wayland") == 0); +} + static void cleanup_free(pam_handle_t *pamh, void *ptr, int error_status) { free(ptr); @@ -537,6 +558,11 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, cons parseArguments(argc, argv); + if (!force_run && !is_graphical_session(pamh)) { + pam_syslog(pamh, LOG_INFO, "%s: not a graphical session, skipping. Use force_run parameter to ignore this.", logPrefix); + return PAM_IGNORE; + } + int result; result = pam_set_data(pamh, "sm_open_session", "1", NULL); if (result != PAM_SUCCESS) { -- 2.13.2 ++++++ baselibs.conf ++++++ pam_kwallet requires "pam_kwallet = <version>" supplements "packageand(pam_kwallet:pam-<targettype>)" post "%if 0%{?suse_version} >= 1330" post "%{_sbindir}/pam-config -a --kwallet5 || :" post "%endif" post ":" ++++++ kwallet-pam-5.10.4.tar.xz -> kwallet-pam-5.10.5.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwallet-pam-5.10.4/CMakeLists.txt new/kwallet-pam-5.10.5/CMakeLists.txt --- old/kwallet-pam-5.10.4/CMakeLists.txt 2017-07-18 13:19:09.000000000 +0200 +++ new/kwallet-pam-5.10.5/CMakeLists.txt 2017-08-22 14:16:09.000000000 +0200 @@ -1,7 +1,7 @@ project(pam_kwallet) cmake_minimum_required(VERSION 2.8.12) -set(PROJECT_VERSION "5.10.4") +set(PROJECT_VERSION "5.10.5") set(PROJECT_VERSION_MAJOR 5) find_package (ECM 1.2.0 REQUIRED NO_MODULE)