* Add support for windows desktop services proxying different desktops
* Add filter to GetWindowsDesktops, remove GetWindowsDesktop and GetWindowsDesktopByName
* Cache cleanup
* Fix cache deletes for Windows desktops
For deletes, the cache only gets the backend key, not the entire
resource. Do what database access does, which is to extract the
host ID from the path, and stuff it in the description field of
the resource header.
* Godoc cleanup
* Fix lint
* Address review comments
* Send error message if no desktop found
* Revert to x/net/websocket
This got converted to gorilla/websocket as part of moderated sessions.
We'll do a more intentional conversion post-release.
* fix lint
Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
* Define sorters for resource Server, AppServer, and DbServer
* Add sorting to ListResources in caching and presence layer
* ListResources now returns nextKey set to the limit+1th item,
previously it returned a possible next key, where there
may or may not be more results.
Introduce two new audit events:
- desktop.clipboard.send: emitted when a user's local clipboard
data is sent to teleport
- desktop.clipboard.receive: emitted when clipboard data is received
from a remote windows desktop
Closes#9706
* 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>
This adds an rpc UpsertKubeServiceV2 to replace UpsertKubeService. Currently, kubernetes service does not have a keepalive heartbeat unlike app, db, and windows service. This brings functionality in line with the others. This would allow for future use of the keepalive to track connected agents via prometheus metrics.
Adds Application certificate path to profile
Prior to this patch, the API Profile type had no way of exposing the
path to an application certificate. While this could be constructed
manually using the `keypaths` package, this was fragile and easy to miss
should the profile layout ever change.
This patch adds `GetAppCertPath()` to the API profile, providing a
centralised and integrated method for finding application
certificates.
* Add the `cert.create` event
For now, this is only emitted for user certificate issuance.
* Make `cert_type` a string rather than an enum
* Match field names and json tags in events.Identity
* Change events.Identity.Traits to be a wrappers.LabelValues/wrappers.Traits
* Event code shouldn't be under T10xx anymore
Takes resource parser and match search and
adds these filters to ListResources.
Allows resource filtering by labels, search keywords,
or with the predicate language.
Part of RFD 55
* Add desktop_clipboard role option
As described in RFD 49, desktop_clipboard defaults to true.
Since sharing clipboards with a remote machine requires a high level
of trust, the presence of a single role in a role set which disables
the clipboard will result in the feature being disabled.
(This is in contrast to session recording, for example, where all
roles in a set must disable recording to turn it off.)
* completing TestBoolOptions
Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
* update github.com/gravitational/trace to v1.1.17
github.com/gravitational/trace v.1.17 adds support for `errors.Is`
to all errors it defines. This makes checking any `trace.Error` for
equivalence much easier, especially within tests.
require.ErrorIs/require.NotErrorIs should work out of the box now.
This option defaults to true, as defined in RFD #0033.
The preset editor and audit roles disable desktop session recording,
as they aren't permitted access to desktops. The preset access role
enables desktop session recording. The implicit role applied to all
role sets also disables recording, otherwise it would be impossible
to disable.
Adds a method to resources MatchSearch, that goes through
select resource field values, and matches it against a list of
user provided search values.
Part of RFD 55
* Refactor most uses of `UserMetadata` into a handful of functions
* Add access requests to `UserMetadata`
* Explanation for the reserved field in SessionStart
* Add access request locks
This only contains the internal part, no user-visible changes
* Add a `tctl lock` flag to specify an access request ID
* Tests for access request locks
* go get google.golang.org/api
go get: upgraded cloud.google.com/go v0.60.0 => v0.100.2
go get: upgraded github.com/golang/snappy v0.0.1 => v0.0.3
go get: upgraded github.com/googleapis/gax-go/v2 v2.0.5 => v2.1.1
go get: upgraded go.opencensus.io v0.22.5 => v0.23.0
go get: upgraded golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d => v0.0.0-20211104180415-d3ed0bb246c8
go get: upgraded google.golang.org/api v0.29.0 => v0.65.0
* Optionally fetch transitive groups in the Google OIDC connector
* Refactor the google workspace parts of the OIDC code
* Further refactoring
This undoes the user account impersonation changes, and always requires
an admin account again.
* Test coverage
* Address review comments
* Minor refactor and name changes
* Allow domain filtering, tests now bypass addGoogleWorkspaceClaims
* Update `OIDCConnectorV2` to `OIDCConnectorV3`
* Backwards compatibility for OIDCConnector v2
This also removes the extra boolean flag that was added previously.
* Update e-ref
Enterprise builds will break unless gravitational/teleport.e#385
is included.
* Allow impersonation of roles without users
This adds the ability to impersonate one or more roles without
impersonating a particular user.
In Teleport today, when creating an impersonator role, both users and
roles must be specified as impersonation is fundamentally tied to an
existing Teleport user:
```yaml
allow:
impersonate:
users: ['jenkins']
roles: ['jenkins']
```
This is inconvenient for two reasons:
1. A user must exist for each set of roles you'd like to
impersonate, creating a UX burden.
2. It makes it difficult to use impersonation to reduce one's
permissions as you always inherit all of the roles granted to the
target user.
For the [certificate bot][bot] we'd instead like to use impersonation
to generate end-user (impersonated) certificates with a reduced set
of permissions. For example, given the following role:
```yaml
allow:
impersonate:
roles: ['jenkins', 'deploy']
```
We can then use `GenerateUserCerts` to issue certifices for a subset
of the allowed roles, e.g. one set of certificates with only the
`jenkins` role attached, and another with only `deploy`.
To that end, this patch:
1. Removes the requirement that roles define both `users` and
`roles` in impersonate conditions
2. Introduces a new `RoleRequests` field in `UserCertsRequest`
3. Modifies `generateUserCerts` to gather `roles` from
`RoleRequests` if allowed by an `allow` (with no `users`)
[bot]: https://github.com/gravitational/teleport/pull/7986
* Add `determineDesiredRolesAndTraits`; audit log on role impersonation
This splits initial role and trait determination into a new function,
`determineDesiredRolesAndTraits`, to improve control flow and clarity
given the new branches introduced for role impersonation.
Additionally, this moves the call to `CheckRoleImpersonation` down
to match regular user impersonation's flow, and emits an audit log
event on failure.
* Formatting fix
* Unit testing for role requests
This adds a new set of unit tests for role requests.
Also discovered the `impersonator` field wasn't being set for
role impersonation, so it's now set to the user's own username.
In other words, role impersonation will appear (in the audit log and
elsewhere) as self-impersonation.
* Clean up testing users between runs
* Deny most reimpersonation cases and add tests
This attempts to deny most cases of reimpersonation, where an
impersonated certificate might be used to generate certificates for
other roles the user is allowed to impersonate.
One test case is currently failing pending a solution.
* Add new DisallowReissue certificate extension
This adds a new DisallowReissue certificate extension that, if set,
prevents that identity from interacting with `GenerateUserCerts`.
This flag is always set when RoleRequests are used to prevent
unintended privilege escalation (while avoiding breaking changes to
Teleport's existing certificate generation behavior).
* Fix test lints
* Fix typo
* Fix test doc typo, add testcase for user impersonation misuse
* Apply suggestions from code review
Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com>
* Accept context in CreateRole per review feedback
* Fix misleading comment
Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com>
* Adds logic for grabbing known desktops from the auth server when the desktop discovery's reconciler starts up
* moving desktop initialization into goroutine
* Apply suggestions from code review
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* minor fixes
* removes initial discovery logic since it would break a multi-w_d_s setup, instead solves the problem by changing discovery's create function to an upsert
* consolidating verb check call
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
* Add tests for ParseTeleportRoles
Updates #9752
* Be more tolerant when parsing system roles.
Our original attempt at canonicalizing roles didn't work for system
roles using camelcase, resulting in an awkward user experience.
Here we maintain a mapping of allowed inputs to their corresponding
system roles, and perform a case-insensitive lookup. This allows us
to support camelcase roles, and has the advantage of permitting
_ word separators as well.
Fixes#9752
* Refactor *SystemRole.Check()
Rather than having to list each role here, we rely on the new
roleMappings set to validate the role.
Additionally, remove the LegacyClusterTokenType role. This change
is guaranteed to be backwards compatible because we check for
RoleTrustedCluster everywhere we were checking for
LegacyClusterTokenType, and our roleMappings will convert the old
string that represented LegacyClusterTokenType to RoleTrustedCluster.
This change adds a new audit event, `session.connect`, that is emitted when dialing to either an OpenSSH server or a trusted cluster. It also adds `emitConn`, a wrapper for a `net.Conn` that peeks at the first few bytes read and emits session.connect when it detects a non-Teleport connection.
- Ensure that the dial request uses proper "server ID" format,
which is <uuid>.<cluster_name>
- Update reverse tunnel agent to handle tunnel connections
to desktops
* Add the `access_request.delete` event
* fix typo
Co-authored-by: Marek Smoliński <marek@goteleport.com>
* Use a custom RequestID field instead of ResourceMetadata in AccessRequestDelete
This is for consistency with AccessRequestCreate and other FooDelete
events for resources that don't use the Name field in Metadata to
identify the resource.
Co-authored-by: Marek Smoliński <marek@goteleport.com>
Now 'verify-full', 'verify-ca' and 'insecure' modes can be used when connecting to a database. 'verify-full` is the default on and it's the most strict. 'verify-ca' skips the server-name check. 'insecure' accepts any certificate provided by a database.
* Add access requests to tlsca.Identity, and store them in TLS certs
This mirrors what we already do for SSH certs.
* Keep track of access requests in web sessions
* Keep track of access requests in app sessions
* Include the current access requests when issuing new user certs
This is necessary because we extend the list of current roles
instead of starting from the statically assigned ones, so we should
also keep track of all the potential ways that those roles were
granted to the user.
* fix: pass access requests through PreAuthenticatedSignIn
* Tests for access requests in TLS certs
Prior to this change, desktop access only respected locks
on users or roles. This introduces a desktop as a lock target,
preventing new connections and terminating existing connections
to a locked desktop.
Note: when a lock is created, connection attempts will fail
with the generic "websocket connection failed" error.
This will be addressed with #8584.
Updates #8742