Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package google-authenticator-libpam for openSUSE:Factory checked in at 2021-12-10 21:52:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/google-authenticator-libpam (Old) and /work/SRC/openSUSE:Factory/.google-authenticator-libpam.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "google-authenticator-libpam" Fri Dec 10 21:52:38 2021 rev:4 rq:939036 version:1.09 Changes: -------- --- /work/SRC/openSUSE:Factory/google-authenticator-libpam/google-authenticator-libpam.changes 2019-05-16 22:07:58.694395041 +0200 +++ /work/SRC/openSUSE:Factory/.google-authenticator-libpam.new.2520/google-authenticator-libpam.changes 2021-12-10 21:53:08.346912574 +0100 @@ -1,0 +2,10 @@ +Thu Dec 09 22:34:52 UTC 2021 - r...@fthiessen.de + +- Update to version 1.09: + * Fixed typo preventing use of setfsgid() over setegid() + * Fixed regression getting maximum getpwnam buf size + * set umask before `mkstemp` + * Add `allow_readonly` option + * Minor linter-level changes that probably don't matter + +------------------------------------------------------------------- Old: ---- google-authenticator-libpam-1.06.tar.xz New: ---- google-authenticator-libpam-1.09.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ google-authenticator-libpam.spec ++++++ --- /var/tmp/diff_new_pack.16QS3B/_old 2021-12-10 21:53:08.874912807 +0100 +++ /var/tmp/diff_new_pack.16QS3B/_new 2021-12-10 21:53:08.878912809 +0100 @@ -1,7 +1,7 @@ # # spec file for package google-authenticator-libpam # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,12 +17,12 @@ Name: google-authenticator-libpam -Version: 1.06 +Version: 1.09 Release: 0 Summary: Google Authenticator PAM module License: Apache-2.0 Group: Productivity/Security -Url: https://github.com/google/google-authenticator-libpam +URL: https://github.com/google/google-authenticator-libpam Source: %{name}-%{version}.tar.xz Source99: baselibs.conf BuildRequires: libtool @@ -33,8 +33,8 @@ Recommends: libqrencode3 BuildRoot: %{_tmppath}/%{name}-%{version}-build -Provides: pam-google-authenticator -Obsoletes: pam-google-authenticator +Provides: pam-google-authenticator = %{version} +Obsoletes: pam-google-authenticator < %{version} %description Integrate GOOGLE Authenticator into your login process for full 2FA. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.16QS3B/_old 2021-12-10 21:53:08.906912822 +0100 +++ /var/tmp/diff_new_pack.16QS3B/_new 2021-12-10 21:53:08.910912823 +0100 @@ -4,7 +4,7 @@ <param name="scm">git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> - <param name="revision">refs/tags/1.06</param> + <param name="revision">refs/tags/1.09</param> </service> <service name="recompress" mode="disabled"> <param name="file">*.tar</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.16QS3B/_old 2021-12-10 21:53:08.930912832 +0100 +++ /var/tmp/diff_new_pack.16QS3B/_new 2021-12-10 21:53:08.930912832 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/google/google-authenticator-libpam</param> - <param name="changesrevision">842142d52328baa6076826428fe040db98aab82a</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">962f353aac6cfc7b804547319db40f8b804f0b6c</param></service></servicedata> \ No newline at end of file ++++++ google-authenticator-libpam-1.06.tar.xz -> google-authenticator-libpam-1.09.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/.gitignore new/google-authenticator-libpam-1.09/.gitignore --- old/google-authenticator-libpam-1.06/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/google-authenticator-libpam-1.09/.gitignore 2020-05-26 12:10:21.000000000 +0200 @@ -0,0 +1,319 @@ +### Project specific ignores +.deps +.dirstamp +cmake-build-debug +libtool + +contrib/rpm.spec + +### Project binaries +google-authenticator +examples/demo +.libs + +### Project tests +test-suite.log +tests/pam_google_authenticator_unittest +tests/*.log +tests/*.trs + +### Autotools template +# http://www.gnu.org/software/automake + +Makefile.in +/ar-lib +/mdate-sh +/py-compile +/test-driver +/ylwrap + +# http://www.gnu.org/software/autoconf + +/autom4te.cache +/autoscan.log +/autoscan-*.log +/aclocal.m4 +/compile +/config.guess +/config.h.in +/config.h +/config.log +/config.sub +/config.status +/configure +/configure.scan +/depcomp +/install-sh +/missing +/stamp-h1 + +# https://www.gnu.org/software/libtool/ + +/ltmain.sh + +# http://www.gnu.org/software/texinfo + +/texinfo.tex +### C++ template +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +.idea/ + +## File-based project format: +*.iws +*.iml + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Archives template +# It's better to unpack these files and commit the raw source because +# git has its own built in compression methods. +*.7z +*.jar +*.rar +*.zip +*.gz +*.bzip +*.bz2 +*.xz +*.lzma +*.cab + +#packing-only formats +*.iso +*.tar + +#package management formats +*.dmg +*.xpi +*.gem +*.egg +*.deb +*.rpm +*.msi +*.msm +*.msp +### Xcode template +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint +### macOS template +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### Eclipse template + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# Eclipse Core +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet +### C template +# Prerequisites + +# Object files +*.ko +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers + +# Libraries + +# Shared objects (inc. Windows DLLs) +*.so.* + +# Executables +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +modules.order +Module.symvers +Mkfile.old +dkms.conf +### CMake template +CMakeCache.txt +CMakeFiles +CMakeLists.txt +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +### NetBeans template +nbproject/private/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ +### Vim template +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags +base32 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/README.md new/google-authenticator-libpam-1.09/README.md --- old/google-authenticator-libpam-1.06/README.md 2019-05-13 15:08:45.000000000 +0200 +++ new/google-authenticator-libpam-1.09/README.md 2020-05-26 12:10:21.000000000 +0200 @@ -1,6 +1,11 @@ # Google Authenticator PAM module -Example PAM module demonstrating two-factor authentication. +Example PAM module demonstrating two-factor authentication for logging +into servers via SSH, OpenVPN, etc??? + +This project is not about logging in to Google, Facebook, or other +TOTP/HOTP second factor systems, even if they recommend using the +Google Authenticator apps. [](https://travis-ci.org/google/google-authenticator-libpam) @@ -192,3 +197,18 @@ This works by adding an (IP address, timestamp) pair to the security file after a successful one-time-password login; only the last ten distinct IP addresses are tracked. + +### allow_readonly + +DANGEROUS OPTION! + +With this option an attacker with ability to fill up the filesystem (flood +server with web requests, or if they have an account just fill the disk up) can +force a situation where one-time-passwords can be reused, defeating the purpose +of "one time". + +By default, if the `grace_period` option is defined the PAM module requires +some free space to store the IP address and timestamp of the last login. +It could prevent access if a server has no free space or in case of an +update config file error. With the `allow_readonly` option you can ignore +any errors which could occur during config file update. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/build/.gitignore new/google-authenticator-libpam-1.09/build/.gitignore --- old/google-authenticator-libpam-1.06/build/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/google-authenticator-libpam-1.09/build/.gitignore 2020-05-26 12:10:21.000000000 +0200 @@ -0,0 +1,2 @@ +* +!.gitignore diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/configure.ac new/google-authenticator-libpam-1.09/configure.ac --- old/google-authenticator-libpam-1.06/configure.ac 2019-05-13 15:08:45.000000000 +0200 +++ new/google-authenticator-libpam-1.09/configure.ac 2020-05-26 12:10:21.000000000 +0200 @@ -1,5 +1,5 @@ AC_PREREQ(2.61) -AC_INIT(google-authenticator, 1.06, hab...@google.com) +AC_INIT(google-authenticator, 1.09, hab...@google.com) AC_CONFIG_SRCDIR([src/google-authenticator.c]) AC_CONFIG_AUX_DIR([build]) AC_CONFIG_MACRO_DIR([build]) @@ -21,6 +21,7 @@ AC_CHECK_FUNCS([ \ explicit_bzero \ setfsuid \ + setfsgid \ ]) AC_CHECK_HEADERS_ONCE([security/pam_appl.h]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/src/base32_prog.c new/google-authenticator-libpam-1.09/src/base32_prog.c --- old/google-authenticator-libpam-1.06/src/base32_prog.c 2019-05-13 15:08:45.000000000 +0200 +++ new/google-authenticator-libpam-1.09/src/base32_prog.c 2020-05-26 12:10:21.000000000 +0200 @@ -112,7 +112,7 @@ } const char *binfile = (optind < argc) ? argv[optind] : "-"; - int d = strcmp(binfile, "-") == 0 ? STDIN_FILENO : open(binfile, O_RDONLY); + const int d = strcmp(binfile, "-") == 0 ? STDIN_FILENO : open(binfile, O_RDONLY); if (d < 0) { err(1, "Failed to open %s: %s\n", binfile, strerror(errno)); } @@ -123,9 +123,16 @@ // AND multiple of 8 to ensure we feed // valid data to base32_decode(). } - uint8_t *input = malloc(st.st_size + 1); + const size_t bufsize = st.st_size + 1; + if (bufsize < st.st_size) { + err(1, "Integer overflow in input size"); + } + uint8_t *input = malloc(bufsize); + if (!input) { + err(1, "Failed to allocate memory"); + } int amt_read; - int amt_to_read = st.st_size; + const int amt_to_read = st.st_size; errno = 0; while ((amt_read = read(d, input, amt_to_read)) > 0 || errno == EINTR) { if (errno == EINTR) { @@ -134,9 +141,9 @@ // Encoding: 8 bytes out for every 5 input, plus up to 6 padding, and nul // Decoding: up to 5 bytes out for every 8 input. - int result_avail = (mode == ENCODE_FILE) ? - ((amt_read + 4) / 5 * 8 + 6 + 1) : - ((amt_read + 7) / 8 * 5) ; + const int result_avail = (mode == ENCODE_FILE) ? + ((amt_read + 4) / 5 * 8 + 6 + 1) : + ((amt_read + 7) / 8 * 5) ; uint8_t *result = malloc(result_avail); input[amt_read] = '\0'; @@ -155,6 +162,7 @@ fflush(stdout); free(result); } + free(input); if (amt_read < 0) { err(1, "Failed to read from %s: %s\n", binfile, strerror(errno)); } @@ -167,7 +175,11 @@ } const char *base32_value = argv[2]; - int result_avail = strlen(base32_value) + 1; + const int result_avail = strlen(base32_value) + 1; + if (result_avail < strlen(base32_value)) { + err(1, "Integer overflow in input size"); + } + uint8_t *result = malloc(result_avail); retval = base32_decode((uint8_t *)base32_value, result, result_avail); @@ -176,6 +188,7 @@ exit(1); } full_write(STDOUT_FILENO, result, retval); + free(result); } return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/src/google-authenticator.c new/google-authenticator-libpam-1.09/src/google-authenticator.c --- old/google-authenticator-libpam-1.06/src/google-authenticator.c 2019-05-13 15:08:45.000000000 +0200 +++ new/google-authenticator-libpam-1.09/src/google-authenticator.c 2020-05-26 12:10:21.000000000 +0200 @@ -413,10 +413,17 @@ return buf; } +static void +print_version() { + puts("google-authenticator "VERSION); +} + static void usage(void) { + print_version(); puts( "google-authenticator [<options>]\n" " -h, --help Print this message\n" + " --version Print version\n" " -c, --counter-based Set up counter-based (HOTP) verification\n" " -C, --no-confirm Don't confirm code. For non-interactive setups\n" " -t, --time-based Set up time-based (TOTP) verification\n" @@ -471,6 +478,7 @@ static const char optstring[] = "+hcCtdDfl:i:qQ:r:R:us:S:w:We:"; static struct option options[] = { { "help", 0, 0, 'h' }, + { "version", 0, 0, 0}, { "counter-based", 0, 0, 'c' }, { "no-confirm", 0, 0, 'C' }, { "time-based", 0, 0, 't' }, @@ -513,6 +521,10 @@ } exit(0); } else if (!idx--) { + // --version + print_version(); + exit(0); + } else if (!idx--) { // counter-based, -c if (mode != ASK_MODE) { fprintf(stderr, "Duplicate -c and/or -t option detected\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-authenticator-libpam-1.06/src/pam_google_authenticator.c new/google-authenticator-libpam-1.09/src/pam_google_authenticator.c --- old/google-authenticator-libpam-1.06/src/pam_google_authenticator.c 2019-05-13 15:08:45.000000000 +0200 +++ new/google-authenticator-libpam-1.09/src/pam_google_authenticator.c 2020-05-26 12:10:21.000000000 +0200 @@ -73,6 +73,7 @@ int no_strict_owner; int allowed_perm; time_t grace_period; + int allow_readonly; } Params; static char oom; @@ -181,8 +182,22 @@ return (const char *)rhost; } +static size_t +getpwnam_buf_max_size() +{ +#ifdef _SC_GETPW_R_SIZE_MAX + const ssize_t len = sysconf(_SC_GETPW_R_SIZE_MAX); + if (len <= 0) { + return 4096; + } + return len; +#else + return 4096; +#endif +} + static char *get_secret_filename(pam_handle_t *pamh, const Params *params, - const char *username, int *uid) { + const char *username, uid_t *uid) { if (!username) { return NULL; } @@ -200,14 +215,7 @@ char *secret_filename = NULL; // Here because goto jumps. if (!params->fixed_uid) { - #ifdef _SC_GETPW_R_SIZE_MAX - int len = sysconf(_SC_GETPW_R_SIZE_MAX); - if (len <= 0) { - len = 4096; - } - #else - int len = 4096; - #endif + const int len = getpwnam_buf_max_size(); buf = malloc(len); *uid = -1; if (buf == NULL) { @@ -279,13 +287,14 @@ log_message(LOG_ERR, pamh, "Unexpectedly large path name: %d", subst_len); goto errout; } + const int varidx = var - secret_filename; char *resized = realloc(secret_filename, strlen(secret_filename) + subst_len + 1); if (!resized) { log_message(LOG_ERR, pamh, "Short mem allocation failed"); goto errout; } - var += resized - secret_filename; + var = resized + varidx; secret_filename = resized; memmove(var + subst_len, var + var_len, strlen(var + var_len) + 1); memmove(var, subst, subst_len); @@ -329,7 +338,7 @@ } static int setgroup(int gid) { -#ifdef HAS_SETFSUID +#ifdef HAVE_SETFSGID // The semantics of setfsgid() are a little unusual. On success, the // previous group id is returned. On failure, the current groupd id is // returned. @@ -415,7 +424,7 @@ struct Params *params, const char *username, int uid, struct stat *orig_stat) { // Try to open "~/.google_authenticator" - int fd = open(secret_filename, O_RDONLY); + const int fd = open(secret_filename, O_RDONLY); if (fd < 0 || fstat(fd, orig_stat) < 0) { if (params->nullok != NULLERR && errno == ENOENT) { @@ -424,7 +433,8 @@ // but we remember that this was the result of a missing state file. params->nullok = SECRETNOTFOUND; } else { - log_message(LOG_ERR, pamh, "Failed to read \"%s\" for \"%s\"", secret_filename, username); + log_message(LOG_ERR, pamh, "Failed to read \"%s\" for \"%s\": %s", + secret_filename, username, strerror(errno)); } error: if (fd >= 0) { @@ -484,6 +494,7 @@ off_t filesize) { // Arbitrary limit to prevent integer overflow. if (filesize > 1000000) { + close(*fd); errno = E2BIG; return NULL; } @@ -582,7 +593,9 @@ err = ERANGE; goto cleanup; } + const mode_t old_mask = umask(077); fd = mkstemp(tmp_filename); + umask(old_mask); if (fd < 0) { err = errno; log_message(LOG_ERR, pamh, "Failed to create tempfile \"%s\": %s", @@ -1596,7 +1609,9 @@ memset(value, 0, sizeof value); snprintf(value, sizeof value, "%s %lu", rhost, (unsigned long)now); - set_cfg_value(pamh, name, value, buf); + if (set_cfg_value(pamh, name, value, buf) < 0) { + log_message(LOG_WARNING, pamh, "Failed to set cfg value for login host"); + } return 0; } @@ -1692,6 +1707,10 @@ return 1; } +// parse a user name. +// input: user name +// output: uid +// return: 0 on success. static int parse_user(pam_handle_t *pamh, const char *name, uid_t *uid) { char *endptr; errno = 0; @@ -1700,14 +1719,7 @@ *uid = (uid_t)l; return 0; } - #ifdef _SC_GETPW_R_SIZE_MAX - int len = sysconf(_SC_GETPW_R_SIZE_MAX); - if (len <= 0) { - len = 4096; - } - #else - int len = 4096; - #endif + const size_t len = getpwnam_buf_max_size(); char *buf = malloc(len); if (!buf) { log_message(LOG_ERR, pamh, "Out of memory"); @@ -1767,6 +1779,8 @@ params->no_increment_hotp = 1; } else if (!strcmp(argv[i], "nullok")) { params->nullok = NULLOK; + } else if (!strcmp(argv[i], "allow_readonly")) { + params->allow_readonly = 1; } else if (!strcmp(argv[i], "echo-verification-code") || !strcmp(argv[i], "echo_verification_code")) { params->echocode = PAM_PROMPT_ECHO_ON; @@ -1792,7 +1806,8 @@ static int google_authenticator(pam_handle_t *pamh, int argc, const char **argv) { int rc = PAM_AUTH_ERR; - int uid = -1, old_uid = -1, old_gid = -1, fd = -1; + uid_t uid = -1; + int old_uid = -1, old_gid = -1, fd = -1; char *buf = NULL; struct stat orig_stat = { 0 }; uint8_t *secret = NULL; @@ -1824,7 +1839,7 @@ // If user doesn't exist, use 'nobody'. if (uid == -1) { drop_username = nobody; - if (!get_secret_filename(pamh, ¶ms, drop_username, &uid)) { + if (parse_user(pamh, drop_username, &uid)) { // If 'nobody' doesn't exist, bail. We need to drop privs to *someone*. goto out; } @@ -2087,8 +2102,13 @@ snprintf(s, sizeof(s), "Error \"%s\" while writing config", strerror(err)); conv_error(pamh, s); } - // Could not persist new state. Deny access. - rc = PAM_AUTH_ERR; + + // If allow_readonly parameter is defined than ignore write errors and + // allow user to login. + if (!params.allow_readonly) { + // Could not persist new state. Deny access. + rc = PAM_AUTH_ERR; + } } }