| <?xml version="1.0" encoding="UTF-8"?> |
| <chapter xml:id="guacamole-common" xmlns="http://docbook.org/ns/docbook" |
| version="5.0" xml:lang="en" xmlns:xl="http://www.w3.org/1999/xlink" |
| xmlns:xi="http://www.w3.org/2001/XInclude"> |
| <title><package>guacamole-common</package></title> |
| <indexterm> |
| <primary>API</primary> |
| <secondary>Java</secondary> |
| </indexterm> |
| <indexterm> |
| <primary><package>guacamole-common</package></primary> |
| </indexterm> |
| <para>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.</para> |
| <section xml:id="java-http-tunnel"> |
| <title>HTTP tunnel</title> |
| <para>The Guacamole Java API implements the HTTP tunnel using a servlet |
| called <classname>GuacamoleHTTPTunnelServlet</classname>. 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 |
| <methodname>doConnect()</methodname>, |
| <methodname>doRead()</methodname>, and |
| <methodname>doWrite()</methodname> functions accordingly.</para> |
| <para>Normally, you wouldn't touch the <methodname>doRead()</methodname> |
| and <methodname>doWrite()</methodname> 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.</para> |
| <para>When developing an application based on the Guacamole API, you |
| should use <classname>GuacamoleHTTPTunnelServlet</classname> by |
| extending it, implementing your own version of |
| <methodname>doConnect()</methodname>, 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, <methodname>doConnect()</methodname> is |
| an excellent place for authentication or other validation, as it is |
| the responsibility of <methodname>doConnect()</methodname> to create |
| (or not create) the actual tunnel. If |
| <methodname>doConnect()</methodname> 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.</para> |
| <para>The <methodname>doConnect()</methodname> function is expected to return a new |
| <classname>GuacamoleTunnel</classname>, but it is completely up to the |
| implementation to decide how that tunnel is to be created. The already-implemented parts |
| of <classname>GuacamoleHTTPTunnelServlet</classname> 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.</para> |
| <para>Instances of <classname>GuacamoleTunnel</classname> are created associated with a |
| <classname>GuacamoleSocket</classname>, which is the abstract interface surrounding |
| the low-level connection to guacd. Overall, there is a socket |
| (<classname>GuacamoleSocket</classname>) which provides a TCP connection to guacd. |
| This socket is exposed to <classname>GuacamoleTunnel</classname>, which provides |
| abstract protocol access around what is actually (but secretly, through the abstraction |
| of the API) a TCP socket.</para> |
| <para>The Guacamole web application extends this tunnel servlet in order |
| to implement authentication at the lowest possible level, |
| effectively prohibiting communication between the client and any |
| remote desktops unless they have properly authenticated. Your own |
| implementation can be considerably simpler, especially if you don't |
| need authentication:</para> |
| <informalexample> |
| <programlisting>public class MyGuacamoleTunnelServlet |
| extends GuacamoleHTTPTunnelServlet { |
| |
| @Override |
| protected GuacamoleTunnel doConnect(HttpServletRequest request) |
| throws GuacamoleException { |
| |
| // Connect to guacd here (this is a STUB) |
| GuacamoleSocket socket; |
| |
| // Return a new tunnel which uses the connected socket |
| return new SimpleGuacamoleTunnel(socket); |
| |
| } |
| |
| }</programlisting> |
| </informalexample> |
| </section> |
| <section xml:id="java-protocol-usage"> |
| <title>Using the Guacamole protocol</title> |
| <para>guacamole-common provides basic low-level support for the |
| Guacamole protocol. This low-level support is leveraged by the HTTP |
| tunnel implementation to satisfy the requirements of the JavaScript |
| client implementation, as the JavaScript client expects the |
| handshake procedure to have already taken place. This support exists |
| through the <classname>GuacamoleReader</classname> and |
| <classname>GuacamoleWriter</classname> classes, which are |
| similar to Java's <classname>Reader</classname> and |
| <classname>Writer</classname> classes, except that they deal |
| with the Guacamole protocol specifically, and thus have slightly |
| different contracts.</para> |
| <section xml:id="java-reading-protocol"> |
| <title><classname>GuacamoleReader</classname></title> |
| <para><classname>GuacamoleReader</classname> provides a very basic |
| <methodname>read()</methodname> function which is required |
| to return one or more complete instructions in a |
| <type>char</type> array. It also provides the typical |
| <methodname>available()</methodname> function, which informs |
| you whether <methodname>read()</methodname> is likely to block |
| the next time it is called, and an even more abstract version of |
| <methodname>read()</methodname> called |
| <methodname>readInstruction()</methodname> which returns one |
| instruction at a time, wrapped within a |
| <classname>GuacamoleInstruction</classname> instance.</para> |
| <para>Normally, you would not need to use this class yourself. It is |
| used by <classname>ConfiguredGuacamoleSocket</classname> to |
| complete the Guacamole protocol handshake procedure, and it is |
| used by <classname>GuacamoleHTTPTunnelServlet</classname> within |
| <methodname>doRead()</methodname> to implement the reading |
| half of the tunnel.</para> |
| <para>The only concrete implementation of |
| <classname>GuacamoleReader</classname> is |
| <classname>ReaderGuacamoleReader</classname>, which wraps a |
| Java <classname>Reader</classname>, using that as the source for |
| data to parse into Guacamole instructions. Again, you would not |
| normally directly use this class, nor instantiate it yourself. A |
| working, concrete instance of |
| <classname>GuacamoleReader</classname> can be retrieved from |
| any <classname>GuacamoleSocket</classname> or |
| <classname>GuacamoleTunnel</classname>.</para> |
| </section> |
| <section xml:id="java-writing-protocol"> |
| <title><classname>GuacamoleWriter</classname></title> |
| <para><classname>GuacamoleWriter</classname> provides a very basic |
| <methodname>write()</methodname> function and a more |
| abstract version called |
| <methodname>writeInstruction()</methodname> which writes |
| instances of <classname>GuacamoleInstruction</classname>. These |
| functions are analogous to the <methodname>read()</methodname> |
| and <methodname>readInstruction()</methodname> functions |
| provided by <classname>GuacamoleReader</classname>, and have |
| similar restrictions: the contract imposed by |
| <methodname>write()</methodname> requires that written |
| instructions be complete</para> |
| <para>The only concrete implementation of |
| <classname>GuacamoleWriter</classname> is |
| <classname>WriterGuacamoleWriter</classname>, which wraps a |
| Java <classname>Writer</classname>, using that as the |
| destination for Guacamole instruction data, but you would not |
| normally directly use this class, nor instantiate it yourself. |
| It is used by <classname>ConfiguredGuacamoleSocket</classname> |
| to complete the Guacamole protocol handshake procedure, and it |
| is used by <classname>GuacamoleHTTPTunnelServlet</classname> |
| within <methodname>doWrite()</methodname> to implement the |
| writing half of the tunnel.</para> |
| <para>If necessary, a <classname>GuacamoleWriter</classname> can be |
| retrieved from any <classname>GuacamoleSocket</classname> or |
| <classname>GuacamoleTunnel</classname>, but in most cases, |
| the classes provided by the Guacamole Java API which already use |
| <classname>GuacamoleWriter</classname> will be |
| sufficient.</para> |
| </section> |
| </section> |
| </chapter> |