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) {


Reply via email to