GUACAMOLE-2064: Add interactive database terminal protocols#694
Open
4m1nr wants to merge 7 commits into
Open
Conversation
Add libguac-dbshell, a convenience library (analogous to common-ssh) that
provides all of the database-agnostic machinery for an interactive,
terminal-based database shell, so that each database protocol plugin need
only supply a thin driver.
The library contains:
- a byte-stream line editor with cursor movement, in-memory command
history, UTF-8-aware editing, the usual control shortcuts, and a
parser that safely consumes and discards unknown escape sequences;
- a statement splitter that accumulates input and recognizes complete
statements according to the MySQL, PostgreSQL, Transact-SQL, Oracle
(PL/SQL), and JSON dialects;
- a result table renderer that buffers an initial window of rows to size
columns and then streams the remainder, and which neutralizes control
characters in cell data so that a database server cannot inject
terminal escape sequences;
- the REPL loop, the generic protocol-plugin scaffold, and the
connection settings common to every database protocol.
CUnit tests are included for the line editor and input parser, command
history, the statement splitter (all five dialects), and cell
sanitization. The library builds whenever terminal support is enabled.
Add the "mysql" protocol, providing an interactive shell for MySQL and MariaDB servers via the dbshell library and MariaDB Connector/C. The non-blocking API of MariaDB Connector/C is used so that session teardown can never block on an unresponsive server, a running statement can be cancelled with Ctrl-C (via KILL QUERY on a secondary connection), and LOAD DATA LOCAL INFILE is disabled so the server cannot read files local to guacd. The plugin is built automatically when MariaDB Connector/C is present, and is disabled with a warning otherwise.
Add the "postgresql" protocol, providing an interactive shell for PostgreSQL servers via the dbshell library and libpq. The asynchronous libpq API is used so that teardown never blocks and a running statement can be cancelled with Ctrl-C; server notices are rendered inline, and the statement splitter understands PostgreSQL dollar-quoting and nested block comments. The plugin is built automatically when libpq is present, and is disabled with a warning otherwise.
Add the "mssql" protocol, providing an interactive shell for Microsoft SQL Server via the dbshell library and the CT-Library interface of FreeTDS. In addition to semicolons, a line containing only GO submits the current batch; server messages including PRINT output are displayed, and a running statement can be cancelled with Ctrl-C via a TDS attention. The plugin is built automatically when FreeTDS is present, and is disabled with a warning otherwise.
Add the "mongodb" protocol, providing an interactive shell for MongoDB servers via the dbshell library and the MongoDB C Driver. Each statement is a MongoDB database command written as an Extended JSON document; replies are rendered as indented JSON, cursors are followed to completion automatically, and the shell provides the meta-commands \use, \show dbs, and \show collections. The plugin is built automatically when the MongoDB C Driver is present, and is disabled with a warning otherwise.
Add the "oracle" protocol, providing an interactive shell for Oracle Database servers via the dbshell library and the Oracle Call Interface (OCI). Plain SQL statements end with a semicolon while PL/SQL blocks end with a line containing only a slash, and a running statement can be cancelled with Ctrl-C via OCIBreak. Because it depends on the proprietary Oracle Instant Client, which cannot be redistributed, Oracle support is never built by default; it is enabled by configuring with --with-oracle=<path>.
…image. Install the MariaDB Connector/C, libpq, FreeTDS, and MongoDB C Driver development packages in the guacd image builder so that the MySQL, PostgreSQL, SQL Server, and MongoDB protocols are compiled into the official image; their runtime libraries are picked up automatically by the existing dependency-detection step. Oracle is not included, as its client library cannot be redistributed. These database client libraries depend on the OpenSSL 3 development package (openssl-dev), which cannot be installed alongside the openssl1.1-compat-dev package the image previously used. This commit therefore switches the image back to openssl-dev, effectively reverting the workaround from GUACAMOLE-1741: that workaround existed because libvncclient could not authenticate VeNCrypt VNC connections against OpenSSL 3, an incompatibility since fixed upstream in LibVNCServer 0.9.15 (which the image already builds, as it auto-selects the latest release). The base image remains pinned to Alpine 3.18. Migrating to a newer base is a separate, larger effort (newer Alpine renames packages such as webkit2gtk and ships a CMake that rejects the older cmake_minimum_required used by some bundled dependency sources) and is left to be handled under GUACAMOLE-1891.
This was referenced Jul 14, 2026
Contributor
|
Haven't read through this yet, but in principle I like the idea. It's broad and would be an interesting addition to the suite of supported protocols. |
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.
What this does
Adds interactive, terminal-based access to five databases from within
Guacamole — MySQL/MariaDB, PostgreSQL, SQL Server, MongoDB, and Oracle —
implementing the feature requested in
GUACAMOLE-2064.
Following the approach suggested on the issue, guacd does not spawn a
command-line client (
mysql,psql, …). Instead each protocol links thedatabase's own C client library and drives
libguac-terminaldirectly,presenting a prompt at which statements are typed, edited, and executed. As a
result, every feature Guacamole already provides for terminal protocols —
typescripts, graphical session recording, terminal resize, clipboard, and
shared / read-only sessions — works here unchanged.
How it is structured
All database-agnostic logic lives in one new convenience library,
libguac-dbshell(src/dbshell), modeled onsrc/common-ssh:(Left/Right/Home/End), in-memory command history (Up/Down), UTF-8-aware
insertion/deletion, the usual control shortcuts (Ctrl-A/E/K/U/W/L), and a
parser that consumes-and-drops unknown escape sequences so arrow keys etc.
never leak bytes into the buffer.
per dialect: MySQL, PostgreSQL, Transact-SQL, Oracle, and JSON. Handles
single/double/backtick/bracket quoting,
--/#/ block comments,PostgreSQL dollar-quoting (and
$1positional params), T-SQLGObatches,Oracle PL/SQL
/-terminated blocks, and JSON brace/bracket balancing.column widths, then streams the remainder; mysql-style borders, right-aligned
numeric columns,
NULLrendering, width capping with an ellipsis. Itstrips control characters from every cell, so a malicious or compromised
database server cannot inject terminal escape sequences (the DB analogue of
CVE-2023-43826).
every protocol (hostname/port/credentials/database/timeout plus the full
terminal, typescript, recording, and Wake-on-LAN parameter sets).
Each protocol plugin (
src/protocols/{mysql,postgresql,mssql,mongodb,oracle})is a thin driver implementing a small vtable:
KILL QUERYcancel via a second connection;LOAD DATA LOCAL INFILEdisabledPQcancel; server notices rendered inline; dollar-quoting-awareGObatches; server messages incl.PRINT;ct_cancelattention on Ctrl-CgetMore;\use/\showmeta-commandsOCIBreakcancelBuild / packaging
configureautodetects libmariadb, libpq, FreeTDS, and libmongoc anddisables the corresponding protocol with a warning if absent (same pattern as
the existing libwebsockets/Kubernetes check).
proprietary and non-redistributable. It is enabled explicitly with
--with-oracle=<instant-client-dir>.Dockerfileinstalls the four redistributable client libraries, sothe official image gains MySQL/PostgreSQL/SQL Server/MongoDB support; Oracle
is documented as a custom-image step.
Testing
Unit tests (CUnit,
make check): new suites for the line editor & inputparser, command history, the statement splitter across all five dialects, and
cell sanitization. Full suite: 160 tests across 7 suites, all passing
(was 123/6 before).
Manual / integration testing: built and ran guacd against live database
containers, opening real connections through the Guacamole protocol with a
typescript recording enabled and asserting on the recorded output:
mariadb:11), PostgreSQL (postgres:16), SQL Server(
mcr.microsoft.com/mssql/server:2022), MongoDB (mongo:7), Oracle(
gvenzl/oracle-free):SELECTrendering (bordered table, right-alignednumerics, "N rows in set" footer), banners, and clean disconnect.
recovery (session survives), and UTF-8 round-trip (
café).ERROR 1045and aborts cleanly.BEGIN … END; /PL/SQL block followed by aSELECT … FROM dual(proves semicolons inside the block do not terminate early).\use,\show collections,insert, andfind.docker build .produces a guacd image containing all four redistributableplugins;
make checkgreen with--with-oracleactive.-Werror -Wallclean; every function, parameter, struct member, and constantis Doxygen-documented in the house style.
Related PRs
Part of a three-repo change under GUACAMOLE-2064: