This commit adds a user message ("Detected security key tap") that is
printed at the earliest opportunity after `tsh` succesfully detects a
security key tap.
This solves a problem users have when there is significant latency in
their connection to their teleport proxy, where there may be zero
visible feedback to the user for upwards of 8 seconds after they tap
their security key.
This often causes users to think that the tap was not detected or
failed, and they attempt to tap again.
This can cause the user to accidentally paste a "yubisneeze" into their
terminal, which is not great from a security perspective.
As an API choice here I added a `TouchAcknowledger` returned by they
`PromptTouch` of the `LoginPrompt` interface.
It may seem like a bit of a weird API, but I did it this way so that all
callers of `PromptTouch` are forced to explicitly acknowledge the touch
or explicitly ignore that return value, they cannot simply forget to ack.
This applies to WebAuthn and Passwordless logins from `tsh`, no changes
are made to Connect.
Implement the Touch ID credential picker.
During passwordless authentication, when more than one login is present in
Enclave credentials, `tsh` now asks the end user to pick their desired login.
Credential picker terminal prompts are preceded by a system Touch ID prompt,
which is then reused for authentication, provided less than 10 seconds pass in
the meantime.
I've done a couple of refactors to make the `CredentialInfo` structs similar
between the `webauthncli` and `touchid` packages, so it's easier to trace
parallels between them.
#13901
* Refactor touchid.CredentialInfo
* Refactor wancli.CredentialInfo
* Move fido2_prompt*.go to prompt*.go
* Define the touchid credential picker API
* Add Touch ID credential picker tests
* Implement touchid credential picker
* configure golangci-lint misspell to check for anglicized spellings
* Americanize spellings
* fix aws constant value with british spelling 🇬🇧
* update api types with americanized spellings
* use american spellings .cloudbuild/scripts
Add a credential picker to the tsh FIDO2/WebAuthn backend.
The PR pulls a recent patch in our go-libfido2 fork that makes it correctly
return multiple assertions from the authenticator. This allows us to implement
the credential picker for FIDO2, simplify our implementation and provide the
exact same UX that browsers use (always 1-touch for bio, touch->PIN->touch
otherwise).
I've dropped concepts like "optimistic assertions" and "eager PIN prompts" in
favor of a simple, uniform implementation.
Issue #13901.
* Prompt for credentials in LoginPrompt
* Update go-libfido2
* Implement FIDO2 credential picker
* Drop optimistic assertions, only set user if explicit
* Add license to fido2_prompt_test.go
Favor newer Touch ID credentials in the allowed set for MFA, or just the newer
credential for passwordless.
Fixes a capture-by-reference bug and adds coverage for it.
Issue #13340.
* Add tests for Touch ID credential-choosing logic
* Favor newer Touch ID credentials within the allowed set
* Warn about origin vs RPID mismatch
Add the --mfa-mode flag and wire touch ID into tsh authn/registration.
In the default MFA mode (auto), touch ID should be eager if there is a
credential present in the system. Users may change this behavior using other MFA
modes.
See https://github.com/gravitational/teleport/blob/master/rfd/0054-passwordless-macos.md.
#9160
* Add AuthenticatorAttachment/MFAMode to tsh
* Add support for touch ID in wancli.Login
* Warn users about passwordless in U2F mode
* Add support for touch ID in `tsh mfa add`
Introduce the concept of an "optimistic assertion", which allows us to skip
credential listing (saving a touch) and go directly for an authenticator
assertion.
The downside of an optimistic assertion is that the authenticator picks the
credential, meaning that we can't guarantee or choose the user. This should be
fine for most people, as they are unlikely to have multiple Teleport users in a
single cluster. If the --user flag is explicitly provided we'll honor it and do
the two-touch ceremony instead.
Optimistic assertions are only applied for biometric authenticators; we already
do single-touch for PINs if possible.
This is a bit of an experimental change. It should improve the experience in
most scenarios, but we may elect to rollback if the underlying assumption proves
itself to be poor.
Note that we now depend on gravitational/go-libfido2, as the upstream
go-libfido2 doesn't yet return the credential ID and user ID in assertions.
#9160
* Alias keys-pub/go-libfido2 to gravitational/go-libfido2
* Add LoginOpts to wancli.Login
* Allow optimistic assertions for bio devices
* Use optimistic assertions if the user is not provided
* Pull optimistic assertion check to deviceCallback
* Tweak OptimisticAssertion godoc
During passwordless logins, if the only candidate device is PIN protected, we
can ask for the PIN right away, saving a touch.
The timing for the the initial touch prompt is now dictated by
wancli.Login/wancli.Register, as the touch is not necessarily the first
operation to happen anymore.
#9160
* Move initial prompt to wancli callbacks
* Eagerly ask for PIN in certain situations
* Rename func to "shouldDoEagerPINPrompt"
Seamlessly change the public API of lib/auth/webauthncli to use the
libfido2-backed implementation, as long as the binary was compiled with the
libfido2 build tag.
A few adjustments are necessary to "wancli" methods to allow users to provide
prompt callbacks and to return the credential user (not applicable here, but
will be in following PRs).
Additional changes are made to tsh mfa add in order to avoid stdin hijacking by
ContextReader, since we now may require PIN reads for authenticators.
#9160
* Move U2F logic to u2f_* files
* Split U2F API from general l/a/webauthncli API
* Move FIDO2 public API to fido2_common.go, introduce IsFIDO2Available
* Introduce prompt.SyncReader
Sync reads allow prompt calls to be mixed with term.ReadPassword calls.
* Wire FIDO2 into MFA login
* Wire FIDO2 into MFA registration