Installing support for encrypted JSON authentication
guacamole-auth-json is an authentication extension for Apache Guacamole which authenticates users using JSON which has been signed using HMAC/SHA-256 and encrypted with 128-bit AES in CBC mode. As this JSON contains all information describing the user being authenticated, including any connections they have access to, this extension can provide a simple means of integrating Glyptodon Enterprise with external applications. Glyptodon Enterprise packages encrypted JSON support within the glyptodon-guacamole-auth-json package:
Configuring Guacamole to accept encrypted JSON
Guacamole’s main configuration file,
/etc/guacamole/guacamole.properties, must be modified to specify the secret key which the Guacamole server should use to decrypt and verify received JSON. Systems generating this JSON will also use this same key to encrypt and sign the JSON they generate.
As guacamole-auth-json uses 128-bit AES, this key must be 128 bits, specified as a 32-digit hexadecimal value using the
This key can be essentially anything as long as it is unpredictable. An easy way of generating such a key is to echo a passphrase through the "md5sum" utility. This is the technique OpenSSL itself uses to generate 128-bit keys from passphrases. For example:
If encrypted JSON will only ever be received from a known set of machines or private subnets, you may wish to further restrict acceptance of received JSON to only those trusted machines using the
Guacamole will generally only load new extensions and reread
guacamole.properties during the startup process. To apply the configuration changes, Guacamole (and thus Tomcat) must be restarted:
The general format of the JSON (prior to being encrypted, signed, and sent to Guacamole), is as follows:
TIMESTAMP is a standard UNIX epoch timestamp with millisecond resolution (the number of milliseconds since midnight of January 1, 1970 UTC) and
PROTOCOL is the internal name of any of Guacamole's supported protocols, such as
The top-level JSON object which must be submitted to Guacamole has the following properties:
|The unique username of the user authenticated by the JSON. If the user is anonymous, this should be the empty string (|
|The absolute time after which the JSON should no longer be accepted, even if the signature is valid, as a standard UNIX epoch timestamp with millisecond resolution (the number of milliseconds since midnight of January 1, 1970 UTC).|
|The set of connections which should be exposed to the user by their corresponding, unique names. If no connections will be exposed to the user, this can simply be an empty object (|
Each connection defined within each submitted JSON object has the following properties:
|The internal name of a supported protocol, such as |
|An object representing the connection parameter name/value pairs to apply to the connection, as documented in the Guacamole manual.|
Generating encrypted JSON
To authenticate a user with the above JSON format, the JSON must be both signed and encrypted using the same 128-bit secret key specified with the
- Generate JSON in the format described above
- Sign the JSON using the secret key (the same 128-bit key stored within
json-secret-keyproperty) with HMAC/SHA-256. Prepend the binary result of the signing process to the plaintext JSON that was signed.
- Encrypt the result of (2) above using AES in CBC mode, with the initial vector (IV) set to all zero bytes.
- Encode the encrypted result using base64.
- POST the encrypted result to the
/api/tokensREST endpoint as the value of an HTTP parameter named
data(or include it in the URL of any Guacamole page as a query parameter named
For example, if Guacamole is running on localhost at
BASE64_RESULT is the result of the above process, the equivalent run of the "curl" utility would be:
/api/tokensor including it in the URL. Base64 can contain both "+" and "=" characters, which have special meaning within URLs.
If the data is invalid in any way, if the signature does not match, if decryption or signature verification fails, or if the submitted data has expired, the REST service will return an invalid credentials error and fail without user-visible explanation. Details describing the error that occurred will be in the Tomcat logs via
The source includes a shell script,
/usr/share/guacamole-auth-json/doc/encrypt-json.sh, which uses the OpenSSL command-line utility to encrypt and sign JSON in the manner that guacamole-auth-json requires. It is thoroughly commented and should work well as a reference implementation, for testing, and as a point of comparison for development. The script is run as:
For example, if you have a file called
auth.json containing the following:
and you run:
You will receive the following output:
The resulting base64 data above, if submitted using the data parameter to Guacamole, will authenticate a user and grant them access to the connections described in the JSON (at least until the expires timestamp is reached, at which point the JSON will no longer be accepted).
The OpenSSL utility is not an explicit dependency of the glyptodon-guacamole-auth-json package as it's not inherently required by the actual Guacamole extension. If you do not already have the OpenSSL utility installed, you will need to install it before running the
encrypt-json.sh reference implementation: