# security/pam_u2f



## dnb (Jul 2, 2022)

pam_u2f - is an important library because it supports many inexpensive u2f keys available from different manufacturers. You can log in as a user or log in via ssh, for example.

Luckily it works fine on FreeBSD 13.0 (pam_u2f-1.2.0, u2f-devd-1.1.10_6, libfido2-1.8.0).

Here is the Makefile. Sorry, I didn't master the formatting properly.


```
PORTNAME=    pam_u2f
PORTVERSION=    1.1.0
CATEGORIES=    security
MASTER_SITES=    https://developers.yubico.com/pam-u2f/Releases/

MAINTAINER=
COMMENT=    Pluggable Authentication Module (PAM) Universal 2nd Factor (U2F)

LICENSE=    BSD2CLAUSE
LICENSE_FILE=    ${WRKSRC}/COPYING

LIB_DEPENDS=    libfido2.so:security/libfido2

USES=        libtool ssl

PLIST_FILES=    /usr/lib/pam_u2f.so \
        bin/pamu2fcfg \
        man/man1/pamu2fcfg.1.gz \
        man/man8/pam_u2f.8.gz

GNU_CONFIGURE=    yes

CONFIGURE_ENV=    LIBCRYPTO_CFLAGS="-I${OPENSSLINC}" LIBCRYPTO_LIBS="-L${OPENSSLLIB} -lcrypto" \
        EXTRA_CFLAGS="-I${LOCALBASE}/include"

INSTALL_TARGET=install-strip

.include <bsd.port.mk>
```

Unfortunately, after updating to release 13.1, the following problem arose: the u2f key may not work (tested with several keys, all these keys work in win and linux). In case of failure, the key does not blink. Such a failure can occur 1 in 3-4 times. Sometimes there are 5-6 successful attempts in a row.

It must be said that *the failure is always one-time*, that is, if you try to log in again (for example, su -l), then after one erroneous time, *the next time everything will definitely (100%) work*. And you don't even need to pull out the usb and insert it again. There haven't been two erroneous times in a row. The key is used for login (su -l), for xdm login and for ssh. The key always works immediately after it has been inserted. But the next time may be wrong.

Here is the error log for pam_u2f:

```
debug(pam_u2f): pam-u2f.c:91 (parse_cfg): called.
debug(pam_u2f): pam-u2f.c:92 (parse_cfg): flags 0 argc 4
debug(pam_u2f): pam-u2f.c:94 (parse_cfg): argv[0]=authfile=/etc/u2f_mappings
debug(pam_u2f): pam-u2f.c:94 (parse_cfg): argv[1]=debug
debug(pam_u2f): pam-u2f.c:94 (parse_cfg): argv[2]=debug_file=/var/log/u2f
debug(pam_u2f): pam-u2f.c:94 (parse_cfg): argv[3]=authpending_file=/tmp/u2f
debug(pam_u2f): pam-u2f.c:96 (parse_cfg): max_devices=0
debug(pam_u2f): pam-u2f.c:97 (parse_cfg): debug=1
debug(pam_u2f): pam-u2f.c:98 (parse_cfg): interactive=0
debug(pam_u2f): pam-u2f.c:99 (parse_cfg): cue=0
debug(pam_u2f): pam-u2f.c:100 (parse_cfg): nodetect=0
debug(pam_u2f): pam-u2f.c:101 (parse_cfg): userpresence=-1
debug(pam_u2f): pam-u2f.c:102 (parse_cfg): userverification=-1
debug(pam_u2f): pam-u2f.c:103 (parse_cfg): pinverification=-1
debug(pam_u2f): pam-u2f.c:104 (parse_cfg): manual=0
debug(pam_u2f): pam-u2f.c:105 (parse_cfg): nouserok=0
debug(pam_u2f): pam-u2f.c:106 (parse_cfg): openasuser=0
debug(pam_u2f): pam-u2f.c:107 (parse_cfg): alwaysok=0
debug(pam_u2f): pam-u2f.c:108 (parse_cfg): sshformat=0
debug(pam_u2f): pam-u2f.c:109 (parse_cfg): authfile=/etc/u2f_mappings
debug(pam_u2f): pam-u2f.c:111 (parse_cfg): authpending_file=/tmp/u2f
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): origin=(null)
debug(pam_u2f): pam-u2f.c:113 (parse_cfg): appid=(null)
debug(pam_u2f): pam-u2f.c:114 (parse_cfg): prompt=(null)
debug(pam_u2f): pam-u2f.c:199 (pam_sm_authenticate): Origin not specified, using "pam://system"
debug(pam_u2f): pam-u2f.c:211 (pam_sm_authenticate): Appid not specified, using the same value of origin (pam://system)
debug(pam_u2f): pam-u2f.c:223 (pam_sm_authenticate): Maximum devices number not set. Using default (24)
debug(pam_u2f): pam-u2f.c:245 (pam_sm_authenticate): Requesting authentication for user root
debug(pam_u2f): pam-u2f.c:256 (pam_sm_authenticate): Found user root
debug(pam_u2f): pam-u2f.c:257 (pam_sm_authenticate): Home directory for root is /root
debug(pam_u2f): pam-u2f.c:269 (pam_sm_authenticate): Using authentication file /etc/u2f_mappings
debug(pam_u2f): util.c:227 (parse_native_format): Read 199 bytes
debug(pam_u2f): util.c:227 (parse_native_format): Read 199 bytes
debug(pam_u2f): util.c:231 (parse_native_format): Matched user: root
debug(pam_u2f): util.c:255 (parse_native_format): KeyHandle for device number 1: hW3Z/CV3PoaDXvDZqaa6+m7TVoqsVrzFawDCOz+pvl7xSsdbJ2Y56cScRPIZgb/4ShpSRE4bZ6kXl0zEHRJUNw==
debug(pam_u2f): util.c:257 (parse_native_format): publicKey for device number 1: 1+c43SJ67FXmhjC+1E9MaOhZgvbrJLmJip8wKzSwR67piG760BPf9vjOmREAGy11GSdHZlyLhoihxYBAL4PXcA==
debug(pam_u2f): util.c:259 (parse_native_format): COSE type for device number 1: es256
debug(pam_u2f): util.c:261 (parse_native_format): Attributes for device number 1: +presence
debug(pam_u2f): util.c:753 (get_devices_from_authfile): Found 1 device(s) for user root
debug(pam_u2f): pam-u2f.c:342 (pam_sm_authenticate): Touch request notifications will be emitted via '/tmp/u2f'
debug(pam_u2f): util.c:1172 (do_authentication): Device max index is 1
debug(pam_u2f): util.c:1188 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): util.c:991 (prepare_assert): Key handle: hW3Z/CV3PoaDXvDZqaa6+m7TVoqsVrzFawDCOz+pvl7xSsdbJ2Y56cScRPIZgb/4ShpSRE4bZ6kXl0zEHRJUNw==
debug(pam_u2f): util.c:797 (get_authenticators): Working with 1 authenticator(s)
debug(pam_u2f): util.c:800 (get_authenticators): Checking whether key exists in authenticator 0
debug(pam_u2f): util.c:808 (get_authenticators): Authenticator path: /dev/uhid0
debug(pam_u2f): util.c:819 (get_authenticators): Failed to open authenticator: FIDO_ERR_RX (-2)
debug(pam_u2f): util.c:845 (get_authenticators): Key not found
debug(pam_u2f): util.c:1263 (do_authentication): Device for this keyhandle is not present
debug(pam_u2f): pam-u2f.c:373 (pam_sm_authenticate): do_authentication returned -2
debug(pam_u2f): pam-u2f.c:408 (pam_sm_authenticate): done. [Authentication error]
```

"Failed to open authentificator" - is check from here. And "FIDO_ERR_RX" is error code libfido2 functions fido_dev_open_rx, fido_dev_open_tx and fido_dev_open. One way or another, but periodically it is not possible to open the device.

If successful, the last lines should have been:


```
debug(pam_u2f): util.c:1172 (do_authentication): Device max index is 1
debug(pam_u2f): util.c:1188 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): util.c:991 (prepare_assert): Key handle: hW3Z/CV3PoaDXvDZqaa6+m7TVoqsVrzFawDCOz+pvl7xSsdbJ2Y56cScRPIZgb/4ShpSRE4bZ6kXl0zEHRJUNw==
debug(pam_u2f): util.c:797 (get_authenticators): Working with 1 authenticator(s)
debug(pam_u2f): util.c:800 (get_authenticators): Checking whether key exists in authenticator 0
debug(pam_u2f): util.c:808 (get_authenticators): Authenticator path: /dev/uhid0
debug(pam_u2f): util.c:832 (get_authenticators): Found key in authenticator 0
debug(pam_u2f): pam-u2f.c:408 (pam_sm_authenticate): done. [Success]
```

Relevant line in /etc/pam.d/system (experimenting with options does not affect anything):


```
auth            required        pam_u2f.so              authfile=/etc/u2f_mappings debug debug_file=/var/log/u2f  authpending_file=/tmp/u2f
```

Here is my config /usr/local/etc/devd/u2f.conf:

```
notify 100 {
    match "system"        "USB";
    match "subsystem"    "DEVICE";
    match "type"        "ATTACH";
    match "vendor"        "0x0a89";
    match "product"        "0x0090";
    action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev";
};

attach 100 {
    match "vendor"        "0x0a89";
    match "product"        "0x0090";
    action "chgrp u2f /dev/$device-name; chmod g+rw /dev/$device-name";
};
```

*The error occurred immediately after upgrading to release 13.1 without any ports update.*

Then I updated the libraries (pam_u2f-1.2.1, u2f-devd-1.1.10_6, libfido2-1.10.0) but that didn't change anything. I currently have release 13.1 installed and ports 2022q2. So I guess the issue is with something in the new 13.1 release. I would be very grateful if you could point me in the direction of FreeBSD tweaks or pam_u2f fixes.


----------

