Apache Guacamole 1.0.0

Apache Guacamole is split into two subprojects: "guacamole-client", the HTML5 web application which serves the Guacamole client to users, and "guacamole-server", the remote desktop proxy which the web application communicates with. The source code for each of these may be downloaded below.

If you do not wish to build Apache Guacamole entirely from source, pre-built versions of the web application (.war) and all extensions are provided here in binary form for convenience. Please note that guacamole-server must still be built and installed from source.

Release notes

The 1.0.0 release features support for user groups, improved clipboard integration leveraging the Asynchronous Clipboard API, as well as support for TOTP (Google Authenticator), RADIUS, and dead keys.

This release contains changes which break compatibility with past releases. Please see the deprecation / compatibility notes section for more information.

New features and improvements

Support for user groups

Guacamole now supports granting permissions based on group membership. While this has been supported to a degree for some time via LDAP and the seeAlso attribute, groups can now be defined and used within a database, with LDAP and a database combined, or within other extensions using Guacamole’s extension API.

Clipboard integration with the Asynchronous Clipboard API

For browsers which implement the Asynchronous Clipboard API, Guacamole will now automatically synchronize the local and remote clipboards. Users will be prompted to grant clipboard access upon opening Guacamole, and Guacamole will synchronize the clipboard if access is granted.

This API has been implemented in Google Chrome since version 66, and other browsers will likely follow suit. The legacy synchronous clipboard API will continue to be used as a fallback for browsers that support clipboard access but lack support for the newer API (Internet Explorer).

  • GUACAMOLE-559 - Add support for the new Asynchronous Clipboard API

Multi-factor authentication with Google Authenticator / TOTP

Guacamole now has support for TOTP as an additional authentication factor. TOTP (Time-based One-Time Password) is a standardized algorithm used for multi-factor authentication. With this new support, Guacamole may be used with any application or authentication device which supports the TOTP standard, including the popular Google Authenticator.

  • GUACAMOLE-96 - Two factor authentication with Google Authenticator

Support for RADIUS authentication

RADIUS support has been added, allowing Guacamole to delegate authentication to a RADIUS service like FreeRADIUS for validating credentials, enforcing multiple authentication factors, etc.

Because the RADIUS library used by this support is licensed under the LGPL, a convenience binary for this extension is not provided. If you wish to use the RADIUS support, you will need to build guacamole-client from source and explicitly enable that part of the build with -P:

mvn package -Plgpl-extensions

Instructions for building this support are provided in the manual.

Support for creating ad-hoc connections

An extension is now provided which allows users to create arbitrary, temporary connections through entering a URL. This ability can be quite convenient, as users need not create new connections through the administrative interface in order to quickly access a particular machine.

Be sure you understand the security implications of providing this level of access. A Guacamole connection implicitly has network and filesystem access to the Guacamole server, thus providing this ability is equivalent to granting your users those privileges.

Improved keyboard handling / Support for dead keys

Multiple improvements have been made to keyboard handling, including bug fixes for Mac and iOS and support for dead keys.

Automatic connection behavior

Guacamole will automatically connect upon login for users that have access to only a single connection, skipping the home screen. This feature has been tweaked slightly so that it applies only to non-administrative users. Users with access to Guacamole’s administrative interface will now see the home screen and will not be automatically connected.

  • GUACAMOLE-508 - Automatically connect only if user lacks access to settings

Support for renaming RDP drive and printer

By default, the filesystem and printer made available within RDP connections are named “Guacamole Filesystem” and “Guacamole Printer” respectively. Support has been added to override these names with the drive-name and printer-name parameters respectively.

Configurable terminal color schemes

The Guacamole terminal now allows for finer control of terminal color schemes by allowing for the individual colors of a scheme to be customized through the existing color-scheme parameter. The behavior of this parameter is the same for both SSH and telnet.

  • GUACAMOLE-470 - Make individual terminal colors configurable through “color-scheme” parameter

Optional recording of input events

Guacamole has supported session recording for quite some time, but did not record input events (mouse movement/clicks, keyboard input, etc.). This meant that the mouse cursor could not be rendered in recording playback (as the mouse position information from mouse events was not included) and session recording could not be used for some auditing purposes that required logging of key events.

Options are now available for capturing input events during session recording. For security and privacy reasons, only mouse events are captured within session recordings by default. Capture of keyboard events can be manually enabled, and capture of mouse events can be manually disabled.

SSH host key verification

SSH host key verification is now implemented and can be enabled and configured within Guacamole. In the past, Guacamole has not performed any SSH host key checking, and version 1.0.0 introduces this capability.

For compatibility with past releases, this functionality is still disabled by default. If known host keys are not provided, Guacamole will continue to behave as it has in the past and will allow the connection to succeed, though a warning will be logged.

If host keys are provided (either in an ssh_known_hosts file within the GUACAMOLE_HOME directory on the server running guacd, or by passing the host-key parameter to the connection with the key of the specific server), host key checking will be strictly enforced and the connection will only succeed if the host key matches.

  • GUACAMOLE-527 - Add parameter for specifying known SSH/SFTP server host key

Automatic detection of network issues

The Guacamole web application will now periodically check the responsiveness of the network connection, displaying a warning if the network appears unstable.

Downstream web applications which leverage the Guacamole API should handle the Guacamole.Tunnel.State.UNSTABLE tunnel state in their tunnel’s onstatechange handler to provide similar behavior, if desired.

  • GUACAMOLE-567 - Network connection problem acknowledgement/feedback

Support for configuring Guacamole with environment variables

Support has been added for specifying any of the properties supported in the GUACAMOLE_HOME/guacamole.properties file by setting environment variables that correspond to those properties. The name of the environment variable for any particular property is the name of the property in uppercase with all dashes replaced with underscores.

For security reasons, the enable-environment-properties property must be set to true for reading of properties from environment variables to be enabled.

  • GUACAMOLE-464 - Extension configuration properties from the OS environment

Improvements to guacamole/guacd and guacamole/guacamole Docker images

Many improvements have been made to the Docker support files for building and running Guacamole within Docker containers. Most notable among these is that the base for the guacd Docker image has been changed from CentOS 7 to the latest Debian stable. This allows for more recent, but still stable, versions of libraries to be used to support the various protocols and features of guacd.

  • GUACAMOLE-42 - Support setting guacd log level on Docker container
  • GUACAMOLE-407 - Update guacd Docker image to build against more recent dependencies
  • GUACAMOLE-450 - Change Tomcat Version in Dockerfile to major release
  • GUACAMOLE-553 - Docker image need a new MySQL JDBC driver for MySQL 8.0

General usability improvements

Improvements to usability have been made in order to address issues reported by users. Guacamole now supports Ctrl-Alt-End as an alternative shortcut for sending Ctrl-Alt-Delete to remote systems. The zoom level of the client display can be specified more granularly, connections are easier to select within in the web interface, and guacd now provides a flag for printing the build version.

General improvements to terminal behavior

Compatibility of Guacamole’s terminal emulator has been improved, particularly when dealing with non-Linux operating systems. Parameters have been added for configuring the terminal type reported to the remote system, and for adjusting the control code sent for backspace. The terminal has also been adjusted to hide escape sequences and control codes that need not be supported but which were previously incorrectly printed to the screen.

Support for systemd

The guacamole-server build now includes an optional systemd init script to allow for automatic startup on distributions that have moved from traditional init scripts to systemd.

Control of RDP bitmap and glyph caching

Parameters have been added to RDP connections that allow for controlling how the RDP protocol behaves for caching bitmaps, glyphs, and other off-screen data. The default behavior remains unchanged, with caching of all of these items enabled, however these parameters are available to workaround issues if your RDP server handles such caching incorrectly.

  • GUACAMOLE-448 - Add parameters for controlling RDP bitmap/glyph/off-screen caching

Internationalization

Additional RDP keymaps

Several keymaps have been added or updated to better support RDP servers with differing keyboard layouts. As always, bear in mind that the client side of Guacamole is always independent of keyboard layout. Additional keyboard layouts for RDP are mainly of benefit for enabling the typing of certain characters if your RDP server does not support Unicode events, and to ensure correct translation of key event to RDP scancode if the keyboard layout of the RDP server is not the default (US English).

Spanish translation of web interface

The entire web interface has been translated into Spanish, including the on-screen keyboard. Spanish will automatically be selected if accessing Guacamole from a browser whose default language is set to Spanish. The language can also be manually selected within Guacamole’s preferences.

Bug fixes

Hostname / desktop name regression

An issue was corrected where the hostname or desktop name of VNC and RDP connections replaced the connection name on the tab or window title in the browser. The connection name is now always displayed for VNC and RDP.

  • GUACAMOLE-502 - Hostname / desktop name replaces connection name

General connection stability

Several issues potentially affecting connection stability have been addressed. Additional safeguard measures have also been put in place to ensure that connection processes are automatically killed and cleaned up if an unknown issue causes the process to become unresponsive.

Issues with database authentication behavior and SQL queries

The new SQL Server support introduced with 0.9.14 leveraged SQL syntax that was not compatible with SQL Server 2008 and later, and contained a bug which resulted in the login history query failing after several history entries existed. These issues have been fixed.

A usability issue where users with disabled accounts would be shown a home screen (albeit entirely blank) has also been fixed, and handling of the hostname/address logged for user and connection access history has been updated to be consistent across both underlying tables.

  • GUACAMOLE-505 - Individual user query fails after two or more login history entries exist
  • GUACAMOLE-525 - Creating user results in “Incorrect syntax near ‘LIMIT’”
  • GUACAMOLE-529 - Despite the fact user account is disabled, user account can access to a welcome blank screen
  • GUACAMOLE-540 - Discrepancy with remote_host between tables

Incorrect status reported for sessions closed by RDP server

Guacamole would previously incorrectly report that an RDP server was unavailable when the connection was actually closed by the RDP server due to another user starting a conflicting desktop session. As the web application will automatically attempt to reconnect if the RDP server is reported as unavailable (under the assumption that the condition is transient and the server may eventually become available), this could cause users to repeatedly kick each other out.

This has been fixed for 1.0.0. Disconnects due to conflicting RDP sessions should now be handled correctly.

  • GUACAMOLE-484 - UPSTREAM_UNAVAILABLE incorrectly reported for sessions closed by RDP server

CAS authorization URI derived incorrectly

Guacamole’s CAS authentication has been corrected to more properly comply with the CAS specification. The /login portion of the URI used for logins is required by the specification but was previously omitted by Guacamole. This is tolerated by some CAS implementations, but not by all. CAS implementations which require this should now work as expected with Guacamole.

Build issues for guacamole-server

Issues which broke the guacamole-server build on some platforms have now been fixed. In particular, Guacamole should now build correctly on systems having GCC 7.

Fixes for guacenc behavior and protocol implementation

Previous releases of the “guacenc” utility (part of guacamole-server) produced incorrect error messages and erratic behavior under certain conditions. These issues have been corrected.

  • GUACAMOLE-307 - guacenc reports “Layer index out of bounds: -1”
  • GUACAMOLE-482 - Return value of guacenc_video_flush_frame() not handled
  • GUACAMOLE-490 - guacenc does not take channel mask into account for image streams

Issues specific to Internet Explorer

Several issues specific to Internet Explorer which either caused problems or had the potential to impact compatibility across versions of Internet Explorer have been fixed.

Use of deprecated navigator.getUserMedia()

The navigator.getUserMedia() method used by Guacamole’s support for audio input has been deprecated. Guacamole has been updated to no longer rely upon that method.

Incorrect documentation for RDP load-balance-info parameter

The load-balance-info parameter was incorrectly documented as load-balancing-info. The correct parameter name is indeed load-balance-info. This has been fixed in the documentation.

  • GUACAMOLE-427 - RDP “load-balance-info” parameter incorrectly documented

Erroneous inclusion of “guaclog” binary in source tree

The “guaclog” binary was accidentally included in the source tree of the git repository. It has been removed.

  • GUACAMOLE-492 - guaclog binary erroneously included in source tree

Platform / API changes

Java 8 or later is now required

As noted in the compatibility section below, the Guacamole web application now requires Java version 1.8 or later for both the build and at runtime. The core Java library, guacamole-common, remains compatible with Java 1.6, however Java 1.8 is still required for the overall guacamole-client build.

Guacamole no longer uses cookies

The Guacamole web application no longer uses cookies at all, instead relying on the browser’s local storage.

Removal of NoAuth and other deprecated components

Several components that were previously marked as deprecated have been removed entirely from the code base. This includes the NoAuth extension, several classes and functions, and several old properties. The use of any of these components would previously have resulted in warnings. They will no longer be available from this point forward, and continuing to use the deprecated properties will silently have no effect.

Improvements to extension API

The extension API has been updated to make development and maintenance of extensions easier and more consistent. The error status codes sent by the REST API are now derived from the exceptions thrown, allowing extensions to control the exact code sent. Dependency precedence has been updated so that extensions always see the classes they bundle, even if the web application bundles a different version of the same class. Base implementations of the UserContext and AuthenticationProvider interfaces have been provided, removing the need to fully implement these interfaces when writing an extension.

  • GUACAMOLE-499 - REST API Error Codes should come from GuacamoleStatus
  • GUACAMOLE-541 - Webapp dependencies take precedence over bundled extension dependencies
  • GUACAMOLE-542 - Provide base implementations of UserContext and AuthenticationProvider
  • GUACAMOLE-566 - Add RESTExceptionWrapper support for extensions

Web application updated to AngularJS 1.6.9

The AngularJS library included with the Guacamole web application was updated from 1.3.16 to 1.6.9. Several parts of the web application were reworked for compatibility with this update, including the handling HTTP requests and responses.

  • GUACAMOLE-526 - Update Guacamole-Client Webapp to Angular 1.6.9

Improvements to JavaScript tunnel API

The tunnel implementations provided by Guacamole’s JavaScript API have been updated to allow arbitrary HTTP headers to be included in the connection request (where supported by the underlying transport), and to allow the same instance of the tunnel to be reused following disconnect.

  • GUACAMOLE-431 - Tunnel implementations handles close only once
  • GUACAMOLE-437 - Allow to configure custom headers for Guacamole tunnels

Deprecation / Compatibility notes

As of 1.0.0, the following changes have been made which affect compatibility with past releases:

Java 8 or later is now required

Most of the Java components of the Guacamole Client have been updated to require Java 1.8 for both compile and runtime. This decision was made based on the fact that many support libraries are moving toward requiring later versions of Java, that Java 1.8 has been out and stable for many years, and that Java 1.6 and 1.7 have ceased receiving public updates.

The only exception to this is the core Java API, guacamole-common, which continues to maintain compatibility with Java 1.6.

Database schema changes

Significant changes have been made to the schemas for all of the JDBC authentication modules (MySQL, PostgreSQL, and SQL Server). Among those changes are the addition of support for user groups and the changes required to support those within the database modules (including the “entity” as an overall type for both users and groups).

Users of any of the database authentication modules will need to run the upgrade-pre-1.0.0.sql script specific to their chosen database as part of the move from earlier versions of Guacamole to 1.0.0. More thorough instructions for this process can be found in the database authentication documentation.

Hostname logging within database

The hostname/address of users logged by the database authentication backend is now determined entirely by the servlet container. The database authentication will not manually parse the X-Forwarded-For header, and will instead rely on the servlet container to perform any such parsing.

If proxying Guacamole, the configuration of your servlet container should be updated to handle the headers set by your proxy. For Apache Tomcat, this is accomplished with a RemoteIpValve in your server.xml.

Logging of hostnames/addresses by Guacamole during the authentication process (as would be parsed by tools like fail2ban) is unchanged, however you will need to update the pattern if RemoteIpValve or similar are used, as the address of interest will likely be the rightmost address. If the user is not behind any additional, untrusted proxies, the address of interest will be the only address.

Removal of deprecated NoAuth extension

The NoAuth extension has been deprecated since 0.9.13-incubating, and has now been removed from Guacamole’s codebase.

Removal of deprecated properties

The following properties have been deprecated for quite some time, and have been removed in the 1.0.0 release.

  • basic-user-mapping
  • mysql-disallow-simultaneous-connections
  • mysql-disallow-duplicate-connections
  • postgresql-disallow-simultaneous-connections
  • postgresql-disallow-duplicate-connections

Prior to the 1.0.0 release a warning would be logged regarding the deprecation of these properties. As of this release, these properties will be silently ignored.

Extension API changes

Support for user groups

As noted above, one of the major changes in this release is the addition of support for user groups. These changes center around the new UserGroup interface and functions for accessing instances of that interface. Note that if you are using the abstract base classes AbstractUserContext and AbstractUser, little to no changes will be necessary as default implementations of the required new functions have been provided.

Retrieval of user groups

The UserContext interface now defines a getUserGroupDirectory() function which returns a Directory<UserGroup> providing access to all user groups. If your extension does not provide user groups, it can simply return an empty SimpleDirectory<UserGroup>:

@Override
public Object getUserGroupDirectory() {
    return new SimpleDirectory<UserGroup>();
}

Effective group membership

To allow extensions to take group membership into account, even when that membership is dictated by a different extension, the AuthenticatedUser class now defines a getEffectiveGroups() function. This function should return the identifiers of all user groups that apply to the current user. If support for user groups is not implemented by the extension, simply return an empty set of strings:

@Override
public Set<String> getEffectiveUserGroups() {
    return Collections.<String>emptySet();
}

Effective permissions

The User interface now provides a getEffectivePermissions() function which should return an implementation of Permissions which exposes the permissions that apply to the user, including permissions which may be inherited through group membership. If inheritance of permissions is not implemented by your extension, this function can simply return this (as User extends Permissions):

@Override
public Permissions getEffectivePermissions() {
    return this;
}

Exposing group membership

The User and UserGroup interfaces provide multiple functions for retrieving parent groups and child objects, if applicable. Existing implementations of the User interface which do not extend AbstractUser will need to implement getUserGroups(), a function which retrieves the immediate parent groups of the user. The returned RelatedObjectSet should allow for manipulation of the group relationship if the extension allows such manipulation (and if the current user has permission to do so). Extensions which do not implement user groups can simply return an empty set:

@Override
public RelatedObjectSet getUserGroups() {
    return RelatedObjectSet.EMPTY_SET;
}

The new decoration API

The AuthenticationProvider interface now defines decorate() and redecorate() functions which allow an implementation of AuthenticationProvider to decorate the UserContext instances of other extensions. After an extension returns a UserContext instance, the decorate() (if the UserContext is for a new session) or redecorate() (if the UserContext has been updated for an existing session) functions of all other extensions are invoked to give those extensions a chance to wrap the UserContext. This allows extensions to add functionality to the objects of other extensions which may not otherwise be possible.

Implementations of AuthenticationProvider which extend AbstractAuthenticationProvider need not implement these functions as default implementations are provided. Implementations which do not extend AbstractAuthenticationProvider and which do not decorate the UserContext of other extensions should simply return the original UserContext:

@Override
public UserContext decorate(UserContext context,
    AuthenticationProvider authProvider, Credentials credentials) {
    return context;
}

@Override
public UserContext redecorate(UserContext decorated, UserContext context,
    AuthenticationProvider authProvider, Credentials credentials) {
    return decorate(context, authProvider, credentials);
}

Removal of deprecated GuacamoleHome and GuacamoleProperties classes

The GuacamoleHome and GuacamoleProperties classes have been deprecated since 0.9.4, having been replaced by the Environment interface and its concrete LocalEnvironment implementation. These classes are no longer part of the extension API. Implementations should migrate to LocalEnvironment.

Deprecation of SimpleUserDirectory, SimpleConnectionDirectory, and SimpleConnectionGroupDirectory classes

The SimpleUserDirectory, SimpleConnectionDirectory, and SimpleConnectionGroupDirectory classes have been deprecated in favor of the SimpleDirectory<T> class. These classes can still be used, but will result in deprecation warnings, and will be removed in a future release.

Deprecation of SimpleUser convenience constructors

With the increasing number of permission sets available for both users and user groups, the old convenience constructors which provided parameters for these permission sets for the SimpleUser implementation of the User interface have been deprecated for the sake of API simplicity and consistency.

Implementations which use these constructors of SimpleUser should migrate to extending SimpleUser and overriding the applicable getters instead. The deprecated constructors will continue to work as before, however their use will result in deprecation warnings, and they will eventually be removed from the API.

libguac API changes

guac_protocol_send_mouse() now requires additional parameters

The guac_protocol_send_mouse() function now accepts an additional guac_timestamp argument representing the point in time that the mouse event occurred. Callers of this function will now need to include an appropriate timestamp, such as the value returned by guac_timestamp_current().

GUAC_INSTRUCTION_MAX_ELEMENTS macro definition changed

The value of the GUAC_INSTRUCTION_MAX_ELEMENTS has been increased from 64 to 128. This should not affect whether existing code builds against libguac, however it does affect the size of the guac_parser structure such that it will not be binary-compatible with older versions of libguac. The system linker should take this into account automatically.

Java API (guacamole-common) changes

Removal of deprecated GuacamoleSession class

The GuacamoleSession class has been deprecated since 0.9.9 and has now been removed from the API. Downstream usages of this class should simply be removed; it is entirely unnecessary and has had no effect since 0.9.9.

Change in definition of GuacamoleHTTPTunnelServlet.sendError()

The definition of the protected function sendError() within GuacamoleHTTPTunnelServlet has changed to include explicit numeric codes for the Guacamole and HTTP statuses rather than a single GuacamoleStatus.

It is unlikely that this change will affect downstream implementations of GuacamoleHTTPTunnelServlet, which generally will only override doConnect(), however any downstream implementations which do call or override sendError() will need to be updated accordingly.

JavaScript API changes

Removal of deprecated Guacamole.Client.setClipboard() function

The setClipboard() function of Guacamole.Client has been deprecated since 0.9.1, having been replaced by createClipboardStream(), and convenience “writer” implementations like Guacamole.StringWriter which may be given the resulting Guacamole.OutputStream.

setClipboard() has now been removed from the API. Downstream uses of setClipboard() should migrate to createClipboardStream().

Addition of Guacamole.Tunnel.State.UNSTABLE state

In order to support changes to detecting and handling network problems within the Guacamole connections, another tunnel state, Guacamole.Tunnel.State.UNSTABLE, has been added. The tunnel enters this state when it is still technically connected but the network connection appears unstable and may result in disconnection.

Code which handles changes in tunnel state may need to be updated to take this additional state into account if it does not currently ignore unknown states, or that code would benefit from explicitly handling the unstable condition.

Internal WebSocket tunnel implementation changes

The WebSocket tunnel (Guacamole.WebSocketTunnel) now uses the internal tunnel opcode to send “ping” requests which the server side of the tunnel must respond to with an identical instruction to verify connection stability. Third-party reimplementations of the WebSocket tunnel will need to be updated to do the same.