Closed rolandog closed 4 years ago
It's not possible to perform authentication operations without a user interaction of some sort. There exist debug commands such as wink and ping, but those are not exposed through the module.
I think the best way is what you are doing, trying to authenticate using the module and reacting to it failing by invoking a different module
BTW, are you running the released version or are you using the git version?
Hi @a-dma , thanks for your response! In that case, I think I may change the cue
and prompt
messages so that the procedure seems more clear to the users.
As for the version, I'm using the released version from Synaptic (currently on Ubuntu 20.04); this would be libpam-u2f (1.0.8-1).
Thank you for your help.
No problem. The git version, which should be cleaned up a bit and released, uses a different set of dependencies and should allow you to expose the behavior you wanted by setting setting userpresence=0
in the module config file.
If you want to try that I'm more than happy to hear feedback.
Ah, that totally makes sense (I'm glad I wasn't misreading the documentation); I'll see if tonight I have some time to build the git version and test the behaviour. Thanks for the tip!
Thank you and sorry for the messy state. I promised a release a long time ago and still haven't gotten around that...
Hey, don't worry about it (everything is understandable, given the current global state of affairs).
I didn't have time yesterday night to build; today I had some time before heading out, but I stumbled on some unmet dependencies.
I'm writing from my phone, and what I'm writing is from my (sometimes shoddy) memory.
Running ./configure
made it apparent that I didn't have libssl-dev
and
libfido2-dev
.
And running make
made it apparent that I didn't have gengetopt
.
I'll continue documenting in the evening, and update package names that I didn't name correctly.
On Wed, Jul 15, 2020, 12:53 Alessio Di Mauro notifications@github.com wrote:
Thank you and sorry for the messy state. I promised a review a long time ago and still haven't gotten around that...
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/Yubico/pam-u2f/issues/149#issuecomment-658699150, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC6TSHT6HOREDLCNTTUZRFLR3WDDBANCNFSM4OX757LA .
That looks correct, the current version uses libfido2
instead of libu2f-server
and libu2f-host
. OpenSSL is used for the base64 encoding and some of the crypto stuff. It goes without saying that the documentation should be updated to reflect the current state.
Hello. I'm back. I finished the building process; I received some warnings while building (see below section).
Afterwards, I changed the /etc/pam.d/sudo
file to contain:
auth [success=1 new_authtok_reqd=ok ignore=ignore default=ignore] pam_u2f.so interactive userpresence=0 nouserok authfile=/etc/Yubico/u2f_keys debug
auth [success=1 new_authtok_reqd=ok ignore=ignore default=bad] pam_google_authenticator.so nullok
auth required pam_u2f.so cue nouserok authfile=/etc/Yubico/u2f_keys
I re-ran pamu2fcfg
(because this new version apparently has additional fields), and I removed cue
on the first line, because I thought it would be mutually exclusive to userpresence=0
.
Afterwards, I ran the following test, which still requested a first touch of the device (although it wasn't apparent because of the lack of a cue
message).
I hope I have been of help to provide some feedback, and I'll be happy to test any modifications; I think I will reopen the bug, as it may seem that userpresence=0
was still requiring interacting.
Thanks for spending the time.
Since you re-ran pamu2fcfg
, your authentication file should now look like
user:base64_string,base64_other_string,es256,+presence
if you delete the +presence
part (or re-run pamu2fcfg
with -P
) then you should be able to authenticate without having to touch the device.
No problem! (And sorry for taking time to get back in touch; I was mostly busy).
I re-generated the u2f_keys
file with pamu2fcfg
with the -P
and -nP
flags for my two devices, and ran some tests with one key either plugged or unplugged before testing; the debug logs looked the same for any of the keys, and failed with the following debugging information (falling back to google-authenticator):
user@computer:~$ sudo echo "hello world"
[sudo] password for user:
debug(pam_u2f): pam-u2f.c:109 (parse_cfg): called.
debug(pam_u2f): pam-u2f.c:110 (parse_cfg): flags 32768 argc 5
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): argv[0]=interactive
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): argv[1]=userpresence=0
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): argv[2]=nouserok
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): argv[3]=authfile=/etc/Yubico/u2f_keys
debug(pam_u2f): pam-u2f.c:112 (parse_cfg): argv[4]=debug
debug(pam_u2f): pam-u2f.c:114 (parse_cfg): max_devices=0
debug(pam_u2f): pam-u2f.c:115 (parse_cfg): debug=1
debug(pam_u2f): pam-u2f.c:116 (parse_cfg): interactive=1
debug(pam_u2f): pam-u2f.c:117 (parse_cfg): cue=0
debug(pam_u2f): pam-u2f.c:118 (parse_cfg): nodetect=0
debug(pam_u2f): pam-u2f.c:119 (parse_cfg): userpresence=0
debug(pam_u2f): pam-u2f.c:120 (parse_cfg): userverification=-1
debug(pam_u2f): pam-u2f.c:121 (parse_cfg): pinverification=-1
debug(pam_u2f): pam-u2f.c:122 (parse_cfg): manual=0
debug(pam_u2f): pam-u2f.c:123 (parse_cfg): nouserok=1
debug(pam_u2f): pam-u2f.c:124 (parse_cfg): openasuser=0
debug(pam_u2f): pam-u2f.c:125 (parse_cfg): alwaysok=0
debug(pam_u2f): pam-u2f.c:126 (parse_cfg): authfile=/etc/Yubico/u2f_keys
debug(pam_u2f): pam-u2f.c:128 (parse_cfg): authpending_file=(null)
debug(pam_u2f): pam-u2f.c:130 (parse_cfg): origin=(null)
debug(pam_u2f): pam-u2f.c:131 (parse_cfg): appid=(null)
debug(pam_u2f): pam-u2f.c:132 (parse_cfg): prompt=(null)
debug(pam_u2f): pam-u2f.c:185 (pam_sm_authenticate): Origin not specified, using "pam://computer"
debug(pam_u2f): pam-u2f.c:196 (pam_sm_authenticate): Appid not specified, using the same value of origin (pam://computer)
debug(pam_u2f): pam-u2f.c:208 (pam_sm_authenticate): Maximum devices number not set. Using default (24)
debug(pam_u2f): pam-u2f.c:226 (pam_sm_authenticate): Requesting authentication for user user
debug(pam_u2f): pam-u2f.c:237 (pam_sm_authenticate): Found user user
debug(pam_u2f): pam-u2f.c:238 (pam_sm_authenticate): Home directory for user is /home/user
debug(pam_u2f): pam-u2f.c:309 (pam_sm_authenticate): Using authentication file /etc/Yubico/u2f_keys
debug(pam_u2f): util.c:215 (get_devices_from_authfile): Authorization line: user:KeyHandle1,UserKey1,es256,:KeyHandle1,UserKey2,es256,
debug(pam_u2f): util.c:220 (get_devices_from_authfile): Matched user: user
debug(pam_u2f): util.c:256 (get_devices_from_authfile): KeyHandle for device number 1: KeyHandle1
debug(pam_u2f): util.c:279 (get_devices_from_authfile): publicKey for device number 1: UserKey1
debug(pam_u2f): util.c:303 (get_devices_from_authfile): COSE type for device number 1: es256
debug(pam_u2f): util.c:324 (get_devices_from_authfile): Attributes for device number 1: KeyHandle1,UserKey2,es256,
debug(pam_u2f): util.c:354 (get_devices_from_authfile): Found 1 device(s) for user user
debug(pam_u2f): pam-u2f.c:382 (pam_sm_authenticate): Using file '/var/run/user/1000/pam-u2f-authpending' for emitting touch request notifications
Insert your U2F device, then press ENTER.
get_key_val: key_len=4
debug(pam_u2f): util.c:527 (do_authentication): Device max index is 1
debug(pam_u2f): util.c:559 (do_authentication): Attempting authentication with device number 1
debug(pam_u2f): util.c:581 (do_authentication): Key handle: KeyHandle1
debug(pam_u2f): util.c:687 (do_authentication): Challenge: wjlYq0xTLr+3INTNqqaPrnPema0fq333DiHjv1nsBF8=
debug(pam_u2f): util.c:422 (get_authenticators): Working with 1 authenticator(s)
debug(pam_u2f): util.c:426 (get_authenticators): Checking whether key exists in authenticator 0
debug(pam_u2f): util.c:436 (get_authenticators): Authenticator path: /dev/hidraw5
I think that, when parsing the generated file with the options, the Attributes for the device aren't properly parsed (this may be a separate bug).
I do have one question, though, would registering the keys with pamu2fcfg -P
always disable checking for user presence? Or is it just to allow for disabling checking for user presence with the userpresence=0
option?
Yes there is an issue with how credentials are parsed right now. Some of that logic has been rewritten in the ssh format branch, but that issue is still pending.
Did you leave the tail end of the logs out on purpose? Did you get a "Key not found" error?
Just to be clear, the KeyHandle1
, UserKey1
, KeyHandle2
and UserKey2
is you redacting the values and not what is actually in the file, right?
If that's the case, could you please try either registering only one device, or making sure that the device you have plugged in is the first of the two (i.e. the one for KeyHandle1
) and only that. I can get it to work in that scenario.
I do have one question, though, would registering the keys with
pamu2fcfg -P
always disable checking for user presence? Or is it just to allow for disabling checking for user presence with theuserpresence=0
option?
Neither, the idea is that it's possible to set that flag either at the system level (userpresence=1
) or at the credential level (+presence
), and that the more "restrictive" setting will take effect. However, that logic is a bit tricky because the currently released version of pam-u2f
doesn't have the +presence
flag but assumes that behavior. On top of that, not setting a flag is not exactly equivalent to setting it to off, but rather it's equivalent to setting it to its default behavior in the specifications.
Did you leave the tail end of the logs out on purpose? Did you get a "Key not found" error?
Yes, sorry, I was being cautious to not paste revealing information about the U2F key (because I couldn't easily find in util.c
what exactly was being displayed after line 436.
Just to be clear, the KeyHandle1, UserKey1, KeyHandle2 and UserKey2 is you redacting the values and not what is actually in the file, right?
Correct! I've been redacting the Key Handle and User Key (is it safe to disclose them?).
If that's the case, could you please try either registering only one device, or making sure that the device you have plugged in is the first of the two (i.e. the one for KeyHandle1) and only that. I can get it to work in that scenario.
I couldn't get it to work on my end.
I re-ran make clean
, autoreconf --install
, ./configure
, make
, and sudo make install
just to be on the safe side, then generated the keys for a single device with pamu2fcfg -P > ~/.config/Yubico/u2f_keys
, and moved them with sudo mv ~/.config/Yubico/u2f_keys /etc/Yubico/u2f_keys
.
Here is the relevant information:
Hopefully this helps.
Neither, the idea is that it's possible to set that flag either at the system level (
userpresence=1
) or at the credential level (+presence
), and that the more "restrictive" setting will take effect. However, that logic is a bit tricky because the currently released version ofpam-u2f
doesn't have the+presence
flag but assumes that behavior. On top of that, not setting a flag is not exactly equivalent to setting it to off, but rather it's equivalent to setting it to its default behavior in the specifications.
Thanks for clearing it up! I was getting that impression from reading the source, but I just wanted to confirm; I added userpresence=1
to the relevant line in /etc/pam.d/sudo
.
Edit: I noticed I left an incomplete sentence.
Yes, that was helpful. Thanks.
So, what kind of device do you have? Am I correct in thinking that you have a relatively old device that only does U2F (like a YubiKey NEO or a YubiKey 4) and not a FIDO2-capable one?
Silent authentications (i.e., without testing for user presence) are a relatively new addition to U2F and are supported in FIDO2. Older devices don't implement that version of the specifications, plus libfido2 doesn't implement that behavior over U2F either.
If that's the case I'm afraid there isn't much more I can do to help you with this.
Wow. You're right, and sorry about that --- it didn't occur to me that that may be a factor.
I tested with a more recent Yubico Security Key, and now I was able to achieve the desired behaviour:
I'll close this issue, as this would accomplish what I was looking for.
Should I file a new issue to keep track of the Attribute-parsing issue for multiple keys?
Ah, good. Glad that the mystery has been solved and that you have a more recent device that solves your use-case.
I am already aware of the issue with the attribute parsing and I was working on a fix for it in the SSH format branch, I just seem to never have time to dedicate to this project. It should be just a quick fix. I'll try to get it out "soon".
Thanks again for patiently testing.
Not a problem! And thank you for patiently helping me debug the issue.
Although perhaps in retrospect, it would be nice to know which options in pam-u2f
require a FIDO2-capable U2F device, and which are backwards-compatible, for future sysadmins. This would bring the pending documentation tasks to:
libfido2-dev
, libssl-dev
, gengetopt
for building, and remove libu2f-server
and libu2f-host
userpresence
, requiring pamu2fcfg -P
and userpresence=0
pam-u2f
options that require a FIDO2-capable device (which, I think are userpresence
, userverification
, and pinverification
)I'm not sure if they'll be merged on the SSH branch, or on master; if you'd like, I can submit a pull request.
In the meantime, I'll keep an eye on the SSH branch, and order a new Yubikey (because I like to have a spare device in case I lose one).
Indeed, those are all valid points. The README file still reflects the old/current version of the project, that's why the dependencies are incorrect.
A bit pedantic maybe, but the idea is that FIDO2 is backwards compatible with U2F, the actual issue is that the version of U2F required is 1.2, which only YubiKeys that already support FIDO2 implement.
Let me try to fix the parsing issue in the SSH branch and get that merged in in a relatively short amount of time. It'll then be easier to contribute to the right place and hopefully get a new release out at some point.
As a side note, the fact that you had to replace your authfile when switching to the git version of this project worries me, as it would be a problem for anybody who is updating. I hope that was due to lots of different things all moving at the same time (there is a test to parse both new and old formats and it passes).
A bit pedantic maybe, but the idea is that FIDO2 is backwards compatible with U2F, the actual issue is that the version of U2F required is 1.2, which only YubiKeys that already support FIDO2 implement.
You're technically correct; the best kind of correct! :laughing:
Let me try to fix the parsing issue in the SSH branch and get that merged in in a relatively short amount of time. It'll then be easier to contribute to the right place and hopefully get a new release out at some point.
I'll be on standby if anything needs to be tested, or to contribute in some small way.
As a side note, the fact that you had to replace your authfile when switching to the git version of this project worries me, as it would be a problem for anybody who is updating. I hope that was due to lots of different things all moving at the same time (there is a test to parse both new and old formats and it passes).
I'll try to replicate soon by creating an authfile with the 1.0.8
version, then upgrading everything to master
and test with my FIDO2-capable security key. It may very well have been an issue on my end (or due to the fact that the authfile had two keys listed, and I was using the one that wasn't FIDO2-capable as my first option).
I have pushed a bit of a reworked logic for parsing authentication files that is hopefully more robust than the previous. I've also added a whole slew of tests checking different combinations of options and number of devices/credentials.
All seems good on my end, but if you're willing to take a look at your convenience it would greatly be appreciated. The latest commit is cbd0ac7b455e1435a683f5a8bc5285b6c1f76423. Thanks!
Hello. Sorry for the delay!
I ran sudo make uninstall
, installed the 1.0.8
version available for Ubuntu, ran pamu2fcfg
, and set everything up... and, it worked!
~The one thing I noticed is that, when parsing a previously generated auth_file
, setting userpresence=0
worked as if it had been specified in a new configuration file (in other words, previous versions would infer +presence
; since it is omitted, it is parsed as if I had ran pamu2fcfg -P
).~
I was about to be done, but I wanted to generate a new auth_file
, however I ran into the following error when running pamu2fcfg
: bash: /usr/bin/pamu2fcfg: No such file or directory
.
After running which pamu2fcfg
, it reports that it is located in /usr/local/bin/pamu2fcfg
.
Edit: I noticed checked out a different commit; I'll test against cbd0ac7.
Great, thanks for testing!
Old credentials/devices didn't have the concept of not checking for user presence and therefore there was no such option. The intended behavior with +presence
is to maintain backwards compatibility, hence it is on by default no matter if it's a new or an old credential.
Similarly, the userpresence=0
option also didn't exist hence it won't be assumed unless somebody specifically turns that on by changing the configuration of the module, in which case it will be honored.
The aim here is to allow a working system to be upgraded without breaking and without resulting in a completely different behavior.
Regarding the location of pamu2cfg
, the path that you described is what is used by default if you build and install the package yourself from a git checkout. If you want the binaries to end up in a different place you can use the --prefix
option when calling ./configure
.
Hi @a-dma . Thanks for pointing that out; once I used ./configure --prefix=/usr
and followed the building instructions, everything worked fine.
It turns out that I had checked out a different commit and, once I tested commit cbd0ac7, everything worked as expected (I updated my previous comment).
I tested with a single key and also with two keys (the second being the older device mentioned above, as my new device has yet to arrive); I also tested userpresence=0
with the older key but, as expected, it doesn't work and falls back to the other authentication method I had set up in the pam rules.
I can confirm, on my end, that pamu2fcfg
version 1.0.8
authentication files are compatible with commit pam-u2f
from cbd0ac7, and that it also parses attributes from multiple keys.
Thanks a lot, that's very valuable feedback. Appreciate the effort.
No problem! Thank you for the effort put on the SSH branch!
Hello. First, I'd like to thank the Yubico developers for such great work on the pam-u2f module.
I'm writing this issue because I'm trying to implement a PAM authentication flow similar to what is seen in websites:
Although I've been reading several resources online, I haven't been able to create something that feels entirely correct.
At first, I wanted to give the user some choice, and I dabbled unsuccessfully with the
pam_exec.so
module (but found that it couldn't request user input to allow choosing which 2FA option to use). Also, this particular answer on ServerFault dissuaded me from using[success=1 default=ignore] pam_u2f.so
on the first line.Then, I cobbled together something that looks and performs similar to the above requirements (with the limitation of having to press two times the tactile trigger):
On a terminal emulator, this results in the following dialogue:
(Note: It's most likely that I'm not understanding the proper usage of
userpresence
anduserverification
) I tried usinguserpresence=0 userverification=0
instead ofcue
on the firstauth
line, but this still resulted in a flashing Yubikey, which I had to tap twice, although the reminder to touch the device was only displayed once.So, what I'm trying to ask is: What would be the best way to achieve something that only detects if a (valid?) U2F device is plugged in? (perhaps succeeding on 'check-only' authentication request?).
If such an option were to be called
notouching
, this would allow the above code to be converted into:And, in turn, it would allow for not having to request two times that the user touch the device.