Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"websocket unavailable" when starting RDP session in full screen mode #41515

Closed
uedvt359 opened this issue May 14, 2024 · 1 comment · Fixed by #41570
Closed

"websocket unavailable" when starting RDP session in full screen mode #41515

uedvt359 opened this issue May 14, 2024 · 1 comment · Fixed by #41570
Assignees

Comments

@uedvt359
Copy link

Expected behavior:

I'm starting RDP sessions using Chrome/ium's App mode, to provide a more native feel, using the following command:

chrome.exe --app=https://teleport.local/web/cluster/teleport.local/desktops/the-hostname/myuser --start-fullscreen

After logging in with a Passkey, I'm prompted for MFA auth.

Current behavior:

After touching the yubikey when the Windows MFA prompt appears, I get the following error: "websocket unavailable"

image

devtools error:

image

This error only occurs when trying to use MFA in full screen mode, if I hit F11 to get out of full screen mode, it works flawlessly.

This message is produced when the error occurs:

May 14 13:48:03 teleport.local teleport[3068931]: 2024-05-14T13:48:03+02:00 INFO [AUDIT]     mfa_auth_challenge.create challenge_allow_reuse:false challenge_scope:CHALLENGE_SCOPE_USER_SESSION cluster_name:teleport.local code:T1015I ei:0 event:mfa_auth_challenge.create time:2024-05-14T11:48:03.89Z uid:7394e7f6-842e-4209-8fb4-2f33da719448 user:myuser user_kind:1 events/emitter.go:288
May 14 13:48:05 teleport.local teleport[3068931]: 2024-05-14T13:48:05+02:00 ERRO [WEB]       expected MFA message type 10, got 1 cluster-name:teleport.local desktop-name:the-hostname session:6d11 user:myuser web/desktop.go:84

My Role has spec.options.require_session_mfa: true

This is reproducible reliably with Chrome 123.0.6312.123/32bit and MSEdge 123.0.2420.97 on Windows 10, and sometimes with chromium-121.0.6167.85-1.fc38.x86_64 on Fedora 38.

Previously, with Teleport 15.1.8, this used to work everytime/everywhere.

Bug details:

  • Teleport version: 15.3.0, 15.3.4
  • Recreation steps: use the above chromium command line for a RDP host with MFA enabled
  • Debug logs: see above
@uedvt359 uedvt359 added the bug label May 14, 2024
@zmb3
Copy link
Collaborator

zmb3 commented May 14, 2024

@ibeckermayer looks like there are 2 problems here:

  1. Error handling. The error that we sent to the browser is not the error that the user sees. This is likely due to a timing issue related to us closing the websocket on error.
  2. Resize functionality is breaking the per-session MFA flow, as the MFA decoder is seeing unexpected screen spec messages on the connection instead of the MFA message. We probably need to withhold resizes until after MFA completes.

ibeckermayer added a commit that referenced this issue May 15, 2024
1. A new mechanism is added to withhold all non-MFA TDP
   messages during the MFA ceremony within lib/web/desktop.go
2. A new mechanism is added to withhold all resizes when the
   rdpclient/client.go is not yet ready to receive messages.
   (Non-resize messages are still just dropped).

This fixes #41515
github-merge-queue bot pushed a commit that referenced this issue May 21, 2024
* Update 'failed' statusText only if a previous error has not already been displayed to the user. This way the first error message (which is usually the most informative as to what's gone awry) is displayed to the user in the case of an error cascade. (E.g. tdp error is sent back, the server to closes the websocket, and that close causes a client websocket error. In that case, we want to display the tdp error that was sent back, not the websocket is closed error.)

* Adds mechanisms for withholding resizes

1. A new mechanism is added to withhold all non-MFA TDP
   messages during the MFA ceremony within lib/web/desktop.go
2. A new mechanism is added to withhold all resizes when the
   rdpclient/client.go is not yet ready to receive messages.
   (Non-resize messages are still just dropped).

This fixes #41515

* Remove superfluous comment, rename handleMessage to handleTDPInput

* Refactors mfa and desktop handlers
to use a single function to handle checking if MFA is required,
and refactors the desktop handler to make the TLS configuration
creation more clear.

* use idiomatic TypeAttr

* Only log a warning when we try to send TDP message on a closed ws

The only time I know this happens is when the user tries to resize on when
an "Active Session" warning modal is shown, in which case the session was
failing. In reality we can just ignore this scenario. If the websocket isn't
yet open, we don't want to send messages. If it closes, then the onclose
handler will take care of cleaning up the session, we don't need to error
if any straggling messages are attempted to be sent.
ibeckermayer added a commit that referenced this issue May 21, 2024
* Update 'failed' statusText only if a previous error has not already been displayed to the user. This way the first error message (which is usually the most informative as to what's gone awry) is displayed to the user in the case of an error cascade. (E.g. tdp error is sent back, the server to closes the websocket, and that close causes a client websocket error. In that case, we want to display the tdp error that was sent back, not the websocket is closed error.)

* Adds mechanisms for withholding resizes

1. A new mechanism is added to withhold all non-MFA TDP
   messages during the MFA ceremony within lib/web/desktop.go
2. A new mechanism is added to withhold all resizes when the
   rdpclient/client.go is not yet ready to receive messages.
   (Non-resize messages are still just dropped).

This fixes #41515

* Remove superfluous comment, rename handleMessage to handleTDPInput

* Refactors mfa and desktop handlers
to use a single function to handle checking if MFA is required,
and refactors the desktop handler to make the TLS configuration
creation more clear.

* use idiomatic TypeAttr

* Only log a warning when we try to send TDP message on a closed ws

The only time I know this happens is when the user tries to resize on when
an "Active Session" warning modal is shown, in which case the session was
failing. In reality we can just ignore this scenario. If the websocket isn't
yet open, we don't want to send messages. If it closes, then the onclose
handler will take care of cleaning up the session, we don't need to error
if any straggling messages are attempted to be sent.
github-merge-queue bot pushed a commit that referenced this issue May 21, 2024
* Backports the piece of mfa.go changed in #40077 required for backporting #41570

* Fixes error propagation and resizes during MFA (#41570)

* Update 'failed' statusText only if a previous error has not already been displayed to the user. This way the first error message (which is usually the most informative as to what's gone awry) is displayed to the user in the case of an error cascade. (E.g. tdp error is sent back, the server to closes the websocket, and that close causes a client websocket error. In that case, we want to display the tdp error that was sent back, not the websocket is closed error.)

* Adds mechanisms for withholding resizes

1. A new mechanism is added to withhold all non-MFA TDP
   messages during the MFA ceremony within lib/web/desktop.go
2. A new mechanism is added to withhold all resizes when the
   rdpclient/client.go is not yet ready to receive messages.
   (Non-resize messages are still just dropped).

This fixes #41515

* Remove superfluous comment, rename handleMessage to handleTDPInput

* Refactors mfa and desktop handlers
to use a single function to handle checking if MFA is required,
and refactors the desktop handler to make the TLS configuration
creation more clear.

* use idiomatic TypeAttr

* Only log a warning when we try to send TDP message on a closed ws

The only time I know this happens is when the user tries to resize on when
an "Active Session" warning modal is shown, in which case the session was
failing. In reality we can just ignore this scenario. If the websocket isn't
yet open, we don't want to send messages. If it closes, then the onclose
handler will take care of cleaning up the session, we don't need to error
if any straggling messages are attempted to be sent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants