Partial move to maven build system
authorMichael Jumper <zhangmaike@users.sourceforge.net>
Wed, 8 Dec 2010 09:17:55 +0000 (01:17 -0800)
committerMichael Jumper <zhangmaike@users.sourceforge.net>
Wed, 8 Dec 2010 09:17:55 +0000 (01:17 -0800)
35 files changed:
web-client/ant/build.properties [deleted file]
web-client/build.xml [deleted file]
web-client/guacamole-common/pom.xml [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java [new file with mode: 0644]
web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java [new file with mode: 0644]
web-client/src/net/sourceforge/guacamole/Client.java [deleted file]
web-client/src/net/sourceforge/guacamole/GuacamoleClient.java [deleted file]
web-client/src/net/sourceforge/guacamole/GuacamoleException.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/Configuration.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/GuacamoleConfiguration.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/GuacamoleProperties.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/GuacamoleServlet.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/GuacamoleSession.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/tunnel/Connect.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/tunnel/Inbound.java [deleted file]
web-client/src/net/sourceforge/guacamole/net/tunnel/Outbound.java [deleted file]

diff --git a/web-client/ant/build.properties b/web-client/ant/build.properties
deleted file mode 100644 (file)
index 10b783c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-servlet.api.jar=/usr/share/tomcat6/lib/servlet-api.jar
-
-src.dir=src
-web.dir=web
-
-build.dir=build
-dist.dir=dist
-doc.dir=doc
-
-guac.version=0.3.1rc1
-tar.dir=guacamole-${guac.version}
-tar.src.dir=guacamole-src
-
diff --git a/web-client/build.xml b/web-client/build.xml
deleted file mode 100644 (file)
index 326b7ca..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-
-<project name="guacamole" default="compile" basedir=".">
-
-       <property file="ant/build.properties"/>
-
-       <target name="clean" description="Removes build and dist dirs.">
-               <delete dir="${build.dir}"/>
-               <delete dir="${dist.dir}"/>
-               <delete dir="${tar.dir}"/>
-               <delete dir="${tar.src.dir}"/>
-        <delete file="${tar.dir}.tar.gz"/>
-       </target>
-
-       <target name="init" description="Creates build and dist dirs.">
-               <mkdir dir="${build.dir}"/>
-               <mkdir dir="${build.dir}/WEB-INF/classes"/>
-               <mkdir dir="${dist.dir}"/>
-       </target>
-
-       <target name="compile" description="Compiles Guacamole."
-               depends="init">
-               <copy todir="${build.dir}">
-                       <fileset dir="${web.dir}"/>
-        </copy>
-
-        <!-- Replace __GUAC_VERSION with declared version -->
-        <replace dir="${build.dir}" value="${guac.version}">
-            <include name="**/*.html"/>
-            <replacetoken><![CDATA[__GUAC_VERSION]]></replacetoken>
-        </replace>
-
-               <javac srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes"
-            classpath="${servlet.api.jar}">
-            <compilerarg value="-Xlint:unchecked"/>
-        </javac>
-       </target>
-
-       <target name="war" description="Builds Guacamole .war file."
-               depends="compile">
-               <war destfile="${dist.dir}/guacamole.war"
-                       webxml="${build.dir}/WEB-INF/web.xml">
-            <fileset dir="${build.dir}"/>
-               </war>
-       </target>
-
-    <target name="tar" description="Build distributable .tar.gz file"
-        depends="war">
-        <mkdir dir="${tar.dir}"/>
-
-        <mkdir dir="${tar.src.dir}"/>
-        <copy todir="${tar.src.dir}">
-            <fileset dir=".">
-                <exclude name=".git/**"/>
-                <exclude name="**/.svn"/>
-                <exclude name="${tar.dir}/**"/>
-                <exclude name="${tar.src.dir}/**"/>
-                <exclude name="${dist.dir}/**"/>
-                <exclude name="${build.dir}/**"/>
-            </fileset>
-        </copy>
-        <tar basedir="." includes="${tar.src.dir}/**" destfile="${tar.dir}/${tar.src.dir}.tar" longfile="gnu"/>
-        <delete dir="${tar.src.dir}"/>
-
-        <copy todir="${tar.dir}">
-            <fileset file="${doc.dir}/example/guacamole.properties"/>
-            <fileset file="${doc.dir}/example/user-mapping.xml"/>
-            <fileset file="${dist.dir}/guacamole.war"/>
-            <fileset file="LICENSE.txt"/>
-        </copy>
-
-        <tar basedir="." includes="${tar.dir}/**" destfile="${tar.dir}.tar.gz" compression="gzip" longfile="gnu"/>
-    </target>
-
-</project>
diff --git a/web-client/guacamole-common/pom.xml b/web-client/guacamole-common/pom.xml
new file mode 100644 (file)
index 0000000..ca17143
--- /dev/null
@@ -0,0 +1,18 @@
+<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>net.sourceforge.guacamole</groupId>
+  <artifactId>guacamole-common</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>guacamole-common</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java
new file mode 100644 (file)
index 0000000..e57d479
--- /dev/null
@@ -0,0 +1,30 @@
+
+package net.sourceforge.guacamole;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import net.sourceforge.guacamole.GuacamoleException;
+
+public abstract class Client {
+
+    public abstract void write(char[] chunk, int off, int len) throws GuacamoleException;
+    public abstract char[] read() throws GuacamoleException;
+    public abstract void disconnect() throws GuacamoleException;
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java
new file mode 100644 (file)
index 0000000..f0748d8
--- /dev/null
@@ -0,0 +1,129 @@
+
+package net.sourceforge.guacamole;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.InputStreamReader;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.io.OutputStreamWriter;
+
+import net.sourceforge.guacamole.GuacamoleException;
+
+public class GuacamoleClient extends Client {
+
+    private Socket sock;
+    private Reader input;
+    private Writer output;
+
+    public GuacamoleClient(String hostname, int port) throws GuacamoleException {
+
+        try {
+            sock = new Socket(InetAddress.getByName(hostname), port);
+            input = new InputStreamReader(sock.getInputStream());
+            output = new OutputStreamWriter(sock.getOutputStream());
+        }
+        catch (IOException e) {
+            throw new GuacamoleException(e);
+        }
+
+    }
+
+    public void write(char[] chunk, int off, int len) throws GuacamoleException {
+        try {
+            output.write(chunk, off, len);
+            output.flush();
+        }
+        catch (IOException e) {
+            throw new GuacamoleException(e);
+        }
+    }
+
+    public void disconnect() throws GuacamoleException {
+        try {
+            sock.close();
+        }
+        catch (IOException e) {
+            throw new GuacamoleException(e);
+        }
+    }
+
+    private int usedLength = 0;
+    private char[] buffer = new char[20000];
+
+    public char[] read() throws GuacamoleException {
+
+        try {
+
+            // While we're blocking, or input is available
+            for (;;) {
+
+                // If past threshold, resize buffer before reading
+                if (usedLength > buffer.length/2) {
+                    char[] biggerBuffer = new char[buffer.length*2];
+                    System.arraycopy(buffer, 0, biggerBuffer, 0, usedLength);
+                    buffer = biggerBuffer;
+                }
+
+                // Attempt to fill buffer
+                int numRead = input.read(buffer, usedLength, buffer.length - usedLength);
+                if (numRead == -1)
+                    return null;
+
+                int prevLength = usedLength;
+                usedLength += numRead;
+
+                for (int i=usedLength-1; i>=prevLength; i--) {
+
+                    char readChar = buffer[i];
+
+                    // If end of instruction, return it.
+                    if (readChar == ';') {
+
+                        // Get instruction
+                        char[] chunk = new char[i+1];
+                        System.arraycopy(buffer, 0, chunk, 0, i+1);
+
+                        // Reset buffer
+                        usedLength -= i+1;
+                        System.arraycopy(buffer, i+1, buffer, 0, usedLength);
+
+                        // Return instruction string
+                        return chunk;
+                    }
+
+                }
+
+            } // End read loop
+
+        }
+        catch (IOException e) {
+            throw new GuacamoleException(e);
+        }
+
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java
new file mode 100644 (file)
index 0000000..3a09c5a
--- /dev/null
@@ -0,0 +1,36 @@
+
+package net.sourceforge.guacamole;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class GuacamoleException extends Exception {
+
+    public GuacamoleException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public GuacamoleException(String message) {
+        super(message);
+    }
+
+    public GuacamoleException(Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java
new file mode 100644 (file)
index 0000000..6e78eb2
--- /dev/null
@@ -0,0 +1,129 @@
+
+package net.sourceforge.guacamole.net;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import javax.servlet.ServletContext;
+import net.sourceforge.guacamole.GuacamoleException;
+
+public abstract class Configuration {
+
+    protected String humanReadableList(Object... values) {
+
+        String list = "";
+        for (int i=0; i<values.length; i++) {
+
+            if (i >= 1)
+                list += ", ";
+
+            if (i == values.length -1)
+                list += " or ";
+
+            list += "\"" + values[i] + "\"";
+        }
+
+        return list;
+
+    }
+
+    protected String readParameter(String name) throws GuacamoleException {
+        String value = GuacamoleProperties.getProperty(name);
+        return value;
+    }
+
+    protected String readParameter(String name, String defaultValue, String... allowedValues) throws GuacamoleException {
+
+        String value = GuacamoleProperties.getProperty(name);
+
+        // Use default if not specified
+        if (value == null) {
+            if (defaultValue == null)
+                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
+
+            return defaultValue;
+        }
+
+        // If not restricted to certain values, just return whatever is given.
+        if (allowedValues.length == 0)
+            return value;
+
+        // If restricted, only return value within given list
+        for (String allowedValue : allowedValues)
+            if (value.equals(allowedValue))
+                return value;
+
+        throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
+    }
+
+    protected boolean readBooleanParameter(String name, Boolean defaultValue) throws GuacamoleException {
+
+        String value = GuacamoleProperties.getProperty(name);
+
+        // Use default if not specified
+        if (value == null) {
+            if (defaultValue == null)
+                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
+
+            return defaultValue;
+        }
+
+        value = value.trim();
+        if (value.equals("true"))
+            return true;
+
+        if (value.equals("false"))
+            return false;
+
+        throw new GuacamoleException("Parameter \"" + name + "\" must be \"true\" or \"false\".");
+
+    }
+
+    protected int readIntParameter(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException {
+
+        String parmString = GuacamoleProperties.getProperty(name);
+
+        // Use default if not specified
+        if (parmString== null) {
+            if (defaultValue == null)
+                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
+
+            return defaultValue;
+        }
+
+        try {
+            int value = Integer.parseInt(parmString);
+
+            // If not restricted to certain values, just return whatever is given.
+            if (allowedValues.length == 0)
+                return value;
+
+            // If restricted, only return value within given list
+            for (int allowedValue : allowedValues)
+                if (value == allowedValue)
+                    return value;
+
+            throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
+        }
+        catch (NumberFormatException e) {
+            throw new GuacamoleException("Parameter \"" + name + "\" must be an integer.", e);
+        }
+
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java
new file mode 100644 (file)
index 0000000..a6bfeeb
--- /dev/null
@@ -0,0 +1,80 @@
+
+package net.sourceforge.guacamole.net;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider;
+import java.lang.reflect.InvocationTargetException;
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+
+public class GuacamoleConfiguration extends Configuration {
+
+    private String guacd_hostname;
+    private int guacd_port;
+    private GuacamoleSessionProvider sessionProvider;
+
+    public GuacamoleConfiguration() throws GuacamoleException {
+
+        guacd_hostname       = readParameter("guacd-hostname");
+        guacd_port           = readIntParameter("guacd-port", null);
+
+        // Get session provider instance
+        try {
+            String sessionProviderClassName = readParameter("session-provider");
+            Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance();
+            if (!(obj instanceof GuacamoleSessionProvider))
+                throw new GuacamoleException("Specified session provider class is not a GuacamoleSessionProvider");
+
+            sessionProvider = (GuacamoleSessionProvider) obj;
+        }
+        catch (ClassNotFoundException e) {
+            throw new GuacamoleException("Session provider class not found", e);
+        }
+        catch (NoSuchMethodException e) {
+            throw new GuacamoleException("Default constructor for session provider not present", e);
+        }
+        catch (SecurityException e) {
+            throw new GuacamoleException("Creation of session provider disallowed; check your security settings", e);
+        }
+        catch (InstantiationException e) {
+            throw new GuacamoleException("Unable to instantiate session provider", e);
+        }
+        catch (IllegalAccessException e) {
+            throw new GuacamoleException("Unable to access default constructor of session provider", e);
+        }
+        catch (InvocationTargetException e) {
+            throw new GuacamoleException("Internal error in constructor of session provider", e.getTargetException());
+        }
+
+    }
+
+    public int getProxyPort() {
+        return guacd_port;
+    }
+
+    public String getProxyHostname() {
+        return guacd_hostname;
+    }
+
+    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
+        return sessionProvider.createSession(session);
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java
new file mode 100644 (file)
index 0000000..6c4340d
--- /dev/null
@@ -0,0 +1,55 @@
+
+package net.sourceforge.guacamole.net;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import net.sourceforge.guacamole.GuacamoleException;
+
+public class GuacamoleProperties {
+
+    private static final Properties properties;
+    private static GuacamoleException exception;
+
+    static {
+
+        properties = new Properties();
+
+        try {
+
+            InputStream stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties");
+            if (stream == null)
+                throw new IOException("Resource /guacamole.properties not found.");
+
+            properties.load(stream);
+        }
+        catch (IOException e) {
+            exception = new GuacamoleException("Error reading guacamole.properties", e);
+        }
+
+    }
+
+    public static String getProperty(String name) throws GuacamoleException {
+        if (exception != null) throw exception;
+        return properties.getProperty(name);
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java
new file mode 100644 (file)
index 0000000..a1e7131
--- /dev/null
@@ -0,0 +1,83 @@
+
+package net.sourceforge.guacamole.net;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.IOException;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+
+public abstract class GuacamoleServlet extends HttpServlet  {
+
+    private GuacamoleConfiguration config;
+
+    @Override
+    public void init() throws ServletException {
+        try {
+            this.config = new GuacamoleConfiguration();
+        }
+        catch (GuacamoleException e) {
+            throw new ServletException(e);
+        }
+    }
+
+    @Override
+    protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try {
+            handleRequest(req, resp);
+        }
+        catch (GuacamoleException e) {
+            throw new ServletException(e);
+        }
+    }
+
+    @Override
+    protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        try {
+            handleRequest(req, resp);
+        }
+        catch (GuacamoleException e) {
+            throw new ServletException(e);
+        }
+    }
+
+    private final void handleRequest(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
+
+        HttpSession httpSession = request.getSession(shouldCreateSession());
+
+        if (httpSession != null) {
+            GuacamoleSession session = config.createSession(httpSession);
+            handleRequest(session, request, response);
+        }
+        else
+            throw new GuacamoleException("No session");
+    }
+
+    protected abstract void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException;
+
+    protected boolean shouldCreateSession() {
+        return false;
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java
new file mode 100644 (file)
index 0000000..2eb0132
--- /dev/null
@@ -0,0 +1,209 @@
+
+package net.sourceforge.guacamole.net;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.concurrent.locks.ReentrantLock;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import net.sourceforge.guacamole.Client;
+import net.sourceforge.guacamole.GuacamoleClient;
+import net.sourceforge.guacamole.GuacamoleException;
+
+public class GuacamoleSession {
+
+    private GuacamoleConfiguration config;
+    private final HttpSession session;
+    private SessionClient client;
+    private ReentrantLock instructionStreamLock;
+
+    private String protocol;
+    private String hostname;
+    private int port;
+    private String password;
+
+    public class SessionClient extends Client implements HttpSessionBindingListener {
+
+        private Client client;
+        private ReentrantLock authorizedLock;
+
+        public SessionClient(Client client) {
+            this.client = client;
+
+            authorizedLock = new ReentrantLock();
+            authorizedLock.lock();
+        }
+
+        public void authorize() {
+            authorizedLock.unlock();
+        }
+
+        public void waitForAuthorization() {
+            if (authorizedLock.isLocked()) {
+                try {
+                    authorizedLock.lock();
+                    authorizedLock.unlock();
+                }
+                catch (Throwable t) {
+                    throw new Error("Internal error waiting for authorization", t);
+                }
+            }
+        }
+
+        public void valueBound(HttpSessionBindingEvent event) {
+            // Do nothing
+        }
+
+        public void valueUnbound(HttpSessionBindingEvent event) {
+            try {
+                disconnect();
+            }
+            catch (GuacamoleException e) {
+                // Ignore
+            }
+        }
+
+        public void write(char[] data, int off, int len) throws GuacamoleException {
+            client.write(data, off, len);
+        }
+
+        public char[] read() throws GuacamoleException {
+            return client.read();
+        }
+
+        public void disconnect() throws GuacamoleException {
+            client.disconnect();
+        }
+
+    }
+
+    public GuacamoleSession(HttpSession session) throws GuacamoleException {
+
+        if (session == null)
+            throw new GuacamoleException("User has no session.");
+
+        this.session = session;
+        synchronized (session) {
+
+            // Read configuration parameters
+            config = new GuacamoleConfiguration();
+
+            client = (SessionClient) session.getAttribute("CLIENT");
+            instructionStreamLock = (ReentrantLock) session.getAttribute("INSTRUCTION_STREAM_LOCK");
+        }
+    }
+
+    public void connect() throws GuacamoleException {
+        synchronized (session) {
+
+            if (client != null)
+                client.disconnect();
+
+
+            client = new SessionClient(
+                    new GuacamoleClient (
+                        config.getProxyHostname(),
+                        config.getProxyPort()
+                    )
+            );
+
+            session.setAttribute("CLIENT", client);
+
+            instructionStreamLock = new ReentrantLock();
+            session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock);
+
+        }
+    }
+
+    public boolean isConnected() {
+        synchronized (session) {
+            return client != null;
+        }
+    }
+
+    public GuacamoleConfiguration getConfiguration() {
+        return config;
+    }
+
+    public SessionClient getClient() {
+        synchronized (session) {
+            return client;
+        }
+    }
+
+    public void invalidate() {
+        session.invalidate();
+    }
+
+    public void disconnect() throws GuacamoleException {
+        if (client != null) {
+            client.disconnect();
+
+            session.removeAttribute("CLIENT");
+            client = null;
+        }
+    }
+
+    public ReentrantLock getInstructionStreamLock() {
+        return instructionStreamLock;
+    }
+
+    public void setConnection(String protocol, String hostname, int port) {
+        this.protocol = protocol;
+        this.hostname = hostname;
+        this.port = port;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public String getHostname() {
+        return hostname;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getConnectMessage() throws GuacamoleException {
+
+        if (getProtocol() == null)
+            throw new GuacamoleException("Protocol not specified");
+
+        if (getHostname() == null)
+            throw new GuacamoleException("Hostname not specified");
+
+        if (getPassword() == null)
+            return "connect:" + getProtocol() + "," + getHostname() + "," + getPort() + ";";
+        else
+            return "connect:" + getProtocol() + "," + getHostname() + "," + getPort() + "," + getPassword() + ";";
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java
new file mode 100644 (file)
index 0000000..bbe82a2
--- /dev/null
@@ -0,0 +1,30 @@
+
+package net.sourceforge.guacamole.net.authentication;
+
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleSession;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public interface GuacamoleSessionProvider {
+
+    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException;
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java
new file mode 100644 (file)
index 0000000..a46d0fe
--- /dev/null
@@ -0,0 +1,32 @@
+
+package net.sourceforge.guacamole.net.authentication;
+
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleSession;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class NullGuacamoleSessionProvider implements GuacamoleSessionProvider {
+
+    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
+        throw new GuacamoleException("Null provider will not create sessions");
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java
new file mode 100644 (file)
index 0000000..83fcfd3
--- /dev/null
@@ -0,0 +1,318 @@
+
+package net.sourceforge.guacamole.net.authentication.basic;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleProperties;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+public class BasicFileAuthenticationProvider implements BasicLogin.AuthenticationProvider {
+
+    private long mappingTime;
+    private Map<String, AuthInfo> mapping;
+
+    private File getUserMappingFile() throws GuacamoleException {
+
+        // Get user mapping filename
+        String filename = GuacamoleProperties.getProperty("basic-user-mapping");
+        if (filename == null)
+            return null;
+
+        return new File(filename);
+
+    }
+
+    public synchronized void init() throws GuacamoleException {
+
+        // Get user mapping file
+        File mapFile = getUserMappingFile();
+        if (mapFile == null)
+            throw new GuacamoleException("Missing \"basic-user-mapping\" parameter required for basic login.");
+
+        // Parse document
+        try {
+
+            BasicUserMappingContentHandler contentHandler = new BasicUserMappingContentHandler();
+
+            XMLReader parser = XMLReaderFactory.createXMLReader();
+            parser.setContentHandler(contentHandler);
+            parser.parse(mapFile.getAbsolutePath());
+
+            mappingTime = mapFile.lastModified();
+            mapping = contentHandler.getUserMapping();
+
+        }
+        catch (IOException e) {
+            throw new GuacamoleException("Error reading basic user mapping file.", e);
+        }
+        catch (SAXException e) {
+            throw new GuacamoleException("Error parsing basic user mapping XML.", e);
+        }
+
+    }
+
+    @Override
+    public BasicLogin.AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException {
+
+        // Check mapping file mod time
+        File userMappingFile = getUserMappingFile();
+        if (userMappingFile.exists() && mappingTime < userMappingFile.lastModified()) {
+
+            // If modified recently, gain exclusive access and recheck
+            synchronized (this) {
+                if (userMappingFile.exists() && mappingTime < userMappingFile.lastModified())
+                    init(); // If still not up to date, re-init
+            }
+
+        }
+
+        AuthInfo info = mapping.get(username);
+        if (info != null && info.validate(username, password))
+            return new BasicLogin.AuthorizedConfiguration(
+                info.getProtocol(),
+                info.getHostname(),
+                info.getPort(),
+                info.getPassword()
+            );
+
+        return null;
+
+    }
+
+    public static class AuthInfo {
+
+        public static enum Encoding {
+            PLAIN_TEXT,
+            MD5
+        }
+
+        private String auth_username;
+        private String auth_password;
+        private Encoding auth_encoding;
+
+        private String protocol;
+        private String hostname;
+        private int port;
+        private String password;
+
+        public AuthInfo(String auth_username, String auth_password, Encoding auth_encoding) {
+            this.auth_username = auth_username;
+            this.auth_password = auth_password;
+            this.auth_encoding = auth_encoding;
+        }
+
+        private static final char HEX_CHARS[] = {
+            '0', '1', '2', '3', '4', '5', '6', '7',
+            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+        };
+
+        public static String getHexString(byte[] bytes) {
+
+            if (bytes == null)
+                return null;
+
+            StringBuilder hex = new StringBuilder(2 * bytes.length);
+            for (byte b : bytes) {
+                hex.append(HEX_CHARS[(b & 0xF0) >> 4])
+                   .append(HEX_CHARS[(b & 0x0F)     ]);
+            }
+
+            return hex.toString();
+
+        }
+
+
+        public boolean validate(String username, String password) {
+
+            // If username matches
+            if (username != null && password != null && username.equals(auth_username)) {
+
+                switch (auth_encoding) {
+
+                    case PLAIN_TEXT:
+
+                        // Compare plaintext
+                        return password.equals(auth_password);
+
+                    case MD5:
+
+                        // Compare hashed password
+                        try {
+                            MessageDigest digest = MessageDigest.getInstance("MD5");
+                            String hashedPassword = getHexString(digest.digest(password.getBytes()));
+                            return hashedPassword.equals(auth_password.toUpperCase());
+                        }
+                        catch (NoSuchAlgorithmException e) {
+                            throw new UnsupportedOperationException("Unexpected lack of MD5 support.", e);
+                        }
+
+                }
+
+            }
+
+            return false;
+
+        }
+
+        public String getHostname() {
+            return hostname;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public int getPort() {
+            return port;
+        }
+
+        public String getProtocol() {
+            return protocol;
+        }
+
+    }
+
+
+    private static class BasicUserMappingContentHandler extends DefaultHandler {
+
+        private Map<String, AuthInfo> authMapping = new HashMap<String, AuthInfo>();
+
+        public Map<String, AuthInfo> getUserMapping() {
+            return Collections.unmodifiableMap(authMapping);
+        }
+
+        private AuthInfo current;
+
+        private enum AUTH_INFO_STATE {
+            PROTOCOL,
+            HOSTNAME,
+            PORT,
+            PASSWORD
+        };
+
+        private AUTH_INFO_STATE infoState;
+
+        @Override
+        public void endElement(String uri, String localName, String qName) throws SAXException {
+
+            if (localName.equals("authorize")) {
+
+                // Finalize mapping for this user
+                authMapping.put(
+                    current.auth_username,
+                    current
+                );
+
+            }
+
+            infoState = null;
+
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+            if (localName.equals("authorize")) {
+
+                AuthInfo.Encoding encoding;
+                String encodingString = attributes.getValue("encoding");
+                if (encodingString == null)
+                    encoding = AuthInfo.Encoding.PLAIN_TEXT;
+                else if (encodingString.equals("plain"))
+                    encoding = AuthInfo.Encoding.PLAIN_TEXT;
+                else if (encodingString.equals("md5"))
+                    encoding = AuthInfo.Encoding.MD5;
+                else
+                    throw new SAXException("Invalid encoding type");
+
+
+                current = new AuthInfo(
+                    attributes.getValue("username"),
+                    attributes.getValue("password"),
+                    encoding
+                );
+
+                infoState = null;
+
+            }
+
+            else if (localName.equals("protocol"))
+                infoState = AUTH_INFO_STATE.PROTOCOL;
+
+            else if (localName.equals("hostname"))
+                infoState = AUTH_INFO_STATE.HOSTNAME;
+
+            else if (localName.equals("port"))
+                infoState = AUTH_INFO_STATE.PORT;
+
+            else if (localName.equals("password"))
+                infoState = AUTH_INFO_STATE.PASSWORD;
+
+            else
+                infoState = null;
+
+        }
+
+        @Override
+        public void characters(char[] ch, int start, int length) throws SAXException {
+
+            String str = new String(ch, start, length);
+
+            if (infoState == null)
+                return;
+
+            switch (infoState) {
+
+                case PROTOCOL:
+                    current.protocol = str;
+                    break;
+
+                case HOSTNAME:
+                    current.hostname = str;
+                    break;
+
+                case PORT:
+                    current.port = Integer.parseInt(str);
+                    break;
+
+                case PASSWORD:
+                    current.password = str;
+                    break;
+
+            }
+
+        }
+
+
+    }
+
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java
new file mode 100644 (file)
index 0000000..959bf0e
--- /dev/null
@@ -0,0 +1,50 @@
+
+package net.sourceforge.guacamole.net.authentication.basic;
+
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleSession;
+import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class BasicGuacamoleSessionProvider implements GuacamoleSessionProvider {
+
+    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
+
+        // Retrieve authorized config data from session
+        BasicLogin.AuthorizedConfiguration config = (BasicLogin.AuthorizedConfiguration)
+                session.getAttribute("BASIC-LOGIN-AUTH");
+
+        // If no data, not authorized
+        if (config == null)
+            throw new GuacamoleException("Unauthorized");
+
+        // Configure session from authorized config info
+        GuacamoleSession guacSession = new GuacamoleSession(session);
+        guacSession.setConnection(config.getProtocol(), config.getHostname(), config.getPort());
+        if (config.getPassword() != null)
+            guacSession.setPassword(config.getPassword());
+
+        // Return authorized session
+        return guacSession;
+
+    }
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java
new file mode 100644 (file)
index 0000000..43e8721
--- /dev/null
@@ -0,0 +1,161 @@
+
+package net.sourceforge.guacamole.net.authentication.basic;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.Configuration;
+
+public class BasicLogin extends HttpServlet {
+
+    private Config config;
+
+    @Override
+    public void init() throws ServletException {
+        try {
+            config = new Config();
+        }
+        catch (GuacamoleException e) {
+            throw new ServletException(e);
+        }
+    }
+
+
+    private class Config extends Configuration {
+
+        private AuthenticationProvider authProvider;
+
+        public Config() throws GuacamoleException {
+
+            // Get auth provider instance
+            try {
+                String authProviderClassName = readParameter("auth-provider");
+                Object obj = Class.forName(authProviderClassName).getConstructor().newInstance();
+                if (!(obj instanceof AuthenticationProvider))
+                    throw new GuacamoleException("Specified session provider class is not a GuacamoleSessionProvider");
+
+                authProvider = (AuthenticationProvider) obj;
+            }
+            catch (ClassNotFoundException e) {
+                throw new GuacamoleException("Session provider class not found", e);
+            }
+            catch (NoSuchMethodException e) {
+                throw new GuacamoleException("Default constructor for session provider not present", e);
+            }
+            catch (SecurityException e) {
+                throw new GuacamoleException("Creation of session provider disallowed; check your security settings", e);
+            }
+            catch (InstantiationException e) {
+                throw new GuacamoleException("Unable to instantiate session provider", e);
+            }
+            catch (IllegalAccessException e) {
+                throw new GuacamoleException("Unable to access default constructor of session provider", e);
+            }
+            catch (InvocationTargetException e) {
+                throw new GuacamoleException("Internal error in constructor of session provider", e.getTargetException());
+            }
+
+        }
+
+        public AuthenticationProvider getAuthenticationProvider() {
+            return authProvider;
+        }
+
+    }
+
+    public static interface AuthenticationProvider {
+        public AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException;
+    }
+
+    // Added to session when session validated
+    public static class AuthorizedConfiguration {
+
+        private String protocol;
+        private String hostname;
+        private int port;
+        private String password;
+
+        public AuthorizedConfiguration(String protocol, String hostname, int port, String password) {
+            this.protocol = protocol;
+            this.hostname = hostname;
+            this.port = port;
+            this.password = password;
+        }
+
+        public String getHostname() {
+            return hostname;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public int getPort() {
+            return port;
+        }
+
+        public String getProtocol() {
+            return protocol;
+        }
+
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+        // Retrieve username and password from parms
+        String username = req.getParameter("username");
+        String password = req.getParameter("password");
+
+        // Validate username and password
+        try {
+
+            AuthorizedConfiguration info = config.getAuthenticationProvider().getAuthorizedConfiguration(username, password);
+            if (info != null) {
+
+                // Store authorized configuration
+                HttpSession session = req.getSession(true);
+                session.setAttribute(
+                    "BASIC-LOGIN-AUTH",
+                    info
+                );
+
+                // Success
+                return;
+
+            }
+
+            // Report "forbidden" on any failure
+            resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Login invalid");
+        }
+        catch (GuacamoleException e) {
+            throw new ServletException("Error validating credentials", e);
+        }
+
+    }
+
+
+}
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java
new file mode 100644 (file)
index 0000000..79aa94d
--- /dev/null
@@ -0,0 +1,59 @@
+package net.sourceforge.guacamole.net.tunnel;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import net.sourceforge.guacamole.GuacamoleException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import net.sourceforge.guacamole.net.GuacamoleServlet;
+
+import net.sourceforge.guacamole.net.GuacamoleSession;
+
+public class Connect extends GuacamoleServlet {
+
+    @Override
+    protected boolean shouldCreateSession() {
+        return true;
+    }
+
+    @Override
+    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
+
+        // Disconnect if already connected
+        if (session.isConnected())
+            session.disconnect();
+
+        // Obtain new connection
+        session.connect();
+
+        // Send data
+        try {
+            char[] connect = session.getConnectMessage().toCharArray();
+            session.getClient().write(connect, 0, connect.length);
+            session.getClient().authorize();
+        }
+        catch (GuacamoleException e) {
+            throw new GuacamoleException("Error sending data to server: " + e.getMessage(), e);
+        }
+
+    }
+
+}
+
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java
new file mode 100644 (file)
index 0000000..415d639
--- /dev/null
@@ -0,0 +1,59 @@
+package net.sourceforge.guacamole.net.tunnel;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import net.sourceforge.guacamole.GuacamoleException;
+
+import java.io.Reader;
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import net.sourceforge.guacamole.net.GuacamoleServlet;
+
+import net.sourceforge.guacamole.net.GuacamoleSession;
+
+public class Inbound extends GuacamoleServlet {
+
+    @Override
+    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
+        
+        session.getClient().waitForAuthorization();
+
+        // Send data
+        try {
+
+            Reader input = request.getReader();
+            char[] buffer = new char[8192];
+
+            int length;
+            while ((length = input.read(buffer, 0, buffer.length)) != -1)
+                session.getClient().write(buffer, 0, length);
+
+        }
+        catch (IOException e) {
+            throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e);
+        }
+        catch (GuacamoleException e) {
+            throw new GuacamoleException("Error sending data to server: " + e.getMessage(), e);
+        }
+
+    }
+
+}
+
diff --git a/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/web-client/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java
new file mode 100644 (file)
index 0000000..76aa34c
--- /dev/null
@@ -0,0 +1,99 @@
+package net.sourceforge.guacamole.net.tunnel;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.Writer;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import net.sourceforge.guacamole.Client;
+import net.sourceforge.guacamole.net.GuacamoleServlet;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleSession;
+
+
+public class Outbound extends GuacamoleServlet {
+
+    @Override
+    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
+
+        session.getClient().waitForAuthorization();
+
+        ReentrantLock instructionStreamLock = session.getInstructionStreamLock();
+        instructionStreamLock.lock();
+
+        try {
+
+            response.setContentType("text/plain");
+            Writer out = response.getWriter();
+
+            try {
+
+                // Query new update from server
+                Client client = session.getClient();
+
+                // For all messages, until another stream is ready (we send at least one message)
+                char[] message;
+                while ((message = client.read()) != null) {
+
+                    // Get message output bytes
+                    out.write(message, 0, message.length);
+                    out.flush();
+                    response.flushBuffer();
+
+                    // No more messages another stream can take over
+                    if (instructionStreamLock.hasQueuedThreads())
+                        break;
+
+                }
+
+                if (message == null) {
+                    session.disconnect();
+                    throw new GuacamoleException("Disconnected.");
+                }
+
+            }
+            catch (GuacamoleException e) {
+                out.write("error:" + e.getMessage() + ";");
+                out.flush();
+                response.flushBuffer();
+            }
+
+            // End-of-instructions marker
+            out.write(';');
+            out.flush();
+            response.flushBuffer();
+
+        }
+        catch (UnsupportedEncodingException e) {
+            throw new GuacamoleException("UTF-8 not supported by Java.", e);
+        }
+        catch (IOException e) {
+            throw new GuacamoleException("I/O error writing to servlet output stream.", e);
+        }
+        finally {
+            instructionStreamLock.unlock();
+        }
+
+    }
+
+}
+
diff --git a/web-client/src/net/sourceforge/guacamole/Client.java b/web-client/src/net/sourceforge/guacamole/Client.java
deleted file mode 100644 (file)
index e57d479..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-
-package net.sourceforge.guacamole;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import net.sourceforge.guacamole.GuacamoleException;
-
-public abstract class Client {
-
-    public abstract void write(char[] chunk, int off, int len) throws GuacamoleException;
-    public abstract char[] read() throws GuacamoleException;
-    public abstract void disconnect() throws GuacamoleException;
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/GuacamoleClient.java b/web-client/src/net/sourceforge/guacamole/GuacamoleClient.java
deleted file mode 100644 (file)
index f0748d8..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-
-package net.sourceforge.guacamole;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.InputStreamReader;
-
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.OutputStreamWriter;
-
-import net.sourceforge.guacamole.GuacamoleException;
-
-public class GuacamoleClient extends Client {
-
-    private Socket sock;
-    private Reader input;
-    private Writer output;
-
-    public GuacamoleClient(String hostname, int port) throws GuacamoleException {
-
-        try {
-            sock = new Socket(InetAddress.getByName(hostname), port);
-            input = new InputStreamReader(sock.getInputStream());
-            output = new OutputStreamWriter(sock.getOutputStream());
-        }
-        catch (IOException e) {
-            throw new GuacamoleException(e);
-        }
-
-    }
-
-    public void write(char[] chunk, int off, int len) throws GuacamoleException {
-        try {
-            output.write(chunk, off, len);
-            output.flush();
-        }
-        catch (IOException e) {
-            throw new GuacamoleException(e);
-        }
-    }
-
-    public void disconnect() throws GuacamoleException {
-        try {
-            sock.close();
-        }
-        catch (IOException e) {
-            throw new GuacamoleException(e);
-        }
-    }
-
-    private int usedLength = 0;
-    private char[] buffer = new char[20000];
-
-    public char[] read() throws GuacamoleException {
-
-        try {
-
-            // While we're blocking, or input is available
-            for (;;) {
-
-                // If past threshold, resize buffer before reading
-                if (usedLength > buffer.length/2) {
-                    char[] biggerBuffer = new char[buffer.length*2];
-                    System.arraycopy(buffer, 0, biggerBuffer, 0, usedLength);
-                    buffer = biggerBuffer;
-                }
-
-                // Attempt to fill buffer
-                int numRead = input.read(buffer, usedLength, buffer.length - usedLength);
-                if (numRead == -1)
-                    return null;
-
-                int prevLength = usedLength;
-                usedLength += numRead;
-
-                for (int i=usedLength-1; i>=prevLength; i--) {
-
-                    char readChar = buffer[i];
-
-                    // If end of instruction, return it.
-                    if (readChar == ';') {
-
-                        // Get instruction
-                        char[] chunk = new char[i+1];
-                        System.arraycopy(buffer, 0, chunk, 0, i+1);
-
-                        // Reset buffer
-                        usedLength -= i+1;
-                        System.arraycopy(buffer, i+1, buffer, 0, usedLength);
-
-                        // Return instruction string
-                        return chunk;
-                    }
-
-                }
-
-            } // End read loop
-
-        }
-        catch (IOException e) {
-            throw new GuacamoleException(e);
-        }
-
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/GuacamoleException.java b/web-client/src/net/sourceforge/guacamole/GuacamoleException.java
deleted file mode 100644 (file)
index 3a09c5a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-package net.sourceforge.guacamole;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-public class GuacamoleException extends Exception {
-
-    public GuacamoleException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public GuacamoleException(String message) {
-        super(message);
-    }
-
-    public GuacamoleException(Throwable cause) {
-        super(cause);
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/Configuration.java b/web-client/src/net/sourceforge/guacamole/net/Configuration.java
deleted file mode 100644 (file)
index 6e78eb2..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-
-package net.sourceforge.guacamole.net;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import javax.servlet.ServletContext;
-import net.sourceforge.guacamole.GuacamoleException;
-
-public abstract class Configuration {
-
-    protected String humanReadableList(Object... values) {
-
-        String list = "";
-        for (int i=0; i<values.length; i++) {
-
-            if (i >= 1)
-                list += ", ";
-
-            if (i == values.length -1)
-                list += " or ";
-
-            list += "\"" + values[i] + "\"";
-        }
-
-        return list;
-
-    }
-
-    protected String readParameter(String name) throws GuacamoleException {
-        String value = GuacamoleProperties.getProperty(name);
-        return value;
-    }
-
-    protected String readParameter(String name, String defaultValue, String... allowedValues) throws GuacamoleException {
-
-        String value = GuacamoleProperties.getProperty(name);
-
-        // Use default if not specified
-        if (value == null) {
-            if (defaultValue == null)
-                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
-
-            return defaultValue;
-        }
-
-        // If not restricted to certain values, just return whatever is given.
-        if (allowedValues.length == 0)
-            return value;
-
-        // If restricted, only return value within given list
-        for (String allowedValue : allowedValues)
-            if (value.equals(allowedValue))
-                return value;
-
-        throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
-    }
-
-    protected boolean readBooleanParameter(String name, Boolean defaultValue) throws GuacamoleException {
-
-        String value = GuacamoleProperties.getProperty(name);
-
-        // Use default if not specified
-        if (value == null) {
-            if (defaultValue == null)
-                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
-
-            return defaultValue;
-        }
-
-        value = value.trim();
-        if (value.equals("true"))
-            return true;
-
-        if (value.equals("false"))
-            return false;
-
-        throw new GuacamoleException("Parameter \"" + name + "\" must be \"true\" or \"false\".");
-
-    }
-
-    protected int readIntParameter(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException {
-
-        String parmString = GuacamoleProperties.getProperty(name);
-
-        // Use default if not specified
-        if (parmString== null) {
-            if (defaultValue == null)
-                throw new GuacamoleException("Parameter \"" + name + "\" is required.");
-
-            return defaultValue;
-        }
-
-        try {
-            int value = Integer.parseInt(parmString);
-
-            // If not restricted to certain values, just return whatever is given.
-            if (allowedValues.length == 0)
-                return value;
-
-            // If restricted, only return value within given list
-            for (int allowedValue : allowedValues)
-                if (value == allowedValue)
-                    return value;
-
-            throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
-        }
-        catch (NumberFormatException e) {
-            throw new GuacamoleException("Parameter \"" + name + "\" must be an integer.", e);
-        }
-
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/GuacamoleConfiguration.java b/web-client/src/net/sourceforge/guacamole/net/GuacamoleConfiguration.java
deleted file mode 100644 (file)
index a6bfeeb..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-
-package net.sourceforge.guacamole.net;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider;
-import java.lang.reflect.InvocationTargetException;
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-
-public class GuacamoleConfiguration extends Configuration {
-
-    private String guacd_hostname;
-    private int guacd_port;
-    private GuacamoleSessionProvider sessionProvider;
-
-    public GuacamoleConfiguration() throws GuacamoleException {
-
-        guacd_hostname       = readParameter("guacd-hostname");
-        guacd_port           = readIntParameter("guacd-port", null);
-
-        // Get session provider instance
-        try {
-            String sessionProviderClassName = readParameter("session-provider");
-            Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance();
-            if (!(obj instanceof GuacamoleSessionProvider))
-                throw new GuacamoleException("Specified session provider class is not a GuacamoleSessionProvider");
-
-            sessionProvider = (GuacamoleSessionProvider) obj;
-        }
-        catch (ClassNotFoundException e) {
-            throw new GuacamoleException("Session provider class not found", e);
-        }
-        catch (NoSuchMethodException e) {
-            throw new GuacamoleException("Default constructor for session provider not present", e);
-        }
-        catch (SecurityException e) {
-            throw new GuacamoleException("Creation of session provider disallowed; check your security settings", e);
-        }
-        catch (InstantiationException e) {
-            throw new GuacamoleException("Unable to instantiate session provider", e);
-        }
-        catch (IllegalAccessException e) {
-            throw new GuacamoleException("Unable to access default constructor of session provider", e);
-        }
-        catch (InvocationTargetException e) {
-            throw new GuacamoleException("Internal error in constructor of session provider", e.getTargetException());
-        }
-
-    }
-
-    public int getProxyPort() {
-        return guacd_port;
-    }
-
-    public String getProxyHostname() {
-        return guacd_hostname;
-    }
-
-    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
-        return sessionProvider.createSession(session);
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/GuacamoleProperties.java b/web-client/src/net/sourceforge/guacamole/net/GuacamoleProperties.java
deleted file mode 100644 (file)
index 6c4340d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-
-package net.sourceforge.guacamole.net;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import net.sourceforge.guacamole.GuacamoleException;
-
-public class GuacamoleProperties {
-
-    private static final Properties properties;
-    private static GuacamoleException exception;
-
-    static {
-
-        properties = new Properties();
-
-        try {
-
-            InputStream stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties");
-            if (stream == null)
-                throw new IOException("Resource /guacamole.properties not found.");
-
-            properties.load(stream);
-        }
-        catch (IOException e) {
-            exception = new GuacamoleException("Error reading guacamole.properties", e);
-        }
-
-    }
-
-    public static String getProperty(String name) throws GuacamoleException {
-        if (exception != null) throw exception;
-        return properties.getProperty(name);
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/GuacamoleServlet.java b/web-client/src/net/sourceforge/guacamole/net/GuacamoleServlet.java
deleted file mode 100644 (file)
index a1e7131..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-
-package net.sourceforge.guacamole.net;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-
-public abstract class GuacamoleServlet extends HttpServlet  {
-
-    private GuacamoleConfiguration config;
-
-    @Override
-    public void init() throws ServletException {
-        try {
-            this.config = new GuacamoleConfiguration();
-        }
-        catch (GuacamoleException e) {
-            throw new ServletException(e);
-        }
-    }
-
-    @Override
-    protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-        try {
-            handleRequest(req, resp);
-        }
-        catch (GuacamoleException e) {
-            throw new ServletException(e);
-        }
-    }
-
-    @Override
-    protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-        try {
-            handleRequest(req, resp);
-        }
-        catch (GuacamoleException e) {
-            throw new ServletException(e);
-        }
-    }
-
-    private final void handleRequest(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
-
-        HttpSession httpSession = request.getSession(shouldCreateSession());
-
-        if (httpSession != null) {
-            GuacamoleSession session = config.createSession(httpSession);
-            handleRequest(session, request, response);
-        }
-        else
-            throw new GuacamoleException("No session");
-    }
-
-    protected abstract void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException;
-
-    protected boolean shouldCreateSession() {
-        return false;
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/GuacamoleSession.java b/web-client/src/net/sourceforge/guacamole/net/GuacamoleSession.java
deleted file mode 100644 (file)
index 2eb0132..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-
-package net.sourceforge.guacamole.net;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.concurrent.locks.ReentrantLock;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-import net.sourceforge.guacamole.Client;
-import net.sourceforge.guacamole.GuacamoleClient;
-import net.sourceforge.guacamole.GuacamoleException;
-
-public class GuacamoleSession {
-
-    private GuacamoleConfiguration config;
-    private final HttpSession session;
-    private SessionClient client;
-    private ReentrantLock instructionStreamLock;
-
-    private String protocol;
-    private String hostname;
-    private int port;
-    private String password;
-
-    public class SessionClient extends Client implements HttpSessionBindingListener {
-
-        private Client client;
-        private ReentrantLock authorizedLock;
-
-        public SessionClient(Client client) {
-            this.client = client;
-
-            authorizedLock = new ReentrantLock();
-            authorizedLock.lock();
-        }
-
-        public void authorize() {
-            authorizedLock.unlock();
-        }
-
-        public void waitForAuthorization() {
-            if (authorizedLock.isLocked()) {
-                try {
-                    authorizedLock.lock();
-                    authorizedLock.unlock();
-                }
-                catch (Throwable t) {
-                    throw new Error("Internal error waiting for authorization", t);
-                }
-            }
-        }
-
-        public void valueBound(HttpSessionBindingEvent event) {
-            // Do nothing
-        }
-
-        public void valueUnbound(HttpSessionBindingEvent event) {
-            try {
-                disconnect();
-            }
-            catch (GuacamoleException e) {
-                // Ignore
-            }
-        }
-
-        public void write(char[] data, int off, int len) throws GuacamoleException {
-            client.write(data, off, len);
-        }
-
-        public char[] read() throws GuacamoleException {
-            return client.read();
-        }
-
-        public void disconnect() throws GuacamoleException {
-            client.disconnect();
-        }
-
-    }
-
-    public GuacamoleSession(HttpSession session) throws GuacamoleException {
-
-        if (session == null)
-            throw new GuacamoleException("User has no session.");
-
-        this.session = session;
-        synchronized (session) {
-
-            // Read configuration parameters
-            config = new GuacamoleConfiguration();
-
-            client = (SessionClient) session.getAttribute("CLIENT");
-            instructionStreamLock = (ReentrantLock) session.getAttribute("INSTRUCTION_STREAM_LOCK");
-        }
-    }
-
-    public void connect() throws GuacamoleException {
-        synchronized (session) {
-
-            if (client != null)
-                client.disconnect();
-
-
-            client = new SessionClient(
-                    new GuacamoleClient (
-                        config.getProxyHostname(),
-                        config.getProxyPort()
-                    )
-            );
-
-            session.setAttribute("CLIENT", client);
-
-            instructionStreamLock = new ReentrantLock();
-            session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock);
-
-        }
-    }
-
-    public boolean isConnected() {
-        synchronized (session) {
-            return client != null;
-        }
-    }
-
-    public GuacamoleConfiguration getConfiguration() {
-        return config;
-    }
-
-    public SessionClient getClient() {
-        synchronized (session) {
-            return client;
-        }
-    }
-
-    public void invalidate() {
-        session.invalidate();
-    }
-
-    public void disconnect() throws GuacamoleException {
-        if (client != null) {
-            client.disconnect();
-
-            session.removeAttribute("CLIENT");
-            client = null;
-        }
-    }
-
-    public ReentrantLock getInstructionStreamLock() {
-        return instructionStreamLock;
-    }
-
-    public void setConnection(String protocol, String hostname, int port) {
-        this.protocol = protocol;
-        this.hostname = hostname;
-        this.port = port;
-    }
-
-    public String getProtocol() {
-        return protocol;
-    }
-
-    public String getHostname() {
-        return hostname;
-    }
-
-    public int getPort() {
-        return port;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public String getConnectMessage() throws GuacamoleException {
-
-        if (getProtocol() == null)
-            throw new GuacamoleException("Protocol not specified");
-
-        if (getHostname() == null)
-            throw new GuacamoleException("Hostname not specified");
-
-        if (getPassword() == null)
-            return "connect:" + getProtocol() + "," + getHostname() + "," + getPort() + ";";
-        else
-            return "connect:" + getProtocol() + "," + getHostname() + "," + getPort() + "," + getPassword() + ";";
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java b/web-client/src/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java
deleted file mode 100644 (file)
index bbe82a2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-
-package net.sourceforge.guacamole.net.authentication;
-
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.GuacamoleSession;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-public interface GuacamoleSessionProvider {
-
-    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException;
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java b/web-client/src/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java
deleted file mode 100644 (file)
index a46d0fe..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-
-package net.sourceforge.guacamole.net.authentication;
-
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.GuacamoleSession;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-public class NullGuacamoleSessionProvider implements GuacamoleSessionProvider {
-
-    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
-        throw new GuacamoleException("Null provider will not create sessions");
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java
deleted file mode 100644 (file)
index 83fcfd3..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-
-package net.sourceforge.guacamole.net.authentication.basic;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.GuacamoleProperties;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-public class BasicFileAuthenticationProvider implements BasicLogin.AuthenticationProvider {
-
-    private long mappingTime;
-    private Map<String, AuthInfo> mapping;
-
-    private File getUserMappingFile() throws GuacamoleException {
-
-        // Get user mapping filename
-        String filename = GuacamoleProperties.getProperty("basic-user-mapping");
-        if (filename == null)
-            return null;
-
-        return new File(filename);
-
-    }
-
-    public synchronized void init() throws GuacamoleException {
-
-        // Get user mapping file
-        File mapFile = getUserMappingFile();
-        if (mapFile == null)
-            throw new GuacamoleException("Missing \"basic-user-mapping\" parameter required for basic login.");
-
-        // Parse document
-        try {
-
-            BasicUserMappingContentHandler contentHandler = new BasicUserMappingContentHandler();
-
-            XMLReader parser = XMLReaderFactory.createXMLReader();
-            parser.setContentHandler(contentHandler);
-            parser.parse(mapFile.getAbsolutePath());
-
-            mappingTime = mapFile.lastModified();
-            mapping = contentHandler.getUserMapping();
-
-        }
-        catch (IOException e) {
-            throw new GuacamoleException("Error reading basic user mapping file.", e);
-        }
-        catch (SAXException e) {
-            throw new GuacamoleException("Error parsing basic user mapping XML.", e);
-        }
-
-    }
-
-    @Override
-    public BasicLogin.AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException {
-
-        // Check mapping file mod time
-        File userMappingFile = getUserMappingFile();
-        if (userMappingFile.exists() && mappingTime < userMappingFile.lastModified()) {
-
-            // If modified recently, gain exclusive access and recheck
-            synchronized (this) {
-                if (userMappingFile.exists() && mappingTime < userMappingFile.lastModified())
-                    init(); // If still not up to date, re-init
-            }
-
-        }
-
-        AuthInfo info = mapping.get(username);
-        if (info != null && info.validate(username, password))
-            return new BasicLogin.AuthorizedConfiguration(
-                info.getProtocol(),
-                info.getHostname(),
-                info.getPort(),
-                info.getPassword()
-            );
-
-        return null;
-
-    }
-
-    public static class AuthInfo {
-
-        public static enum Encoding {
-            PLAIN_TEXT,
-            MD5
-        }
-
-        private String auth_username;
-        private String auth_password;
-        private Encoding auth_encoding;
-
-        private String protocol;
-        private String hostname;
-        private int port;
-        private String password;
-
-        public AuthInfo(String auth_username, String auth_password, Encoding auth_encoding) {
-            this.auth_username = auth_username;
-            this.auth_password = auth_password;
-            this.auth_encoding = auth_encoding;
-        }
-
-        private static final char HEX_CHARS[] = {
-            '0', '1', '2', '3', '4', '5', '6', '7',
-            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-        };
-
-        public static String getHexString(byte[] bytes) {
-
-            if (bytes == null)
-                return null;
-
-            StringBuilder hex = new StringBuilder(2 * bytes.length);
-            for (byte b : bytes) {
-                hex.append(HEX_CHARS[(b & 0xF0) >> 4])
-                   .append(HEX_CHARS[(b & 0x0F)     ]);
-            }
-
-            return hex.toString();
-
-        }
-
-
-        public boolean validate(String username, String password) {
-
-            // If username matches
-            if (username != null && password != null && username.equals(auth_username)) {
-
-                switch (auth_encoding) {
-
-                    case PLAIN_TEXT:
-
-                        // Compare plaintext
-                        return password.equals(auth_password);
-
-                    case MD5:
-
-                        // Compare hashed password
-                        try {
-                            MessageDigest digest = MessageDigest.getInstance("MD5");
-                            String hashedPassword = getHexString(digest.digest(password.getBytes()));
-                            return hashedPassword.equals(auth_password.toUpperCase());
-                        }
-                        catch (NoSuchAlgorithmException e) {
-                            throw new UnsupportedOperationException("Unexpected lack of MD5 support.", e);
-                        }
-
-                }
-
-            }
-
-            return false;
-
-        }
-
-        public String getHostname() {
-            return hostname;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-
-        public int getPort() {
-            return port;
-        }
-
-        public String getProtocol() {
-            return protocol;
-        }
-
-    }
-
-
-    private static class BasicUserMappingContentHandler extends DefaultHandler {
-
-        private Map<String, AuthInfo> authMapping = new HashMap<String, AuthInfo>();
-
-        public Map<String, AuthInfo> getUserMapping() {
-            return Collections.unmodifiableMap(authMapping);
-        }
-
-        private AuthInfo current;
-
-        private enum AUTH_INFO_STATE {
-            PROTOCOL,
-            HOSTNAME,
-            PORT,
-            PASSWORD
-        };
-
-        private AUTH_INFO_STATE infoState;
-
-        @Override
-        public void endElement(String uri, String localName, String qName) throws SAXException {
-
-            if (localName.equals("authorize")) {
-
-                // Finalize mapping for this user
-                authMapping.put(
-                    current.auth_username,
-                    current
-                );
-
-            }
-
-            infoState = null;
-
-        }
-
-        @Override
-        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-
-            if (localName.equals("authorize")) {
-
-                AuthInfo.Encoding encoding;
-                String encodingString = attributes.getValue("encoding");
-                if (encodingString == null)
-                    encoding = AuthInfo.Encoding.PLAIN_TEXT;
-                else if (encodingString.equals("plain"))
-                    encoding = AuthInfo.Encoding.PLAIN_TEXT;
-                else if (encodingString.equals("md5"))
-                    encoding = AuthInfo.Encoding.MD5;
-                else
-                    throw new SAXException("Invalid encoding type");
-
-
-                current = new AuthInfo(
-                    attributes.getValue("username"),
-                    attributes.getValue("password"),
-                    encoding
-                );
-
-                infoState = null;
-
-            }
-
-            else if (localName.equals("protocol"))
-                infoState = AUTH_INFO_STATE.PROTOCOL;
-
-            else if (localName.equals("hostname"))
-                infoState = AUTH_INFO_STATE.HOSTNAME;
-
-            else if (localName.equals("port"))
-                infoState = AUTH_INFO_STATE.PORT;
-
-            else if (localName.equals("password"))
-                infoState = AUTH_INFO_STATE.PASSWORD;
-
-            else
-                infoState = null;
-
-        }
-
-        @Override
-        public void characters(char[] ch, int start, int length) throws SAXException {
-
-            String str = new String(ch, start, length);
-
-            if (infoState == null)
-                return;
-
-            switch (infoState) {
-
-                case PROTOCOL:
-                    current.protocol = str;
-                    break;
-
-                case HOSTNAME:
-                    current.hostname = str;
-                    break;
-
-                case PORT:
-                    current.port = Integer.parseInt(str);
-                    break;
-
-                case PASSWORD:
-                    current.password = str;
-                    break;
-
-            }
-
-        }
-
-
-    }
-
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java b/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java
deleted file mode 100644 (file)
index 959bf0e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-package net.sourceforge.guacamole.net.authentication.basic;
-
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.GuacamoleSession;
-import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-public class BasicGuacamoleSessionProvider implements GuacamoleSessionProvider {
-
-    public GuacamoleSession createSession(HttpSession session) throws GuacamoleException {
-
-        // Retrieve authorized config data from session
-        BasicLogin.AuthorizedConfiguration config = (BasicLogin.AuthorizedConfiguration)
-                session.getAttribute("BASIC-LOGIN-AUTH");
-
-        // If no data, not authorized
-        if (config == null)
-            throw new GuacamoleException("Unauthorized");
-
-        // Configure session from authorized config info
-        GuacamoleSession guacSession = new GuacamoleSession(session);
-        guacSession.setConnection(config.getProtocol(), config.getHostname(), config.getPort());
-        if (config.getPassword() != null)
-            guacSession.setPassword(config.getPassword());
-
-        // Return authorized session
-        return guacSession;
-
-    }
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java b/web-client/src/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java
deleted file mode 100644 (file)
index 43e8721..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-
-package net.sourceforge.guacamole.net.authentication.basic;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.Configuration;
-
-public class BasicLogin extends HttpServlet {
-
-    private Config config;
-
-    @Override
-    public void init() throws ServletException {
-        try {
-            config = new Config();
-        }
-        catch (GuacamoleException e) {
-            throw new ServletException(e);
-        }
-    }
-
-
-    private class Config extends Configuration {
-
-        private AuthenticationProvider authProvider;
-
-        public Config() throws GuacamoleException {
-
-            // Get auth provider instance
-            try {
-                String authProviderClassName = readParameter("auth-provider");
-                Object obj = Class.forName(authProviderClassName).getConstructor().newInstance();
-                if (!(obj instanceof AuthenticationProvider))
-                    throw new GuacamoleException("Specified session provider class is not a GuacamoleSessionProvider");
-
-                authProvider = (AuthenticationProvider) obj;
-            }
-            catch (ClassNotFoundException e) {
-                throw new GuacamoleException("Session provider class not found", e);
-            }
-            catch (NoSuchMethodException e) {
-                throw new GuacamoleException("Default constructor for session provider not present", e);
-            }
-            catch (SecurityException e) {
-                throw new GuacamoleException("Creation of session provider disallowed; check your security settings", e);
-            }
-            catch (InstantiationException e) {
-                throw new GuacamoleException("Unable to instantiate session provider", e);
-            }
-            catch (IllegalAccessException e) {
-                throw new GuacamoleException("Unable to access default constructor of session provider", e);
-            }
-            catch (InvocationTargetException e) {
-                throw new GuacamoleException("Internal error in constructor of session provider", e.getTargetException());
-            }
-
-        }
-
-        public AuthenticationProvider getAuthenticationProvider() {
-            return authProvider;
-        }
-
-    }
-
-    public static interface AuthenticationProvider {
-        public AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException;
-    }
-
-    // Added to session when session validated
-    public static class AuthorizedConfiguration {
-
-        private String protocol;
-        private String hostname;
-        private int port;
-        private String password;
-
-        public AuthorizedConfiguration(String protocol, String hostname, int port, String password) {
-            this.protocol = protocol;
-            this.hostname = hostname;
-            this.port = port;
-            this.password = password;
-        }
-
-        public String getHostname() {
-            return hostname;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-
-        public int getPort() {
-            return port;
-        }
-
-        public String getProtocol() {
-            return protocol;
-        }
-
-    }
-
-    @Override
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
-        // Retrieve username and password from parms
-        String username = req.getParameter("username");
-        String password = req.getParameter("password");
-
-        // Validate username and password
-        try {
-
-            AuthorizedConfiguration info = config.getAuthenticationProvider().getAuthorizedConfiguration(username, password);
-            if (info != null) {
-
-                // Store authorized configuration
-                HttpSession session = req.getSession(true);
-                session.setAttribute(
-                    "BASIC-LOGIN-AUTH",
-                    info
-                );
-
-                // Success
-                return;
-
-            }
-
-            // Report "forbidden" on any failure
-            resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Login invalid");
-        }
-        catch (GuacamoleException e) {
-            throw new ServletException("Error validating credentials", e);
-        }
-
-    }
-
-
-}
diff --git a/web-client/src/net/sourceforge/guacamole/net/tunnel/Connect.java b/web-client/src/net/sourceforge/guacamole/net/tunnel/Connect.java
deleted file mode 100644 (file)
index 79aa94d..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package net.sourceforge.guacamole.net.tunnel;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import net.sourceforge.guacamole.GuacamoleException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import net.sourceforge.guacamole.net.GuacamoleServlet;
-
-import net.sourceforge.guacamole.net.GuacamoleSession;
-
-public class Connect extends GuacamoleServlet {
-
-    @Override
-    protected boolean shouldCreateSession() {
-        return true;
-    }
-
-    @Override
-    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
-
-        // Disconnect if already connected
-        if (session.isConnected())
-            session.disconnect();
-
-        // Obtain new connection
-        session.connect();
-
-        // Send data
-        try {
-            char[] connect = session.getConnectMessage().toCharArray();
-            session.getClient().write(connect, 0, connect.length);
-            session.getClient().authorize();
-        }
-        catch (GuacamoleException e) {
-            throw new GuacamoleException("Error sending data to server: " + e.getMessage(), e);
-        }
-
-    }
-
-}
-
diff --git a/web-client/src/net/sourceforge/guacamole/net/tunnel/Inbound.java b/web-client/src/net/sourceforge/guacamole/net/tunnel/Inbound.java
deleted file mode 100644 (file)
index 415d639..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package net.sourceforge.guacamole.net.tunnel;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import net.sourceforge.guacamole.GuacamoleException;
-
-import java.io.Reader;
-import java.io.IOException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import net.sourceforge.guacamole.net.GuacamoleServlet;
-
-import net.sourceforge.guacamole.net.GuacamoleSession;
-
-public class Inbound extends GuacamoleServlet {
-
-    @Override
-    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
-        
-        session.getClient().waitForAuthorization();
-
-        // Send data
-        try {
-
-            Reader input = request.getReader();
-            char[] buffer = new char[8192];
-
-            int length;
-            while ((length = input.read(buffer, 0, buffer.length)) != -1)
-                session.getClient().write(buffer, 0, length);
-
-        }
-        catch (IOException e) {
-            throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e);
-        }
-        catch (GuacamoleException e) {
-            throw new GuacamoleException("Error sending data to server: " + e.getMessage(), e);
-        }
-
-    }
-
-}
-
diff --git a/web-client/src/net/sourceforge/guacamole/net/tunnel/Outbound.java b/web-client/src/net/sourceforge/guacamole/net/tunnel/Outbound.java
deleted file mode 100644 (file)
index 76aa34c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-package net.sourceforge.guacamole.net.tunnel;
-
-/*
- *  Guacamole - Clientless Remote Desktop
- *  Copyright (C) 2010  Michael Jumper
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
- *
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.Writer;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import net.sourceforge.guacamole.Client;
-import net.sourceforge.guacamole.net.GuacamoleServlet;
-import net.sourceforge.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.GuacamoleSession;
-
-
-public class Outbound extends GuacamoleServlet {
-
-    @Override
-    protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
-
-        session.getClient().waitForAuthorization();
-
-        ReentrantLock instructionStreamLock = session.getInstructionStreamLock();
-        instructionStreamLock.lock();
-
-        try {
-
-            response.setContentType("text/plain");
-            Writer out = response.getWriter();
-
-            try {
-
-                // Query new update from server
-                Client client = session.getClient();
-
-                // For all messages, until another stream is ready (we send at least one message)
-                char[] message;
-                while ((message = client.read()) != null) {
-
-                    // Get message output bytes
-                    out.write(message, 0, message.length);
-                    out.flush();
-                    response.flushBuffer();
-
-                    // No more messages another stream can take over
-                    if (instructionStreamLock.hasQueuedThreads())
-                        break;
-
-                }
-
-                if (message == null) {
-                    session.disconnect();
-                    throw new GuacamoleException("Disconnected.");
-                }
-
-            }
-            catch (GuacamoleException e) {
-                out.write("error:" + e.getMessage() + ";");
-                out.flush();
-                response.flushBuffer();
-            }
-
-            // End-of-instructions marker
-            out.write(';');
-            out.flush();
-            response.flushBuffer();
-
-        }
-        catch (UnsupportedEncodingException e) {
-            throw new GuacamoleException("UTF-8 not supported by Java.", e);
-        }
-        catch (IOException e) {
-            throw new GuacamoleException("I/O error writing to servlet output stream.", e);
-        }
-        finally {
-            instructionStreamLock.unlock();
-        }
-
-    }
-
-}
-