Skip to content

Conversation

@Venefilyn
Copy link
Member

@Venefilyn Venefilyn commented Dec 16, 2025

To test, you need to use localhost as the domain due to limitations in
the browser with domains and WebAuthn. localhost and any .local TLD
will work.

E.g.

TEST_BIND_GLOBAL=localhost bots/vm-run -s cockpit.socket fedora-43

Modifying the system to support pam-u2f:

sudo dnf install pam-u2f -y

Add this to the top of /etc/pam.d/cockpit:

auth       sufficient   pam_u2f.so authfile=/etc/u2f_mappings origin=localhost appid=cockpit manual

Several items outstanding:

  • ID or user agent doesn't work between WebAuthn API and pam-u2f
    config file.
  • Unclear issue during authentication with sending passkey credentials
    from browser to pam-u2f.
  • Currently several converse requests are sent from browser to backend
    due to pam-u2f in manual mode expecting data on newlines, sending
    \n does not work.

Notes:

  • Registration with discoverable keys should be possible
  • To make pam-u2f see a key as discoverable the ID can be replaced with
    *
  • Check journalctl -f to see how cockpit-session and pam-u2f
    interacts.
  • Chromium has a virtual passkey system to help test with passkeys.
  • Currently Bitwarden doesn't work with registration due to WebAuthn
    call originating from an iframe, need to be moved to the shell.
  • ./build.js is temporarily modified to be able to build and test the
    login page.
  • Multiple registered keys don't work at the moment, will be fixed when
    one registered key works.

See-also: https://developers.yubico.com/libfido2/Manuals/fido2-assert.html
Signed-off-by: Freya Gustavsson [email protected]

Output

To test, you need to use `localhost` as the domain due to limitations in
the browser with domains and WebAuthn. `localhost` and any `.local` TLD
will work.

E.g.
```
TEST_BIND_GLOBAL=localhost bots/vm-run -s cockpit.socket fedora-43
```

Modifying the system to support pam-u2f:
```
sudo dnf install pam-u2f -y
```
Add this to the top of `/etc/pam.d/cockpit`:
```
auth       sufficient   pam_u2f.so authfile=/etc/u2f_mappings origin=localhost appid=cockpit manual
```

Several items outstanding:
- ID or user agent doesn't work between WebAuthn API and `pam-u2f`
  config file.
- Unclear issue during authentication with sending passkey credentials
  from browser to `pam-u2f`.
- Currently several `converse` requests are sent from browser to backend
  due to `pam-u2f` in manual mode expecting data on newlines, sending
  `\n` does not work.

Notes:
- Registration with discoverable keys should be possible
- To make pam-u2f see a key ass discoverable the ID can be replaced with
  `*`
- Check `journalctl -f` to see how `cockpit-session` and `pam-u2f`
  interacts.
- Chromium has a virtual passkey system to help test with passkeys.
- Currently Bitwarden doesn't work with registration due to WebAuthn
  call originating from an iframe, need to be moved to the shell.
- `./build.js` is temporarily modified to be able to build and test the
  login page.

See-also: https://developers.yubico.com/libfido2/Manuals/fido2-assert.html
Signed-off-by: Freya Gustavsson <[email protected]>
@Venefilyn Venefilyn added the no-test For doc/workflow changes, or experiments which don't need a full CI run, label Dec 16, 2025
if (!window.isSecureContext) {
login_failure(_("This web page was not loaded in a secure context (https). Please try loading the page again using https or make sure you are using a browser with secure context support"))
}
if (!isPasskeySupported) {

Check warning

Code scanning / CodeQL

Useless conditional Warning

This negation always evaluates to false.
@@ -0,0 +1,120 @@
import cockpit from "cockpit";
import React, { useState } from 'react';

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused import useState.
@Venefilyn
Copy link
Member Author

Output from syslog with Chromium passkey pubkey visible. /etc/u2f_mappings had the following entry:

admin:,*,MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqZaSWI0KEZpJj1Z12A1UUQvuu9nVmcmDj8V0d70En8lAtUqRpiKC+zfoIJO3lfCicae5a3Z2xkLYrs/GbTpykg==,es256,
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:272 (cfg_init): called.
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:273 (cfg_init): flags 0 argc 5
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:275 (cfg_init): argv[0]=authfile=/etc/u2f_mappings
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:275 (cfg_init): argv[1]=origin=localhost
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:275 (cfg_init): argv[2]=appid=cockpit
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:275 (cfg_init): argv[3]=manual
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:275 (cfg_init): argv[4]=debug
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:277 (cfg_init): max_devices=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:278 (cfg_init): debug=1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:279 (cfg_init): interactive=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:280 (cfg_init): cue=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:281 (cfg_init): nodetect=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:282 (cfg_init): userpresence=-1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:283 (cfg_init): userverification=-1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:284 (cfg_init): pinverification=-1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:285 (cfg_init): manual=1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:286 (cfg_init): nouserok=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:287 (cfg_init): openasuser=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:288 (cfg_init): alwaysok=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:289 (cfg_init): sshformat=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:290 (cfg_init): expand=0
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:291 (cfg_init): authfile=/etc/u2f_mappings
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:292 (cfg_init): authpending_file=(null)
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:294 (cfg_init): origin=localhost
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:295 (cfg_init): appid=cockpit
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): cfg.c:296 (cfg_init): prompt=(null)
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:147 (pam_sm_authenticate): Maximum number of devices not set. Using default (24)
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:170 (pam_sm_authenticate): Requesting authentication for user admin
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:181 (pam_sm_authenticate): Found user admin
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:182 (pam_sm_authenticate): Home directory for admin is /home/admin
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:208 (pam_sm_authenticate): Using authentication file /etc/u2f_mappings
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:228 (parse_native_format): Read 140 bytes
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:232 (parse_native_format): Matched user: admin
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:193 (parse_native_credential): Empty attributes
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:255 (parse_native_format): KeyHandle for device number 1: *
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:257 (parse_native_format): publicKey for device number 1: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqZaSWI0KEZpJj1Z12A1UUQvuu9nVmcmDj8V0d70En8lAtUqRpiKC+zfoIJO3lfCicae5a3Z2xkLYrs/GbTpykg==
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:259 (parse_native_format): COSE type for device number 1: es256
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:261 (parse_native_format): Attributes for device number 1:
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:228 (parse_native_format): Read 1 bytes
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:228 (parse_native_format): Read 1 bytes
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:777 (get_devices_from_authfile): Found 1 device(s) for user admin
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:261 (pam_sm_authenticate): Touch request notifications will be emitted via '/var/run/user/0/pam-u2f-authpending'
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1014 (prepare_assert): Credential is resident
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1430 (do_manual_authentication): Attempting authentication with device number 1
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: es256_pk_to_EVP_PKEY: EC_KEY_set_public_key
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: es256_pk_from_ptr: es256_pk_to_EVP_PKEY
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1128 (parse_pk): Failed to convert ES256 public key
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1445 (do_manual_authentication): Challenge: XALzHBMLR6GSHLoE0hiJiaz7WEWBrYdsTc8XWA5h+ws=
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: cockpit-session: pam: Challenge #1:
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: cockpit-session: pam: XALzHBMLR6GSHLoE0hiJiaz7WEWBrYdsTc8XWA5h+ws=
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: localhost
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: *
Dec 15 15:36:39 fedora-43-127-0-0-2-2201 cockpit-session[9993]: cockpit-session: pam: Please pass the challenge(s) above to fido2-assert, and paste the results in the prompt below.
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: cbor_decode_assert_authdata: buf=0x55eec230a2e0, len=9
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: cbor_decode_assert_authdata: fido_buf_read
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: fido_assert_set_authdata: cbor_decode_assert_authdata
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1376 (manual_get_assert): Failed to set authdata of assertion
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): util.c:1480 (do_manual_authentication): Failed to get assert 0
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: debug(pam_u2f): pam-u2f.c:319 (pam_sm_authenticate): done. [Authentication failure]
Dec 15 15:36:43 fedora-43-127-0-0-2-2201 cockpit-session[9993]: pam_unix(cockpit:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=::ffff:172.27.0.2  user=admin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-test For doc/workflow changes, or experiments which don't need a full CI run,

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant