Hello community, here is the log from the commit of package pam_passwdqc for openSUSE:Factory checked in at 2018-12-04 20:58:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pam_passwdqc (Old) and /work/SRC/openSUSE:Factory/.pam_passwdqc.new.19453 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "pam_passwdqc" Tue Dec 4 20:58:07 2018 rev:22 rq:653824 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/pam_passwdqc/pam_passwdqc.changes 2015-05-29 10:47:22.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.pam_passwdqc.new.19453/pam_passwdqc.changes 2018-12-04 20:58:18.428588426 +0100 @@ -1,0 +2,10 @@ +Sat Sep 22 06:24:50 UTC 2018 - sean@suspend.net + +- Update to passwdqc 1.3.1 + * The rarely used "non-unix" option to pam_passwdqc was broken + (uninitialized pointer): when that option was enabled, + pam_passwdqc would either segfault or potentially wrongly + conclude that a password is based on the user's information + (false positive detection of weak password). + +------------------------------------------------------------------- Old: ---- passwdqc-1.3.0.tar.gz New: ---- passwdqc-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pam_passwdqc.spec ++++++ --- /var/tmp/diff_new_pack.5LYX84/_old 2018-12-04 20:58:19.164587614 +0100 +++ /var/tmp/diff_new_pack.5LYX84/_new 2018-12-04 20:58:19.184587592 +0100 @@ -1,7 +1,7 @@ # # spec file for package pam_passwdqc # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -22,7 +22,7 @@ Requires: pam Recommends: passwdqc Provides: pam-modules:/%_lib/security/pam_passwdqc.so -Version: 1.3.0 +Version: 1.3.1 Release: 0 Summary: Simple Password Strength Checking Module License: BSD-3-Clause @@ -120,7 +120,7 @@ %defattr(-,root,root) %attr(644,root,root) %doc %{_mandir}/man1/* %attr(644,root,root) %doc %{_mandir}/man5/* -%doc INTERNALS LICENSE PLATFORMS README +%license INTERNALS LICENSE PLATFORMS README %config(noreplace) %{_sysconfdir}/*.conf %{_bindir}/* ++++++ passwdqc-1.3.0.tar.gz -> passwdqc-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/INSTALL new/passwdqc-1.3.1/INSTALL --- old/passwdqc-1.3.0/INSTALL 2013-04-24 04:02:54.000000000 +0200 +++ new/passwdqc-1.3.1/INSTALL 2016-07-20 22:55:40.000000000 +0200 @@ -26,8 +26,8 @@ Alternatively, on a Red Hat'ish Linux system and under an account configured to build RPM packages (perhaps with ~/.rpmmacros specifying the proper pathnames for %_topdir, %_tmppath, and %buildroot), you may -build RPM packages by running "rpmbuild -tb passwdqc-1.3.0.tar.gz", then -install the two binary subpackages with "rpm -Uvh passwdqc*-1.3.0*.rpm". +build RPM packages by running "rpmbuild -tb passwdqc-1.3.1.tar.gz", then +install the two binary subpackages with "rpm -Uvh passwdqc*-1.3.1*.rpm". This works due to the RPM spec file included in the tarball. Please refer to README and PLATFORMS for information on configuring your @@ -37,4 +37,4 @@ Please refer to the pwqcheck(1) and pwqgen(1) manual pages for information on using the command-line programs. -$Owl: Owl/packages/passwdqc/passwdqc/INSTALL,v 1.8 2013/04/24 02:02:54 solar Exp $ +$Owl: Owl/packages/passwdqc/passwdqc/INSTALL,v 1.9 2016/07/20 20:55:40 solar Exp $ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/Makefile new/passwdqc-1.3.1/Makefile --- old/passwdqc-1.3.0/Makefile 2012-08-19 00:24:09.000000000 +0200 +++ new/passwdqc-1.3.1/Makefile 2016-07-21 14:22:55.000000000 +0200 @@ -85,10 +85,10 @@ CONFIGS = passwdqc.conf BINS = pwqgen pwqcheck PROJ = $(SHARED_LIB) $(DEVEL_LIB) $(SHARED_PAM) $(BINS) -OBJS_LIB = concat.o passwdqc_check.o passwdqc_load.o passwdqc_parse.o passwdqc_random.o wordset_4k.o -OBJS_PAM = pam_passwdqc.o -OBJS_GEN = pwqgen.o -OBJS_CHECK = pwqcheck.o +OBJS_LIB = concat.o passwdqc_check.o passwdqc_load.o passwdqc_memzero.o passwdqc_parse.o passwdqc_random.o wordset_4k.o +OBJS_PAM = pam_passwdqc.o passwdqc_memzero.o +OBJS_GEN = pwqgen.o passwdqc_memzero.o +OBJS_CHECK = pwqcheck.o passwdqc_memzero.o default: all diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/concat.c new/passwdqc-1.3.1/concat.c --- old/passwdqc-1.3.0/concat.c 2009-09-29 01:00:19.000000000 +0200 +++ new/passwdqc-1.3.1/concat.c 2016-07-20 22:12:47.000000000 +0200 @@ -27,7 +27,7 @@ va_list args; const char *s; char *p, *result; - unsigned long l, m, n; + size_t l, m, n; m = n = strlen(s1); va_start(args, s1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/libpasswdqc.map new/passwdqc-1.3.1/libpasswdqc.map --- old/passwdqc-1.3.0/libpasswdqc.map 2009-10-10 00:09:33.000000000 +0200 +++ new/passwdqc-1.3.1/libpasswdqc.map 2016-07-21 14:22:55.000000000 +0200 @@ -1,4 +1,4 @@ -# $Owl: Owl/packages/passwdqc/passwdqc/libpasswdqc.map,v 1.2 2009/10/09 22:09:33 solar Exp $ +# $Owl: Owl/packages/passwdqc/passwdqc/libpasswdqc.map,v 1.4 2016/07/21 01:01:59 ldv Exp $ { global: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/pam_passwdqc.c new/passwdqc-1.3.1/pam_passwdqc.c --- old/passwdqc-1.3.0/pam_passwdqc.c 2012-08-19 00:24:09.000000000 +0200 +++ new/passwdqc-1.3.1/pam_passwdqc.c 2016-07-20 22:23:36.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003,2005,2012 by Solar Designer. See LICENSE. + * Copyright (c) 2000-2003,2005,2012,2016 by Solar Designer. See LICENSE. */ #ifdef __FreeBSD__ @@ -165,7 +165,7 @@ } else { status = PAM_ABORT; } - memset(buffer, 0, sizeof(buffer)); + _passwdqc_memzero(buffer, sizeof(buffer)); return status; } @@ -173,7 +173,7 @@ static int check_max(passwdqc_params_qc_t *qc, pam_handle_t *pamh, const char *newpass) { - if ((int)strlen(newpass) > qc->max) { + if (strlen(newpass) > (size_t)qc->max) { if (qc->max != 8) { say(pamh, PAM_ERROR_MSG, MESSAGE_TOOLONG); return -1; @@ -208,7 +208,7 @@ #endif } retval = (hash && !strcmp(hash, spw->sp_pwdp)) ? 0 : -1; - memset(spw->sp_pwdp, 0, strlen(spw->sp_pwdp)); + _passwdqc_memzero(spw->sp_pwdp, strlen(spw->sp_pwdp)); return retval; } #endif @@ -217,7 +217,7 @@ if (strlen(pw->pw_passwd) >= 13) hash = crypt(pass, pw->pw_passwd); retval = (hash && !strcmp(hash, pw->pw_passwd)) ? 0 : -1; - memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); + _passwdqc_memzero(pw->pw_passwd, strlen(pw->pw_passwd)); return retval; } @@ -303,8 +303,10 @@ if (params.pam.flags & F_NON_UNIX) { pw = &fake_pw; + memset(pw, 0, sizeof(*pw)); pw->pw_name = (char *)user; pw->pw_gecos = ""; + pw->pw_dir = ""; } else { /* As currently implemented, we don't avoid timing leaks for valid vs. not * usernames and hashes. Normally, the username would have already been @@ -317,7 +319,7 @@ if ((params.pam.flags & F_CHECK_OLDAUTHTOK) && !am_root(pamh) && (!oldpass || check_pass(pw, oldpass))) status = PAM_AUTH_ERR; - memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); + _passwdqc_memzero(pw->pw_passwd, strlen(pw->pw_passwd)); if (status != PAM_SUCCESS) return status; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc.h new/passwdqc-1.3.1/passwdqc.h --- old/passwdqc-1.3.0/passwdqc.h 2013-04-24 03:45:10.000000000 +0200 +++ new/passwdqc-1.3.1/passwdqc.h 2016-07-20 22:33:53.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 by Solar Designer + * Copyright (c) 2000-2002,2016 by Solar Designer * Copyright (c) 2008,2009 by Dmitry V. Levin * See LICENSE */ @@ -49,6 +49,8 @@ #define F_USE_FIRST_PASS 0x00000100 #define F_USE_AUTHTOK 0x00000200 -#define PASSWDQC_VERSION "1.3.0" +#define PASSWDQC_VERSION "1.3.1" + +extern void (*_passwdqc_memzero)(void *, size_t); #endif /* PASSWDQC_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc.spec new/passwdqc-1.3.1/passwdqc.spec --- old/passwdqc-1.3.0/passwdqc.spec 2013-04-24 04:02:54.000000000 +0200 +++ new/passwdqc-1.3.1/passwdqc.spec 2016-07-20 22:55:40.000000000 +0200 @@ -1,8 +1,8 @@ -# $Owl: Owl/packages/passwdqc/passwdqc/passwdqc.spec,v 1.63 2013/04/24 02:02:54 solar Exp $ +# $Owl: Owl/packages/passwdqc/passwdqc/passwdqc.spec,v 1.64 2016/07/20 20:55:40 solar Exp $ Summary: A password/passphrase strength checking and policy enforcement toolset. Name: passwdqc -Version: 1.3.0 +Version: 1.3.1 Release: owl1 License: BSD-compatible Group: System Environment/Base @@ -73,6 +73,21 @@ %_libdir/lib*.so %changelog +* Wed Jul 20 2016 Solar Designer <solar-at-owl.openwall.com> 1.3.1-owl1 +- With "non-unix", initialize the pw_dir field in fake_pw now that (since +passwdqc 1.1.3 in 2009) passwdqc_check.c uses that field. +Bug reported by Jim Paris via Debian: https://bugs.debian.org/831356 +- Use size_t for variables holding strlen() return values. +- Cap "max" at 10000 (in case a config set it higher; the default remains 40). +- Check against the shortest allowed password length prior to checking against +the old password (this affects reporting when the old password is empty). +- For zeroization of sensitive data, use a wrapper around memset() called via +a function pointer to reduce the likelihood of a compiler optimizing those +calls out and to allow for overriding of this function with an OS-specific +"secure" memory zeroization function. +- In pwqgen, set stdout to non-buffered, and zeroize and free our own buffer +holding the generated password. + * Wed Apr 24 2013 Solar Designer <solar-at-owl.openwall.com> 1.3.0-owl1 - When checking is_simple() after discounting a common character sequence, apply the (negative) bias even for the passphrase length check. Previously, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc_check.c new/passwdqc-1.3.1/passwdqc_check.c --- old/passwdqc-1.3.0/passwdqc_check.c 2013-04-24 03:16:03.000000000 +0200 +++ new/passwdqc-1.3.1/passwdqc_check.c 2016-07-21 14:22:55.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002,2010,2013 by Solar Designer. See LICENSE. + * Copyright (c) 2000-2002,2010,2013,2016 by Solar Designer. See LICENSE. */ #include <stdio.h> @@ -237,10 +237,10 @@ static void clean(char *dst) { - if (dst) { - memset(dst, 0, strlen(dst)); - free(dst); - } + if (!dst) + return; + _passwdqc_memzero(dst, strlen(dst)); + free(dst); } /* @@ -443,7 +443,7 @@ char *u_oldpass; char *u_name, *u_gecos, *u_dir; const char *reason; - int length; + size_t length; u_newpass = u_reversed = NULL; u_oldpass = NULL; @@ -451,23 +451,24 @@ reason = REASON_ERROR; - if (oldpass && !strcmp(oldpass, newpass)) { - reason = REASON_SAME; - goto out; - } - length = strlen(newpass); - if (length < params->min[4]) { + if (length < (size_t)params->min[4]) { reason = REASON_SHORT; goto out; } - if (length > params->max) { + if (length > 10000) { + reason = REASON_LONG; + goto out; + } + + if (length > (size_t)params->max) { if (params->max == 8) { truncated[0] = '\0'; strncat(truncated, newpass, 8); newpass = truncated; + length = 8; if (oldpass && !strncmp(oldpass, newpass, 8)) { reason = REASON_SAME; goto out; @@ -478,9 +479,15 @@ } } + if (oldpass && !strcmp(oldpass, newpass)) { + reason = REASON_SAME; + goto out; + } + if (is_simple(params, newpass, 0, 0)) { reason = REASON_SIMPLE; - if (length < params->min[1] && params->min[1] <= params->max) + if (length < (size_t)params->min[1] && + params->min[1] <= params->max) reason = REASON_SIMPLESHORT; goto out; } @@ -521,7 +528,7 @@ reason = is_word_based(params, u_reversed, newpass, 0x100); out: - memset(truncated, 0, sizeof(truncated)); + _passwdqc_memzero(truncated, sizeof(truncated)); clean(u_newpass); clean(u_reversed); clean(u_oldpass); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc_memzero.c new/passwdqc-1.3.1/passwdqc_memzero.c --- old/passwdqc-1.3.0/passwdqc_memzero.c 1970-01-01 01:00:00.000000000 +0100 +++ new/passwdqc-1.3.1/passwdqc_memzero.c 2016-07-21 03:01:59.000000000 +0200 @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2016 by Solar Designer. See LICENSE. + */ + +#include <string.h> + +static void memzero(void *buf, size_t len) +{ + memset(buf, 0, len); +} + +void (*_passwdqc_memzero)(void *, size_t) = memzero; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc_parse.c new/passwdqc-1.3.1/passwdqc_parse.c --- old/passwdqc-1.3.0/passwdqc_parse.c 2013-04-23 15:52:53.000000000 +0200 +++ new/passwdqc-1.3.1/passwdqc_parse.c 2016-07-20 22:12:50.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003,2005 by Solar Designer + * Copyright (c) 2000-2003,2005,2016 by Solar Designer * Copyright (c) 2008,2009 by Dmitry V. Levin * See LICENSE */ @@ -54,6 +54,8 @@ v = strtoul(p, &e, 10); if (*e || v < 8 || v > INT_MAX) goto parse_error; + if (v > 10000) + v = 10000; params->qc.max = v; } else if ((p = skip_prefix(option, "passphrase="))) { v = strtoul(p, &e, 10); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/passwdqc_random.c new/passwdqc-1.3.1/passwdqc_random.c --- old/passwdqc-1.3.0/passwdqc_random.c 2013-04-23 16:00:38.000000000 +0200 +++ new/passwdqc-1.3.1/passwdqc_random.c 2016-07-20 22:31:47.000000000 +0200 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2000-2002,2005,2008,2010,2013 by Solar Designer. See LICENSE. + * Copyright (c) 2000-2002,2005,2008,2010,2013,2016 by Solar Designer + * See LICENSE */ #include <stdio.h> @@ -204,8 +205,8 @@ } out: - memset(bytes, 0, sizeof(bytes)); - memset(output, 0, length); + _passwdqc_memzero(bytes, sizeof(bytes)); + _passwdqc_memzero(output, length); close(fd); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/pwqcheck.c new/passwdqc-1.3.1/pwqcheck.c --- old/passwdqc-1.3.0/pwqcheck.c 2010-03-15 04:46:05.000000000 +0100 +++ new/passwdqc-1.3.1/pwqcheck.c 2016-07-20 22:23:36.000000000 +0200 @@ -1,23 +1,24 @@ /* * Copyright (c) 2008,2009 by Dmitry V. Levin - * Copyright (c) 2010 by Solar Designer + * Copyright (c) 2010,2016 by Solar Designer * See LICENSE */ #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "passwdqc.h" -static void clean(char *dst, int size) +static void clean(char *dst, size_t size) { if (!dst) return; - memset(dst, 0, size); + _passwdqc_memzero(dst, size); free(dst); } -static char *read_line(unsigned int size, int eof_ok) +static char *read_line(size_t size, int eof_ok) { char *p, *buf = malloc(size + 1); @@ -73,7 +74,7 @@ return NULL; } if (p->pw_passwd) - memset(p->pw_passwd, 0, strlen(p->pw_passwd)); + _passwdqc_memzero(p->pw_passwd, strlen(p->pw_passwd)); memcpy(pw, p, sizeof(*pw)); } else { memset(pw, 0, sizeof(*pw)); @@ -131,7 +132,7 @@ char *parse_reason, *newpass, *oldpass, *pwline; struct passwd pwbuf, *pw; int lines_to_read = 3, multi = 0; - int size = 8192; + size_t size = 8192; int rc = 1; while (argc > 1 && argv[1][0] == '-') { @@ -173,8 +174,8 @@ return rc; } - if (params.qc.max + 1 > size) - size = params.qc.max + 1; + if ((size_t)params.qc.max + 1 > size) + size = (size_t)params.qc.max + 1; next_pass: oldpass = pwline = NULL; pw = NULL; @@ -204,7 +205,7 @@ printf("Bad passphrase (%s)\n", check_reason); cleanup: - memset(&pwbuf, 0, sizeof(pwbuf)); + _passwdqc_memzero(&pwbuf, sizeof(pwbuf)); clean(pwline, size); clean(oldpass, size); clean(newpass, size); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/passwdqc-1.3.0/pwqgen.c new/passwdqc-1.3.1/pwqgen.c --- old/passwdqc-1.3.0/pwqgen.c 2009-10-27 02:45:50.000000000 +0100 +++ new/passwdqc-1.3.1/pwqgen.c 2016-07-20 22:30:01.000000000 +0200 @@ -1,10 +1,13 @@ /* - * Copyright (c) 2008,2009 by Dmitry V. Levin. See LICENSE. + * Copyright (c) 2008,2009 by Dmitry V. Levin + * Copyright (c) 2016 by Solar Designer + * See LICENSE */ #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "passwdqc.h" static void @@ -27,6 +30,7 @@ { passwdqc_params_t params; char *reason, *pass; + int retval; if (argc > 1 && argv[1][0] == '-') { if (!strcmp("-h", argv[1]) || !strcmp("--help", argv[1])) { @@ -58,5 +62,12 @@ return 1; } - return (puts(pass) >= 0 && fflush(stdout) >= 0) ? 0 : 1; + setvbuf(stdout, NULL, _IONBF, 0); + + retval = (puts(pass) >= 0 && fflush(stdout) == 0) ? 0 : 1; + + _passwdqc_memzero(pass, strlen(pass)); + free(pass); + + return retval; }