Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pam_u2f for openSUSE:Factory checked in at 2023-04-16 19:13:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pam_u2f (Old) and /work/SRC/openSUSE:Factory/.pam_u2f.new.19717 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pam_u2f" Sun Apr 16 19:13:05 2023 rev:12 rq:1079764 version:1.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/pam_u2f/pam_u2f.changes 2022-05-30 12:45:12.316490737 +0200 +++ /work/SRC/openSUSE:Factory/.pam_u2f.new.19717/pam_u2f.changes 2023-04-16 19:13:24.069455037 +0200 @@ -1,0 +2,8 @@ +Sat Apr 15 12:01:02 UTC 2023 - Dirk Müller <[email protected]> + +- update to 1.3.0: + * Add sanity checking of UV options to pamu2fcfg. + * Add support for username expansion in the authfile path. + * Improvements to the documentation. + +------------------------------------------------------------------- Old: ---- pam_u2f-1.2.1.tar.gz pam_u2f-1.2.1.tar.gz.sig New: ---- pam_u2f-1.3.0.tar.gz pam_u2f-1.3.0.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pam_u2f.spec ++++++ --- /var/tmp/diff_new_pack.9XeZBI/_old 2023-04-16 19:13:24.469457348 +0200 +++ /var/tmp/diff_new_pack.9XeZBI/_new 2023-04-16 19:13:24.469457348 +0200 @@ -1,7 +1,7 @@ # # spec file for package pam_u2f # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{!?_pam_moduledir: %define _pam_moduledir /%{_lib}/security} Name: pam_u2f -Version: 1.2.1 +Version: 1.3.0 Release: 0 Summary: U2F authentication integration into PAM License: BSD-2-Clause ++++++ pam_u2f-1.2.1.tar.gz -> pam_u2f-1.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/COPYING new/pam_u2f-1.3.0/COPYING --- old/pam_u2f-1.2.1/COPYING 2022-04-22 14:15:06.000000000 +0200 +++ new/pam_u2f-1.3.0/COPYING 2023-03-09 08:46:20.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Yubico AB +Copyright (c) 2014-2023 Yubico AB All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/ChangeLog new/pam_u2f-1.3.0/ChangeLog --- old/pam_u2f-1.2.1/ChangeLog 2022-05-11 09:16:55.000000000 +0200 +++ new/pam_u2f-1.3.0/ChangeLog 2023-03-14 10:02:38.000000000 +0100 @@ -1,3 +1,214 @@ +2023-03-14 Ludvig Michaelsson <[email protected]> + + * NEWS: release 1.3.0 + +2023-03-06 Ludvig Michaelsson <[email protected]> + + * NEWS: news: prepare for 1.3.0 + +2023-03-06 Ludvig Michaelsson <[email protected]> + + * NEWS, configure.ac: misc: adjust version to reflect changes Next version introduces new features. + +2023-03-03 Ludvig Michaelsson <[email protected]> + + * man/pam_u2f.8.txt: man: clarify relative and absolute authfile + paths + +2023-02-16 Ludvig Michaelsson <[email protected]> + + * COPYING: COPYING: bump copyright + +2023-03-02 Ludvig Michaelsson <[email protected]> + + * README, man/pam_u2f.8.txt: man: clarify what a global authfile is + +2023-03-02 Ludvig Michaelsson <[email protected]> + + * README, man/pam_u2f.8.txt: man: document `expand` + +2023-02-15 Ludvig Michaelsson <[email protected]> + + * Makefile.am, pam-u2f.c, util.h: pam: add opt-in for %u expansion + in authfile path + +2023-02-15 Ludvig Michaelsson <[email protected]> + + * expand.c, tests/Makefile.am, tests/expand.c, util.h: expand: + utility for replacing occurrences of %u with username + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * README, man/pamu2fcfg.1.txt: man: add references to fido2-token, + yubikey-manager For setting PIN, enrolling fingerprints, and more. + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * pamu2fcfg/pamu2fcfg.c: pamu2fcfg: also check FIDO_ERR_PIN_BLOCKED For CTAP 2.0 authenticators' equivalent of FIDO_ERR_UV_BLOCKED. + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * pamu2fcfg/pamu2fcfg.c: pamu2fcfg: make_cred() exercises UV Attempt using either built-in UV/PIN depending on the user selection + of authentication options. This fixes #278 (more consistent PIN prompts). + +2022-11-29 Ludvig Michaelsson <[email protected]> + + * pamu2fcfg/pamu2fcfg.c: pamu2fcfg: make_cred() for non-PIN + authenticators CTAP2.0 with some form of UV configured will require UV for + credential creation. Similarly, CTAP2.1 devices will require some + form of UV if the makeCredUvNotRqd option is not enabled. While here, allow fallback to PIN if built-in UV is blocked. + +2022-11-29 Ludvig Michaelsson <[email protected]> + + * pamu2fcfg/pamu2fcfg.c: pamu2fcfg: basic sanity checking of user + options Compare selection of user verification methods to what the + authenticator actually supports. This fixes #278 (ensure that device actually has some form of UV). + +2022-11-29 Ludvig Michaelsson <[email protected]> + + * pamu2fcfg/pamu2fcfg.c: pamu2fcfg: defer prepare_cred() + +2022-12-01 Ludvig Michaelsson <[email protected]> + + * .github/ISSUE_TEMPLATE/config.yml: github: direct questions to + discussions tab + +2022-12-01 Ludvig Michaelsson <[email protected]> + + * .github/ISSUE_TEMPLATE/feature_request.md: github: feature request + template + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * SECURITY.md: github: add security policy + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * .github/ISSUE_TEMPLATE/bug_report.md: github: add bug report + template + +2022-11-30 Ludvig Michaelsson <[email protected]> + + * .github/workflows/format.yml, build-aux/ci/format-code.sh: ci: + update clang-format version + +2022-11-21 Ludvig Michaelsson <[email protected]> + + * README, man/pam_u2f.8.txt: README: add common example + configurations + +2022-11-21 Ludvig Michaelsson <[email protected]> + + * README, man/pam_u2f.8.txt: README: clarify multiple authenticators While here, remove an unused anchor and refer to the authorization + mapping file consistently. + +2022-11-21 Ludvig Michaelsson <[email protected]> + + * README: README: change heading syntax, add subsections While here, move a notice about origin/appid to a more relevant + section. + +2022-11-21 Ludvig Michaelsson <[email protected]> + + * README: README: yubikey-touch-detector no longer uses + authpending_file + +2022-11-21 Ludvig Michaelsson <[email protected]> + + * README: README: consistent headings + +2022-11-01 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_builds.yml: ci: restore install of + docbook-xsl + +2022-11-01 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_builds.yml: ci: bump gcc to gcc-12 + +2022-09-05 Ludvig Michaelsson <[email protected]> + + * .github/workflows/macos_builds.yml: ci: macos 10.15 workflows are + deprecated + +2022-09-05 Ludvig Michaelsson <[email protected]> + + * .github/workflows/format.yml, .github/workflows/linux_builds.yml: + ci: ubuntu 18.04 workflows are deprected + +2022-06-08 Ludvig Michaelsson <[email protected]> + + * .github/workflows/alpine_builds.yml, + .github/workflows/codeql-analysis.yml, + .github/workflows/format.yml, .github/workflows/linux_builds.yml, + .github/workflows/linux_fuzz.yml, + .github/workflows/macos_builds.yml: ci: bump checkout to v3 While here, use the proposed workaround for ownership problems [1]. [1] https://github.com/actions/checkout/issues/766 + +2022-07-13 Ludvig Michaelsson <[email protected]> + + * .github/workflows/format.yml, build-aux/ci/format-code.sh: ci: + update base branch name to main + +2022-06-23 Ludvig Michaelsson <[email protected]> + + * .github/workflows/alpine_builds.yml: ci: drop USER environment + variable + +2022-06-23 Ludvig Michaelsson <[email protected]> + + * tests/get_devices.c: tests: prefer getpwuid over getenv `$USER` may not be set, look up the username of the effective user + ID from the password database instead. In the long term, consider + splitting authfile handling and parsing to simplify testing. This fixes #270. + +2022-06-17 Ludvig Michaelsson <[email protected]> + + * build-aux/ci/fuzz-linux-asan.sh: fuzz: bump libcbor to 0.9.0 + +2022-06-17 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_fuzz.yml, build-aux/ci/fuzz-linux-asan.sh: + fuzz: bump libfido2 to 1.11.0 + +2022-06-09 Ludvig Michaelsson <[email protected]> + + * .github/workflows/macos_builds.yml: ci: add macos-11, macos-12 + +2022-06-07 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_fuzz.yml: ci: bump fuzzer builds to ubuntu + 22.04/clang-14 + +2022-06-07 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_builds.yml: ci: add ubuntu 22.04 builds + +2022-06-07 Ludvig Michaelsson <[email protected]> + + * .github/workflows/linux_builds.yml: ci: collapse linux build + matrix + +2022-06-02 Ludvig Michaelsson <[email protected]> + + * .github/workflows/codeql-analysis.yml: ci: update codeql to v2 + +2022-06-02 Ludvig Michaelsson <[email protected]> + + * .github/workflows/alpine_builds.yml: ci: alpine now packages + libfido2-dev + +2022-06-02 Ludvig Michaelsson <[email protected]> + + * .github/workflows/alpine_builds.yml: ci: bump alpine host to + ubuntu-22.04 + +2022-06-02 Ludvig Michaelsson <[email protected]> + + * .github/workflows/alpine_builds.yml: ci: explicitly add bash to + alpine container + +2022-05-11 Ludvig Michaelsson <[email protected]> + + * NEWS, configure.ac: Bump version + 2022-05-11 Ludvig Michaelsson <[email protected]> * NEWS: Update NEWS file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/Makefile.am new/pam_u2f-1.3.0/Makefile.am --- old/pam_u2f-1.2.1/Makefile.am 2022-04-29 09:07:32.000000000 +0200 +++ new/pam_u2f-1.3.0/Makefile.am 2023-03-09 08:46:20.000000000 +0100 @@ -23,6 +23,7 @@ libmodule_la_SOURCES += b64.c b64.h libmodule_la_SOURCES += debug.c debug.h libmodule_la_SOURCES += drop_privs.h +libmodule_la_SOURCES += expand.c libmodule_la_SOURCES += explicit_bzero.c libmodule_la_SOURCES += util.c util.h libmodule_la_LIBADD = -lpam $(LIBFIDO2_LIBS) $(LIBCRYPTO_LIBS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/Makefile.in new/pam_u2f-1.3.0/Makefile.in --- old/pam_u2f-1.2.1/Makefile.in 2022-05-05 10:21:49.000000000 +0200 +++ new/pam_u2f-1.3.0/Makefile.in 2023-03-14 09:58:14.000000000 +0100 @@ -198,8 +198,8 @@ am__DEPENDENCIES_1 = libmodule_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) -am_libmodule_la_OBJECTS = pam-u2f.lo b64.lo debug.lo explicit_bzero.lo \ - util.lo +am_libmodule_la_OBJECTS = pam-u2f.lo b64.lo debug.lo expand.lo \ + explicit_bzero.lo util.lo libmodule_la_OBJECTS = $(am_libmodule_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -230,8 +230,9 @@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/b64.Plo ./$(DEPDIR)/debug.Plo \ - ./$(DEPDIR)/explicit_bzero.Plo ./$(DEPDIR)/pam-u2f.Plo \ - ./$(DEPDIR)/util.Plo fuzz/$(DEPDIR)/wrap.Plo + ./$(DEPDIR)/expand.Plo ./$(DEPDIR)/explicit_bzero.Plo \ + ./$(DEPDIR)/pam-u2f.Plo ./$(DEPDIR)/util.Plo \ + fuzz/$(DEPDIR)/wrap.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -523,7 +524,7 @@ AM_CPPFLAGS = $(LIBFIDO2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(am__append_3) noinst_LTLIBRARIES = libmodule.la libmodule_la_SOURCES = pam-u2f.c b64.c b64.h debug.c debug.h \ - drop_privs.h explicit_bzero.c util.c util.h + drop_privs.h expand.c explicit_bzero.c util.c util.h libmodule_la_LIBADD = -lpam $(LIBFIDO2_LIBS) $(LIBCRYPTO_LIBS) pampluginexecdir = $(PAMDIR) pampluginexec_LTLIBRARIES = pam_u2f.la @@ -723,6 +724,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/b64.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/explicit_bzero.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam-u2f.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ # am--include-marker @@ -1114,6 +1116,7 @@ -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f ./$(DEPDIR)/b64.Plo -rm -f ./$(DEPDIR)/debug.Plo + -rm -f ./$(DEPDIR)/expand.Plo -rm -f ./$(DEPDIR)/explicit_bzero.Plo -rm -f ./$(DEPDIR)/pam-u2f.Plo -rm -f ./$(DEPDIR)/util.Plo @@ -1168,6 +1171,7 @@ -rm -rf $(top_srcdir)/autom4te.cache -rm -f ./$(DEPDIR)/b64.Plo -rm -f ./$(DEPDIR)/debug.Plo + -rm -f ./$(DEPDIR)/expand.Plo -rm -f ./$(DEPDIR)/explicit_bzero.Plo -rm -f ./$(DEPDIR)/pam-u2f.Plo -rm -f ./$(DEPDIR)/util.Plo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/NEWS new/pam_u2f-1.3.0/NEWS --- old/pam_u2f-1.2.1/NEWS 2022-05-11 08:12:30.000000000 +0200 +++ new/pam_u2f-1.3.0/NEWS 2023-03-14 10:02:07.000000000 +0100 @@ -1,7 +1,12 @@ -Copyright (c) 2014-2022 Yubico AB - See COPYING +Copyright (c) 2014-2023 Yubico AB - See COPYING pam-u2f NEWS -- History of user-visible changes. -*- outline -*- +* Version 1.3.0 (released 2023-03-14) +** Add sanity checking of UV options to pamu2fcfg. +** Add support for username expansion in the authfile path. +** Improvements to the documentation. + * Version 1.2.1 (released 2022-05-11) ** Fixed an issue where native credentials could be truncated, resulting in failure to authenticate or successful authentication with missing options. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/README new/pam_u2f-1.3.0/README --- old/pam_u2f-1.2.1/README 2022-04-29 09:07:32.000000000 +0200 +++ new/pam_u2f-1.3.0/README 2023-03-09 08:46:20.000000000 +0100 @@ -1,5 +1,4 @@ -Pluggable Authentication Module (PAM) Universal 2nd Factor (U2F) -================================================================ += Pluggable Authentication Module (PAM) Universal 2nd Factor (U2F) image:https://github.com/yubico/pam-u2f/workflows/linux/badge.svg["Linux Build Status (github actions)", link="https://github.com/Yubico/pam-u2f/actions"] image:https://github.com/yubico/pam-u2f/workflows/macos/badge.svg["macOS Build Status (github actions)", link="https://github.com/Yubico/pam-u2f/actions"] @@ -10,8 +9,7 @@ infrastructure. [[building]] -Building --------- +== Building This project uses 'autoconf', 'automake', 'pkg-config' and 'libtool' to achieve portability and ease of use. @@ -35,8 +33,7 @@ $ make ---- -Building from Git ------------------ +== Building from Git You may check out the sources using Git with the following command: @@ -80,8 +77,7 @@ Then build as usual, see above under <<building,Building>>. -Installation ------------- +== Installation Once the module is built, copy the file `pam_u2f.so` to the correct directory for your system. Typically `/lib/security/` or @@ -90,6 +86,8 @@ that is not the case it can be specified with `./configure --with-pam-dir=`. +== Service Configuration + Create a file for a new service in `/etc/pam.d/` or edit an already existing one by adding a line similar to this: @@ -98,7 +96,8 @@ ---- For more information about the syntax of PAM configuration files, please -see the manual page for pam.conf(5). +see the manual page for pam.conf(5). Additional <<examples,example +configurations>> can be found below. IMPORTANT: An erroneous PAM configuration may lock some or all users out of the system or prevent you from gaining root privileges. It is @@ -106,7 +105,7 @@ configuring PAM to be able to revert changes if something goes wrong. Test your configuration thoroughly before closing the root shell. -Supported parameters for the module are: +=== Module Arguments [horizontal] debug:: @@ -141,6 +140,11 @@ $XDG_CONFIG_HOME/Yubico/u2f_keys. If $XDG_CONFIG_HOME is not set, $HOME/.config/Yubico/u2f_keys is used. +expand:: +Enables variable expansion within the authfile path: `%u` is expanded to the +local user name (`PAM_USER`) and `%%` is expanded to `%`. Unknown expansion +sequences result in an authentication error. See also `openasuser`. + authpending_file=file:: Set the location of the file that is used for touch request notifications. This file will be opened when pam-u2f starts waiting @@ -148,8 +152,9 @@ waits for a touch. Use inotify to listen on these events, or a more high-level tool like https://github.com/maximbaz/yubikey-touch-detector[yubikey-touch-detector]. -Set an empty value in order to disable this functionality, like so: -`authpending_file=`. Default value: +Note that yubikey-touch-detector v1.5.1 and later no longer rely on the +authpending file for its detection mechanism. Set an empty value in order to +disable this functionality, like so: `authpending_file=`. Default value: /var/run/user/$UID/pam-u2f-authpending nouserok:: @@ -162,17 +167,17 @@ when the user's home is stored on an NFS volume mounted with the `root_squash` option (which maps root to nobody which will not be able to read the file). Note that after release 1.0.8 this is done by -default when no global authfile or XDG_CONFIG_HOME environment -variable has been set. +default when no global authfile (path is absolute) or XDG_CONFIG_HOME +environment variable has been set. alwaysok:: Set to enable all authentication attempts to succeed (aka presentation mode). max_devices=n_devices:: -Maximum number of devices allowed per user (default is 24). Devices -specified in the authentication file that exceed this value will be -ignored. +Maximum number of devices (credentials) allowed per user (default is 24). +Devices specified in the authorization mapping file that exceed this value will +be ignored. interactive:: Set to prompt a message and wait before testing the presence of a FIDO @@ -232,9 +237,53 @@ credentials. Once this option is enabled all credentials will be parsed as SSH. +IMPORTANT: On dynamic networks (e.g. where hostnames are set by DHCP), +users should not rely on the default origin and appid +("pam://$HOSTNAME") but set those parameters explicitly to the same +value. + +[[examples]] +=== Example Service Configurations + +==== Second Factor Authentication + +Configure pam-u2f as a `required` module after your primary authentication +module(s) for use as a second factor. Make sure that the primary authentication +method is not `sufficient` or uses other control values that may preempt +execution of pam-u2f. + +---- +# Primary authentication method(s) above this line. +auth required pam_u2f.so authfile=/etc/u2f_mappings cue +---- + +==== Passwordless Authentication + +For a passwordless experience, where the authenticator PIN can be used in place +of the user password, you can insert the below line towards the top of your +service configuration. You may need to change the control value to something +else if you'd like to execute additional authentication modules after pam-u2f. + +---- +auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=1 +# Fallback modules go below this line (e.g. password authentication). +---- + +==== Passwordless Authentication using Biometrics + +Similar to the previous configuration but capable of built-in user +verification, e.g. fingerprint matching using the YubiKey Bio. This example +falls back to using PIN verification if the fingerprint does not match or is +otherwise blocked. + +---- +auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=0 userverification=1 +auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=1 userverification=0 +# More fallback modules go below this line (e.g. password authentication). +---- + [[authMappingFiles]] -Authorization Mapping Files ---------------------------- +== Authorization Mapping Files A mapping must be made between the YubiKey token and the user name, see <<registration, here>> for details on how to perform the @@ -257,8 +306,7 @@ in the impossibility of logging into the system. The partition is decrypted after login and the mapping file can not be accessed. -Central Authorization Mapping ------------------------------ +=== Central Authorization Mapping Create a file e.g. `/etc/u2f_mappings`. The file must contain a user name, and the information obtained during the registration procedure. @@ -277,14 +325,8 @@ opened and parsed as `root` so make sure it has the correct owner and permissions set. -IMPORTANT: On dynamic networks (e.g. where hostnames are set by DHCP), -users should not rely on the default origin and appid -("pam://$HOSTNAME") but set those parameters explicitly to the same -value. - [[individualAuth]] -Individual Authorization Mapping by User ----------------------------------------- +=== Individual Authorization Mapping by User Each user creates a `.config/Yubico/u2f_keys` (default) file inside their home directory and places the mapping in that file. You may want @@ -308,8 +350,7 @@ case. [[registration]] -Obtaining key-handles and Public Keys -------------------------------------- +=== Obtaining Key Handles and Public Keys In order to obtain the required information for the authentication procedure, a token should be first registered. This can be done by using the command line @@ -329,8 +370,13 @@ additional information on the tool read the relative manpage (`man pamu2fcfg`). -SSH Credentials ---------------- +For authenticator management (e.g. setting a PIN, enrolling fingerprints, and +more), please refer to +https://developers.yubico.com/libfido2/Manuals/fido2-token.html[`fido2-token`], +https://developers.yubico.com/yubikey-manager[`yubikey-manager`], or some other +suitable tool. + +=== SSH Credentials To generate SSH credentials OpenSSH version 8.2 or later is required. It is then possible to generate a credential file with: @@ -347,18 +393,15 @@ the file `credential.ssh` and the `sshformat` option should also be set. If the `authfile` parameter is not set, it defaults to `~/.ssh/id_ecdsa_sk`. -[[devices]] -Multiple Devices ----------------- - -Multiple devices are supported. If more than one device is specified, -authentication against them is attempted sequentially as they are defined -in the configuration file of the module. If during an authentication -attempt a connected device is removed or a new device is plugged in, -the authentication restarts from the top of the list. +=== Multiple Devices + +Multiple devices (credentials) are supported. If more than one credential is +specified, authentication against them is attempted sequentially as they are +defined in the authorization mapping file. If during an authentication attempt +a connected device is removed or a new device is plugged in, the authentication +restarts from the top of the list. -SELinux Note ------------- +== SELinux Note Due to an issue with Fedora Linux, and possibly with other distributions that use SELinux, a system configured with pam-u2f may @@ -383,8 +426,7 @@ For more information see https://access.redhat.com/security/cve/CVE-2020-24612[HERE]. -FIDO U2F vs FIDO2 ------------------ +== FIDO U2F vs FIDO2 Devices that solely support FIDO U2F and not FIDO2, e.g. the YubiKey 4 series, can be used only in conjunction with compatible features. Enabling incompatible features, such as setting the `+pin` or the `+verification` flags in the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/aclocal.m4 new/pam_u2f-1.3.0/aclocal.m4 --- old/pam_u2f-1.2.1/aclocal.m4 2022-05-05 10:21:48.000000000 +0200 +++ new/pam_u2f-1.3.0/aclocal.m4 2023-03-14 09:58:13.000000000 +0100 @@ -20,9 +20,9 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 11 (pkg-config-0.29.1) + dnl Copyright © 2004 Scott James Remnant <[email protected]>. dnl Copyright © 2012-2015 Dan Nicholson <[email protected]> dnl @@ -296,6 +296,74 @@ AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + # Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/configure new/pam_u2f-1.3.0/configure --- old/pam_u2f-1.2.1/configure 2022-05-05 10:21:49.000000000 +0200 +++ new/pam_u2f-1.3.0/configure 2023-03-14 09:58:14.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pam_u2f 1.2.1. +# Generated by GNU Autoconf 2.69 for pam_u2f 1.3.0. # # Report bugs to <https://github.com/Yubico/pam-u2f/issues>. # @@ -650,8 +650,8 @@ # Identity of this package. PACKAGE_NAME='pam_u2f' PACKAGE_TARNAME='pam_u2f' -PACKAGE_VERSION='1.2.1' -PACKAGE_STRING='pam_u2f 1.2.1' +PACKAGE_VERSION='1.3.0' +PACKAGE_STRING='pam_u2f 1.3.0' PACKAGE_BUGREPORT='https://github.com/Yubico/pam-u2f/issues' PACKAGE_URL='https://developers.yubico.com/pam-u2f/' @@ -1415,7 +1415,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures pam_u2f 1.2.1 to adapt to many kinds of systems. +\`configure' configures pam_u2f 1.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1486,7 +1486,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pam_u2f 1.2.1:";; + short | recursive ) echo "Configuration of pam_u2f 1.3.0:";; esac cat <<\_ACEOF @@ -1619,7 +1619,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pam_u2f configure 1.2.1 +pam_u2f configure 1.3.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1988,7 +1988,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by pam_u2f $as_me 1.2.1, which was +It was created by pam_u2f $as_me 1.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2925,7 +2925,7 @@ # Define the identity of the package. PACKAGE='pam_u2f' - VERSION='1.2.1' + VERSION='1.3.0' cat >>confdefs.h <<_ACEOF @@ -14775,7 +14775,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by pam_u2f $as_me 1.2.1, which was +This file was extended by pam_u2f $as_me 1.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14833,7 +14833,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -pam_u2f config.status 1.2.1 +pam_u2f config.status 1.3.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/configure.ac new/pam_u2f-1.3.0/configure.ac --- old/pam_u2f-1.2.1/configure.ac 2022-04-29 09:07:32.000000000 +0200 +++ new/pam_u2f-1.3.0/configure.ac 2023-03-09 08:46:33.000000000 +0100 @@ -1,6 +1,6 @@ # Copyright (C) 2014-2022 Yubico AB AC_PREREQ([2.65]) -AC_INIT([pam_u2f], [1.2.1], [https://github.com/Yubico/pam-u2f/issues], +AC_INIT([pam_u2f], [1.3.0], [https://github.com/Yubico/pam-u2f/issues], [pam_u2f], [https://developers.yubico.com/pam-u2f/]) AC_CONFIG_AUX_DIR([build-aux]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/expand.c new/pam_u2f-1.3.0/expand.c --- old/pam_u2f-1.2.1/expand.c 1970-01-01 01:00:00.000000000 +0100 +++ new/pam_u2f-1.3.0/expand.c 2023-03-09 08:46:20.000000000 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2023 Yubico AB - See COPYING + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +#include "util.h" + +static int buf_write(uint8_t **dst, size_t *size, const void *src, size_t n) { + if (*size < n) { + return -1; + } + + memcpy(*dst, src, n); + *dst += n; + *size -= n; + + return 0; +} + +static int buf_write_byte(uint8_t **dst, size_t *size, uint8_t c) { + return buf_write(dst, size, &c, sizeof(c)); +} + +static const char *lookup(char var, const char *user) { + switch (var) { + case 'u': + return user; + case '%': + return "%"; + default: + // Capture all unknown variables (incl. null byte). + return NULL; + } +} + +char *expand_variables(const char *str, const char *user) { + uint8_t *tail, *head; + size_t size = PATH_MAX; + int ok = -1; + + if (str == NULL || (tail = head = malloc(size)) == NULL) { + return NULL; + } + + for (; *str != '\0'; str++) { + if (*str == '%') { + str++; + const char *value = lookup(*str, user); + if (value == NULL || *value == '\0' || + buf_write(&head, &size, value, strlen(value)) != 0) { + goto fail; + } + } else if (buf_write_byte(&head, &size, *str) != 0) { + goto fail; + } + } + + ok = buf_write_byte(&head, &size, '\0'); + +fail: + if (ok != 0) { + free(tail); + return NULL; + } + return (char *) tail; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/man/pam_u2f.8 new/pam_u2f-1.3.0/man/pam_u2f.8 --- old/pam_u2f-1.2.1/man/pam_u2f.8 2022-05-05 10:21:56.000000000 +0200 +++ new/pam_u2f-1.3.0/man/pam_u2f.8 2023-03-14 09:58:28.000000000 +0100 @@ -2,12 +2,12 @@ .\" Title: pam_u2f .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> -.\" Date: Version 1.2.1 +.\" Date: Version 1.3.0 .\" Manual: PAM U2F Module Manual .\" Source: pam-u2f .\" Language: English .\" -.TH "PAM_U2F" "8" "Version 1\&.2\&.1" "pam\-u2f" "PAM U2F Module Manual" +.TH "PAM_U2F" "8" "Version 1\&.3\&.0" "pam\-u2f" "PAM U2F Module Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -67,6 +67,17 @@ Set the location of the file that holds the mappings of user names to keyHandles and user keys\&. An individual (per user) file may be configured relative to the users\*(Aq home dirs, e\&.g\&. "\&.ssh/u2f_keys"\&. If not specified, the location defaults to $XDG_CONFIG_HOME/Yubico/u2f_keys\&. If $XDG_CONFIG_HOME is not set, $HOME/\&.config/Yubico/u2f_keys is used\&. The authfile format is <username>:<KeyHandle1>,<UserKey1>,<CoseType1>,<Options1>:<KeyHandle2>,<UserKey2>,<CoseType2>,<Options2>:\&... .RE .PP +\fBexpand\fR +.RS 4 +Enables variable expansion within the authfile path: +%u +is expanded to the local user name (PAM_USER) and +%% +is expanded to +%\&. Unknown expansion sequences result in an authentication error\&. See also +openasuser\&. +.RE +.PP \fBauthpending_file\fR=\fIfile\fR .RS 4 Set the location of the file that is used for touch request notifications\&. This file will be opened when pam\-u2f starts waiting for a user to touch the device, and will be closed when it no longer waits for a touch\&. Use inotify to listen on these events, or a more high\-level tool like yubikey\-touch\-detector\&. Default value: /var/run/user/$UID/pam\-u2f\-authpending\&. Set an empty value in order to disable this functionality, like so: "authpending_file="\&. @@ -79,7 +90,7 @@ .PP \fBopenasuser\fR .RS 4 -Setuid to the authenticating user when opening the authfile\&. Useful when the user\(cqs home is stored on an NFS volume mounted with the root_squash option (which maps root to nobody which will not be able to read the file)\&. Note that after release 1\&.0\&.8 this is done by default when no global authfile or XDG_CONFIG_HOME environment variable has been set\&. +Setuid to the authenticating user when opening the authfile\&. Useful when the user\(cqs home is stored on an NFS volume mounted with the root_squash option (which maps root to nobody which will not be able to read the file)\&. Note that after release 1\&.0\&.8 this is done by default when no global authfile (path is absolute) or XDG_CONFIG_HOME environment variable has been set\&. .RE .PP \fBalwaysok\fR @@ -89,7 +100,7 @@ .PP \fBmax_devices\fR=\fIn_devices\fR .RS 4 -Maximum number of devices allowed per user (default is 24)\&. Devices specified in the authentication file that exceed this value will be ignored\&. +Maximum number of devices (credentials) allowed per user (default is 24)\&. Devices specified in the authorization mapping file that exceed this value will be ignored\&. .RE .PP \fBinteractive\fR @@ -145,12 +156,45 @@ .RE .SH "EXAMPLES" .sp -auth sufficient pam_u2f\&.so debug origin=pam://$HOSTNAME appid=pam://$HOSTNAME +Second factor authentication deferring user verification configuration to the authorization mapping file\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth required pam_u2f\&.so authfile=/etc/u2f_mappings cue +.fi +.if n \{\ +.RE +.\} +.sp +Passwordless authentication enforcing PIN verification\&. .sp -auth required pam_u2f\&.so origin=http://example\&.com appid=http://example\&.com authfile=/etc/yubikey_mappings +.if n \{\ +.RS 4 +.\} +.nf +auth sufficient pam_u2f\&.so authfile=/etc/u2f_mappings cue pinverification=1 userverification=0 +.fi +.if n \{\ +.RE +.\} +.sp +Passwordless authentication using built\-in UV (e\&.g\&. biometrics) with a fallback to PIN\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth sufficient pam_u2f\&.so authfile=/etc/u2f_mappings cue pinverification=0 userverification=1 +auth sufficient pam_u2f\&.so authfile=/etc/u2f_mappings cue pinverification=1 userverification=0 +.fi +.if n \{\ +.RE +.\} .SH "CAVEATS" .sp -By default the mapping file inside a home directory will be opened as the target user, whereas the central file will be opened as "root"\&. If the "XDG_CONFIG_HOME" variable is set, privileges will not be dropped unless the "openasuser" configuration setting is set\&. +By default, relative paths to the authfile will be opened as the target user, whereas absolute paths will be opened as "root"\&. If the "XDG_CONFIG_HOME" variable is set, privileges will not be dropped unless the "openasuser" configuration setting is set\&. .sp Using pam\-u2f to secure the login to a computer while storing the mapping file in an encrypted home directory, will result in the impossibility of logging into the system\&. The partition is decrypted after login and the mapping file can not be accessed\&. .SH "NOTES" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/man/pam_u2f.8.txt new/pam_u2f-1.3.0/man/pam_u2f.8.txt --- old/pam_u2f-1.2.1/man/pam_u2f.8.txt 2022-04-29 09:07:32.000000000 +0200 +++ new/pam_u2f-1.3.0/man/pam_u2f.8.txt 2023-03-09 08:46:20.000000000 +0100 @@ -48,6 +48,11 @@ $HOME/.config/Yubico/u2f_keys is used. The authfile format is <username>:<KeyHandle1>,<UserKey1>,<CoseType1>,<Options1>:<KeyHandle2>,<UserKey2>,<CoseType2>,<Options2>:... +*expand*:: +Enables variable expansion within the authfile path: `%u` is expanded to the +local user name (`PAM_USER`) and `%%` is expanded to `%`. Unknown expansion +sequences result in an authentication error. See also `openasuser`. + *authpending_file*=_file_:: Set the location of the file that is used for touch request notifications. This file will be opened when pam-u2f starts waiting @@ -67,17 +72,17 @@ when the user's home is stored on an NFS volume mounted with the root_squash option (which maps root to nobody which will not be able to read the file). Note that after release 1.0.8 this is done by -default when no global authfile or XDG_CONFIG_HOME environment -variable has been set. +default when no global authfile (path is absolute) or XDG_CONFIG_HOME +environment variable has been set. *alwaysok*:: Set to enable all authentication attempts to succeed (aka presentation mode). *max_devices*=_n_devices_:: -Maximum number of devices allowed per user (default is 24). Devices -specified in the authentication file that exceed this value will be -ignored. +Maximum number of devices (credentials) allowed per user (default is 24). +Devices specified in the authorization mapping file that exceed this value +will be ignored. *interactive*:: Set to prompt a message and wait before testing the presence of a U2F @@ -131,15 +136,26 @@ == EXAMPLES -auth sufficient pam_u2f.so debug origin=pam://$HOSTNAME appid=pam://$HOSTNAME +Second factor authentication deferring user verification configuration to the +authorization mapping file. + + auth required pam_u2f.so authfile=/etc/u2f_mappings cue + +Passwordless authentication enforcing PIN verification. + + auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=1 userverification=0 + +Passwordless authentication using built-in UV (e.g. biometrics) with a fallback +to PIN. -auth required pam_u2f.so origin=http://example.com appid=http://example.com authfile=/etc/yubikey_mappings + auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=0 userverification=1 + auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue pinverification=1 userverification=0 == CAVEATS -By default the mapping file inside a home directory will be opened as -the target user, whereas the central file will be opened as "root". If -the "XDG_CONFIG_HOME" variable is set, privileges will not be dropped -unless the "openasuser" configuration setting is set. +By default, relative paths to the authfile will be opened as the +target user, whereas absolute paths will be opened as "root". If the +"XDG_CONFIG_HOME" variable is set, privileges will not be dropped unless +the "openasuser" configuration setting is set. Using pam-u2f to secure the login to a computer while storing the mapping file in an encrypted home directory, will result in the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/man/pamu2fcfg.1 new/pam_u2f-1.3.0/man/pamu2fcfg.1 --- old/pam_u2f-1.2.1/man/pamu2fcfg.1 2022-05-11 09:16:56.000000000 +0200 +++ new/pam_u2f-1.3.0/man/pamu2fcfg.1 2023-03-14 09:58:28.000000000 +0100 @@ -2,12 +2,12 @@ .\" Title: pamu2fcfg .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> -.\" Date: Version 1.2.1 +.\" Date: Version 1.3.0 .\" Manual: PAM U2F Configuration Tool .\" Source: pamu2fcfg .\" Language: English .\" -.TH "PAMU2FCFG" "1" "Version 1\&.2\&.1" "pamu2fcfg" "PAM U2F Configuration Tool" +.TH "PAMU2FCFG" "1" "Version 1\&.3\&.0" "pamu2fcfg" "PAM U2F Configuration Tool" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -99,7 +99,7 @@ Report pamu2fcfg bugs in the issue tracker: https://github\&.com/Yubico/pam\-u2f/issues .SH "SEE ALSO" .sp -\fBpam_u2f\fR(8), \fBpam\fR(7) +\fBpam_u2f\fR(8), \fBpam\fR(7), \fBfido2\-token\fR(1) .sp The pam\-u2f home page: https://developers\&.yubico\&.com/pam\-u2f/ .sp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/man/pamu2fcfg.1.txt new/pam_u2f-1.3.0/man/pamu2fcfg.1.txt --- old/pam_u2f-1.2.1/man/pamu2fcfg.1.txt 2022-05-05 10:45:30.000000000 +0200 +++ new/pam_u2f-1.3.0/man/pamu2fcfg.1.txt 2023-03-09 08:46:20.000000000 +0100 @@ -59,7 +59,7 @@ Report pamu2fcfg bugs in the issue tracker: https://github.com/Yubico/pam-u2f/issues == SEE ALSO -*pam_u2f*(8), *pam*(7) +*pam_u2f*(8), *pam*(7), *fido2-token*(1) The pam-u2f home page: https://developers.yubico.com/pam-u2f/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/pam-u2f.c new/pam_u2f-1.3.0/pam-u2f.c --- old/pam_u2f-1.2.1/pam-u2f.c 2022-05-11 08:11:50.000000000 +0200 +++ new/pam_u2f-1.3.0/pam-u2f.c 2023-03-09 08:46:20.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2021 Yubico AB - See COPYING + * Copyright (C) 2014-2023 Yubico AB - See COPYING */ /* Define which PAM interfaces we provide */ @@ -24,6 +24,8 @@ #include "drop_privs.h" #include "util.h" +#define free_const(a) free((void *) (uintptr_t) (a)) + /* If secure_getenv is not defined, define it here */ #ifndef HAVE_SECURE_GETENV char *secure_getenv(const char *); @@ -61,6 +63,8 @@ cfg->cue = 1; } else if (strcmp(argv[i], "nodetect") == 0) { cfg->nodetect = 1; + } else if (strcmp(argv[i], "expand") == 0) { + cfg->expand = 1; } else if (strncmp(argv[i], "userpresence=", 13) == 0) { sscanf(argv[i], "userpresence=%d", &cfg->userpresence); } else if (strncmp(argv[i], "userverification=", 17) == 0) { @@ -106,6 +110,7 @@ debug_dbg(cfg, "openasuser=%d", cfg->openasuser); debug_dbg(cfg, "alwaysok=%d", cfg->alwaysok); debug_dbg(cfg, "sshformat=%d", cfg->sshformat); + debug_dbg(cfg, "expand=%d", cfg->expand); debug_dbg(cfg, "authfile=%s", cfg->auth_file ? cfg->auth_file : "(null)"); debug_dbg(cfg, "authpending_file=%s", cfg->authpending_file ? cfg->authpending_file : "(null)"); @@ -256,13 +261,27 @@ debug_dbg(cfg, "Found user %s", user); debug_dbg(cfg, "Home directory for %s is %s", user, pw->pw_dir); + // Perform variable expansion. + if (cfg->expand && cfg->auth_file) { + if ((cfg->auth_file = expand_variables(cfg->auth_file, user)) == NULL) { + debug_dbg(cfg, "Failed to perform variable expansion"); + retval = PAM_AUTHINFO_UNAVAIL; + goto done; + } + should_free_auth_file = 1; + } + // Resolve default or relative paths. if (!cfg->auth_file || cfg->auth_file[0] != '/') { - if ((cfg->auth_file = resolve_authfile_path(cfg, pw, &openasuser)) == - NULL) { + char *tmp = resolve_authfile_path(cfg, pw, &openasuser); + if (tmp == NULL) { debug_dbg(cfg, "Could not resolve authfile path"); retval = PAM_IGNORE; goto done; } + if (should_free_auth_file) { + free_const(cfg->auth_file); + } + cfg->auth_file = tmp; should_free_auth_file = 1; } @@ -380,7 +399,6 @@ done: free_devices(devices, n_devices); -#define free_const(a) free((void *) (uintptr_t)(a)) if (should_free_origin) { free_const(cfg->origin); cfg->origin = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/pamu2fcfg/pamu2fcfg.c new/pam_u2f-1.3.0/pamu2fcfg/pamu2fcfg.c --- old/pam_u2f-1.2.1/pamu2fcfg/pamu2fcfg.c 2022-04-22 14:15:06.000000000 +0200 +++ new/pam_u2f-1.3.0/pamu2fcfg/pamu2fcfg.c 2023-03-09 08:46:20.000000000 +0100 @@ -7,6 +7,13 @@ #define TIMEOUT 15 #define FREQUENCY 1 +#define PIN_SET 0x01 +#define PIN_UNSET 0x02 +#define UV_SET 0x04 +#define UV_UNSET 0x08 +#define UV_REQD 0x10 +#define UV_NOT_REQD 0x20 + #include <fido.h> #include <stdio.h> @@ -23,6 +30,10 @@ #include "openbsd-compat.h" +#ifndef FIDO_ERR_UV_BLOCKED /* XXX: compat libfido2 <1.5.0 */ +#define FIDO_ERR_UV_BLOCKED 0x3c +#endif + struct args { const char *appid; const char *origin; @@ -159,7 +170,8 @@ return cred; } -static int make_cred(const char *path, fido_dev_t *dev, fido_cred_t *cred) { +static int make_cred(const struct args *args, const char *path, fido_dev_t *dev, + fido_cred_t *cred, int devopts) { char prompt[BUFSIZE]; char pin[BUFSIZE]; int n; @@ -170,8 +182,25 @@ return -1; } - r = fido_dev_make_cred(dev, cred, NULL); - if (r == FIDO_ERR_PIN_REQUIRED) { + /* Some form of UV required; built-in UV is available. */ + if (args->user_verification || (devopts & (UV_SET | UV_NOT_REQD)) == UV_SET) { + if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) { + fprintf(stderr, "error: fido_cred_set_uv: %s (%d)\n", fido_strerr(r), r); + return -1; + } + } + + /* Let built-in UV have precedence over PIN. No UV also handled here. */ + if (args->user_verification || !args->pin_verification) { + r = fido_dev_make_cred(dev, cred, NULL); + } else { + r = FIDO_ERR_PIN_REQUIRED; + } + + /* Some form of UV required; built-in UV failed or is not available. */ + if ((devopts & PIN_SET) && + (r == FIDO_ERR_PIN_REQUIRED || r == FIDO_ERR_UV_BLOCKED || + r == FIDO_ERR_PIN_BLOCKED)) { n = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ", path); if (n < 0 || (size_t) n >= sizeof(prompt)) { fprintf(stderr, "error: snprintf prompt"); @@ -282,6 +311,44 @@ return ok; } +static int get_device_options(fido_dev_t *dev, int *devopts) { + char *const *opts; + const bool *vals; + fido_cbor_info_t *info; + int r; + + *devopts = 0; + + if (!fido_dev_is_fido2(dev)) + return 0; + + if ((info = fido_cbor_info_new()) == NULL) { + fprintf(stderr, "fido_cbor_info_new failed\n"); + return -1; + } + if ((r = fido_dev_get_cbor_info(dev, info)) != FIDO_OK) { + fprintf(stderr, "fido_dev_get_cbor_info: %s (%d)\n", fido_strerr(r), r); + fido_cbor_info_free(&info); + return -1; + } + + opts = fido_cbor_info_options_name_ptr(info); + vals = fido_cbor_info_options_value_ptr(info); + for (size_t i = 0; i < fido_cbor_info_options_len(info); i++) { + if (strcmp(opts[i], "clientPin") == 0) { + *devopts |= vals[i] ? PIN_SET : PIN_UNSET; + } else if (strcmp(opts[i], "uv") == 0) { + *devopts |= vals[i] ? UV_SET : UV_UNSET; + } else if (strcmp(opts[i], "makeCredUvNotRqd") == 0) { + *devopts |= vals[i] ? UV_NOT_REQD : UV_REQD; + } + } + + fido_cbor_info_free(&info); + + return 0; +} + static void parse_args(int argc, char *argv[], struct args *args) { int c; enum { @@ -394,14 +461,12 @@ const fido_dev_info_t *di = NULL; const char *path = NULL; size_t ndevs = 0; + int devopts = 0; int r; parse_args(argc, argv, &args); fido_init(args.debug ? FIDO_DEBUG : 0); - if ((cred = prepare_cred(&args)) == NULL) - goto err; - devlist = fido_dev_info_new(64); if (!devlist) { fprintf(stderr, "error: fido_dev_info_new failed\n"); @@ -468,8 +533,30 @@ goto err; } - if (make_cred(path, dev, cred) != 0 || verify_cred(cred) != 0 || - print_authfile_line(&args, cred) != 0) + if (get_device_options(dev, &devopts) != 0) { + goto err; + } + if (args.pin_verification && !(devopts & PIN_SET)) { + warnx("%s", devopts & PIN_UNSET ? "device has no PIN" + : "device does not support PIN"); + goto err; + } + if (args.user_verification && !(devopts & UV_SET)) { + warnx("%s", devopts & UV_UNSET + ? "device has no built-in user verification configured" + : "device does not support built-in user verification"); + goto err; + } + if ((devopts & (UV_REQD | PIN_SET | UV_SET)) == UV_REQD) { + warnx("%s", "some form of user verification required but none configured"); + goto err; + } + + if ((cred = prepare_cred(&args)) == NULL) + goto err; + + if (make_cred(&args, path, dev, cred, devopts) != 0 || + verify_cred(cred) != 0 || print_authfile_line(&args, cred) != 0) goto err; exit_code = EXIT_SUCCESS; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/tests/Makefile.am new/pam_u2f-1.3.0/tests/Makefile.am --- old/pam_u2f-1.2.1/tests/Makefile.am 2022-04-22 14:15:06.000000000 +0200 +++ new/pam_u2f-1.3.0/tests/Makefile.am 2023-03-09 08:46:20.000000000 +0100 @@ -13,4 +13,7 @@ check_PROGRAMS += get_devices get_devices_LDADD = $(top_builddir)/libmodule.la +check_PROGRAMS += expand +expand_LDADD = $(top_builddir)/libmodule.la + TESTS = $(check_PROGRAMS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/tests/Makefile.in new/pam_u2f-1.3.0/tests/Makefile.in --- old/pam_u2f-1.2.1/tests/Makefile.in 2022-05-05 10:21:49.000000000 +0200 +++ new/pam_u2f-1.3.0/tests/Makefile.in 2023-03-14 09:58:14.000000000 +0100 @@ -89,7 +89,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -check_PROGRAMS = dlsym_check$(EXEEXT) get_devices$(EXEEXT) +check_PROGRAMS = dlsym_check$(EXEEXT) get_devices$(EXEEXT) \ + expand$(EXEEXT) subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ @@ -112,6 +113,9 @@ dlsym_check_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(dlsym_check_LDFLAGS) $(LDFLAGS) -o $@ +expand_SOURCES = expand.c +expand_OBJECTS = expand.$(OBJEXT) +expand_DEPENDENCIES = $(top_builddir)/libmodule.la get_devices_SOURCES = get_devices.c get_devices_OBJECTS = get_devices.$(OBJEXT) get_devices_DEPENDENCIES = $(top_builddir)/libmodule.la @@ -130,7 +134,7 @@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/dlsym_check.Po \ +am__depfiles_remade = ./$(DEPDIR)/dlsym_check.Po ./$(DEPDIR)/expand.Po \ ./$(DEPDIR)/get_devices.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -151,8 +155,8 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = dlsym_check.c get_devices.c -DIST_SOURCES = dlsym_check.c get_devices.c +SOURCES = dlsym_check.c expand.c get_devices.c +DIST_SOURCES = dlsym_check.c expand.c get_devices.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -520,6 +524,7 @@ AM_LDFLAGS = -no-install dlsym_check_LDFLAGS = -ldl $(AM_LDFLAGS) get_devices_LDADD = $(top_builddir)/libmodule.la +expand_LDADD = $(top_builddir)/libmodule.la TESTS = $(check_PROGRAMS) all: all-am @@ -568,6 +573,10 @@ @rm -f dlsym_check$(EXEEXT) $(AM_V_CCLD)$(dlsym_check_LINK) $(dlsym_check_OBJECTS) $(dlsym_check_LDADD) $(LIBS) +expand$(EXEEXT): $(expand_OBJECTS) $(expand_DEPENDENCIES) $(EXTRA_expand_DEPENDENCIES) + @rm -f expand$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(expand_OBJECTS) $(expand_LDADD) $(LIBS) + get_devices$(EXEEXT): $(get_devices_OBJECTS) $(get_devices_DEPENDENCIES) $(EXTRA_get_devices_DEPENDENCIES) @rm -f get_devices$(EXEEXT) $(AM_V_CCLD)$(LINK) $(get_devices_OBJECTS) $(get_devices_LDADD) $(LIBS) @@ -579,6 +588,7 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlsym_check.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_devices.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -824,6 +834,13 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +expand.log: expand$(EXEEXT) + @p='expand$(EXEEXT)'; \ + b='expand'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ @@ -918,6 +935,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/dlsym_check.Po + -rm -f ./$(DEPDIR)/expand.Po -rm -f ./$(DEPDIR)/get_devices.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -965,6 +983,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dlsym_check.Po + -rm -f ./$(DEPDIR)/expand.Po -rm -f ./$(DEPDIR)/get_devices.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/tests/expand.c new/pam_u2f-1.3.0/tests/expand.c --- old/pam_u2f-1.2.1/tests/expand.c 1970-01-01 01:00:00.000000000 +0100 +++ new/pam_u2f-1.3.0/tests/expand.c 2023-03-09 08:46:20.000000000 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Yubico AB - See COPYING + */ + +#undef NDEBUG +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include "util.h" + +#define ASSERT_STR_EQ(a, b) assert(!strcmp(a, b)) +#define ASSERT_EXPANDED_EQ(str, user, result) \ + do { \ + char *tmp = expand_variables(str, user); \ + assert(tmp != NULL); \ + ASSERT_STR_EQ(tmp, result); \ + free(tmp); \ + } while (0) + +#define ASSERT_NULL(x) assert((x) == NULL) + +int main(void) { + ASSERT_EXPANDED_EQ("foobar", "user", "foobar"); + ASSERT_EXPANDED_EQ("", "user", ""); + ASSERT_EXPANDED_EQ("%%", "user", "%"); + ASSERT_EXPANDED_EQ("%u", "user", "user"); + ASSERT_EXPANDED_EQ("x%u", "user", "xuser"); + ASSERT_EXPANDED_EQ("%ux", "user", "userx"); + ASSERT_EXPANDED_EQ("x%ux", "user", "xuserx"); + ASSERT_EXPANDED_EQ("%%%u", "user", "%user"); + ASSERT_EXPANDED_EQ("%u%%", "user", "user%"); + ASSERT_EXPANDED_EQ("%%u", "user", "%u"); + ASSERT_EXPANDED_EQ("%u", "%user", "%user"); + ASSERT_EXPANDED_EQ("%u%u", "user", "useruser"); + ASSERT_EXPANDED_EQ("%%%u%%", "user", "%user%"); + + ASSERT_NULL(expand_variables("%", "user")); // Unexpected end of string. + ASSERT_NULL(expand_variables("%x", "user")); // Unknown variable. + ASSERT_NULL(expand_variables("%u", "")); // Disallow empty username. + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/tests/get_devices.c new/pam_u2f-1.3.0/tests/get_devices.c --- old/pam_u2f-1.2.1/tests/get_devices.c 2022-04-29 09:07:32.000000000 +0200 +++ new/pam_u2f-1.3.0/tests/get_devices.c 2023-03-09 08:46:20.000000000 +0100 @@ -3,9 +3,12 @@ */ #undef NDEBUG +#include <sys/types.h> +#include <assert.h> +#include <pwd.h> #include <stdio.h> #include <stdlib.h> -#include <assert.h> +#include <unistd.h> #include <string.h> #include "../util.h" @@ -718,15 +721,16 @@ } int main(void) { - const char *username; + struct passwd *pwd; + char *username; - if ((username = getenv("USER")) == NULL) { - username = getenv("LOGNAME"); - } - assert(username != NULL); + assert((pwd = getpwuid(geteuid())) != NULL); + assert((username = strdup(pwd->pw_name)) != NULL); test_ssh_credential(username); test_old_credential(username); test_limited_count(username); test_new_credentials(username); + + free(username); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pam_u2f-1.2.1/util.h new/pam_u2f-1.3.0/util.h --- old/pam_u2f-1.2.1/util.h 2022-05-11 08:11:49.000000000 +0200 +++ new/pam_u2f-1.3.0/util.h 2023-03-09 08:46:20.000000000 +0100 @@ -35,6 +35,7 @@ int userverification; int pinverification; int sshformat; + int expand; const char *auth_file; const char *authpending_file; const char *origin; @@ -64,6 +65,7 @@ int random_bytes(void *, size_t); int cose_type(const char *, int *); const char *cose_string(int); +char *expand_variables(const char *, const char *); #if !defined(HAVE_EXPLICIT_BZERO) void explicit_bzero(void *, size_t);
