Hello community, here is the log from the commit of package pam_kwallet for openSUSE:Factory checked in at 2018-05-29 10:35:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pam_kwallet (Old) and /work/SRC/openSUSE:Factory/.pam_kwallet.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pam_kwallet" Tue May 29 10:35:38 2018 rev:30 rq:610925 version:5.12.90 Changes: -------- --- /work/SRC/openSUSE:Factory/pam_kwallet/pam_kwallet.changes 2018-05-06 15:02:34.666583049 +0200 +++ /work/SRC/openSUSE:Factory/.pam_kwallet.new/pam_kwallet.changes 2018-05-29 10:35:40.336974672 +0200 @@ -1,0 +2,18 @@ +Sat May 19 14:16:37 CEST 2018 - [email protected] + +- Update to 5.12.90 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/plasma-5.12.90.php +- Changes since 5.12.5: + * Don't create salt file if user home directory does not exist + * Return PAM_IGNORE from pam_sm_authenticate + * Avoid giving an stderr to kwallet (kde#393856) + * Move socket creation to unprivileged codepath + * Move salt creation to an unprivileged process +- Remove patches, now upstream: + * 0001-Move-salt-creation-to-an-unprivileged-process.patch + * 0002-Move-socket-creation-to-unprivileged-codepath.patch + * 0001-Avoid-giving-an-stderr-to-kwallet.patch + +------------------------------------------------------------------- Old: ---- 0001-Avoid-giving-an-stderr-to-kwallet.patch 0001-Move-salt-creation-to-an-unprivileged-process.patch 0002-Move-socket-creation-to-unprivileged-codepath.patch kwallet-pam-5.12.5.tar.xz New: ---- kwallet-pam-5.12.90.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pam_kwallet.spec ++++++ --- /var/tmp/diff_new_pack.H1yE7o/_old 2018-05-29 10:35:41.900916922 +0200 +++ /var/tmp/diff_new_pack.H1yE7o/_new 2018-05-29 10:35:41.904916774 +0200 @@ -17,20 +17,14 @@ Name: pam_kwallet -Version: 5.12.5 +Version: 5.12.90 Release: 0 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 +Source: http://download.kde.org/unstable/plasma/%{version}/kwallet-pam-%{version}.tar.xz Source1: baselibs.conf -# PATCH-FIX-UPSTREAM -Patch1: 0001-Move-salt-creation-to-an-unprivileged-process.patch -# PATCH-FIX-UPSTREAM -Patch2: 0002-Move-socket-creation-to-unprivileged-codepath.patch -# PATCH-FIX-UPSTREAM -Patch3: 0001-Avoid-giving-an-stderr-to-kwallet.patch BuildRequires: extra-cmake-modules >= 1.2.0 BuildRequires: kf5-filesystem BuildRequires: libgcrypt-devel >= 1.5.0 @@ -59,7 +53,6 @@ %prep %setup -q -n kwallet-pam-%{version} -%autopatch -p1 %build %cmake_kf5 -d build -- -DLIBEXEC_INSTALL_DIR=%{_kf5_libexecdir} -DCMAKE_INSTALL_PREFIX=/ @@ -81,13 +74,11 @@ %endif %files -%defattr(-,root,root) -%doc COPYING* +%license COPYING* /%{_lib}/security/pam_kwallet5.so %files common -%defattr(-,root,root) -%doc COPYING* +%license COPYING* %config %{_kf5_configdir}/autostart/pam_kwallet_init.desktop %{_kf5_libexecdir}/pam_kwallet_init ++++++ kwallet-pam-5.12.5.tar.xz -> kwallet-pam-5.12.90.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwallet-pam-5.12.5/CMakeLists.txt new/kwallet-pam-5.12.90/CMakeLists.txt --- old/kwallet-pam-5.12.5/CMakeLists.txt 2018-05-01 14:51:31.000000000 +0200 +++ new/kwallet-pam-5.12.90/CMakeLists.txt 2018-05-18 14:24:14.000000000 +0200 @@ -1,7 +1,7 @@ project(pam_kwallet) cmake_minimum_required(VERSION 2.8.12) -set(PROJECT_VERSION "5.12.5") +set(PROJECT_VERSION "5.12.90") set(PROJECT_VERSION_MAJOR 5) find_package (ECM 1.2.0 REQUIRED NO_MODULE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwallet-pam-5.12.5/pam_kwallet.c new/kwallet-pam-5.12.90/pam_kwallet.c --- old/kwallet-pam-5.12.5/pam_kwallet.c 2018-05-01 14:51:31.000000000 +0200 +++ new/kwallet-pam-5.12.90/pam_kwallet.c 2018-05-18 14:24:14.000000000 +0200 @@ -82,7 +82,7 @@ static int argumentsParsed = -1; -int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key); +int kwallet_hash(pam_handle_t *pamh, const char *passphrase, struct passwd *userInfo, char *key); static void parseArguments(int argc, const char **argv) { @@ -272,7 +272,7 @@ pam_syslog(pamh, LOG_INFO, "%s: pam_sm_authenticate\n", logPrefix); if (get_env(pamh, envVar) != NULL) { pam_syslog(pamh, LOG_INFO, "%s: we were already executed", logPrefix); - return PAM_SUCCESS; + return PAM_IGNORE; } parseArguments(argc, argv); @@ -325,7 +325,7 @@ } char *key = malloc(KWALLET_PAM_KEYSIZE); - if (!key || kwallet_hash(password, userInfo, key) != 0) { + if (!key || kwallet_hash(pamh, password, userInfo, key) != 0) { free(key); pam_syslog(pamh, LOG_ERR, "%s: Fail into creating the hash", logPrefix); return PAM_IGNORE; @@ -349,23 +349,11 @@ } //TODO unlock kwallet that is already executed - return PAM_SUCCESS; + return PAM_IGNORE; } -static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], int envSocket) +static int drop_privileges(struct passwd *userInfo) { - //In the child pam_syslog does not work, using syslog directly - int x = 2; - //Close fd that are not of interest of kwallet - for (; x < 64; ++x) { - if (x != toWalletPipe[0] && x != envSocket) { - close (x); - } - } - - //This is the side of the pipe PAM will send the hash to - close (toWalletPipe[1]); - /* When dropping privileges from root, the `setgroups` call will * remove any extraneous groups. If we don't call this, then * even though our uid has dropped, we may still have groups @@ -378,10 +366,68 @@ //Change to the user in case we are not it yet if (setgid (userInfo->pw_gid) < 0 || setuid (userInfo->pw_uid) < 0 || setegid (userInfo->pw_gid) < 0 || seteuid (userInfo->pw_uid) < 0) { + return -1; + } + + return 0; +} + +static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], char *fullSocket) +{ + //In the child pam_syslog does not work, using syslog directly + //keep stderr open so socket doesn't returns us that fd + int x = 3; + //Close fd that are not of interest of kwallet + for (; x < 64; ++x) { + if (x != toWalletPipe[0]) { + close (x); + } + } + + //This is the side of the pipe PAM will send the hash to + close (toWalletPipe[1]); + + //Change to the user in case we are not it yet + if (drop_privileges(userInfo) < 0) { syslog(LOG_ERR, "%s: could not set gid/uid/euid/egit for kwalletd", logPrefix); goto cleanup; } + int envSocket; + if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + pam_syslog(pamh, LOG_ERR, "%s: couldn't create socket", logPrefix); + return; + } + + struct sockaddr_un local; + local.sun_family = AF_UNIX; + + 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, local.sun_path); + + size_t len = strlen(local.sun_path) + sizeof(local.sun_family); + if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { + pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't bind to local file\n", logPrefix); + return; + } + + if (listen(envSocket, 5) == -1) { + pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't listen in socket\n", logPrefix); + return; + } + //finally close stderr + close(2); + // Fork twice to daemonize kwallet setsid(); pid_t pid = fork(); @@ -442,12 +488,6 @@ pam_syslog(pamh, LOG_ERR, "%s: Couldn't create pipes", logPrefix); } - int envSocket; - if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - pam_syslog(pamh, LOG_ERR, "%s: couldn't create socket", logPrefix); - return; - } - #ifdef KWALLET5 const char *socketPrefix = "kwallet5"; #else @@ -483,38 +523,6 @@ return; } - struct sockaddr_un local; - local.sun_family = AF_UNIX; - - 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, local.sun_path); - - size_t len = strlen(local.sun_path) + sizeof(local.sun_family); - if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { - pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't bind to local file\n", logPrefix); - return; - } - - if (listen(envSocket, 5) == -1) { - pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't listen in socket\n", logPrefix); - return; - } - - 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; - } - pid_t pid; int status; switch (pid = fork ()) { @@ -524,7 +532,7 @@ //Child fork, will contain kwalletd case 0: - execute_kwallet(pamh, userInfo, toWalletPipe, envSocket); + execute_kwallet(pamh, userInfo, toWalletPipe, fullSocket); /* Should never be reached */ break; @@ -619,7 +627,7 @@ return PAM_SUCCESS; } -int mkpath(char *path, struct passwd *userInfo) +static int mkpath(char *path) { struct stat sb; char *slash; @@ -639,10 +647,6 @@ errno != EEXIST)) { syslog(LOG_ERR, "%s: Couldn't create directory: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); return (-1); - } else { - if (chown(path, userInfo->pw_uid, userInfo->pw_gid) == -1) { - syslog(LOG_INFO, "%s: Couldn't change ownership of: %s", logPrefix, path); - } } } else if (!S_ISDIR(sb.st_mode)) { return (-1); @@ -654,40 +658,61 @@ return (0); } -static char* createNewSalt(const char *path, struct passwd *userInfo) +static void createNewSalt(pam_handle_t *pamh, const char *path, struct passwd *userInfo) { - unlink(path);//in case the file already exists + const int pid = fork(); + if (pid == -1) { + pam_syslog(pamh, LOG_ERR, "%s: Couldn't fork to create salt file", logPrefix); + } else if (pid == 0) { + // Child process + if (drop_privileges(userInfo) < 0) { + syslog(LOG_ERR, "%s: could not set gid/uid/euid/egit for salt file creation", logPrefix); + exit(-1); + } - char *dir = strdup(path); - dir[strlen(dir) - 14] = '\0';//remove kdewallet.salt - mkpath(dir, userInfo);//create the path in case it does not exists - free(dir); + unlink(path);//in case the file already exists - char *salt = gcry_random_bytes(KWALLET_PAM_SALTSIZE, GCRY_STRONG_RANDOM); - FILE *fd = fopen(path, "w"); + char *dir = strdup(path); + dir[strlen(dir) - 14] = '\0';//remove kdewallet.salt + mkpath(dir); //create the path in case it does not exists + free(dir); - //If the file can't be created - if (fd == NULL) { - syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); - return NULL; - } + char *salt = gcry_random_bytes(KWALLET_PAM_SALTSIZE, GCRY_STRONG_RANDOM); + FILE *fd = fopen(path, "w"); - fwrite(salt, KWALLET_PAM_SALTSIZE, 1, fd); - fclose(fd); + //If the file can't be created + if (fd == NULL) { + syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); + exit(-2); + } - if (chown(path, userInfo->pw_uid, userInfo->pw_gid) == -1) { - syslog(LOG_ERR, "%s: Couldn't change ownership of the created salt file", logPrefix); - } + fwrite(salt, KWALLET_PAM_SALTSIZE, 1, fd); + fclose(fd); - return salt; + exit(0); // success + } else { + // pam process, just wait for child to finish + int status; + waitpid(pid, &status, 0); + if (status != 0) { + pam_syslog(pamh, LOG_ERR, "%s: Couldn't create salt file", logPrefix); + } + } } -int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) + +int kwallet_hash(pam_handle_t *pamh, const char *passphrase, struct passwd *userInfo, char *key) { if (!gcry_check_version("1.5.0")) { syslog(LOG_ERR, "%s-kwalletd: libcrypt version is too old", logPrefix); return 1; } + struct stat info; + if (stat(userInfo->pw_dir, &info) != 0 || !S_ISDIR(info.st_mode)) { + syslog(LOG_ERR, "%s-kwalletd: user home folder does not exist", logPrefix); + return 1; + } + #ifdef KWALLET5 char *fixpath = "kwalletd/kdewallet.salt"; #else @@ -697,22 +722,21 @@ char *path = (char*) malloc(pathSize); sprintf(path, "%s/%s/%s", userInfo->pw_dir, kdehome, fixpath); - struct stat info; char *salt = NULL; if (stat(path, &info) != 0 || info.st_size == 0) { - salt = createNewSalt(path, userInfo); - } else { - 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(KWALLET_PAM_SALTSIZE); - memset(salt, '\0', KWALLET_PAM_SALTSIZE); - fread(salt, KWALLET_PAM_SALTSIZE, 1, fd); - fclose(fd); + createNewSalt(pamh, path, userInfo); + } + + 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(KWALLET_PAM_SALTSIZE); + memset(salt, '\0', KWALLET_PAM_SALTSIZE); + fread(salt, KWALLET_PAM_SALTSIZE, 1, fd); + fclose(fd); free(path); if (salt == NULL) {
