Passwordless login is enabled by the global `--pwdless` flag. Registration gets
a new prompt and an `--allow-passwordless` flag.
UX messages were tweaked to follow the descriptions on RFD 53: Passwordless
FIDO2[1].
Passwordless login requires two touches for all devices (both PIN and biometric).
I'd like to get it down to a single touch, at least for the most common
situations, but that'll be a follow up to this work.
Passwordless support requires `tsh` to be compiled with the `libfido2` tag, try
`go build -tags=libfido2 ./tool/tsh`.
#9160
[1] https://github.com/gravitational/teleport/blob/master/rfd/0053-passwordless-fido2.md#ux
* Allow reuse of devices for passwordless
* Implement passwordless registration in tsh
* Add better tracing to FIDO2 filters
* Implement passwordless logins in tsh
* Make --pwdless a global flag
* Fix lint errors
* Fix U2F tests
* Use initClient's URL as origin
* Distinguish whether --allow-passwordless is set or unset
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
- changes to configuration.go: fixes tsh login in first test case
`tsh login --insecure --proxy=127.0.0.1:3080 --user=test`
- changes to apiserver.go fixes `--auth` not showing motd
* Fix goroutine and memory leak in watchCertAuthorities
The CA Watcher was blocking both on writing to a channel when the watcher
was closed and on HTTP calls that had no request timeout or context passed
to cause cancellation.
All resourceWatcher implementations that had a bug which may cause them to block
on writing to a channel forever were fixed by selecting on the write and ctx.Done.
Adding context.Context to all Get/Put/Post/Delete methods on the auth HTTPClient to
force callers to propagate context. Prior all calls used context.TODO which
prevents requests from being properly cancelled.
Add context propagation to RotateCertAuthority, RotateExternalCertAuthority,
GetCertAuthority, GetCertAuthorities. This is needed to get the correct ctx
from the CertAtuhorityWatcher all the way down to the HTTPClient that makes
the call.
Closes#10648
Wire passwordless registration and authorization into Auth and Proxy APIs, thus
making passwordless logins possible.
API changes are described by RFD 52: Passwordless [1].
#9160
[1] https://github.com/gravitational/teleport/blob/master/rfd/0052-passwordless.md#authentication-api-changes
* Add passwordless settings to Auth protos
* Update generated protos
* Register: Apply DeviceUsage in lib/auth
* Register: Apply DeviceUsage in lib/web
* Login: Generate passwordless challenge
* Login: Allow passwordless authentication
* Wire passwordless in lib/web endpoints
* Make mocku2f passwordless setup a bit nicer
`tsh kube credentials` command is executed as kubernetes client-go
credential plugins.
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins
client-go captures all stdout of plugin and treats it as
`ExecCredential` object.
When session is timeout, `tsh` prompt to relogin.
To avoid client-go's capturing prompt text, prompt to stderr instead of
stdout when login.
* The web UI needed to show the total count of resources available after filter
* ListResources response returns as a struct to make adding extra fields easier
Alias the "u2f" second factor mode to "webauthn", effectively sunsetting U2F in
favor of WebAuthn.
The change effectively disables "U2F mode" server-side, making Teleport use
WebAuthn instead. This is in line with our compatibility promise, as Teleport
8.x clients are already WebAuthn-capable (and thus have no problems talking to
the cluster).
I have cleaned up a good chunk of U2F references in lib/web and lib/client, plus
a few other places. Changes on lib/auth are just the necessary to get the tests
back to good standing. There is more work to be done, but this seems enough for
a single PR.
#10375
* Remove "Disabled" field from types.Webauthn
* Update generated protos
* Treat second_factor "u2f" as "webauthn"
* Remove references to Webauthn.Disabled
* Remove U2F from lib/web/
* Remove U2F from lib/client/
* Remove U2F from lib/auth/ (partially)
* Fix issues after rebase on master
* Fix typo
Add support for Database Access for Redis for standalone and cluster self-hosted instances. Teleport requires mTLS in order to connect to Redis instance which is only supported in Redis 6.0+. RESP2 is currently the only supported protocol.
In Teleport 8 we migrated all uses of this API to GRPC, but left
the JSON API in place so that Teleport 7 nodes could still join
the cluster.
In Teleport 9, the oldest nodes we support are v8, which use the
GRPC API, so we can safely remove the old API.
* Record desktop sessions
Here we introduce a new protobuf type (DesktopRecording) that contains
an encoded TDP message, and update AuditWriter to treat these similarly
to SessionPrint events (which are used for SSH session recordings).
We also add desktop session playback endpoint, temporarily located at
/webapi/sites/:site/desktopplaybacktest/:session
which streams TDP messages from a recorded session over
a websocket interface.
* update session end (#9795)
* Updates SessionEnd event with fields needed for frontend
* removes the clock which didn't need to be passed
* Add `Recorded` field to `WindowsDesktopSessionEnd` (#9839)
* Adds the SessionRecording field to WindowsDesktopSessionEnd event to mimic SessionEnd events (useful for easy integration with frontend).
* 14 should have been 12
* removing test logic
* switches SessionRecording to simple boolean Recorded
* session recording websocket (#9908)
* Adds the SessionRecording field to WindowsDesktopSessionEnd event to mimic SessionEnd events (useful for easy integration with frontend).
* 14 should have been 12
* removing test logic
* switches SessionRecording to simple boolean Recorded
* Updates the websocket address
* updates desktopPlaybackHandle to restart playback once it reaches the end
* adds playback state and synchronization logic for ensuring that goroutines aren't leaked
* adds toggle functionality for play/pause
* fix for the fact that urls are case insensitive
* moves desktop_playback to its own file, fixes mistaken comment about how websocket.JSON.Receive works, fixes error messaging, wraps playbackState.Close in a sync.Once
* Adds a cond variable for the two goroutines, but doesn't solve the spinning loop problem for the hanging logic
* Adds a cancel-able context which is cancelled in ps.Close() in order to avoid a spinning loop in the websocket.Handler
* Moves the majority of playback logic into the playbackState, which is now renamed to the more accurate playbackPlayer.
* changes pp.hangWhilePaused to pp.waitWhilePaused
* Moves the context out of NewPlaybackPlayer and the playbackPlayer
struct, wraps playback goroutines in playbackPlayer.Play(ctx) in
order to comply with context semantics.
* removing unnecessary warnings
* touchups
* record screen size (#9992)
* Adds the SessionRecording field to WindowsDesktopSessionEnd event to mimic SessionEnd events (useful for easy integration with frontend).
* 14 should have been 12
* removing test logic
* switches SessionRecording to simple boolean Recorded
* Updates the websocket address
* updates desktopPlaybackHandle to restart playback once it reaches the end
* adds playback state and synchronization logic for ensuring that goroutines aren't leaked
* adds toggle functionality for play/pause
* fix for the fact that urls are case insensitive
* moves desktop_playback to its own file, fixes mistaken comment about how websocket.JSON.Receive works, fixes error messaging, wraps playbackState.Close in a sync.Once
* Adds a cond variable for the two goroutines, but doesn't solve the spinning loop problem for the hanging logic
* Adds a cancel-able context which is cancelled in ps.Close() in order to avoid a spinning loop in the websocket.Handler
* Moves the majority of playback logic into the playbackState, which is now renamed to the more accurate playbackPlayer.
* changes pp.hangWhilePaused to pp.waitWhilePaused
* Moves the context out of NewPlaybackPlayer and the playbackPlayer
struct, wraps playback goroutines in playbackPlayer.Play(ctx) in
order to comply with context semantics.
* removing unnecessary warnings
* Adds an OnRecv that's similar to OnSend, for emitting audit events for particular incoming tdp messages
* Send full `DesktopRecording` event as json over playback websocket. (#10052)
* playback websocket now sends a json representation of the DesktopRecording event rather than just the raw tdp message, in order for us to have timing data on the frontend
* updating json.Marshal to utils.FastMarshal
* Removing unnecessary comment
* playback end event (#10088)
* Adds an end event so that the playback player knows to set the progress bar to its end state
* making the end message a json
* if the marshal fails we don't want to send a message over websocket
* Use a static string
Co-authored-by: Edoardo Spadolini <edoardo.spadolini@goteleport.com>
Co-authored-by: Edoardo Spadolini <edoardo.spadolini@goteleport.com>
* Add participants to session end event
Desktop sessions are not joinable, so the participants list always
has a single member - the user who started the session.
This will ensure that our example role for RBAC for sessions
(which depends on the participants field) will work for desktop
sessions.
* Minor cleanup
* Only record sessions when enabled
In order for desktop sessions to be recorded, session recording
must be enabled in the cluster's session recording config and
at least one of the user's roles must enable it.
* Cleanup
* Start to address review comments
* Move TDP event handlers out of connectRDP
* Address more review comments and add some tests
* Add playback streaming test
* Consistent comments
* Fix tests
* Don't log PNG frames that exceed the size of a protobuf
Since the PNG frame message in our desktop protocol is unbounded,
it is theoretically possible for a message to exceed the size limit
of a single protobuf.
In practice, this is unlikely to occur with any legitimate RDP traffic,
as the bitmaps are at most 64x64 pixels and compressed in PNG form.
Rather than complicating the protocol to allow for PNGs to be split
across events, we simply refuse to log anything this big.
* Mark RFD 48 implemented
Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
Co-authored-by: Edoardo Spadolini <edoardo.spadolini@goteleport.com>
* add diag to teleport db/app start
* db --cluster flag supports
* add some ut and fix issue ~/.tsh get removed during test
* working mongodb
* fix logout
* fix ut
* code review comment
* fix mysql
This change clears the screen when an ssh session ends (only in FIPS mode). Note: This doesn't currently do anything in `tsh` on Windows since BoringCrypto isn't supported, but once it is supported, the behavior will match Unix and web.
Co-authored-by: Grzegorz <grzegorz.zdunek@goteleport.com>
Co-authored-by: Russell Jones <russjones@users.noreply.github.com>
`tsh` doesn't support MFA logins on Windows; we make that explicit by warning
users when necessary, instead of directing them to a hopeless workflow.
Example attempt:
```shell
$ tsh login
> Enter password for Teleport user codingllama: <password>
> ERROR: hardware device MFA not supported by your platform, please register an OTP device
>
> exit status 1
```
This new feature in Go 1.17 automatically restores the environment
variable to its previous value when a test ends, making it simpler
to set up the environment for tests and less likely that we accidentally
leave behind global state.
Also convert some of the remaining uses of check to standard Go tests.