You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@guacamole.apache.org by GitBox <gi...@apache.org> on 2021/05/30 19:23:46 UTC

[GitHub] [guacamole-manual] necouchman commented on a change in pull request #165: GUACAMOLE-1347: Migrate from DocBook to Sphinx.

necouchman commented on a change in pull request #165:
URL: https://github.com/apache/guacamole-manual/pull/165#discussion_r637587494



##########
File path: src/administration.md
##########
@@ -0,0 +1,314 @@
+Administration
+==============
+
+Users, user groups, connections, and active sessions can be administered from
+within the web interface if the underlying authentication module supports this.
+The only officially-supported authentication modules supporting this are the
+database extensions, which are documented in [](jdbc-auth).
+
+If you are using the default authentication mechanism, or another
+authentication extension, this chapter probably does not apply to you, and the
+management options will not be visible in the Guacamole interface. If, on the
+other hand, you are using one of the database authentication providers, and you
+are logged in as a user with sufficient privileges, you will see management
+sections listed within the settings screen:
+
+![Sections within the Guacamole settings screen.](images/guacamole-settings-sections.png)
+
+Clicking any of these options will take you to a corresponding management
+section where you can perform administrative tasks.
+
+(session-management)=
+
+Managing sessions
+-----------------
+
+Clicking "Active Sessions" navigates to the session management screen.  The
+session management screen displays all active sessions and allows system
+administrators to kill them as needed.
+
+When any user accesses a particular remote desktop connection, a unique session
+is created and will appear in the list of active sessions in the session
+management screen. Each active session is displayed in a sortable table,
+showing the corresponding user's username, how long the session has been
+active, the IP address of the machine from which the user is connecting, and
+the name of the connection being used.
+
+![Session management interface](images/manage-sessions.png)
+
+To kill one or more sessions, select the sessions by clicking their checkboxes.
+Once all desired sessions have been selected, clicking "Kill Sessions" will
+immediately disconnect those users from the associated connection.
+
+(filtering-sessions)=
+
+### Filtering and sorting
+
+The table can be resorted by clicking on the column headers. Clicking any
+column will resort the table by the values within that column, while clicking a
+column which is already sorted will toggle between ascending and descending
+order.
+
+The content of the table can be limited through search terms specified in the
+"Filter" field. Entering search terms will limit the table to only sessions
+containing those terms. For example, to list only connections by the user
+"guacadmin" which have been active since March, 2015, you would enter:
+"guacadmin 2015-03". Beware that if a search term needs to contain spaces, it
+must be enclosed in double quotes to avoid being interpreted as multiple terms.
+
+![](images/session-filter-example-1.png)
+
+If you wish to narrow the content of the table to only those connections which
+originate from a particular block of IP addresses, you can do this by
+specifying the block in standard CIDR notation, such "10.0.0.0/8" or
+"2001:db8:1234::/48". This will work with both IPv4 and IPv6 addresses.
+
+![](images/session-filter-example-2.png)
+
+Connection history
+------------------
+
+Clicking "History" navigates to the connection history screen. The connection
+history screen displays a table of the most recent connections, including the
+user that used that connection, the time the connection began, and how long the
+connection was used.
+
+![Connection history interface](images/manage-history.png)
+
+(filtering-history)=
+
+### Filtering and sorting
+
+Initially, the connection history table will display only the most recent
+history records. You can page through these records to see how and when
+Guacamole has been used.
+
+Just as with the table of active sessions described earlier, the table of
+history records can be resorted by clicking on the column headers or filtered
+by entering search terms within the "Filter" field.
+
+The same filtering format applies - a search term containing spaces must be
+enclosed in double quotes to avoid being interpreted as multiple terms, and
+only history records which contain each term will be included in the history
+table. Unlike the table of active sessions, however, the filter will only take
+effect once you click the "Search" button. This is due to the nature of the
+connection history, as the number of records may be quite extensive.
+
+(user-management)=
+
+User management
+---------------
+
+Clicking "Users" within the list of settings sections will take you to the user
+management screen. Here you can add new users, edit the properties and
+privileges of existing users, and view the times that each user last logged in.
+If you have a large number of users, you can also enter search terms within the
+"Filter" field to filter the list of users by username.
+
+To add a new user, click the "New User" button. This will take you to a screen
+where you will be allowed to enter the details of the new user, such as the
+password and username. Note that, unless you specify otherwise, the new user
+will have no access to any existing connections, nor any administrative
+privileges, and you will need to manually set the user's password before they
+will be able to log in.
+
+![User management interface](images/manage-users.png)
+
+To edit a user, just click on the user you wish to edit. You will be taken to a
+screen which allows you to change the user's password, expire their password
+(such that it must be changed at next login), add or remove administrative
+permissions, and add or remove read access to specific connections, sharing
+profiles, or groups. If you are managing a large number of connections or
+groups and wish to reduce the size of the list displayed, you can do so by
+specifying search terms within the "Filter" field. Groups will be filtered by
+name and connections will be filtered by name or protocol.
+
+If you have delete permission on the user, you will also see a "Delete" button.
+Clicking this button will permanently delete the user.  Alternatively, if you
+only wish to temporarily disable the account, checking "Login disabled" will
+achieve the same effect while not removing the user entirely. If they attempt
+to log in, the attempt will be rejected as if their account did not exist at
+all.
+
+![Editing a user](images/edit-user.png)
+
+(user-group-membership)=
+
+### Editing group membership
+
+When editing a user, the groups that user is a member of may be modified within
+the "Groups" section. By default, only groups that the user is already a member
+of will be displayed. If you have permission to modify the user's membership
+within a group, an "X" icon will be available next to that group's name.
+Clicking the "X" will remove the user from that group, taking effect after the
+user is saved.
+
+To add users to a group, the arrow next to the list of groups must be clicked
+to expand the section and reveal all available groups. Available groups may
+then be checked/unchecked to modify the user's membership within those groups:
+
+![Editing group membership of a user](images/edit-user-membership.png)
+
+If you have a large number of available groups, you can also enter search terms
+within the "Filter" field to filter the list of groups by name.
+
+(user-group-management)=
+
+User group management
+---------------------
+
+Clicking "Groups" within the list of settings sections will take you to the
+user group management screen. Here you can add new groups and edit the
+properties and privileges of existing groups. If you have a large number of
+user groups, you can also enter search terms within the "Filter" field to
+filter the list of groups by name:
+
+![User group management interface](images/manage-groups.png)
+
+To add a new group, click the "New Group" button. This will take you to a
+screen where you will be allowed to enter the details of the new group,
+including membership and any permissions that members of the group should have.
+
+To edit a group, just click on the group you wish to edit. You will be taken to
+a screen which allows you to modify membership, add or remove administrative
+permissions, and add or remove read access to specific connections, sharing
+profiles, or connection groups. If you are managing a large number of
+connections or groups and wish to reduce the size of the list displayed, you
+can do so by specifying search terms within the "Filter" field. Connection
+groups will be filtered by name and connections will be filtered by name or
+protocol.
+
+If you have delete permission on the group, you will also see a "Delete"
+button. Clicking this button will permanently delete the group.  Alternatively,
+if you only wish to temporarily disable the effects of membership in the group,
+checking "Disabled" will achieve the same effect while not removing the group
+entirely.

Review comment:
       Given recent queries on the mailing list, is it worth noting (more explicitly), here, that disabling a group does not block logins by members of that group?

##########
File path: src/installing-guacamole.md
##########
@@ -0,0 +1,741 @@
+Installing Guacamole natively
+=============================
+
+Guacamole is separated into two pieces: guacamole-server, which provides the
+guacd proxy and related libraries, and guacamole-client, which provides the
+client to be served by your servlet container, usually [Apache
+Tomcat](http://tomcat.apache.org/).
+
+guacamole-client is available in binary form, but guacamole-server must be
+built from source. Don't be discouraged: building the components of Guacamole
+from source is *not* as difficult as it sounds, and the build process is
+automated. You just need to be sure you have the necessary tools installed
+ahead of time. With the necessary dependencies in place, building Guacamole
+only takes a few minutes.
+
+(building-guacamole-server)=
+
+Building guacamole-server
+-------------------------
+
+guacamole-server contains all the native, server-side components required by
+Guacamole to connect to remote desktops. It provides a common C library,
+libguac, which all other native components depend on, as well as separate
+libraries for each supported protocol, and guacd, the heart of Guacamole.
+
+guacd is the proxy daemon that runs on your Guacamole server, accepts users'
+connections that are tunneled through the Guacamole web application, and then
+connects to remote desktops on their behalf. Building guacd creates an
+executable called {program}`guacd` which can be run manually or, if you wish,
+automatically when your computer starts up.
+
+To build guacamole-server, you will need a C compiler (such as gcc) and the
+libraries that guacamole-server depends on. Some dependencies are absolutely
+required, while others are optional. The presence of optional dependencies
+enables additional features.
+
+:::{important}
+Many Linux distributions separate library packages into binary and
+"development" packages; *you will need to install the development packages*.
+These will usually end in a "-dev" or "-devel" suffix.
+:::
+
+### Required dependencies
+
+In order to build guacamole-server, you will need Cairo, libjpeg,
+libpng, and the OSSP UUID library. These libraries are strictly required
+*in all cases* - Guacamole cannot be built without them.
+
+
+[Cairo](http://cairographics.org/)
+: Cairo is used by libguac for graphics rendering.  Guacamole cannot function
+  without Cairo installed.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libcairo2-dev`
+  * - Fedora / CentOS / RHEL package
+    - `cairo-devel`
+  :::
+
+[libjpeg-turbo](http://libjpeg-turbo.virtualgl.org/)
+: libjpeg-turbo is used by libguac to provide JPEG support. Guacamole will not
+  build without this library present:
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian package
+    - `libjpeg62-turbo-dev`
+  * - Ubuntu package
+    - `libjpeg-turbo8-dev`
+  * - Fedora / CentOS / RHEL package
+    - `libjpeg-turbo-devel`
+  :::
+
+  If libjpeg-turbo is unavailable on your platform, and you do not wish to
+  build it from source, [libjpeg](http://www.ijg.org/) will work as well,
+  though it will not be quite as fast:
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libjpeg62-dev`
+  * - Fedora / CentOS / RHEL package
+    - `libjpeg-devel`
+  :::
+
+[libpng](http://www.libpng.org/pub/png/libpng.html)
+: libpng is used by libguac to write PNG images, the core image type used by
+  the Guacamole protocol. Guacamole cannot function without libpng.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libpng12-dev`
+  * - Fedora / CentOS / RHEL package
+    - `libpng-devel`
+  :::
+
+[libtool](https://www.gnu.org/software/libtool/manual/libtool.html)
+: libtool is used during the build process. libtool creates compiled libraries
+  needed for Guacamole.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libtool-bin`
+  * - Fedora / CentOS / RHEL package
+    - `libtool`
+  :::
+
+libuuid (part of [util-linux](https://www.kernel.org/pub/linux/utils/util-linux/))
+: libuuid is used by libguac to assign unique, internal IDs to each Guacamole
+  user and connection. These unique IDs are the basis for connection sharing
+  support.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `uuid-dev`
+  * - Fedora / CentOS / RHEL package
+    - `libuuid-devel`
+  :::
+
+  If libuuid is unavailable, the [OSSP UUID](http://www.ossp.org/pkg/lib/uuid/)
+  library may also be used:
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libossp-uuid-dev`
+  * - Fedora / CentOS / RHEL package
+    - `uuid-devel`
+  :::
+
+### Optional dependencies
+
+The optional dependencies of Guacamole dictate which parts of guacamole-server
+will be built. This includes the support for various remote desktop protocols,
+as well as any additional features of those protocols:
+
+* VNC support depends on the libvncclient library, which is part of
+  libVNCServer.
+
+* RDP support depends on a recent version of FreeRDP (2.0.0 or higher, but
+  please *not a non-release version from git*).
+
+* SSH support depends on libssh2, OpenSSL and Pango (a font rendering and text
+  layout library, used by Guacamole's built-in terminal emulator).
+
+* Telnet depends on libtelnet and Pango.
+
+* Kubernetes support depends on libwebsockets, OpenSSL, and Pango.
+
+The `guacenc` utility, provided by guacamole-server to translate screen
+recordings into video, depends on FFmpeg, and will only be built if at least
+the libavcodec, libavformat, libavutil, and libswscale libraries provided by
+FFmpeg are installed.
+
+:::{important}
+If you lack these dependencies, *then the features or protocols which
+depend on them will not be enabled*. Please read this section
+carefully before deciding not to install an optional dependency.
+:::
+
+[FFmpeg](https://ffmpeg.org/)
+: The libavcodec, libavformat, libavutil, and libswscale libraries provided by
+  FFmpeg are used by `guacenc` to encode video streams when translating
+  recordings of Guacamole sessions. Without FFmpeg, the `guacenc` utility will
+  simply not be built.
+
+  If you do not wish to make graphical recordings of Guacamole sessions, or do
+  not wish to translate such recordings into video, then FFmpeg is not needed.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libavcodec-dev`, `libavformat-dev`, `libavutil-dev`, `libswsccale-dev`
+  * - Fedora / CentOS / RHEL package
+    - `ffmpeg-devel`
+  :::
+
+[FreeRDP](http://www.freerdp.com/)
+: FreeRDP 2.0.0 or later is required for RDP support. If you do not wish to
+  build RDP support, this library is not needed.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `freerdp2-dev`
+  * - Fedora / CentOS / RHEL package
+    - `freerdp-devel`
+  :::
+
+[Pango](http://www.pango.org/)
+: Pango is a text layout library which Guacamole uses to render text for
+  protocols that require a terminal (Kubernetes, SSH, and telnet). If you do
+  not wish to build any terminal-based protocol support, this library is not
+  needed.
+
+  :::{list-table}
+  :stub-columns: 1
+  * - Debian / Ubuntu package
+    - `libpango1.0-dev`
+  * - Fedora / CentOS / RHEL package
+    - `pango-devel`
+  :::
+
+[libssh2](http://www.libssh2.org/)
+: libssh2 is required for SSH support. If you do not wish to build SSH support,
+  this library is not needed.

Review comment:
       Might be worth noting that this is both SSH support and also for SFTP file transfer support?

##########
File path: src/jdbc-auth.md
##########
@@ -0,0 +1,1834 @@
+Database authentication
+=======================
+
+Guacamole supports authentication via MySQL, PostgreSQL, or SQL Server
+databases through extensions available from the project website. Using a
+database for authentication provides additional features, such as the ability
+to use load balancing groups of connections and a web-based administrative
+interface. Unlike the default, XML-driven authentication module, all changes to
+users and connections take effect immediately; users need not logout and back
+in to see new connections.
+
+While most authentication extensions function independently, the database
+authentication can act in a subordinate role, allowing users and user groups
+from other authentication extensions to be associated with connections within
+the database. Users and groups are considered identical to those within the
+database if they have the same names, and the authentication result of another
+extension will be trusted if it succeeds. A user with an account under multiple
+systems will thus be able to see data from each system after successfully
+logging in. For more information on using the database authentication alongside
+other mechanisms, see [](ldap-and-database) within [](ldap-auth).
+
+To use the database authentication extension, you will need:
+
+1. A supported database - currently MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+2. Sufficient permission to create new databases, to create new users, and to
+   grant those users permissions.
+
+3. Network access to the database from the Guacamole server.
+
+:::{important}
+This chapter involves modifying the contents of `GUACAMOLE_HOME` - the
+Guacamole configuration directory. If you are unsure where `GUACAMOLE_HOME` is
+located on your system, please consult [](configuring-guacamole) before
+proceeding.
+:::
+
+Downloading the database authentication extension
+-------------------------------------------------
+
+The database authentication extension is available separately from the main
+`guacamole.war`. The link for this and all other officially-supported and
+compatible extensions for a particular version of Guacamole are provided on the
+release notes for that version. You can find the release notes for current
+versions of Guacamole here: <http://guacamole.apache.org/releases/>.
+
+The database authentication extension is packaged as a `.tar.gz` file
+containing several database-specific directories. Only one of the directories
+within the archive will be applicable to you, depending on whether you are
+using MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+Each database-specific directory contains a `schema/` directory and `.jar` file
+(the actual Guacamole extension). The Guacamole extension `.jar` will
+ultimately need to be placed within `GUACAMOLE_HOME/extensions`, while the JDBC
+driver must be downloaded separately from the database vendor and placed within
+`GUACAMOLE_HOME/lib`.
+
+::::{tab} MySQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `mysql/guacamole-auth-jdbc-mysql-1.3.0.jar`
+* - SQL schema scripts
+  - `mysql/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following MySQL-compatible JDBC drivers are supported for connecting Guacamole with MySQL or MariaDB:
+
+* [MySQL Connector/J](http://dev.mysql.com/downloads/connector/j/)
+* [MariaDB Connector/J](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+
+If using the JDBC driver from MySQL, the required `.jar` will be within a
+`.tar.gz` archive.
+::::
+
+::::{tab} PostgreSQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `postgresql/guacamole-auth-jdbc-postgresql-1.3.0.jar`
+* - SQL schema scripts
+  - `postgresql/schema/`
+* - JDBC driver
+  - [PostgreSQL JDBC Driver](https://jdbc.postgresql.org/download.html#current)
+:::
+::::
+
+::::{tab} SQL Server
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `sqlserver/guacamole-auth-jdbc-sqlserver-1.3.0.jar`
+* - SQL schema scripts
+  - `sqlserver/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following TDS-compatible JDBC drivers are supported for connecting
+Guacamole to SQL Server:
+
+* [Microsoft JDBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server)
+* [jTDS](http://jtds.sourceforge.net/)
+* [Progress DataDirect’s JDBC Driver for SQL Server](https://www.progress.com/jdbc/microsoft-sql-server)
+* Microsoft SQL Server 2000 JDBC Driver (legacy)
+::::
+
+(jdbc-auth-database-creation)=
+
+Creating the Guacamole database
+-------------------------------
+
+The database authentication module will need a database to store
+authentication data and a user to use only for data access and
+manipulation. You can use an existing database and existing user, but
+for the sake of simplicity and security, these instructions assume you
+will be creating a new database and new user that will be used only by
+Guacamole and only for this authentication module.
+
+You need MariaDB, MySQL, PostgreSQL, or SQL Server installed, and must
+have sufficient access to create and administer databases. If this is
+not the case, install your database of choice now. Most distributions
+will provide a convenient MySQL or PostgreSQL package which will set up
+everything for you, including the root database user, if applicable. If
+you're using SQL Server, you need to install the packages on your
+platform of choice, and also make sure that you obtain the proper
+licensing for the version and edition of SQL Server you are running.
+
+For the sake of clarity, these instructions will refer to the database
+as "guacamole_db", but the database can be named whatever you like.
+
+:::{tab} MySQL
+```console
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql  upgrade
+$ cat schema/*.sql | mysql -u root -p guacamole_db
+Enter password: password
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ createdb guacamole_db
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql
+$ cat schema/*.sql | psql -d guacamole_db -f -
+CREATE TYPE
+CREATE TYPE
+CREATE TYPE
+CREATE TABLE
+CREATE INDEX
+...
+INSERT 0 1
+INSERT 0 4
+INSERT 0 3
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/001-create-schema.sql
+Password: password
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/002-create-admin-user.sql
+Password: password
+
+(1 rows affected)
+
+(3 rows affected)
+
+(5 rows affected)
+```
+:::
+
+Upgrading an existing Guacamole database
+----------------------------------------
+
+If you are upgrading from an older version of Guacamole, you may need to run
+one or more database schema upgrade scripts located within the
+`schema/upgrade/` directory. Each of these scripts is named
+{samp}`upgrade-pre-{VERSION}.sql` where `VERSION` is the version of Guacamole
+where those changes were introduced. They need to be run when you are upgrading
+from a version of Guacamole older than `VERSION`.
+
+If there are no {samp}`upgrade-pre-{VERSION}.sql` scripts present in the
+`schema/upgrade/` directory which apply to your existing Guacamole database,
+then the schema has not changed between your version and the version your are
+installing, and there is no need to run any database upgrade scripts.
+
+These scripts are incremental and, when relevant, *must be run in order*. For
+example, if you are upgrading an existing database from version
+0.9.13-incubating to version 1.0.0, you would need to run the
+`upgrade-pre-0.9.14.sql` script (because 0.9.13-incubating is older than
+0.9.14), followed by the `upgrade-pre-1.0.0.sql` script (because
+0.9.13-incubating is also older than 1.0.0).
+
+:::{important}
+Because the permissions granted to the Guacamole-specific PostgreSQL user when
+the database was first created will not automatically be granted for any new
+tables and sequences, you will also need to re-grant those permissions after
+applying any upgrade relevant scripts:
+
+```
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+Granting Guacamole access to the database

Review comment:
       I feel like the "Granting Guacamole access to the database" section might be more appropriate before the "Upgrading an existing Guacamole database section," particularly since the Upgrading section ends with instructions for granting additional permissions. I'm not feeling particularly ornery about this, just a thought.

##########
File path: src/guacamole-common-js.md
##########
@@ -0,0 +1,379 @@
+guacamole-common-js
+===================
+
+The Guacamole project provides a JavaScript API for interfacing with other
+components that conform to the design of Guacamole, such as projects using
+libguac or guacamole-common. This API is called guacamole-common-js.
+
+guacamole-common-js provides a JavaScript implementation of a Guacamole client,
+as well as tunneling mechanisms for getting protocol data out of JavaScript and
+into guacd or the server side of a web application.
+
+For convenience, it also provides mouse and keyboard abstraction objects that
+translate JavaScript mouse, touch, and keyboard events into consistent data
+that Guacamole can more easily digest. The extendable on-screen keyboard that
+was developed for the Guacamole web application is also included.
+
+Guacamole client
+----------------
+
+The main benefit to using the JavaScript API is the full Guacamole client
+implementation, which implements all Guacamole instructions, and makes use of
+the tunnel implementations provided by both the JavaScript and Java APIs.
+
+Using the Guacamole client is straightforward. The client, like all other
+objects within the JavaScript API, is within the `Guacamole` namespace. It is
+instantiated given an existing, unconnected tunnel:
+
+```javascript
+var client = new Guacamole.Client(tunnel);
+```
+
+Once you have the client, it won't immediately appear within the DOM. You need
+to add its display element manually:
+
+```javascript
+document.body.appendChild(client.getDisplay().getElement());
+```
+
+At this point, the client will be visible, rendering all updates as soon as
+they are received through the tunnel.
+
+```javascript
+client.connect();
+```
+
+It is possible to pass arbitrary data to the tunnel during connection which can
+be used for authentication or for choosing a particular connection. When the
+`connect()` function of the Guacamole client is called, it in turn calls the
+`connect()` function of the tunnel originally given to the client, establishing
+a connection.
+
+:::{important}
+When creating the `Guacamole.Client`, the tunnel used must not already be
+connected. The `Guacamole.Client` will call the `connect()` function for you
+when its own `connect()` function is invoked. If the tunnel is already
+connected when it is given to the `Guacamole.Client`, connection may not work
+at all.
+:::
+
+In general, all instructions available within the Guacamole protocol are
+automatically handled by the Guacamole client, including instructions related
+to audio and video. The only instructions which you must handle yourself are
+"name" (used to name the connection), "clipboard" (used to update clipboard
+data on the client side), and "error" (used when something goes wrong
+server-side). Each of these instructions has a corresponding event handler; you
+need only supply functions to handle these events. If any of these event
+handlers are left unset, the corresponding instructions are simply ignored.
+
+HTTP tunnel
+-----------
+
+Both the Java and JavaScript API implement corresponding ends of an HTTP
+tunnel, based on `XMLHttpRequest`.
+
+The tunnel is a true stream - there is no polling. An initial request is made
+from the JavaScript side, and this request is handled on the Java side. While
+this request is open, data is streamed along the connection, and instructions
+within this stream are handled as soon as they are received by the client.
+
+While data is being streamed along this existing connection, a second
+connection attempt is made. Data continues to be streamed along the original
+connection until the server receives and handles the second request, at which
+point the original connection closes and the stream is transferred to the new
+connection.
+
+This process repeats, alternating between active streams, thus creating an
+unbroken sequence of instructions, while also allowing JavaScript to free any
+memory used by the previously active connection.
+
+The tunnel is created by supplying the relative URL to the server-side tunnel
+servlet:
+
+```javascript
+var tunnel = new Guacamole.Tunnel("tunnel");
+```
+
+Once created, the tunnel can be passed to a `Guacamole.Client` for use in a
+Guacamole connection.
+
+The tunnel actually takes care of the Guacamole protocol parsing on behalf of
+the client, triggering "oninstruction" events for every instruction received,
+splitting each element into elements of an array so that the client doesn't
+have to.
+
+Input abstraction
+-----------------
+
+Browsers can be rather finicky when it comes to keyboard and mouse input, not
+to mention touch events. There is little agreement on which keyboard events get
+fired when, and what detail about the event is made available to JavaScript.
+Touch and mouse events can also cause confusion, as most browsers will generate
+*both* events when the user touches the screen (for compatibility with
+JavaScript code that only handles mouse events), making it more difficult for
+applications to support both mouse and touch independently.
+
+The Guacamole JavaScript API abstracts mouse, keyboard, and touch interaction,
+providing several helper objects which act as an abstract interface between you
+and the browser events.
+
+(guacamole-mouse)=
+
+### Mouse
+
+Mouse event abstraction is provided by the `Guacamole.Mouse` object.  Given an
+arbitrary DOM element, `Guacamole.Mouse` triggers onmousedown, onmousemove, and
+onmouseup events which are consistent across browsers. This object only
+response. to true mouse events. Mouse events which are actually the result of

Review comment:
       _responds_, maybe?

##########
File path: src/introduction.md
##########
@@ -0,0 +1,161 @@
+Introduction
+============
+
+This book is the official Apache Guacamole manual, written by the upstream
+developers of the Guacamole project. It is also the official general
+documentation, and an online version at <http://guacamole.apache.org/>. It is a

Review comment:
       and an online version _is available_ at ?

##########
File path: src/custom-protocols.md
##########
@@ -0,0 +1,828 @@
+Adding new protocols
+====================
+
+Guacamole's support for multiple remote desktop protocols is provided through
+plugins which guacd loads dynamically. The Guacamole API has been designed such
+that protocol support is easy to create, especially when a C library exists
+providing a basic client implementation.
+
+In this tutorial, we will implement a simple "client" which renders a bouncing
+ball using the Guacamole protocol. After completing the tutorial and installing
+the result, you will be able to add a connection to your Guacamole
+configuration using the "ball" protocol, and any users using that connection
+will see a bouncing ball.
+
+This example client plugin doesn't actually act as a client, but this isn't
+important. The Guacamole client is really just a remote display, and this
+client plugin functions as a simple example application which renders to this
+display, just as Guacamole's own VNC or RDP plugins function as VNC or RDP
+clients which render to the remote display.
+
+Each step of this tutorial is intended to exercise a new concept, while also
+progressing towards the goal of a nifty bouncing ball. At the end of each step,
+you will have a buildable and working client plugin.
+
+This tutorial will use the GNU Automake build system, which is the build system
+used by Guacamole for libguac, guacd, etc. There will be four files involved:
+
+`configure.ac`
+: Used by GNU Automake to generate the `configure` script which ultimately
+  serves to generate the `Makefile` which {command}`make` will use when
+  building.
+
+`Makefile.am`
+: Used by GNU Automake and the `configure` script to generate the `Makefile`
+  which {command}`make` will use when building.
+
+`src/ball.c`
+: The main body of code defining the bouncing ball "client".
+
+`src/ball.h`
+: A header file defining the structure representing the state of the bouncing
+  ball (once it becomes necessary to do so).
+
+All source files will be within the `src` subdirectory, as is common with C
+projects, with build files being at the root level directory. The main
+`src/ball.c` and the build-related `configure.ac` and `Makefile.am` files will
+be created first, with each successive step building upon those files
+iteratively, with `src/ball.h` being added when it becomes necessary. After
+each step, you can build/rebuild the plugin by running {command}`make`, and
+then install it (such that guacd can find the plugin) by running {command}`make
+install` and {command}`ldconfig` as root:
+
+```console
+$ make
+  CC       src/ball.lo
+  CCLD     libguac-client-ball.la
+# make install
+make[1]: Entering directory '/home/user/libguac-client-ball'
+ /usr/bin/mkdir -p '/usr/local/lib'
+ /bin/sh ./libtool   --mode=install /usr/bin/install -c   libguac-client-ball.la '/usr/local/lib'
+...
+----------------------------------------------------------------------
+Libraries have been installed in:
+   /usr/local/lib
+
+If you ever happen to want to link against installed libraries
+in a given directory, LIBDIR, you must either use libtool, and
+specify the full pathname of the library, or use the '-LLIBDIR'
+flag during linking and do at least one of the following:
+   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
+     during execution
+   - add LIBDIR to the 'LD_RUN_PATH' environment variable
+     during linking
+   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
+   - have your system administrator add LIBDIR to '/etc/ld.so.conf'
+
+See any operating system documentation about shared libraries for
+more information, such as the ld(1) and ld.so(8) manual pages.
+----------------------------------------------------------------------
+make[1]: Nothing to be done for 'install-data-am'.
+make[1]: Leaving directory '/home/user/libguac-client-ball'
+# ldconfig
+```
+
+Prior to the first time {command}`make` is invoked, you will need to run the
+`configure` script, which will first need to be generated using
+{command}`autoreconf`:
+
+```console
+$ autoreconf -fi
+libtoolize: putting auxiliary files in '.'.
+libtoolize: copying file './ltmain.sh'
+libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
+libtoolize: copying file 'm4/libtool.m4'
+libtoolize: copying file 'm4/ltoptions.m4'
+libtoolize: copying file 'm4/ltsugar.m4'
+libtoolize: copying file 'm4/ltversion.m4'
+libtoolize: copying file 'm4/lt~obsolete.m4'
+configure.ac:10: installing './compile'
+configure.ac:4: installing './missing'
+Makefile.am: installing './depcomp'
+$ ./configure
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+...
+configure: creating ./config.status
+config.status: creating Makefile
+config.status: executing depfiles commands
+config.status: executing libtool commands
+$
+```
+
+This process is almost identical to that of building guacamole-server from git,
+as documented in [](building-guacamole-server).
+
+:::{important}
+The libguac library which is part of guacamole-server is a required dependency
+of this project. *You must first install libguac, guacd, etc. by [building and
+installing guacamole-server](building-guacamole-server)*. If guacamole-server
+has not been installed, and libguac is thus not present, the `configure` script
+will fail with an error indicating that it could not find libguac:
+
+```console
+$ ./configure
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+...
+checking for guac_client_stream_png in -lguac... no
+configure: error: "libguac is required for communication via "
+                   "the Guacamole protocol"
+$
+```
+
+You will need to install guacamole-server and then rerun `configure`.
+:::
+
+(libguac-client-ball-skeleton)=
+
+Minimal skeleton client
+-----------------------
+
+Very little needs too be done to implement the most basic client plugin
+possible. We begin with `src/ball.c`, containing the absolute minimum required
+for a client plugin:
+
+```c
+#include <guacamole/client.h>
+
+#include <stdlib.h>
+
+/* Client plugin arguments (empty) */
+const char* TUTORIAL_ARGS[] = { NULL };
+
+int guac_client_init(guac_client* client) {
+
+    /* This example does not implement any arguments */
+    client->args = TUTORIAL_ARGS;
+
+    return 0;
+
+}
+```
+
+Notice the structure of this file. There is exactly one function,
+`guac_client_init`, which is the entry point for all Guacamole client plugins.
+Just as a typical C program has a main function which is executed when the
+program is run, a Guacamole client plugin has `guac_client_init` which is
+called when guacd loads the plugin when a new connection is made and your
+protocol is selected.
+
+`guac_client_init` receives a single `guac_client` which it must initialize.
+Part of this initialization process involves declaring the list of arguments
+that joining users can specify. While we won't be using arguments in this
+tutorial, and thus the arguments assigned above are simply an empty list, a
+typical client plugin implementation would register arguments which define the
+remote desktop connection and its behavior. Examples of such parameters can be
+seen in the connection parameters for the protocols supported by Guacamole
+out-of-the-box (see [](connection-configuration)).
+
+The `guac_client` instance given to `guac_client_init` will be shared by the
+user that starts the connection, and any users which join the connection via
+screen sharing. It lives until the connection is explicitly closed, or until
+all users leave the connection.
+
+For this project to build with GNU Automake, we a `configure.ac` file which
+describes the name of the project and what it needs configuration-wise.  In
+this case, the project is "libguac-client-ball", and it depends on the
+"libguac" library used by guacd and all client plugins:
+
+```
+# Project information
+AC_PREREQ([2.61])
+AC_INIT([libguac-client-ball], [0.1.0])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
+AM_SILENT_RULES([yes])
+
+AC_CONFIG_MACRO_DIRS([m4])
+
+# Check for required build tools
+AC_PROG_CC
+AC_PROG_CC_C99
+AC_PROG_LIBTOOL
+
+# Check for libguac
+AC_CHECK_LIB([guac], [guac_client_stream_png],,
+      AC_MSG_ERROR("libguac is required for communication via "
+                   "the Guacamole protocol"))
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+```
+
+We also need a `Makefile.am`, describing which files should be built and how
+when building libguac-client-ball:
+
+```
+AUTOMAKE_OPTIONS = foreign
+
+ACLOCAL_AMFLAGS = -I m4
+AM_CFLAGS = -Werror -Wall -pedantic
+
+lib_LTLIBRARIES = libguac-client-ball.la
+
+# All source files of libguac-client-ball
+libguac_client_ball_la_SOURCES = src/ball.c
+
+# libtool versioning information
+libguac_client_ball_la_LDFLAGS = -version-info 0:0:0
+```
+
+The GNU Automake files will remain largely unchanged throughout the rest of the
+tutorial.
+
+Once you have created all of the above files, you will have a functioning
+client plugin. It doesn't do anything yet, and any connection will be extremely
+short-lived (the lack of any data sent by the server will lead to the client
+disconnecting under the assumption that the connection has stopped responding),
+but it does technically work.
+
+(libguac-client-ball-display-init)=
+
+Initializing the remote display
+-------------------------------
+
+Now that we have a basic functioning skeleton, we need to actually do something
+with the remote display. A good first step would be simply initializing the
+display - setting the remote display size and providing a basic background.
+
+In this case, we'll set the display to a nice default of 1024x768, and fill the
+background with gray. Though the size of the display *can* be chosen based on
+the size of the user's browser window (which is provided by the user during the
+[Guacamole protocol handshake](guacamole-protocol-handshake), or even updated
+when the window size changes (provided by the user via ["size"
+instructions](client-size-instruction)), we won't be doing that here for the
+simplicity's sake:

Review comment:
       _for simplicity's sake_

##########
File path: src/administration.md
##########
@@ -0,0 +1,314 @@
+Administration
+==============
+
+Users, user groups, connections, and active sessions can be administered from
+within the web interface if the underlying authentication module supports this.
+The only officially-supported authentication modules supporting this are the
+database extensions, which are documented in [](jdbc-auth).
+
+If you are using the default authentication mechanism, or another
+authentication extension, this chapter probably does not apply to you, and the
+management options will not be visible in the Guacamole interface. If, on the
+other hand, you are using one of the database authentication providers, and you
+are logged in as a user with sufficient privileges, you will see management
+sections listed within the settings screen:
+
+![Sections within the Guacamole settings screen.](images/guacamole-settings-sections.png)
+
+Clicking any of these options will take you to a corresponding management
+section where you can perform administrative tasks.
+
+(session-management)=
+
+Managing sessions
+-----------------
+
+Clicking "Active Sessions" navigates to the session management screen.  The
+session management screen displays all active sessions and allows system
+administrators to kill them as needed.
+
+When any user accesses a particular remote desktop connection, a unique session
+is created and will appear in the list of active sessions in the session
+management screen. Each active session is displayed in a sortable table,
+showing the corresponding user's username, how long the session has been
+active, the IP address of the machine from which the user is connecting, and
+the name of the connection being used.
+
+![Session management interface](images/manage-sessions.png)
+
+To kill one or more sessions, select the sessions by clicking their checkboxes.
+Once all desired sessions have been selected, clicking "Kill Sessions" will
+immediately disconnect those users from the associated connection.
+
+(filtering-sessions)=
+
+### Filtering and sorting
+
+The table can be resorted by clicking on the column headers. Clicking any
+column will resort the table by the values within that column, while clicking a
+column which is already sorted will toggle between ascending and descending
+order.
+
+The content of the table can be limited through search terms specified in the
+"Filter" field. Entering search terms will limit the table to only sessions
+containing those terms. For example, to list only connections by the user
+"guacadmin" which have been active since March, 2015, you would enter:
+"guacadmin 2015-03". Beware that if a search term needs to contain spaces, it
+must be enclosed in double quotes to avoid being interpreted as multiple terms.
+
+![](images/session-filter-example-1.png)
+
+If you wish to narrow the content of the table to only those connections which
+originate from a particular block of IP addresses, you can do this by
+specifying the block in standard CIDR notation, such "10.0.0.0/8" or
+"2001:db8:1234::/48". This will work with both IPv4 and IPv6 addresses.
+
+![](images/session-filter-example-2.png)
+
+Connection history
+------------------
+
+Clicking "History" navigates to the connection history screen. The connection
+history screen displays a table of the most recent connections, including the
+user that used that connection, the time the connection began, and how long the
+connection was used.
+
+![Connection history interface](images/manage-history.png)
+
+(filtering-history)=
+
+### Filtering and sorting
+
+Initially, the connection history table will display only the most recent
+history records. You can page through these records to see how and when
+Guacamole has been used.
+
+Just as with the table of active sessions described earlier, the table of
+history records can be resorted by clicking on the column headers or filtered
+by entering search terms within the "Filter" field.
+
+The same filtering format applies - a search term containing spaces must be
+enclosed in double quotes to avoid being interpreted as multiple terms, and
+only history records which contain each term will be included in the history
+table. Unlike the table of active sessions, however, the filter will only take
+effect once you click the "Search" button. This is due to the nature of the
+connection history, as the number of records may be quite extensive.
+
+(user-management)=
+
+User management
+---------------
+
+Clicking "Users" within the list of settings sections will take you to the user
+management screen. Here you can add new users, edit the properties and
+privileges of existing users, and view the times that each user last logged in.
+If you have a large number of users, you can also enter search terms within the
+"Filter" field to filter the list of users by username.
+
+To add a new user, click the "New User" button. This will take you to a screen
+where you will be allowed to enter the details of the new user, such as the
+password and username. Note that, unless you specify otherwise, the new user
+will have no access to any existing connections, nor any administrative
+privileges, and you will need to manually set the user's password before they
+will be able to log in.
+
+![User management interface](images/manage-users.png)
+
+To edit a user, just click on the user you wish to edit. You will be taken to a
+screen which allows you to change the user's password, expire their password
+(such that it must be changed at next login), add or remove administrative
+permissions, and add or remove read access to specific connections, sharing
+profiles, or groups. If you are managing a large number of connections or
+groups and wish to reduce the size of the list displayed, you can do so by
+specifying search terms within the "Filter" field. Groups will be filtered by
+name and connections will be filtered by name or protocol.
+
+If you have delete permission on the user, you will also see a "Delete" button.
+Clicking this button will permanently delete the user.  Alternatively, if you
+only wish to temporarily disable the account, checking "Login disabled" will
+achieve the same effect while not removing the user entirely. If they attempt
+to log in, the attempt will be rejected as if their account did not exist at
+all.
+
+![Editing a user](images/edit-user.png)
+
+(user-group-membership)=
+
+### Editing group membership
+
+When editing a user, the groups that user is a member of may be modified within
+the "Groups" section. By default, only groups that the user is already a member
+of will be displayed. If you have permission to modify the user's membership
+within a group, an "X" icon will be available next to that group's name.
+Clicking the "X" will remove the user from that group, taking effect after the
+user is saved.
+
+To add users to a group, the arrow next to the list of groups must be clicked
+to expand the section and reveal all available groups. Available groups may
+then be checked/unchecked to modify the user's membership within those groups:
+
+![Editing group membership of a user](images/edit-user-membership.png)
+
+If you have a large number of available groups, you can also enter search terms
+within the "Filter" field to filter the list of groups by name.
+
+(user-group-management)=
+
+User group management
+---------------------
+
+Clicking "Groups" within the list of settings sections will take you to the
+user group management screen. Here you can add new groups and edit the
+properties and privileges of existing groups. If you have a large number of
+user groups, you can also enter search terms within the "Filter" field to
+filter the list of groups by name:
+
+![User group management interface](images/manage-groups.png)
+
+To add a new group, click the "New Group" button. This will take you to a
+screen where you will be allowed to enter the details of the new group,
+including membership and any permissions that members of the group should have.
+
+To edit a group, just click on the group you wish to edit. You will be taken to
+a screen which allows you to modify membership, add or remove administrative
+permissions, and add or remove read access to specific connections, sharing
+profiles, or connection groups. If you are managing a large number of
+connections or groups and wish to reduce the size of the list displayed, you
+can do so by specifying search terms within the "Filter" field. Connection
+groups will be filtered by name and connections will be filtered by name or
+protocol.
+
+If you have delete permission on the group, you will also see a "Delete"
+button. Clicking this button will permanently delete the group.  Alternatively,
+if you only wish to temporarily disable the effects of membership in the group,
+checking "Disabled" will achieve the same effect while not removing the group
+entirely.
+
+![Editing a user group](images/edit-user-group.png)
+
+### Group membership of groups
+
+Managing the group membership of groups is more complex than that of users, as
+groups may contain both users and groups, with permissions from parent groups
+possibly being inherited. Parent groups, member groups, and member users, can
+all be managed identically to the [group memberships of users](user-group-membership),
+with a corresponding section dedicated to each within the user group editor:
+
+![Editing the various membership relations of a user group](images/edit-group-memberships.png)
+
+Note that it is ultimately up to the extension providing the group to determine
+how permissions granted to that group are inherited, if at all. The [database
+authentication extension](jdbc-auth) implements full recursive inheritance of
+group permissions, with permissions granted to a group being granted to all
+members/descendants of that group, regardless of how deeply those members are
+nested.
+
+(connection-management)=
+
+Connections and connection groups
+---------------------------------
+
+Clicking "Connections" within the list of settings sections will take you to
+the connection management screen. The connection management screen allows
+administrators to create and edit connections, sharing profiles, and connection
+groups. If you have a large number of connections, you can also enter search
+terms within the "Filter" field to filter the list of connections by name or
+protocol.
+
+To add a new connection or connection group, click the "New Connection" or "New
+Group" button, or the "New Connection" or "New Group" placeholders which appear
+when you expand an existing connection group.  These options will take you to a
+screen where you will be allowed to enter the details of the new object, such
+as its location, parameters, and name. This name should be descriptive, but
+must also be unique with respect to other objects in the same location.
+
+Once you click "Save", the new object will be added, but will initially only be
+usable by administrators and your current user. To grant another user access to
+the new connection or connection group, you must [edit that user](user-management)
+or [a user group that the user is a member of](user-group-management), checking
+the box corresponding to the connection or connection group you created.
+
+![Connection management interface](images/manage-connections.png)
+
+Editing connections, sharing profiles, and connection groups works identically
+to editing a user. Click on the object you wish to edit, and you will be taken
+to screen which allows you to edit it. The screen will display all properties
+of the object, including its usage history, if applicable.
+
+If you have delete permission on the object, you will also see a "Delete"
+button. Clicking this button will permanently delete the object being edited.
+
+![Editing a connection](images/edit-connection.png)
+
+(connection-group-management)=
+
+### Connection organization and balancing
+
+Connection groups can be either "organizational" or "balancing". Each group can
+contain any number of other connections or groups, but the semantics of the
+group change depending on the type.
+
+An organizational group behaves exactly as a folder or directory in a file
+system. It simply contains connections and other groups, but provides no other
+behavior. Clicking on an organizational group within a connection list will
+expand the group, revealing its contents.
+
+A balancing group behaves as a connection. It dynamically balances load across
+the connections it contains, choosing the connection with the fewest number of
+active users. Unlike organizational groups, clicking on a balancing group
+causes a new connection to be opened. The actual underlying connection used
+depends on which connection has the least load at the time the group was
+clicked, and whether session affinity is enabled on that group.
+
+Enabling session affinity for a balancing group ensures that users are
+consistently routed to the same underlying connections until they log out of
+Guacamole. The load balancing behavior of the balancing group will apply only
+for the first time a particular user connects to the group. If your users may
+lose their desktop state if they are routed to a different underlying
+connection, this option should be enabled.
+
+![Editing a connection group](images/edit-group.png)
+
+### Connection sharing
+
+The ability to share a connection is governed through the use of "sharing
+profiles". If a sharing profile is created for a connection, users with access
+to both that connection and that sharing profile will be able to share the
+connection with other users by [generating connection sharing
+links](client-share-menu), even if those users do not otherwise have user
+accounts within Guacamole.
+
+The name of the sharing profile will be presented an option within the [share

Review comment:
       will be presented _as_ an option
   
   ??

##########
File path: src/installing-guacamole.md
##########
@@ -0,0 +1,741 @@
+Installing Guacamole natively
+=============================
+
+Guacamole is separated into two pieces: guacamole-server, which provides the
+guacd proxy and related libraries, and guacamole-client, which provides the
+client to be served by your servlet container, usually [Apache
+Tomcat](http://tomcat.apache.org/).
+
+guacamole-client is available in binary form, but guacamole-server must be
+built from source. Don't be discouraged: building the components of Guacamole
+from source is *not* as difficult as it sounds, and the build process is
+automated. You just need to be sure you have the necessary tools installed
+ahead of time. With the necessary dependencies in place, building Guacamole
+only takes a few minutes.
+
+(building-guacamole-server)=
+
+Building guacamole-server
+-------------------------
+
+guacamole-server contains all the native, server-side components required by
+Guacamole to connect to remote desktops. It provides a common C library,
+libguac, which all other native components depend on, as well as separate
+libraries for each supported protocol, and guacd, the heart of Guacamole.
+
+guacd is the proxy daemon that runs on your Guacamole server, accepts users'
+connections that are tunneled through the Guacamole web application, and then
+connects to remote desktops on their behalf. Building guacd creates an
+executable called {program}`guacd` which can be run manually or, if you wish,
+automatically when your computer starts up.
+
+To build guacamole-server, you will need a C compiler (such as gcc) and the
+libraries that guacamole-server depends on. Some dependencies are absolutely
+required, while others are optional. The presence of optional dependencies
+enables additional features.
+
+:::{important}
+Many Linux distributions separate library packages into binary and
+"development" packages; *you will need to install the development packages*.
+These will usually end in a "-dev" or "-devel" suffix.
+:::
+
+### Required dependencies
+
+In order to build guacamole-server, you will need Cairo, libjpeg,
+libpng, and the OSSP UUID library. These libraries are strictly required

Review comment:
       > ...and the OSSP UUID library
   
   This is noted below, but I believe the OSSP library is no longer the "preferred" library, but a suitable alternative? Maybe this should read _a UUID library_ or something similar?

##########
File path: src/configuring-guacamole.md
##########
@@ -0,0 +1,2770 @@
+Configuring Guacamole
+=====================
+
+After installing Guacamole, you need to configure users and connections before
+Guacamole will work. This chapter covers general configuration of Guacamole and
+the use of its default authentication method.
+
+Guacamole's default authentication method reads all users and connections from
+a single file called `user-mapping.xml`. This authentication method is intended
+to be:
+
+1. Sufficient for small deployments of Guacamole.
+
+2. A relatively-easy means of verifying that Guacamole has been properly set
+   up.
+
+Other, more complex authentication methods which use backend databases, LDAP,
+etc. are discussed in a separate, dedicated chapters.
+
+Regardless of the authentication method you use, Guacamole's configuration
+always consists of two main pieces: a directory referred to as
+`GUACAMOLE_HOME`, which is the primary search location for configuration files,
+and `guacamole.properties`, the main configuration file used by Guacamole and
+its extensions.
+
+(guacamole-home)=
+
+`GUACAMOLE_HOME` (`/etc/guacamole`)
+---------------------------------------
+
+`GUACAMOLE_HOME` is the name given to Guacamole's configuration directory,
+which is located at `/etc/guacamole` by default. All configuration files,
+extensions, etc. reside within this directory. The structure of
+`GUACAMOLE_HOME` is rigorously defined, and consists of the following optional
+files:
+
+`guacamole.properties`
+: The main Guacamole configuration file. Properties within this file dictate
+  how Guacamole will connect to guacd, and may configure the behavior of
+  installed authentication extensions.
+
+`logback.xml`
+: Guacamole uses a logging system called Logback for all messages. By
+  default, Guacamole will log to the console only, but you can change this
+  by providing your own Logback configuration file.
+
+`extensions/`
+: The install location for all Guacamole extensions. Guacamole will
+  automatically load all `.jar` files within this directory on startup.
+
+`lib/`
+: The search directory for libraries required by any Guacamole extensions.
+  Guacamole will make the `.jar` files within this directory available to
+  all extensions. If your extensions require additional libraries, such as
+  database drivers, this is the proper place to put them.
+
+(overriding-guacamole-home)=
+
+### Overriding `GUACAMOLE_HOME`
+
+If you cannot or do not wish to use `/etc/guacamole` for `GUACAMOLE_HOME`, the
+location can be overridden through any of the following methods:
+
+1. Creating a directory named `.guacamole`, within the home directory of *the
+   user running the servlet container*. This directory will automatically be
+   used for `GUACAMOLE_HOME` if it exists.
+
+2. Specifying the full path to an alternative directory with the environment
+   variable `GUACAMOLE_HOME`. *Be sure to consult the documentation for your
+   servlet container to determine how to properly set environment variables.*
+
+3. Specifying the full path to an alternative directory with the system
+   property guacamole.home.
+
+(initial-setup)=
+
+`guacamole.properties`
+------------------------
+
+The Guacamole web application uses one main configuration file called
+`guacamole.properties`. This file is the common location for all configuration
+properties read by Guacamole or any extension of Guacamole, including
+authentication providers.
+
+In previous releases, this file had to be in the classpath of your servlet
+container. Now, the location of `guacamole.properties` can be explicitly
+defined with environment variables or system properties, and the classpath is
+only used as a last resort. When searching for `guacamole.properties`,
+Guacamole will check, in order:
+
+1. Within `GUACAMOLE_HOME`, as defined above.
+
+2. The classpath of the servlet container.
+
+The `guacamole.properties` file is optional and is used to configure Guacamole
+in situations where the defaults are insufficient, or to provide additional
+configuration information for extensions. There are several standard properties
+that are always available for use:
+
+`api-session-timeout`
+: The amount of time, in minutes, to allow Guacamole sessions
+  (authentication tokens) to remain valid despite inactivity. If omitted,
+  Guacamole sessions will expire after 60 minutes of inactivity.
+
+`api-max-request-size`
+: The maximum number of bytes to accept within the entity body of any
+  particular HTTP request, where 0 indicates that no limit should be
+  applied. If omitted, requests will be limited to 2097152 bytes (2 MB) by
+  default. This limit does not apply to file uploads.
+
+  If using a reverse proxy for SSL termination, *keep in mind that reverse
+  proxies may enforce their own limits independently of this*. For example,
+  [Nginx will enforce a 1 MB request size limit by
+  default](nginx-file-upload-size).
+
+`allowed-languages`
+: A comma-separated whitelist of language keys to allow as display language
+  choices within the Guacamole interface. For example, to restrict Guacamole
+  to only English and German, you would specify:
+
+  ```
+  allowed-languages: en, de
+  ```
+
+  As English is the fallback language, used whenever a translation key is
+  missing from the chosen language, English should only be omitted from this
+  list if you are absolutely positive that no strings are missing.
+
+  The corresponding JSON of any built-in languages not listed here will
+  still be available over HTTP, but the Guacamole interface will not use
+  them, nor will they be used automatically based on local browser language.
+  If omitted, all defined languages will be available.
+
+`enable-environment-properties`
+: If set to "true", Guacamole will first evaluate its environment to obtain
+  the value for any given configuration property, before using a value
+  specified in `guacamole.properties` or falling back to a default value. By
+  enabling this option, you can easily override any other configuration
+  property using an environment variable.
+
+  ```
+  enable-environment-properties: true
+  ```
+
+  When searching for a configuration property in the environment, the name
+  of the property is first transformed by converting all lower case
+  characters to their upper case equivalents, and by replacing all hyphen
+  characters (`-`) with underscore characters (`_`). For example, the
+  `guacd-hostname` property would be transformed to `GUACD_HOSTNAME` when
+  searching the environment.
+
+`guacd-hostname`
+: The host the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on localhost.
+
+`guacd-port`
+: The port the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on port 4822.
+
+`guacd-ssl`
+: If set to "true", Guacamole will require SSL/TLS encryption between the
+  web application and guacd. By default, communication between the web
+  application and guacd will be unencrypted.
+
+  Note that if you enable this option, you must also configure guacd to use
+  SSL via command line options. These options are documented in the manpage
+  of guacd. You will need an SSL certificate and private key.
+
+`skip-if-unavailable`
+: A comma-separated list of the identifiers of authentication providers that
+  should be allowed to fail internally without aborting the authentication
+  process. For example, to request that Guacamole ignore failures due to the
+  LDAP directory or MySQL server being unexpectedly down, allowing other
+  authentication providers to continue functioning:
+
+  ```
+  skip-if-unavailable: mysql, ldap
+  ```
+
+  By default, Guacamole takes a conservative approach to internal failures,
+  aborting the authentication process if an internal error occurs within any
+  authentication provider. Depending on the nature of the error, this may
+  mean that no users can log in until the cause of the failure is dealt
+  with. The `skip-if-unavailable` property may be used to explicitly inform
+  Guacamole that one or more underlying systems are expected to occasionally
+  experience failures, and that other functioning systems should be relied
+  upon if they do fail.
+
+
+```
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port:     4822
+```

Review comment:
       These lines seem oddly placed. Maybe meant to be up just below where these properties are described?

##########
File path: src/custom-protocols.md
##########
@@ -0,0 +1,828 @@
+Adding new protocols
+====================
+
+Guacamole's support for multiple remote desktop protocols is provided through
+plugins which guacd loads dynamically. The Guacamole API has been designed such
+that protocol support is easy to create, especially when a C library exists
+providing a basic client implementation.
+
+In this tutorial, we will implement a simple "client" which renders a bouncing
+ball using the Guacamole protocol. After completing the tutorial and installing
+the result, you will be able to add a connection to your Guacamole
+configuration using the "ball" protocol, and any users using that connection
+will see a bouncing ball.
+
+This example client plugin doesn't actually act as a client, but this isn't
+important. The Guacamole client is really just a remote display, and this
+client plugin functions as a simple example application which renders to this
+display, just as Guacamole's own VNC or RDP plugins function as VNC or RDP
+clients which render to the remote display.
+
+Each step of this tutorial is intended to exercise a new concept, while also
+progressing towards the goal of a nifty bouncing ball. At the end of each step,
+you will have a buildable and working client plugin.
+
+This tutorial will use the GNU Automake build system, which is the build system
+used by Guacamole for libguac, guacd, etc. There will be four files involved:
+
+`configure.ac`
+: Used by GNU Automake to generate the `configure` script which ultimately
+  serves to generate the `Makefile` which {command}`make` will use when
+  building.
+
+`Makefile.am`
+: Used by GNU Automake and the `configure` script to generate the `Makefile`
+  which {command}`make` will use when building.
+
+`src/ball.c`
+: The main body of code defining the bouncing ball "client".
+
+`src/ball.h`
+: A header file defining the structure representing the state of the bouncing
+  ball (once it becomes necessary to do so).
+
+All source files will be within the `src` subdirectory, as is common with C
+projects, with build files being at the root level directory. The main
+`src/ball.c` and the build-related `configure.ac` and `Makefile.am` files will
+be created first, with each successive step building upon those files
+iteratively, with `src/ball.h` being added when it becomes necessary. After
+each step, you can build/rebuild the plugin by running {command}`make`, and
+then install it (such that guacd can find the plugin) by running {command}`make
+install` and {command}`ldconfig` as root:
+
+```console
+$ make
+  CC       src/ball.lo
+  CCLD     libguac-client-ball.la
+# make install
+make[1]: Entering directory '/home/user/libguac-client-ball'
+ /usr/bin/mkdir -p '/usr/local/lib'
+ /bin/sh ./libtool   --mode=install /usr/bin/install -c   libguac-client-ball.la '/usr/local/lib'
+...
+----------------------------------------------------------------------
+Libraries have been installed in:
+   /usr/local/lib
+
+If you ever happen to want to link against installed libraries
+in a given directory, LIBDIR, you must either use libtool, and
+specify the full pathname of the library, or use the '-LLIBDIR'
+flag during linking and do at least one of the following:
+   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
+     during execution
+   - add LIBDIR to the 'LD_RUN_PATH' environment variable
+     during linking
+   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
+   - have your system administrator add LIBDIR to '/etc/ld.so.conf'
+
+See any operating system documentation about shared libraries for
+more information, such as the ld(1) and ld.so(8) manual pages.
+----------------------------------------------------------------------
+make[1]: Nothing to be done for 'install-data-am'.
+make[1]: Leaving directory '/home/user/libguac-client-ball'
+# ldconfig
+```
+
+Prior to the first time {command}`make` is invoked, you will need to run the
+`configure` script, which will first need to be generated using
+{command}`autoreconf`:
+
+```console
+$ autoreconf -fi
+libtoolize: putting auxiliary files in '.'.
+libtoolize: copying file './ltmain.sh'
+libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
+libtoolize: copying file 'm4/libtool.m4'
+libtoolize: copying file 'm4/ltoptions.m4'
+libtoolize: copying file 'm4/ltsugar.m4'
+libtoolize: copying file 'm4/ltversion.m4'
+libtoolize: copying file 'm4/lt~obsolete.m4'
+configure.ac:10: installing './compile'
+configure.ac:4: installing './missing'
+Makefile.am: installing './depcomp'
+$ ./configure
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+...
+configure: creating ./config.status
+config.status: creating Makefile
+config.status: executing depfiles commands
+config.status: executing libtool commands
+$
+```
+
+This process is almost identical to that of building guacamole-server from git,
+as documented in [](building-guacamole-server).
+
+:::{important}
+The libguac library which is part of guacamole-server is a required dependency
+of this project. *You must first install libguac, guacd, etc. by [building and
+installing guacamole-server](building-guacamole-server)*. If guacamole-server
+has not been installed, and libguac is thus not present, the `configure` script
+will fail with an error indicating that it could not find libguac:
+
+```console
+$ ./configure
+checking for a BSD-compatible install... /usr/bin/install -c
+checking whether build environment is sane... yes
+...
+checking for guac_client_stream_png in -lguac... no
+configure: error: "libguac is required for communication via "
+                   "the Guacamole protocol"
+$
+```
+
+You will need to install guacamole-server and then rerun `configure`.
+:::
+
+(libguac-client-ball-skeleton)=
+
+Minimal skeleton client
+-----------------------
+
+Very little needs too be done to implement the most basic client plugin

Review comment:
       One _too_ many Os in _to_

##########
File path: src/troubleshooting.md
##########
@@ -0,0 +1,539 @@
+Troubleshooting
+===============
+
+(not-working)=
+
+It isn't working
+----------------
+
+If Guacamole isn't working, chances are something isn't configured properly, or
+something is wrong with the network. Thankfully, Guacamole and all its
+components log errors thoroughly, so the problem can usually be traced down
+fairly easily if you know where to look. Troubleshooting Guacamole usually
+boils down to checking either syslog or your servlet container's logs (likely
+Tomcat).
+
+Failing all that, you can always post a question in the forums, or if you truly
+feel you've discovered a bug, you can create a new ticket in Trac. Beware that

Review comment:
       I feel like this may be a good time to change this from "Trac" to "JIRA"

##########
File path: src/troubleshooting.md
##########
@@ -0,0 +1,539 @@
+Troubleshooting
+===============
+
+(not-working)=
+
+It isn't working
+----------------
+
+If Guacamole isn't working, chances are something isn't configured properly, or
+something is wrong with the network. Thankfully, Guacamole and all its
+components log errors thoroughly, so the problem can usually be traced down
+fairly easily if you know where to look. Troubleshooting Guacamole usually
+boils down to checking either syslog or your servlet container's logs (likely
+Tomcat).
+
+Failing all that, you can always post a question in the forums, or if you truly
+feel you've discovered a bug, you can create a new ticket in Trac. Beware that
+if something isn't working, and there are errors in the logs describing the
+problem, it is usually not a bug, and the best place to handle such things is
+through consulting this guide or the forums.
+
+### No graphics appear
+
+If you *never* see any graphics appear, or you see "Connecting, waiting for
+first update..." for a while and then are disconnected, the most likely cause
+is a proxy.
+
+Guacamole relies on streaming data to you over a persistent connection.  If
+software between Guacamole and your browser is buffering all incoming data,
+such as a proxy, this data never makes it to your browser, and you will just
+see it wait indefinitely. Eventually, thinking the client has disconnected,
+Guacamole closes the connection, at which point the proxy finally flushes its
+buffer and you see graphics! ... just in time to see it disconnect.
+
+The solution here is to either modify your proxy settings to flush packets
+immediately as they are received, or to use HTTPS. Proxies are required to pass
+HTTPS through untouched, and this usually solves the problem.
+
+Even if you aren't aware of any proxy, there may be one in place.  Corporate
+firewalls very often incorporate proxies. Antivirus software may buffer
+incoming data until the connection is closed and the data is scanned for
+viruses. Virtualization software may detect HTTP data and buffer the connection
+just like a proxy. If all else fails, try HTTPS - it's the only secure way to
+do this anyway.
+
+### Connections involving Unicode don't work
+
+If you are using Tomcat, beware that you *must* set the `URIEncoding="UTF-8"`
+attribute on all connectors in your `server.xml`. If you are using a different
+servlet container, you need to find out whether it requires special options to
+support UTF-8 in URIs, and change the required settings to enable such support.
+
+Without UTF-8 support enabled for URIs, Unicode characters in connection names
+will not be received properly when connecting, and Guacamole will thing the

Review comment:
       thing -> think

##########
File path: src/configuring-guacamole.md
##########
@@ -0,0 +1,2770 @@
+Configuring Guacamole
+=====================
+
+After installing Guacamole, you need to configure users and connections before
+Guacamole will work. This chapter covers general configuration of Guacamole and
+the use of its default authentication method.
+
+Guacamole's default authentication method reads all users and connections from
+a single file called `user-mapping.xml`. This authentication method is intended
+to be:
+
+1. Sufficient for small deployments of Guacamole.
+
+2. A relatively-easy means of verifying that Guacamole has been properly set
+   up.
+
+Other, more complex authentication methods which use backend databases, LDAP,
+etc. are discussed in a separate, dedicated chapters.
+
+Regardless of the authentication method you use, Guacamole's configuration
+always consists of two main pieces: a directory referred to as
+`GUACAMOLE_HOME`, which is the primary search location for configuration files,
+and `guacamole.properties`, the main configuration file used by Guacamole and
+its extensions.
+
+(guacamole-home)=
+
+`GUACAMOLE_HOME` (`/etc/guacamole`)
+---------------------------------------
+
+`GUACAMOLE_HOME` is the name given to Guacamole's configuration directory,
+which is located at `/etc/guacamole` by default. All configuration files,
+extensions, etc. reside within this directory. The structure of
+`GUACAMOLE_HOME` is rigorously defined, and consists of the following optional
+files:
+
+`guacamole.properties`
+: The main Guacamole configuration file. Properties within this file dictate
+  how Guacamole will connect to guacd, and may configure the behavior of
+  installed authentication extensions.
+
+`logback.xml`
+: Guacamole uses a logging system called Logback for all messages. By
+  default, Guacamole will log to the console only, but you can change this
+  by providing your own Logback configuration file.
+
+`extensions/`
+: The install location for all Guacamole extensions. Guacamole will
+  automatically load all `.jar` files within this directory on startup.
+
+`lib/`
+: The search directory for libraries required by any Guacamole extensions.
+  Guacamole will make the `.jar` files within this directory available to
+  all extensions. If your extensions require additional libraries, such as
+  database drivers, this is the proper place to put them.
+
+(overriding-guacamole-home)=
+
+### Overriding `GUACAMOLE_HOME`
+
+If you cannot or do not wish to use `/etc/guacamole` for `GUACAMOLE_HOME`, the
+location can be overridden through any of the following methods:
+
+1. Creating a directory named `.guacamole`, within the home directory of *the
+   user running the servlet container*. This directory will automatically be
+   used for `GUACAMOLE_HOME` if it exists.
+
+2. Specifying the full path to an alternative directory with the environment
+   variable `GUACAMOLE_HOME`. *Be sure to consult the documentation for your
+   servlet container to determine how to properly set environment variables.*
+
+3. Specifying the full path to an alternative directory with the system
+   property guacamole.home.
+
+(initial-setup)=
+
+`guacamole.properties`
+------------------------
+
+The Guacamole web application uses one main configuration file called
+`guacamole.properties`. This file is the common location for all configuration
+properties read by Guacamole or any extension of Guacamole, including
+authentication providers.
+
+In previous releases, this file had to be in the classpath of your servlet
+container. Now, the location of `guacamole.properties` can be explicitly
+defined with environment variables or system properties, and the classpath is
+only used as a last resort. When searching for `guacamole.properties`,
+Guacamole will check, in order:
+
+1. Within `GUACAMOLE_HOME`, as defined above.
+
+2. The classpath of the servlet container.
+
+The `guacamole.properties` file is optional and is used to configure Guacamole
+in situations where the defaults are insufficient, or to provide additional
+configuration information for extensions. There are several standard properties
+that are always available for use:
+
+`api-session-timeout`
+: The amount of time, in minutes, to allow Guacamole sessions
+  (authentication tokens) to remain valid despite inactivity. If omitted,
+  Guacamole sessions will expire after 60 minutes of inactivity.
+
+`api-max-request-size`
+: The maximum number of bytes to accept within the entity body of any
+  particular HTTP request, where 0 indicates that no limit should be
+  applied. If omitted, requests will be limited to 2097152 bytes (2 MB) by
+  default. This limit does not apply to file uploads.
+
+  If using a reverse proxy for SSL termination, *keep in mind that reverse
+  proxies may enforce their own limits independently of this*. For example,
+  [Nginx will enforce a 1 MB request size limit by
+  default](nginx-file-upload-size).
+
+`allowed-languages`
+: A comma-separated whitelist of language keys to allow as display language
+  choices within the Guacamole interface. For example, to restrict Guacamole
+  to only English and German, you would specify:
+
+  ```
+  allowed-languages: en, de
+  ```
+
+  As English is the fallback language, used whenever a translation key is
+  missing from the chosen language, English should only be omitted from this
+  list if you are absolutely positive that no strings are missing.
+
+  The corresponding JSON of any built-in languages not listed here will
+  still be available over HTTP, but the Guacamole interface will not use
+  them, nor will they be used automatically based on local browser language.
+  If omitted, all defined languages will be available.
+
+`enable-environment-properties`
+: If set to "true", Guacamole will first evaluate its environment to obtain
+  the value for any given configuration property, before using a value
+  specified in `guacamole.properties` or falling back to a default value. By
+  enabling this option, you can easily override any other configuration
+  property using an environment variable.
+
+  ```
+  enable-environment-properties: true
+  ```
+
+  When searching for a configuration property in the environment, the name
+  of the property is first transformed by converting all lower case
+  characters to their upper case equivalents, and by replacing all hyphen
+  characters (`-`) with underscore characters (`_`). For example, the
+  `guacd-hostname` property would be transformed to `GUACD_HOSTNAME` when
+  searching the environment.
+
+`guacd-hostname`
+: The host the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on localhost.
+
+`guacd-port`
+: The port the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on port 4822.
+
+`guacd-ssl`
+: If set to "true", Guacamole will require SSL/TLS encryption between the
+  web application and guacd. By default, communication between the web
+  application and guacd will be unencrypted.
+
+  Note that if you enable this option, you must also configure guacd to use
+  SSL via command line options. These options are documented in the manpage
+  of guacd. You will need an SSL certificate and private key.
+
+`skip-if-unavailable`
+: A comma-separated list of the identifiers of authentication providers that
+  should be allowed to fail internally without aborting the authentication
+  process. For example, to request that Guacamole ignore failures due to the
+  LDAP directory or MySQL server being unexpectedly down, allowing other
+  authentication providers to continue functioning:
+
+  ```
+  skip-if-unavailable: mysql, ldap
+  ```
+
+  By default, Guacamole takes a conservative approach to internal failures,
+  aborting the authentication process if an internal error occurs within any
+  authentication provider. Depending on the nature of the error, this may
+  mean that no users can log in until the cause of the failure is dealt
+  with. The `skip-if-unavailable` property may be used to explicitly inform
+  Guacamole that one or more underlying systems are expected to occasionally
+  experience failures, and that other functioning systems should be relied
+  upon if they do fail.
+
+
+```
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port:     4822
+```
+
+(webapp-logging)=
+
+Logging within the web application
+----------------------------------
+
+By default, Guacamole logs all messages to the console. Servlet containers like
+Tomcat will automatically redirect these messages to a log file, `catalina.out`
+in the case of Tomcat, which you can read through while Guacamole runs.
+Messages are logged at four different log levels, depending on message
+importance and severity:
+
+`error`
+: Errors are fatal conditions. An operation, described in the log message,
+  was attempted but could not proceed, and the failure of this operation is
+  a serious problem that needs to be addressed.
+
+`warn`
+: Warnings are generally non-fatal conditions. The operation continued, but
+  encountered noteworthy problems.
+
+`info`
+: "Info" messages are purely informational. They may be useful or
+  interesting to administrators, but are not generally critical to proper
+  operation of a Guacamole server.
+
+`debug`
+: Debug messages are highly detailed and oriented toward development. Most
+  debug messages will contain stack traces and internal information that is
+  useful when investigating problems within code. It is expected that debug
+  messages, though verbose, will not affect performance.
+
+`trace`
+: Trace messages are similar to debug messages in intent and verbosity, but
+  are so low-level that they may affect performance due to their frequency.
+  Trace-level logging is rarely necessary, and is mainly useful in providing
+  highly detailed context around issues being investigated.
+
+Guacamole logs messages using a logging framework called
+[Logback](http://logback.qos.ch/) and, by default, will only log messages at
+the "`info`" level or higher. If you wish to change the log level, or configure
+how or where Guacamole logs messages, you can do so by providing your own
+`logback.xml` file within `GUACAMOLE_HOME`.  For example, to log all messages
+to the console, even "`debug`" messages, you might use the following
+`logback.xml`:
+
+```xml
+<configuration>
+
+    <!-- Appender for debugging -->
+    <appender name="GUAC-DEBUG" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log at DEBUG level -->
+    <root level="debug">
+        <appender-ref ref="GUAC-DEBUG"/>
+    </root>
+
+</configuration>
+```
+
+Guacamole and the above example configure only one appender which logs to the
+console, but Logback is extremely flexible and allows any number of appenders
+which can each log to separate files, the console, etc.  based on a number of
+criteria, including the log level and the source of the message.
+
+More thorough [documentation on configuring
+Logback](http://logback.qos.ch/manual/configuration.html) is provided on the
+Logback project's web site.
+
+(basic-auth)=
+
+Using the default authentication
+--------------------------------
+
+Guacamole's default authentication module is simple and consists of a mapping
+of usernames to configurations. This authentication module comes with Guacamole
+and simply reads usernames and passwords from an XML file. It is always
+enabled, but will only read from the XML file if it exists, and is always last
+in priority relative to any other authentication extensions.
+
+There are other authentication modules available. The Guacamole project
+provides database-backed authentication modules with the ability to manage
+connections and users from the web interface, and other authentication modules
+can be created using the extension API provided along with the Guacamole web
+application, guacamole-ext.
+
+(user-mapping)=
+
+### `user-mapping.xml`
+
+The default authentication provider used by Guacamole reads all username,
+password, and configuration information from a file called the "user mapping"
+located at `GUACAMOLE_HOME/user-mapping.xml`. An example of a user mapping file
+is included with Guacamole, and looks something like this:
+
+```xml
+<user-mapping>
+
+    <!-- Per-user authentication and config information -->
+    <authorize username="USERNAME" password="PASSWORD">
+        <protocol>vnc</protocol>
+        <param name="hostname">localhost</param>
+        <param name="port">5900</param>
+        <param name="password">VNCPASS</param>
+    </authorize>
+
+    <!-- Another user, but using md5 to hash the password
+         (example below uses the md5 hash of "PASSWORD") -->
+    <authorize
+            username="USERNAME2"
+            password="319f4d26e3c536b5dd871bb2c52e3178"
+            encoding="md5">
+
+        <!-- First authorized connection -->
+        <connection name="localhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">localhost</param>
+            <param name="port">5901</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+        <!-- Second authorized connection -->
+        <connection name="otherhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">otherhost</param>
+            <param name="port">5900</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+    </authorize>
+
+</user-mapping>
+```
+
+Each user is specified with a corresponding `<authorize>` tag. This tag
+contains all authorized connections for that user, each denoted with a
+`<connection>` tag. Each `<connection>` tag contains a corresponding protocol
+and set of protocol-specific parameters, specified with the `<protocol>` and
+`<param>` tags respectively.
+
+(user-setup)=
+
+#### Adding users
+
+When using `user-mapping.xml`, username/password pairs are specified with
+`<authorize>` tags, which each have a `username` and `password` attribute. Each
+`<authorize>` tag authorizes a specific username/password pair to access all
+connections within the tag:
+
+```xml
+<authorize username="USER" password="PASS">
+    ...
+</authorize>
+```
+
+In the example above, the password would be listed in plaintext. If you don't
+want to do this, you can also specify your password hashed with MD5:
+
+```xml
+<authorize username="USER"
+           password="319f4d26e3c536b5dd871bb2c52e3178"
+           encoding="md5">
+    ...
+</authorize>
+```
+
+After modifying `user-mapping.xml`, the file will be automatically reread by
+Guacamole, and your changes will take effect immediately. The newly-added user
+will be able to log in - no restart of the servlet container is needed.
+
+(connection-setup)=
+
+#### Adding connections to a user
+
+To specify a connection within an `<authorize>` tag, you can either list a
+single protocol and set of parameters (specified with a `<protocol>` tag and
+any number of `<param>` tags), in which case that user will have access to only
+one connection named "DEFAULT", or you can specify one or more connections with
+one or more `<connection>` tags, each of which can be named and contains a
+`<protocol>` tag and any number of `<param>` tags.
+
+(connection-configuration)=
+
+Configuring connections
+-----------------------
+
+Each protocol supported by Guacamole has its own set of configuration
+parameters. These parameters typically describe the hostname and port of the
+remote desktop server, the credentials to use when connecting, if any, and the
+size and color depth of the display. If the protocol supports file transfer,
+options for enabling that functionality will be provided as well.
+
+### VNC
+
+The VNC protocol is the simplest and first protocol supported by Guacamole.
+Although generally not as fast as RDP, many VNC servers are adequate, and VNC
+over Guacamole tends to be faster than VNC by itself due to decreased bandwidth
+usage.
+
+VNC support for Guacamole is provided by the libguac-client-vnc library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the VNC-specific parameters below, Guacamole's VNC support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(vnc-network-parameters)=
+
+#### Network parameters
+
+With the exception of reverse-mode VNC connections, VNC works by making
+outbound network connections to a particular host which runs one or more VNC
+servers. Each VNC server is associated with a display number, from which the
+appropriate port number is derived.
+
+`hostname`
+: The hostname or IP address of the VNC server Guacamole should connect to.
+
+`port`
+: The port the VNC server is listening on, usually 5900 or 5900 + display
+  number. For example, if your VNC server is serving display number 1
+  (sometimes written as `:1`), your port number here would be 5901.
+
+`autoretry`
+: The number of times to retry connecting before giving up and returning an
+  error. In the case of a reverse connection, this is the number of times
+  the connection process is allowed to time out.
+
+(vnc-authentication)=
+
+#### Authentication
+
+The VNC standard defines only password based authentication. Other
+authentication mechanisms exist, but are non-standard or proprietary.
+Guacamole currently supports both standard password-only based authentication,
+as well as username and password authentication.
+
+`username`
+: The username to use when attempting authentication, if any. This parameter
+  is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+(vnc-display-settings)=
+
+#### Display settings
+
+VNC servers do not allow the client to request particular display sizes, so you
+are at the mercy of your VNC server with respect to display width and height.
+However, to reduce bandwidth usage, you may request that the VNC server reduce
+its color depth. Guacamole will automatically detect 256-color images, but this
+can be guaranteed for absolutely all graphics sent over the connection by
+forcing the color depth to 8-bit. Color depth is otherwise dictated by the VNC
+server.
+
+If you are noticing problems with your VNC display, such as the lack of a mouse
+cursor, the presence of multiple mouse cursors, or strange colors (such as blue
+colors appearing more like orange or red), these are typically the result of
+bugs or limitations within the VNC server, and additional parameters are
+available to work around such issues.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, 24, or 32. Regardless of what
+  value is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`swap-red-blue`
+: If the colors of your display appear wrong (blues appear orange or red,
+  etc.), it may be that your VNC server is sending image data incorrectly,
+  and the red and blue components of each color are swapped. If this is the
+  case, set this parameter to "true" to work around the problem. This
+  parameter is optional.
+
+`cursor`
+: If set to "remote", the mouse pointer will be rendered remotely, and the
+  local position of the mouse pointer will be indicated by a small dot. A
+  remote mouse cursor will feel slower than a local cursor, but may be
+  necessary if the VNC server does not support sending the cursor image to
+  the client.
+
+`encodings`
+: A space-delimited list of VNC encodings to use. The format of this
+  parameter is dictated by libvncclient and thus doesn't really follow the
+  form of other Guacamole parameters. This parameter is optional, and
+  libguac-client-vnc will use any supported encoding by default.
+
+  Beware that this parameter is intended to be replaced with individual,
+  encoding-specific parameters in a future release.
+
+`read-only`
+: Whether this connection should be read-only. If set to "true", no input
+  will be accepted on the connection at all. Users will only see the desktop
+  and whatever other users using that same desktop are doing. This parameter
+  is optional.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+#### VNC Repeater
+
+There exist VNC repeaters, such as UltraVNC Repeater, which act as
+intermediaries or proxies, providing a single logical VNC connection which is
+then routed to another VNC server elsewhere. Additional parameters are required
+to select which VNC host behind the repeater will receive the connection.
+
+`dest-host`
+: The destination host to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+`dest-port`
+: The destination port to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+(vnc-reverse-connections)=
+
+#### Reverse VNC connections
+
+Guacamole supports "reverse" VNC connections, where the VNC client listens for
+an incoming connection from the VNC server. When reverse VNC connections are
+used, the VNC client and server switch network roles, but otherwise function as
+they normally would. The VNC server still provides the remote display, and the
+VNC client still provides all keyboard and mouse input.
+
+`reverse-connect`
+: Whether reverse connection should be used. If set to "true", instead of
+  connecting to a server at a given hostname and port, guacd will listen on
+  the given port for inbound connections from a VNC server.
+
+`listen-timeout`
+: If reverse connection is in use, the maximum amount of time to wait for an
+  inbound connection from a VNC server, in milliseconds. If blank, the
+  default value is 5000 (five seconds).
+
+(vnc-audio)=
+
+#### Audio support (via PulseAudio)
+
+VNC does not provide its own support for audio, but Guacamole's VNC support can
+obtain audio through a secondary network connection to a PulseAudio server
+running on the same machine as the VNC server.
+
+Most Linux systems provide audio through a service called PulseAudio.  This
+service is capable of communicating over the network, and if PulseAudio is
+configured to allow TCP connections, Guacamole can connect to your PulseAudio
+server and combine its audio with the graphics coming over VNC.
+
+Configuring PulseAudio for network connections requires an additional line
+within the PulseAudio configuration file, usually `/etc/pulse/default.pa`:
+
+```
+load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24 auth-anonymous=1
+```
+
+This loads the TCP module for PulseAudio, configuring it to accept connections
+without authentication and *only* from the `192.168.1.0/24` subnet. You will
+want to replace this value with the subnet or IP address from which guacd will
+be connecting. It is possible to allow connections from absolutely anywhere,
+but beware that you should only do so if the nature of your network prevents
+unauthorized access:
+
+```
+load-module module-native-protocol-tcp auth-anonymous=1
+```
+
+In either case, the `auth-anonymous=1` parameter is strictly required.
+Guacamole does not currently support the cookie-based authentication used by
+PulseAudio for non-anonymous connections. If this parameter is omitted,
+Guacamole will not be able to connect to PulseAudio.
+
+Once the PulseAudio configuration file has been modified appropriately, restart
+the PulseAudio service. PulseAudio should then begin listening on port 4713
+(the default PulseAudio port) for incoming TCP connections. You can verify this
+using a utility like {command}`netstat`:
+
+```console
+$ netstat -ln | grep 4713
+tcp        0      0 0.0.0.0:4713            0.0.0.0:*               LISTEN
+tcp6       0      0 :::4713                 :::*                    LISTEN
+$
+```
+
+The following parameters are available for configuring the audio support for
+VNC:
+
+`enable-audio`
+: If set to "true", audio support will be enabled, and a second connection
+  for PulseAudio will be made in addition to the VNC connection. By default,
+  audio support within VNC is disabled.
+
+`audio-servername`
+: The name of the PulseAudio server to connect to. This will be the hostname
+  of the computer providing audio for your connection via PulseAudio, most
+  likely the same as the value given for the `hostname` parameter.
+
+  If this parameter is omitted, the default PulseAudio device will be used,
+  which will be the PulseAudio server running on the same machine as guacd.
+
+(vnc-clipboard-encoding)=
+
+#### Clipboard encoding
+
+While Guacamole will always use UTF-8 for its own clipboard data, the VNC
+standard requires that clipboard data be encoded in ISO 8859-1. As most VNC
+servers will not accept data in any other format, Guacamole will translate
+between UTF-8 and ISO 8859-1 when exchanging clipboard data with the VNC
+server, but this behavior can be overridden with the `clipboard-encoding`
+parameter.
+
+:::{important}
+*The only clipboard encoding guaranteed to be supported by VNC servers is ISO
+8859-1.* You should only override the clipboard encoding using the
+`clipboard-encoding` parameter of you are absolutely positive your VNC server
+supports other encodings.
+:::
+
+`clipboard-encoding`
+: The encoding to assume for the VNC clipboard. This parameter is optional.
+  By default, the standard encoding ISO 8859-1 will be used. *Only use this
+  parameter if you are sure your VNC server supports other encodings beyond
+  the standard ISO 8859-1.*
+
+  Possible values are:
+
+  ISO8859-1
+  : ISO 8859-1 is the clipboard encoding mandated by the VNC standard, and
+    supports only basic Latin characters. Unless your VNC server specifies
+    otherwise, this encoding is the only encoding guaranteed to work.
+
+  UTF-8
+  : UTF-8 - the most common encoding used for Unicode. Using this encoding
+    for the VNC clipboard violates the VNC specification, but some servers
+    do support this. This parameter value should only be used if you know
+    your VNC server supports this encoding.
+
+  UTF-16
+  : UTF-16 - a 16-bit encoding for Unicode which is not as common as UTF-8,
+    but still widely used. Using this encoding for the VNC clipboard
+    violates the VNC specification. This parameter value should only be used
+    if you know your VNC server supports this encoding.
+
+  CP1252
+  : Code page 1252 - a Windows-specific encoding for Latin characters which
+    is mostly a superset of ISO 8859-1, mapping some additional displayable
+    characters onto what would otherwise be control characters. Using this
+    encoding for the VNC clipboard violates the VNC specification. This
+    parameter value should only be used if you know your VNC server supports
+    this encoding.
+
+(adding-vnc)=
+
+#### Adding a VNC connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a VNC connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>vnc</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">5901</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use VNC to connect to localhost at port 5901. Naturally,
+you will want to change some or all of these values.
+
+If your VNC server requires a password, or you wish to specify other
+configuration parameters (to reduce the color depth, for example), you will
+need to add additional `<param>` tags accordingly.
+
+Other authentication methods will provide documentation describing how to
+configure new connections. If the authentication method in use fully implements
+the features of Guacamole's authentication API, you will be able to add a new
+VNC connection easily and intuitively using the administration interface built
+into Guacamole. You will not need to edit configuration files.
+
+(vnc-servers)=
+
+#### Which VNC server?
+
+The choice of VNC server can make a big difference when it comes to
+performance, especially over slower networks. While many systems provide VNC
+access by default, using this is often not the fastest method.
+
+(realvnc)=
+
+##### RealVNC or TigerVNC
+
+RealVNC, and its derivative TigerVNC, perform quite well. In our testing, they
+perform the best with Guacamole. If you are okay with having a desktop that can
+only be accessed via VNC, one of these is likely your best choice. Both
+optimize window movement and (depending on the application) scrolling, giving a
+very responsive user experience.
+
+##### TightVNC
+
+TightVNC is widely-available and performs generally as well as RealVNC or
+TigerVNC. If you wish to use TightVNC with Guacamole, performance should be
+just fine, but we highly recommend disabling its JPEG encoding. This is because
+images transmitted to Guacamole are always encoded losslessly as PNG images.
+When this operation is performed on a JPEG image, the artifacts present from
+JPEG's lossy compression reduce the compressibility of the image for PNG, thus
+leading to a slower experience overall than if JPEG was simply not used to
+begin with.
+
+##### x11vnc
+
+The main benefit of using x11vnc is that it allows you to continue using your
+desktop normally, while simultaneously exposing control of your desktop via
+VNC. Performance of x11vnc is comparable to RealVNC, TigerVNC, and TightVNC. If
+you need to use your desktop locally as well as via VNC, you will likely be
+quite happy with x11vnc.
+
+##### vino
+
+vino is the VNC server that comes with the Gnome desktop environment, and is
+enabled if you enable "desktop sharing" via the system preferences available
+within Gnome. If you need to share your local desktop, we recommend using
+x11vnc rather vino, as it has proven more performant and feature-complete in
+our testing. If you don't need to share a local desktop but simply need an
+environment you can access remotely, using a VNC server like RealVNC, TigerVNC,
+or TightVNC is a better choice.
+
+(qemu)=
+
+##### QEMU or KVM
+
+QEMU (and thus KVM) expose the displays of virtual machines using VNC.  If you
+need to see the virtual monitor of your virtual machine, using this VNC
+connection is really your only choice. As the VNC server built into QEMU cannot
+be aware of higher-level operations like window movement, resizing, or
+scrolling, those operations will tend to be sent suboptimally, and will not be
+as fast as a VNC server running within the virtual machine.
+
+If you wish to use a virtual machine for desktop access, we recommend
+installing a native VNC server inside the virtual machine after the virtual
+machine is set up. This will give a more responsive desktop.
+
+### RDP
+
+The RDP protocol is more complicated than VNC and was the second protocol
+officially supported by Guacamole. RDP tends to be faster than VNC due to the
+use of caching, which Guacamole does take advantage of.
+
+RDP support for Guacamole is provided by the libguac-client-rdp library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the RDP-specific parameters below, Guacamole's RDP support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(rdp-network-parameters)=
+
+#### Network parameters
+
+RDP connections require a hostname or IP address defining the
+destination machine. The RDP port is defined to be 3389, and will be
+this value in most cases. You only need to specify the RDP port if you
+are not using port 3389.
+
+`hostname`
+: The hostname or IP address of the RDP server Guacamole should connect to.
+
+`port`
+: The port the RDP server is listening on. This parameter is optional. If
+  this is not specified, the standard port for RDP (3389) or Hyper-V's
+  default port for VMConnect (2179) will be used, depending on the security
+  mode selected.
+
+(rdp-authentication)=
+
+#### Authentication and security
+
+RDP provides authentication through the use of a username, password, and
+optional domain. All RDP connections are encrypted.
+
+Most RDP servers will provide a graphical login if the username, password, and
+domain parameters are omitted. One notable exception to this is Network Level
+Authentication, or NLA, which performs all authentication outside of a desktop
+session, and thus in the absence of a graphical interface.
+
+Servers that require NLA can be handled by Guacamole in one of two ways. The
+first is to provide the username and password within the connection
+configuration, either via static values or by passing through the Guacamole
+credentials with [parameter tokens](parameter-tokens) and [](ldap-auth).
+Alternatively, if credentials are not configured within the connection
+configuration, Guacamole will attempt to prompt the user for the credentials
+interactively, if the versions of both guacd and Guacamole Client in use
+support it. If either component does not support prompting and the credentials
+are not configured, NLA-based connections will fail.
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+`domain`
+: The domain to use when attempting authentication, if any. This parameter
+  is optional.
+
+`security`
+: The security mode to use for the RDP connection. This mode dictates how
+  data will be encrypted and what type of authentication will be performed,
+  if any. By default, a security mode is selected based on a negotiation
+  process which determines what both the client and the server support.
+
+  Possible values are:
+
+  any
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server. *This is the default*.
+
+  nla
+  : Network Level Authentication, sometimes also referred to as "hybrid" or
+    CredSSP (the protocol that drives NLA). This mode uses TLS encryption
+    and requires the username and password to be given in advance. Unlike
+    RDP mode, the authentication step is performed before the remote desktop
+    session actually starts, avoiding the need for the Windows server to
+    allocate significant resources for users that may not be authorized.
+
+    If the versions of guacd and Guacamole Client in use support prompting
+    and the username, password, and domain are not specified, the user will
+    be interactively prompted to enter credentials to complete NLA and
+    continue the connection. Otherwise, when prompting is not supported and
+    credentials are not provided, NLA connections will fail.
+
+  nla-ext
+  : Extended Network Level Authentication. This mode is identical to NLA
+    except that an additional "[Early User Authorization
+    Result](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d0e560a3-25cb-4563-8bdc-6c4cc625bbfc)"
+    is required to be sent from the server to the client immediately after the
+    NLA handshake is completed.
+
+  tls
+  : RDP authentication and encryption implemented via TLS (Transport Layer
+    Security). Also referred to as RDSTLS, the TLS security mode is
+    primarily used in load balanced configurations where the initial RDP
+    server may redirect the connection to a different RDP server.
+
+  vmconnect
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server, limiting that negotiation
+    to only the protocols known to be supported by [Hyper-V /
+    VMConnect](rdp-preconnection-pdu).
+
+  rdp
+  : Legacy RDP encryption. This mode is generally only used for older
+    Windows servers or in cases where a standard Windows login screen is
+    desired. Newer versions of Windows have this mode disabled by default
+    and will only accept NLA unless explicitly configured otherwise.
+
+`ignore-cert`
+: If set to "true", the certificate returned by the server will be ignored,
+  even if that certificate cannot be validated. This is useful if you
+  universally trust the server and your connection to the server, and you
+  know that the server's certificate cannot be validated (for example, if it
+  is self-signed).
+
+`disable-auth`
+: If set to "true", authentication will be disabled. Note that this refers
+  to authentication that takes place while connecting. Any authentication
+  enforced by the server over the remote desktop session (such as a login
+  dialog) will still take place. By default, authentication is enabled and
+  only used when requested by the server.
+
+  If you are using NLA, authentication must be enabled by definition.
+
+(rdp-session-settings)=
+
+#### Session settings
+
+RDP sessions will typically involve the full desktop environment of a normal
+user. Alternatively, you can manually specify a program to use instead of the
+RDP server's default shell, or connect to the administrative console.
+
+Although Guacamole is independent of keyboard layout, RDP is not. This is
+because Guacamole represents keys based on what they *do* ("press the Enter
+key"), while RDP uses identifiers based on the key's location ("press the
+rightmost key in the second row"). To translate between a Guacamole key event
+and an RDP key event, Guacamole must know ahead of time the keyboard layout of
+the RDP server.
+
+By default, the US English qwerty keyboard will be used. If this does not match
+the keyboard layout of your RDP server, keys will not be properly translated,
+and you will need to explicitly choose a different layout in your connection
+settings. If your keyboard layout is not supported, please notify the Guacamole
+team by [opening an issue in
+JIRA](https://issues.apache.org/jira/browse/GUACAMOLE).
+
+
+`client-name`
+: When connecting to the RDP server, Guacamole will normally provide its own
+  hostname as the name of the client. If this parameter is specified,
+  Guacamole will use its value instead.
+
+  On Windows RDP servers, this value is exposed within the session as the
+  `CLIENTNAME` environment variable.
+
+`console`
+: If set to "true", you will be connected to the console (admin) session of
+  the RDP server.
+
+`initial-program`
+: The full path to the program to run immediately upon connecting. This
+  parameter is optional.
+
+`server-layout`
+: The server-side keyboard layout. This is the layout of the RDP server and
+  has nothing to do with the keyboard layout in use on the client. *The
+  Guacamole client is independent of keyboard layout.* The RDP protocol,
+  however, is *not* independent of keyboard layout, and Guacamole needs to
+  know the keyboard layout of the server in order to send the proper keys
+  when a user is typing.
+
+  Possible values are generally in the format
+  {samp}`{LANGUAGE}-{REGION}-{VARIANT}`, where `LANGUAGE` is the standard
+  two-letter language code for the primary language associated with the
+  layout, `REGION` is a standard representation of the location that the
+  keyboard is used (the two-letter country code, when possible), and
+  `VARIANT` is the specific keyboard layout variant (such as "qwerty",
+  "qwertz", or "azerty"):
+
+  | Keyboard layout                | Parameter value        |
+  | ------------------------------ | ---------------------- |
+  | Brazilian (Portuguese)         | `pt-br-qwerty`         |
+  | English (UK)                   | `en-gb-qwerty`         |
+  | English (US)                   | `en-us-qwerty`         |
+  | French                         | `fr-fr-azerty`         |
+  | French (Belgian)               | `fr-be-azerty`         |
+  | French (Swiss)                 | `fr-ch-qwertz`         |
+  | German                         | `de-de-qwertz`         |
+  | German (Swiss)                 | `de-ch-qwertz`         |
+  | Hungarian                      | `hu-hu-qwertz`         |
+  | Italian                        | `it-it-qwerty`         |
+  | Japanese                       | `ja-jp-qwerty`         |
+  | Spanish                        | `es-es-qwerty`         |
+  | Spanish (Latin American)       | `es-latam-qwerty`      |
+  | Swedish                        | `sv-se-qwerty`         |
+  | Turkish-Q                      | `tr-tr-qwerty`         |
+
+  If you server's keyboard layout is not yet supported, and it is not possible
+  to set your server to use a supported layout, the `failsafe` layout may be used
+  to force Unicode events to be used for all input, however beware that doing so
+  may prevent keyboard shortcuts from working as expected.
+
+`timezone`
+: The timezone that the client should send to the server for configuring the
+  local time display of that server. The format of the timezone is in the
+  standard IANA key zone format, which is the format used in UNIX/Linux.
+  This will be converted by RDP into the correct format for Windows.
+
+  The timezone is detected and will be passed to the server during the
+  handshake phase of the connection, and may used by protocols, like RDP,
+  that support it. This parameter can be used to override the value detected
+  and passed during the handshake, or can be used in situations where guacd
+  does not support passing the timezone parameter during the handshake phase
+  (guacd versions prior to 1.3.0).
+
+  Support for forwarding the client timezone varies by RDP server
+  implementation. For example, with Windows, support for forwarding
+  timezones is only present in Windows Server with Remote Desktop Services
+  (RDS, formerly known as Terminal Services) installed. Windows Server
+  installations in admin mode, along with Windows workstation versions, do
+  not allow the timezone to be forwarded. Other server implementations, for
+  example, xrdp, may not implement this feature at all. Consult the
+  documentation for the RDP server to determine whether or not this feature
+  is supported.
+
+(rdp-display-settings)=
+
+#### Display settings
+
+Guacamole will automatically choose an appropriate display size for RDP
+connections based on the size of the browser window and the DPI of the device.
+The size of the display can be forced by specifying explicit width or height
+values.
+
+To reduce bandwidth usage, you may also request that the server reduce its
+color depth. Guacamole will automatically detect 256-color images, but this can
+be guaranteed for absolutely all graphics sent over the connection by forcing
+the color depth to 8-bit. Color depth is otherwise dictated by the RDP server.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, or 24. Regardless of what value
+  is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`width`
+: The width of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the width of the connecting
+  client display will be used instead.
+
+`height`
+: The height of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the height of the connecting
+  client display will be used instead.
+
+`dpi`
+: The desired effective resolution of the client display, in DPI. This
+  parameter is optional. If this value is not specified, the resolution and
+  size of the client display will be used together to determine,
+  heuristically, an appropriate resolution for the RDP session.
+
+`resize-method`
+: The method to use to update the RDP server when the width or height of the
+  client display changes. This parameter is optional. If this value is not
+  specified, no action will be taken when the client display changes size.
+
+  Normally, the display size of an RDP session is constant and can only be
+  changed when initially connecting. As of RDP 8.1, the "Display Update"
+  channel can be used to request that the server change the display size.
+  For older RDP servers, the only option is to disconnect and reconnect with
+  the new size.
+
+  Possible values are:
+
+  display-update
+  : Uses the "Display Update" channel added with RDP 8.1 to signal the
+    server when the client display size has changed.
+
+  reconnect
+  : Automatically disconnects the RDP session when the client display size
+    has changed, and reconnects with the new size.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+(rdp-device-redirection)=
+
+#### Device redirection
+
+Device redirection refers to the use of non-display devices over RDP.
+Guacamole's RDP support currently allows redirection of audio, printing, and
+disk access, some of which require additional configuration in order to
+function properly.
+
+Audio redirection will be enabled by default. If Guacamole was correctly
+installed, and audio redirection is supported by your RDP server, sound should
+play within remote connections without manual intervention.
+
+Printing requires GhostScript to be installed on the Guacamole server, and
+allows users to print arbitrary documents directly to PDF. When documents are
+printed to the redirected printer, the user will receive a PDF of that document
+within their web browser.
+
+Guacamole provides support for file transfer over RDP by emulating a virtual
+disk drive. This drive will persist on the Guacamole server, confined within
+the drive path specified. If drive redirection is enabled on a Guacamole RDP
+connection, users will be able to upload and download files as described in
+[](using-guacamole).
+
+`disable-audio`
+: Audio is enabled by default in both the client and in libguac-client-rdp.
+  If you are concerned about bandwidth usage, or sound is causing problems,
+  you can explicitly disable sound by setting this parameter to "true".
+
+`enable-audio-input`
+: If set to "true", audio input support (microphone) will be enabled,
+  leveraging the standard "`AUDIO_INPUT`" channel of RDP. By default, audio
+  input support within RDP is disabled.
+
+`enable-printing`
+: Printing is disabled by default, but with printing enabled, RDP users can
+  print to a virtual printer that sends a PDF containing the document
+  printed to the Guacamole client. Enable printing by setting this parameter
+  to "true".
+
+  *Printing support requires GhostScript to be installed.* If guacd cannot
+  find the `gs` executable when printing, the print attempt will fail.
+
+`printer-name`
+: The name of the redirected printer device that is passed through to the
+  RDP session. This is the name that the user will see in, for example, the
+  Devices and Printers control panel.
+
+  If printer redirection is not enabled, this option has no effect.
+
+`enable-drive`
+: File transfer is disabled by default, but with file transfer enabled, RDP
+  users can transfer files to and from a virtual drive which persists on the
+  Guacamole server. Enable file transfer support by setting this parameter
+  to "true".
+
+  Files will be stored in the directory specified by the "`drive-path`"
+  parameter, which is required if file transfer is enabled.
+
+`disable-download`
+: If set to true downloads from the remote server to client (browser) will
+  be disabled. This includes both downloads down via the hidden Guacamole

Review comment:
       downloads _done_ via ?

##########
File path: src/event-listeners.md
##########
@@ -0,0 +1,371 @@
+Event listeners
+===============
+
+Guacamole supports the delivery of event notifications to custom extensions.
+Developers can use listener extensions to integrate custom handling of events
+such as successful and failed authentications, and requests to connect and
+disconnect tunnels to desktop environments.
+
+A listener extension could be used, for example, to record authentication
+attempts in an external database for security auditing or alerting. By
+listening to tunnel lifecycle events, a listener extension could be used to
+help coordinate startup and shutdown of machine resources; particularly useful
+in cloud environments where minimizing running-but-idle resources is an
+important cost savings measure.
+
+For certain *vetoable* events, an event listener can even influence Guacamole's
+behavior. For example, a listener can veto a successful authentication,
+effectively causing the authentication to be considered failed. Similarly, a
+listener can veto a tunnel connection, effectively preventing the tunnel from
+being connected to a virtual desktop resource.
+
+Custom event listeners are packaged using the same extension mechanism used for
+custom authentication providers. A single listener extension can include any
+number of classes that implement the listener interface.  A single extension
+module can also include any combination of authentication providers and
+listeners, so developers can easily combine authentication providers with
+listeners designed to support them.
+
+To demonstrate the principles involved in receiving Guacamole event
+notifications, we will implement a simple listener extension that logs
+authentication events. While our approach simply writes event details to the
+same log used by the Guacamole web application, a listener could process these
+events in arbitrary ways, limited only by the imagination and ingenuity of the
+developer.
+
+(custom-event-listener-skeleton)=
+
+A Guacamole listener extension skeleton
+---------------------------------------
+
+For simplicity's sake, and because this is how things are done upstream in the
+Guacamole project, we will use Maven to build our extension.
+
+The bare minimum required for a Guacamole listener extension is a `pom.xml`
+file listing guacamole-ext as a dependency, a single `.java` file implementing
+our stub of a listener, and a `guac-manifest.json` file describing the
+extension and pointing to our listener class.
+
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.guacamole</groupId>
+    <artifactId>guacamole-listener-tutorial</artifactId>
+    <packaging>jar</packaging>
+    <version>1.3.0</version>
+    <name>guacamole-listener-tutorial</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+
+            <!-- Written for 1.6 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>

Review comment:
       This might need to be updated, as I think at least guacamole-ext has a minimum Java version of 1.8, now.

##########
File path: src/event-listeners.md
##########
@@ -0,0 +1,371 @@
+Event listeners
+===============
+
+Guacamole supports the delivery of event notifications to custom extensions.
+Developers can use listener extensions to integrate custom handling of events
+such as successful and failed authentications, and requests to connect and
+disconnect tunnels to desktop environments.
+
+A listener extension could be used, for example, to record authentication
+attempts in an external database for security auditing or alerting. By
+listening to tunnel lifecycle events, a listener extension could be used to
+help coordinate startup and shutdown of machine resources; particularly useful
+in cloud environments where minimizing running-but-idle resources is an
+important cost savings measure.
+
+For certain *vetoable* events, an event listener can even influence Guacamole's
+behavior. For example, a listener can veto a successful authentication,
+effectively causing the authentication to be considered failed. Similarly, a
+listener can veto a tunnel connection, effectively preventing the tunnel from
+being connected to a virtual desktop resource.
+
+Custom event listeners are packaged using the same extension mechanism used for
+custom authentication providers. A single listener extension can include any
+number of classes that implement the listener interface.  A single extension
+module can also include any combination of authentication providers and
+listeners, so developers can easily combine authentication providers with
+listeners designed to support them.
+
+To demonstrate the principles involved in receiving Guacamole event
+notifications, we will implement a simple listener extension that logs
+authentication events. While our approach simply writes event details to the
+same log used by the Guacamole web application, a listener could process these
+events in arbitrary ways, limited only by the imagination and ingenuity of the
+developer.
+
+(custom-event-listener-skeleton)=
+
+A Guacamole listener extension skeleton
+---------------------------------------
+
+For simplicity's sake, and because this is how things are done upstream in the
+Guacamole project, we will use Maven to build our extension.
+
+The bare minimum required for a Guacamole listener extension is a `pom.xml`
+file listing guacamole-ext as a dependency, a single `.java` file implementing
+our stub of a listener, and a `guac-manifest.json` file describing the
+extension and pointing to our listener class.
+
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.guacamole</groupId>
+    <artifactId>guacamole-listener-tutorial</artifactId>
+    <packaging>jar</packaging>
+    <version>1.3.0</version>
+    <name>guacamole-listener-tutorial</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+
+            <!-- Written for 1.6 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <!-- Guacamole Extension API -->
+        <dependency>
+            <groupId>org.apache.guacamole</groupId>
+            <artifactId>guacamole-ext</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Slf4j API -->
+        <!-- This is needed only if your listener wants to 
+                write to the Guacamole web application log -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.7</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
+```
+
+Naturally, we need the actual listener extension skeleton code. While you can
+put this in whatever file and package you want, for the sake of this tutorial,
+we will assume you are using `org.apache.guacamole.event.TutorialListener`.
+
+For now, we won't actually do anything other than log the fact that an event
+notification was received. At this point, we're just creating the skeleton for
+our listener extension.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener implementation intended to demonstrate basic use
+ * of Guacamole's listener extension API.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+         LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+        logger.info("received Guacamole event notification");
+    }
+
+}
+```
+
+To conform with Maven, this skeleton file must be placed within
+`src/main/java/org/apache/guacamole/event` as `TutorialListener.java`.
+
+As you can see, implementing a listener is quite simple. There is a single
+`Listener` interface to implement. All Guacamole event notifications will be
+delivered to your code by invoking the handleEvent method. We will see shortly
+how to use the passed event object to get the details of the event itself.
+
+The only remaining piece for the overall skeleton to be complete is a
+`guac-manifest.json` file. *This file is absolutely required for all Guacamole
+extensions.* The `guac-manifest.json` format is described in more detail in
+[](guacamole-ext). It provides for quite a few properties, but for our listener
+extension we are mainly interested in the Guacamole version sanity check (to
+make sure an extension built for the API of Guacamole version X is not
+accidentally used against version Y) and telling Guacamole where to find our
+listener class.
+
+The Guacamole extension format requires that `guac-manifest.json` be placed in
+the root directory of the extension `.jar` file. To accomplish this with Maven,
+we place it within the `src/main/resources` directory. Maven will automatically
+pick it up during the build and include it within the `.jar`.
+
+```json
+{
+
+    "guacamoleVersion" : "1.3.0",
+
+    "name"      : "Tutorial Listener Extension",
+    "namespace" : "guac-listener-tutorial",
+
+    "listeners" : [
+        "org.apache.guacamole.event.TutorialListener"
+    ]
+
+}
+```
+
+(custom-listener-building)=
+
+Building the extension
+----------------------
+
+Once all three of the above files are in place, the extension should build
+successfully even though it is just a skeleton at this point.
+
+```console
+$ mvn package
+[INFO] Scanning for projects...
+[INFO] ---------------------------------------------------------------
+[INFO] Building guacamole-listener-tutorial 1.3.0
+[INFO] ---------------------------------------------------------------
+...
+[INFO] ---------------------------------------------------------------
+[INFO] BUILD SUCCESS
+[INFO] ---------------------------------------------------------------
+[INFO] Total time: 1.297 s
+[INFO] Finished at: 2017-10-08T13:12:39-04:00
+[INFO] Final Memory: 19M/306M
+[INFO] ---------------------------------------------------------------
+$
+```
+
+Assuming you see the "`BUILD SUCCESS`" message when you build the extension,
+there will be a new file, `target/guacamole-listener-tutorial-1.3.0.jar`, which
+can be installed within Guacamole (see [](custom-listener-installing) at the
+end of this chapter).  It should log event notifications that occur during, for
+example, authentication attempts. If you changed the name or version of the
+project in the `pom.xml` file, the name of this new `.jar` file will be
+different, but it can still be found within `target/`.
+
+(custom-listener-event-handling)=
+
+Handling events
+---------------
+
+The Guacamole `Listener` interface represents a low-level event handling API. A
+listener is notified of every event generated by Guacamole. The listener must
+examine the event type to determine whether the event is of interest, and if so
+to dispatch the event to the appropriate entry point.
+
+The event types that can be produced by Guacamole are described in the
+`org.apache.guacamole.net.event` package of the guacamole-ext API. In this
+package you will find several concrete event types as well as interfaces that
+describe common characteristics of certain of event types. You can use any of
+these types to distinguish the events received by your listener, and to examine
+properties of an event of a given type.
+
+Suppose we wish to log authentication success and failure events, while
+ignoring all other event types. The `AuthenticationSuccessEvent` and
+`AuthenticationFailureEvent` types are used to notify a listener of
+authentication events. We can simply check whether a received event is of one
+of these types and, if so, log an appropriate message.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.AuthenticationFailureEvent;
+import org.apache.guacamole.net.event.AuthenticationSuccessEvent;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener that logs authentication success and failure events.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+        LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+
+        if (event instanceof AuthenticationSuccessEvent) {
+            logger.info("successful authentication for user {}", 
+                ((AuthenticationSuccessEvent) event)
+                    .getCredentials().getUsername());
+        }
+        else if (event instanceof AuthenticationFailureEvent) {
+            logger.info("failed authentication for user {}", 
+                ((AuthenticationFailureEvent) event)
+                    .getCredentials().getUsername());
+        }
+    }
+
+}
+```
+
+In our example, we use `instanceof` to check for the two event types of
+interest to our listener. Once we have identified an event of interest, we can
+safely cast the event type to access properties of the event.
+
+The extension is now complete and can be built as described earlier in
+[](custom-listener-building) and installed as described below in
+[](custom-listener-installing).
+
+(custom-listener-veto)=
+
+Influencing Guacamole by event veto
+-----------------------------------
+
+An implementation of the handleEvent method is permitted to throw any
+`GuacamoleException`. For certain *vetoable* event types, throwing a
+`GuacamoleException` serves to effectively veto the action that resulted in the
+event notification. See the API documentation for guacamole-ext to learn more
+about vetoable event types.
+
+As an (admittedly contrived) example, suppose we want to prevent a user named
+"guacadmin" from accessing Guacamole. For whatever reason, we don't wish to
+remove or disable the auth database entry for this user.  In this case we can
+use a listener to "blacklist" this user, preventing access to Guacamole. In the

Review comment:
       blacklist -> deny, block

##########
File path: src/guacamole-common.md
##########
@@ -0,0 +1,137 @@
+guacamole-common
+================
+
+The Java API provided by the Guacamole project is called guacamole-common. It
+provides a basic means of tunneling data between the JavaScript client provided
+by guacamole-common-js and the native proxy daemon, guacd, and for dealing with
+the Guacamole protocol. The purpose of this library is to facilitate the
+creation of custom tunnels between the JavaScript client and guacd, allowing
+your Guacamole-driven web application to enforce its own security model, if
+any, and dictate exactly what connections are established.
+
+(java-http-tunnel)=
+
+HTTP tunnel
+-----------
+
+The Guacamole Java API implements the HTTP tunnel using a servlet called
+`GuacamoleHTTPTunnelServlet`. This servlet handles all requests coming to it
+over HTTP from the JavaScript client, and translated them into connect, read,

Review comment:
       translated -> translates

##########
File path: src/writing-you-own-guacamole-app.md
##########
@@ -0,0 +1,585 @@
+Writing your own Guacamole application
+======================================
+
+As Guacamole is an API, one of the best ways to put Guacamole to use is by
+building your own Guacamole-driven web application, integrating HTML5 remote
+desktop into whatever you think needs it.
+
+The Guacamole project provides an example of doing this called
+"guacamole-example", but this example is already completed for you, and from a
+quick glance at this example, it may not be obvious just how easy it is to
+integrate remote access into a web application. This tutorial will walk you
+through the basic steps of building an HTML5 remote desktop application using
+the Guacamole API and Maven.
+
+(basic-guacamole-architecture)=
+
+The basics
+----------
+
+Guacamole's architecture is made up of many components, but it's actually
+straightforward, especially from the perspective of the web application.
+
+Guacamole has a proxy daemon, guacd, which handles communication using remote
+desktop protocols, exposing those to whatever connects to it (in this case, the
+web application) using the Guacamole protocol. From where the web application
+is standing, it doesn't really matter that guacd dynamically loads protocol
+plugins or that it shares a common library allowing this; all that matters is
+that the web application just has to connect to port 4822 (where guacd listens
+by default) and use the Guacamole protocol. The architecture will take care of
+the rest.
+
+Thankfully, the Java side of the Guacamole API provides simple classes which
+already implement the Guacamole protocol with the intent of tunneling it
+between guacd and the JavaScript half of your web application. A typical web
+application leveraging these classes needs
+only the following:
+
+1. A class which extends `GuacamoleHTTPTunnelServlet`, providing the tunnel
+   between the JavaScript client (presumably using guacamole-common-js) and
+   guacd.
+
+   `GuacamoleHTTPTunnelServlet` is an abstract class which is provided by the
+   Guacamole API and already implements a fully functional, HTTP-based tunnel
+   which the tunneling objects already part of guacamole-common-js are written
+   to connect to. This class exists to make it easy for you to use Guacamole's
+   existing and robust HTTP tunnel implementation.
+
+   If you want to not use this class and instead use your own tunneling
+   mechanism, perhaps WebSocket, this is fine; the JavaScript object mentioned
+   above implements a common interface which you can also implement, and the
+   Guacamole JavaScript client which is also part of guacamole-common-js will
+   happily use your implementation as long as it provides that interface.
+
+2. A web page which includes JavaScript files from guacamole-common-js and uses
+   the client and tunnel objects to connect back to the web application.
+
+   The JavaScript API provided by the Guacamole project includes a full
+   implementation of the Guacamole protocol as a client, implementations of
+   HTTP and WebSocket-based tunnels, and mouse/keyboard/touch input
+   abstraction. Again, as the Guacamole protocol and all parts of the
+   architecture are documented here, you don't absolutely need to use these
+   objects, but it will make your life easier. Mouse and keyboard support in
+   JavaScript is finicky business, and the Guacamole client provided is
+   well-known to work with other components in the API, being the official
+   client of the project.
+
+That's really all there is to it.
+
+If you want authentication, the place to implement that would be in your
+extended version of `GuacamoleHTTPTunnelServlet`; this is what the Guacamole
+web application does. Besides authentication, there are many other things you
+could wrap around your remote desktop application, but ultimately the base of
+all this is simple: you have a tunnel which allows the JavaScript client to
+communicate with guacd, and you have the JavaScript client itself, with the
+hard part already provided within guacamole-common-js.
+
+(web-app-skeleton)=
+
+Web application skeleton
+------------------------
+
+As with most tutorials, this tutorial begins with creating a project skeleton
+that establishes a minimal base for the tutorial to enhance in subsequent
+steps.
+
+This tutorial will use Maven, which is the same build system used by the
+upstream Guacamole project. As the Guacamole project has a Maven repository for
+both the Java and JavaScript APIs, writing a Guacamole-based application using
+Maven is much easier; Maven will download and use the Guacamole API
+automatically.
+
+### `pom.xml`
+
+All Maven projects must have a project descriptor, the `pom.xml` file, in the
+root directory of the project. This file describes project dependencies and
+specific build requirements. Unlike other build tools like Apache Ant or GNU
+Autotools, Maven chooses convention over configuration: files within the
+project must be placed in specific locations, and the project dependencies must
+be fully described in the pom.xml. If this is done, the build will be handled
+automatically.
+
+The basis of this Guacamole-driven web application will be a simple HTML file
+which will ultimately become the client. While the finished product will have
+an HTTP tunnel written in Java, we don't need this yet for our skeleton. We
+will create a very basic, barebones Maven project containing only `index.html`
+and a web application descriptor file, `web.xml`. Once these files are in
+place, the project can be packaged into a `.war` file which can be deployed to
+your servlet container of choice (such as Apache Tomcat).
+
+As this skeleton will contain no Java code, it has no dependencies, and
+no build requirements beyond the metadata common to any Maven project.
+The `pom.xml` is thus very simple for the time being:
+i
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
+                             http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.guacamole</groupId>
+    <artifactId>guacamole-tutorial</artifactId>
+    <packaging>war</packaging>
+    <version>1.3.0</version>
+    <name>guacamole-tutorial</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+</project>
+```
+
+### `WEB-INF/web.xml`
+
+Before the project will build, there needs to be a web application deployment
+descriptor, `web.xml`. This file is required by the Java EE standard for
+building the `.war` file which will contain the web application, and will be
+read by the servlet container when the application is actually deployed. For
+Maven to find and use this file when building the `.war`, it must be placed in
+the `src/main/webapp/WEB-INF/` directory.
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.5"
+    xmlns="http://java.sun.com/xml/ns/javaee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
+                        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+
+    <!-- Basic config -->
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+    </welcome-file-list>
+
+</web-app>
+```
+
+### `index.html`
+
+With the `web.xml` file in place and the skeleton `pom.xml` written, the web
+application will now build successfully. However, as the `web.xml` refers to a
+"welcome file" called `index.html` (which will ultimately contain our client),
+we need to put this in place so the servlet container will have something to
+serve. This file, as well as any other future static files, belongs within
+`src/main/webapp`.
+
+For now, this file can contain anything, since the other parts of our
+Guacamole-driven web application are not written yet. It is a placeholder which
+we will replace later:
+
+```html
+<!DOCTYPE HTML>
+<html>
+
+    <head>
+        <title>Guacamole Tutorial</title>
+    </head>
+
+    <body>
+        <p>Hello World</p>
+    </body>
+
+</html>
+```
+
+### Building the skeleton
+
+Once all three of the above files are in place, the web application will build,
+and can even be deployed to your servlet container. It won't do anything yet
+other than serve the `index.html` file, but it's good to at least try building
+the web application to make sure nothing is missing and all steps were followed
+correctly before proceeding:
+
+```console
+$ mvn package
+[INFO] Scanning for projects...
+[INFO] ------------------------------------------------------------------------
+[INFO] Building guacamole-tutorial
+[INFO]    task-segment: [package]
+[INFO] ------------------------------------------------------------------------
+...
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 4 seconds
+[INFO] Finished at: Fri Jan 11 13:04:11 PST 2013
+[INFO] Final Memory: 18M/128M
+[INFO] ------------------------------------------------------------------------
+$
+```
+
+Assuming you see the "`BUILD SUCCESSFUL`" message when you build the web
+application, there will be a new file, `target/guacamole-tutorial-1.3.0.war`,
+which can be deployed to your servlet container and tested. If you changed the
+name or version of the project in the `pom.xml` file, the name of this new
+`.war` file will be different, but it can still be found within `target/`.
+
+(guacamole-skeleton)=
+
+Adding Guacamole
+----------------
+
+Once we have a functional web application built, the next step is to actually
+add the references to the Guacamole API and integrate a Guacamole client into
+the application.
+
+(adding-guac-to-pom)=
+
+### Updating `pom.xml`
+
+Now that we're adding Guacamole components to our project, we need to modify
+`pom.xml` to specify which components are being used, and where they can be
+obtained. With this information in place, Maven will automatically resolve
+dependencies and download them as necessary during the build.
+
+Regarding the build process itself, there are two main changes: we are now
+going to be using Java, and we need the JavaScript files from
+guacamole-common-js included automatically inside the `.war`.
+
+Guacamole requires at least Java 1.6, thus we must add a section to the

Review comment:
       Did we recently push that to 1.8?

##########
File path: src/saml-auth.md
##########
@@ -0,0 +1,121 @@
+SAML Authentication
+===================
+
+SAML is a widely implemented and used Single Sign On (SSO) provider that allows
+applications and services to authenticate in a standard way, and brokers those
+authentication requests to one or more back-end authentication providers. The
+SAML authentication extension allows Guacamole to redirect to a SAML Identity
+Provider (IdP) for authentication and user services. This module does not
+provide any capability for storing or retrieving connections, and must be
+layered with other authentication extensions that provide connection
+management.
+
+(saml-downloading)=
+
+Downloading the SAML authentication extension
+---------------------------------------------
+
+The SAML authentication extension is available separately from the main
+`guacamole.war`. The link for this and all other officially-supported and
+compatible extensions for a particular version of Guacamole are provided on the
+release notes for that version. You can find the release notes for current
+versions of Guacamole here: <http://guacamole.apache.org/releases/>.
+
+The SAML authentication extension is packaged as a `.tar.gz` file containing
+only the extension itself, `guacamole-auth-saml-1.3.0.jar`, which must
+ultimately be placed in `GUACAMOLE_HOME/extensions`.
+
+(installing-saml-auth)=
+
+Installing SAML authentication
+------------------------------
+
+Guacamole extensions are self-contained `.jar` files which are located within
+the `GUACAMOLE_HOME/extensions` directory. *If you are unsure where
+`GUACAMOLE_HOME` is located on your system, please consult
+[](configuring-guacamole) before proceeding.*
+
+To install the SAML authentication extension, you must:
+
+1. Create the `GUACAMOLE_HOME/extensions` directory, if it does not already
+   exist.
+
+2. Copy `guacamole-auth-saml-1.3.0.jar` within `GUACAMOLE_HOME/extensions`.
+
+3. Configure Guacamole to use SAML authentication, as described below.
+
+(guac-saml-config)=
+
+### Configuring Guacamole for SAML Authentication
+
+The SAML authentication extension provides several configuration properties to
+set it up to talk to the IdP. The SAML IdP also must be configured with
+Guacamole as a Service Provider (SP). Configuration of the SAML IdP is beyond
+the scope of this document, and will vary widely based on the IdP in use.
+
+`saml-idp-metadata-url`
+: The URI of the XML metadata file that from the SAML Identity Provider that
+  contains all of the information the SAML extension needs in order to know how
+  to authenticate with the IdP. This URI can either be a remote server (e.g.
+  https://) or a local file on the filesystem (e.g. file://). Often the
+  metadata file contains most of the required properties for SAML
+  authentication and the other parameters are not required.
+
+`saml-idp-url`
+: The base URL of the SAML IdP. This is the URL that the SAML authentication
+  extension will use to redirect when requesting SAML authentication. If the
+  saml-idp-metadata property is provided, this parameter will be ignored. If

Review comment:
       Two things:
   1) If the _saml-idp-metadata-url_ property is provided (property name is incorrect).
   2) Should `saml-idp-metadata-url` be back-tick quoted or something along those lines to denote that it is a property, both on this line and throughout this section?

##########
File path: src/reverse-proxy.md
##########
@@ -0,0 +1,427 @@
+Proxying Guacamole
+==================
+
+Like most web applications, Guacamole can be placed behind a reverse proxy. For
+production deployments of Guacamole, this is *highly recommended*. It provides
+flexibility and, if your proxy is properly configured for SSL, encryption.
+
+Proxying isolates privileged operations within native applications that can
+safely drop those privileges when no longer needed, using Java only for
+unprivileged tasks. On Linux and UNIX systems, a process must be running with
+root privileges to listen on any port under 1024, including the standard HTTP
+and HTTPS ports (80 and 443 respectively). If the servlet container instead
+listens on a higher port, such as the default port 8080, it can run as a
+reduced-privilege user, allowing the reverse proxy to bear the burden of root
+privileges. As a native application, the reverse proxy can make system calls to
+safely drop root privileges once the port is open; a Java application like
+Tomcat cannot do this.
+
+(preparing-servlet-container)=
+
+Preparing your servlet container
+--------------------------------
+
+Your servlet container is most likely already configured to listen for HTTP
+connections on port 8080 as this is the default. If this is the case, and you
+can already access Guacamole over port 8080 from a web browser, you need not
+make any further changes to its configuration.
+
+If you *have* changed this, perhaps with the intent of proxying Guacamole over
+AJP, *change it back*. Using Guacamole over AJP is unsupported as it is known
+to cause problems, namely:
+
+1. WebSocket will not work over AJP, forcing Guacamole to fallback to HTTP,
+   possibly resulting in reduced performance.
+
+2. Apache 2.4.3 and older does not support the HTTP PATCH method over AJP,
+   preventing the Guacamole management interface from functioning properly.
+
+The connector entry within `conf/server.xml` should look like this:
+
+```xml
+<Connector port="8080" protocol="HTTP/1.1" 
+           connectionTimeout="20000"
+           URIEncoding="UTF-8"
+           redirectPort="8443" />
+```
+
+Be sure to specify the `URIEncoding="UTF-8"` attribute as above to ensure that
+connection names, user names, etc. are properly received by the web
+application. If you will be creating connections that have Cyrillic, Chinese,
+Japanese, or other non-Latin characters in their names or parameter values,
+this attribute is required.
+
+(tomcat-remote-ip)=
+
+### Setting up the Remote IP Valve
+
+By default, when Tomcat is behind a reverse proxy, the remote IP address of the
+client that it sees is that of the proxy rather than the original client. In
+order to allow applications hosted within Tomcat, like Guacamole, to see the
+actual IP address of the client, you have to configure both the reverse proxy
+and Tomcat.
+
+Because the remote IP address in Guacamole is used for auditing of user logins
+and connections and could potentially be used for authentication, it is
+important that you are either in direct control of the proxy server or you
+explicitly trust it. Passing the remote IP address is done using the
+`X-Forwarded-For` header, and, as with most HTTP headers, attackers can attempt
+to spoof this header in order to manipulate the behavior of the web server,
+gain unauthorized access to the system, or attempt to disguise the host or IP
+address they are coming from.
+
+One final caveat: This may not work as expected if there are other upstream
+proxy servers between your reverse proxy and the clients access Guacamole.
+Other proxies or firewalls can mask the IP address of the client, and if the
+configuration of those is not within your control you may end up with multiple
+clients appearing to come from the same IP address or host. Make sure you take
+this into account when configuring the system and looking at the data provided.
+
+Configuring Tomcat to pass through the remote IP address provided by the
+reverse proxy in the `X-Forwarded-For` header requires the configuration of
+what Tomcat calls a Valve. In this case, it is the
+[`RemoteIpValve`](https://tomcat.apache.org/tomcat-8.5-doc/config/valve.html#Remote_IP_Valve)
+and is configured in the `conf/server.xml` file, in the `<Host>` section:
+
+```xml
+<Valve className="org.apache.catalina.valves.RemoteIpValve"
+               internalProxies="127.0.0.1"
+               remoteIpHeader="x-forwarded-for"
+               remoteIpProxiesHeader="x-forwarded-by"
+               protocolHeader="x-forwarded-proto" />
+```
+
+The `internalProxies` value should be set to the IP address or addresses of any
+and all reverse proxy servers that will be accessing this Tomcat instance
+directly. Often it is run on the same system that runs Tomcat, but in other
+cases (for example, when running Docker), it may be on a different
+system/container and may need to be set to the actual IP address of the reverse
+proxy system. Only proxy servers listed in the `internalProxies` or
+`trustedProxies` parameters will be allowed to manipulate the remote IP address
+information. The other parameters in this configuration line allow you to
+control which headers coming from the proxy server(s) are used for various
+remote host information. They are as follows:
+
+`remoteIpHeader`
+: The header that is queried to learn the client IP address of the client
+  that originated the request. The standard value is `X-Forwarded-For`, but
+  can be configured to any header you like. The IP address in this header
+  will be available to Java applications in the `request.getRemoteAddr()`
+  method.
+
+`remoteIpProxiesHeader`
+: The header that is queried to learn the IP address of the proxy server
+  that forwarded the request. The default value is `X-Forwarded-By`, but can
+  be configured to any header that fits your environment. This value will
+  only be allowed by the valve if the proxy used is listed in the
+  `trustedProxies` parameter. Otherwise this header will not be available.
+
+`protocolHeader`
+: The header that is queried to determine the protocol that the client used
+  to connect to the service. The default value is `X-Forwarded-Proto`, but
+  can be configured to fit your environment.
+
+In addition to configuring Tomcat to properly handle these headers, you also
+may need to configure your reverse proxy appropriately to send the headers. You
+can find instructions for this in [](nginx) - the Apache web server passes it
+through by default.
+
+(nginx)=
+
+Nginx
+-----
+
+Nginx can be used as a reverse proxy, and supports WebSocket out-of-the-box
+[since version 1.3](http://nginx.com/blog/websocket-nginx/). Both Apache and
+Nginx require some additional configuration for proxying of WebSocket to work
+properly.
+
+(proxying-with-nginx)=
+
+### Proxying Guacamole
+
+Nginx does support WebSocket for proxying, but requires that the "Connection"
+and "Upgrade" HTTP headers are set explicitly due to the nature of the
+WebSocket protocol. From the Nginx documentation:
+
+> NGINX supports WebSocket by allowing a tunnel to be set up between a client
+> and a back-end server. For NGINX to send the Upgrade request from the client
+> to the back-end server, Upgrade and Connection headers must be set
+> explicitly. ...
+
+The proxy configuration belongs within a dedicated
+[`location`](http://nginx.org/en/docs/http/ngx_http_core_module.html#location>)
+block, declaring the backend hosting Guacamole and explicitly specifying the
+"`Connection`" and "`Upgrade`" headers mentioned earlier:
+
+```nginx
+location /guacamole/ {
+    proxy_pass http://HOSTNAME:8080;
+    proxy_buffering off;
+    proxy_http_version 1.1;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $http_connection;
+    access_log off;
+}
+```
+
+Here, `HOSTNAME` is the hostname or IP address of the machine hosting your
+servlet container, and 8080 is the port that servlet container is configured to
+use. You will need to replace these values with the correct values for your
+server.
+
+Related to the `RemoteIpValve` configuration for tomcat, documented in
+[Setting up the Remote IP Valve](tomcat-remote-ip), the `proxy_set_header
+X-Forwarded-For $proxy_add_x_forwarded_for;` line is important if you want the
+`X-Forwarded-For` header to be passed through to the web application server and
+available to applications running inside it.
+
+:::{important}
+*Do not forget to specify "`proxy_buffering off`".*
+
+Most proxies, including Nginx, will buffer all data sent over the connection,
+waiting until the connection is closed before sending that data to the client.
+As Guacamole's HTTP tunnel relies on streaming data to the client over an open
+connection, excessive buffering will effectively block Guacamole connections,
+rendering Guacamole useless.
+
+*If the option "`proxy_buffering off`" is not specified, Guacamole may not
+work*.
+:::
+
+(changing-path-with-nginx)=
+
+### Changing the path
+
+If you wish to serve Guacamole through Nginx under a path other than
+`/guacamole/`, the easiest method is to simply rename the `.war` file. For
+example, if intending to server Guacamole at `/new-path/`, you would:
+
+1. Rename `guacamole.war` to `new-path.war`.
+
+2. Update the path within the Nginx configuration to reflect the new
+   path:
+
+   :::{code-block} nginx
+   :emphasize-lines: 1
+   location /new-path/ {
+       proxy_pass http://HOSTNAME:8080;
+       proxy_buffering off;
+       proxy_http_version 1.1;
+       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+       proxy_set_header Upgrade $http_upgrade;
+       proxy_set_header Connection $http_connection;
+       access_log off;
+   }
+   :::
+
+
+Alternatively, the configuration can be altered slightly to handle requests at
+a different location externally while still serving internal requests at
+`/guacamole/`:
+
+:::{code-block} nginx
+:emphasize-lines: 1-2
+location /new-path/ {
+    proxy_pass http://HOSTNAME:8080/guacamole/;
+    proxy_buffering off;
+    proxy_http_version 1.1;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $http_connection;
+    access_log off;
+}
+:::
+
+(nginx-file-upload-size)=
+
+### Adjusting file upload limits
+
+When proxying Guacamole through Nginx, you may run into issues with the default
+limitations that Nginx places on file uploads (1MB). The errors you receive can
+be non-intuitive (permission denied, for example), but may be indicative of
+these limits. The `client_max_body_size` parameter can be set within the
+`location` block to configure the maximum file upload size:
+
+:::{code-block} nginx
+:emphasize-lines: 8
+location /guacamole/ {
+    proxy_pass http://HOSTNAME:8080;

Review comment:
       `/guacamole/`?

##########
File path: src/event-listeners.md
##########
@@ -0,0 +1,371 @@
+Event listeners
+===============
+
+Guacamole supports the delivery of event notifications to custom extensions.
+Developers can use listener extensions to integrate custom handling of events
+such as successful and failed authentications, and requests to connect and
+disconnect tunnels to desktop environments.
+
+A listener extension could be used, for example, to record authentication
+attempts in an external database for security auditing or alerting. By
+listening to tunnel lifecycle events, a listener extension could be used to
+help coordinate startup and shutdown of machine resources; particularly useful
+in cloud environments where minimizing running-but-idle resources is an
+important cost savings measure.
+
+For certain *vetoable* events, an event listener can even influence Guacamole's
+behavior. For example, a listener can veto a successful authentication,
+effectively causing the authentication to be considered failed. Similarly, a
+listener can veto a tunnel connection, effectively preventing the tunnel from
+being connected to a virtual desktop resource.
+
+Custom event listeners are packaged using the same extension mechanism used for
+custom authentication providers. A single listener extension can include any
+number of classes that implement the listener interface.  A single extension
+module can also include any combination of authentication providers and
+listeners, so developers can easily combine authentication providers with
+listeners designed to support them.
+
+To demonstrate the principles involved in receiving Guacamole event
+notifications, we will implement a simple listener extension that logs
+authentication events. While our approach simply writes event details to the
+same log used by the Guacamole web application, a listener could process these
+events in arbitrary ways, limited only by the imagination and ingenuity of the
+developer.
+
+(custom-event-listener-skeleton)=
+
+A Guacamole listener extension skeleton
+---------------------------------------
+
+For simplicity's sake, and because this is how things are done upstream in the
+Guacamole project, we will use Maven to build our extension.
+
+The bare minimum required for a Guacamole listener extension is a `pom.xml`
+file listing guacamole-ext as a dependency, a single `.java` file implementing
+our stub of a listener, and a `guac-manifest.json` file describing the
+extension and pointing to our listener class.
+
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.guacamole</groupId>
+    <artifactId>guacamole-listener-tutorial</artifactId>
+    <packaging>jar</packaging>
+    <version>1.3.0</version>
+    <name>guacamole-listener-tutorial</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+
+            <!-- Written for 1.6 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <!-- Guacamole Extension API -->
+        <dependency>
+            <groupId>org.apache.guacamole</groupId>
+            <artifactId>guacamole-ext</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Slf4j API -->
+        <!-- This is needed only if your listener wants to 
+                write to the Guacamole web application log -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.7</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
+```
+
+Naturally, we need the actual listener extension skeleton code. While you can
+put this in whatever file and package you want, for the sake of this tutorial,
+we will assume you are using `org.apache.guacamole.event.TutorialListener`.
+
+For now, we won't actually do anything other than log the fact that an event
+notification was received. At this point, we're just creating the skeleton for
+our listener extension.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener implementation intended to demonstrate basic use
+ * of Guacamole's listener extension API.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+         LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+        logger.info("received Guacamole event notification");
+    }
+
+}
+```
+
+To conform with Maven, this skeleton file must be placed within
+`src/main/java/org/apache/guacamole/event` as `TutorialListener.java`.
+
+As you can see, implementing a listener is quite simple. There is a single
+`Listener` interface to implement. All Guacamole event notifications will be
+delivered to your code by invoking the handleEvent method. We will see shortly
+how to use the passed event object to get the details of the event itself.
+
+The only remaining piece for the overall skeleton to be complete is a
+`guac-manifest.json` file. *This file is absolutely required for all Guacamole
+extensions.* The `guac-manifest.json` format is described in more detail in
+[](guacamole-ext). It provides for quite a few properties, but for our listener
+extension we are mainly interested in the Guacamole version sanity check (to
+make sure an extension built for the API of Guacamole version X is not
+accidentally used against version Y) and telling Guacamole where to find our
+listener class.
+
+The Guacamole extension format requires that `guac-manifest.json` be placed in
+the root directory of the extension `.jar` file. To accomplish this with Maven,
+we place it within the `src/main/resources` directory. Maven will automatically
+pick it up during the build and include it within the `.jar`.
+
+```json
+{
+
+    "guacamoleVersion" : "1.3.0",
+
+    "name"      : "Tutorial Listener Extension",
+    "namespace" : "guac-listener-tutorial",
+
+    "listeners" : [
+        "org.apache.guacamole.event.TutorialListener"
+    ]
+
+}
+```
+
+(custom-listener-building)=
+
+Building the extension
+----------------------
+
+Once all three of the above files are in place, the extension should build
+successfully even though it is just a skeleton at this point.
+
+```console
+$ mvn package
+[INFO] Scanning for projects...
+[INFO] ---------------------------------------------------------------
+[INFO] Building guacamole-listener-tutorial 1.3.0
+[INFO] ---------------------------------------------------------------
+...
+[INFO] ---------------------------------------------------------------
+[INFO] BUILD SUCCESS
+[INFO] ---------------------------------------------------------------
+[INFO] Total time: 1.297 s
+[INFO] Finished at: 2017-10-08T13:12:39-04:00
+[INFO] Final Memory: 19M/306M
+[INFO] ---------------------------------------------------------------
+$
+```
+
+Assuming you see the "`BUILD SUCCESS`" message when you build the extension,
+there will be a new file, `target/guacamole-listener-tutorial-1.3.0.jar`, which
+can be installed within Guacamole (see [](custom-listener-installing) at the
+end of this chapter).  It should log event notifications that occur during, for
+example, authentication attempts. If you changed the name or version of the
+project in the `pom.xml` file, the name of this new `.jar` file will be
+different, but it can still be found within `target/`.
+
+(custom-listener-event-handling)=
+
+Handling events
+---------------
+
+The Guacamole `Listener` interface represents a low-level event handling API. A
+listener is notified of every event generated by Guacamole. The listener must
+examine the event type to determine whether the event is of interest, and if so
+to dispatch the event to the appropriate entry point.
+
+The event types that can be produced by Guacamole are described in the
+`org.apache.guacamole.net.event` package of the guacamole-ext API. In this
+package you will find several concrete event types as well as interfaces that
+describe common characteristics of certain of event types. You can use any of
+these types to distinguish the events received by your listener, and to examine
+properties of an event of a given type.
+
+Suppose we wish to log authentication success and failure events, while
+ignoring all other event types. The `AuthenticationSuccessEvent` and
+`AuthenticationFailureEvent` types are used to notify a listener of
+authentication events. We can simply check whether a received event is of one
+of these types and, if so, log an appropriate message.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.AuthenticationFailureEvent;
+import org.apache.guacamole.net.event.AuthenticationSuccessEvent;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener that logs authentication success and failure events.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+        LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+
+        if (event instanceof AuthenticationSuccessEvent) {
+            logger.info("successful authentication for user {}", 
+                ((AuthenticationSuccessEvent) event)
+                    .getCredentials().getUsername());
+        }
+        else if (event instanceof AuthenticationFailureEvent) {
+            logger.info("failed authentication for user {}", 
+                ((AuthenticationFailureEvent) event)
+                    .getCredentials().getUsername());
+        }
+    }
+
+}
+```
+
+In our example, we use `instanceof` to check for the two event types of
+interest to our listener. Once we have identified an event of interest, we can
+safely cast the event type to access properties of the event.
+
+The extension is now complete and can be built as described earlier in
+[](custom-listener-building) and installed as described below in
+[](custom-listener-installing).
+
+(custom-listener-veto)=
+
+Influencing Guacamole by event veto
+-----------------------------------
+
+An implementation of the handleEvent method is permitted to throw any
+`GuacamoleException`. For certain *vetoable* event types, throwing a
+`GuacamoleException` serves to effectively veto the action that resulted in the
+event notification. See the API documentation for guacamole-ext to learn more
+about vetoable event types.
+
+As an (admittedly contrived) example, suppose we want to prevent a user named
+"guacadmin" from accessing Guacamole. For whatever reason, we don't wish to
+remove or disable the auth database entry for this user.  In this case we can
+use a listener to "blacklist" this user, preventing access to Guacamole. In the
+listener, when we get an `AuthenticationSuccessEvent` we can check to see if
+the user is "guacadmin" and, if so, throw an exception to prevent this user
+from logging in to Guacamole.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSecurityException;
+import org.apache.guacamole.net.event.AuthenticationFailureEvent;
+import org.apache.guacamole.net.event.AuthenticationSuccessEvent;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener that logs authentication success and failure events
+ * and prevents the "guacadmin" user from logging in by throwing
+ * a GuacamoleSecurityException.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+        LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+
+        if (event instanceof AuthenticationSuccessEvent) {
+          final String username = ((AuthenticationSuccessEvent) event)
+              .getCredentials().getUsername();
+
+          if ("guacadmin".equals(username)) {
+            logger.warn("user {} is blacklisted", username);
+            throw new GuacamoleSecurityException(
+                "User '" + username + "' is blacklisted");

Review comment:
       blacklisted -> denied, blocked

##########
File path: src/guacamole-common.md
##########
@@ -0,0 +1,137 @@
+guacamole-common
+================
+
+The Java API provided by the Guacamole project is called guacamole-common. It
+provides a basic means of tunneling data between the JavaScript client provided
+by guacamole-common-js and the native proxy daemon, guacd, and for dealing with
+the Guacamole protocol. The purpose of this library is to facilitate the
+creation of custom tunnels between the JavaScript client and guacd, allowing
+your Guacamole-driven web application to enforce its own security model, if
+any, and dictate exactly what connections are established.
+
+(java-http-tunnel)=
+
+HTTP tunnel
+-----------
+
+The Guacamole Java API implements the HTTP tunnel using a servlet called
+`GuacamoleHTTPTunnelServlet`. This servlet handles all requests coming to it
+over HTTP from the JavaScript client, and translated them into connect, read,
+or write requests, which each get dispatched to the `doConnect()`, `doRead()`,
+and `doWrite()` functions accordingly.
+
+Normally, you wouldn't touch the `doRead()` and `doWrite()` functions, as these
+have already been written to properly handle the requests of the JavaScript
+tunnel, and if you feel the need to touch these functions, you are probably
+better off writing your own tunnel implementation, although such a thing is
+difficult to do in a performant way.
+
+When developing an application based on the Guacamole API, you should use
+`GuacamoleHTTPTunnelServlet` by extending it, implementing your own version of
+`doConnect()`, which is the only abstract function it defines. The tutorial
+later in this book demonstrating how to write a Guacamole-based web application
+shows the basics of doing this, but generally, `doConnect()` is an excellent
+place for authentication or other validation, as it is the responsibility of
+`doConnect()` to create (or not create) the actual tunnel. If `doConnect()`
+does not create the tunnel, communication between the JavaScript client and
+guacd cannot take place, which is an ideal power to have as an authenticator.
+
+The `doConnect()` function is expected to return a new `GuacamoleTunnel`, but
+it is completely up to the implementation to decide how that tunnel is to be
+created. The already-implemented parts of `GuacamoleHTTPTunnelServlet` then
+return the unique identifier of this tunnel to the JavaScript client, allowing
+its own tunnel implementation to continue to communicate with the tunnel
+existing on the Java side.
+
+Instances of `GuacamoleTunnel` are created associated with a `GuacamoleSocket`,

Review comment:
       created associated? Maybe just _associated_?

##########
File path: src/troubleshooting.md
##########
@@ -0,0 +1,539 @@
+Troubleshooting
+===============
+
+(not-working)=
+
+It isn't working
+----------------
+
+If Guacamole isn't working, chances are something isn't configured properly, or
+something is wrong with the network. Thankfully, Guacamole and all its
+components log errors thoroughly, so the problem can usually be traced down
+fairly easily if you know where to look. Troubleshooting Guacamole usually
+boils down to checking either syslog or your servlet container's logs (likely
+Tomcat).
+
+Failing all that, you can always post a question in the forums, or if you truly
+feel you've discovered a bug, you can create a new ticket in Trac. Beware that
+if something isn't working, and there are errors in the logs describing the
+problem, it is usually not a bug, and the best place to handle such things is
+through consulting this guide or the forums.
+
+### No graphics appear
+
+If you *never* see any graphics appear, or you see "Connecting, waiting for
+first update..." for a while and then are disconnected, the most likely cause
+is a proxy.
+
+Guacamole relies on streaming data to you over a persistent connection.  If
+software between Guacamole and your browser is buffering all incoming data,
+such as a proxy, this data never makes it to your browser, and you will just
+see it wait indefinitely. Eventually, thinking the client has disconnected,
+Guacamole closes the connection, at which point the proxy finally flushes its
+buffer and you see graphics! ... just in time to see it disconnect.
+
+The solution here is to either modify your proxy settings to flush packets
+immediately as they are received, or to use HTTPS. Proxies are required to pass
+HTTPS through untouched, and this usually solves the problem.
+
+Even if you aren't aware of any proxy, there may be one in place.  Corporate
+firewalls very often incorporate proxies. Antivirus software may buffer
+incoming data until the connection is closed and the data is scanned for
+viruses. Virtualization software may detect HTTP data and buffer the connection
+just like a proxy. If all else fails, try HTTPS - it's the only secure way to
+do this anyway.
+
+### Connections involving Unicode don't work
+
+If you are using Tomcat, beware that you *must* set the `URIEncoding="UTF-8"`
+attribute on all connectors in your `server.xml`. If you are using a different
+servlet container, you need to find out whether it requires special options to
+support UTF-8 in URIs, and change the required settings to enable such support.
+
+Without UTF-8 support enabled for URIs, Unicode characters in connection names
+will not be received properly when connecting, and Guacamole will thing the
+connection you requested does not exist. Similarly, if you are using the
+built-in administration interface, parameters involving Unicode characters will
+not save properly without these options enabled.
+
+syslog
+------
+
+guacd and libguac-based programs (such as all client plugins) log informational
+messages and errors to syslog. Specifically, guacd uses syslog, and it exposes
+this logging facility to everything it loads (client plugins), thus if the VNC
+or RDP support plugins encounter errors, they log those errors over the logging
+facilities exposed by guacd, in this case syslog.
+
+Once you guacd is started, you'll see entries like the following in syslog:
+
+```
+guacd[19663]: Guacamole proxy daemon (guacd) version 0.7.0
+guacd[19663]: Unable to bind socket to host ::1, port 4823: Address family
+              not supported by protocol
+guacd[19663]: Successfully bound socket to host 127.0.0.1, port 4823
+guacd[19663]: Exiting and passing control to PID 19665
+guacd[19665]: Exiting and passing control to PID 19666
+guacd[19666]: Listening on host 127.0.0.1, port 4823
+```
+
+Each entry relevant to Guacamole has the prefix "guacd", denoting the program
+that produced the entry, followed by the process ID, followed by the message.
+The entries above show guacamole starting successfully and listening on a
+non-default port 4823.
+
+### guacd errors
+
+#### Unable to bind socket to any addresses.
+
+This means that guacd failed to start up at all because the port it wants to
+listen on is already taken at all addresses attempted. The details of what
+guacd tried will be listed in the log entries above this. To solve the problem,
+find what port guacd was trying to listen on (the default is 4822) and check if
+any other service is listening on that port.
+
+If another service is listening on the default port, you can always specify a
+non-standard port for guacd by using the `-l PORT` option (that's a lowercase
+"L", not a number "1"), where <PORT> is the number of the port to listen on.
+Beware that you will likely have to modify `guacamole.properties` so that
+Guacamole knows how to connect to guacd.
+
+#### Unable to start input thread
+
+guacd creates two threads for each connection: one that receives input from the
+connected client, and the other that produces output for the client. If either
+of these fails to start, the above error will be logged along with the cause.
+
+If it is the output thread that fails to start, the message will instead read:
+"Unable to start output thread".
+
+#### Client finished abnormally
+
+If the client plugin ever returns an error code, this will cause the connection
+to immediately terminate, with the cause of the error specific to the plugin in
+use. The cause should be detailed in the log messages above the error. If those
+log messages don't make sense, you may have found a bug.
+
+#### Could not fork() parent
+
+When guacd starts up, it immediately attempts to "fork" into the background
+(unless instructed otherwise). The word "fork()" above is a reference to the C
+function call that does this. There are several calls to this function, each of
+which might fail if system resources are lacking or something went wrong at a
+low level. If you see this message, it is probably not a bug in Guacamole, but
+rather a problem with the load level of your system.
+
+This message may also appear as "Could not fork() group leader".
+
+#### Unable to change working directory to /
+
+One of the duties of guacd as it starts up is to change its working directory
+to the root directory. This is to prevent locking the current directory in case
+it needs to be unmounted, etc. If guacd cannot do this, this error will be
+logged, along with the cause.
+
+#### Unable to redirect standard file descriptors to /dev/null
+
+As guacd starts, it also has to redirect STDOUT, STDERR, and STDIN to
+`/dev/null` such that attempts to use these output mechanisms do not pollute
+the active console. Though guacd and client plugins will use the exposed
+logging facilities (and thus syslog) rather than STDOUT or STDERR, libraries
+used by client plugins are often written only from the mindset of a typical
+client, and use standard output mechanisms for debug logging. Not redirecting
+these would result in undesired output to the console.
+
+If guacd cannot redirect these file descriptors for any reason, this error will
+be logged, along with the cause.
+
+####  Error parsing given address or port: HOSTNAME
+
+If you specified a host or port to listen on via commandline options, and that
+host or port is actually invalid, you will see this error. Fix the
+corresponding option and try again.
+
+#### Error opening socket
+
+When guacd starts up, it needs to open a socket and then listen on that socket.
+If it can't even open the socket, this error will be logged, and guacd will
+exit. The cause is most likely related to permissions, and is logged along with
+the error.
+
+#### Unable to resolve host
+
+If the hostname you specified on the commandline cannot be found, you will see
+this error. Note that this error is from guacd, and does not relate to whatever
+remote desktop servers you may be trying to use; it relates only to the host
+guacd is trying to listen on. Check the hostname or IP address specified on the
+commandline. If that checks out, there may be a problem with your DNS or your
+network.
+
+#### Could not become a daemon
+
+In order to become a "daemon" (that is, in order to run in the background as a
+system process), guacd must create and exit from several processes, redirect
+file descriptors, etc. If any of these steps fails, guacd will not become a
+daemon, and it will log this message and exit.  The reason guacd could not
+become a daemon will be in the previous error message in the logs.
+
+#### Could not write PID file
+
+guacd offers a commandline option that lets you specify a file that it should
+write its process ID into, which is useful for init scripts. If you see this
+error, it likely means the user guacd is running as does not have permission to
+write this file. The true cause of the error will be logged in the same entry.
+Check which user guacd is running as, and then check that it has write
+permission to the file in question.
+
+#### Could not listen on socket
+
+When guacd starts up, it needs to listen on the socket it just opened in order
+to accept connections. If it cannot listen on the socket, clients will be
+unable to connect. If, for any reason, guacd is unable to listen on the socket,
+guacd will exit and log this message along with the cause, which is most likely
+a low-level system resource problem.
+
+#### Could not accept client connection
+
+When a client connects to guacd, it must accept the connection in order for
+communication to ensue. If it cannot even accept the connection, no
+communication between server and client will happen, and this error will be
+logged. The cause of the error will be logged in the same entry.  Possible
+causes include permissions problems, or lack of server resources.
+
+#### Error forking child process
+
+When a client connects to guacd, it must create a new process to handle the
+connection while the old guacd process continues to listen for new connections.
+If, for any reason, guacd cannot create this process, the connection from that
+client will be denied, and the cause of the error will be logged. Possible
+causes include permissions problems, or lack of server resources.
+
+#### Error closing daemon reference to child descriptor
+
+When guacd receives a connection, and it creates a new process to handle that
+connection, it gains a copy of the file descriptor that the client will use for
+communication. As this connection can never be closed unless all references to
+the descriptor are closed, the server must close its copy such that the client
+is the only remaining holder of the file descriptor. If the server cannot close
+the descriptor, it will log this error message along with the cause.
+
+#### Error sending "sync" instruction
+
+During the course of a Guacamole session, guacd must occasionally "ping" the
+client to make sure it is still alive. This ping takes the form of a "sync"
+instruction, which the client is obligated to respond to as soon as it is
+received. If guacd cannot send this instruction, this error will be logged,
+along with the cause. Chances are the connection has simply been closed, and
+this error can be ignored.
+
+#### Error flushing output
+
+After the client plugin is finished (for the time being) with handling server
+messages, the socket is automatically flushed. If the server cannot flush this
+socket for some reason, such as the connection already being closed, you will
+see this error. Normally, this error does not indicate a problem, but rather
+that the client has simply closed the connection.
+
+#### Error handling server messages
+
+While the client plugin is running, guacd will occasionally ask the plugin to
+check and handle any messages that it may have received from the server it
+connected to. If the client plugin fails for some reason while doing this, this
+error will be logged, and the cause of the error will likely be logged in
+previous log entries by the client plugin.
+
+#### Error reading instruction
+
+During the course of a Guacamole session, instructions are sent from client to
+server which are to be handled by the client plugin. If an instruction cannot
+be read, this error will be logged. Usually this means simply that the
+connection was closed, but it could also indicate that the version of the
+client in use is so old that it doesn't support the current Guacamole protocol
+at all. If the cause looks like the connection was closed (end of stream
+reached, etc.), this log entry can be ignored. Otherwise, if the first two
+numbers of the version numbers of all Guacamole components match, you have
+probably found a bug.
+
+#### Client instruction handler error
+
+This error indicates that a client plugin failed inside the handler for a
+specific instruction. When the server receives instructions from the client, it
+then invokes specific instruction handles within the client plugin. In general,

Review comment:
       handles or handlers?

##########
File path: src/configuring-guacamole.md
##########
@@ -0,0 +1,2770 @@
+Configuring Guacamole
+=====================
+
+After installing Guacamole, you need to configure users and connections before
+Guacamole will work. This chapter covers general configuration of Guacamole and
+the use of its default authentication method.
+
+Guacamole's default authentication method reads all users and connections from
+a single file called `user-mapping.xml`. This authentication method is intended
+to be:
+
+1. Sufficient for small deployments of Guacamole.
+
+2. A relatively-easy means of verifying that Guacamole has been properly set
+   up.
+
+Other, more complex authentication methods which use backend databases, LDAP,
+etc. are discussed in a separate, dedicated chapters.
+
+Regardless of the authentication method you use, Guacamole's configuration
+always consists of two main pieces: a directory referred to as
+`GUACAMOLE_HOME`, which is the primary search location for configuration files,
+and `guacamole.properties`, the main configuration file used by Guacamole and
+its extensions.
+
+(guacamole-home)=
+
+`GUACAMOLE_HOME` (`/etc/guacamole`)
+---------------------------------------
+
+`GUACAMOLE_HOME` is the name given to Guacamole's configuration directory,
+which is located at `/etc/guacamole` by default. All configuration files,
+extensions, etc. reside within this directory. The structure of
+`GUACAMOLE_HOME` is rigorously defined, and consists of the following optional
+files:
+
+`guacamole.properties`
+: The main Guacamole configuration file. Properties within this file dictate
+  how Guacamole will connect to guacd, and may configure the behavior of
+  installed authentication extensions.
+
+`logback.xml`
+: Guacamole uses a logging system called Logback for all messages. By
+  default, Guacamole will log to the console only, but you can change this
+  by providing your own Logback configuration file.
+
+`extensions/`
+: The install location for all Guacamole extensions. Guacamole will
+  automatically load all `.jar` files within this directory on startup.
+
+`lib/`
+: The search directory for libraries required by any Guacamole extensions.
+  Guacamole will make the `.jar` files within this directory available to
+  all extensions. If your extensions require additional libraries, such as
+  database drivers, this is the proper place to put them.
+
+(overriding-guacamole-home)=
+
+### Overriding `GUACAMOLE_HOME`
+
+If you cannot or do not wish to use `/etc/guacamole` for `GUACAMOLE_HOME`, the
+location can be overridden through any of the following methods:
+
+1. Creating a directory named `.guacamole`, within the home directory of *the
+   user running the servlet container*. This directory will automatically be
+   used for `GUACAMOLE_HOME` if it exists.
+
+2. Specifying the full path to an alternative directory with the environment
+   variable `GUACAMOLE_HOME`. *Be sure to consult the documentation for your
+   servlet container to determine how to properly set environment variables.*
+
+3. Specifying the full path to an alternative directory with the system
+   property guacamole.home.
+
+(initial-setup)=
+
+`guacamole.properties`
+------------------------
+
+The Guacamole web application uses one main configuration file called
+`guacamole.properties`. This file is the common location for all configuration
+properties read by Guacamole or any extension of Guacamole, including
+authentication providers.
+
+In previous releases, this file had to be in the classpath of your servlet
+container. Now, the location of `guacamole.properties` can be explicitly
+defined with environment variables or system properties, and the classpath is
+only used as a last resort. When searching for `guacamole.properties`,
+Guacamole will check, in order:
+
+1. Within `GUACAMOLE_HOME`, as defined above.
+
+2. The classpath of the servlet container.
+
+The `guacamole.properties` file is optional and is used to configure Guacamole
+in situations where the defaults are insufficient, or to provide additional
+configuration information for extensions. There are several standard properties
+that are always available for use:
+
+`api-session-timeout`
+: The amount of time, in minutes, to allow Guacamole sessions
+  (authentication tokens) to remain valid despite inactivity. If omitted,
+  Guacamole sessions will expire after 60 minutes of inactivity.
+
+`api-max-request-size`
+: The maximum number of bytes to accept within the entity body of any
+  particular HTTP request, where 0 indicates that no limit should be
+  applied. If omitted, requests will be limited to 2097152 bytes (2 MB) by
+  default. This limit does not apply to file uploads.
+
+  If using a reverse proxy for SSL termination, *keep in mind that reverse
+  proxies may enforce their own limits independently of this*. For example,
+  [Nginx will enforce a 1 MB request size limit by
+  default](nginx-file-upload-size).
+
+`allowed-languages`
+: A comma-separated whitelist of language keys to allow as display language
+  choices within the Guacamole interface. For example, to restrict Guacamole
+  to only English and German, you would specify:
+
+  ```
+  allowed-languages: en, de
+  ```
+
+  As English is the fallback language, used whenever a translation key is
+  missing from the chosen language, English should only be omitted from this
+  list if you are absolutely positive that no strings are missing.
+
+  The corresponding JSON of any built-in languages not listed here will
+  still be available over HTTP, but the Guacamole interface will not use
+  them, nor will they be used automatically based on local browser language.
+  If omitted, all defined languages will be available.
+
+`enable-environment-properties`
+: If set to "true", Guacamole will first evaluate its environment to obtain
+  the value for any given configuration property, before using a value
+  specified in `guacamole.properties` or falling back to a default value. By
+  enabling this option, you can easily override any other configuration
+  property using an environment variable.
+
+  ```
+  enable-environment-properties: true
+  ```
+
+  When searching for a configuration property in the environment, the name
+  of the property is first transformed by converting all lower case
+  characters to their upper case equivalents, and by replacing all hyphen
+  characters (`-`) with underscore characters (`_`). For example, the
+  `guacd-hostname` property would be transformed to `GUACD_HOSTNAME` when
+  searching the environment.
+
+`guacd-hostname`
+: The host the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on localhost.
+
+`guacd-port`
+: The port the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on port 4822.
+
+`guacd-ssl`
+: If set to "true", Guacamole will require SSL/TLS encryption between the
+  web application and guacd. By default, communication between the web
+  application and guacd will be unencrypted.
+
+  Note that if you enable this option, you must also configure guacd to use
+  SSL via command line options. These options are documented in the manpage
+  of guacd. You will need an SSL certificate and private key.
+
+`skip-if-unavailable`
+: A comma-separated list of the identifiers of authentication providers that
+  should be allowed to fail internally without aborting the authentication
+  process. For example, to request that Guacamole ignore failures due to the
+  LDAP directory or MySQL server being unexpectedly down, allowing other
+  authentication providers to continue functioning:
+
+  ```
+  skip-if-unavailable: mysql, ldap
+  ```
+
+  By default, Guacamole takes a conservative approach to internal failures,
+  aborting the authentication process if an internal error occurs within any
+  authentication provider. Depending on the nature of the error, this may
+  mean that no users can log in until the cause of the failure is dealt
+  with. The `skip-if-unavailable` property may be used to explicitly inform
+  Guacamole that one or more underlying systems are expected to occasionally
+  experience failures, and that other functioning systems should be relied
+  upon if they do fail.
+
+
+```
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port:     4822
+```
+
+(webapp-logging)=
+
+Logging within the web application
+----------------------------------
+
+By default, Guacamole logs all messages to the console. Servlet containers like
+Tomcat will automatically redirect these messages to a log file, `catalina.out`
+in the case of Tomcat, which you can read through while Guacamole runs.
+Messages are logged at four different log levels, depending on message
+importance and severity:
+
+`error`
+: Errors are fatal conditions. An operation, described in the log message,
+  was attempted but could not proceed, and the failure of this operation is
+  a serious problem that needs to be addressed.
+
+`warn`
+: Warnings are generally non-fatal conditions. The operation continued, but
+  encountered noteworthy problems.
+
+`info`
+: "Info" messages are purely informational. They may be useful or
+  interesting to administrators, but are not generally critical to proper
+  operation of a Guacamole server.
+
+`debug`
+: Debug messages are highly detailed and oriented toward development. Most
+  debug messages will contain stack traces and internal information that is
+  useful when investigating problems within code. It is expected that debug
+  messages, though verbose, will not affect performance.
+
+`trace`
+: Trace messages are similar to debug messages in intent and verbosity, but
+  are so low-level that they may affect performance due to their frequency.
+  Trace-level logging is rarely necessary, and is mainly useful in providing
+  highly detailed context around issues being investigated.
+
+Guacamole logs messages using a logging framework called
+[Logback](http://logback.qos.ch/) and, by default, will only log messages at
+the "`info`" level or higher. If you wish to change the log level, or configure
+how or where Guacamole logs messages, you can do so by providing your own
+`logback.xml` file within `GUACAMOLE_HOME`.  For example, to log all messages
+to the console, even "`debug`" messages, you might use the following
+`logback.xml`:
+
+```xml
+<configuration>
+
+    <!-- Appender for debugging -->
+    <appender name="GUAC-DEBUG" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log at DEBUG level -->
+    <root level="debug">
+        <appender-ref ref="GUAC-DEBUG"/>
+    </root>
+
+</configuration>
+```
+
+Guacamole and the above example configure only one appender which logs to the
+console, but Logback is extremely flexible and allows any number of appenders
+which can each log to separate files, the console, etc.  based on a number of
+criteria, including the log level and the source of the message.
+
+More thorough [documentation on configuring
+Logback](http://logback.qos.ch/manual/configuration.html) is provided on the
+Logback project's web site.
+
+(basic-auth)=
+
+Using the default authentication
+--------------------------------
+
+Guacamole's default authentication module is simple and consists of a mapping
+of usernames to configurations. This authentication module comes with Guacamole
+and simply reads usernames and passwords from an XML file. It is always
+enabled, but will only read from the XML file if it exists, and is always last
+in priority relative to any other authentication extensions.
+
+There are other authentication modules available. The Guacamole project
+provides database-backed authentication modules with the ability to manage
+connections and users from the web interface, and other authentication modules
+can be created using the extension API provided along with the Guacamole web
+application, guacamole-ext.
+
+(user-mapping)=
+
+### `user-mapping.xml`
+
+The default authentication provider used by Guacamole reads all username,
+password, and configuration information from a file called the "user mapping"
+located at `GUACAMOLE_HOME/user-mapping.xml`. An example of a user mapping file
+is included with Guacamole, and looks something like this:
+
+```xml
+<user-mapping>
+
+    <!-- Per-user authentication and config information -->
+    <authorize username="USERNAME" password="PASSWORD">
+        <protocol>vnc</protocol>
+        <param name="hostname">localhost</param>
+        <param name="port">5900</param>
+        <param name="password">VNCPASS</param>
+    </authorize>
+
+    <!-- Another user, but using md5 to hash the password
+         (example below uses the md5 hash of "PASSWORD") -->
+    <authorize
+            username="USERNAME2"
+            password="319f4d26e3c536b5dd871bb2c52e3178"
+            encoding="md5">
+
+        <!-- First authorized connection -->
+        <connection name="localhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">localhost</param>
+            <param name="port">5901</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+        <!-- Second authorized connection -->
+        <connection name="otherhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">otherhost</param>
+            <param name="port">5900</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+    </authorize>
+
+</user-mapping>
+```
+
+Each user is specified with a corresponding `<authorize>` tag. This tag
+contains all authorized connections for that user, each denoted with a
+`<connection>` tag. Each `<connection>` tag contains a corresponding protocol
+and set of protocol-specific parameters, specified with the `<protocol>` and
+`<param>` tags respectively.
+
+(user-setup)=
+
+#### Adding users
+
+When using `user-mapping.xml`, username/password pairs are specified with
+`<authorize>` tags, which each have a `username` and `password` attribute. Each
+`<authorize>` tag authorizes a specific username/password pair to access all
+connections within the tag:
+
+```xml
+<authorize username="USER" password="PASS">
+    ...
+</authorize>
+```
+
+In the example above, the password would be listed in plaintext. If you don't
+want to do this, you can also specify your password hashed with MD5:
+
+```xml
+<authorize username="USER"
+           password="319f4d26e3c536b5dd871bb2c52e3178"
+           encoding="md5">
+    ...
+</authorize>
+```
+
+After modifying `user-mapping.xml`, the file will be automatically reread by
+Guacamole, and your changes will take effect immediately. The newly-added user
+will be able to log in - no restart of the servlet container is needed.
+
+(connection-setup)=
+
+#### Adding connections to a user
+
+To specify a connection within an `<authorize>` tag, you can either list a
+single protocol and set of parameters (specified with a `<protocol>` tag and
+any number of `<param>` tags), in which case that user will have access to only
+one connection named "DEFAULT", or you can specify one or more connections with
+one or more `<connection>` tags, each of which can be named and contains a
+`<protocol>` tag and any number of `<param>` tags.
+
+(connection-configuration)=
+
+Configuring connections
+-----------------------
+
+Each protocol supported by Guacamole has its own set of configuration
+parameters. These parameters typically describe the hostname and port of the
+remote desktop server, the credentials to use when connecting, if any, and the
+size and color depth of the display. If the protocol supports file transfer,
+options for enabling that functionality will be provided as well.
+
+### VNC
+
+The VNC protocol is the simplest and first protocol supported by Guacamole.
+Although generally not as fast as RDP, many VNC servers are adequate, and VNC
+over Guacamole tends to be faster than VNC by itself due to decreased bandwidth
+usage.
+
+VNC support for Guacamole is provided by the libguac-client-vnc library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the VNC-specific parameters below, Guacamole's VNC support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(vnc-network-parameters)=
+
+#### Network parameters
+
+With the exception of reverse-mode VNC connections, VNC works by making
+outbound network connections to a particular host which runs one or more VNC
+servers. Each VNC server is associated with a display number, from which the
+appropriate port number is derived.
+
+`hostname`
+: The hostname or IP address of the VNC server Guacamole should connect to.
+
+`port`
+: The port the VNC server is listening on, usually 5900 or 5900 + display
+  number. For example, if your VNC server is serving display number 1
+  (sometimes written as `:1`), your port number here would be 5901.
+
+`autoretry`
+: The number of times to retry connecting before giving up and returning an
+  error. In the case of a reverse connection, this is the number of times
+  the connection process is allowed to time out.
+
+(vnc-authentication)=
+
+#### Authentication
+
+The VNC standard defines only password based authentication. Other
+authentication mechanisms exist, but are non-standard or proprietary.
+Guacamole currently supports both standard password-only based authentication,
+as well as username and password authentication.
+
+`username`
+: The username to use when attempting authentication, if any. This parameter
+  is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+(vnc-display-settings)=
+
+#### Display settings
+
+VNC servers do not allow the client to request particular display sizes, so you
+are at the mercy of your VNC server with respect to display width and height.
+However, to reduce bandwidth usage, you may request that the VNC server reduce
+its color depth. Guacamole will automatically detect 256-color images, but this
+can be guaranteed for absolutely all graphics sent over the connection by
+forcing the color depth to 8-bit. Color depth is otherwise dictated by the VNC
+server.
+
+If you are noticing problems with your VNC display, such as the lack of a mouse
+cursor, the presence of multiple mouse cursors, or strange colors (such as blue
+colors appearing more like orange or red), these are typically the result of
+bugs or limitations within the VNC server, and additional parameters are
+available to work around such issues.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, 24, or 32. Regardless of what
+  value is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`swap-red-blue`
+: If the colors of your display appear wrong (blues appear orange or red,
+  etc.), it may be that your VNC server is sending image data incorrectly,
+  and the red and blue components of each color are swapped. If this is the
+  case, set this parameter to "true" to work around the problem. This
+  parameter is optional.
+
+`cursor`
+: If set to "remote", the mouse pointer will be rendered remotely, and the
+  local position of the mouse pointer will be indicated by a small dot. A
+  remote mouse cursor will feel slower than a local cursor, but may be
+  necessary if the VNC server does not support sending the cursor image to
+  the client.
+
+`encodings`
+: A space-delimited list of VNC encodings to use. The format of this
+  parameter is dictated by libvncclient and thus doesn't really follow the
+  form of other Guacamole parameters. This parameter is optional, and
+  libguac-client-vnc will use any supported encoding by default.
+
+  Beware that this parameter is intended to be replaced with individual,
+  encoding-specific parameters in a future release.
+
+`read-only`
+: Whether this connection should be read-only. If set to "true", no input
+  will be accepted on the connection at all. Users will only see the desktop
+  and whatever other users using that same desktop are doing. This parameter
+  is optional.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+#### VNC Repeater
+
+There exist VNC repeaters, such as UltraVNC Repeater, which act as
+intermediaries or proxies, providing a single logical VNC connection which is
+then routed to another VNC server elsewhere. Additional parameters are required
+to select which VNC host behind the repeater will receive the connection.
+
+`dest-host`
+: The destination host to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+`dest-port`
+: The destination port to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+(vnc-reverse-connections)=
+
+#### Reverse VNC connections
+
+Guacamole supports "reverse" VNC connections, where the VNC client listens for
+an incoming connection from the VNC server. When reverse VNC connections are
+used, the VNC client and server switch network roles, but otherwise function as
+they normally would. The VNC server still provides the remote display, and the
+VNC client still provides all keyboard and mouse input.
+
+`reverse-connect`
+: Whether reverse connection should be used. If set to "true", instead of
+  connecting to a server at a given hostname and port, guacd will listen on
+  the given port for inbound connections from a VNC server.
+
+`listen-timeout`
+: If reverse connection is in use, the maximum amount of time to wait for an
+  inbound connection from a VNC server, in milliseconds. If blank, the
+  default value is 5000 (five seconds).
+
+(vnc-audio)=
+
+#### Audio support (via PulseAudio)
+
+VNC does not provide its own support for audio, but Guacamole's VNC support can
+obtain audio through a secondary network connection to a PulseAudio server
+running on the same machine as the VNC server.
+
+Most Linux systems provide audio through a service called PulseAudio.  This
+service is capable of communicating over the network, and if PulseAudio is
+configured to allow TCP connections, Guacamole can connect to your PulseAudio
+server and combine its audio with the graphics coming over VNC.
+
+Configuring PulseAudio for network connections requires an additional line
+within the PulseAudio configuration file, usually `/etc/pulse/default.pa`:
+
+```
+load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24 auth-anonymous=1
+```
+
+This loads the TCP module for PulseAudio, configuring it to accept connections
+without authentication and *only* from the `192.168.1.0/24` subnet. You will
+want to replace this value with the subnet or IP address from which guacd will
+be connecting. It is possible to allow connections from absolutely anywhere,
+but beware that you should only do so if the nature of your network prevents
+unauthorized access:
+
+```
+load-module module-native-protocol-tcp auth-anonymous=1
+```
+
+In either case, the `auth-anonymous=1` parameter is strictly required.
+Guacamole does not currently support the cookie-based authentication used by
+PulseAudio for non-anonymous connections. If this parameter is omitted,
+Guacamole will not be able to connect to PulseAudio.
+
+Once the PulseAudio configuration file has been modified appropriately, restart
+the PulseAudio service. PulseAudio should then begin listening on port 4713
+(the default PulseAudio port) for incoming TCP connections. You can verify this
+using a utility like {command}`netstat`:
+
+```console
+$ netstat -ln | grep 4713
+tcp        0      0 0.0.0.0:4713            0.0.0.0:*               LISTEN
+tcp6       0      0 :::4713                 :::*                    LISTEN
+$
+```
+
+The following parameters are available for configuring the audio support for
+VNC:
+
+`enable-audio`
+: If set to "true", audio support will be enabled, and a second connection
+  for PulseAudio will be made in addition to the VNC connection. By default,
+  audio support within VNC is disabled.
+
+`audio-servername`
+: The name of the PulseAudio server to connect to. This will be the hostname
+  of the computer providing audio for your connection via PulseAudio, most
+  likely the same as the value given for the `hostname` parameter.
+
+  If this parameter is omitted, the default PulseAudio device will be used,
+  which will be the PulseAudio server running on the same machine as guacd.
+
+(vnc-clipboard-encoding)=
+
+#### Clipboard encoding
+
+While Guacamole will always use UTF-8 for its own clipboard data, the VNC
+standard requires that clipboard data be encoded in ISO 8859-1. As most VNC
+servers will not accept data in any other format, Guacamole will translate
+between UTF-8 and ISO 8859-1 when exchanging clipboard data with the VNC
+server, but this behavior can be overridden with the `clipboard-encoding`
+parameter.
+
+:::{important}
+*The only clipboard encoding guaranteed to be supported by VNC servers is ISO
+8859-1.* You should only override the clipboard encoding using the
+`clipboard-encoding` parameter of you are absolutely positive your VNC server
+supports other encodings.
+:::
+
+`clipboard-encoding`
+: The encoding to assume for the VNC clipboard. This parameter is optional.
+  By default, the standard encoding ISO 8859-1 will be used. *Only use this
+  parameter if you are sure your VNC server supports other encodings beyond
+  the standard ISO 8859-1.*
+
+  Possible values are:
+
+  ISO8859-1
+  : ISO 8859-1 is the clipboard encoding mandated by the VNC standard, and
+    supports only basic Latin characters. Unless your VNC server specifies
+    otherwise, this encoding is the only encoding guaranteed to work.
+
+  UTF-8
+  : UTF-8 - the most common encoding used for Unicode. Using this encoding
+    for the VNC clipboard violates the VNC specification, but some servers
+    do support this. This parameter value should only be used if you know
+    your VNC server supports this encoding.
+
+  UTF-16
+  : UTF-16 - a 16-bit encoding for Unicode which is not as common as UTF-8,
+    but still widely used. Using this encoding for the VNC clipboard
+    violates the VNC specification. This parameter value should only be used
+    if you know your VNC server supports this encoding.
+
+  CP1252
+  : Code page 1252 - a Windows-specific encoding for Latin characters which
+    is mostly a superset of ISO 8859-1, mapping some additional displayable
+    characters onto what would otherwise be control characters. Using this
+    encoding for the VNC clipboard violates the VNC specification. This
+    parameter value should only be used if you know your VNC server supports
+    this encoding.
+
+(adding-vnc)=
+
+#### Adding a VNC connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a VNC connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>vnc</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">5901</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use VNC to connect to localhost at port 5901. Naturally,
+you will want to change some or all of these values.
+
+If your VNC server requires a password, or you wish to specify other
+configuration parameters (to reduce the color depth, for example), you will
+need to add additional `<param>` tags accordingly.
+
+Other authentication methods will provide documentation describing how to
+configure new connections. If the authentication method in use fully implements
+the features of Guacamole's authentication API, you will be able to add a new
+VNC connection easily and intuitively using the administration interface built
+into Guacamole. You will not need to edit configuration files.
+
+(vnc-servers)=
+
+#### Which VNC server?
+
+The choice of VNC server can make a big difference when it comes to
+performance, especially over slower networks. While many systems provide VNC
+access by default, using this is often not the fastest method.
+
+(realvnc)=
+
+##### RealVNC or TigerVNC
+
+RealVNC, and its derivative TigerVNC, perform quite well. In our testing, they
+perform the best with Guacamole. If you are okay with having a desktop that can
+only be accessed via VNC, one of these is likely your best choice. Both
+optimize window movement and (depending on the application) scrolling, giving a
+very responsive user experience.
+
+##### TightVNC
+
+TightVNC is widely-available and performs generally as well as RealVNC or
+TigerVNC. If you wish to use TightVNC with Guacamole, performance should be
+just fine, but we highly recommend disabling its JPEG encoding. This is because
+images transmitted to Guacamole are always encoded losslessly as PNG images.
+When this operation is performed on a JPEG image, the artifacts present from
+JPEG's lossy compression reduce the compressibility of the image for PNG, thus
+leading to a slower experience overall than if JPEG was simply not used to
+begin with.
+
+##### x11vnc
+
+The main benefit of using x11vnc is that it allows you to continue using your
+desktop normally, while simultaneously exposing control of your desktop via
+VNC. Performance of x11vnc is comparable to RealVNC, TigerVNC, and TightVNC. If
+you need to use your desktop locally as well as via VNC, you will likely be
+quite happy with x11vnc.
+
+##### vino
+
+vino is the VNC server that comes with the Gnome desktop environment, and is
+enabled if you enable "desktop sharing" via the system preferences available
+within Gnome. If you need to share your local desktop, we recommend using
+x11vnc rather vino, as it has proven more performant and feature-complete in
+our testing. If you don't need to share a local desktop but simply need an
+environment you can access remotely, using a VNC server like RealVNC, TigerVNC,
+or TightVNC is a better choice.
+
+(qemu)=
+
+##### QEMU or KVM
+
+QEMU (and thus KVM) expose the displays of virtual machines using VNC.  If you
+need to see the virtual monitor of your virtual machine, using this VNC
+connection is really your only choice. As the VNC server built into QEMU cannot
+be aware of higher-level operations like window movement, resizing, or
+scrolling, those operations will tend to be sent suboptimally, and will not be
+as fast as a VNC server running within the virtual machine.
+
+If you wish to use a virtual machine for desktop access, we recommend
+installing a native VNC server inside the virtual machine after the virtual
+machine is set up. This will give a more responsive desktop.
+
+### RDP
+
+The RDP protocol is more complicated than VNC and was the second protocol
+officially supported by Guacamole. RDP tends to be faster than VNC due to the
+use of caching, which Guacamole does take advantage of.
+
+RDP support for Guacamole is provided by the libguac-client-rdp library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the RDP-specific parameters below, Guacamole's RDP support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(rdp-network-parameters)=
+
+#### Network parameters
+
+RDP connections require a hostname or IP address defining the
+destination machine. The RDP port is defined to be 3389, and will be
+this value in most cases. You only need to specify the RDP port if you
+are not using port 3389.
+
+`hostname`
+: The hostname or IP address of the RDP server Guacamole should connect to.
+
+`port`
+: The port the RDP server is listening on. This parameter is optional. If
+  this is not specified, the standard port for RDP (3389) or Hyper-V's
+  default port for VMConnect (2179) will be used, depending on the security
+  mode selected.
+
+(rdp-authentication)=
+
+#### Authentication and security
+
+RDP provides authentication through the use of a username, password, and
+optional domain. All RDP connections are encrypted.
+
+Most RDP servers will provide a graphical login if the username, password, and
+domain parameters are omitted. One notable exception to this is Network Level
+Authentication, or NLA, which performs all authentication outside of a desktop
+session, and thus in the absence of a graphical interface.
+
+Servers that require NLA can be handled by Guacamole in one of two ways. The
+first is to provide the username and password within the connection
+configuration, either via static values or by passing through the Guacamole
+credentials with [parameter tokens](parameter-tokens) and [](ldap-auth).
+Alternatively, if credentials are not configured within the connection
+configuration, Guacamole will attempt to prompt the user for the credentials
+interactively, if the versions of both guacd and Guacamole Client in use
+support it. If either component does not support prompting and the credentials
+are not configured, NLA-based connections will fail.
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+`domain`
+: The domain to use when attempting authentication, if any. This parameter
+  is optional.
+
+`security`
+: The security mode to use for the RDP connection. This mode dictates how
+  data will be encrypted and what type of authentication will be performed,
+  if any. By default, a security mode is selected based on a negotiation
+  process which determines what both the client and the server support.
+
+  Possible values are:
+
+  any
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server. *This is the default*.
+
+  nla
+  : Network Level Authentication, sometimes also referred to as "hybrid" or
+    CredSSP (the protocol that drives NLA). This mode uses TLS encryption
+    and requires the username and password to be given in advance. Unlike
+    RDP mode, the authentication step is performed before the remote desktop
+    session actually starts, avoiding the need for the Windows server to
+    allocate significant resources for users that may not be authorized.
+
+    If the versions of guacd and Guacamole Client in use support prompting
+    and the username, password, and domain are not specified, the user will
+    be interactively prompted to enter credentials to complete NLA and
+    continue the connection. Otherwise, when prompting is not supported and
+    credentials are not provided, NLA connections will fail.
+
+  nla-ext
+  : Extended Network Level Authentication. This mode is identical to NLA
+    except that an additional "[Early User Authorization
+    Result](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d0e560a3-25cb-4563-8bdc-6c4cc625bbfc)"
+    is required to be sent from the server to the client immediately after the
+    NLA handshake is completed.
+
+  tls
+  : RDP authentication and encryption implemented via TLS (Transport Layer
+    Security). Also referred to as RDSTLS, the TLS security mode is
+    primarily used in load balanced configurations where the initial RDP
+    server may redirect the connection to a different RDP server.
+
+  vmconnect
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server, limiting that negotiation
+    to only the protocols known to be supported by [Hyper-V /
+    VMConnect](rdp-preconnection-pdu).
+
+  rdp
+  : Legacy RDP encryption. This mode is generally only used for older
+    Windows servers or in cases where a standard Windows login screen is
+    desired. Newer versions of Windows have this mode disabled by default
+    and will only accept NLA unless explicitly configured otherwise.
+
+`ignore-cert`
+: If set to "true", the certificate returned by the server will be ignored,
+  even if that certificate cannot be validated. This is useful if you
+  universally trust the server and your connection to the server, and you
+  know that the server's certificate cannot be validated (for example, if it
+  is self-signed).
+
+`disable-auth`
+: If set to "true", authentication will be disabled. Note that this refers
+  to authentication that takes place while connecting. Any authentication
+  enforced by the server over the remote desktop session (such as a login
+  dialog) will still take place. By default, authentication is enabled and
+  only used when requested by the server.
+
+  If you are using NLA, authentication must be enabled by definition.
+
+(rdp-session-settings)=
+
+#### Session settings
+
+RDP sessions will typically involve the full desktop environment of a normal
+user. Alternatively, you can manually specify a program to use instead of the
+RDP server's default shell, or connect to the administrative console.
+
+Although Guacamole is independent of keyboard layout, RDP is not. This is
+because Guacamole represents keys based on what they *do* ("press the Enter
+key"), while RDP uses identifiers based on the key's location ("press the
+rightmost key in the second row"). To translate between a Guacamole key event
+and an RDP key event, Guacamole must know ahead of time the keyboard layout of
+the RDP server.
+
+By default, the US English qwerty keyboard will be used. If this does not match
+the keyboard layout of your RDP server, keys will not be properly translated,
+and you will need to explicitly choose a different layout in your connection
+settings. If your keyboard layout is not supported, please notify the Guacamole
+team by [opening an issue in
+JIRA](https://issues.apache.org/jira/browse/GUACAMOLE).
+
+
+`client-name`
+: When connecting to the RDP server, Guacamole will normally provide its own
+  hostname as the name of the client. If this parameter is specified,
+  Guacamole will use its value instead.
+
+  On Windows RDP servers, this value is exposed within the session as the
+  `CLIENTNAME` environment variable.
+
+`console`
+: If set to "true", you will be connected to the console (admin) session of
+  the RDP server.
+
+`initial-program`
+: The full path to the program to run immediately upon connecting. This
+  parameter is optional.
+
+`server-layout`
+: The server-side keyboard layout. This is the layout of the RDP server and
+  has nothing to do with the keyboard layout in use on the client. *The
+  Guacamole client is independent of keyboard layout.* The RDP protocol,
+  however, is *not* independent of keyboard layout, and Guacamole needs to
+  know the keyboard layout of the server in order to send the proper keys
+  when a user is typing.
+
+  Possible values are generally in the format
+  {samp}`{LANGUAGE}-{REGION}-{VARIANT}`, where `LANGUAGE` is the standard
+  two-letter language code for the primary language associated with the
+  layout, `REGION` is a standard representation of the location that the
+  keyboard is used (the two-letter country code, when possible), and
+  `VARIANT` is the specific keyboard layout variant (such as "qwerty",
+  "qwertz", or "azerty"):
+
+  | Keyboard layout                | Parameter value        |
+  | ------------------------------ | ---------------------- |
+  | Brazilian (Portuguese)         | `pt-br-qwerty`         |
+  | English (UK)                   | `en-gb-qwerty`         |
+  | English (US)                   | `en-us-qwerty`         |
+  | French                         | `fr-fr-azerty`         |
+  | French (Belgian)               | `fr-be-azerty`         |
+  | French (Swiss)                 | `fr-ch-qwertz`         |
+  | German                         | `de-de-qwertz`         |
+  | German (Swiss)                 | `de-ch-qwertz`         |
+  | Hungarian                      | `hu-hu-qwertz`         |
+  | Italian                        | `it-it-qwerty`         |
+  | Japanese                       | `ja-jp-qwerty`         |
+  | Spanish                        | `es-es-qwerty`         |
+  | Spanish (Latin American)       | `es-latam-qwerty`      |
+  | Swedish                        | `sv-se-qwerty`         |
+  | Turkish-Q                      | `tr-tr-qwerty`         |
+
+  If you server's keyboard layout is not yet supported, and it is not possible
+  to set your server to use a supported layout, the `failsafe` layout may be used
+  to force Unicode events to be used for all input, however beware that doing so
+  may prevent keyboard shortcuts from working as expected.
+
+`timezone`
+: The timezone that the client should send to the server for configuring the
+  local time display of that server. The format of the timezone is in the
+  standard IANA key zone format, which is the format used in UNIX/Linux.
+  This will be converted by RDP into the correct format for Windows.
+
+  The timezone is detected and will be passed to the server during the
+  handshake phase of the connection, and may used by protocols, like RDP,
+  that support it. This parameter can be used to override the value detected
+  and passed during the handshake, or can be used in situations where guacd
+  does not support passing the timezone parameter during the handshake phase
+  (guacd versions prior to 1.3.0).
+
+  Support for forwarding the client timezone varies by RDP server
+  implementation. For example, with Windows, support for forwarding
+  timezones is only present in Windows Server with Remote Desktop Services
+  (RDS, formerly known as Terminal Services) installed. Windows Server
+  installations in admin mode, along with Windows workstation versions, do
+  not allow the timezone to be forwarded. Other server implementations, for
+  example, xrdp, may not implement this feature at all. Consult the
+  documentation for the RDP server to determine whether or not this feature
+  is supported.
+
+(rdp-display-settings)=
+
+#### Display settings
+
+Guacamole will automatically choose an appropriate display size for RDP
+connections based on the size of the browser window and the DPI of the device.
+The size of the display can be forced by specifying explicit width or height
+values.
+
+To reduce bandwidth usage, you may also request that the server reduce its
+color depth. Guacamole will automatically detect 256-color images, but this can
+be guaranteed for absolutely all graphics sent over the connection by forcing
+the color depth to 8-bit. Color depth is otherwise dictated by the RDP server.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, or 24. Regardless of what value
+  is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`width`
+: The width of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the width of the connecting
+  client display will be used instead.
+
+`height`
+: The height of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the height of the connecting
+  client display will be used instead.
+
+`dpi`
+: The desired effective resolution of the client display, in DPI. This
+  parameter is optional. If this value is not specified, the resolution and
+  size of the client display will be used together to determine,
+  heuristically, an appropriate resolution for the RDP session.
+
+`resize-method`
+: The method to use to update the RDP server when the width or height of the
+  client display changes. This parameter is optional. If this value is not
+  specified, no action will be taken when the client display changes size.
+
+  Normally, the display size of an RDP session is constant and can only be
+  changed when initially connecting. As of RDP 8.1, the "Display Update"
+  channel can be used to request that the server change the display size.
+  For older RDP servers, the only option is to disconnect and reconnect with
+  the new size.
+
+  Possible values are:
+
+  display-update
+  : Uses the "Display Update" channel added with RDP 8.1 to signal the
+    server when the client display size has changed.
+
+  reconnect
+  : Automatically disconnects the RDP session when the client display size
+    has changed, and reconnects with the new size.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+(rdp-device-redirection)=
+
+#### Device redirection
+
+Device redirection refers to the use of non-display devices over RDP.
+Guacamole's RDP support currently allows redirection of audio, printing, and
+disk access, some of which require additional configuration in order to
+function properly.
+
+Audio redirection will be enabled by default. If Guacamole was correctly
+installed, and audio redirection is supported by your RDP server, sound should
+play within remote connections without manual intervention.
+
+Printing requires GhostScript to be installed on the Guacamole server, and
+allows users to print arbitrary documents directly to PDF. When documents are
+printed to the redirected printer, the user will receive a PDF of that document
+within their web browser.
+
+Guacamole provides support for file transfer over RDP by emulating a virtual
+disk drive. This drive will persist on the Guacamole server, confined within
+the drive path specified. If drive redirection is enabled on a Guacamole RDP
+connection, users will be able to upload and download files as described in
+[](using-guacamole).
+
+`disable-audio`
+: Audio is enabled by default in both the client and in libguac-client-rdp.
+  If you are concerned about bandwidth usage, or sound is causing problems,
+  you can explicitly disable sound by setting this parameter to "true".
+
+`enable-audio-input`
+: If set to "true", audio input support (microphone) will be enabled,
+  leveraging the standard "`AUDIO_INPUT`" channel of RDP. By default, audio
+  input support within RDP is disabled.
+
+`enable-printing`
+: Printing is disabled by default, but with printing enabled, RDP users can
+  print to a virtual printer that sends a PDF containing the document
+  printed to the Guacamole client. Enable printing by setting this parameter
+  to "true".
+
+  *Printing support requires GhostScript to be installed.* If guacd cannot
+  find the `gs` executable when printing, the print attempt will fail.
+
+`printer-name`
+: The name of the redirected printer device that is passed through to the
+  RDP session. This is the name that the user will see in, for example, the
+  Devices and Printers control panel.
+
+  If printer redirection is not enabled, this option has no effect.
+
+`enable-drive`
+: File transfer is disabled by default, but with file transfer enabled, RDP
+  users can transfer files to and from a virtual drive which persists on the
+  Guacamole server. Enable file transfer support by setting this parameter
+  to "true".
+
+  Files will be stored in the directory specified by the "`drive-path`"
+  parameter, which is required if file transfer is enabled.
+
+`disable-download`
+: If set to true downloads from the remote server to client (browser) will
+  be disabled. This includes both downloads down via the hidden Guacamole
+  menu, as well as using the special "Download" folder presented to the
+  remote server. The default is false, which means that downloads will be
+  allowed.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`disable-upload`
+: If set to true, uploads from the client (browser) to the remote server
+  location will be disabled. The default is false, which means uploads will
+  be allowed if file transfer is enabled.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-name`
+: The name of the filesystem used when passed through to the RDP session.
+  This is the name that users will see in their Computer/My Computer area
+  along with client name (for example, "Guacamole on Guacamole RDP"), and is
+  also the name of the share when accessing the special `\\tsclient` network
+  location.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-path`
+: The directory on the Guacamole server in which transferred files should be
+  stored. This directory must be accessible by guacd and both readable and
+  writable by the user that runs guacd. *This parameter does not refer to a
+  directory on the RDP server.*
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`create-drive-path`
+: If set to "true", and file transfer is enabled, the directory specified by
+  the `drive-path` parameter will automatically be created if it does not
+  yet exist. Only the final directory in the path will be created - if other
+  directories earlier in the path do not exist, automatic creation will
+  fail, and an error will be logged.
+
+  By default, the directory specified by the `drive-path` parameter will not
+  automatically be created, and attempts to transfer files to a non-existent
+  directory will be logged as errors.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`console-audio`
+: If set to "true", audio will be explicitly enabled in the console (admin)
+  session of the RDP server. Setting this option to "true" only makes sense
+  if the `console` parameter is also set to "true".
+
+`static-channels`
+: A comma-separated list of static channel names to open and expose as
+  pipes. If you wish to communicate between an application running on the
+  remote desktop and JavaScript, this is the best way to do it. Guacamole
+  will open an outbound pipe with the name of the static channel. If
+  JavaScript needs to communicate back in the other direction, it should
+  respond by opening another pipe with the same name.
+
+  Guacamole allows any number of static channels to be opened, but protocol
+  restrictions of RDP limit the size of each channel name to 7 characters.
+
+(rdp-preconnection-pdu)=
+
+#### Preconnection PDU (Hyper-V / VMConnect)
+
+Some RDP servers host multiple logical RDP connections behind a single server
+listening on a single TCP port. To select between these logical connections, an
+RDP client must send the "preconnection PDU" - a message which contains values
+that uniquely identify the destination, referred to as the "RDP source". This
+mechanism is defined by the ["Session Selection
+Extension](https://msdn.microsoft.com/en-us/library/cc242359.aspx) for the RDP
+protocol, and is implemented by Microsoft's Hyper-V hypervisor.
+
+If you are using Hyper-V, you will need to specify the ID of the destination
+virtual machine within the `preconnection-blob` parameter.  This value can be
+determined using PowerShell:
+
+```ps1con
+PS C:\> Get-VM VirtualMachineName | Select-Object Id
+
+Id
+--
+ed272546-87bd-4db9-acba-e36e1a9ca20a
+
+
+PS C:\>
+```
+
+The preconnection PDU is intentionally generic. While its primary use is as a
+means for selecting virtual machines behind Hyper-V, other RDP servers may use
+it as well. It is up to the RDP server itself to determine whether the
+preconnection ID, BLOB, or both will be used, and what their values mean.
+
+*If you do intend to use Hyper-V, beware that its built-in RDP server requires
+different parameters for authentication and Guacamole's defaults will not
+work.* In most cases, you will need to do the following when connecting to
+Hyper-V:
+
+1. Specify both "`username`" and "`password`" appropriately, and set
+   "`security`" to "`vmconnect`". Selecting the "`vmconnect`" security mode
+   will configure Guacamole to automatically negotiate security modes known to
+   be supported by Hyper-V, and will automatically select Hyper-V's default RDP
+   port (2179).
+
+2. If necessary, set "`ignore-cert`" to "`true`". Hyper-V may use a self-signed
+   certificate.
+
+`preconnection-id`
+: The numeric ID of the RDP source. This is a non-negative integer value
+  dictating which of potentially several logical RDP connections should be
+  used. This parameter is optional, and is only required if the RDP server
+  is documented as requiring it. *If using Hyper-V, this should be left
+  blank.*
+
+`preconnection-blob`
+: An arbitrary string which identifies the RDP source - one of potentially
+  several logical RDP connections hosted by the same RDP server. This
+  parameter is optional, and is only required if the RDP server is
+  documented as requiring it, such as Hyper-V. In all cases, the meaning of
+  this parameter is opaque to the RDP protocol itself and is dictated by the
+  RDP server. *For Hyper-V, this will be the ID of the destination virtual
+  machine.*
+
+(rdp-gateway)=
+
+#### Remote desktop gateway
+
+Microsoft's remote desktop server provides an additional gateway service which
+allows external connections to be forwarded to internal RDP servers which are
+otherwise not accessible. If you will be using Guacamole to connect through
+such a gateway, you will need to provide additional parameters describing the
+connection to that gateway, as well as any required credentials.
+
+`gateway-hostname`
+: The hostname of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. *If omitted, a gateway
+  will not be used.*
+
+`gateway-port`
+: The port of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. By default, this will be
+  "443".
+
+`gateway-username`
+: The username of the user authenticating with the remote desktop gateway,
+  if a gateway is being used. This is not necessarily the same as the user
+  actually using the remote desktop connection.
+
+`gateway-password`
+: The password to provide when authenticating with the remote desktop
+  gateway, if a gateway is being used.
+
+`gateway-domain`
+: The domain of the user authenticating with the remote desktop gateway, if
+  a gateway is being used. This is not necessarily the same domain as the
+  user actually using the remote desktop connection.
+
+(rdp-connection-broker)=
+
+#### Load balancing and RDP connection brokers
+
+If your remote desktop servers are behind a load balancer, sometimes referred
+to as a "connection broker" or "TS session broker", that balancer may require
+additional information during the connection process to determine how the
+incoming connection should be routed. RDP does not dictate the format of this
+information; it is specific to the balancer in use.
+
+If you are using a load balancer and are unsure whether such information is
+required, *you will need to check the documentation for your balancer*. If your
+balancer provides `.rdp` files for convenience, look through the contents of
+those files for a string field called "loadbalanceinfo", as that field is where
+the required information/cookie would be specified.
+
+`load-balance-info`
+: The load balancing information or cookie which should be provided to the
+  connection broker. *If no connection broker is being used, this should be
+  left blank.*
+
+(rdp-perf-flags)=
+
+#### Performance flags
+
+RDP provides several flags which control the availability of features that
+decrease performance and increase bandwidth for the sake of aesthetics, such as
+wallpaper, window theming, menu effects, and smooth fonts. These features are
+all disabled by default within Guacamole such that bandwidth usage is
+minimized, but you can manually re-enable them on a per-connection basis if
+desired.
+
+`enable-wallpaper`
+: If set to "true", enables rendering of the desktop wallpaper. By default,
+  wallpaper will be disabled, such that unnecessary bandwidth need not be
+  spent redrawing the desktop.
+
+`enable-theming`
+: If set to "true", enables use of theming of windows and controls. By
+  default, theming within RDP sessions is disabled.
+
+`enable-font-smoothing`
+: If set to "true", text will be rendered with smooth edges. Text over RDP
+  is rendered with rough edges by default, as this reduces the number of
+  colors used by text, and thus reduces the bandwidth required for the
+  connection.
+
+`enable-full-window-drag`
+: If set to "true", the contents of windows will be displayed as windows are
+  moved. By default, the RDP server will only draw the window border while
+  windows are being dragged.
+
+`enable-desktop-composition`
+: If set to "true", graphical effects such as transparent windows and
+  shadows will be allowed. By default, such effects, if available, are
+  disabled.
+
+`enable-menu-animations`
+: If set to "true", menu open and close animations will be allowed. Menu
+  animations are disabled by default.
+
+`disable-bitmap-caching`
+: In certain situations, particularly with RDP server implementations with
+  known bugs, it is necessary to disable RDP's built-in bitmap caching
+  functionality. This parameter allows that to be controlled in a Guacamole
+  session. If set to "true" the RDP bitmap cache will not be used.
+
+`disable-offscreen-caching`
+: RDP normally maintains caches of regions of the screen that are current
+  not visible in the client in order to accelerate retrieval of those
+  regions when they come into view. This parameter, when set to "true," will
+  disable caching of those regions. This is usually only useful when dealing
+  with known bugs in RDP server implementations and should remain enabled in
+  most circumstances.
+
+`disable-glyph-caching`
+: In addition to screen regions, RDP maintains caches of frequently used
+  symbols or fonts, collectively known as "glyphs." As with bitmap and
+  offscreen caching, certain known bugs in RDP implementations can cause
+  performance issues with this enabled, and setting this parameter to "true"
+  will disable that glyph caching in the RDP session.

Review comment:
       Does this section still need to be updated with the other JIRA issue for disabling unsupported caches?

##########
File path: src/event-listeners.md
##########
@@ -0,0 +1,371 @@
+Event listeners
+===============
+
+Guacamole supports the delivery of event notifications to custom extensions.
+Developers can use listener extensions to integrate custom handling of events
+such as successful and failed authentications, and requests to connect and
+disconnect tunnels to desktop environments.
+
+A listener extension could be used, for example, to record authentication
+attempts in an external database for security auditing or alerting. By
+listening to tunnel lifecycle events, a listener extension could be used to
+help coordinate startup and shutdown of machine resources; particularly useful
+in cloud environments where minimizing running-but-idle resources is an
+important cost savings measure.
+
+For certain *vetoable* events, an event listener can even influence Guacamole's
+behavior. For example, a listener can veto a successful authentication,
+effectively causing the authentication to be considered failed. Similarly, a
+listener can veto a tunnel connection, effectively preventing the tunnel from
+being connected to a virtual desktop resource.
+
+Custom event listeners are packaged using the same extension mechanism used for
+custom authentication providers. A single listener extension can include any
+number of classes that implement the listener interface.  A single extension
+module can also include any combination of authentication providers and
+listeners, so developers can easily combine authentication providers with
+listeners designed to support them.
+
+To demonstrate the principles involved in receiving Guacamole event
+notifications, we will implement a simple listener extension that logs
+authentication events. While our approach simply writes event details to the
+same log used by the Guacamole web application, a listener could process these
+events in arbitrary ways, limited only by the imagination and ingenuity of the
+developer.
+
+(custom-event-listener-skeleton)=
+
+A Guacamole listener extension skeleton
+---------------------------------------
+
+For simplicity's sake, and because this is how things are done upstream in the
+Guacamole project, we will use Maven to build our extension.
+
+The bare minimum required for a Guacamole listener extension is a `pom.xml`
+file listing guacamole-ext as a dependency, a single `.java` file implementing
+our stub of a listener, and a `guac-manifest.json` file describing the
+extension and pointing to our listener class.
+
+```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.guacamole</groupId>
+    <artifactId>guacamole-listener-tutorial</artifactId>
+    <packaging>jar</packaging>
+    <version>1.3.0</version>
+    <name>guacamole-listener-tutorial</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+
+            <!-- Written for 1.6 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.3</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <!-- Guacamole Extension API -->
+        <dependency>
+            <groupId>org.apache.guacamole</groupId>
+            <artifactId>guacamole-ext</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Slf4j API -->
+        <!-- This is needed only if your listener wants to 
+                write to the Guacamole web application log -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.7</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
+```
+
+Naturally, we need the actual listener extension skeleton code. While you can
+put this in whatever file and package you want, for the sake of this tutorial,
+we will assume you are using `org.apache.guacamole.event.TutorialListener`.
+
+For now, we won't actually do anything other than log the fact that an event
+notification was received. At this point, we're just creating the skeleton for
+our listener extension.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener implementation intended to demonstrate basic use
+ * of Guacamole's listener extension API.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+         LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+        logger.info("received Guacamole event notification");
+    }
+
+}
+```
+
+To conform with Maven, this skeleton file must be placed within
+`src/main/java/org/apache/guacamole/event` as `TutorialListener.java`.
+
+As you can see, implementing a listener is quite simple. There is a single
+`Listener` interface to implement. All Guacamole event notifications will be
+delivered to your code by invoking the handleEvent method. We will see shortly
+how to use the passed event object to get the details of the event itself.
+
+The only remaining piece for the overall skeleton to be complete is a
+`guac-manifest.json` file. *This file is absolutely required for all Guacamole
+extensions.* The `guac-manifest.json` format is described in more detail in
+[](guacamole-ext). It provides for quite a few properties, but for our listener
+extension we are mainly interested in the Guacamole version sanity check (to
+make sure an extension built for the API of Guacamole version X is not
+accidentally used against version Y) and telling Guacamole where to find our
+listener class.
+
+The Guacamole extension format requires that `guac-manifest.json` be placed in
+the root directory of the extension `.jar` file. To accomplish this with Maven,
+we place it within the `src/main/resources` directory. Maven will automatically
+pick it up during the build and include it within the `.jar`.
+
+```json
+{
+
+    "guacamoleVersion" : "1.3.0",
+
+    "name"      : "Tutorial Listener Extension",
+    "namespace" : "guac-listener-tutorial",
+
+    "listeners" : [
+        "org.apache.guacamole.event.TutorialListener"
+    ]
+
+}
+```
+
+(custom-listener-building)=
+
+Building the extension
+----------------------
+
+Once all three of the above files are in place, the extension should build
+successfully even though it is just a skeleton at this point.
+
+```console
+$ mvn package
+[INFO] Scanning for projects...
+[INFO] ---------------------------------------------------------------
+[INFO] Building guacamole-listener-tutorial 1.3.0
+[INFO] ---------------------------------------------------------------
+...
+[INFO] ---------------------------------------------------------------
+[INFO] BUILD SUCCESS
+[INFO] ---------------------------------------------------------------
+[INFO] Total time: 1.297 s
+[INFO] Finished at: 2017-10-08T13:12:39-04:00
+[INFO] Final Memory: 19M/306M
+[INFO] ---------------------------------------------------------------
+$
+```
+
+Assuming you see the "`BUILD SUCCESS`" message when you build the extension,
+there will be a new file, `target/guacamole-listener-tutorial-1.3.0.jar`, which
+can be installed within Guacamole (see [](custom-listener-installing) at the
+end of this chapter).  It should log event notifications that occur during, for
+example, authentication attempts. If you changed the name or version of the
+project in the `pom.xml` file, the name of this new `.jar` file will be
+different, but it can still be found within `target/`.
+
+(custom-listener-event-handling)=
+
+Handling events
+---------------
+
+The Guacamole `Listener` interface represents a low-level event handling API. A
+listener is notified of every event generated by Guacamole. The listener must
+examine the event type to determine whether the event is of interest, and if so
+to dispatch the event to the appropriate entry point.
+
+The event types that can be produced by Guacamole are described in the
+`org.apache.guacamole.net.event` package of the guacamole-ext API. In this
+package you will find several concrete event types as well as interfaces that
+describe common characteristics of certain of event types. You can use any of
+these types to distinguish the events received by your listener, and to examine
+properties of an event of a given type.
+
+Suppose we wish to log authentication success and failure events, while
+ignoring all other event types. The `AuthenticationSuccessEvent` and
+`AuthenticationFailureEvent` types are used to notify a listener of
+authentication events. We can simply check whether a received event is of one
+of these types and, if so, log an appropriate message.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.event.AuthenticationFailureEvent;
+import org.apache.guacamole.net.event.AuthenticationSuccessEvent;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener that logs authentication success and failure events.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+        LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+
+        if (event instanceof AuthenticationSuccessEvent) {
+            logger.info("successful authentication for user {}", 
+                ((AuthenticationSuccessEvent) event)
+                    .getCredentials().getUsername());
+        }
+        else if (event instanceof AuthenticationFailureEvent) {
+            logger.info("failed authentication for user {}", 
+                ((AuthenticationFailureEvent) event)
+                    .getCredentials().getUsername());
+        }
+    }
+
+}
+```
+
+In our example, we use `instanceof` to check for the two event types of
+interest to our listener. Once we have identified an event of interest, we can
+safely cast the event type to access properties of the event.
+
+The extension is now complete and can be built as described earlier in
+[](custom-listener-building) and installed as described below in
+[](custom-listener-installing).
+
+(custom-listener-veto)=
+
+Influencing Guacamole by event veto
+-----------------------------------
+
+An implementation of the handleEvent method is permitted to throw any
+`GuacamoleException`. For certain *vetoable* event types, throwing a
+`GuacamoleException` serves to effectively veto the action that resulted in the
+event notification. See the API documentation for guacamole-ext to learn more
+about vetoable event types.
+
+As an (admittedly contrived) example, suppose we want to prevent a user named
+"guacadmin" from accessing Guacamole. For whatever reason, we don't wish to
+remove or disable the auth database entry for this user.  In this case we can
+use a listener to "blacklist" this user, preventing access to Guacamole. In the
+listener, when we get an `AuthenticationSuccessEvent` we can check to see if
+the user is "guacadmin" and, if so, throw an exception to prevent this user
+from logging in to Guacamole.
+
+```java
+package org.apache.guacamole.event;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSecurityException;
+import org.apache.guacamole.net.event.AuthenticationFailureEvent;
+import org.apache.guacamole.net.event.AuthenticationSuccessEvent;
+import org.apache.guacamole.net.event.listener.Listener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Listener that logs authentication success and failure events
+ * and prevents the "guacadmin" user from logging in by throwing
+ * a GuacamoleSecurityException.
+ */
+public class TutorialListener implements Listener {
+
+    private static final Logger logger = 
+        LoggerFactory.getLogger(TutorialListener.class);
+
+    @Override
+    public void handleEvent(Object event) throws GuacamoleException {
+
+        if (event instanceof AuthenticationSuccessEvent) {
+          final String username = ((AuthenticationSuccessEvent) event)
+              .getCredentials().getUsername();
+
+          if ("guacadmin".equals(username)) {
+            logger.warn("user {} is blacklisted", username);
+            throw new GuacamoleSecurityException(
+                "User '" + username + "' is blacklisted");
+          }
+
+          logger.info("successful authentication for user {}", username);
+        }
+        else if (event instanceof AuthenticationFailureEvent) {
+            logger.info("failed authentication for user {}", 
+                ((AuthenticationFailureEvent) event)
+                    .getCredentials().getUsername());
+        }
+    }
+
+}
+```
+
+If our Guacamole user database contains a user named "guacadmin", and we build
+and install this listener extension, we will find that an attempt to log in as
+this user now results in a message in the UI indicating that the user is
+blacklisted. If we examine the Guacamole log, we will see the message
+indicating that the user is blacklisted. Because the successful authentication

Review comment:
       Couple of more instances, here.

##########
File path: src/configuring-guacamole.md
##########
@@ -0,0 +1,2770 @@
+Configuring Guacamole
+=====================
+
+After installing Guacamole, you need to configure users and connections before
+Guacamole will work. This chapter covers general configuration of Guacamole and
+the use of its default authentication method.
+
+Guacamole's default authentication method reads all users and connections from
+a single file called `user-mapping.xml`. This authentication method is intended
+to be:
+
+1. Sufficient for small deployments of Guacamole.
+
+2. A relatively-easy means of verifying that Guacamole has been properly set
+   up.
+
+Other, more complex authentication methods which use backend databases, LDAP,
+etc. are discussed in a separate, dedicated chapters.
+
+Regardless of the authentication method you use, Guacamole's configuration
+always consists of two main pieces: a directory referred to as
+`GUACAMOLE_HOME`, which is the primary search location for configuration files,
+and `guacamole.properties`, the main configuration file used by Guacamole and
+its extensions.
+
+(guacamole-home)=
+
+`GUACAMOLE_HOME` (`/etc/guacamole`)
+---------------------------------------
+
+`GUACAMOLE_HOME` is the name given to Guacamole's configuration directory,
+which is located at `/etc/guacamole` by default. All configuration files,
+extensions, etc. reside within this directory. The structure of
+`GUACAMOLE_HOME` is rigorously defined, and consists of the following optional
+files:
+
+`guacamole.properties`
+: The main Guacamole configuration file. Properties within this file dictate
+  how Guacamole will connect to guacd, and may configure the behavior of
+  installed authentication extensions.
+
+`logback.xml`
+: Guacamole uses a logging system called Logback for all messages. By
+  default, Guacamole will log to the console only, but you can change this
+  by providing your own Logback configuration file.
+
+`extensions/`
+: The install location for all Guacamole extensions. Guacamole will
+  automatically load all `.jar` files within this directory on startup.
+
+`lib/`
+: The search directory for libraries required by any Guacamole extensions.
+  Guacamole will make the `.jar` files within this directory available to
+  all extensions. If your extensions require additional libraries, such as
+  database drivers, this is the proper place to put them.
+
+(overriding-guacamole-home)=
+
+### Overriding `GUACAMOLE_HOME`
+
+If you cannot or do not wish to use `/etc/guacamole` for `GUACAMOLE_HOME`, the
+location can be overridden through any of the following methods:
+
+1. Creating a directory named `.guacamole`, within the home directory of *the
+   user running the servlet container*. This directory will automatically be
+   used for `GUACAMOLE_HOME` if it exists.
+
+2. Specifying the full path to an alternative directory with the environment
+   variable `GUACAMOLE_HOME`. *Be sure to consult the documentation for your
+   servlet container to determine how to properly set environment variables.*
+
+3. Specifying the full path to an alternative directory with the system
+   property guacamole.home.
+
+(initial-setup)=
+
+`guacamole.properties`
+------------------------
+
+The Guacamole web application uses one main configuration file called
+`guacamole.properties`. This file is the common location for all configuration
+properties read by Guacamole or any extension of Guacamole, including
+authentication providers.
+
+In previous releases, this file had to be in the classpath of your servlet
+container. Now, the location of `guacamole.properties` can be explicitly
+defined with environment variables or system properties, and the classpath is
+only used as a last resort. When searching for `guacamole.properties`,
+Guacamole will check, in order:
+
+1. Within `GUACAMOLE_HOME`, as defined above.
+
+2. The classpath of the servlet container.
+
+The `guacamole.properties` file is optional and is used to configure Guacamole
+in situations where the defaults are insufficient, or to provide additional
+configuration information for extensions. There are several standard properties
+that are always available for use:
+
+`api-session-timeout`
+: The amount of time, in minutes, to allow Guacamole sessions
+  (authentication tokens) to remain valid despite inactivity. If omitted,
+  Guacamole sessions will expire after 60 minutes of inactivity.
+
+`api-max-request-size`
+: The maximum number of bytes to accept within the entity body of any
+  particular HTTP request, where 0 indicates that no limit should be
+  applied. If omitted, requests will be limited to 2097152 bytes (2 MB) by
+  default. This limit does not apply to file uploads.
+
+  If using a reverse proxy for SSL termination, *keep in mind that reverse
+  proxies may enforce their own limits independently of this*. For example,
+  [Nginx will enforce a 1 MB request size limit by
+  default](nginx-file-upload-size).
+
+`allowed-languages`
+: A comma-separated whitelist of language keys to allow as display language
+  choices within the Guacamole interface. For example, to restrict Guacamole
+  to only English and German, you would specify:
+
+  ```
+  allowed-languages: en, de
+  ```
+
+  As English is the fallback language, used whenever a translation key is
+  missing from the chosen language, English should only be omitted from this
+  list if you are absolutely positive that no strings are missing.
+
+  The corresponding JSON of any built-in languages not listed here will
+  still be available over HTTP, but the Guacamole interface will not use
+  them, nor will they be used automatically based on local browser language.
+  If omitted, all defined languages will be available.
+
+`enable-environment-properties`
+: If set to "true", Guacamole will first evaluate its environment to obtain
+  the value for any given configuration property, before using a value
+  specified in `guacamole.properties` or falling back to a default value. By
+  enabling this option, you can easily override any other configuration
+  property using an environment variable.
+
+  ```
+  enable-environment-properties: true
+  ```
+
+  When searching for a configuration property in the environment, the name
+  of the property is first transformed by converting all lower case
+  characters to their upper case equivalents, and by replacing all hyphen
+  characters (`-`) with underscore characters (`_`). For example, the
+  `guacd-hostname` property would be transformed to `GUACD_HOSTNAME` when
+  searching the environment.
+
+`guacd-hostname`
+: The host the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on localhost.
+
+`guacd-port`
+: The port the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on port 4822.
+
+`guacd-ssl`
+: If set to "true", Guacamole will require SSL/TLS encryption between the
+  web application and guacd. By default, communication between the web
+  application and guacd will be unencrypted.
+
+  Note that if you enable this option, you must also configure guacd to use
+  SSL via command line options. These options are documented in the manpage
+  of guacd. You will need an SSL certificate and private key.
+
+`skip-if-unavailable`
+: A comma-separated list of the identifiers of authentication providers that
+  should be allowed to fail internally without aborting the authentication
+  process. For example, to request that Guacamole ignore failures due to the
+  LDAP directory or MySQL server being unexpectedly down, allowing other
+  authentication providers to continue functioning:
+
+  ```
+  skip-if-unavailable: mysql, ldap
+  ```
+
+  By default, Guacamole takes a conservative approach to internal failures,
+  aborting the authentication process if an internal error occurs within any
+  authentication provider. Depending on the nature of the error, this may
+  mean that no users can log in until the cause of the failure is dealt
+  with. The `skip-if-unavailable` property may be used to explicitly inform
+  Guacamole that one or more underlying systems are expected to occasionally
+  experience failures, and that other functioning systems should be relied
+  upon if they do fail.
+
+
+```
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port:     4822
+```
+
+(webapp-logging)=
+
+Logging within the web application
+----------------------------------
+
+By default, Guacamole logs all messages to the console. Servlet containers like
+Tomcat will automatically redirect these messages to a log file, `catalina.out`
+in the case of Tomcat, which you can read through while Guacamole runs.
+Messages are logged at four different log levels, depending on message
+importance and severity:
+
+`error`
+: Errors are fatal conditions. An operation, described in the log message,
+  was attempted but could not proceed, and the failure of this operation is
+  a serious problem that needs to be addressed.
+
+`warn`
+: Warnings are generally non-fatal conditions. The operation continued, but
+  encountered noteworthy problems.
+
+`info`
+: "Info" messages are purely informational. They may be useful or
+  interesting to administrators, but are not generally critical to proper
+  operation of a Guacamole server.
+
+`debug`
+: Debug messages are highly detailed and oriented toward development. Most
+  debug messages will contain stack traces and internal information that is
+  useful when investigating problems within code. It is expected that debug
+  messages, though verbose, will not affect performance.
+
+`trace`
+: Trace messages are similar to debug messages in intent and verbosity, but
+  are so low-level that they may affect performance due to their frequency.
+  Trace-level logging is rarely necessary, and is mainly useful in providing
+  highly detailed context around issues being investigated.
+
+Guacamole logs messages using a logging framework called
+[Logback](http://logback.qos.ch/) and, by default, will only log messages at
+the "`info`" level or higher. If you wish to change the log level, or configure
+how or where Guacamole logs messages, you can do so by providing your own
+`logback.xml` file within `GUACAMOLE_HOME`.  For example, to log all messages
+to the console, even "`debug`" messages, you might use the following
+`logback.xml`:
+
+```xml
+<configuration>
+
+    <!-- Appender for debugging -->
+    <appender name="GUAC-DEBUG" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log at DEBUG level -->
+    <root level="debug">
+        <appender-ref ref="GUAC-DEBUG"/>
+    </root>
+
+</configuration>
+```
+
+Guacamole and the above example configure only one appender which logs to the
+console, but Logback is extremely flexible and allows any number of appenders
+which can each log to separate files, the console, etc.  based on a number of
+criteria, including the log level and the source of the message.
+
+More thorough [documentation on configuring
+Logback](http://logback.qos.ch/manual/configuration.html) is provided on the
+Logback project's web site.
+
+(basic-auth)=
+
+Using the default authentication
+--------------------------------
+
+Guacamole's default authentication module is simple and consists of a mapping
+of usernames to configurations. This authentication module comes with Guacamole
+and simply reads usernames and passwords from an XML file. It is always
+enabled, but will only read from the XML file if it exists, and is always last
+in priority relative to any other authentication extensions.
+
+There are other authentication modules available. The Guacamole project
+provides database-backed authentication modules with the ability to manage
+connections and users from the web interface, and other authentication modules
+can be created using the extension API provided along with the Guacamole web
+application, guacamole-ext.
+
+(user-mapping)=
+
+### `user-mapping.xml`
+
+The default authentication provider used by Guacamole reads all username,
+password, and configuration information from a file called the "user mapping"
+located at `GUACAMOLE_HOME/user-mapping.xml`. An example of a user mapping file
+is included with Guacamole, and looks something like this:
+
+```xml
+<user-mapping>
+
+    <!-- Per-user authentication and config information -->
+    <authorize username="USERNAME" password="PASSWORD">
+        <protocol>vnc</protocol>
+        <param name="hostname">localhost</param>
+        <param name="port">5900</param>
+        <param name="password">VNCPASS</param>
+    </authorize>
+
+    <!-- Another user, but using md5 to hash the password
+         (example below uses the md5 hash of "PASSWORD") -->
+    <authorize
+            username="USERNAME2"
+            password="319f4d26e3c536b5dd871bb2c52e3178"
+            encoding="md5">
+
+        <!-- First authorized connection -->
+        <connection name="localhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">localhost</param>
+            <param name="port">5901</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+        <!-- Second authorized connection -->
+        <connection name="otherhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">otherhost</param>
+            <param name="port">5900</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+    </authorize>
+
+</user-mapping>
+```
+
+Each user is specified with a corresponding `<authorize>` tag. This tag
+contains all authorized connections for that user, each denoted with a
+`<connection>` tag. Each `<connection>` tag contains a corresponding protocol
+and set of protocol-specific parameters, specified with the `<protocol>` and
+`<param>` tags respectively.
+
+(user-setup)=
+
+#### Adding users
+
+When using `user-mapping.xml`, username/password pairs are specified with
+`<authorize>` tags, which each have a `username` and `password` attribute. Each
+`<authorize>` tag authorizes a specific username/password pair to access all
+connections within the tag:
+
+```xml
+<authorize username="USER" password="PASS">
+    ...
+</authorize>
+```
+
+In the example above, the password would be listed in plaintext. If you don't
+want to do this, you can also specify your password hashed with MD5:
+
+```xml
+<authorize username="USER"
+           password="319f4d26e3c536b5dd871bb2c52e3178"
+           encoding="md5">
+    ...
+</authorize>
+```
+
+After modifying `user-mapping.xml`, the file will be automatically reread by
+Guacamole, and your changes will take effect immediately. The newly-added user
+will be able to log in - no restart of the servlet container is needed.
+
+(connection-setup)=
+
+#### Adding connections to a user
+
+To specify a connection within an `<authorize>` tag, you can either list a
+single protocol and set of parameters (specified with a `<protocol>` tag and
+any number of `<param>` tags), in which case that user will have access to only
+one connection named "DEFAULT", or you can specify one or more connections with
+one or more `<connection>` tags, each of which can be named and contains a
+`<protocol>` tag and any number of `<param>` tags.
+
+(connection-configuration)=
+
+Configuring connections
+-----------------------
+
+Each protocol supported by Guacamole has its own set of configuration
+parameters. These parameters typically describe the hostname and port of the
+remote desktop server, the credentials to use when connecting, if any, and the
+size and color depth of the display. If the protocol supports file transfer,
+options for enabling that functionality will be provided as well.
+
+### VNC
+
+The VNC protocol is the simplest and first protocol supported by Guacamole.
+Although generally not as fast as RDP, many VNC servers are adequate, and VNC
+over Guacamole tends to be faster than VNC by itself due to decreased bandwidth
+usage.
+
+VNC support for Guacamole is provided by the libguac-client-vnc library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the VNC-specific parameters below, Guacamole's VNC support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(vnc-network-parameters)=
+
+#### Network parameters
+
+With the exception of reverse-mode VNC connections, VNC works by making
+outbound network connections to a particular host which runs one or more VNC
+servers. Each VNC server is associated with a display number, from which the
+appropriate port number is derived.
+
+`hostname`
+: The hostname or IP address of the VNC server Guacamole should connect to.
+
+`port`
+: The port the VNC server is listening on, usually 5900 or 5900 + display
+  number. For example, if your VNC server is serving display number 1
+  (sometimes written as `:1`), your port number here would be 5901.
+
+`autoretry`
+: The number of times to retry connecting before giving up and returning an
+  error. In the case of a reverse connection, this is the number of times
+  the connection process is allowed to time out.
+
+(vnc-authentication)=
+
+#### Authentication
+
+The VNC standard defines only password based authentication. Other
+authentication mechanisms exist, but are non-standard or proprietary.
+Guacamole currently supports both standard password-only based authentication,
+as well as username and password authentication.
+
+`username`
+: The username to use when attempting authentication, if any. This parameter
+  is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+(vnc-display-settings)=
+
+#### Display settings
+
+VNC servers do not allow the client to request particular display sizes, so you
+are at the mercy of your VNC server with respect to display width and height.
+However, to reduce bandwidth usage, you may request that the VNC server reduce
+its color depth. Guacamole will automatically detect 256-color images, but this
+can be guaranteed for absolutely all graphics sent over the connection by
+forcing the color depth to 8-bit. Color depth is otherwise dictated by the VNC
+server.
+
+If you are noticing problems with your VNC display, such as the lack of a mouse
+cursor, the presence of multiple mouse cursors, or strange colors (such as blue
+colors appearing more like orange or red), these are typically the result of
+bugs or limitations within the VNC server, and additional parameters are
+available to work around such issues.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, 24, or 32. Regardless of what
+  value is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`swap-red-blue`
+: If the colors of your display appear wrong (blues appear orange or red,
+  etc.), it may be that your VNC server is sending image data incorrectly,
+  and the red and blue components of each color are swapped. If this is the
+  case, set this parameter to "true" to work around the problem. This
+  parameter is optional.
+
+`cursor`
+: If set to "remote", the mouse pointer will be rendered remotely, and the
+  local position of the mouse pointer will be indicated by a small dot. A
+  remote mouse cursor will feel slower than a local cursor, but may be
+  necessary if the VNC server does not support sending the cursor image to
+  the client.
+
+`encodings`
+: A space-delimited list of VNC encodings to use. The format of this
+  parameter is dictated by libvncclient and thus doesn't really follow the
+  form of other Guacamole parameters. This parameter is optional, and
+  libguac-client-vnc will use any supported encoding by default.
+
+  Beware that this parameter is intended to be replaced with individual,
+  encoding-specific parameters in a future release.
+
+`read-only`
+: Whether this connection should be read-only. If set to "true", no input
+  will be accepted on the connection at all. Users will only see the desktop
+  and whatever other users using that same desktop are doing. This parameter
+  is optional.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+#### VNC Repeater
+
+There exist VNC repeaters, such as UltraVNC Repeater, which act as
+intermediaries or proxies, providing a single logical VNC connection which is
+then routed to another VNC server elsewhere. Additional parameters are required
+to select which VNC host behind the repeater will receive the connection.
+
+`dest-host`
+: The destination host to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+`dest-port`
+: The destination port to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+(vnc-reverse-connections)=
+
+#### Reverse VNC connections
+
+Guacamole supports "reverse" VNC connections, where the VNC client listens for
+an incoming connection from the VNC server. When reverse VNC connections are
+used, the VNC client and server switch network roles, but otherwise function as
+they normally would. The VNC server still provides the remote display, and the
+VNC client still provides all keyboard and mouse input.
+
+`reverse-connect`
+: Whether reverse connection should be used. If set to "true", instead of
+  connecting to a server at a given hostname and port, guacd will listen on
+  the given port for inbound connections from a VNC server.
+
+`listen-timeout`
+: If reverse connection is in use, the maximum amount of time to wait for an
+  inbound connection from a VNC server, in milliseconds. If blank, the
+  default value is 5000 (five seconds).
+
+(vnc-audio)=
+
+#### Audio support (via PulseAudio)
+
+VNC does not provide its own support for audio, but Guacamole's VNC support can
+obtain audio through a secondary network connection to a PulseAudio server
+running on the same machine as the VNC server.
+
+Most Linux systems provide audio through a service called PulseAudio.  This
+service is capable of communicating over the network, and if PulseAudio is
+configured to allow TCP connections, Guacamole can connect to your PulseAudio
+server and combine its audio with the graphics coming over VNC.
+
+Configuring PulseAudio for network connections requires an additional line
+within the PulseAudio configuration file, usually `/etc/pulse/default.pa`:
+
+```
+load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24 auth-anonymous=1
+```
+
+This loads the TCP module for PulseAudio, configuring it to accept connections
+without authentication and *only* from the `192.168.1.0/24` subnet. You will
+want to replace this value with the subnet or IP address from which guacd will
+be connecting. It is possible to allow connections from absolutely anywhere,
+but beware that you should only do so if the nature of your network prevents
+unauthorized access:
+
+```
+load-module module-native-protocol-tcp auth-anonymous=1
+```
+
+In either case, the `auth-anonymous=1` parameter is strictly required.
+Guacamole does not currently support the cookie-based authentication used by
+PulseAudio for non-anonymous connections. If this parameter is omitted,
+Guacamole will not be able to connect to PulseAudio.
+
+Once the PulseAudio configuration file has been modified appropriately, restart
+the PulseAudio service. PulseAudio should then begin listening on port 4713
+(the default PulseAudio port) for incoming TCP connections. You can verify this
+using a utility like {command}`netstat`:
+
+```console
+$ netstat -ln | grep 4713
+tcp        0      0 0.0.0.0:4713            0.0.0.0:*               LISTEN
+tcp6       0      0 :::4713                 :::*                    LISTEN
+$
+```
+
+The following parameters are available for configuring the audio support for
+VNC:
+
+`enable-audio`
+: If set to "true", audio support will be enabled, and a second connection
+  for PulseAudio will be made in addition to the VNC connection. By default,
+  audio support within VNC is disabled.
+
+`audio-servername`
+: The name of the PulseAudio server to connect to. This will be the hostname
+  of the computer providing audio for your connection via PulseAudio, most
+  likely the same as the value given for the `hostname` parameter.
+
+  If this parameter is omitted, the default PulseAudio device will be used,
+  which will be the PulseAudio server running on the same machine as guacd.
+
+(vnc-clipboard-encoding)=
+
+#### Clipboard encoding
+
+While Guacamole will always use UTF-8 for its own clipboard data, the VNC
+standard requires that clipboard data be encoded in ISO 8859-1. As most VNC
+servers will not accept data in any other format, Guacamole will translate
+between UTF-8 and ISO 8859-1 when exchanging clipboard data with the VNC
+server, but this behavior can be overridden with the `clipboard-encoding`
+parameter.
+
+:::{important}
+*The only clipboard encoding guaranteed to be supported by VNC servers is ISO
+8859-1.* You should only override the clipboard encoding using the
+`clipboard-encoding` parameter of you are absolutely positive your VNC server
+supports other encodings.
+:::
+
+`clipboard-encoding`
+: The encoding to assume for the VNC clipboard. This parameter is optional.
+  By default, the standard encoding ISO 8859-1 will be used. *Only use this
+  parameter if you are sure your VNC server supports other encodings beyond
+  the standard ISO 8859-1.*
+
+  Possible values are:
+
+  ISO8859-1
+  : ISO 8859-1 is the clipboard encoding mandated by the VNC standard, and
+    supports only basic Latin characters. Unless your VNC server specifies
+    otherwise, this encoding is the only encoding guaranteed to work.
+
+  UTF-8
+  : UTF-8 - the most common encoding used for Unicode. Using this encoding
+    for the VNC clipboard violates the VNC specification, but some servers
+    do support this. This parameter value should only be used if you know
+    your VNC server supports this encoding.
+
+  UTF-16
+  : UTF-16 - a 16-bit encoding for Unicode which is not as common as UTF-8,
+    but still widely used. Using this encoding for the VNC clipboard
+    violates the VNC specification. This parameter value should only be used
+    if you know your VNC server supports this encoding.
+
+  CP1252
+  : Code page 1252 - a Windows-specific encoding for Latin characters which
+    is mostly a superset of ISO 8859-1, mapping some additional displayable
+    characters onto what would otherwise be control characters. Using this
+    encoding for the VNC clipboard violates the VNC specification. This
+    parameter value should only be used if you know your VNC server supports
+    this encoding.
+
+(adding-vnc)=
+
+#### Adding a VNC connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a VNC connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>vnc</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">5901</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use VNC to connect to localhost at port 5901. Naturally,
+you will want to change some or all of these values.
+
+If your VNC server requires a password, or you wish to specify other
+configuration parameters (to reduce the color depth, for example), you will
+need to add additional `<param>` tags accordingly.
+
+Other authentication methods will provide documentation describing how to
+configure new connections. If the authentication method in use fully implements
+the features of Guacamole's authentication API, you will be able to add a new
+VNC connection easily and intuitively using the administration interface built
+into Guacamole. You will not need to edit configuration files.
+
+(vnc-servers)=
+
+#### Which VNC server?
+
+The choice of VNC server can make a big difference when it comes to
+performance, especially over slower networks. While many systems provide VNC
+access by default, using this is often not the fastest method.
+
+(realvnc)=
+
+##### RealVNC or TigerVNC
+
+RealVNC, and its derivative TigerVNC, perform quite well. In our testing, they
+perform the best with Guacamole. If you are okay with having a desktop that can
+only be accessed via VNC, one of these is likely your best choice. Both
+optimize window movement and (depending on the application) scrolling, giving a
+very responsive user experience.
+
+##### TightVNC
+
+TightVNC is widely-available and performs generally as well as RealVNC or
+TigerVNC. If you wish to use TightVNC with Guacamole, performance should be
+just fine, but we highly recommend disabling its JPEG encoding. This is because
+images transmitted to Guacamole are always encoded losslessly as PNG images.
+When this operation is performed on a JPEG image, the artifacts present from
+JPEG's lossy compression reduce the compressibility of the image for PNG, thus
+leading to a slower experience overall than if JPEG was simply not used to
+begin with.
+
+##### x11vnc
+
+The main benefit of using x11vnc is that it allows you to continue using your
+desktop normally, while simultaneously exposing control of your desktop via
+VNC. Performance of x11vnc is comparable to RealVNC, TigerVNC, and TightVNC. If
+you need to use your desktop locally as well as via VNC, you will likely be
+quite happy with x11vnc.
+
+##### vino
+
+vino is the VNC server that comes with the Gnome desktop environment, and is
+enabled if you enable "desktop sharing" via the system preferences available
+within Gnome. If you need to share your local desktop, we recommend using
+x11vnc rather vino, as it has proven more performant and feature-complete in
+our testing. If you don't need to share a local desktop but simply need an
+environment you can access remotely, using a VNC server like RealVNC, TigerVNC,
+or TightVNC is a better choice.
+
+(qemu)=
+
+##### QEMU or KVM
+
+QEMU (and thus KVM) expose the displays of virtual machines using VNC.  If you
+need to see the virtual monitor of your virtual machine, using this VNC
+connection is really your only choice. As the VNC server built into QEMU cannot
+be aware of higher-level operations like window movement, resizing, or
+scrolling, those operations will tend to be sent suboptimally, and will not be
+as fast as a VNC server running within the virtual machine.
+
+If you wish to use a virtual machine for desktop access, we recommend
+installing a native VNC server inside the virtual machine after the virtual
+machine is set up. This will give a more responsive desktop.
+
+### RDP
+
+The RDP protocol is more complicated than VNC and was the second protocol
+officially supported by Guacamole. RDP tends to be faster than VNC due to the
+use of caching, which Guacamole does take advantage of.
+
+RDP support for Guacamole is provided by the libguac-client-rdp library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the RDP-specific parameters below, Guacamole's RDP support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(rdp-network-parameters)=
+
+#### Network parameters
+
+RDP connections require a hostname or IP address defining the
+destination machine. The RDP port is defined to be 3389, and will be
+this value in most cases. You only need to specify the RDP port if you
+are not using port 3389.
+
+`hostname`
+: The hostname or IP address of the RDP server Guacamole should connect to.
+
+`port`
+: The port the RDP server is listening on. This parameter is optional. If
+  this is not specified, the standard port for RDP (3389) or Hyper-V's
+  default port for VMConnect (2179) will be used, depending on the security
+  mode selected.
+
+(rdp-authentication)=
+
+#### Authentication and security
+
+RDP provides authentication through the use of a username, password, and
+optional domain. All RDP connections are encrypted.
+
+Most RDP servers will provide a graphical login if the username, password, and
+domain parameters are omitted. One notable exception to this is Network Level
+Authentication, or NLA, which performs all authentication outside of a desktop
+session, and thus in the absence of a graphical interface.
+
+Servers that require NLA can be handled by Guacamole in one of two ways. The
+first is to provide the username and password within the connection
+configuration, either via static values or by passing through the Guacamole
+credentials with [parameter tokens](parameter-tokens) and [](ldap-auth).
+Alternatively, if credentials are not configured within the connection
+configuration, Guacamole will attempt to prompt the user for the credentials
+interactively, if the versions of both guacd and Guacamole Client in use
+support it. If either component does not support prompting and the credentials
+are not configured, NLA-based connections will fail.
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+`domain`
+: The domain to use when attempting authentication, if any. This parameter
+  is optional.
+
+`security`
+: The security mode to use for the RDP connection. This mode dictates how
+  data will be encrypted and what type of authentication will be performed,
+  if any. By default, a security mode is selected based on a negotiation
+  process which determines what both the client and the server support.
+
+  Possible values are:
+
+  any
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server. *This is the default*.
+
+  nla
+  : Network Level Authentication, sometimes also referred to as "hybrid" or
+    CredSSP (the protocol that drives NLA). This mode uses TLS encryption
+    and requires the username and password to be given in advance. Unlike
+    RDP mode, the authentication step is performed before the remote desktop
+    session actually starts, avoiding the need for the Windows server to
+    allocate significant resources for users that may not be authorized.
+
+    If the versions of guacd and Guacamole Client in use support prompting
+    and the username, password, and domain are not specified, the user will
+    be interactively prompted to enter credentials to complete NLA and
+    continue the connection. Otherwise, when prompting is not supported and
+    credentials are not provided, NLA connections will fail.
+
+  nla-ext
+  : Extended Network Level Authentication. This mode is identical to NLA
+    except that an additional "[Early User Authorization
+    Result](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d0e560a3-25cb-4563-8bdc-6c4cc625bbfc)"
+    is required to be sent from the server to the client immediately after the
+    NLA handshake is completed.
+
+  tls
+  : RDP authentication and encryption implemented via TLS (Transport Layer
+    Security). Also referred to as RDSTLS, the TLS security mode is
+    primarily used in load balanced configurations where the initial RDP
+    server may redirect the connection to a different RDP server.
+
+  vmconnect
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server, limiting that negotiation
+    to only the protocols known to be supported by [Hyper-V /
+    VMConnect](rdp-preconnection-pdu).
+
+  rdp
+  : Legacy RDP encryption. This mode is generally only used for older
+    Windows servers or in cases where a standard Windows login screen is
+    desired. Newer versions of Windows have this mode disabled by default
+    and will only accept NLA unless explicitly configured otherwise.
+
+`ignore-cert`
+: If set to "true", the certificate returned by the server will be ignored,
+  even if that certificate cannot be validated. This is useful if you
+  universally trust the server and your connection to the server, and you
+  know that the server's certificate cannot be validated (for example, if it
+  is self-signed).
+
+`disable-auth`
+: If set to "true", authentication will be disabled. Note that this refers
+  to authentication that takes place while connecting. Any authentication
+  enforced by the server over the remote desktop session (such as a login
+  dialog) will still take place. By default, authentication is enabled and
+  only used when requested by the server.
+
+  If you are using NLA, authentication must be enabled by definition.
+
+(rdp-session-settings)=
+
+#### Session settings
+
+RDP sessions will typically involve the full desktop environment of a normal
+user. Alternatively, you can manually specify a program to use instead of the
+RDP server's default shell, or connect to the administrative console.
+
+Although Guacamole is independent of keyboard layout, RDP is not. This is
+because Guacamole represents keys based on what they *do* ("press the Enter
+key"), while RDP uses identifiers based on the key's location ("press the
+rightmost key in the second row"). To translate between a Guacamole key event
+and an RDP key event, Guacamole must know ahead of time the keyboard layout of
+the RDP server.
+
+By default, the US English qwerty keyboard will be used. If this does not match
+the keyboard layout of your RDP server, keys will not be properly translated,
+and you will need to explicitly choose a different layout in your connection
+settings. If your keyboard layout is not supported, please notify the Guacamole
+team by [opening an issue in
+JIRA](https://issues.apache.org/jira/browse/GUACAMOLE).
+
+
+`client-name`
+: When connecting to the RDP server, Guacamole will normally provide its own
+  hostname as the name of the client. If this parameter is specified,
+  Guacamole will use its value instead.
+
+  On Windows RDP servers, this value is exposed within the session as the
+  `CLIENTNAME` environment variable.
+
+`console`
+: If set to "true", you will be connected to the console (admin) session of
+  the RDP server.
+
+`initial-program`
+: The full path to the program to run immediately upon connecting. This
+  parameter is optional.
+
+`server-layout`
+: The server-side keyboard layout. This is the layout of the RDP server and
+  has nothing to do with the keyboard layout in use on the client. *The
+  Guacamole client is independent of keyboard layout.* The RDP protocol,
+  however, is *not* independent of keyboard layout, and Guacamole needs to
+  know the keyboard layout of the server in order to send the proper keys
+  when a user is typing.
+
+  Possible values are generally in the format
+  {samp}`{LANGUAGE}-{REGION}-{VARIANT}`, where `LANGUAGE` is the standard
+  two-letter language code for the primary language associated with the
+  layout, `REGION` is a standard representation of the location that the
+  keyboard is used (the two-letter country code, when possible), and
+  `VARIANT` is the specific keyboard layout variant (such as "qwerty",
+  "qwertz", or "azerty"):
+
+  | Keyboard layout                | Parameter value        |
+  | ------------------------------ | ---------------------- |
+  | Brazilian (Portuguese)         | `pt-br-qwerty`         |
+  | English (UK)                   | `en-gb-qwerty`         |
+  | English (US)                   | `en-us-qwerty`         |
+  | French                         | `fr-fr-azerty`         |
+  | French (Belgian)               | `fr-be-azerty`         |
+  | French (Swiss)                 | `fr-ch-qwertz`         |
+  | German                         | `de-de-qwertz`         |
+  | German (Swiss)                 | `de-ch-qwertz`         |
+  | Hungarian                      | `hu-hu-qwertz`         |
+  | Italian                        | `it-it-qwerty`         |
+  | Japanese                       | `ja-jp-qwerty`         |
+  | Spanish                        | `es-es-qwerty`         |
+  | Spanish (Latin American)       | `es-latam-qwerty`      |
+  | Swedish                        | `sv-se-qwerty`         |
+  | Turkish-Q                      | `tr-tr-qwerty`         |
+
+  If you server's keyboard layout is not yet supported, and it is not possible
+  to set your server to use a supported layout, the `failsafe` layout may be used
+  to force Unicode events to be used for all input, however beware that doing so
+  may prevent keyboard shortcuts from working as expected.
+
+`timezone`
+: The timezone that the client should send to the server for configuring the
+  local time display of that server. The format of the timezone is in the
+  standard IANA key zone format, which is the format used in UNIX/Linux.
+  This will be converted by RDP into the correct format for Windows.
+
+  The timezone is detected and will be passed to the server during the
+  handshake phase of the connection, and may used by protocols, like RDP,
+  that support it. This parameter can be used to override the value detected
+  and passed during the handshake, or can be used in situations where guacd
+  does not support passing the timezone parameter during the handshake phase
+  (guacd versions prior to 1.3.0).
+
+  Support for forwarding the client timezone varies by RDP server
+  implementation. For example, with Windows, support for forwarding
+  timezones is only present in Windows Server with Remote Desktop Services
+  (RDS, formerly known as Terminal Services) installed. Windows Server
+  installations in admin mode, along with Windows workstation versions, do
+  not allow the timezone to be forwarded. Other server implementations, for
+  example, xrdp, may not implement this feature at all. Consult the
+  documentation for the RDP server to determine whether or not this feature
+  is supported.
+
+(rdp-display-settings)=
+
+#### Display settings
+
+Guacamole will automatically choose an appropriate display size for RDP
+connections based on the size of the browser window and the DPI of the device.
+The size of the display can be forced by specifying explicit width or height
+values.
+
+To reduce bandwidth usage, you may also request that the server reduce its
+color depth. Guacamole will automatically detect 256-color images, but this can
+be guaranteed for absolutely all graphics sent over the connection by forcing
+the color depth to 8-bit. Color depth is otherwise dictated by the RDP server.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, or 24. Regardless of what value
+  is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`width`
+: The width of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the width of the connecting
+  client display will be used instead.
+
+`height`
+: The height of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the height of the connecting
+  client display will be used instead.
+
+`dpi`
+: The desired effective resolution of the client display, in DPI. This
+  parameter is optional. If this value is not specified, the resolution and
+  size of the client display will be used together to determine,
+  heuristically, an appropriate resolution for the RDP session.
+
+`resize-method`
+: The method to use to update the RDP server when the width or height of the
+  client display changes. This parameter is optional. If this value is not
+  specified, no action will be taken when the client display changes size.
+
+  Normally, the display size of an RDP session is constant and can only be
+  changed when initially connecting. As of RDP 8.1, the "Display Update"
+  channel can be used to request that the server change the display size.
+  For older RDP servers, the only option is to disconnect and reconnect with
+  the new size.
+
+  Possible values are:
+
+  display-update
+  : Uses the "Display Update" channel added with RDP 8.1 to signal the
+    server when the client display size has changed.
+
+  reconnect
+  : Automatically disconnects the RDP session when the client display size
+    has changed, and reconnects with the new size.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+(rdp-device-redirection)=
+
+#### Device redirection
+
+Device redirection refers to the use of non-display devices over RDP.
+Guacamole's RDP support currently allows redirection of audio, printing, and
+disk access, some of which require additional configuration in order to
+function properly.
+
+Audio redirection will be enabled by default. If Guacamole was correctly
+installed, and audio redirection is supported by your RDP server, sound should
+play within remote connections without manual intervention.
+
+Printing requires GhostScript to be installed on the Guacamole server, and
+allows users to print arbitrary documents directly to PDF. When documents are
+printed to the redirected printer, the user will receive a PDF of that document
+within their web browser.
+
+Guacamole provides support for file transfer over RDP by emulating a virtual
+disk drive. This drive will persist on the Guacamole server, confined within
+the drive path specified. If drive redirection is enabled on a Guacamole RDP
+connection, users will be able to upload and download files as described in
+[](using-guacamole).
+
+`disable-audio`
+: Audio is enabled by default in both the client and in libguac-client-rdp.
+  If you are concerned about bandwidth usage, or sound is causing problems,
+  you can explicitly disable sound by setting this parameter to "true".
+
+`enable-audio-input`
+: If set to "true", audio input support (microphone) will be enabled,
+  leveraging the standard "`AUDIO_INPUT`" channel of RDP. By default, audio
+  input support within RDP is disabled.
+
+`enable-printing`
+: Printing is disabled by default, but with printing enabled, RDP users can
+  print to a virtual printer that sends a PDF containing the document
+  printed to the Guacamole client. Enable printing by setting this parameter
+  to "true".
+
+  *Printing support requires GhostScript to be installed.* If guacd cannot
+  find the `gs` executable when printing, the print attempt will fail.
+
+`printer-name`
+: The name of the redirected printer device that is passed through to the
+  RDP session. This is the name that the user will see in, for example, the
+  Devices and Printers control panel.
+
+  If printer redirection is not enabled, this option has no effect.
+
+`enable-drive`
+: File transfer is disabled by default, but with file transfer enabled, RDP
+  users can transfer files to and from a virtual drive which persists on the
+  Guacamole server. Enable file transfer support by setting this parameter
+  to "true".
+
+  Files will be stored in the directory specified by the "`drive-path`"
+  parameter, which is required if file transfer is enabled.
+
+`disable-download`
+: If set to true downloads from the remote server to client (browser) will
+  be disabled. This includes both downloads down via the hidden Guacamole
+  menu, as well as using the special "Download" folder presented to the
+  remote server. The default is false, which means that downloads will be
+  allowed.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`disable-upload`
+: If set to true, uploads from the client (browser) to the remote server
+  location will be disabled. The default is false, which means uploads will
+  be allowed if file transfer is enabled.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-name`
+: The name of the filesystem used when passed through to the RDP session.
+  This is the name that users will see in their Computer/My Computer area
+  along with client name (for example, "Guacamole on Guacamole RDP"), and is
+  also the name of the share when accessing the special `\\tsclient` network
+  location.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-path`
+: The directory on the Guacamole server in which transferred files should be
+  stored. This directory must be accessible by guacd and both readable and
+  writable by the user that runs guacd. *This parameter does not refer to a
+  directory on the RDP server.*
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`create-drive-path`
+: If set to "true", and file transfer is enabled, the directory specified by
+  the `drive-path` parameter will automatically be created if it does not
+  yet exist. Only the final directory in the path will be created - if other
+  directories earlier in the path do not exist, automatic creation will
+  fail, and an error will be logged.
+
+  By default, the directory specified by the `drive-path` parameter will not
+  automatically be created, and attempts to transfer files to a non-existent
+  directory will be logged as errors.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`console-audio`
+: If set to "true", audio will be explicitly enabled in the console (admin)
+  session of the RDP server. Setting this option to "true" only makes sense
+  if the `console` parameter is also set to "true".
+
+`static-channels`
+: A comma-separated list of static channel names to open and expose as
+  pipes. If you wish to communicate between an application running on the
+  remote desktop and JavaScript, this is the best way to do it. Guacamole
+  will open an outbound pipe with the name of the static channel. If
+  JavaScript needs to communicate back in the other direction, it should
+  respond by opening another pipe with the same name.
+
+  Guacamole allows any number of static channels to be opened, but protocol
+  restrictions of RDP limit the size of each channel name to 7 characters.
+
+(rdp-preconnection-pdu)=
+
+#### Preconnection PDU (Hyper-V / VMConnect)
+
+Some RDP servers host multiple logical RDP connections behind a single server
+listening on a single TCP port. To select between these logical connections, an
+RDP client must send the "preconnection PDU" - a message which contains values
+that uniquely identify the destination, referred to as the "RDP source". This
+mechanism is defined by the ["Session Selection
+Extension](https://msdn.microsoft.com/en-us/library/cc242359.aspx) for the RDP
+protocol, and is implemented by Microsoft's Hyper-V hypervisor.
+
+If you are using Hyper-V, you will need to specify the ID of the destination
+virtual machine within the `preconnection-blob` parameter.  This value can be
+determined using PowerShell:
+
+```ps1con
+PS C:\> Get-VM VirtualMachineName | Select-Object Id
+
+Id
+--
+ed272546-87bd-4db9-acba-e36e1a9ca20a
+
+
+PS C:\>
+```
+
+The preconnection PDU is intentionally generic. While its primary use is as a
+means for selecting virtual machines behind Hyper-V, other RDP servers may use
+it as well. It is up to the RDP server itself to determine whether the
+preconnection ID, BLOB, or both will be used, and what their values mean.
+
+*If you do intend to use Hyper-V, beware that its built-in RDP server requires
+different parameters for authentication and Guacamole's defaults will not
+work.* In most cases, you will need to do the following when connecting to
+Hyper-V:
+
+1. Specify both "`username`" and "`password`" appropriately, and set
+   "`security`" to "`vmconnect`". Selecting the "`vmconnect`" security mode
+   will configure Guacamole to automatically negotiate security modes known to
+   be supported by Hyper-V, and will automatically select Hyper-V's default RDP
+   port (2179).
+
+2. If necessary, set "`ignore-cert`" to "`true`". Hyper-V may use a self-signed
+   certificate.
+
+`preconnection-id`
+: The numeric ID of the RDP source. This is a non-negative integer value
+  dictating which of potentially several logical RDP connections should be
+  used. This parameter is optional, and is only required if the RDP server
+  is documented as requiring it. *If using Hyper-V, this should be left
+  blank.*
+
+`preconnection-blob`
+: An arbitrary string which identifies the RDP source - one of potentially
+  several logical RDP connections hosted by the same RDP server. This
+  parameter is optional, and is only required if the RDP server is
+  documented as requiring it, such as Hyper-V. In all cases, the meaning of
+  this parameter is opaque to the RDP protocol itself and is dictated by the
+  RDP server. *For Hyper-V, this will be the ID of the destination virtual
+  machine.*
+
+(rdp-gateway)=
+
+#### Remote desktop gateway
+
+Microsoft's remote desktop server provides an additional gateway service which
+allows external connections to be forwarded to internal RDP servers which are
+otherwise not accessible. If you will be using Guacamole to connect through
+such a gateway, you will need to provide additional parameters describing the
+connection to that gateway, as well as any required credentials.
+
+`gateway-hostname`
+: The hostname of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. *If omitted, a gateway
+  will not be used.*
+
+`gateway-port`
+: The port of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. By default, this will be
+  "443".
+
+`gateway-username`
+: The username of the user authenticating with the remote desktop gateway,
+  if a gateway is being used. This is not necessarily the same as the user
+  actually using the remote desktop connection.
+
+`gateway-password`
+: The password to provide when authenticating with the remote desktop
+  gateway, if a gateway is being used.
+
+`gateway-domain`
+: The domain of the user authenticating with the remote desktop gateway, if
+  a gateway is being used. This is not necessarily the same domain as the
+  user actually using the remote desktop connection.
+
+(rdp-connection-broker)=
+
+#### Load balancing and RDP connection brokers
+
+If your remote desktop servers are behind a load balancer, sometimes referred
+to as a "connection broker" or "TS session broker", that balancer may require
+additional information during the connection process to determine how the
+incoming connection should be routed. RDP does not dictate the format of this
+information; it is specific to the balancer in use.
+
+If you are using a load balancer and are unsure whether such information is
+required, *you will need to check the documentation for your balancer*. If your
+balancer provides `.rdp` files for convenience, look through the contents of
+those files for a string field called "loadbalanceinfo", as that field is where
+the required information/cookie would be specified.
+
+`load-balance-info`
+: The load balancing information or cookie which should be provided to the
+  connection broker. *If no connection broker is being used, this should be
+  left blank.*
+
+(rdp-perf-flags)=
+
+#### Performance flags
+
+RDP provides several flags which control the availability of features that
+decrease performance and increase bandwidth for the sake of aesthetics, such as
+wallpaper, window theming, menu effects, and smooth fonts. These features are
+all disabled by default within Guacamole such that bandwidth usage is
+minimized, but you can manually re-enable them on a per-connection basis if
+desired.
+
+`enable-wallpaper`
+: If set to "true", enables rendering of the desktop wallpaper. By default,
+  wallpaper will be disabled, such that unnecessary bandwidth need not be
+  spent redrawing the desktop.
+
+`enable-theming`
+: If set to "true", enables use of theming of windows and controls. By
+  default, theming within RDP sessions is disabled.
+
+`enable-font-smoothing`
+: If set to "true", text will be rendered with smooth edges. Text over RDP
+  is rendered with rough edges by default, as this reduces the number of
+  colors used by text, and thus reduces the bandwidth required for the
+  connection.
+
+`enable-full-window-drag`
+: If set to "true", the contents of windows will be displayed as windows are
+  moved. By default, the RDP server will only draw the window border while
+  windows are being dragged.
+
+`enable-desktop-composition`
+: If set to "true", graphical effects such as transparent windows and
+  shadows will be allowed. By default, such effects, if available, are
+  disabled.
+
+`enable-menu-animations`
+: If set to "true", menu open and close animations will be allowed. Menu
+  animations are disabled by default.
+
+`disable-bitmap-caching`
+: In certain situations, particularly with RDP server implementations with
+  known bugs, it is necessary to disable RDP's built-in bitmap caching
+  functionality. This parameter allows that to be controlled in a Guacamole
+  session. If set to "true" the RDP bitmap cache will not be used.
+
+`disable-offscreen-caching`
+: RDP normally maintains caches of regions of the screen that are current

Review comment:
       that are _currently_

##########
File path: src/reverse-proxy.md
##########
@@ -0,0 +1,427 @@
+Proxying Guacamole
+==================
+
+Like most web applications, Guacamole can be placed behind a reverse proxy. For
+production deployments of Guacamole, this is *highly recommended*. It provides
+flexibility and, if your proxy is properly configured for SSL, encryption.
+
+Proxying isolates privileged operations within native applications that can
+safely drop those privileges when no longer needed, using Java only for
+unprivileged tasks. On Linux and UNIX systems, a process must be running with
+root privileges to listen on any port under 1024, including the standard HTTP
+and HTTPS ports (80 and 443 respectively). If the servlet container instead
+listens on a higher port, such as the default port 8080, it can run as a
+reduced-privilege user, allowing the reverse proxy to bear the burden of root
+privileges. As a native application, the reverse proxy can make system calls to
+safely drop root privileges once the port is open; a Java application like
+Tomcat cannot do this.
+
+(preparing-servlet-container)=
+
+Preparing your servlet container
+--------------------------------
+
+Your servlet container is most likely already configured to listen for HTTP
+connections on port 8080 as this is the default. If this is the case, and you
+can already access Guacamole over port 8080 from a web browser, you need not
+make any further changes to its configuration.
+
+If you *have* changed this, perhaps with the intent of proxying Guacamole over
+AJP, *change it back*. Using Guacamole over AJP is unsupported as it is known
+to cause problems, namely:
+
+1. WebSocket will not work over AJP, forcing Guacamole to fallback to HTTP,
+   possibly resulting in reduced performance.
+
+2. Apache 2.4.3 and older does not support the HTTP PATCH method over AJP,
+   preventing the Guacamole management interface from functioning properly.
+
+The connector entry within `conf/server.xml` should look like this:
+
+```xml
+<Connector port="8080" protocol="HTTP/1.1" 
+           connectionTimeout="20000"
+           URIEncoding="UTF-8"
+           redirectPort="8443" />
+```
+
+Be sure to specify the `URIEncoding="UTF-8"` attribute as above to ensure that
+connection names, user names, etc. are properly received by the web
+application. If you will be creating connections that have Cyrillic, Chinese,
+Japanese, or other non-Latin characters in their names or parameter values,
+this attribute is required.
+
+(tomcat-remote-ip)=
+
+### Setting up the Remote IP Valve
+
+By default, when Tomcat is behind a reverse proxy, the remote IP address of the
+client that it sees is that of the proxy rather than the original client. In
+order to allow applications hosted within Tomcat, like Guacamole, to see the
+actual IP address of the client, you have to configure both the reverse proxy
+and Tomcat.
+
+Because the remote IP address in Guacamole is used for auditing of user logins
+and connections and could potentially be used for authentication, it is
+important that you are either in direct control of the proxy server or you
+explicitly trust it. Passing the remote IP address is done using the
+`X-Forwarded-For` header, and, as with most HTTP headers, attackers can attempt
+to spoof this header in order to manipulate the behavior of the web server,
+gain unauthorized access to the system, or attempt to disguise the host or IP
+address they are coming from.
+
+One final caveat: This may not work as expected if there are other upstream
+proxy servers between your reverse proxy and the clients access Guacamole.
+Other proxies or firewalls can mask the IP address of the client, and if the
+configuration of those is not within your control you may end up with multiple
+clients appearing to come from the same IP address or host. Make sure you take
+this into account when configuring the system and looking at the data provided.
+
+Configuring Tomcat to pass through the remote IP address provided by the
+reverse proxy in the `X-Forwarded-For` header requires the configuration of
+what Tomcat calls a Valve. In this case, it is the
+[`RemoteIpValve`](https://tomcat.apache.org/tomcat-8.5-doc/config/valve.html#Remote_IP_Valve)
+and is configured in the `conf/server.xml` file, in the `<Host>` section:
+
+```xml
+<Valve className="org.apache.catalina.valves.RemoteIpValve"
+               internalProxies="127.0.0.1"
+               remoteIpHeader="x-forwarded-for"
+               remoteIpProxiesHeader="x-forwarded-by"
+               protocolHeader="x-forwarded-proto" />
+```
+
+The `internalProxies` value should be set to the IP address or addresses of any
+and all reverse proxy servers that will be accessing this Tomcat instance
+directly. Often it is run on the same system that runs Tomcat, but in other
+cases (for example, when running Docker), it may be on a different
+system/container and may need to be set to the actual IP address of the reverse
+proxy system. Only proxy servers listed in the `internalProxies` or
+`trustedProxies` parameters will be allowed to manipulate the remote IP address
+information. The other parameters in this configuration line allow you to
+control which headers coming from the proxy server(s) are used for various
+remote host information. They are as follows:
+
+`remoteIpHeader`
+: The header that is queried to learn the client IP address of the client
+  that originated the request. The standard value is `X-Forwarded-For`, but
+  can be configured to any header you like. The IP address in this header
+  will be available to Java applications in the `request.getRemoteAddr()`
+  method.
+
+`remoteIpProxiesHeader`
+: The header that is queried to learn the IP address of the proxy server
+  that forwarded the request. The default value is `X-Forwarded-By`, but can
+  be configured to any header that fits your environment. This value will
+  only be allowed by the valve if the proxy used is listed in the
+  `trustedProxies` parameter. Otherwise this header will not be available.
+
+`protocolHeader`
+: The header that is queried to determine the protocol that the client used
+  to connect to the service. The default value is `X-Forwarded-Proto`, but
+  can be configured to fit your environment.
+
+In addition to configuring Tomcat to properly handle these headers, you also
+may need to configure your reverse proxy appropriately to send the headers. You
+can find instructions for this in [](nginx) - the Apache web server passes it
+through by default.
+
+(nginx)=
+
+Nginx
+-----
+
+Nginx can be used as a reverse proxy, and supports WebSocket out-of-the-box
+[since version 1.3](http://nginx.com/blog/websocket-nginx/). Both Apache and
+Nginx require some additional configuration for proxying of WebSocket to work
+properly.
+
+(proxying-with-nginx)=
+
+### Proxying Guacamole
+
+Nginx does support WebSocket for proxying, but requires that the "Connection"
+and "Upgrade" HTTP headers are set explicitly due to the nature of the
+WebSocket protocol. From the Nginx documentation:
+
+> NGINX supports WebSocket by allowing a tunnel to be set up between a client
+> and a back-end server. For NGINX to send the Upgrade request from the client
+> to the back-end server, Upgrade and Connection headers must be set
+> explicitly. ...
+
+The proxy configuration belongs within a dedicated
+[`location`](http://nginx.org/en/docs/http/ngx_http_core_module.html#location>)
+block, declaring the backend hosting Guacamole and explicitly specifying the
+"`Connection`" and "`Upgrade`" headers mentioned earlier:
+
+```nginx
+location /guacamole/ {
+    proxy_pass http://HOSTNAME:8080;

Review comment:
       This appears to have changed slightly from the current manual, which has `proxy_pass` listed as `http://HOSTNAME:8080/guacamole`. I'm not sure if this change is intentional or not, and how much confusion it may or may not cause? I think given the instructions throughout the manual for deploying as `guacamole.war`, it might be best to have the `/guacamole` on the end of it?

##########
File path: src/jdbc-auth.md
##########
@@ -0,0 +1,1834 @@
+Database authentication
+=======================
+
+Guacamole supports authentication via MySQL, PostgreSQL, or SQL Server
+databases through extensions available from the project website. Using a
+database for authentication provides additional features, such as the ability
+to use load balancing groups of connections and a web-based administrative
+interface. Unlike the default, XML-driven authentication module, all changes to
+users and connections take effect immediately; users need not logout and back
+in to see new connections.
+
+While most authentication extensions function independently, the database
+authentication can act in a subordinate role, allowing users and user groups
+from other authentication extensions to be associated with connections within
+the database. Users and groups are considered identical to those within the
+database if they have the same names, and the authentication result of another
+extension will be trusted if it succeeds. A user with an account under multiple
+systems will thus be able to see data from each system after successfully
+logging in. For more information on using the database authentication alongside
+other mechanisms, see [](ldap-and-database) within [](ldap-auth).
+
+To use the database authentication extension, you will need:
+
+1. A supported database - currently MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+2. Sufficient permission to create new databases, to create new users, and to
+   grant those users permissions.
+
+3. Network access to the database from the Guacamole server.
+
+:::{important}
+This chapter involves modifying the contents of `GUACAMOLE_HOME` - the
+Guacamole configuration directory. If you are unsure where `GUACAMOLE_HOME` is
+located on your system, please consult [](configuring-guacamole) before
+proceeding.
+:::
+
+Downloading the database authentication extension
+-------------------------------------------------
+
+The database authentication extension is available separately from the main
+`guacamole.war`. The link for this and all other officially-supported and
+compatible extensions for a particular version of Guacamole are provided on the
+release notes for that version. You can find the release notes for current
+versions of Guacamole here: <http://guacamole.apache.org/releases/>.
+
+The database authentication extension is packaged as a `.tar.gz` file
+containing several database-specific directories. Only one of the directories
+within the archive will be applicable to you, depending on whether you are
+using MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+Each database-specific directory contains a `schema/` directory and `.jar` file
+(the actual Guacamole extension). The Guacamole extension `.jar` will
+ultimately need to be placed within `GUACAMOLE_HOME/extensions`, while the JDBC
+driver must be downloaded separately from the database vendor and placed within
+`GUACAMOLE_HOME/lib`.
+
+::::{tab} MySQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `mysql/guacamole-auth-jdbc-mysql-1.3.0.jar`
+* - SQL schema scripts
+  - `mysql/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following MySQL-compatible JDBC drivers are supported for connecting Guacamole with MySQL or MariaDB:
+
+* [MySQL Connector/J](http://dev.mysql.com/downloads/connector/j/)
+* [MariaDB Connector/J](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+
+If using the JDBC driver from MySQL, the required `.jar` will be within a
+`.tar.gz` archive.
+::::
+
+::::{tab} PostgreSQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `postgresql/guacamole-auth-jdbc-postgresql-1.3.0.jar`
+* - SQL schema scripts
+  - `postgresql/schema/`
+* - JDBC driver
+  - [PostgreSQL JDBC Driver](https://jdbc.postgresql.org/download.html#current)
+:::
+::::
+
+::::{tab} SQL Server
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `sqlserver/guacamole-auth-jdbc-sqlserver-1.3.0.jar`
+* - SQL schema scripts
+  - `sqlserver/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following TDS-compatible JDBC drivers are supported for connecting
+Guacamole to SQL Server:
+
+* [Microsoft JDBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server)
+* [jTDS](http://jtds.sourceforge.net/)
+* [Progress DataDirect’s JDBC Driver for SQL Server](https://www.progress.com/jdbc/microsoft-sql-server)
+* Microsoft SQL Server 2000 JDBC Driver (legacy)
+::::
+
+(jdbc-auth-database-creation)=
+
+Creating the Guacamole database
+-------------------------------
+
+The database authentication module will need a database to store
+authentication data and a user to use only for data access and
+manipulation. You can use an existing database and existing user, but
+for the sake of simplicity and security, these instructions assume you
+will be creating a new database and new user that will be used only by
+Guacamole and only for this authentication module.
+
+You need MariaDB, MySQL, PostgreSQL, or SQL Server installed, and must
+have sufficient access to create and administer databases. If this is
+not the case, install your database of choice now. Most distributions
+will provide a convenient MySQL or PostgreSQL package which will set up
+everything for you, including the root database user, if applicable. If
+you're using SQL Server, you need to install the packages on your
+platform of choice, and also make sure that you obtain the proper
+licensing for the version and edition of SQL Server you are running.
+
+For the sake of clarity, these instructions will refer to the database
+as "guacamole_db", but the database can be named whatever you like.
+
+:::{tab} MySQL
+```console
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql  upgrade
+$ cat schema/*.sql | mysql -u root -p guacamole_db
+Enter password: password
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ createdb guacamole_db
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql
+$ cat schema/*.sql | psql -d guacamole_db -f -
+CREATE TYPE
+CREATE TYPE
+CREATE TYPE
+CREATE TABLE
+CREATE INDEX
+...
+INSERT 0 1
+INSERT 0 4
+INSERT 0 3
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/001-create-schema.sql
+Password: password
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/002-create-admin-user.sql
+Password: password
+
+(1 rows affected)
+
+(3 rows affected)
+
+(5 rows affected)
+```
+:::
+
+Upgrading an existing Guacamole database
+----------------------------------------
+
+If you are upgrading from an older version of Guacamole, you may need to run
+one or more database schema upgrade scripts located within the
+`schema/upgrade/` directory. Each of these scripts is named
+{samp}`upgrade-pre-{VERSION}.sql` where `VERSION` is the version of Guacamole
+where those changes were introduced. They need to be run when you are upgrading
+from a version of Guacamole older than `VERSION`.
+
+If there are no {samp}`upgrade-pre-{VERSION}.sql` scripts present in the
+`schema/upgrade/` directory which apply to your existing Guacamole database,
+then the schema has not changed between your version and the version your are
+installing, and there is no need to run any database upgrade scripts.
+
+These scripts are incremental and, when relevant, *must be run in order*. For
+example, if you are upgrading an existing database from version
+0.9.13-incubating to version 1.0.0, you would need to run the
+`upgrade-pre-0.9.14.sql` script (because 0.9.13-incubating is older than
+0.9.14), followed by the `upgrade-pre-1.0.0.sql` script (because
+0.9.13-incubating is also older than 1.0.0).
+
+:::{important}
+Because the permissions granted to the Guacamole-specific PostgreSQL user when
+the database was first created will not automatically be granted for any new
+tables and sequences, you will also need to re-grant those permissions after
+applying any upgrade relevant scripts:
+
+```
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+Granting Guacamole access to the database
+-----------------------------------------
+
+For Guacamole to be able to execute queries against the database, you must
+create a new user for the database and grant that user sufficient privileges to
+manage the contents of all tables in the database. The user created for
+Guacamole needs only `SELECT`, `UPDATE`, `INSERT`, and `DELETE` permissions on
+all Guacamole tables.  Additionally, if using PostgreSQL, the user will need
+`SELECT` and `USAGE` permission on all sequences within all Guacamole tables.
+*No other permissions should be granted.*
+
+These instructions will refer to the user as "guacamole_user" but the user can
+be named whatever you like. Naturally, you should also choose a real password
+for your user rather than the string "some_password" used as a placeholder
+below.
+
+:::{tab} MySQL
+```console
+$ mysql -u root -p
+Enter password: password
+Welcome to the MySQL monitor.  Commands end with ; or \g.
+Your MySQL connection id is 233
+Server version: 5.5.29-0ubuntu0.12.10.1 (Ubuntu)
+
+Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+
+Oracle is a registered trademark of Oracle Corporation and/or its
+affiliates. Other names may be trademarks of their respective
+owners.
+
+Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
+
+mysql> CREATE DATABASE guacamole_db;
+Query OK, 1 row affected (0.00 sec)
+
+mysql> CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'some_password';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> FLUSH PRIVILEGES;
+Query OK, 0 rows affected (0.02 sec)
+
+mysql> quit
+Bye
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# CREATE USER guacamole_user WITH PASSWORD 'some_password';
+CREATE ROLE
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA
+Password: password
+1> CREATE DATABASE guacamole_db;
+2> GO
+1> CREATE LOGIN guacamole_user WITH PASSWORD = 'some_password';
+2> GO
+1> USE guacamole_db;
+2> GO
+1> CREATE USER guacamole_user;
+2> GO
+1> ALTER ROLE db_datawriter ADD MEMBER guacamole_user;
+2> ALTER ROLE db_datareader ADD MEMBER guacamole_user;
+3> GO
+```
+:::
+
+(jdbc-auth-installation)=
+
+Installing database authentication
+----------------------------------
+
+Guacamole extensions are self-contained `.jar` files which are located within
+the `GUACAMOLE_HOME/extensions` directory. To install the database
+authentication extension, you must:
+
+1. Create the `GUACAMOLE_HOME/extensions` directory, if it does not already
+   exist.
+
+2. Copy `guacamole-auth-jdbc-mysql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-postgresql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-sqlserver-1.3.0.jar` within
+   `GUACAMOLE_HOME/extensions`, depending on whether you are using
+   MySQL/MariaDB, PostgreSQL, or SQL Server.
+
+3. Copy the JDBC driver for your database to `GUACAMOLE_HOME/lib`. Without a

Review comment:
       Since creation of the `GUACAMOLE_HOME/extensions` directory is explicitly mentioned, I wonder if it would be appropriate to mention the creation of the `GUACAMOLE_HOME/lib` directory, too?

##########
File path: src/configuring-guacamole.md
##########
@@ -0,0 +1,2770 @@
+Configuring Guacamole
+=====================
+
+After installing Guacamole, you need to configure users and connections before
+Guacamole will work. This chapter covers general configuration of Guacamole and
+the use of its default authentication method.
+
+Guacamole's default authentication method reads all users and connections from
+a single file called `user-mapping.xml`. This authentication method is intended
+to be:
+
+1. Sufficient for small deployments of Guacamole.
+
+2. A relatively-easy means of verifying that Guacamole has been properly set
+   up.
+
+Other, more complex authentication methods which use backend databases, LDAP,
+etc. are discussed in a separate, dedicated chapters.
+
+Regardless of the authentication method you use, Guacamole's configuration
+always consists of two main pieces: a directory referred to as
+`GUACAMOLE_HOME`, which is the primary search location for configuration files,
+and `guacamole.properties`, the main configuration file used by Guacamole and
+its extensions.
+
+(guacamole-home)=
+
+`GUACAMOLE_HOME` (`/etc/guacamole`)
+---------------------------------------
+
+`GUACAMOLE_HOME` is the name given to Guacamole's configuration directory,
+which is located at `/etc/guacamole` by default. All configuration files,
+extensions, etc. reside within this directory. The structure of
+`GUACAMOLE_HOME` is rigorously defined, and consists of the following optional
+files:
+
+`guacamole.properties`
+: The main Guacamole configuration file. Properties within this file dictate
+  how Guacamole will connect to guacd, and may configure the behavior of
+  installed authentication extensions.
+
+`logback.xml`
+: Guacamole uses a logging system called Logback for all messages. By
+  default, Guacamole will log to the console only, but you can change this
+  by providing your own Logback configuration file.
+
+`extensions/`
+: The install location for all Guacamole extensions. Guacamole will
+  automatically load all `.jar` files within this directory on startup.
+
+`lib/`
+: The search directory for libraries required by any Guacamole extensions.
+  Guacamole will make the `.jar` files within this directory available to
+  all extensions. If your extensions require additional libraries, such as
+  database drivers, this is the proper place to put them.
+
+(overriding-guacamole-home)=
+
+### Overriding `GUACAMOLE_HOME`
+
+If you cannot or do not wish to use `/etc/guacamole` for `GUACAMOLE_HOME`, the
+location can be overridden through any of the following methods:
+
+1. Creating a directory named `.guacamole`, within the home directory of *the
+   user running the servlet container*. This directory will automatically be
+   used for `GUACAMOLE_HOME` if it exists.
+
+2. Specifying the full path to an alternative directory with the environment
+   variable `GUACAMOLE_HOME`. *Be sure to consult the documentation for your
+   servlet container to determine how to properly set environment variables.*
+
+3. Specifying the full path to an alternative directory with the system
+   property guacamole.home.
+
+(initial-setup)=
+
+`guacamole.properties`
+------------------------
+
+The Guacamole web application uses one main configuration file called
+`guacamole.properties`. This file is the common location for all configuration
+properties read by Guacamole or any extension of Guacamole, including
+authentication providers.
+
+In previous releases, this file had to be in the classpath of your servlet
+container. Now, the location of `guacamole.properties` can be explicitly
+defined with environment variables or system properties, and the classpath is
+only used as a last resort. When searching for `guacamole.properties`,
+Guacamole will check, in order:
+
+1. Within `GUACAMOLE_HOME`, as defined above.
+
+2. The classpath of the servlet container.
+
+The `guacamole.properties` file is optional and is used to configure Guacamole
+in situations where the defaults are insufficient, or to provide additional
+configuration information for extensions. There are several standard properties
+that are always available for use:
+
+`api-session-timeout`
+: The amount of time, in minutes, to allow Guacamole sessions
+  (authentication tokens) to remain valid despite inactivity. If omitted,
+  Guacamole sessions will expire after 60 minutes of inactivity.
+
+`api-max-request-size`
+: The maximum number of bytes to accept within the entity body of any
+  particular HTTP request, where 0 indicates that no limit should be
+  applied. If omitted, requests will be limited to 2097152 bytes (2 MB) by
+  default. This limit does not apply to file uploads.
+
+  If using a reverse proxy for SSL termination, *keep in mind that reverse
+  proxies may enforce their own limits independently of this*. For example,
+  [Nginx will enforce a 1 MB request size limit by
+  default](nginx-file-upload-size).
+
+`allowed-languages`
+: A comma-separated whitelist of language keys to allow as display language
+  choices within the Guacamole interface. For example, to restrict Guacamole
+  to only English and German, you would specify:
+
+  ```
+  allowed-languages: en, de
+  ```
+
+  As English is the fallback language, used whenever a translation key is
+  missing from the chosen language, English should only be omitted from this
+  list if you are absolutely positive that no strings are missing.
+
+  The corresponding JSON of any built-in languages not listed here will
+  still be available over HTTP, but the Guacamole interface will not use
+  them, nor will they be used automatically based on local browser language.
+  If omitted, all defined languages will be available.
+
+`enable-environment-properties`
+: If set to "true", Guacamole will first evaluate its environment to obtain
+  the value for any given configuration property, before using a value
+  specified in `guacamole.properties` or falling back to a default value. By
+  enabling this option, you can easily override any other configuration
+  property using an environment variable.
+
+  ```
+  enable-environment-properties: true
+  ```
+
+  When searching for a configuration property in the environment, the name
+  of the property is first transformed by converting all lower case
+  characters to their upper case equivalents, and by replacing all hyphen
+  characters (`-`) with underscore characters (`_`). For example, the
+  `guacd-hostname` property would be transformed to `GUACD_HOSTNAME` when
+  searching the environment.
+
+`guacd-hostname`
+: The host the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on localhost.
+
+`guacd-port`
+: The port the Guacamole proxy daemon (guacd) is listening on. If omitted,
+  Guacamole will assume guacd is listening on port 4822.
+
+`guacd-ssl`
+: If set to "true", Guacamole will require SSL/TLS encryption between the
+  web application and guacd. By default, communication between the web
+  application and guacd will be unencrypted.
+
+  Note that if you enable this option, you must also configure guacd to use
+  SSL via command line options. These options are documented in the manpage
+  of guacd. You will need an SSL certificate and private key.
+
+`skip-if-unavailable`
+: A comma-separated list of the identifiers of authentication providers that
+  should be allowed to fail internally without aborting the authentication
+  process. For example, to request that Guacamole ignore failures due to the
+  LDAP directory or MySQL server being unexpectedly down, allowing other
+  authentication providers to continue functioning:
+
+  ```
+  skip-if-unavailable: mysql, ldap
+  ```
+
+  By default, Guacamole takes a conservative approach to internal failures,
+  aborting the authentication process if an internal error occurs within any
+  authentication provider. Depending on the nature of the error, this may
+  mean that no users can log in until the cause of the failure is dealt
+  with. The `skip-if-unavailable` property may be used to explicitly inform
+  Guacamole that one or more underlying systems are expected to occasionally
+  experience failures, and that other functioning systems should be relied
+  upon if they do fail.
+
+
+```
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port:     4822
+```
+
+(webapp-logging)=
+
+Logging within the web application
+----------------------------------
+
+By default, Guacamole logs all messages to the console. Servlet containers like
+Tomcat will automatically redirect these messages to a log file, `catalina.out`
+in the case of Tomcat, which you can read through while Guacamole runs.
+Messages are logged at four different log levels, depending on message
+importance and severity:
+
+`error`
+: Errors are fatal conditions. An operation, described in the log message,
+  was attempted but could not proceed, and the failure of this operation is
+  a serious problem that needs to be addressed.
+
+`warn`
+: Warnings are generally non-fatal conditions. The operation continued, but
+  encountered noteworthy problems.
+
+`info`
+: "Info" messages are purely informational. They may be useful or
+  interesting to administrators, but are not generally critical to proper
+  operation of a Guacamole server.
+
+`debug`
+: Debug messages are highly detailed and oriented toward development. Most
+  debug messages will contain stack traces and internal information that is
+  useful when investigating problems within code. It is expected that debug
+  messages, though verbose, will not affect performance.
+
+`trace`
+: Trace messages are similar to debug messages in intent and verbosity, but
+  are so low-level that they may affect performance due to their frequency.
+  Trace-level logging is rarely necessary, and is mainly useful in providing
+  highly detailed context around issues being investigated.
+
+Guacamole logs messages using a logging framework called
+[Logback](http://logback.qos.ch/) and, by default, will only log messages at
+the "`info`" level or higher. If you wish to change the log level, or configure
+how or where Guacamole logs messages, you can do so by providing your own
+`logback.xml` file within `GUACAMOLE_HOME`.  For example, to log all messages
+to the console, even "`debug`" messages, you might use the following
+`logback.xml`:
+
+```xml
+<configuration>
+
+    <!-- Appender for debugging -->
+    <appender name="GUAC-DEBUG" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log at DEBUG level -->
+    <root level="debug">
+        <appender-ref ref="GUAC-DEBUG"/>
+    </root>
+
+</configuration>
+```
+
+Guacamole and the above example configure only one appender which logs to the
+console, but Logback is extremely flexible and allows any number of appenders
+which can each log to separate files, the console, etc.  based on a number of
+criteria, including the log level and the source of the message.
+
+More thorough [documentation on configuring
+Logback](http://logback.qos.ch/manual/configuration.html) is provided on the
+Logback project's web site.
+
+(basic-auth)=
+
+Using the default authentication
+--------------------------------
+
+Guacamole's default authentication module is simple and consists of a mapping
+of usernames to configurations. This authentication module comes with Guacamole
+and simply reads usernames and passwords from an XML file. It is always
+enabled, but will only read from the XML file if it exists, and is always last
+in priority relative to any other authentication extensions.
+
+There are other authentication modules available. The Guacamole project
+provides database-backed authentication modules with the ability to manage
+connections and users from the web interface, and other authentication modules
+can be created using the extension API provided along with the Guacamole web
+application, guacamole-ext.
+
+(user-mapping)=
+
+### `user-mapping.xml`
+
+The default authentication provider used by Guacamole reads all username,
+password, and configuration information from a file called the "user mapping"
+located at `GUACAMOLE_HOME/user-mapping.xml`. An example of a user mapping file
+is included with Guacamole, and looks something like this:
+
+```xml
+<user-mapping>
+
+    <!-- Per-user authentication and config information -->
+    <authorize username="USERNAME" password="PASSWORD">
+        <protocol>vnc</protocol>
+        <param name="hostname">localhost</param>
+        <param name="port">5900</param>
+        <param name="password">VNCPASS</param>
+    </authorize>
+
+    <!-- Another user, but using md5 to hash the password
+         (example below uses the md5 hash of "PASSWORD") -->
+    <authorize
+            username="USERNAME2"
+            password="319f4d26e3c536b5dd871bb2c52e3178"
+            encoding="md5">
+
+        <!-- First authorized connection -->
+        <connection name="localhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">localhost</param>
+            <param name="port">5901</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+        <!-- Second authorized connection -->
+        <connection name="otherhost">
+            <protocol>vnc</protocol>
+            <param name="hostname">otherhost</param>
+            <param name="port">5900</param>
+            <param name="password">VNCPASS</param>
+        </connection>
+
+    </authorize>
+
+</user-mapping>
+```
+
+Each user is specified with a corresponding `<authorize>` tag. This tag
+contains all authorized connections for that user, each denoted with a
+`<connection>` tag. Each `<connection>` tag contains a corresponding protocol
+and set of protocol-specific parameters, specified with the `<protocol>` and
+`<param>` tags respectively.
+
+(user-setup)=
+
+#### Adding users
+
+When using `user-mapping.xml`, username/password pairs are specified with
+`<authorize>` tags, which each have a `username` and `password` attribute. Each
+`<authorize>` tag authorizes a specific username/password pair to access all
+connections within the tag:
+
+```xml
+<authorize username="USER" password="PASS">
+    ...
+</authorize>
+```
+
+In the example above, the password would be listed in plaintext. If you don't
+want to do this, you can also specify your password hashed with MD5:
+
+```xml
+<authorize username="USER"
+           password="319f4d26e3c536b5dd871bb2c52e3178"
+           encoding="md5">
+    ...
+</authorize>
+```
+
+After modifying `user-mapping.xml`, the file will be automatically reread by
+Guacamole, and your changes will take effect immediately. The newly-added user
+will be able to log in - no restart of the servlet container is needed.
+
+(connection-setup)=
+
+#### Adding connections to a user
+
+To specify a connection within an `<authorize>` tag, you can either list a
+single protocol and set of parameters (specified with a `<protocol>` tag and
+any number of `<param>` tags), in which case that user will have access to only
+one connection named "DEFAULT", or you can specify one or more connections with
+one or more `<connection>` tags, each of which can be named and contains a
+`<protocol>` tag and any number of `<param>` tags.
+
+(connection-configuration)=
+
+Configuring connections
+-----------------------
+
+Each protocol supported by Guacamole has its own set of configuration
+parameters. These parameters typically describe the hostname and port of the
+remote desktop server, the credentials to use when connecting, if any, and the
+size and color depth of the display. If the protocol supports file transfer,
+options for enabling that functionality will be provided as well.
+
+### VNC
+
+The VNC protocol is the simplest and first protocol supported by Guacamole.
+Although generally not as fast as RDP, many VNC servers are adequate, and VNC
+over Guacamole tends to be faster than VNC by itself due to decreased bandwidth
+usage.
+
+VNC support for Guacamole is provided by the libguac-client-vnc library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the VNC-specific parameters below, Guacamole's VNC support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(vnc-network-parameters)=
+
+#### Network parameters
+
+With the exception of reverse-mode VNC connections, VNC works by making
+outbound network connections to a particular host which runs one or more VNC
+servers. Each VNC server is associated with a display number, from which the
+appropriate port number is derived.
+
+`hostname`
+: The hostname or IP address of the VNC server Guacamole should connect to.
+
+`port`
+: The port the VNC server is listening on, usually 5900 or 5900 + display
+  number. For example, if your VNC server is serving display number 1
+  (sometimes written as `:1`), your port number here would be 5901.
+
+`autoretry`
+: The number of times to retry connecting before giving up and returning an
+  error. In the case of a reverse connection, this is the number of times
+  the connection process is allowed to time out.
+
+(vnc-authentication)=
+
+#### Authentication
+
+The VNC standard defines only password based authentication. Other
+authentication mechanisms exist, but are non-standard or proprietary.
+Guacamole currently supports both standard password-only based authentication,
+as well as username and password authentication.
+
+`username`
+: The username to use when attempting authentication, if any. This parameter
+  is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+(vnc-display-settings)=
+
+#### Display settings
+
+VNC servers do not allow the client to request particular display sizes, so you
+are at the mercy of your VNC server with respect to display width and height.
+However, to reduce bandwidth usage, you may request that the VNC server reduce
+its color depth. Guacamole will automatically detect 256-color images, but this
+can be guaranteed for absolutely all graphics sent over the connection by
+forcing the color depth to 8-bit. Color depth is otherwise dictated by the VNC
+server.
+
+If you are noticing problems with your VNC display, such as the lack of a mouse
+cursor, the presence of multiple mouse cursors, or strange colors (such as blue
+colors appearing more like orange or red), these are typically the result of
+bugs or limitations within the VNC server, and additional parameters are
+available to work around such issues.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, 24, or 32. Regardless of what
+  value is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`swap-red-blue`
+: If the colors of your display appear wrong (blues appear orange or red,
+  etc.), it may be that your VNC server is sending image data incorrectly,
+  and the red and blue components of each color are swapped. If this is the
+  case, set this parameter to "true" to work around the problem. This
+  parameter is optional.
+
+`cursor`
+: If set to "remote", the mouse pointer will be rendered remotely, and the
+  local position of the mouse pointer will be indicated by a small dot. A
+  remote mouse cursor will feel slower than a local cursor, but may be
+  necessary if the VNC server does not support sending the cursor image to
+  the client.
+
+`encodings`
+: A space-delimited list of VNC encodings to use. The format of this
+  parameter is dictated by libvncclient and thus doesn't really follow the
+  form of other Guacamole parameters. This parameter is optional, and
+  libguac-client-vnc will use any supported encoding by default.
+
+  Beware that this parameter is intended to be replaced with individual,
+  encoding-specific parameters in a future release.
+
+`read-only`
+: Whether this connection should be read-only. If set to "true", no input
+  will be accepted on the connection at all. Users will only see the desktop
+  and whatever other users using that same desktop are doing. This parameter
+  is optional.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+#### VNC Repeater
+
+There exist VNC repeaters, such as UltraVNC Repeater, which act as
+intermediaries or proxies, providing a single logical VNC connection which is
+then routed to another VNC server elsewhere. Additional parameters are required
+to select which VNC host behind the repeater will receive the connection.
+
+`dest-host`
+: The destination host to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+`dest-port`
+: The destination port to request when connecting to a VNC proxy such as
+  UltraVNC Repeater. This is only necessary if the VNC proxy in use requires
+  the connecting user to specify which VNC server to connect to. If the VNC
+  proxy automatically connects to a specific server, this parameter is not
+  necessary.
+
+(vnc-reverse-connections)=
+
+#### Reverse VNC connections
+
+Guacamole supports "reverse" VNC connections, where the VNC client listens for
+an incoming connection from the VNC server. When reverse VNC connections are
+used, the VNC client and server switch network roles, but otherwise function as
+they normally would. The VNC server still provides the remote display, and the
+VNC client still provides all keyboard and mouse input.
+
+`reverse-connect`
+: Whether reverse connection should be used. If set to "true", instead of
+  connecting to a server at a given hostname and port, guacd will listen on
+  the given port for inbound connections from a VNC server.
+
+`listen-timeout`
+: If reverse connection is in use, the maximum amount of time to wait for an
+  inbound connection from a VNC server, in milliseconds. If blank, the
+  default value is 5000 (five seconds).
+
+(vnc-audio)=
+
+#### Audio support (via PulseAudio)
+
+VNC does not provide its own support for audio, but Guacamole's VNC support can
+obtain audio through a secondary network connection to a PulseAudio server
+running on the same machine as the VNC server.
+
+Most Linux systems provide audio through a service called PulseAudio.  This
+service is capable of communicating over the network, and if PulseAudio is
+configured to allow TCP connections, Guacamole can connect to your PulseAudio
+server and combine its audio with the graphics coming over VNC.
+
+Configuring PulseAudio for network connections requires an additional line
+within the PulseAudio configuration file, usually `/etc/pulse/default.pa`:
+
+```
+load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24 auth-anonymous=1
+```
+
+This loads the TCP module for PulseAudio, configuring it to accept connections
+without authentication and *only* from the `192.168.1.0/24` subnet. You will
+want to replace this value with the subnet or IP address from which guacd will
+be connecting. It is possible to allow connections from absolutely anywhere,
+but beware that you should only do so if the nature of your network prevents
+unauthorized access:
+
+```
+load-module module-native-protocol-tcp auth-anonymous=1
+```
+
+In either case, the `auth-anonymous=1` parameter is strictly required.
+Guacamole does not currently support the cookie-based authentication used by
+PulseAudio for non-anonymous connections. If this parameter is omitted,
+Guacamole will not be able to connect to PulseAudio.
+
+Once the PulseAudio configuration file has been modified appropriately, restart
+the PulseAudio service. PulseAudio should then begin listening on port 4713
+(the default PulseAudio port) for incoming TCP connections. You can verify this
+using a utility like {command}`netstat`:
+
+```console
+$ netstat -ln | grep 4713
+tcp        0      0 0.0.0.0:4713            0.0.0.0:*               LISTEN
+tcp6       0      0 :::4713                 :::*                    LISTEN
+$
+```
+
+The following parameters are available for configuring the audio support for
+VNC:
+
+`enable-audio`
+: If set to "true", audio support will be enabled, and a second connection
+  for PulseAudio will be made in addition to the VNC connection. By default,
+  audio support within VNC is disabled.
+
+`audio-servername`
+: The name of the PulseAudio server to connect to. This will be the hostname
+  of the computer providing audio for your connection via PulseAudio, most
+  likely the same as the value given for the `hostname` parameter.
+
+  If this parameter is omitted, the default PulseAudio device will be used,
+  which will be the PulseAudio server running on the same machine as guacd.
+
+(vnc-clipboard-encoding)=
+
+#### Clipboard encoding
+
+While Guacamole will always use UTF-8 for its own clipboard data, the VNC
+standard requires that clipboard data be encoded in ISO 8859-1. As most VNC
+servers will not accept data in any other format, Guacamole will translate
+between UTF-8 and ISO 8859-1 when exchanging clipboard data with the VNC
+server, but this behavior can be overridden with the `clipboard-encoding`
+parameter.
+
+:::{important}
+*The only clipboard encoding guaranteed to be supported by VNC servers is ISO
+8859-1.* You should only override the clipboard encoding using the
+`clipboard-encoding` parameter of you are absolutely positive your VNC server
+supports other encodings.
+:::
+
+`clipboard-encoding`
+: The encoding to assume for the VNC clipboard. This parameter is optional.
+  By default, the standard encoding ISO 8859-1 will be used. *Only use this
+  parameter if you are sure your VNC server supports other encodings beyond
+  the standard ISO 8859-1.*
+
+  Possible values are:
+
+  ISO8859-1
+  : ISO 8859-1 is the clipboard encoding mandated by the VNC standard, and
+    supports only basic Latin characters. Unless your VNC server specifies
+    otherwise, this encoding is the only encoding guaranteed to work.
+
+  UTF-8
+  : UTF-8 - the most common encoding used for Unicode. Using this encoding
+    for the VNC clipboard violates the VNC specification, but some servers
+    do support this. This parameter value should only be used if you know
+    your VNC server supports this encoding.
+
+  UTF-16
+  : UTF-16 - a 16-bit encoding for Unicode which is not as common as UTF-8,
+    but still widely used. Using this encoding for the VNC clipboard
+    violates the VNC specification. This parameter value should only be used
+    if you know your VNC server supports this encoding.
+
+  CP1252
+  : Code page 1252 - a Windows-specific encoding for Latin characters which
+    is mostly a superset of ISO 8859-1, mapping some additional displayable
+    characters onto what would otherwise be control characters. Using this
+    encoding for the VNC clipboard violates the VNC specification. This
+    parameter value should only be used if you know your VNC server supports
+    this encoding.
+
+(adding-vnc)=
+
+#### Adding a VNC connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a VNC connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>vnc</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">5901</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use VNC to connect to localhost at port 5901. Naturally,
+you will want to change some or all of these values.
+
+If your VNC server requires a password, or you wish to specify other
+configuration parameters (to reduce the color depth, for example), you will
+need to add additional `<param>` tags accordingly.
+
+Other authentication methods will provide documentation describing how to
+configure new connections. If the authentication method in use fully implements
+the features of Guacamole's authentication API, you will be able to add a new
+VNC connection easily and intuitively using the administration interface built
+into Guacamole. You will not need to edit configuration files.
+
+(vnc-servers)=
+
+#### Which VNC server?
+
+The choice of VNC server can make a big difference when it comes to
+performance, especially over slower networks. While many systems provide VNC
+access by default, using this is often not the fastest method.
+
+(realvnc)=
+
+##### RealVNC or TigerVNC
+
+RealVNC, and its derivative TigerVNC, perform quite well. In our testing, they
+perform the best with Guacamole. If you are okay with having a desktop that can
+only be accessed via VNC, one of these is likely your best choice. Both
+optimize window movement and (depending on the application) scrolling, giving a
+very responsive user experience.
+
+##### TightVNC
+
+TightVNC is widely-available and performs generally as well as RealVNC or
+TigerVNC. If you wish to use TightVNC with Guacamole, performance should be
+just fine, but we highly recommend disabling its JPEG encoding. This is because
+images transmitted to Guacamole are always encoded losslessly as PNG images.
+When this operation is performed on a JPEG image, the artifacts present from
+JPEG's lossy compression reduce the compressibility of the image for PNG, thus
+leading to a slower experience overall than if JPEG was simply not used to
+begin with.
+
+##### x11vnc
+
+The main benefit of using x11vnc is that it allows you to continue using your
+desktop normally, while simultaneously exposing control of your desktop via
+VNC. Performance of x11vnc is comparable to RealVNC, TigerVNC, and TightVNC. If
+you need to use your desktop locally as well as via VNC, you will likely be
+quite happy with x11vnc.
+
+##### vino
+
+vino is the VNC server that comes with the Gnome desktop environment, and is
+enabled if you enable "desktop sharing" via the system preferences available
+within Gnome. If you need to share your local desktop, we recommend using
+x11vnc rather vino, as it has proven more performant and feature-complete in
+our testing. If you don't need to share a local desktop but simply need an
+environment you can access remotely, using a VNC server like RealVNC, TigerVNC,
+or TightVNC is a better choice.
+
+(qemu)=
+
+##### QEMU or KVM
+
+QEMU (and thus KVM) expose the displays of virtual machines using VNC.  If you
+need to see the virtual monitor of your virtual machine, using this VNC
+connection is really your only choice. As the VNC server built into QEMU cannot
+be aware of higher-level operations like window movement, resizing, or
+scrolling, those operations will tend to be sent suboptimally, and will not be
+as fast as a VNC server running within the virtual machine.
+
+If you wish to use a virtual machine for desktop access, we recommend
+installing a native VNC server inside the virtual machine after the virtual
+machine is set up. This will give a more responsive desktop.
+
+### RDP
+
+The RDP protocol is more complicated than VNC and was the second protocol
+officially supported by Guacamole. RDP tends to be faster than VNC due to the
+use of caching, which Guacamole does take advantage of.
+
+RDP support for Guacamole is provided by the libguac-client-rdp library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the RDP-specific parameters below, Guacamole's RDP support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](common-sftp)
+* [](graphical-recording)
+* [](wake-on-lan)
+:::
+
+(rdp-network-parameters)=
+
+#### Network parameters
+
+RDP connections require a hostname or IP address defining the
+destination machine. The RDP port is defined to be 3389, and will be
+this value in most cases. You only need to specify the RDP port if you
+are not using port 3389.
+
+`hostname`
+: The hostname or IP address of the RDP server Guacamole should connect to.
+
+`port`
+: The port the RDP server is listening on. This parameter is optional. If
+  this is not specified, the standard port for RDP (3389) or Hyper-V's
+  default port for VMConnect (2179) will be used, depending on the security
+  mode selected.
+
+(rdp-authentication)=
+
+#### Authentication and security
+
+RDP provides authentication through the use of a username, password, and
+optional domain. All RDP connections are encrypted.
+
+Most RDP servers will provide a graphical login if the username, password, and
+domain parameters are omitted. One notable exception to this is Network Level
+Authentication, or NLA, which performs all authentication outside of a desktop
+session, and thus in the absence of a graphical interface.
+
+Servers that require NLA can be handled by Guacamole in one of two ways. The
+first is to provide the username and password within the connection
+configuration, either via static values or by passing through the Guacamole
+credentials with [parameter tokens](parameter-tokens) and [](ldap-auth).
+Alternatively, if credentials are not configured within the connection
+configuration, Guacamole will attempt to prompt the user for the credentials
+interactively, if the versions of both guacd and Guacamole Client in use
+support it. If either component does not support prompting and the credentials
+are not configured, NLA-based connections will fail.
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional.
+
+`domain`
+: The domain to use when attempting authentication, if any. This parameter
+  is optional.
+
+`security`
+: The security mode to use for the RDP connection. This mode dictates how
+  data will be encrypted and what type of authentication will be performed,
+  if any. By default, a security mode is selected based on a negotiation
+  process which determines what both the client and the server support.
+
+  Possible values are:
+
+  any
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server. *This is the default*.
+
+  nla
+  : Network Level Authentication, sometimes also referred to as "hybrid" or
+    CredSSP (the protocol that drives NLA). This mode uses TLS encryption
+    and requires the username and password to be given in advance. Unlike
+    RDP mode, the authentication step is performed before the remote desktop
+    session actually starts, avoiding the need for the Windows server to
+    allocate significant resources for users that may not be authorized.
+
+    If the versions of guacd and Guacamole Client in use support prompting
+    and the username, password, and domain are not specified, the user will
+    be interactively prompted to enter credentials to complete NLA and
+    continue the connection. Otherwise, when prompting is not supported and
+    credentials are not provided, NLA connections will fail.
+
+  nla-ext
+  : Extended Network Level Authentication. This mode is identical to NLA
+    except that an additional "[Early User Authorization
+    Result](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d0e560a3-25cb-4563-8bdc-6c4cc625bbfc)"
+    is required to be sent from the server to the client immediately after the
+    NLA handshake is completed.
+
+  tls
+  : RDP authentication and encryption implemented via TLS (Transport Layer
+    Security). Also referred to as RDSTLS, the TLS security mode is
+    primarily used in load balanced configurations where the initial RDP
+    server may redirect the connection to a different RDP server.
+
+  vmconnect
+  : Automatically select the security mode based on the security protocols
+    supported by both the client and the server, limiting that negotiation
+    to only the protocols known to be supported by [Hyper-V /
+    VMConnect](rdp-preconnection-pdu).
+
+  rdp
+  : Legacy RDP encryption. This mode is generally only used for older
+    Windows servers or in cases where a standard Windows login screen is
+    desired. Newer versions of Windows have this mode disabled by default
+    and will only accept NLA unless explicitly configured otherwise.
+
+`ignore-cert`
+: If set to "true", the certificate returned by the server will be ignored,
+  even if that certificate cannot be validated. This is useful if you
+  universally trust the server and your connection to the server, and you
+  know that the server's certificate cannot be validated (for example, if it
+  is self-signed).
+
+`disable-auth`
+: If set to "true", authentication will be disabled. Note that this refers
+  to authentication that takes place while connecting. Any authentication
+  enforced by the server over the remote desktop session (such as a login
+  dialog) will still take place. By default, authentication is enabled and
+  only used when requested by the server.
+
+  If you are using NLA, authentication must be enabled by definition.
+
+(rdp-session-settings)=
+
+#### Session settings
+
+RDP sessions will typically involve the full desktop environment of a normal
+user. Alternatively, you can manually specify a program to use instead of the
+RDP server's default shell, or connect to the administrative console.
+
+Although Guacamole is independent of keyboard layout, RDP is not. This is
+because Guacamole represents keys based on what they *do* ("press the Enter
+key"), while RDP uses identifiers based on the key's location ("press the
+rightmost key in the second row"). To translate between a Guacamole key event
+and an RDP key event, Guacamole must know ahead of time the keyboard layout of
+the RDP server.
+
+By default, the US English qwerty keyboard will be used. If this does not match
+the keyboard layout of your RDP server, keys will not be properly translated,
+and you will need to explicitly choose a different layout in your connection
+settings. If your keyboard layout is not supported, please notify the Guacamole
+team by [opening an issue in
+JIRA](https://issues.apache.org/jira/browse/GUACAMOLE).
+
+
+`client-name`
+: When connecting to the RDP server, Guacamole will normally provide its own
+  hostname as the name of the client. If this parameter is specified,
+  Guacamole will use its value instead.
+
+  On Windows RDP servers, this value is exposed within the session as the
+  `CLIENTNAME` environment variable.
+
+`console`
+: If set to "true", you will be connected to the console (admin) session of
+  the RDP server.
+
+`initial-program`
+: The full path to the program to run immediately upon connecting. This
+  parameter is optional.
+
+`server-layout`
+: The server-side keyboard layout. This is the layout of the RDP server and
+  has nothing to do with the keyboard layout in use on the client. *The
+  Guacamole client is independent of keyboard layout.* The RDP protocol,
+  however, is *not* independent of keyboard layout, and Guacamole needs to
+  know the keyboard layout of the server in order to send the proper keys
+  when a user is typing.
+
+  Possible values are generally in the format
+  {samp}`{LANGUAGE}-{REGION}-{VARIANT}`, where `LANGUAGE` is the standard
+  two-letter language code for the primary language associated with the
+  layout, `REGION` is a standard representation of the location that the
+  keyboard is used (the two-letter country code, when possible), and
+  `VARIANT` is the specific keyboard layout variant (such as "qwerty",
+  "qwertz", or "azerty"):
+
+  | Keyboard layout                | Parameter value        |
+  | ------------------------------ | ---------------------- |
+  | Brazilian (Portuguese)         | `pt-br-qwerty`         |
+  | English (UK)                   | `en-gb-qwerty`         |
+  | English (US)                   | `en-us-qwerty`         |
+  | French                         | `fr-fr-azerty`         |
+  | French (Belgian)               | `fr-be-azerty`         |
+  | French (Swiss)                 | `fr-ch-qwertz`         |
+  | German                         | `de-de-qwertz`         |
+  | German (Swiss)                 | `de-ch-qwertz`         |
+  | Hungarian                      | `hu-hu-qwertz`         |
+  | Italian                        | `it-it-qwerty`         |
+  | Japanese                       | `ja-jp-qwerty`         |
+  | Spanish                        | `es-es-qwerty`         |
+  | Spanish (Latin American)       | `es-latam-qwerty`      |
+  | Swedish                        | `sv-se-qwerty`         |
+  | Turkish-Q                      | `tr-tr-qwerty`         |
+
+  If you server's keyboard layout is not yet supported, and it is not possible
+  to set your server to use a supported layout, the `failsafe` layout may be used
+  to force Unicode events to be used for all input, however beware that doing so
+  may prevent keyboard shortcuts from working as expected.
+
+`timezone`
+: The timezone that the client should send to the server for configuring the
+  local time display of that server. The format of the timezone is in the
+  standard IANA key zone format, which is the format used in UNIX/Linux.
+  This will be converted by RDP into the correct format for Windows.
+
+  The timezone is detected and will be passed to the server during the
+  handshake phase of the connection, and may used by protocols, like RDP,
+  that support it. This parameter can be used to override the value detected
+  and passed during the handshake, or can be used in situations where guacd
+  does not support passing the timezone parameter during the handshake phase
+  (guacd versions prior to 1.3.0).
+
+  Support for forwarding the client timezone varies by RDP server
+  implementation. For example, with Windows, support for forwarding
+  timezones is only present in Windows Server with Remote Desktop Services
+  (RDS, formerly known as Terminal Services) installed. Windows Server
+  installations in admin mode, along with Windows workstation versions, do
+  not allow the timezone to be forwarded. Other server implementations, for
+  example, xrdp, may not implement this feature at all. Consult the
+  documentation for the RDP server to determine whether or not this feature
+  is supported.
+
+(rdp-display-settings)=
+
+#### Display settings
+
+Guacamole will automatically choose an appropriate display size for RDP
+connections based on the size of the browser window and the DPI of the device.
+The size of the display can be forced by specifying explicit width or height
+values.
+
+To reduce bandwidth usage, you may also request that the server reduce its
+color depth. Guacamole will automatically detect 256-color images, but this can
+be guaranteed for absolutely all graphics sent over the connection by forcing
+the color depth to 8-bit. Color depth is otherwise dictated by the RDP server.
+
+`color-depth`
+: The color depth to request, in bits-per-pixel. This parameter is optional.
+  If specified, this must be either 8, 16, or 24. Regardless of what value
+  is chosen here, if a particular update uses less than 256 colors,
+  Guacamole will always send that update as a 256-color PNG.
+
+`width`
+: The width of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the width of the connecting
+  client display will be used instead.
+
+`height`
+: The height of the display to request, in pixels. This parameter is
+  optional. If this value is not specified, the height of the connecting
+  client display will be used instead.
+
+`dpi`
+: The desired effective resolution of the client display, in DPI. This
+  parameter is optional. If this value is not specified, the resolution and
+  size of the client display will be used together to determine,
+  heuristically, an appropriate resolution for the RDP session.
+
+`resize-method`
+: The method to use to update the RDP server when the width or height of the
+  client display changes. This parameter is optional. If this value is not
+  specified, no action will be taken when the client display changes size.
+
+  Normally, the display size of an RDP session is constant and can only be
+  changed when initially connecting. As of RDP 8.1, the "Display Update"
+  channel can be used to request that the server change the display size.
+  For older RDP servers, the only option is to disconnect and reconnect with
+  the new size.
+
+  Possible values are:
+
+  display-update
+  : Uses the "Display Update" channel added with RDP 8.1 to signal the
+    server when the client display size has changed.
+
+  reconnect
+  : Automatically disconnects the RDP session when the client display size
+    has changed, and reconnects with the new size.
+
+`force-lossless`
+: Whether this connection should only use lossless compression for graphical
+  updates. If set to "true", lossy compression will not be used. This
+  parameter is optional. By default, lossy compression will be used when
+  heuristics determine that it would likely outperform lossless compression.
+
+(rdp-device-redirection)=
+
+#### Device redirection
+
+Device redirection refers to the use of non-display devices over RDP.
+Guacamole's RDP support currently allows redirection of audio, printing, and
+disk access, some of which require additional configuration in order to
+function properly.
+
+Audio redirection will be enabled by default. If Guacamole was correctly
+installed, and audio redirection is supported by your RDP server, sound should
+play within remote connections without manual intervention.
+
+Printing requires GhostScript to be installed on the Guacamole server, and
+allows users to print arbitrary documents directly to PDF. When documents are
+printed to the redirected printer, the user will receive a PDF of that document
+within their web browser.
+
+Guacamole provides support for file transfer over RDP by emulating a virtual
+disk drive. This drive will persist on the Guacamole server, confined within
+the drive path specified. If drive redirection is enabled on a Guacamole RDP
+connection, users will be able to upload and download files as described in
+[](using-guacamole).
+
+`disable-audio`
+: Audio is enabled by default in both the client and in libguac-client-rdp.
+  If you are concerned about bandwidth usage, or sound is causing problems,
+  you can explicitly disable sound by setting this parameter to "true".
+
+`enable-audio-input`
+: If set to "true", audio input support (microphone) will be enabled,
+  leveraging the standard "`AUDIO_INPUT`" channel of RDP. By default, audio
+  input support within RDP is disabled.
+
+`enable-printing`
+: Printing is disabled by default, but with printing enabled, RDP users can
+  print to a virtual printer that sends a PDF containing the document
+  printed to the Guacamole client. Enable printing by setting this parameter
+  to "true".
+
+  *Printing support requires GhostScript to be installed.* If guacd cannot
+  find the `gs` executable when printing, the print attempt will fail.
+
+`printer-name`
+: The name of the redirected printer device that is passed through to the
+  RDP session. This is the name that the user will see in, for example, the
+  Devices and Printers control panel.
+
+  If printer redirection is not enabled, this option has no effect.
+
+`enable-drive`
+: File transfer is disabled by default, but with file transfer enabled, RDP
+  users can transfer files to and from a virtual drive which persists on the
+  Guacamole server. Enable file transfer support by setting this parameter
+  to "true".
+
+  Files will be stored in the directory specified by the "`drive-path`"
+  parameter, which is required if file transfer is enabled.
+
+`disable-download`
+: If set to true downloads from the remote server to client (browser) will
+  be disabled. This includes both downloads down via the hidden Guacamole
+  menu, as well as using the special "Download" folder presented to the
+  remote server. The default is false, which means that downloads will be
+  allowed.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`disable-upload`
+: If set to true, uploads from the client (browser) to the remote server
+  location will be disabled. The default is false, which means uploads will
+  be allowed if file transfer is enabled.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-name`
+: The name of the filesystem used when passed through to the RDP session.
+  This is the name that users will see in their Computer/My Computer area
+  along with client name (for example, "Guacamole on Guacamole RDP"), and is
+  also the name of the share when accessing the special `\\tsclient` network
+  location.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`drive-path`
+: The directory on the Guacamole server in which transferred files should be
+  stored. This directory must be accessible by guacd and both readable and
+  writable by the user that runs guacd. *This parameter does not refer to a
+  directory on the RDP server.*
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`create-drive-path`
+: If set to "true", and file transfer is enabled, the directory specified by
+  the `drive-path` parameter will automatically be created if it does not
+  yet exist. Only the final directory in the path will be created - if other
+  directories earlier in the path do not exist, automatic creation will
+  fail, and an error will be logged.
+
+  By default, the directory specified by the `drive-path` parameter will not
+  automatically be created, and attempts to transfer files to a non-existent
+  directory will be logged as errors.
+
+  If file transfer is not enabled, this parameter is ignored.
+
+`console-audio`
+: If set to "true", audio will be explicitly enabled in the console (admin)
+  session of the RDP server. Setting this option to "true" only makes sense
+  if the `console` parameter is also set to "true".
+
+`static-channels`
+: A comma-separated list of static channel names to open and expose as
+  pipes. If you wish to communicate between an application running on the
+  remote desktop and JavaScript, this is the best way to do it. Guacamole
+  will open an outbound pipe with the name of the static channel. If
+  JavaScript needs to communicate back in the other direction, it should
+  respond by opening another pipe with the same name.
+
+  Guacamole allows any number of static channels to be opened, but protocol
+  restrictions of RDP limit the size of each channel name to 7 characters.
+
+(rdp-preconnection-pdu)=
+
+#### Preconnection PDU (Hyper-V / VMConnect)
+
+Some RDP servers host multiple logical RDP connections behind a single server
+listening on a single TCP port. To select between these logical connections, an
+RDP client must send the "preconnection PDU" - a message which contains values
+that uniquely identify the destination, referred to as the "RDP source". This
+mechanism is defined by the ["Session Selection
+Extension](https://msdn.microsoft.com/en-us/library/cc242359.aspx) for the RDP
+protocol, and is implemented by Microsoft's Hyper-V hypervisor.
+
+If you are using Hyper-V, you will need to specify the ID of the destination
+virtual machine within the `preconnection-blob` parameter.  This value can be
+determined using PowerShell:
+
+```ps1con
+PS C:\> Get-VM VirtualMachineName | Select-Object Id
+
+Id
+--
+ed272546-87bd-4db9-acba-e36e1a9ca20a
+
+
+PS C:\>
+```
+
+The preconnection PDU is intentionally generic. While its primary use is as a
+means for selecting virtual machines behind Hyper-V, other RDP servers may use
+it as well. It is up to the RDP server itself to determine whether the
+preconnection ID, BLOB, or both will be used, and what their values mean.
+
+*If you do intend to use Hyper-V, beware that its built-in RDP server requires
+different parameters for authentication and Guacamole's defaults will not
+work.* In most cases, you will need to do the following when connecting to
+Hyper-V:
+
+1. Specify both "`username`" and "`password`" appropriately, and set
+   "`security`" to "`vmconnect`". Selecting the "`vmconnect`" security mode
+   will configure Guacamole to automatically negotiate security modes known to
+   be supported by Hyper-V, and will automatically select Hyper-V's default RDP
+   port (2179).
+
+2. If necessary, set "`ignore-cert`" to "`true`". Hyper-V may use a self-signed
+   certificate.
+
+`preconnection-id`
+: The numeric ID of the RDP source. This is a non-negative integer value
+  dictating which of potentially several logical RDP connections should be
+  used. This parameter is optional, and is only required if the RDP server
+  is documented as requiring it. *If using Hyper-V, this should be left
+  blank.*
+
+`preconnection-blob`
+: An arbitrary string which identifies the RDP source - one of potentially
+  several logical RDP connections hosted by the same RDP server. This
+  parameter is optional, and is only required if the RDP server is
+  documented as requiring it, such as Hyper-V. In all cases, the meaning of
+  this parameter is opaque to the RDP protocol itself and is dictated by the
+  RDP server. *For Hyper-V, this will be the ID of the destination virtual
+  machine.*
+
+(rdp-gateway)=
+
+#### Remote desktop gateway
+
+Microsoft's remote desktop server provides an additional gateway service which
+allows external connections to be forwarded to internal RDP servers which are
+otherwise not accessible. If you will be using Guacamole to connect through
+such a gateway, you will need to provide additional parameters describing the
+connection to that gateway, as well as any required credentials.
+
+`gateway-hostname`
+: The hostname of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. *If omitted, a gateway
+  will not be used.*
+
+`gateway-port`
+: The port of the remote desktop gateway that should be used as an
+  intermediary for the remote desktop connection. By default, this will be
+  "443".
+
+`gateway-username`
+: The username of the user authenticating with the remote desktop gateway,
+  if a gateway is being used. This is not necessarily the same as the user
+  actually using the remote desktop connection.
+
+`gateway-password`
+: The password to provide when authenticating with the remote desktop
+  gateway, if a gateway is being used.
+
+`gateway-domain`
+: The domain of the user authenticating with the remote desktop gateway, if
+  a gateway is being used. This is not necessarily the same domain as the
+  user actually using the remote desktop connection.
+
+(rdp-connection-broker)=
+
+#### Load balancing and RDP connection brokers
+
+If your remote desktop servers are behind a load balancer, sometimes referred
+to as a "connection broker" or "TS session broker", that balancer may require
+additional information during the connection process to determine how the
+incoming connection should be routed. RDP does not dictate the format of this
+information; it is specific to the balancer in use.
+
+If you are using a load balancer and are unsure whether such information is
+required, *you will need to check the documentation for your balancer*. If your
+balancer provides `.rdp` files for convenience, look through the contents of
+those files for a string field called "loadbalanceinfo", as that field is where
+the required information/cookie would be specified.
+
+`load-balance-info`
+: The load balancing information or cookie which should be provided to the
+  connection broker. *If no connection broker is being used, this should be
+  left blank.*
+
+(rdp-perf-flags)=
+
+#### Performance flags
+
+RDP provides several flags which control the availability of features that
+decrease performance and increase bandwidth for the sake of aesthetics, such as
+wallpaper, window theming, menu effects, and smooth fonts. These features are
+all disabled by default within Guacamole such that bandwidth usage is
+minimized, but you can manually re-enable them on a per-connection basis if
+desired.
+
+`enable-wallpaper`
+: If set to "true", enables rendering of the desktop wallpaper. By default,
+  wallpaper will be disabled, such that unnecessary bandwidth need not be
+  spent redrawing the desktop.
+
+`enable-theming`
+: If set to "true", enables use of theming of windows and controls. By
+  default, theming within RDP sessions is disabled.
+
+`enable-font-smoothing`
+: If set to "true", text will be rendered with smooth edges. Text over RDP
+  is rendered with rough edges by default, as this reduces the number of
+  colors used by text, and thus reduces the bandwidth required for the
+  connection.
+
+`enable-full-window-drag`
+: If set to "true", the contents of windows will be displayed as windows are
+  moved. By default, the RDP server will only draw the window border while
+  windows are being dragged.
+
+`enable-desktop-composition`
+: If set to "true", graphical effects such as transparent windows and
+  shadows will be allowed. By default, such effects, if available, are
+  disabled.
+
+`enable-menu-animations`
+: If set to "true", menu open and close animations will be allowed. Menu
+  animations are disabled by default.
+
+`disable-bitmap-caching`
+: In certain situations, particularly with RDP server implementations with
+  known bugs, it is necessary to disable RDP's built-in bitmap caching
+  functionality. This parameter allows that to be controlled in a Guacamole
+  session. If set to "true" the RDP bitmap cache will not be used.
+
+`disable-offscreen-caching`
+: RDP normally maintains caches of regions of the screen that are current
+  not visible in the client in order to accelerate retrieval of those
+  regions when they come into view. This parameter, when set to "true," will
+  disable caching of those regions. This is usually only useful when dealing
+  with known bugs in RDP server implementations and should remain enabled in
+  most circumstances.
+
+`disable-glyph-caching`
+: In addition to screen regions, RDP maintains caches of frequently used
+  symbols or fonts, collectively known as "glyphs." As with bitmap and
+  offscreen caching, certain known bugs in RDP implementations can cause
+  performance issues with this enabled, and setting this parameter to "true"
+  will disable that glyph caching in the RDP session.
+
+(rdp-remoteapp)=
+
+#### RemoteApp
+
+Recent versions of Windows provide a feature called RemoteApp which allows
+individual applications to be used over RDP, without providing access to the
+full desktop environment. If your RDP server has this feature enabled and
+configured, you can configure Guacamole connections to use those individual
+applications.
+
+`remote-app`
+: Specifies the RemoteApp to start on the remote desktop. If supported by
+  your remote desktop server, this application, and only this application,
+  will be visible to the user.
+
+  Windows requires a special notation for the names of remote applications.
+  The names of remote applications must be prefixed with two vertical bars.
+  For example, if you have created a remote application on your server for
+  `notepad.exe` and have assigned it the name "notepad", you would set this
+  parameter to: "`||notepad`".
+
+`remote-app-dir`
+: The working directory, if any, for the remote application. This parameter
+  has no effect if RemoteApp is not in use.
+
+`remote-app-args`
+: The command-line arguments, if any, for the remote application. This
+  parameter has no effect if RemoteApp is not in use.
+
+(adding-rdp)=
+
+#### Adding an RDP connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a RDP connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>rdp</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">3389</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use RDP to connect to localhost at port 3389.  Naturally,
+you will want to change some or all of these values.
+
+If you want to login automatically rather than receive a login prompt upon
+connecting, you can specify a username and password with additional `<param>`
+tags. Other options are available for controlling the color depth, size of the
+screen, etc.
+
+Other authentication methods will provide documentation describing how to
+configure new connections. If the authentication method in use fully implements
+the features of Guacamole's authentication API, you will be able to add a new
+RDP connection easily and intuitively using the administration interface built
+into Guacamole. You will not need to edit configuration files.
+
+### SSH
+
+Unlike VNC or RDP, SSH is a text protocol. Its implementation in Guacamole is
+actually a combination of a terminal emulator and SSH client, because the SSH
+protocol isn't inherently graphical. Guacamole's SSH support emulates a
+terminal on the server side, and draws the screen of this terminal remotely on
+the client.
+
+SSH support for Guacamole is provided by the libguac-client-ssh library, which
+will be installed as part of guacamole-server if the required dependencies are
+present during the build.
+
+:::{note}
+In addition to the SSH-specific parameters below, Guacamole's SSH support also
+accepts the parameters of several features that Guacamole provides for multiple
+protocols:
+
+* [](disable-clipboard)
+* [](graphical-recording)
+* [](typescripts)
+* [](stdin-pipe)
+* [](terminal-behavior)
+* [](terminal-display-settings)
+* [](wake-on-lan)
+:::
+
+(ssh-host-verification)=
+
+#### SSH Host Verification
+
+By default, Guacamole does not do any verification of host identity before
+establishing SSH connections. While this may be safe for private and trusted
+networks, it is not ideal for large networks with unknown/untrusted systems, or
+for SSH connections that traverse the Internet. The potential exists for
+Man-in-the-Middle (MitM) attacks when connecting to these hosts.
+
+Guacamole includes two methods for verifying SSH (and SFTP) server identity
+that can be used to make sure that the host you are connecting to is a host
+that you know and trust. The first method is by reading a file in
+`GUACAMOLE_HOME` called `ssh_known_hosts`. This file should be in the format of
+a standard OpenSSH `known_hosts` file. If the file is not present, no
+verification is done. If the file is present, it is read in at connection time
+and remote host identities are verified against the keys present in the file.
+
+The second method for verifying host identity is by passing a connection
+parameter that contains an OpenSSH known hosts entry for that specific host.
+The `host-key` parameter is used for SSH connections, while the SFTP
+connections associated with RDP and VNC use the `sftp-host-key` parameter. If
+these parameters are not present on their respective connections no host
+identity verification is performed. If the parameter is present then the
+identity of the remote host is verified against the identity provided in the
+parameter before a connection is established.
+
+(ssh-network-parameters)=
+
+#### Network parameters
+
+SSH connections require a hostname or IP address defining the destination
+machine. SSH is standardized to use port 22 and this will be the proper value
+in most cases. You only need to specify the SSH port if you are not using the
+standard port.
+
+`hostname`
+: The hostname or IP address of the SSH server Guacamole should connect to.
+
+`port`
+: The port the SSH server is listening on, usually 22. This parameter is
+  optional. If this is not specified, the default of 22 will be used.
+
+`host-key`
+: The known hosts entry for the SSH server. This parameter is optional, and,
+  if not provided, no verification of host identity will be done. If the
+  parameter is provided the identity of the server will be checked against
+  the data.
+
+  The format of this parameter is that of a single entry from an OpenSSH
+  `known_hosts` file.
+
+  For more information, please see [](ssh-host-verification).
+
+`server-alive-interval`
+: By default the SSH client does not send keepalive requests to the server.
+  This parameter allows you to configure the the interval in seconds at
+  which the client connection sends keepalive packets to the server. The
+  default is 0, which disables sending the packets. The minimum value is 2.
+
+(ssh-authentication)=
+
+#### Authentication
+
+SSH provides authentication through passwords and public key authentication,
+and also supports the "NONE" method.
+
+SSH "NONE" authentication is seen occasionally in appliances and items like
+network or SAN fabric switches. Generally for this authentication method you
+need only provide a username.
+
+For Guacamole to use public key authentication, it must have access to your
+private key and, if applicable, its passphrase. If the private key requires a
+passphrase, but no passphrase is provided, you will be prompted for the
+passphrase upon connecting.
+
+If no private key is provided, Guacamole will attempt to authenticate using a
+password, reading that password from the connection parameters, if provided, or
+by prompting the user directly.
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+  If not specified, you will be prompted for the username upon connecting.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional. If not specified, you will be prompted for your password upon
+  connecting.
+
+`private-key`
+: The entire contents of the private key to use for public key
+  authentication. If this parameter is not specified, public key
+  authentication will not be used. The private key must be in OpenSSH
+  format, as would be generated by the OpenSSH {command}`ssh-keygen`
+  utility.
+
+`passphrase`
+: The passphrase to use to decrypt the private key for use in public key
+  authentication. This parameter is not needed if the private key does not
+  require a passphrase. If the private key requires a passphrase, but this
+  parameter is not provided, the user will be prompted for the passphrase
+  upon connecting.
+
+(ssh-command)=
+
+#### Running a command (instead of a shell)
+
+By default, SSH sessions will start an interactive shell. The shell which will
+be used is determined by the SSH server, normally by reading the user's default
+shell previously set with `chsh` or within `/etc/passwd`. If you wish to
+override this and instead run a specific command, you can do so by specifying
+that command in the configuration of the Guacamole SSH connection.
+
+`command`
+: The command to execute over the SSH session, if any. This parameter is
+  optional. If not specified, the SSH session will use the user's default
+  shell.
+
+#### Internationalization/Locale settings
+
+The language of the session is normally set by the SSH server. If the SSH
+server allows the relevant environment variable to be set, the language can be
+overridden on a per-connection basis.
+
+`locale`
+: The specific locale to request for the SSH session. This parameter is
+  optional and may be any value accepted by the `LANG` environment variable
+  of the SSH server. If not specified, the SSH server's default locale will
+  be used.
+
+  As this parameter is sent to the SSH server using the `LANG` environment
+  variable, the parameter will only have an effect if the SSH server allows
+  the `LANG` environment variable to be set by SSH clients.
+
+`timezone`
+: This parameter allows you to control the timezone that is sent to the
+  server over the SSH connection, which will change the way local time is
+  displayed on the server.
+
+  The mechanism used to do this over SSH connections is by setting the `TZ`
+  variable on the SSH connection to the timezone specified by this
+  parameter. This means that the SSH server must allow the `TZ` variable to
+  be set/overriden - many SSH server implementations have this disabled by
+  default. To get this to work, you may need to modify the configuration of
+  the SSH server and explicitly allow for `TZ` to be set/overriden.
+
+  The available values of this parameter are standard IANA key zone format
+  timezones, and the value will be sent directly to the server in this
+  format.
+
+(ssh-sftp)=
+
+#### SFTP
+
+Guacamole provides support for file transfer over SSH using SFTP, the
+file transfer protocol built into most SSH servers. If SFTP is enabled
+on a Guacamole SSH connection, users will be able to upload and download
+files as described in [](using-guacamole)
+
+`enable-sftp`
+: Whether file transfer should be enabled. If set to "true", the user will
+  be allowed to upload or download files from the SSH server using SFTP.
+  Guacamole includes the {program}`guacctl` utility which controls file
+  downloads and uploads when run on the SSH server by the user over the SSH
+  connection.
+
+`sftp-root-directory`
+: The directory to expose to connected users via Guacamole's [file
+  browser](file-browser). If omitted, the root directory will be used by
+  default.
+
+`sftp-disable-download`
+: If set to true downloads from the remote system to the client (browser)
+  will be disabled. The default is false, which means that downloads will be
+  enabled.
+
+  If SFTP is not enabled, this parameter will be ignored.
+
+`sftp-disable-upload`
+: If set to true uploads from the client (browser) to the remote system will
+  be disabled. The default is false, which means that uploads will be
+  enabled.
+
+  If SFTP is not enabled, this parameter will be ignored.
+
+(adding-ssh)=
+
+#### Adding an SSH connection
+
+If you are using the default authentication built into Guacamole, and
+you wish to grant access to a SSH connection to a particular user, you
+need to locate the `<authorize>` section for that user within your
+`user-mapping.xml`, and add a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>ssh</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">22</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use SSH to connect to localhost at port 22. Naturally, you
+will want to change some or all of these values.
+
+If you want to login automatically rather than receive a login prompt upon
+connecting, you can specify a username and password with additional `<param>`
+tags. Other options are available for controlling the font.
+
+Other authentication methods will provide documentation describing how to
+configure new connections.
+
+### Telnet
+
+Telnet is a text protocol and provides similar functionality to SSH. By nature,
+it is not encrypted, and does not provide support for file transfer. As far as
+graphics are concerned, Guacamole's telnet support works in the same manner as
+SSH: it emulates a terminal on the server side which renders to the Guacamole
+client's display.
+
+Telnet support for Guacamole is provided by the libguac-client-telnet library,
+which will be installed as part of guacamole-server if the required
+dependencies are present during the build.
+
+:::{note}
+In addition to the telnet-specific parameters below, Guacamole's telnet support
+also accepts the parameters of several features that Guacamole provides for
+multiple protocols:
+
+* [](disable-clipboard)
+* [](graphical-recording)
+* [](typescripts)
+* [](stdin-pipe)
+* [](terminal-behavior)
+* [](terminal-display-settings)
+* [](wake-on-lan)
+:::
+
+(telnet-network-parameters)=
+
+#### Network parameters
+
+Telnet connections require a hostname or IP address defining the
+destination machine. Telnet is standardized to use port 23 and this will
+be the proper value in most cases. You only need to specify the telnet
+port if you are not using the standard port.
+
+`hostname`
+: The hostname or IP address of the telnet server Guacamole should connect
+  to.
+
+`port`
+: The port the telnet server is listening on, usually 23. This parameter is
+  optional. If this is not specified, the default of 23 will be used.
+
+(telnet-authentication)=
+
+#### Authentication
+
+Telnet does not actually provide any standard means of authentication.
+Authentication over telnet depends entirely on the login process running on the
+server and is interactive. To cope with this, Guacamole provides non-standard
+mechanisms for automatically passing the username and entering password.
+Whether these mechanisms work depends on specific login process used by your
+telnet server.
+
+The de-facto method for passing the username automatically via telnet is to
+submit it via the `USER` environment variable, sent using the NEW-ENVIRON
+option. This is the mechanism used by most telnet clients, typically via the
+`-l` command-line option.
+
+Passwords cannot typically be sent automatically - at least not as reliably as
+the username. There is no `PASSWORD` environment variable (this would actually
+be a horrible idea) nor any similar mechanism for passing the password to the
+telnet login process, and most telnet clients provide no built-in support for
+automatically entering the password. The best that can be done is to
+heuristically detect the password prompt, and type the password on behalf of
+the user when the prompt appears. The prescribed method for doing this with a
+traditional command-line telnet is to use a utility like `expect`. Guacamole
+provides similar functionality by searching for the password prompt with a
+regular expression.
+
+If Guacamole receives a line of text which matches the regular expression, the
+password is automatically sent. If no such line is ever received, the password
+is not sent, and the user must type the password manually. Pressing any key
+during this process cancels the heuristic password prompt detection.
+
+If the password prompt is not being detected properly, you can try using your
+own regular expression by specifying it within the `password-regex` parameter.
+The regular expression must be written in the POSIX ERE dialect (the dialect
+typically used by `egrep`).
+
+`username`
+: The username to use to authenticate, if any. This parameter is optional.
+  If not specified, or not supported by the telnet server, the login process
+  on the telnet server will prompt you for your credentials. For this to
+  work, your telnet server must support the NEW-ENVIRON option, and the
+  telnet login process must pay attention to the `USER` environment
+  variable. Most telnet servers satisfy this criteria.
+
+`password`
+: The password to use when attempting authentication, if any. This parameter
+  is optional. If specified, your password will be typed on your behalf when
+  the password prompt is detected.
+
+`username-regex`
+: The regular expression to use when waiting for the username prompt. This
+  parameter is optional. If not specified, a reasonable default built into
+  Guacamole will be used. The regular expression must be written in the
+  POSIX ERE dialect (the dialect typically used by `egrep`).
+
+`password-regex`
+: The regular expression to use when waiting for the password prompt. This
+  parameter is optional. If not specified, a reasonable default built into
+  Guacamole will be used. The regular expression must be written in the
+  POSIX ERE dialect (the dialect typically used by `egrep`).
+
+`login-success-regex`
+: The regular expression to use when detecting that the login attempt has
+  succeeded. This parameter is optional. If specified, the terminal display
+  will not be shown to the user until text matching this regular expression
+  has been received from the telnet server. The regular expression must be
+  written in the POSIX ERE dialect (the dialect typically used by `egrep`).
+
+`login-failure-regex`
+: The regular expression to use when detecting that the login attempt has
+  failed. This parameter is optional. If specified, the connection will be
+  closed with an explicit login failure error if text matching this regular
+  expression has been received from the telnet server. The regular
+  expression must be written in the POSIX ERE dialect (the dialect typically
+  used by `egrep`).
+
+(adding-telnet)=
+
+#### Adding a telnet connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a telnet connection to a particular user, you need to locate
+the `<authorize>` section for that user within your `user-mapping.xml`, and add
+a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>telnet</protocol>
+    <param name="hostname">localhost</param>
+    <param name="port">23</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will use telnet to connect to localhost at port 23. Naturally,
+you will want to change some or all of these values.
+
+As telnet is inherently insecure compared to SSH, you should use SSH instead
+wherever possible. If Guacamole is set up to use HTTPS then communication with
+the Guacamole *client* will be encrypted, but communication between guacd and
+the telnet server will still be unencrypted. You should not use telnet unless
+the network between guacd and the telnet server is trusted.
+
+### Kubernetes
+
+Kubernetes provides an API for attaching to the console of a container over the
+network. As with SSH and telnet, Guacamole's Kubernetes support emulates a
+terminal on the server side which renders to the Guacamole client's display.
+
+Kubernetes support for Guacamole is provided by the libguac-client-kubernetes
+library, which will be installed as part of guacamole-server if the required
+dependencies are present during the build.
+
+:::{note}
+In addition to the Kubernetes-specific parameters below, Guacamole's Kubernetes
+support also accepts the parameters of several features that Guacamole provides
+for multiple protocols:
+
+* [](disable-clipboard)
+* [](graphical-recording)
+* [](typescripts)
+* [](stdin-pipe)
+* [](terminal-behavior)
+* [](terminal-display-settings)
+* [](wake-on-lan)
+:::
+
+
+(kubernetes-network-parameters)=
+
+#### Network/Container parameters
+
+Attaching to a Kubernetes container requires the hostname or IP address of the
+Kubernetes server and the name of the pod containing the container in question.
+By default, Guacamole will attach to the first container in the pod. If there
+are multiple containers in the pod, you may wish to also specify the container
+name.
+
+`hostname`
+: The hostname or IP address of the Kubernetes server
+  that Guacamole should connect to.
+
+`port`
+: The port the Kubernetes server is listening on for
+  API connections. *This parameter is optional.* If
+  omitted, port 8080 will be used by default.
+
+`namespace`
+: The name of the Kubernetes namespace of the pod containing the container
+  being attached to. *This parameter is optional.* If omitted, the namespace
+  "default" will be used.
+
+`pod`
+: The name of the Kubernetes pod containing with the container being
+  attached to.
+
+`container`
+: The name of the container to attach to. *This parameter is optional.* If
+  omitted, the first container in the pod will be used.
+
+`exec-command`
+: The command to run within the container, with input and output attached to
+  this command's process. *This parameter is optional.* If omitted, no
+  command will be run, and input/output will instead be attached to the main
+  process of the container.
+
+  When this parameter is specified, the behavior of the connection is
+  analogous to running {command}`kubectl exec`. When omitted, the behavior
+  is analogous to running {command}`kubectl attach`.
+
+(kubernetes-authentication)=
+
+#### Authentication and SSL/TLS
+
+If enabled, Kubernetes uses SSL/TLS for both encryption and authentication.
+Standard SSL/TLS client authentication requires both a client certificate and
+client key, which Guacamole will use to identify itself to the Kubernetes
+server. If the certificate used by Kubernetes is self-signed or signed by a
+non-standard certificate authority, the certificate for the certificate
+authority will also be needed.
+
+`use-ssl`
+: If set to "true", SSL/TLS will be used to connect to the Kubernetes
+  server. *This parameter is optional.* By default, SSL/TLS will not be
+  used.
+
+`client-cert`
+: The certificate to use if performing SSL/TLS client authentication to
+  authenticate with the Kubernetes server, in PEM format. *This parameter is
+  optional.* If omitted, SSL client authentication will not be performed.
+
+`client-key`
+: The key to use if performing SSL/TLS client authentication to authenticate
+  with the Kubernetes server, in PEM format. *This parameter is optional.*
+  If omitted, SSL client authentication will not be performed.
+
+`ca-cert`
+: The certificate of the certificate authority that signed the certificate
+  of the Kubernetes server, in PEM format. *This parameter is optional.* If
+  omitted, verification of the Kubernetes server certificate will use only
+  system-wide certificate authorities.
+
+`ignore-cert`
+: If set to "true", the validity of the SSL/TLS certificate used by the
+  Kubernetes server will be ignored if it cannot be validated. *This
+  parameter is optional.* By default, SSL/TLS certificates are validated.
+
+(adding-kubernetes)=
+
+#### Adding a Kubernetes connection
+
+If you are using the default authentication built into Guacamole, and you wish
+to grant access to a Kubernetes connection to a particular user, you need to
+locate the `<authorize>` section for that user within your `user-mapping.xml`,
+and add a section like the following within it:
+
+```xml
+<connection name="Unique Name">
+    <protocol>kubernetes</protocol>
+    <param name="hostname">localhost</param>
+    <param name="pod">mypod</param>
+</connection>
+```
+
+If added exactly as above, a new connection named "`Unique Name`" will be
+available to the user associated with the `<authorize>` section containing it.
+The connection will connect to the Kubernetes server running on localhost and
+attach to the first container of the pod "mypod".
+
+### Common configuration options
+
+(disable-clipboard)=
+
+#### Disabling clipboard access
+
+Guacamole provides bidirectional access to the clipboard by default for all
+supported protocols. For protocols that don't inherently provide a clipboard,
+Guacamole implements its own clipboard. This behavior can be overridden on a
+per-connection basis with the `disable-copy` and `disable-paste` parameters.
+
+`disable-copy`
+: If set to "true", text copied within the remote desktop session will not
+  be accessible by the user at the browser side of the Guacamole session,
+  and will be usable only within the remote desktop. This parameter is
+  optional. By default, the user will be given access to the copied text.
+
+`disable-paste`
+: If set to "true", text copied at the browser side of the Guacamole session
+  will not be accessible within the remote ddesktop session. This parameter
+  is optional. By default, the user will be able to paste data from outside
+  the browser within the remote desktop session.
+
+(common-sftp)=
+
+#### File transfer via SFTP
+
+Guacamole can provide file transfer over SFTP even when the remote desktop is
+otherwise being accessed through a different protocol, like VNC or RDP. If SFTP
+is enabled on a Guacamole RDP connection, users will be able to upload and

Review comment:
       Is this section intended to be specific to RDP, or is it supposed to cover any protocol that leverages SFTP for file transfer? I ask because here and below it talks in specifics about RDP, so not sure if it is supposed to be more generic?

##########
File path: src/reverse-proxy.md
##########
@@ -0,0 +1,427 @@
+Proxying Guacamole
+==================
+
+Like most web applications, Guacamole can be placed behind a reverse proxy. For
+production deployments of Guacamole, this is *highly recommended*. It provides
+flexibility and, if your proxy is properly configured for SSL, encryption.
+
+Proxying isolates privileged operations within native applications that can
+safely drop those privileges when no longer needed, using Java only for
+unprivileged tasks. On Linux and UNIX systems, a process must be running with
+root privileges to listen on any port under 1024, including the standard HTTP
+and HTTPS ports (80 and 443 respectively). If the servlet container instead
+listens on a higher port, such as the default port 8080, it can run as a
+reduced-privilege user, allowing the reverse proxy to bear the burden of root
+privileges. As a native application, the reverse proxy can make system calls to
+safely drop root privileges once the port is open; a Java application like
+Tomcat cannot do this.
+
+(preparing-servlet-container)=
+
+Preparing your servlet container
+--------------------------------
+
+Your servlet container is most likely already configured to listen for HTTP
+connections on port 8080 as this is the default. If this is the case, and you
+can already access Guacamole over port 8080 from a web browser, you need not
+make any further changes to its configuration.
+
+If you *have* changed this, perhaps with the intent of proxying Guacamole over
+AJP, *change it back*. Using Guacamole over AJP is unsupported as it is known
+to cause problems, namely:
+
+1. WebSocket will not work over AJP, forcing Guacamole to fallback to HTTP,
+   possibly resulting in reduced performance.
+
+2. Apache 2.4.3 and older does not support the HTTP PATCH method over AJP,
+   preventing the Guacamole management interface from functioning properly.
+
+The connector entry within `conf/server.xml` should look like this:
+
+```xml
+<Connector port="8080" protocol="HTTP/1.1" 
+           connectionTimeout="20000"
+           URIEncoding="UTF-8"
+           redirectPort="8443" />
+```
+
+Be sure to specify the `URIEncoding="UTF-8"` attribute as above to ensure that
+connection names, user names, etc. are properly received by the web
+application. If you will be creating connections that have Cyrillic, Chinese,
+Japanese, or other non-Latin characters in their names or parameter values,
+this attribute is required.
+
+(tomcat-remote-ip)=
+
+### Setting up the Remote IP Valve
+
+By default, when Tomcat is behind a reverse proxy, the remote IP address of the
+client that it sees is that of the proxy rather than the original client. In
+order to allow applications hosted within Tomcat, like Guacamole, to see the
+actual IP address of the client, you have to configure both the reverse proxy
+and Tomcat.
+
+Because the remote IP address in Guacamole is used for auditing of user logins
+and connections and could potentially be used for authentication, it is
+important that you are either in direct control of the proxy server or you
+explicitly trust it. Passing the remote IP address is done using the
+`X-Forwarded-For` header, and, as with most HTTP headers, attackers can attempt
+to spoof this header in order to manipulate the behavior of the web server,
+gain unauthorized access to the system, or attempt to disguise the host or IP
+address they are coming from.
+
+One final caveat: This may not work as expected if there are other upstream
+proxy servers between your reverse proxy and the clients access Guacamole.
+Other proxies or firewalls can mask the IP address of the client, and if the
+configuration of those is not within your control you may end up with multiple
+clients appearing to come from the same IP address or host. Make sure you take
+this into account when configuring the system and looking at the data provided.
+
+Configuring Tomcat to pass through the remote IP address provided by the
+reverse proxy in the `X-Forwarded-For` header requires the configuration of
+what Tomcat calls a Valve. In this case, it is the
+[`RemoteIpValve`](https://tomcat.apache.org/tomcat-8.5-doc/config/valve.html#Remote_IP_Valve)
+and is configured in the `conf/server.xml` file, in the `<Host>` section:
+
+```xml
+<Valve className="org.apache.catalina.valves.RemoteIpValve"
+               internalProxies="127.0.0.1"
+               remoteIpHeader="x-forwarded-for"
+               remoteIpProxiesHeader="x-forwarded-by"
+               protocolHeader="x-forwarded-proto" />
+```
+
+The `internalProxies` value should be set to the IP address or addresses of any
+and all reverse proxy servers that will be accessing this Tomcat instance
+directly. Often it is run on the same system that runs Tomcat, but in other
+cases (for example, when running Docker), it may be on a different
+system/container and may need to be set to the actual IP address of the reverse
+proxy system. Only proxy servers listed in the `internalProxies` or
+`trustedProxies` parameters will be allowed to manipulate the remote IP address
+information. The other parameters in this configuration line allow you to
+control which headers coming from the proxy server(s) are used for various
+remote host information. They are as follows:
+
+`remoteIpHeader`
+: The header that is queried to learn the client IP address of the client
+  that originated the request. The standard value is `X-Forwarded-For`, but
+  can be configured to any header you like. The IP address in this header
+  will be available to Java applications in the `request.getRemoteAddr()`
+  method.
+
+`remoteIpProxiesHeader`
+: The header that is queried to learn the IP address of the proxy server
+  that forwarded the request. The default value is `X-Forwarded-By`, but can
+  be configured to any header that fits your environment. This value will
+  only be allowed by the valve if the proxy used is listed in the
+  `trustedProxies` parameter. Otherwise this header will not be available.
+
+`protocolHeader`
+: The header that is queried to determine the protocol that the client used
+  to connect to the service. The default value is `X-Forwarded-Proto`, but
+  can be configured to fit your environment.
+
+In addition to configuring Tomcat to properly handle these headers, you also
+may need to configure your reverse proxy appropriately to send the headers. You
+can find instructions for this in [](nginx) - the Apache web server passes it
+through by default.
+
+(nginx)=
+
+Nginx
+-----
+
+Nginx can be used as a reverse proxy, and supports WebSocket out-of-the-box
+[since version 1.3](http://nginx.com/blog/websocket-nginx/). Both Apache and
+Nginx require some additional configuration for proxying of WebSocket to work
+properly.
+
+(proxying-with-nginx)=
+
+### Proxying Guacamole
+
+Nginx does support WebSocket for proxying, but requires that the "Connection"
+and "Upgrade" HTTP headers are set explicitly due to the nature of the
+WebSocket protocol. From the Nginx documentation:
+
+> NGINX supports WebSocket by allowing a tunnel to be set up between a client
+> and a back-end server. For NGINX to send the Upgrade request from the client
+> to the back-end server, Upgrade and Connection headers must be set
+> explicitly. ...
+
+The proxy configuration belongs within a dedicated
+[`location`](http://nginx.org/en/docs/http/ngx_http_core_module.html#location>)
+block, declaring the backend hosting Guacamole and explicitly specifying the
+"`Connection`" and "`Upgrade`" headers mentioned earlier:
+
+```nginx
+location /guacamole/ {
+    proxy_pass http://HOSTNAME:8080;
+    proxy_buffering off;
+    proxy_http_version 1.1;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $http_connection;
+    access_log off;
+}
+```
+
+Here, `HOSTNAME` is the hostname or IP address of the machine hosting your
+servlet container, and 8080 is the port that servlet container is configured to
+use. You will need to replace these values with the correct values for your
+server.
+
+Related to the `RemoteIpValve` configuration for tomcat, documented in
+[Setting up the Remote IP Valve](tomcat-remote-ip), the `proxy_set_header
+X-Forwarded-For $proxy_add_x_forwarded_for;` line is important if you want the
+`X-Forwarded-For` header to be passed through to the web application server and
+available to applications running inside it.
+
+:::{important}
+*Do not forget to specify "`proxy_buffering off`".*
+
+Most proxies, including Nginx, will buffer all data sent over the connection,
+waiting until the connection is closed before sending that data to the client.
+As Guacamole's HTTP tunnel relies on streaming data to the client over an open
+connection, excessive buffering will effectively block Guacamole connections,
+rendering Guacamole useless.
+
+*If the option "`proxy_buffering off`" is not specified, Guacamole may not
+work*.
+:::
+
+(changing-path-with-nginx)=
+
+### Changing the path
+
+If you wish to serve Guacamole through Nginx under a path other than
+`/guacamole/`, the easiest method is to simply rename the `.war` file. For
+example, if intending to server Guacamole at `/new-path/`, you would:
+
+1. Rename `guacamole.war` to `new-path.war`.
+
+2. Update the path within the Nginx configuration to reflect the new
+   path:
+
+   :::{code-block} nginx
+   :emphasize-lines: 1
+   location /new-path/ {
+       proxy_pass http://HOSTNAME:8080;

Review comment:
       Shouldn't this be `proxy_pass http://HOSTNAME:8080/new-path/` if the WAR is being changed?

##########
File path: src/guacamole-ext.md
##########
@@ -0,0 +1,693 @@
+guacamole-ext
+=============
+
+While not strictly part of the Java API provided by the Guacamole project,
+guacamole-ext is an API exposed by the Guacamole web application within a
+separate project such that extensions, specifically authentication providers,
+can be written to tweak Guacamole to fit well in existing deployments.
+
+Extensions to Guacamole can:
+
+1. Provide alternative authentication methods and sources of connection/user
+   data.
+
+2. Provide event listeners that will be notified as Guacamole performs tasks
+   such as authentication and tunnel connection.
+
+3. Theme or brand Guacamole through additional CSS files and static resources.
+
+4. Extend Guacamole's JavaScript code by providing JavaScript that will be
+   loaded automatically.
+
+5. Add additional display languages, or alter the translation strings of
+   existing languages.
+
+(ext-file-format)=
+
+Guacamole extension format
+--------------------------
+
+Guacamole extensions are standard Java `.jar` files which contain all classes
+and resources required by the extension, as well as the Guacamole extension
+manifest. There is no set structure to an extension except that the manifest
+must be in the root of the archive. Java classes and packages, if any, will be
+read from the `.jar` relative to the root, as well.
+
+Beyond this, the semantics and locations associated with all other resources
+within the extension are determined by the extension manifest alone.
+
+(ext-manifest)=
+
+### Extension manifest
+
+The Guacamole extension manifest is a single JSON file, `guac-manifest.json`,
+which describes the location of each resource, the type of each resource, and
+the version of Guacamole that the extension was built for. The manifest can
+contain the following properties:
+
+`guacamoleVersion`
+: The version string of the Guacamole release that this extension is written
+  for. *This property is required for all extensions.* The special version
+  string `"*"` can be used if the extension does not depend on a particular
+  version of Guacamole, but be careful - this will bypass version compatibility
+  checks, and should never be used if the extension does more than basic
+  theming or branding.
+
+`name`
+: A human-readable name for the extension. *This property is required for all
+  extensions.* When your extension is successfully loaded, a message
+  acknowledging the successful loading of your extension by name will be
+  logged.
+
+`namespace`
+: A unique string which identifies your extension. *This property is required
+  for all extensions.* This string should be unique enough that it is unlikely
+  to collide with the namespace of any other extension.
+
+  If your extension contains static resources, those resources will be served
+  at a path derived from the namespace provided here.
+
+`authProviders`
+: An array of the classnames of all `AuthenticationProvider` subclasses
+  provided by this extension.
+
+`listeners`
+: An array of the classnames of all `Listener` subclasses provided by this
+  extension.
+
+`js`
+: An array of all JavaScript files within the extension. All paths within this
+  array must be relative paths, and will be interpreted relative to the root of
+  the archive.
+
+  JavaScript files declared here will be automatically loaded when the web
+  application loads within the user's browser.
+
+`css`
+: An array of all CSS files within the extension. All paths within this array
+  must be relative paths, and will be interpreted relative to the root of the
+  archive.
+
+  CSS files declared here will be automatically applied when the web
+  application loads within the user's browser.
+
+`html`
+: An array of all HTML files within the extension that should be used to update
+  or replace existing HTML within the Guacamole interface. All paths within
+  this array must be relative paths, and will be interpreted relative to the
+  root of the archive.
+
+  HTML files declared here will be automatically applied to other HTML within
+  the Guacamole interface when the web application loads within the user's
+  browser. The manner in which the files are applied is dictated by
+  `<meta ...>` tags within those same files.
+
+`translations`
+: An array of all translation files within the extension. All paths within this
+  array must be relative paths, and will be interpreted relative to the root of
+  the archive.
+
+  Translation files declared here will be automatically added to the available
+  languages. If a translation file provides a language that already exists
+  within Guacamole, its strings will override the strings of the existing
+  translation.
+
+`resources`
+: An object where each property name is the name of a web resource file, and
+  each value is the mimetype for that resource. All paths within this object
+  must be relative paths, and will be interpreted relative to the root of the
+  archive.
+
+  Web resources declared here will be made available to the application at
+  {samp}`app/ext/{NAMESPACE}/{PATH}`, where `NAMESPACE` is the value of the
+  namespace property, and `PATH` is the declared web resource filename.
+
+The only absolutely required properties are `guacamoleVersion`, `name`, and
+`namespace`, as they are used to identify the extension and for compatibility
+checks. The most minimal `guac-manifest.json` will look something like this:
+
+```json
+{
+    "guacamoleVersion" : "1.3.0",
+    "name" : "My Extension",
+    "namespace" : "my-extension"
+}
+```
+
+This will allow the extension to load, but does absolutely nothing otherwise.
+Lacking the semantic information provided by the other properties, no other
+files within the extension will be used. A typical `guac-manifest.json` for an
+extension providing theming or branding would be more involved:
+
+```json
+{
+
+    "guacamoleVersion" : "1.3.0",
+
+    "name"      : "My Extension",
+    "namespace" : "my-extension",
+
+    "css" : [ "theme.css" ],
+
+    "html" : [ "loginDisclaimer.html" ],
+
+    "resources" : {
+        "images/logo.png"   : "image/png",
+        "images/cancel.png" : "image/png",
+        "images/delete.png" : "image/png"
+    }
+
+}
+```
+
+(ext-patch-html)=
+
+### Updating existing HTML
+
+The existing HTML structure of Guacamole's interface can be modified by
+extensions through special "patch" HTML files declared by the html property in
+`guac-manifest.json`. These files are HTML fragments and are identical to any
+other HTML file except that they contain Guacamole-specific meta tags that
+instruct Guacamole to modify its own HTML in a particular way. Each meta tag
+takes the following form:
+
+```html
+<meta name="NAME" content="SELECTOR">
+```
+
+where `SELECTOR` is a CSS selector that matches the elements within the
+Guacamole interface that serve as a basis for the modification, and `NAME` is
+any one of the following defined modifications:
+
+`before`
+: Inserts the specified HTML immediately before any element matching the CSS
+  selector.
+
+`after`
+: Inserts the specified HTML immediately after any element matching the CSS
+  selector.
+
+`replace`
+: Replaces any element matching the CSS selector with the specified HTML.
+
+`before-children`
+: Inserts the specified HTML immediately before the first child (if any) of any
+  element matching the CSS selector. If a matching element has no children, the
+  HTML simply becomes the entire contents of the matching element.
+
+`after-children`
+: Inserts the specified HTML immediately after the last child (if any) of any
+  element matching the CSS selector. If a matching element has no children, the
+  HTML simply becomes the entire contents of the matching element.
+
+`replace-children`
+: Replaces the entire contents of any element matching the CSS selector with
+  the specified HTML.
+
+For example, to add a welcome message and link to some corporate privacy policy
+(a fairly common need), you would add an HTML file like the following:
+
+```html
+<meta name="after" content=".login-ui .login-dialog">
+
+<div class="welcome">
+    <h2>Welcome to our Guacamole server!</h2>
+    <p>
+        Please be sure to read our <a href="/path/to/some/privacy.html">privacy
+        policy</a> before continuing.
+    </p>
+</div>
+```
+
+After the extension is installed and Guacamole is restarted, the "welcome" div
+and its contents will automatically be inserted directly below the login dialog
+(the only element that would match `.login-ui .login-dialog`) as if they were
+part of Guacamole's HTML in the first place.
+
+An example of an extension that modifies style and HTML components for the
+purpose of providing custom "branding" of the Guacamole interface can be found
+in the `doc/guacamole-branding-example` directory of the guacamole-client
+source code, which can be found here:
+<https://github.com/apache/guacamole-client/tree/master/doc/guacamole-branding-example>
+
+(ext-environment)=
+
+Accessing the server configuration
+----------------------------------
+
+The configuration of the Guacamole server is exposed through the `Environment`
+interface, specifically the `LocalEnvironment` implementation of this
+interface. Through `Environment`, you can access all properties declared within
+`guacamole.properties`, determine the proper hostname/port of guacd, and access
+the contents of `GUACAMOLE_HOME`.
+
+(ext-simple-config)=
+
+### Custom properties
+
+If your extension requires generic, unstructured configuration parameters,
+`guacamole.properties` is a reasonable and simple location for them. The
+`Environment` interface provides direct access to `guacamole.properties` and
+simple mechanisms for reading and parsing the properties therein. The value of
+a property can be retrieved calling `getProperty()`, which will return `null`

Review comment:
       _by_ calling

##########
File path: src/guacamole-docker.md
##########
@@ -0,0 +1,707 @@
+Installing Guacamole with Docker
+================================
+
+Guacamole can be deployed using Docker, removing the need to build
+guacamole-server from source or configure the web application manually.  The
+Guacamole project provides officially-supported Docker images for both
+Guacamole and guacd which are kept up-to-date with each release.
+
+A typical Docker deployment of Guacamole will involve three separate
+containers, linked together at creation time:
+
+`guacamole/guacd`
+: Provides the guacd daemon, built from the released guacamole-server source
+  with support for VNC, RDP, SSH, telnet, and Kubernetes.
+
+`guacamole/guacamole`
+: Provides the Guacamole web application running within Tomcat 8 with support
+  for WebSocket. The configuration necessary to connect to guacd, MySQL,
+  PostgreSQL, LDAP, etc. will be generated automatically when the image starts
+  based on Docker links or environment variables.
+
+`mysql` or `postgresql`
+: Provides the database that Guacamole will use for authentication and storage
+  of connection configuration data.
+
+This separation is important, as it facilitates upgrades and maintains proper
+separation of concerns. With the database separate from Guacamole and guacd,
+those containers can be freely destroyed and recreated at will. The only
+container which must persist data through upgrades is the database.
+
+(guacd-docker-image)=
+
+Running the guacd Docker image
+------------------------------
+
+The guacd Docker image is built from the released guacamole-server source with
+support for VNC, RDP, SSH, telnet, and Kubernetes. Common pitfalls like
+installing the required dependencies, installing fonts for SSH, telnet, or
+Kubernetes, and ensuring the FreeRDP plugins are installed to the correct
+location are all taken care of. It will simply just work.
+
+(guacd-docker-guacamole)=
+
+### Running guacd for use by the Guacamole Docker image
+
+When running the guacd image with the intent of linking to a Guacamole
+container, no ports need be exposed on the network. Access to these ports will
+be handled automatically by Docker during linking, and the Guacamole image will
+properly detect and configure the connection to guacd.
+
+```console
+$ docker run --name some-guacd -d guacamole/guacd
+```
+When run in this manner, guacd will be listening on its default port 4822, but
+this port will only be available to Docker containers that have been explicitly
+linked to `some-guacd`.
+
+The log level of guacd can be controlled with the `GUACD_LOG_LEVEL` environment
+variable. The default value is `info`, and can be set to any of the valid
+settings for the guacd log flag (-L).
+
+```console
+$ docker run -e GUACD_LOG_LEVEL=debug -d guacamole/guacd
+```
+
+(guacd-docker-external)=
+
+### Running guacd for use by services outside Docker
+
+If you are not going to use the Guacamole image, you can still leverage the
+guacd image for ease of installation and maintenance. By exposing the guacd
+port, 4822, services external to Docker will be able to access guacd.
+
+:::{important}
+*Take great care when doing this* - guacd is a passive proxy and does not
+perform any kind of authentication.
+
+If you do not properly isolate guacd from untrusted parts of your network,
+malicious users may be able to use guacd as a jumping point to other systems.
+:::
+
+```console
+$ docker run --name some-guacd -d -p 4822:4822 guacamole/guacd
+```
+
+guacd will now be listening on port 4822, and Docker will expose this port on
+the same server hosting Docker. Other services, such as an instance of Tomcat
+running outside of Docker, will be able to connect to guacd directly.
+
+(guacamole-docker-image)=
+
+The Guacamole Docker image
+--------------------------
+
+The Guacamole Docker image is built on top of a standard Tomcat 8 image and
+takes care of all configuration automatically. The configuration information
+required for guacd and the various authentication mechanisms are specified with
+environment variables or Docker links given when the container is created.
+
+:::{important}
+If using [PostgreSQL](guacamole-docker-postgresql) or [MySQL](guacamole-docker-mysql)
+for authentication, *you will need to initialize the database manually*.
+Guacamole will not automatically create its own tables, but SQL scripts are
+provided to do this.
+:::
+
+Once the Guacamole image is running, Guacamole will be accessible at
+{samp}`http://{HOSTNAME}:8080/guacamole/`, where `HOSTNAME` is the hostname or
+address of the machine hosting Docker.
+
+(guacamole-docker-config-via-env)=
+
+### Configuring Guacamole when using Docker
+
+When running Guacamole using Docker, the traditional approach to configuring
+Guacamole by editing `guacamole.properties` is less convenient. When using
+Docker, you may wish to make use of the `enable-environment-properties`
+configuration property, which allows you to specify values for arbitrary
+Guacamole configuration properties using environment variables. This is covered
+in [](configuring-guacamole).
+
+(guacamole-docker-guacd)=
+
+### Connecting Guacamole to guacd
+
+The Guacamole Docker image needs to be able to connect to guacd to establish
+remote desktop connections, just like any other Guacamole deployment. The
+connection information needed by Guacamole will be provided either via a Docker
+link or through environment variables.
+
+If you will be using Docker to provide guacd, and you wish to use a Docker link
+to connect the Guacamole image to guacd, the connection details are implied by
+the Docker link:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+If you are not using Docker to provide guacd, you will need to provide the
+network connection information yourself using additional environment variables:
+
+`GUACD_HOSTNAME`
+: The hostname of the guacd instance to use to establish remote desktop
+  connections. *This is required if you are not using Docker to provide guacd.*
+
+`GUACD_POST`
+: The port that Guacamole should use when connecting to guacd. This environment
+  variable is optional. If not provided, the standard guacd port of 4822 will
+  be used.
+
+The `GUACD_HOSTNAME` and, if necessary, `GUACD_PORT` environment variables can
+thus be used in place of a Docker link if using a Docker link is impossible or
+undesirable:
+
+```console
+$ docker run --name some-guacamole \
+    -e GUACD_HOSTNAME=172.17.42.1  \
+    -e GUACD_PORT=4822             \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+*A connection to guacd is not the only thing required for Guacamole to work*;
+some authentication mechanism needs to be configured, as well.
+[MySQL](guacamole-docker-mysql), [PostgreSQL](guacamole-docker-postgresql), and
+[LDAP](guacamole-docker-ldap) are supported for this, and are described in more
+detail in the sections below. If the required configuration options for at
+least one authentication mechanism are not provided, the Guacamole image will
+not be able to start up, and you will see an error.
+
+(guacamole-docker-mysql)=
+
+### MySQL authentication
+
+To use Guacamole with the MySQL authentication backend, you will need either a
+Docker container running the `mysql` image, or network access to a working
+installation of MySQL. The connection to MySQL can be specified using either
+environment variables or a Docker link.
+
+(initializing-guacamole-docker-mysql)=
+
+#### Initializing the MySQL database
+
+If your database is not already initialized with the Guacamole schema, you will
+need to do so prior to using Guacamole. A convenience script for generating the
+necessary SQL to do this is included in the Guacamole image.
+
+To generate a SQL script which can be used to initialize a fresh MySQL database
+as documented in [](jdbc-auth):
+
+```console
+$ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
+```
+
+Alternatively, you can use the SQL scripts included with the database
+authentication.
+
+Once this script is generated, you must:
+
+1. Create a database for Guacamole within MySQL, such as `guacamole_db`.
+
+2. Create a user for Guacamole within MySQL with access to this database, such
+   as `guacamole_user`.
+
+3. Run the script on the newly-created database.
+
+The process for doing this via the {command}`mysql` utility included with MySQL
+is documented [](jdbc-auth).
+
+(guacamole-docker-mysql-connecting)=
+
+#### Connecting Guacamole to MySQL
+
+If your MySQL database is provided by another Docker container, and you wish to
+use a Docker link to connect the Guacamole image to your database, the
+connection details are implied by the Docker link itself:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    --link some-mysql:mysql        \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+If you are not using Docker to provide your MySQL database, you will need to
+provide the network connection information yourself using additional
+environment variables:
+
+`MYSQL_HOSTNAME`
+: The hostname of the database to use for Guacamole authentication. *This is
+  required if you are not using Docker to provide your MySQL database.*
+
+`MYSQL_PORT`
+: The port that Guacamole should use when connecting to MySQL. This environment
+  variable is optional. If not provided, the standard MySQL port of 3306 will
+  be used.
+
+The `MYSQL_HOSTNAME` and, if necessary, `MYSQL_PORT` environment variables can
+thus be used in place of a Docker link if using a Docker link is impossible or
+undesirable:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    -e MYSQL_HOSTNAME=172.17.42.1  \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+Note that a Docker link to guacd (the `--link some-guacd:guacd` option above)
+is not required any more than a Docker link is required for MySQL. The
+connection information for guacd can be specified using environment variables,
+as described in [](guacamole-docker-guacd).
+
+(guacamole-docker-mysql-required-vars)=
+
+#### Required environment variables
+
+Using MySQL for authentication requires additional configuration parameters
+specified via environment variables. These variables collectively describe how
+Guacamole will connect to MySQL:
+
+`MYSQL_DATABASE`
+: The name of the database to use for Guacamole authentication.
+
+`MYSQL_USER`
+: The user that Guacamole will use to connect to MySQL.
+
+`MYSQL_PASSWORD`
+: The password that Guacamole will provide when connecting to MySQL as
+  `MYSQL_USER`.
+
+If any required environment variables are omitted, you will receive an error
+message in the logs, and the image will stop. You will then need to recreate
+the container with the proper variables specified.
+
+(guacamole-docker-mysql-optional-vars)=
+
+#### Optional environment variables
+
+Additional optional environment variables may be used to override Guacamole's
+default behavior with respect to concurrent connection use by one or more
+users. Concurrent use of connections and connection groups can be limited to an
+overall maximum and/or a per-user maximum:
+
+
+`MYSQL_ABSOLUTE_MAX_CONNECTIONS`
+: The absolute maximum number of concurrent connections to allow at any time,
+  regardless of the Guacamole connection or user involved. If set to "0", this
+  will be unlimited. Because this limit applies across all Guacamole
+  connections, it cannot be overridden if set.
+
+  *By default, the absolute total number of concurrent connections is unlimited
+  ("0").*
+
+`MYSQL_DEFAULT_MAX_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection. If set to "0", this will be unlimited. This can be overridden on
+  a per-connection basis when editing a connection.
+
+  *By default, overall concurrent use of connections is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_GROUP_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection group. If set to "0", this will be unlimited.  This can be
+  overridden on a per-group basis when editing a connection group.
+
+  *By default, overall concurrent use of connection groups is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection. If set to "0", this will be
+  unlimited. This can be overridden on a per-connection basis when editing a
+  connection.
+
+  *By default, per-user concurrent use of connections is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection group. If set to "0", this will be
+  unlimited. This can be overridden on a per-group basis when editing a
+  connection group.
+
+  *By default, per-user concurrent use of connection groups is limited to one
+  ("1")*, to prevent a balancing connection group from being completely
+  exhausted by one user alone.
+
+`MYSQL_AUTO_CREATE_ACCOUNTS`
+: Whether or not accounts that do not exist in the MySQL database will be
+  automatically created when successfully authenticated through other modules.
+  If set to "true" accounts will be automatically created. Otherwise, and by
+  default, accounts will not be automatically created and will need to be
+  manually created in order for permissions within the MySQL database extension
+  to be assigned to users authenticated with other modules.

Review comment:
       I'm wondering if there's any way in this section (and for PostgreSQL) to link these descriptions back to the terms in the jdbc-auth section? There may not be a great way to do it, but it just seems like it would avoid having to duplicate a bunch of text and update things in multiple places if those descriptions change for one reason or another.

##########
File path: src/guacamole-protocol.md
##########
@@ -0,0 +1,404 @@
+The Guacamole protocol
+======================
+
+This chapter is an overview of the Guacamole protocol, describing its design
+and general use. While a few instructions and their syntax will be described
+here, this is not an exhaustive list of all available instructions. The intent
+is only to list the general types and usage. If you are looking for the syntax
+or purpose of a specific instruction, consult the protocol reference included
+with the appendices.
+
+(guacamole-protocol-design)=
+
+Design
+------
+
+The Guacamole protocol consists of instructions. Each instruction is a
+comma-delimited list followed by a terminating semicolon, where the first
+element of the list is the instruction opcode, and all following elements are
+the arguments for that instruction:
+
+```
+OPCODE,ARG1,ARG2,ARG3,...;
+```
+
+Each element of the list has a positive decimal integer length prefix separated
+by the value of the element by a period. This length denotes the number of
+Unicode characters in the value of the element, which is encoded in UTF-8:
+
+```
+LENGTH.VALUE
+```
+
+Any number of complete instructions make up a message which is sent from client
+to server or from server to client. Client to server instructions are generally
+control instructions (for connecting or disconnecting) and events (mouse and
+keyboard). Server to client instructions are generally drawing instructions
+(caching, clipping, drawing images), using the client as a remote display.
+
+For example, a complete and valid instruction for setting the display size to
+1024x768 would be:
+
+```
+4.size,1.0,4.1024,3.768;
+```
+
+Here, the instruction would be decoded into four elements: "size", the opcode
+of the size instruction, "0", the index of the default layer, "1024", the
+desired width in pixels, and "768", the desired height in pixels.
+
+The structure of the Guacamole protocol is important as it allows the protocol
+to be streamed while also being easily parsable by JavaScript.  JavaScript does
+have native support for conceptually-similar structures like XML or JSON, but
+neither of those formats is natively supported in a way that can be streamed;
+JavaScript requires the entirety of the XML or JSON message to be available at
+the time of decoding. The Guacamole protocol, on the other hand, can be parsed
+as it is received, and the presence of length prefixes within each instruction
+element means that the parser can quickly skip around from instruction to
+instruction without having to iterate over every character.
+
+(guacamole-protocol-handshake)=
+
+Handshake phase
+---------------
+
+The handshake phase is the phase of the protocol entered immediately upon
+connection. It begins with a "select" instruction sent by the client which
+tells the server which protocol will be loaded:
+
+```
+6.select,3.vnc;
+```
+
+After receiving the "select" instruction, the server will load the associated
+client support and respond with its protocol version and a list of accepted
+parameter names using an "args" instruction:
+
+```
+4.args,13.VERSION_1_1_0,8.hostname,4.port,8.password,13.swap-red-blue,9.read-only;
+```
+
+The protocol version is used to negotiate compatibility between differing
+versions of client and server, allowing the two sides to negotiate the highest
+supported version and enable or disable features associated with that version.
+Older versions of the Guacamole that do not support version negotiation will

Review comment:
       the Guacamole _protocol_

##########
File path: src/libguac.md
##########
@@ -0,0 +1,411 @@
+libguac
+=======
+
+The C API for extending and developing with Guacamole is libguac. All native
+components produced by the Guacamole project link with this library, and this
+library provides the common basis for extending the native functionality of
+those native components (by implementing client plugins).
+
+libguac is used mainly for developing client plugins like libguac-client-vnc or
+libguac-client-rdp, or for developing a proxy supporting the Guacamole protocol
+like guacd. This chapter is intended to give an overview of how libguac is
+used, and how to use it for general communication with the Guacamole protocol.
+
+(libguac-error-handling)=
+
+Error handling
+--------------
+
+Most functions within libguac handle errors by returning a zero or non-zero
+value, whichever is appropriate for the function at hand. If an error is
+encountered, the `guac_error` variable is set appropriately, and
+`guac_error_message` contains a statically-allocated human-readable string
+describing the context of the error. These variables intentionally mimic the
+functionality provided by `errno` and `errno.h`.
+
+Both `guac_error` and `guac_error_message` are defined within `error.h`. A
+human-readable string describing the error indicated by `guac_error` can be
+retrieved using `guac_status_string()`, which is also statically allocated.
+
+If functions defined within client plugins set `guac_error` and
+`guac_error_message` appropriately when errors are encountered, the messages
+logged to syslog by guacd will be more meaningful for both users and
+developers.
+
+(libguac-client-plugins)=
+
+Client plugins
+--------------
+
+Client plugins are libraries which follow specific conventions such that they
+can be loaded dynamically by guacd. All client plugins *must*:
+
+1. Follow a naming convention, where the name of the library is
+   {samp}`libguac-client-{PROTOCOL}`. *This is necessary for guacd to locate
+   the library for a requested protocol.*
+
+2. Be linked against libguac, the library used by guacd to handle the Guacamole
+   protocol. The structures which are given to functions invoked by guacd are
+   defined by libguac, and are expected to be manipulated via the functions
+   provided by libguac or as otherwise documented within the structure itself.
+   *Communication between guacd and client plugins is only possible if they
+   share the same core structural and functional definitions provided by
+   libguac.*
+
+3. Implement the standard entry point for client plugins, `guac_client_init()`,
+   described in more detail below. It is this function which initializes the
+   structures provided by guacd such that users can join and interact with the
+   connection.
+
+(libguac-lifecycle-entry)=
+
+### Entry point
+
+All client plugins must provide a function named `guac_client_init` which
+accepts, as its sole argument, a pointer to a `guac_client` structure.  This
+function is similar in principle to the main() function of a C program, and it
+is the responsibility of this function to initialize the provided structure as
+necessary to begin the actual remote desktop connection, allow users to
+join/leave, etc.
+
+The provided `guac_client` will already have been initialized with handlers for
+logging, the broadcast socket, etc. The absolutely critical pieces which must
+be provided by `guac_client_init` are:
+
+1. A handler for users which join the connection (`join_handler`). The join
+   handler is also usually the most appropriate place for the actual remote
+   desktop connection to be established.
+
+2. A `NULL`-terminated set of argument names which the client plugin accepts,
+   assigned to the args property of the given `guac_client`.  As the handshake
+   procedure is completed for each connecting user, these argument names will
+   be presented as part of the handshake, and the values for those arguments
+   will be passed to the join handler once the handshake completes.
+
+3. A handler for users leaving the connection (`leave_handler`), if any
+   cleanup, updates, etc. are required.
+
+4. A handler for freeing the data associated with the `guac_client` after the
+   connection has terminated (`free_handler`). If your plugin will allocate any
+   data at all, implementing the free handler is necessary to avoid memory leaks.
+
+If `guac_client_init` returns successfully, guacd will proceed with allowing
+the first use to join the connection, and the rest of the plugin lifecycle
+commences.
+
+(libguac-lifecycle-users)=
+
+### Joining/leaving a connection
+
+Whenever a user joins a connection, including the very first user of a
+connection (the user which is establishing the remote desktop connection in the
+first place), the join handler of the `guac_client` will be invoked. This
+handler is provided with the `guac_user` structure representing the user that
+just joined, along with the arguments provided during the handshake procedure:
+
+```c
+int join_handler(guac_user* user, int argc, char** argv) {
+    /* Synchronize display state, init the user, etc. */
+}
+
+...
+
+/* Within guac_client_init  */
+client->join_handler = join_handler;
+```
+
+As the parameters and user information provided during the Guacamole protocol
+handshake are often required to be known before the remote desktop connection
+can be established, the join handler is usually the best place to create a
+thread which establishes the remote desktop connection and updates the display
+accordingly.
+
+If necessary, the user which first established the connection can be
+distinguished from all other users by the owner flag of `guac_user`, which will
+be set to a non-zero value.
+
+Once a user has disconnected, the leave handler of `guac_client` will be
+invoked. Just as with the join handler, this handler is provided the
+`guac_user` structure of the user that disconnected. The `guac_user` structure
+will be freed immediately after the handler completes:
+
+```c
+int leave_handler(guac_user* user) {
+    /* Free user-specific data and clean up */
+}
+
+...
+
+/* Within guac_client_init  */
+client->leave_handler = leave_handler;
+```
+
+(libguac-lifecycle-termination)=
+
+### Termination
+
+Once the last user of a connection has left, guacd will begin freeing resources
+allocated to that connection, invoking the free handler of the `guac_client`.
+At this point, the "leave" handler has been invoked for all previous users. All
+that remains is for the client plugin to free any remaining data that it
+allocated, such that guacd can clean up the rest:
+
+```c
+int free_handler(guac_client* client) {
+    /* Disconnect, free client-specific data, etc. */
+}
+
+...
+
+/* Within guac_client_init  */
+client->free_handler = free_handler;
+```
+
+(libguac-layers)=
+
+Layers and buffers
+------------------
+
+The main operand of all drawing instructions is the layer, represented within
+libguac by the `guac_layer` structure. Each `guac_layer` is normally allocated
+using `guac_client_alloc_layer()` or `guac_client_alloc_buffer()`, depending on
+whether a layer or buffer is desired, and freed with `guac_client_free_layer()`
+or `guac_client_free_buffer()`.
+
+:::{important}
+Care must be taken to invoke the allocate and free pairs of each type of layer
+correctly. `guac_client_free_layer()` should only be used to free layers
+allocated with `guac_client_alloc_layer()`, and `guac_client_free_buffer()`
+should only be used to free layers allocated with `guac_client_alloc_buffer()`,
+all called using the same instance of `guac_client`.
+
+If these restrictions are not observed, the effect of invoking these functions
+is undefined.
+:::
+
+Using these layer management functions allows you to reuse existing layers or
+buffers after their original purpose has expired, thus conserving resources on
+the client side, as allocation of new layers within the remote client is a
+relatively expensive operation.
+
+It is through layers and buffers that Guacamole provides support for
+hardware-accelerated compositing and cached updates. Creative use of layers and
+buffers leads to efficient updates on the client side, which usually translates
+into speed and responsiveness.
+
+Regardless of whether you allocate new layers or buffers, there is always one
+layer guaranteed to be present: the default layer, represented by libguac as
+`GUAC_DEFAULT_LAYER`. If you only wish to affect to the main display of the

Review comment:
       ..._to affect to_? Sounds a little odd to me, but could just be ignorance on my part of ways to use the word _affect_.

##########
File path: src/guacamole-docker.md
##########
@@ -0,0 +1,707 @@
+Installing Guacamole with Docker
+================================
+
+Guacamole can be deployed using Docker, removing the need to build
+guacamole-server from source or configure the web application manually.  The
+Guacamole project provides officially-supported Docker images for both
+Guacamole and guacd which are kept up-to-date with each release.
+
+A typical Docker deployment of Guacamole will involve three separate
+containers, linked together at creation time:
+
+`guacamole/guacd`
+: Provides the guacd daemon, built from the released guacamole-server source
+  with support for VNC, RDP, SSH, telnet, and Kubernetes.
+
+`guacamole/guacamole`
+: Provides the Guacamole web application running within Tomcat 8 with support
+  for WebSocket. The configuration necessary to connect to guacd, MySQL,
+  PostgreSQL, LDAP, etc. will be generated automatically when the image starts
+  based on Docker links or environment variables.
+
+`mysql` or `postgresql`
+: Provides the database that Guacamole will use for authentication and storage
+  of connection configuration data.
+
+This separation is important, as it facilitates upgrades and maintains proper
+separation of concerns. With the database separate from Guacamole and guacd,
+those containers can be freely destroyed and recreated at will. The only
+container which must persist data through upgrades is the database.
+
+(guacd-docker-image)=
+
+Running the guacd Docker image
+------------------------------
+
+The guacd Docker image is built from the released guacamole-server source with
+support for VNC, RDP, SSH, telnet, and Kubernetes. Common pitfalls like
+installing the required dependencies, installing fonts for SSH, telnet, or
+Kubernetes, and ensuring the FreeRDP plugins are installed to the correct
+location are all taken care of. It will simply just work.
+
+(guacd-docker-guacamole)=
+
+### Running guacd for use by the Guacamole Docker image
+
+When running the guacd image with the intent of linking to a Guacamole
+container, no ports need be exposed on the network. Access to these ports will
+be handled automatically by Docker during linking, and the Guacamole image will
+properly detect and configure the connection to guacd.
+
+```console
+$ docker run --name some-guacd -d guacamole/guacd
+```
+When run in this manner, guacd will be listening on its default port 4822, but
+this port will only be available to Docker containers that have been explicitly
+linked to `some-guacd`.
+
+The log level of guacd can be controlled with the `GUACD_LOG_LEVEL` environment
+variable. The default value is `info`, and can be set to any of the valid
+settings for the guacd log flag (-L).
+
+```console
+$ docker run -e GUACD_LOG_LEVEL=debug -d guacamole/guacd
+```
+
+(guacd-docker-external)=
+
+### Running guacd for use by services outside Docker
+
+If you are not going to use the Guacamole image, you can still leverage the
+guacd image for ease of installation and maintenance. By exposing the guacd
+port, 4822, services external to Docker will be able to access guacd.
+
+:::{important}
+*Take great care when doing this* - guacd is a passive proxy and does not
+perform any kind of authentication.
+
+If you do not properly isolate guacd from untrusted parts of your network,
+malicious users may be able to use guacd as a jumping point to other systems.
+:::
+
+```console
+$ docker run --name some-guacd -d -p 4822:4822 guacamole/guacd
+```
+
+guacd will now be listening on port 4822, and Docker will expose this port on
+the same server hosting Docker. Other services, such as an instance of Tomcat
+running outside of Docker, will be able to connect to guacd directly.
+
+(guacamole-docker-image)=
+
+The Guacamole Docker image
+--------------------------
+
+The Guacamole Docker image is built on top of a standard Tomcat 8 image and
+takes care of all configuration automatically. The configuration information
+required for guacd and the various authentication mechanisms are specified with
+environment variables or Docker links given when the container is created.
+
+:::{important}
+If using [PostgreSQL](guacamole-docker-postgresql) or [MySQL](guacamole-docker-mysql)
+for authentication, *you will need to initialize the database manually*.
+Guacamole will not automatically create its own tables, but SQL scripts are
+provided to do this.
+:::
+
+Once the Guacamole image is running, Guacamole will be accessible at
+{samp}`http://{HOSTNAME}:8080/guacamole/`, where `HOSTNAME` is the hostname or
+address of the machine hosting Docker.
+
+(guacamole-docker-config-via-env)=
+
+### Configuring Guacamole when using Docker
+
+When running Guacamole using Docker, the traditional approach to configuring
+Guacamole by editing `guacamole.properties` is less convenient. When using
+Docker, you may wish to make use of the `enable-environment-properties`
+configuration property, which allows you to specify values for arbitrary
+Guacamole configuration properties using environment variables. This is covered
+in [](configuring-guacamole).
+
+(guacamole-docker-guacd)=
+
+### Connecting Guacamole to guacd
+
+The Guacamole Docker image needs to be able to connect to guacd to establish
+remote desktop connections, just like any other Guacamole deployment. The
+connection information needed by Guacamole will be provided either via a Docker
+link or through environment variables.
+
+If you will be using Docker to provide guacd, and you wish to use a Docker link
+to connect the Guacamole image to guacd, the connection details are implied by
+the Docker link:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+If you are not using Docker to provide guacd, you will need to provide the
+network connection information yourself using additional environment variables:
+
+`GUACD_HOSTNAME`
+: The hostname of the guacd instance to use to establish remote desktop
+  connections. *This is required if you are not using Docker to provide guacd.*
+
+`GUACD_POST`
+: The port that Guacamole should use when connecting to guacd. This environment
+  variable is optional. If not provided, the standard guacd port of 4822 will
+  be used.
+
+The `GUACD_HOSTNAME` and, if necessary, `GUACD_PORT` environment variables can
+thus be used in place of a Docker link if using a Docker link is impossible or
+undesirable:
+
+```console
+$ docker run --name some-guacamole \
+    -e GUACD_HOSTNAME=172.17.42.1  \
+    -e GUACD_PORT=4822             \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+*A connection to guacd is not the only thing required for Guacamole to work*;
+some authentication mechanism needs to be configured, as well.
+[MySQL](guacamole-docker-mysql), [PostgreSQL](guacamole-docker-postgresql), and
+[LDAP](guacamole-docker-ldap) are supported for this, and are described in more
+detail in the sections below. If the required configuration options for at
+least one authentication mechanism are not provided, the Guacamole image will
+not be able to start up, and you will see an error.
+
+(guacamole-docker-mysql)=
+
+### MySQL authentication
+
+To use Guacamole with the MySQL authentication backend, you will need either a
+Docker container running the `mysql` image, or network access to a working
+installation of MySQL. The connection to MySQL can be specified using either
+environment variables or a Docker link.
+
+(initializing-guacamole-docker-mysql)=
+
+#### Initializing the MySQL database
+
+If your database is not already initialized with the Guacamole schema, you will
+need to do so prior to using Guacamole. A convenience script for generating the
+necessary SQL to do this is included in the Guacamole image.
+
+To generate a SQL script which can be used to initialize a fresh MySQL database
+as documented in [](jdbc-auth):
+
+```console
+$ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
+```
+
+Alternatively, you can use the SQL scripts included with the database
+authentication.
+
+Once this script is generated, you must:
+
+1. Create a database for Guacamole within MySQL, such as `guacamole_db`.
+
+2. Create a user for Guacamole within MySQL with access to this database, such
+   as `guacamole_user`.
+
+3. Run the script on the newly-created database.
+
+The process for doing this via the {command}`mysql` utility included with MySQL
+is documented [](jdbc-auth).
+
+(guacamole-docker-mysql-connecting)=
+
+#### Connecting Guacamole to MySQL
+
+If your MySQL database is provided by another Docker container, and you wish to
+use a Docker link to connect the Guacamole image to your database, the
+connection details are implied by the Docker link itself:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    --link some-mysql:mysql        \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+If you are not using Docker to provide your MySQL database, you will need to
+provide the network connection information yourself using additional
+environment variables:
+
+`MYSQL_HOSTNAME`
+: The hostname of the database to use for Guacamole authentication. *This is
+  required if you are not using Docker to provide your MySQL database.*
+
+`MYSQL_PORT`
+: The port that Guacamole should use when connecting to MySQL. This environment
+  variable is optional. If not provided, the standard MySQL port of 3306 will
+  be used.
+
+The `MYSQL_HOSTNAME` and, if necessary, `MYSQL_PORT` environment variables can
+thus be used in place of a Docker link if using a Docker link is impossible or
+undesirable:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    -e MYSQL_HOSTNAME=172.17.42.1  \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+Note that a Docker link to guacd (the `--link some-guacd:guacd` option above)
+is not required any more than a Docker link is required for MySQL. The
+connection information for guacd can be specified using environment variables,
+as described in [](guacamole-docker-guacd).
+
+(guacamole-docker-mysql-required-vars)=
+
+#### Required environment variables
+
+Using MySQL for authentication requires additional configuration parameters
+specified via environment variables. These variables collectively describe how
+Guacamole will connect to MySQL:
+
+`MYSQL_DATABASE`
+: The name of the database to use for Guacamole authentication.
+
+`MYSQL_USER`
+: The user that Guacamole will use to connect to MySQL.
+
+`MYSQL_PASSWORD`
+: The password that Guacamole will provide when connecting to MySQL as
+  `MYSQL_USER`.
+
+If any required environment variables are omitted, you will receive an error
+message in the logs, and the image will stop. You will then need to recreate
+the container with the proper variables specified.
+
+(guacamole-docker-mysql-optional-vars)=
+
+#### Optional environment variables
+
+Additional optional environment variables may be used to override Guacamole's
+default behavior with respect to concurrent connection use by one or more
+users. Concurrent use of connections and connection groups can be limited to an
+overall maximum and/or a per-user maximum:
+
+
+`MYSQL_ABSOLUTE_MAX_CONNECTIONS`
+: The absolute maximum number of concurrent connections to allow at any time,
+  regardless of the Guacamole connection or user involved. If set to "0", this
+  will be unlimited. Because this limit applies across all Guacamole
+  connections, it cannot be overridden if set.
+
+  *By default, the absolute total number of concurrent connections is unlimited
+  ("0").*
+
+`MYSQL_DEFAULT_MAX_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection. If set to "0", this will be unlimited. This can be overridden on
+  a per-connection basis when editing a connection.
+
+  *By default, overall concurrent use of connections is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_GROUP_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection group. If set to "0", this will be unlimited.  This can be
+  overridden on a per-group basis when editing a connection group.
+
+  *By default, overall concurrent use of connection groups is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection. If set to "0", this will be
+  unlimited. This can be overridden on a per-connection basis when editing a
+  connection.
+
+  *By default, per-user concurrent use of connections is unlimited ("0").*
+
+`MYSQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection group. If set to "0", this will be
+  unlimited. This can be overridden on a per-group basis when editing a
+  connection group.
+
+  *By default, per-user concurrent use of connection groups is limited to one
+  ("1")*, to prevent a balancing connection group from being completely
+  exhausted by one user alone.
+
+`MYSQL_AUTO_CREATE_ACCOUNTS`
+: Whether or not accounts that do not exist in the MySQL database will be
+  automatically created when successfully authenticated through other modules.
+  If set to "true" accounts will be automatically created. Otherwise, and by
+  default, accounts will not be automatically created and will need to be
+  manually created in order for permissions within the MySQL database extension
+  to be assigned to users authenticated with other modules.
+
+(guacamole-docker-postgresql)=
+
+### PostgreSQL authentication
+
+To use Guacamole with the PostgreSQL authentication backend, you will
+need either a Docker container running the `postgres` image, or
+network access to a working installation of PostgreSQL. The connection
+to PostgreSQL can be specified using either environment variables or a
+Docker link.
+
+(initializing-guacamole-docker-postgresql)=
+
+#### Initializing the PostgreSQL database
+
+If your database is not already initialized with the Guacamole schema, you will
+need to do so prior to using Guacamole. A convenience script for generating the
+necessary SQL to do this is included in the Guacamole image.
+
+To generate a SQL script which can be used to initialize a fresh PostgreSQL
+database as documented in [](jdbc-auth):
+
+```console
+$ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgres > initdb.sql
+```
+
+Alternatively, you can use the SQL scripts included with the database
+authentication.
+
+Once this script is generated, you must:
+
+1. Create a database for Guacamole within PostgreSQL, such as
+   `guacamole_db`.
+
+2. Run the script on the newly-created database.
+
+3. Create a user for Guacamole within PostgreSQL with access to the tables and
+   sequences of this database, such as `guacamole_user`.
+
+The process for doing this via the {command}`psql` and {command}`createdb`
+utilities included with PostgreSQL is documented in [](jdbc-auth).
+
+(guacamole-docker-postgresql-connecting)=
+
+#### Connecting Guacamole to PostgreSQL
+
+If your PostgreSQL database is provided by another Docker container, and you
+wish to use a Docker link to connect the Guacamole image to your database, the
+connection details are implied by the Docker link itself:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    --link some-postgres:postgres  \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+If you are not using Docker to provide your PostgreSQL database, you will need
+to provide the network connection information yourself using additional
+environment variables:
+
+`POSTGRES_HOSTNAME`
+: The hostname of the database to use for Guacamole authentication. *This is
+  required if you are not using Docker to provide your PostgreSQL database.*
+
+`POSTGRES_PORT`
+: The port that Guacamole should use when connecting to PostgreSQL. This
+  environment variable is optional. If not provided, the standard PostgreSQL
+  port of 5432 will be used.
+
+The `POSTGRES_HOSTNAME` and, if necessary, `POSTGRES_PORT` environment
+variables can thus be used in place of a Docker link if using a Docker link is
+impossible or undesirable:
+
+```console
+$ docker run --name some-guacamole   \
+    --link some-guacd:guacd          \
+    -e POSTGRES_HOSTNAME=172.17.42.1 \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+Note that a Docker link to guacd (the `--link some-guacd:guacd` option above)
+is not required any more than a Docker link is required for PostgreSQL. The
+connection information for guacd can be specified using environment variables,
+as described in [](guacamole-docker-guacd).
+
+(guacamole-docker-postgresql-required-vars)=
+
+#### Required environment variables
+
+Using PostgreSQL for authentication requires additional configuration
+parameters specified via environment variables. These variables collectively
+describe how Guacamole will connect to PostgreSQL:
+
+`POSTGRES_DATABASE`
+: The name of the database to use for Guacamole authentication.
+
+`POSTGRES_USER`
+: The user that Guacamole will use to connect to PostgreSQL.
+
+`POSTGRES_PASSWORD`
+: The password that Guacamole will provide when connecting to PostgreSQL as
+  `POSTGRES_USER`.
+
+If any required environment variables are omitted, you will receive an
+error message in the logs, and the image will stop. You will then need
+to recreate the container with the proper variables specified.
+
+(guacamole-docker-postgresql-optional-vars)=
+
+#### Optional environment variables
+
+Additional optional environment variables may be used to override Guacamole's
+default behavior with respect to concurrent connection use by one or more
+users. Concurrent use of connections and connection groups can be limited to an
+overall maximum and/or a per-user maximum:
+
+`POSTGRES_ABSOLUTE_MAX_CONNECTIONS`
+: The absolute maximum number of concurrent connections to allow at any time,
+  regardless of the Guacamole connection or user involved. If set to "0", this
+  will be unlimited. Because this limit applies across all Guacamole
+  connections, it cannot be overridden if set.
+
+  *By default, the absolute total number of concurrent connections is unlimited
+  ("0").*
+
+`POSTGRES_DEFAULT_MAX_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection. If set to "0", this will be unlimited. This can be overridden on
+  a per-connection basis when editing a connection.
+
+  *By default, overall concurrent use of connections is unlimited ("0").*
+
+`POSTGRES_DEFAULT_MAX_GROUP_CONNECTIONS`
+: The maximum number of concurrent connections to allow to any one Guacamole
+  connection group. If set to "0", this will be unlimited.  This can be
+  overridden on a per-group basis when editing a connection group.
+
+  *By default, overall concurrent use of connection groups is unlimited ("0").*
+
+`POSTGRES_DEFAULT_MAX_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection. If set to "0", this will be
+  unlimited. This can be overridden on a per-connection basis when editing a
+  connection.
+
+  *By default, per-user concurrent use of connections is unlimited ("0").*
+
+`POSTGRES_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER`
+: The maximum number of concurrent connections to allow a single user to
+  maintain to any one Guacamole connection group. If set to "0", this will be
+  unlimited. This can be overridden on a per-group basis when editing a
+  connection group.
+
+  *By default, per-user concurrent use of connection groups is limited to one
+  ("1")*, to prevent a balancing connection group from being completely
+  exhausted by one user alone.
+
+`POSTGRES_AUTO_CREATE_ACCOUNTS`
+: Whether or not accounts that do not exist in the PostgreSQL database will be
+  automatically created when successfully authenticated through other modules.
+  If set to "true", accounts will be automatically created. Otherwise, and by
+  default, accounts will not be automatically created and will need to be
+  manually created in order for permissions within the PostgreSQL database
+  extension to be assigned to users authenticated with other modules.
+
+Optional environment variables may also be used to override Guacamole's default
+behavior with respect to timeouts at the database and network level:
+
+`POSTGRES_DEFAULT_STATEMENT_TIMEOUT`
+: The number of seconds the driver will wait for a response from the database,
+  before aborting the query. A value of 0 (the default) means the timeout is
+  disabled.
+
+`POSTGRES_SOCKET_TIMEOUT`
+: The number of seconds to wait for socket read operations. If reading from the
+  server takes longer than this value, the connection will be closed. This can
+  be used to handle network problems such as a dropped connection to the
+  database. Similar to `POSTGRES_DEFAULT_STATEMENT_TIMEOUT`, it will also abort
+  queries that take too long. A value of 0 (the default) means the timeout is
+  disabled.
+
+(guacamole-docker-ldap)=
+
+### LDAP authentication
+
+To use Guacamole with the LDAP authentication backend, you will need network
+access to an LDAP directory. Unlike MySQL and PostgreSQL, the Guacamole Docker
+image does not support Docker links for LDAP; the connection information *must*
+be specified using environment variables:
+
+
+`LDAP_HOSTNAME`
+: The hostname or IP address of your LDAP server.
+
+`LDAP_PORT`
+: The port your LDAP server listens on. By default, this will be 389 for
+  unencrypted LDAP or LDAP using STARTTLS, and 636 for LDAP over SSL (LDAPS).
+
+`LDAP_ENCRYPTION_METHOD`
+: The encryption mechanism that Guacamole should use when communicating with
+  your LDAP server. Legal values are "none" for unencrypted LDAP, "ssl" for
+  LDAP over SSL/TLS (commonly known as LDAPS), or "starttls" for STARTTLS. If
+  omitted, encryption will not be used.
+
+Only the `LDAP_HOSTNAME` variable is required, but you may also need to specify
+`LDAP_PORT` or `LDAP_ENCRYPTION_METHOD` if your LDAP directory uses encryption
+or listens on a non-standard port:
+
+```console
+$ docker run --name some-guacamole \
+    --link some-guacd:guacd        \
+    -e LDAP_HOSTNAME=172.17.42.1   \
+    ...
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+Note that a Docker link to guacd (the `--link some-guacd:guacd` option above)
+is not required.  Similar to LDAP, the connection information for guacd can be
+specified using environment variables, as described in [](guacamole-docker-guacd).
+
+(guacamole-docker-ldap-required-vars)=
+
+#### Required environment variables
+
+Using LDAP for authentication requires additional configuration parameters
+specified via environment variables. These variables collectively describe how
+Guacamole will query your LDAP directory:
+
+`LDAP_USER_BASE_DN`
+: The base of the DN for all Guacamole users. All Guacamole users that will be
+  authenticating against LDAP must be descendents of this base DN.
+
+As with the other authentication mechanisms, if any required environment
+variables are omitted (including those required for connecting to the LDAP
+directory over the network), you will receive an error message in the logs, and
+the image will stop. You will then need to recreate the container with the
+proper variables specified.
+
+(guacamole-docker-ldap-optional-vars)=
+
+#### Optional environment variables
+
+Additional optional environment variables may be used to configure the details
+of your LDAP directory hierarchy, or to enable more flexible searching for user
+accounts:
+
+`LDAP_GROUP_BASE_DN`
+: The base of the DN for all groups that may be referenced within Guacamole
+  configurations using the standard seeAlso attribute. All groups which will be
+  used to control access to Guacamole configurations must be descendents of
+  this base DN. *If this variable is omitted, the seeAlso attribute will have
+  no effect on Guacamole configurations.*
+
+`LDAP_SEARCH_BIND_DN`
+: The DN (Distinguished Name) of the user to bind as when authenticating users
+  that are attempting to log in. If specified, Guacamole will query the LDAP
+  directory to determine the DN of each user that logs in. If omitted, each
+  user's DN will be derived directly using the base DN specified with
+  `LDAP_USER_BASE_DN`.
+
+`LDAP_SEARCH_BIND_PASSWORD`
+: The password to provide to the LDAP server when binding as
+  `LDAP_SEARCH_BIND_DN` to authenticate other users. This variable is only
+  used if `LDAP_SEARCH_BIND_DN` is specified. If omitted, but
+  `LDAP_SEARCH_BIND_DN` is specified, Guacamole will attempt to bind with the
+  LDAP server without a password.
+
+`LDAP_USERNAME_ATTRIBUTE`
+: The attribute or attributes which contain the username within all Guacamole
+  user objects in the LDAP directory. Usually, and by default, this will simply
+  be "uid". If your LDAP directory contains users whose usernames are dictated
+  by different attributes, multiple attributes can be specified here, separated
+  by commas, but beware: *doing so requires that a search DN be provided with
+  `LDAP_SEARCH_BIND_DN`*.
+
+`LDAP_CONFIG_BASE_DN`
+: The base of the DN for all Guacamole configurations. If omitted, the
+  configurations of Guacamole connections will simply not be queried from the
+  LDAP directory, and you will need to store them elsewhere, such as within a
+  MySQL or PostgreSQL database.
+
+As documented in [](ldap-auth), Guacamole does support combining LDAP with a
+MySQL or PostgreSQL database, and this can be configured with the Guacamole
+Docker image, as well. Each of these authentication mechanisms is independently
+configurable using their respective environment variables, and by providing the
+required environment variables for multiple systems, Guacamole will
+automatically be configured to use each when the Docker image starts.
+
+(guacamole-docker-header-auth)=
+
+### Header Authentication
+
+The header authentication extension can be used to authenticate Guacamole
+through a trusted third-party server, where the authenticated user's username
+is passed back to Guacamole via a specific HTTP header. The following are
+valid Docker variables for enabling and configuring header authentication:
+
+`HEADER_ENABLED`
+: Enables authentication via the header extension, which causes the extension
+  to be loaded when Guacamole starts. By default this is false and the header
+  extension will not be loaded.
+
+`HTTP_AUTH_HEADER`
+: Optional environment variable that, if set, configures the name of the HTTP
+  header that will be used used to authenticate the user to Guacamole. If this
+  is not specified the default value of REMOTE_USER will be used.
+
+(guacamole-docker-guacamole-home)=
+
+### Custom extensions and `GUACAMOLE_HOME`
+
+If you have your own or third-party extensions for Guacamole which are not
+supported by the Guacamole Docker image, but are compatible with the version of
+Guacamole within the image, you can still use them by providing a custom base
+configuration using the `GUACAMOLE_HOME` environment variable:
+
+`GUACAMOLE_HOME`
+: The absolute path to the directory within the Docker container to use *as a
+  template* for the image's automatically-generated [`GUACAMOLE_HOME`](guacamole-home).
+  Any configuration generated by the Guacamole Docker image based on other
+  environment variables will be applied to an independent copy of the contents
+  of this directory.
+
+You will *still* need to follow the steps required to create the contents of
+[`GUACAMOLE_HOME`](guacamole-home) specific to your extension (placing the
+extension itself within `GUACAMOLE_HOME/extensions/`, adding any properties to
+`guacamole.properties`, etc.), but the rest of Guacamole's configuration will
+be handled automatically, overlaid on top of a copy of the `GUACAMOLE_HOME` you
+provide.
+
+Because the Docker image's `GUACAMOLE_HOME` environment variable must point to
+a directory *within the container*, you will need to expose your custom
+`GUACAMOLE_HOME` to the container using the `-v` option of `docker run`. The
+container directory chosen can then be referenced in the `GUACAMOLE_HOME`
+environment variable, and the image will handle the rest automatically:
+
+```console
+$ docker run --name some-guacamole    \
+    ...
+    -v /local/path:/some-directory   \
+    -e GUACAMOLE_HOME=/some-directory \
+    -d -p 8080:8080 guacamole/guacamole
+```
+
+(verifying-guacamole-docker)=
+
+### Verifying the Guacamole install
+
+Once the Guacamole image is running, Guacamole should be accessible at
+{samp}`http://{HOSTNAME}:8080/guacamole/`, where `HOSTNAME` is the hostname or
+address of the machine hosting Docker, and you *should* a login screen. If

Review comment:
       should _see_ a login screen.

##########
File path: src/jdbc-auth.md
##########
@@ -0,0 +1,1834 @@
+Database authentication
+=======================
+
+Guacamole supports authentication via MySQL, PostgreSQL, or SQL Server
+databases through extensions available from the project website. Using a
+database for authentication provides additional features, such as the ability
+to use load balancing groups of connections and a web-based administrative
+interface. Unlike the default, XML-driven authentication module, all changes to
+users and connections take effect immediately; users need not logout and back
+in to see new connections.
+
+While most authentication extensions function independently, the database
+authentication can act in a subordinate role, allowing users and user groups
+from other authentication extensions to be associated with connections within
+the database. Users and groups are considered identical to those within the
+database if they have the same names, and the authentication result of another
+extension will be trusted if it succeeds. A user with an account under multiple
+systems will thus be able to see data from each system after successfully
+logging in. For more information on using the database authentication alongside
+other mechanisms, see [](ldap-and-database) within [](ldap-auth).
+
+To use the database authentication extension, you will need:
+
+1. A supported database - currently MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+2. Sufficient permission to create new databases, to create new users, and to
+   grant those users permissions.
+
+3. Network access to the database from the Guacamole server.
+
+:::{important}
+This chapter involves modifying the contents of `GUACAMOLE_HOME` - the
+Guacamole configuration directory. If you are unsure where `GUACAMOLE_HOME` is
+located on your system, please consult [](configuring-guacamole) before
+proceeding.
+:::
+
+Downloading the database authentication extension
+-------------------------------------------------
+
+The database authentication extension is available separately from the main
+`guacamole.war`. The link for this and all other officially-supported and
+compatible extensions for a particular version of Guacamole are provided on the
+release notes for that version. You can find the release notes for current
+versions of Guacamole here: <http://guacamole.apache.org/releases/>.
+
+The database authentication extension is packaged as a `.tar.gz` file
+containing several database-specific directories. Only one of the directories
+within the archive will be applicable to you, depending on whether you are
+using MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+Each database-specific directory contains a `schema/` directory and `.jar` file
+(the actual Guacamole extension). The Guacamole extension `.jar` will
+ultimately need to be placed within `GUACAMOLE_HOME/extensions`, while the JDBC
+driver must be downloaded separately from the database vendor and placed within
+`GUACAMOLE_HOME/lib`.
+
+::::{tab} MySQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `mysql/guacamole-auth-jdbc-mysql-1.3.0.jar`
+* - SQL schema scripts
+  - `mysql/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following MySQL-compatible JDBC drivers are supported for connecting Guacamole with MySQL or MariaDB:
+
+* [MySQL Connector/J](http://dev.mysql.com/downloads/connector/j/)
+* [MariaDB Connector/J](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+
+If using the JDBC driver from MySQL, the required `.jar` will be within a
+`.tar.gz` archive.
+::::
+
+::::{tab} PostgreSQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `postgresql/guacamole-auth-jdbc-postgresql-1.3.0.jar`
+* - SQL schema scripts
+  - `postgresql/schema/`
+* - JDBC driver
+  - [PostgreSQL JDBC Driver](https://jdbc.postgresql.org/download.html#current)
+:::
+::::
+
+::::{tab} SQL Server
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `sqlserver/guacamole-auth-jdbc-sqlserver-1.3.0.jar`
+* - SQL schema scripts
+  - `sqlserver/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following TDS-compatible JDBC drivers are supported for connecting
+Guacamole to SQL Server:
+
+* [Microsoft JDBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server)
+* [jTDS](http://jtds.sourceforge.net/)
+* [Progress DataDirect’s JDBC Driver for SQL Server](https://www.progress.com/jdbc/microsoft-sql-server)
+* Microsoft SQL Server 2000 JDBC Driver (legacy)
+::::
+
+(jdbc-auth-database-creation)=
+
+Creating the Guacamole database
+-------------------------------
+
+The database authentication module will need a database to store
+authentication data and a user to use only for data access and
+manipulation. You can use an existing database and existing user, but
+for the sake of simplicity and security, these instructions assume you
+will be creating a new database and new user that will be used only by
+Guacamole and only for this authentication module.
+
+You need MariaDB, MySQL, PostgreSQL, or SQL Server installed, and must
+have sufficient access to create and administer databases. If this is
+not the case, install your database of choice now. Most distributions
+will provide a convenient MySQL or PostgreSQL package which will set up
+everything for you, including the root database user, if applicable. If
+you're using SQL Server, you need to install the packages on your
+platform of choice, and also make sure that you obtain the proper
+licensing for the version and edition of SQL Server you are running.
+
+For the sake of clarity, these instructions will refer to the database
+as "guacamole_db", but the database can be named whatever you like.
+
+:::{tab} MySQL
+```console
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql  upgrade
+$ cat schema/*.sql | mysql -u root -p guacamole_db
+Enter password: password
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ createdb guacamole_db
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql
+$ cat schema/*.sql | psql -d guacamole_db -f -
+CREATE TYPE
+CREATE TYPE
+CREATE TYPE
+CREATE TABLE
+CREATE INDEX
+...
+INSERT 0 1
+INSERT 0 4
+INSERT 0 3
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/001-create-schema.sql
+Password: password
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/002-create-admin-user.sql
+Password: password
+
+(1 rows affected)
+
+(3 rows affected)
+
+(5 rows affected)
+```
+:::
+
+Upgrading an existing Guacamole database
+----------------------------------------
+
+If you are upgrading from an older version of Guacamole, you may need to run
+one or more database schema upgrade scripts located within the
+`schema/upgrade/` directory. Each of these scripts is named
+{samp}`upgrade-pre-{VERSION}.sql` where `VERSION` is the version of Guacamole
+where those changes were introduced. They need to be run when you are upgrading
+from a version of Guacamole older than `VERSION`.
+
+If there are no {samp}`upgrade-pre-{VERSION}.sql` scripts present in the
+`schema/upgrade/` directory which apply to your existing Guacamole database,
+then the schema has not changed between your version and the version your are
+installing, and there is no need to run any database upgrade scripts.
+
+These scripts are incremental and, when relevant, *must be run in order*. For
+example, if you are upgrading an existing database from version
+0.9.13-incubating to version 1.0.0, you would need to run the
+`upgrade-pre-0.9.14.sql` script (because 0.9.13-incubating is older than
+0.9.14), followed by the `upgrade-pre-1.0.0.sql` script (because
+0.9.13-incubating is also older than 1.0.0).
+
+:::{important}
+Because the permissions granted to the Guacamole-specific PostgreSQL user when
+the database was first created will not automatically be granted for any new
+tables and sequences, you will also need to re-grant those permissions after
+applying any upgrade relevant scripts:
+
+```
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+Granting Guacamole access to the database
+-----------------------------------------
+
+For Guacamole to be able to execute queries against the database, you must
+create a new user for the database and grant that user sufficient privileges to
+manage the contents of all tables in the database. The user created for
+Guacamole needs only `SELECT`, `UPDATE`, `INSERT`, and `DELETE` permissions on
+all Guacamole tables.  Additionally, if using PostgreSQL, the user will need
+`SELECT` and `USAGE` permission on all sequences within all Guacamole tables.
+*No other permissions should be granted.*
+
+These instructions will refer to the user as "guacamole_user" but the user can
+be named whatever you like. Naturally, you should also choose a real password
+for your user rather than the string "some_password" used as a placeholder
+below.
+
+:::{tab} MySQL
+```console
+$ mysql -u root -p
+Enter password: password
+Welcome to the MySQL monitor.  Commands end with ; or \g.
+Your MySQL connection id is 233
+Server version: 5.5.29-0ubuntu0.12.10.1 (Ubuntu)
+
+Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+
+Oracle is a registered trademark of Oracle Corporation and/or its
+affiliates. Other names may be trademarks of their respective
+owners.
+
+Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
+
+mysql> CREATE DATABASE guacamole_db;
+Query OK, 1 row affected (0.00 sec)
+
+mysql> CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'some_password';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> FLUSH PRIVILEGES;
+Query OK, 0 rows affected (0.02 sec)
+
+mysql> quit
+Bye
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# CREATE USER guacamole_user WITH PASSWORD 'some_password';
+CREATE ROLE
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA
+Password: password
+1> CREATE DATABASE guacamole_db;
+2> GO
+1> CREATE LOGIN guacamole_user WITH PASSWORD = 'some_password';
+2> GO
+1> USE guacamole_db;
+2> GO
+1> CREATE USER guacamole_user;
+2> GO
+1> ALTER ROLE db_datawriter ADD MEMBER guacamole_user;
+2> ALTER ROLE db_datareader ADD MEMBER guacamole_user;
+3> GO
+```
+:::
+
+(jdbc-auth-installation)=
+
+Installing database authentication
+----------------------------------
+
+Guacamole extensions are self-contained `.jar` files which are located within
+the `GUACAMOLE_HOME/extensions` directory. To install the database
+authentication extension, you must:
+
+1. Create the `GUACAMOLE_HOME/extensions` directory, if it does not already
+   exist.
+
+2. Copy `guacamole-auth-jdbc-mysql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-postgresql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-sqlserver-1.3.0.jar` within
+   `GUACAMOLE_HOME/extensions`, depending on whether you are using
+   MySQL/MariaDB, PostgreSQL, or SQL Server.
+
+3. Copy the JDBC driver for your database to `GUACAMOLE_HOME/lib`. Without a
+   JDBC driver for your database, Guacamole will not be able to connect and
+   authenticate users.
+
+4. Configure Guacamole to use database authentication, as described below.
+
+:::{important}
+You will need to restart Guacamole by restarting your servlet container in
+order to complete the installation. Doing this will disconnect all active
+users, so be sure that it is safe to do so prior to attempting installation. If
+you do not configure the database authentication properly, Guacamole will not
+start up again until the configuration is fixed.

Review comment:
       It's kind of implied, here, but it might be worth mentioning more explicitly that the configuration should be done prior to restarting the servlet container.

##########
File path: src/jdbc-auth.md
##########
@@ -0,0 +1,1834 @@
+Database authentication
+=======================
+
+Guacamole supports authentication via MySQL, PostgreSQL, or SQL Server
+databases through extensions available from the project website. Using a
+database for authentication provides additional features, such as the ability
+to use load balancing groups of connections and a web-based administrative
+interface. Unlike the default, XML-driven authentication module, all changes to
+users and connections take effect immediately; users need not logout and back
+in to see new connections.
+
+While most authentication extensions function independently, the database
+authentication can act in a subordinate role, allowing users and user groups
+from other authentication extensions to be associated with connections within
+the database. Users and groups are considered identical to those within the
+database if they have the same names, and the authentication result of another
+extension will be trusted if it succeeds. A user with an account under multiple
+systems will thus be able to see data from each system after successfully
+logging in. For more information on using the database authentication alongside
+other mechanisms, see [](ldap-and-database) within [](ldap-auth).
+
+To use the database authentication extension, you will need:
+
+1. A supported database - currently MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+2. Sufficient permission to create new databases, to create new users, and to
+   grant those users permissions.
+
+3. Network access to the database from the Guacamole server.
+
+:::{important}
+This chapter involves modifying the contents of `GUACAMOLE_HOME` - the
+Guacamole configuration directory. If you are unsure where `GUACAMOLE_HOME` is
+located on your system, please consult [](configuring-guacamole) before
+proceeding.
+:::
+
+Downloading the database authentication extension
+-------------------------------------------------
+
+The database authentication extension is available separately from the main
+`guacamole.war`. The link for this and all other officially-supported and
+compatible extensions for a particular version of Guacamole are provided on the
+release notes for that version. You can find the release notes for current
+versions of Guacamole here: <http://guacamole.apache.org/releases/>.
+
+The database authentication extension is packaged as a `.tar.gz` file
+containing several database-specific directories. Only one of the directories
+within the archive will be applicable to you, depending on whether you are
+using MariaDB, MySQL, PostgreSQL, or SQL Server.
+
+Each database-specific directory contains a `schema/` directory and `.jar` file
+(the actual Guacamole extension). The Guacamole extension `.jar` will
+ultimately need to be placed within `GUACAMOLE_HOME/extensions`, while the JDBC
+driver must be downloaded separately from the database vendor and placed within
+`GUACAMOLE_HOME/lib`.
+
+::::{tab} MySQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `mysql/guacamole-auth-jdbc-mysql-1.3.0.jar`
+* - SQL schema scripts
+  - `mysql/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following MySQL-compatible JDBC drivers are supported for connecting Guacamole with MySQL or MariaDB:
+
+* [MySQL Connector/J](http://dev.mysql.com/downloads/connector/j/)
+* [MariaDB Connector/J](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+
+If using the JDBC driver from MySQL, the required `.jar` will be within a
+`.tar.gz` archive.
+::::
+
+::::{tab} PostgreSQL
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `postgresql/guacamole-auth-jdbc-postgresql-1.3.0.jar`
+* - SQL schema scripts
+  - `postgresql/schema/`
+* - JDBC driver
+  - [PostgreSQL JDBC Driver](https://jdbc.postgresql.org/download.html#current)
+:::
+::::
+
+::::{tab} SQL Server
+:::{list-table}
+:stub-columns: 1
+* - Guacamole extension
+  - `sqlserver/guacamole-auth-jdbc-sqlserver-1.3.0.jar`
+* - SQL schema scripts
+  - `sqlserver/schema/`
+* - JDBC driver
+  - *See below*
+:::
+
+Any of the following TDS-compatible JDBC drivers are supported for connecting
+Guacamole to SQL Server:
+
+* [Microsoft JDBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server)
+* [jTDS](http://jtds.sourceforge.net/)
+* [Progress DataDirect’s JDBC Driver for SQL Server](https://www.progress.com/jdbc/microsoft-sql-server)
+* Microsoft SQL Server 2000 JDBC Driver (legacy)
+::::
+
+(jdbc-auth-database-creation)=
+
+Creating the Guacamole database
+-------------------------------
+
+The database authentication module will need a database to store
+authentication data and a user to use only for data access and
+manipulation. You can use an existing database and existing user, but
+for the sake of simplicity and security, these instructions assume you
+will be creating a new database and new user that will be used only by
+Guacamole and only for this authentication module.
+
+You need MariaDB, MySQL, PostgreSQL, or SQL Server installed, and must
+have sufficient access to create and administer databases. If this is
+not the case, install your database of choice now. Most distributions
+will provide a convenient MySQL or PostgreSQL package which will set up
+everything for you, including the root database user, if applicable. If
+you're using SQL Server, you need to install the packages on your
+platform of choice, and also make sure that you obtain the proper
+licensing for the version and edition of SQL Server you are running.
+
+For the sake of clarity, these instructions will refer to the database
+as "guacamole_db", but the database can be named whatever you like.
+
+:::{tab} MySQL
+```console
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql  upgrade
+$ cat schema/*.sql | mysql -u root -p guacamole_db
+Enter password: password
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ createdb guacamole_db
+$ ls schema/
+001-create-schema.sql  002-create-admin-user.sql
+$ cat schema/*.sql | psql -d guacamole_db -f -
+CREATE TYPE
+CREATE TYPE
+CREATE TYPE
+CREATE TABLE
+CREATE INDEX
+...
+INSERT 0 1
+INSERT 0 4
+INSERT 0 3
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/001-create-schema.sql
+Password: password
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d guacamole_db -i schema/002-create-admin-user.sql
+Password: password
+
+(1 rows affected)
+
+(3 rows affected)
+
+(5 rows affected)
+```
+:::
+
+Upgrading an existing Guacamole database
+----------------------------------------
+
+If you are upgrading from an older version of Guacamole, you may need to run
+one or more database schema upgrade scripts located within the
+`schema/upgrade/` directory. Each of these scripts is named
+{samp}`upgrade-pre-{VERSION}.sql` where `VERSION` is the version of Guacamole
+where those changes were introduced. They need to be run when you are upgrading
+from a version of Guacamole older than `VERSION`.
+
+If there are no {samp}`upgrade-pre-{VERSION}.sql` scripts present in the
+`schema/upgrade/` directory which apply to your existing Guacamole database,
+then the schema has not changed between your version and the version your are
+installing, and there is no need to run any database upgrade scripts.
+
+These scripts are incremental and, when relevant, *must be run in order*. For
+example, if you are upgrading an existing database from version
+0.9.13-incubating to version 1.0.0, you would need to run the
+`upgrade-pre-0.9.14.sql` script (because 0.9.13-incubating is older than
+0.9.14), followed by the `upgrade-pre-1.0.0.sql` script (because
+0.9.13-incubating is also older than 1.0.0).
+
+:::{important}
+Because the permissions granted to the Guacamole-specific PostgreSQL user when
+the database was first created will not automatically be granted for any new
+tables and sequences, you will also need to re-grant those permissions after
+applying any upgrade relevant scripts:
+
+```
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+Granting Guacamole access to the database
+-----------------------------------------
+
+For Guacamole to be able to execute queries against the database, you must
+create a new user for the database and grant that user sufficient privileges to
+manage the contents of all tables in the database. The user created for
+Guacamole needs only `SELECT`, `UPDATE`, `INSERT`, and `DELETE` permissions on
+all Guacamole tables.  Additionally, if using PostgreSQL, the user will need
+`SELECT` and `USAGE` permission on all sequences within all Guacamole tables.
+*No other permissions should be granted.*
+
+These instructions will refer to the user as "guacamole_user" but the user can
+be named whatever you like. Naturally, you should also choose a real password
+for your user rather than the string "some_password" used as a placeholder
+below.
+
+:::{tab} MySQL
+```console
+$ mysql -u root -p
+Enter password: password
+Welcome to the MySQL monitor.  Commands end with ; or \g.
+Your MySQL connection id is 233
+Server version: 5.5.29-0ubuntu0.12.10.1 (Ubuntu)
+
+Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+
+Oracle is a registered trademark of Oracle Corporation and/or its
+affiliates. Other names may be trademarks of their respective
+owners.
+
+Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
+
+mysql> CREATE DATABASE guacamole_db;
+Query OK, 1 row affected (0.00 sec)
+
+mysql> CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'some_password';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql> FLUSH PRIVILEGES;
+Query OK, 0 rows affected (0.02 sec)
+
+mysql> quit
+Bye
+$
+```
+:::
+
+:::{tab} PostgreSQL
+```console
+$ psql -d guacamole_db
+psql (9.3.6)
+Type "help" for help.
+
+guacamole=# CREATE USER guacamole_user WITH PASSWORD 'some_password';
+CREATE ROLE
+guacamole=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;
+GRANT
+guacamole=# \q
+$
+```
+:::
+
+:::{tab} SQL Server
+```console
+$ /opt/mssql-tools/bin/sqlcmd -S localhost -U SA
+Password: password
+1> CREATE DATABASE guacamole_db;
+2> GO
+1> CREATE LOGIN guacamole_user WITH PASSWORD = 'some_password';
+2> GO
+1> USE guacamole_db;
+2> GO
+1> CREATE USER guacamole_user;
+2> GO
+1> ALTER ROLE db_datawriter ADD MEMBER guacamole_user;
+2> ALTER ROLE db_datareader ADD MEMBER guacamole_user;
+3> GO
+```
+:::
+
+(jdbc-auth-installation)=
+
+Installing database authentication
+----------------------------------
+
+Guacamole extensions are self-contained `.jar` files which are located within
+the `GUACAMOLE_HOME/extensions` directory. To install the database
+authentication extension, you must:
+
+1. Create the `GUACAMOLE_HOME/extensions` directory, if it does not already
+   exist.
+
+2. Copy `guacamole-auth-jdbc-mysql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-postgresql-1.3.0.jar` *or*
+   `guacamole-auth-jdbc-sqlserver-1.3.0.jar` within
+   `GUACAMOLE_HOME/extensions`, depending on whether you are using
+   MySQL/MariaDB, PostgreSQL, or SQL Server.
+
+3. Copy the JDBC driver for your database to `GUACAMOLE_HOME/lib`. Without a
+   JDBC driver for your database, Guacamole will not be able to connect and
+   authenticate users.
+
+4. Configure Guacamole to use database authentication, as described below.
+
+:::{important}
+You will need to restart Guacamole by restarting your servlet container in
+order to complete the installation. Doing this will disconnect all active
+users, so be sure that it is safe to do so prior to attempting installation. If
+you do not configure the database authentication properly, Guacamole will not
+start up again until the configuration is fixed.
+:::
+
+(jdbc-auth-configuration)=
+
+### Configuring Guacamole for database authentication
+
+Additional properties must be added to `guacamole.properties` for Guacamole to
+properly connect to your database. These properties are specific to the
+database being used, and must be set correctly for authentication to work.
+
+The properties absolutely required by the database authentication extension are
+relatively few and self-explanatory, describing only how the connection to the
+database is to be established, and how Guacamole will authenticate when
+querying the database:
+
+:::{tab} MySQL
+`mysql-hostname`
+: The hostname or IP address of the server hosting your database.
+
+`mysql-database`
+: The name of the database that you created for Guacamole. This is given as
+  "guacamole_db" in the examples given in this chapter.
+
+`mysql-username`
+: The username of the user that Guacamole should use to connect to the
+  database.  This is given as "guacamole_user" in the examples given in this
+  chapter.
+
+`mysql-password`
+: The password Guacamole should provide when authenticating with the database.
+  This is given as "some_password" in the examples given in this chapter.
+:::
+
+:::{tab} PostgreSQL
+`postgresql-hostname`
+: The hostname or IP address of the server hosting your database.
+
+`postgresql-database`
+: The name of the database that you created for Guacamole. This is given as
+  "guacamole_db" in the examples given in this chapter.
+
+`postgresql-username`
+: The username of the user that Guacamole should use to connect to the
+  database.  This is given as "guacamole_user" in the examples given in this
+  chapter.
+
+`postgresql-password`
+: The password Guacamole should provide when authenticating with the database.
+  This is given as "some_password" in the examples given in this chapter.
+:::
+
+:::{tab} SQL Server
+`sqlserver-hostname`
+: The hostname or IP address of the server hosting your database.
+
+`sqlserver-database`
+: The name of the database that you created for Guacamole. This is given as
+  "guacamole_db" in the examples given in this chapter.
+
+`sqlserver-username`
+: The username of the user that Guacamole should use to connect to the
+  database.  This is given as "guacamole_user" in the examples given in this
+  chapter.
+
+`sqlserver-password`
+: The password Guacamole should provide when authenticating with the database.
+  This is given as "some_password" in the examples given in this chapter.
+:::
+
+A minimal `guacamole.properties` configured to connect to a locally-hosted
+database would look like the following:
+
+:::{tab} MySQL
+```
+# MySQL properties
+mysql-hostname: localhost
+mysql-database: guacamole_db
+mysql-username: guacamole_user
+mysql-password: some_password
+```
+:::
+
+:::{tab} PostgreSQL
+```
+# PostgreSQL properties
+postgresql-hostname: localhost
+postgresql-database: guacamole_db
+postgresql-username: guacamole_user
+postgresql-password: some_password
+```
+:::
+
+:::{tab} SQL Server
+```
+# SQL Server properties
+sqlserver-hostname: localhost
+sqlserver-database: guacamole_db
+sqlserver-username: guacamole_user
+sqlserver-password: some_password
+```
+:::
+
+:::{important}
+Be sure to specify the correct username and password for the database user you
+created, and to specify the correct database. Authentication will not work if
+these parameters are not correct.
+:::
+
+Additional optional properties are available to control how Guacamole connects
+to the database server:
+
+:::{tab} MySQL
+`mysql-port`
+: The port number of the MySQL or MariaDB database to connect to. If not
+  specified, the standard MySQL / MariaDB port 3306 will be used.
+
+`mysql-driver`
+: Controls which JDBC driver the extension attempts to load and its
+  compatibility with various target database implementations. The extension
+  currently supports the following values for the `mysql-driver` property:
+
+  mysql
+  : The MySQL JDBC driver, known as Connector/J. This is the default.
+
+  mariadb
+  : The MariaDB JDBC driver.
+
+`mysql-server-timezone`
+: Specifies the timezone the MySQL server is configured to run in. While the
+  MySQL driver attempts to auto-detect the timezone in use by the server, there
+  are many cases where the timezone provided by the operating system is either
+  unknown by Java, or matches multiple timezones. In these cases MySQL may
+  either complain or refuse the connection unless the timezone is specified as
+  part of the connection. This property allows the timezone of the server to be
+  specified so that the connection can continue and the JDBC driver can
+  properly translate timestamps.  The property accepts timezones in the
+  following formats:
+
+  Region/Locale
+  : Well-known TimeZone Identifiers, in the Region/Locale format. Examples are:
+
+    ```
+    mysql-server-timezone: America/Los_Angeles
+    mysql-server-timezone: Africa/Johannesburg
+    mysql-server-timezone: China/Shanghai
+    ```
+
+   GMT+/-HH:MM
+   : GMT or custom timezones specified by GMT offset. Examples of valid GMT
+     specifications are:
+
+     ```
+     mysql-server-timezone: GMT
+     mysql-server-timezone: GMT-00:00
+     mysql-server-timezone: GMT+0000
+     mysql-server-timezone: GMT-0
+     ```
+
+     Examples of custom timezones specified by GMT offsets are:
+
+     ```
+     mysql-server-timezone: GMT+0130
+     mysql-server-timezone: GMT-0430
+     mysql-server-timezone: GMT+06:00
+     mysql-server-timezone: GMT-9
+     ```
+
+   The MySQL Driver implements several parameters specific to
+   configuring SSL for secure connections to MySQL servers that support
+   or require encrypted communications. *Older versions of MySQL
+   Connector/J have known issues with SSL verification - if you
+   experience problems connecting to SSL-secured MySQL databases it is
+   recommended that you update to a current version of the driver.*
+
+`mysql-ssl-mode`
+: This property sets the SSL mode that the JDBC driver will attempt to use when
+  communicating with the remote MySQL server. The values for this property
+  match the standard values supported by the MySQL and MariaDB JDBC drivers:
+
+  disabled
+  : Do not use SSL, and fail if the server requires it. For compatibility this
+    will also set the legacy JDBC driver property useSSL to false.
+
+  preferred
+  : Prefer SSL, but fall back to plain-text if an SSL connection cannot be
+    negotiated. This is the default.
+
+  required
+  : Require SSL connections, and fail if SSL cannot be negotiated. This mode
+    does not perform any validition checks on the certificate in use by the
+    server, the issuer, etc.
+
+  verify-ca
+  : Require SSL connections, and check to make sure that the certificate issuer
+    is known to be valid.
+
+  verify-identity
+  : Require SSL connections, and check to make sure that the server certificate
+    is issued by a known authority, and that the identity of the server
+    matches the identity on the certificate.
+
+`mysql-ssl-trust-store`
+: The file that will store trusted SSL certificates for the JDBC driver to use
+  when validating CA and server certificates. This should be a JKS-formatted
+  certificate store. This property is optional and defaults to Java's normal
+  trusted certificate locations, which vary based on the version of Java in
+  use.
+
+`mysql-ssl-trust-password`
+: The password to use to access the SSL trusted certificate store, if one is
+  required. By default no password will be used.
+
+`mysql-ssl-client-store`
+: The file that contains the client certificate to use when making SSL
+  connections to the MySQL server. This should be a JKS-formatted certificate
+  store that contains a private key and certificate pair. This property is
+  optional, and by default no client certificate will be used for the SSL
+  connection.
+
+`mysql-ssl-client-password`
+: The password to use to access the client certificate store, if one is
+  required. By default no password will be used.
+:::
+
+:::{tab} PostgreSQL
+`postgresql-port`
+: The port number of the PostgreSQL database to connect to. If not specified,
+  the standard PostgreSQL port 5432 will be used.
+
+`postgresql-ssl-mode`
+: This property sets the SSL mode that the JDBC extension will attempt to use
+  when communicating with the remote Postgres server. The values for this
+  property match the standard values supported by the Postgres JDBC driver:
+
+  disable
+  : Do not use SSL, and fail if the server requires it.
+
+  allow
+  : If the server requires encryption use it, otherwise prefer unencrypted
+    connections.
+
+  prefer
+  : Try SSL connections, first, but allow unencrypted connections if the server
+    does not support SSL or if SSL negotiations fail. This is the
+    default.
+
+  require
+  : Require SSL connections, but implicitly trust all server certificates and
+    authorities.
+
+  verify-ca
+  : Require SSL connections, and verify that the server certificate is issued
+    by a known certificate authority.
+
+  verify-full
+  : Require SSL connections, verifying that the server certificate is issued
+    by a known authority, and that the name on the certificate matches the name of
+    the server.
+
+`postgresql-ssl-cert-file`
+: The file containing the client certificate to be used when making an
+  SSL-encrtyped connection to the Postgres server, in PEM format. This property
+  is optional, and will be ignored if the SSL mode is set to disable.
+
+`postgresql-ssl-key-file`
+: The file containing the client private key to be used when making an
+  SSL-encrypted connection to the Postgres server, in PEM format. This property
+  is optional, and will be ignore if the SSL mode is set to disable.

Review comment:
       *ignored




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org