<?xml version="1.0" encoding="UTF-8"?>

<chapter xml:id="custom-auth" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"
    xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>Custom authentication</title>
    <indexterm xmlns:xl="http://www.w3.org/1999/xlink">
        <primary>authentication</primary>
        <secondary>custom</secondary>
    </indexterm>
    <para>Guacamole's authentication layer is designed to be extendable such that users can
        integrate Guacamole into existing authentication systems without having to resort to writing
        their own web application around the Guacamole API.</para>
    <para>The web application comes with a default authentication mechanism which uses an XML file
        to associate users with connections. Extensions for Guacamole that provide LDAP-based
        authentication or database-based authentication have also been developed.</para>
    <para>To demonstrate the principles involved, we will implement a very simple authentication
        extension which associates a single user/password pair with a single connection, with all
        this information saved in properties inside the <filename>guacamole.properties</filename>
        file.</para>
    <para>In general, all other authentication extensions for Guacamole will use the principles
        demonstrated here. This tutorial demonstrates the simplest way to create an authentication
        extension for Guacamole - an authentication extension that does not support management of
        users and connections via the web interface.</para>
    <section xml:id="custom-auth-model">
        <title>Guacamole's authentication model</title>
        <para>When you view any page in Guacamole, whether that be the login screen or the client
            interface, the page makes an authentication attempt with the web application, sending
            all available credentials. After entering your username and password, the exact same
            process occurs, except the web application receives the username and password as
            well.</para>
        <para>The web application handles this authentication attempt by collecting all credentials
            available and passing them to designated classes called "authentication providers".
            Given the set of credentials, authentication providers return a context object that
            provides restricted access to other users and connections, if any.</para>
    </section>
    <section xml:id="custom-auth-skeleton">
        <title>A Guacamole extension skeleton</title>
        <para>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.</para>
        <para>The bare minimum required for a Guacamole authentication extension is a
                <filename>pom.xml</filename> file listing guacamole-ext as a dependency, a single
            .java file implementing our stub of an authentication provider, and a
                <filename>guac-manifest.json</filename> file describing the extension and pointing
            to our authentication provider class.</para>
        <para>In our stub, we won't actually do any authentication yet; we'll just universally
            reject all authentication attempts by returning <varname>null</varname> for any
            credentials given. You can verify that this is what happens by checking the server
            logs.</para>
        <example>
            <title>Barebones <filename>pom.xml</filename> required for a simple authentication
                extension.</title>
            <programlisting>&lt;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">

    &lt;modelVersion>4.0.0&lt;/modelVersion>
    &lt;groupId>org.apache.guacamole&lt;/groupId>
    &lt;artifactId>guacamole-auth-tutorial&lt;/artifactId>
    &lt;packaging>jar&lt;/packaging>
    &lt;version>1.1.0&lt;/version>
    &lt;name>guacamole-auth-tutorial&lt;/name>

    &lt;properties>
        &lt;project.build.sourceEncoding>UTF-8&lt;/project.build.sourceEncoding>
    &lt;/properties>

    &lt;build>
        &lt;plugins>

            &lt;!-- Written for 1.6 -->
            &lt;plugin>
                &lt;groupId>org.apache.maven.plugins&lt;/groupId>
                &lt;artifactId>maven-compiler-plugin&lt;/artifactId>
                &lt;version>3.3&lt;/version>
                &lt;configuration>
                    &lt;source>1.6&lt;/source>
                    &lt;target>1.6&lt;/target>
                &lt;/configuration>
            &lt;/plugin>

        &lt;/plugins>
    &lt;/build>

    &lt;dependencies>

        &lt;!-- Guacamole Extension API -->
        &lt;dependency>
            &lt;groupId>org.apache.guacamole&lt;/groupId>
            &lt;artifactId>guacamole-ext&lt;/artifactId>
            &lt;version>1.1.0&lt;/version>
            &lt;scope>provided&lt;/scope>
        &lt;/dependency>

    &lt;/dependencies>

&lt;/project></programlisting>
        </example>
        <para>We won't need to update this <filename>pom.xml</filename> throughout the rest of the
            tutorial. Even after adding new files, Maven will just find them and compile as
            necessary.</para>
        <para>Naturally, we need the actual authentication 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
                <classname>org.apache.guacamole.auth.TutorialAuthenticationProvider</classname>.</para>
        <example>
            <title>A skeleton <classname>TutorialAuthenticationProvider</classname></title>
            <programlisting>package org.apache.guacamole.auth;

import java.util.Map;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.simple.SimpleAuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.protocol.GuacamoleConfiguration;

/**
 * Authentication provider implementation intended to demonstrate basic use
 * of Guacamole's extension API. The credentials and connection information for
 * a single user are stored directly in guacamole.properties.
 */
public class TutorialAuthenticationProvider extends SimpleAuthenticationProvider {

    @Override
    public String getIdentifier() {
        return "tutorial";
    }

    @Override
    public Map&lt;String, GuacamoleConfiguration>
        getAuthorizedConfigurations(Credentials credentials)
        throws GuacamoleException {

        // Do nothing ... yet
        return null;        

    }

}</programlisting>
        </example>
        <para>To conform with Maven, this skeleton file must be placed within
                <filename>src/main/java/org/apache/guacamole/auth</filename> as
                <filename>TutorialAuthenticationProvider.java</filename>.</para>
        <para>Notice how simple the authentication provider is. The
                <classname>SimpleAuthenticationProvider</classname> base class simplifies the
                <classname>AuthenticationProvider</classname> interface, requiring nothing more than
            a unique identifier (we will use "tutorial") and a single
                <methodname>getAuthorizedConfigurations()</methodname> implementation, which must
            return a <classname>Map</classname> of <classname>GuacamoleConfiguration</classname>
            each associated with some arbitrary unique ID. This unique ID will be presented to the
            user in the connection list after they log in.</para>
        <para>For now, <methodname>getAuthorizedConfigurations()</methodname> will just return
                <varname>null</varname>. This will cause Guacamole to report an invalid login for
            every attempt. Note that there is a difference in semantics between returning an empty
            map and returning <varname>null</varname>, as the former indicates the credentials are
            authorized but simply have no associated configurations, while the latter indicates the
            credentials are not authorized at all.</para>
        <para>The only remaining piece for the overall skeleton to be complete is a
                <filename>guac-manifest.json</filename> file. <emphasis>This file is absolutely
                required for all Guacamole extensions.</emphasis> The
                <filename>guac-manifest.json</filename> format is described in more detail in <xref
                xmlns:xlink="http://www.w3.org/1999/xlink" linkend="guacamole-ext"/>. It provides
            for quite a few properties, but for our authentication 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 authentication provider class.</para>
        <para>The Guacamole extension format requires that <filename>guac-manifest.json</filename>
            be placed in the root directory of the extension <filename>.jar</filename> file. To
            accomplish this with Maven, we place it within the
                <filename>src/main/resources</filename> directory. Maven will automatically pick it
            up during the build and include it within the <filename>.jar</filename>.</para>
        <example>
            <title>The required <filename>guac-manifest.json</filename></title>
            <programlisting>{

    "guacamoleVersion" : "1.1.0",

    "name"      : "Tutorial Authentication Extension",
    "namespace" : "guac-auth-tutorial",

    "authProviders" : [
        "org.apache.guacamole.auth.TutorialAuthenticationProvider"
    ]

}</programlisting>
        </example>
    </section>
    <section xml:id="custom-auth-building">
        <title>Building the extension</title>
        <para>Once all three of the above files are in place, the extension will build, and can even
            be installed within Guacamole (see <xref xmlns:xlink="http://www.w3.org/1999/xlink"
                linkend="custom-auth-installing"/> at the end of this chapter), even though it is
            just a skeleton at this point. It won't do anything yet other than reject all
            authentication attempts, but it's good to at least try building the extension to make
            sure nothing is missing and that all steps have been followed correctly so far:</para>
        <informalexample>
            <screen><prompt>$</prompt> mvn package
<computeroutput>[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building guacamole-auth-tutorial 1.1.0
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.345 s
[INFO] Finished at: 2015-12-16T13:39:00-08:00
[INFO] Final Memory: 14M/138M
[INFO] ------------------------------------------------------------------------</computeroutput>
<prompt>$</prompt></screen>
        </informalexample>
        <para>Assuming you see the "<computeroutput>BUILD SUCCESS</computeroutput>" message when you
            build the extension, there will be a new file,
                <filename>target/guacamole-auth-tutorial-1.1.0.jar</filename>, which can be
            installed within Guacamole and tested. If you changed the name or version of the project
            in the <filename>pom.xml</filename> file, the name of this new <filename>.jar</filename>
            file will be different, but it can still be found within
            <filename>target/</filename>.</para>
    </section>
    <section xml:id="custom-auth-config">
        <title>Configuration and authentication</title>
        <para>Once we receive credentials, we need to validate those credentials against the
            associated properties in <filename>guacamole.properties</filename> (our source of
            authentication information for the sake of this tutorial).</para>
        <para>We will define four properties:<variablelist>
                <varlistentry>
                    <term><property>tutorial-user</property></term>
                    <listitem>
                        <para>The name of the only user we accept.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>tutorial-password</property></term>
                    <listitem>
                        <para>The password we require for the user specified to be
                            authenticated.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>tutorial-protocol</property></term>
                    <listitem>
                        <para>The protocol of the configuration this user is authorized to use,
                            which will be sent to guacd when the user logs in and selects their
                            connection.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>tutorial-parameters</property></term>
                    <listitem>
                        <para>A comma-delimited list of
                                    <code><replaceable>name</replaceable>=<replaceable>value</replaceable></code>
                            pairs. For the sake of simplicity, we'll assume there will never be any
                            commas in the values.</para>
                    </listitem>
                </varlistentry>
            </variablelist></para>
        <para>If the username and password match what is stored in the file, we read the
            configuration information, store it in a <classname>GuacamoleConfiguration</classname>,
            and return the configuration within a set, telling Guacamole that this user is
            authorized but only to access the configurations returned.</para>
        <para>Upstream, we always place the properties of authentication providers in their own
            class, and so we will also do that here in this tutorial, as it keeps things
            organized.</para>
        <example>
            <title><filename>TutorialProperties.java</filename>, a class containing property
                definitions</title>
            <programlisting>package org.apache.guacamole.auth;

import org.apache.guacamole.properties.StringGuacamoleProperty;

/**
 * Utility class containing all properties used by the custom authentication
 * tutorial. The properties defined here must be specified within
 * guacamole.properties to configure the tutorial authentication provider.
 */
public class TutorialGuacamoleProperties {

    /**
     * This class should not be instantiated.
     */
    private TutorialGuacamoleProperties() {}

    /**
     * The only user to allow.
     */
    public static final StringGuacamoleProperty TUTORIAL_USER = 
        new StringGuacamoleProperty() {

        @Override
        public String getName() { return "tutorial-user"; }

    };

    /**
     * The password required for the specified user.
     */
    public static final StringGuacamoleProperty TUTORIAL_PASSWORD = 
        new StringGuacamoleProperty() {

        @Override
        public String getName() { return "tutorial-password"; }

    };


    /**
     * The protocol to use when connecting.
     */
    public static final StringGuacamoleProperty TUTORIAL_PROTOCOL = 
        new StringGuacamoleProperty() {

        @Override
        public String getName() { return "tutorial-protocol"; }

    };


    /**
     * All parameters associated with the connection, as a comma-delimited
     * list of name="value" 
     */
    public static final StringGuacamoleProperty TUTORIAL_PARAMETERS = 
        new StringGuacamoleProperty() {

        @Override
        public String getName() { return "tutorial-parameters"; }

    };

}</programlisting>
        </example>
        <para>Normally, we would define a new type of <classname>GuacamoleProperty</classname> to
            handle the parsing of the parameters required by <varname>TUTORIAL_PARAMETERS</varname>,
            but for the sake of simplicity, parsing of this parameter will be embedded in the
            authentication function later.</para>
        <para>You will need to modify your existing <filename>guacamole.properties</filename> file,
            adding each of the above properties to describe one of your available
            connections.</para>
        <example>
            <title>Properties describing a user and connection, as required by this tutorial</title>
            <programlisting># Username and password
tutorial-user:     <replaceable>tutorial</replaceable>
tutorial-password: <replaceable>password</replaceable>

# Connection information
tutorial-protocol:   <replaceable>vnc</replaceable>
tutorial-parameters: <replaceable>hostname=localhost, port=5900</replaceable></programlisting>
        </example>
        <para>Once these properties and their accessor class are in place, it's simple enough to
            read the properties within <methodname>getAuthorizedConfigurations()</methodname> and
            authenticate the user based on their username and password.</para>
        <example>
            <title>Checking the credentials against the properties</title>
            <programlisting>@Override
public Map&lt;String, GuacamoleConfiguration>
    getAuthorizedConfigurations(Credentials credentials)
    throws GuacamoleException {

    // Get the Guacamole server environment
    Environment environment = new LocalEnvironment();

    // Get username from guacamole.properties
    String username = environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_USER
    );      

    // If wrong username, fail
    if (!username.equals(credentials.getUsername()))
        return null;

    // Get password from guacamole.properties
    String password = environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_PASSWORD
    );      

    // If wrong password, fail
    if (!password.equals(credentials.getPassword()))
        return null;

    // Successful login. Return configurations (STUB)
    return new HashMap&lt;String, GuacamoleConfiguration>();

}</programlisting>
        </example>
        <para>As is, the authentication provider will work in its current state in that the correct
            username and password will authenticate the user, while an incorrect username or
            password will not, but we still aren't returning an actual map of configurations. We
            need to construct the configuration based on the properties in the
                <filename>guacamole.properties</filename> file after the user has been
            authenticated, and return that configuration to the web application.</para>
    </section>
    <section xml:id="custom-auth-more-config">
        <title>Parsing the configuration</title>
        <para>The only remaining task before we have a fully-functioning authentication provider is
            to actually parse the configuration from the <filename>guacamole.properties</filename>
            file.</para>
        <example>
            <title>Parsing and returning a <classname>GuacamoleConfiguration</classname></title>
            <programlisting>@Override
public Map&lt;String, GuacamoleConfiguration>
    getAuthorizedConfigurations(Credentials credentials)
    throws GuacamoleException {

    // Get the Guacamole server environment
    Environment environment = new LocalEnvironment();

    // Get username from guacamole.properties
    String username = environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_USER
    );      

    // If wrong username, fail
    if (!username.equals(credentials.getUsername()))
        return null;

    // Get password from guacamole.properties
    String password = environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_PASSWORD
    );      

    // If wrong password, fail
    if (!password.equals(credentials.getPassword()))
        return null;

    // Successful login. Return configurations.
    Map&lt;String, GuacamoleConfiguration> configs = 
        new HashMap&lt;String, GuacamoleConfiguration>();

    // Create new configuration
    GuacamoleConfiguration config = new GuacamoleConfiguration();

    // Set protocol specified in properties
    config.setProtocol(environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_PROTOCOL
    ));

    // Set all parameters, splitting at commas
    for (String parameterValue : environment.getRequiredProperty(
        TutorialGuacamoleProperties.TUTORIAL_PARAMETERS
    ).split(",\\s*")) {

        // Find the equals sign
        int equals = parameterValue.indexOf('=');
        if (equals == -1)
            throw new GuacamoleServerException("Required equals sign missing");

        // Get name and value from parameter string
        String name = parameterValue.substring(0, equals);
        String value = parameterValue.substring(equals+1);

        // Set parameter as specified
        config.setParameter(name, value);

    }

    configs.put("Tutorial Connection", config);
    return configs;

}</programlisting>
        </example>
        <para>The extension is now complete and can be built as described earlier in <xref
                xmlns:xlink="http://www.w3.org/1999/xlink" linkend="custom-auth-building"/>.</para>
    </section>
    <section xml:id="custom-auth-installing">
        <title>Installing the extension</title>
        <para>Guacamole extensions are self-contained <filename>.jar</filename> files which are
            installed by being placed within <filename>GUACAMOLE_HOME/extensions</filename>, and
            this extension is no different. As described in <xref
                xmlns:xlink="http://www.w3.org/1999/xlink" linkend="configuring-guacamole"/>,
                <varname>GUACAMOLE_HOME</varname> is a placeholder used to refer to the directory
            that Guacamole uses to locate its configuration files and extensions. Typically, this
            will be the <filename>.guacamole</filename> directory within the home directory of the
            user running Tomcat.</para>
        <para>To install your extension, ensure that the required properties have been added to your
                <filename>guacamole.properties</filename>, copy the
                <filename>target/guacamole-auth-tutorial-1.1.0.jar</filename> file into
                <filename>GUACAMOLE_HOME/extensions</filename> and restart Tomcat. Guacamole will
            automatically load your extension, logging an informative message that it has done
            so:</para>
        <informalexample>
            <screen>Extension "Tutorial Authentication Extension" loaded.</screen>
        </informalexample>
    </section>
</chapter>
