GUACAMOLE-2307: Add opt-in raw text-output mode for terminal protocols (SSH/telnet/Kubernetes) - #697
Open
ciroiriarte wants to merge 1 commit into
Open
Conversation
Add an opt-in per-connection parameter, "text-output", that tees the raw
remote PTY byte stream (including ANSI/CSI/OSC sequences) to an outbound
Guacamole "pipe" stream named STDOUT, for the SSH, telnet, and Kubernetes
protocols. This lets a non-graphical / native CLI client present a terminal
session as true in-terminal text instead of decoding rasterized glyphs.
Default off; existing connections are unaffected.
The parameter is a string enum: "true" tees the raw bytes while the graphical
display is still rendered for browser users; "raw" additionally skips graphical
rendering entirely (headless); any other value, including "false" or omission,
leaves it disabled. The pipe is named STDOUT with mimetype
application/octet-stream (base64 blobs, binary-safe, charset-agnostic).
The tee is taken at the protocol source -- each protocol's PTY read path,
upstream of the terminal emulator -- rather than via guac_terminal_echo(),
which strips escape sequences. The stream is allocated on the connection
owner's user socket (an even, ack-routable index), not broadcast. New additive
public API: guac_terminal_text_output_{open,write,flush,close}.
Flow control: clients must ack every blob; the unacknowledged backlog is bounded
by bytes (256 KB). On a stalled consumer, tee mode drops buffered output (its
read loop is shared with the graphical display, so blocking would stall
co-attached browser users), while raw mode throttles the read loop, propagating
backpressure to the remote program through the PTY, and disconnects only after
15 s with no acks.
Gated behind disable-copy: guacd refuses to open the pipe when copying from the
terminal is disabled. Pipe contents are not logged or recorded by default.
Additive and opt-in: no new protocol instruction (reuses pipe/blob/end/ack), no
schema change, no ABI break. Includes CUnit coverage for the text-output paths
and a direct-to-guacd manual e2e harness for SSH/telnet/Kubernetes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements GUACAMOLE-2307.
What
Adds an opt-in per-connection parameter,
text-output, that tees the raw remotePTY byte stream (including ANSI/CSI/OSC sequences) to an outbound Guacamole
pipestream named
STDOUT, for the SSH, telnet, and Kubernetes protocols. Anon-graphical / native CLI client can then present a terminal session as true
in-terminal text instead of decoding rasterized glyphs. Default off; existing
connections are unaffected.
Modes
text-output=true— tee: raw bytes go toSTDOUTand the graphicaldisplay is still rendered for browser users.
text-output=raw— headless: graphical rendering is skipped entirely; bytesare delivered only via
STDOUT.falseor omitted — disabled.Design notes for review
upstream of the terminal emulator — rather than via
guac_terminal_echo(),which strips escape sequences.
application/octet-stream(base64blobs, binary-safe,charset-agnostic) and is allocated on the connection owner's user socket (an
even, ack-routable index), not broadcast.
guac_terminal_text_output_{open,write,flush,close}.ackeveryblob; the unacknowledged backlog isbounded by bytes (256 KB). On a stalled consumer, tee mode drops buffered
output (its read loop is shared with the graphical display, so blocking would
stall co-attached browser users), while raw mode throttles the read loop,
propagating backpressure to the remote program through the PTY, and disconnects
only after 15 s with no acks.
disable-copy: guacd refuses to open the pipe when copying from theterminal is disabled. Pipe contents are not logged or recorded by default.
Compatibility
Additive and opt-in, default off. No new protocol instruction (reuses
pipe/blob/end/ack), no schema change, no ABI break. An unmodifiedguacamole-client already passes the parameter through.
Testing
tee-drop, raw throttle/abort, the byte bound, disconnect).
make checkgreen onDebian 12 and openSUSE Leap 16.
(
util/manual-tests/).client in both modes, including a 20,000-line flood.
Coordinated PRs