From 93a9e8a41a6e4847e05b5acac7d4c3c08bc38107 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 8 Dec 2010 13:14:04 -0800 Subject: [PATCH 001/116] More renaming --- guacamole-common/pom.xml | 57 ++++ .../net/sourceforge/guacamole/Client.java | 30 ++ .../guacamole/GuacamoleClient.java | 129 +++++++ .../guacamole/GuacamoleException.java | 36 ++ .../guacamole/net/Configuration.java | 129 +++++++ .../guacamole/net/GuacamoleConfiguration.java | 80 +++++ .../guacamole/net/GuacamoleProperties.java | 55 +++ .../guacamole/net/GuacamoleServlet.java | 83 +++++ .../guacamole/net/GuacamoleSession.java | 209 ++++++++++++ .../GuacamoleSessionProvider.java | 30 ++ .../NullGuacamoleSessionProvider.java | 32 ++ .../BasicFileAuthenticationProvider.java | 318 ++++++++++++++++++ .../basic/BasicGuacamoleSessionProvider.java | 50 +++ .../net/authentication/basic/BasicLogin.java | 161 +++++++++ .../guacamole/net/tunnel/Connect.java | 59 ++++ .../guacamole/net/tunnel/Inbound.java | 59 ++++ .../guacamole/net/tunnel/Outbound.java | 99 ++++++ 17 files changed, 1616 insertions(+) create mode 100644 guacamole-common/pom.xml create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml new file mode 100644 index 000000000..70ee49b8c --- /dev/null +++ b/guacamole-common/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + net.sourceforge.guacamole + guacamole-common + jar + 0.3.0rc1 + guacamole-common + http://guacamole.sourceforge.net/ + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + + org.apache.maven.wagon + wagon-ssh-external + + + + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + guac-dev + http://guac-dev.org/repo + + + + + + guac-dev + scpexe://guac-dev.org/var/www/repo + + + + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java new file mode 100644 index 000000000..e57d479a0 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java new file mode 100644 index 000000000..f0748d8df --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java new file mode 100644 index 000000000..3a09c5ac7 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java new file mode 100644 index 000000000..6e78eb296 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java @@ -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 . + */ + +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= 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java new file mode 100644 index 000000000..a6bfeeb52 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java new file mode 100644 index 000000000..6c4340dd1 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java new file mode 100644 index 000000000..a1e713132 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java new file mode 100644 index 000000000..2eb01326b --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java new file mode 100644 index 000000000..bbe82a2de --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java @@ -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 . + */ + +public interface GuacamoleSessionProvider { + + public GuacamoleSession createSession(HttpSession session) throws GuacamoleException; + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java new file mode 100644 index 000000000..a46d0fe57 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java @@ -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 . + */ + +public class NullGuacamoleSessionProvider implements GuacamoleSessionProvider { + + public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { + throw new GuacamoleException("Null provider will not create sessions"); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java new file mode 100644 index 000000000..83fcfd34c --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java @@ -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 . + */ + +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 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 authMapping = new HashMap(); + + public Map 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java new file mode 100644 index 000000000..959bf0e6e --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java new file mode 100644 index 000000000..43e8721d9 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java new file mode 100644 index 000000000..79aa94d40 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java new file mode 100644 index 000000000..415d639bf --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java @@ -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 . + */ + +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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java new file mode 100644 index 000000000..76aa34c76 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java @@ -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 . + */ + +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(); + } + + } + +} + From a13d371d555578e36c248dcfede44a01c49b1453 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 8 Dec 2010 23:42:34 -0800 Subject: [PATCH 002/116] Moved basic auth into default webapp --- .../BasicFileAuthenticationProvider.java | 318 ------------------ .../basic/BasicGuacamoleSessionProvider.java | 50 --- .../net/authentication/basic/BasicLogin.java | 161 --------- 3 files changed, 529 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java deleted file mode 100644 index 83fcfd34c..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java +++ /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 . - */ - -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 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 authMapping = new HashMap(); - - public Map 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java deleted file mode 100644 index 959bf0e6e..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java +++ /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 . - */ - -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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java deleted file mode 100644 index 43e8721d9..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java +++ /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 . - */ - -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); - } - - } - - -} From a4d143d21c03a370de04211490d56138c29229c5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 20 Dec 2010 22:31:42 -0800 Subject: [PATCH 003/116] Adding package descriptor for build system --- guacamole-common/.package.dsc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 guacamole-common/.package.dsc diff --git a/guacamole-common/.package.dsc b/guacamole-common/.package.dsc new file mode 100644 index 000000000..98ecc5b07 --- /dev/null +++ b/guacamole-common/.package.dsc @@ -0,0 +1,2 @@ +PKGNAME=guacamole-common +VERSION=0.0.1 From fabd400c3def1f27509f72a4b0a78e6b2ee188b7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 29 Dec 2010 14:48:41 -0800 Subject: [PATCH 004/116] Using SNAPSHOT version --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 70ee49b8c..00a5a0549 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.3.0rc1 + 0.3.0-SNAPSHOT guacamole-common http://guacamole.sourceforge.net/ From a52ef38607b84f95c250806aac2155332021f603 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 29 Dec 2010 15:28:36 -0800 Subject: [PATCH 005/116] Enabling snapshots in pom.xml --- guacamole-common/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 00a5a0549..13f1532c7 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -44,6 +44,11 @@ guac-dev http://guac-dev.org/repo + + true + always + fail + From 8b1303b143b63c947669a5296b1db9016bf63d13 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 00:39:01 -0800 Subject: [PATCH 006/116] Defining dist repo in property. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 13f1532c7..aa2f37ad0 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -55,7 +55,7 @@ guac-dev - scpexe://guac-dev.org/var/www/repo + ${guac-dev.dist.repo} From ca77a087cab0465bdc8bfab5ed9070d6f8329dfb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 01:47:55 -0800 Subject: [PATCH 007/116] Ignore target dir --- guacamole-common/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 guacamole-common/.gitignore diff --git a/guacamole-common/.gitignore b/guacamole-common/.gitignore new file mode 100644 index 000000000..2f7896d1d --- /dev/null +++ b/guacamole-common/.gitignore @@ -0,0 +1 @@ +target/ From fc8ff9ea16c10e2320afcb20d3f5da1b70f8bf74 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 15:56:30 -0800 Subject: [PATCH 008/116] Added *~ files to .gitignore --- guacamole-common/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole-common/.gitignore b/guacamole-common/.gitignore index 2f7896d1d..42f4a1a64 100644 --- a/guacamole-common/.gitignore +++ b/guacamole-common/.gitignore @@ -1 +1,2 @@ target/ +*~ From bda0d83ff1b8dce0f24ee776b93abbb673e7916c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 20:32:52 -0800 Subject: [PATCH 009/116] Initial work moving to reasonable session/client API. --- .../net/sourceforge/guacamole/Client.java | 2 - .../guacamole/GuacamoleClient.java | 3 - .../guacamole/net/GuacamoleSession.java | 108 ++++++------------ .../guacamole/net/tunnel/Connect.java | 10 -- .../guacamole/net/tunnel/Inbound.java | 2 - .../guacamole/net/tunnel/Outbound.java | 2 - 6 files changed, 38 insertions(+), 89 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java index e57d479a0..076f0c371 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java @@ -19,8 +19,6 @@ package net.sourceforge.guacamole; * along with this program. If not, see . */ -import net.sourceforge.guacamole.GuacamoleException; - public abstract class Client { public abstract void write(char[] chunk, int off, int len) throws GuacamoleException; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java index f0748d8df..1dc4f69f2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java @@ -23,15 +23,12 @@ 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 { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java index 2eb01326b..57568e5ad 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -19,8 +19,8 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ +import java.util.HashMap; 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; @@ -31,41 +31,36 @@ 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; + private HashMap parameters = new HashMap(); + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getParameter(String name) { + return parameters.get(name); + } + + public void setParameter(String name, String value) { + parameters.put(name, value); + } 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) { @@ -109,15 +104,16 @@ public class GuacamoleSession { 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(), @@ -125,12 +121,15 @@ public class GuacamoleSession { ) ); + // TODO: Send "select" and "connect" messages here. + session.setAttribute("CLIENT", client); instructionStreamLock = new ReentrantLock(); session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock); } + } public boolean isConnected() { @@ -143,8 +142,12 @@ public class GuacamoleSession { return config; } - public SessionClient getClient() { + public SessionClient getClient() throws GuacamoleException { synchronized (session) { + + if (client == null) + throw new GuacamoleException("Client not yet connected."); + return client; } } @@ -154,56 +157,21 @@ public class GuacamoleSession { } public void disconnect() throws GuacamoleException { - if (client != null) { - client.disconnect(); - session.removeAttribute("CLIENT"); - client = null; + synchronized (session) { + + 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java index 79aa94d40..273aab895 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java @@ -43,16 +43,6 @@ public class Connect extends GuacamoleServlet { // 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java index 415d639bf..8a939c07c 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java @@ -33,8 +33,6 @@ public class Inbound extends GuacamoleServlet { @Override protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { - session.getClient().waitForAuthorization(); - // Send data try { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java index 76aa34c76..942a2d72d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java @@ -35,8 +35,6 @@ 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(); From 1430bed43e8a2728cae332c28a3391c337ea7923 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 02:36:31 -0800 Subject: [PATCH 010/116] API improvements --- .../guacamole/net/Configuration.java | 110 ++------------ .../guacamole/net/GuacamoleConfiguration.java | 80 ---------- .../guacamole/net/GuacamoleProperties.java | 139 ++++++++++++++++++ .../guacamole/net/GuacamoleServlet.java | 83 ----------- .../guacamole/net/GuacamoleSession.java | 58 +------- ...ider.java => GuacamoleClientProvider.java} | 6 +- ....java => NullGuacamoleClientProvider.java} | 8 +- .../guacamole/net/tunnel/Connect.java | 33 +++-- .../guacamole/net/tunnel/Inbound.java | 40 +++-- .../guacamole/net/tunnel/Outbound.java | 93 +++++++----- 10 files changed, 263 insertions(+), 387 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/{GuacamoleSessionProvider.java => GuacamoleClientProvider.java} (82%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/{NullGuacamoleSessionProvider.java => NullGuacamoleClientProvider.java} (80%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java index 6e78eb296..b086cf1ac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java @@ -1,6 +1,8 @@ package net.sourceforge.guacamole.net; +import java.util.HashMap; + /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -19,111 +21,25 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import javax.servlet.ServletContext; -import net.sourceforge.guacamole.GuacamoleException; +public class Configuration { -public abstract class Configuration { - - protected String humanReadableList(Object... values) { - - String list = ""; - for (int i=0; i= 1) - list += ", "; - - if (i == values.length -1) - list += " or "; - - list += "\"" + values[i] + "\""; - } - - return list; + private String protocol; + private HashMap parameters = new HashMap(); + public String getProtocol() { + return protocol; } - protected String readParameter(String name) throws GuacamoleException { - String value = GuacamoleProperties.getProperty(name); - return value; + public void setProtocol(String protocol) { + this.protocol = protocol; } - 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)); + public String getParameter(String name) { + return parameters.get(name); } - 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); - } - + public void setParameter(String name, String value) { + parameters.put(name, value); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java deleted file mode 100644 index a6bfeeb52..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java +++ /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 . - */ - -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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java index 6c4340dd1..f68c2e4a6 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java @@ -21,8 +21,10 @@ package net.sourceforge.guacamole.net; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.util.Properties; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; public class GuacamoleProperties { @@ -47,9 +49,146 @@ public class GuacamoleProperties { } + public static String getProxyHostname() throws GuacamoleException { + return GuacamoleProperties.getProperty("guacd-hostname"); + } + + public static int getProxyPort() throws GuacamoleException { + return GuacamoleProperties.getIntProperty("guacd-port", null); + } + + public static GuacamoleClientProvider getClientProvider() throws GuacamoleException { + + // Get client provider instance + try { + String sessionProviderClassName = GuacamoleProperties.getProperty("client-provider"); + Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance(); + if (!(obj instanceof GuacamoleClientProvider)) + throw new GuacamoleException("Specified client provider class is not a GuacamoleClientProvider"); + + return (GuacamoleClientProvider) obj; + } + catch (ClassNotFoundException e) { + throw new GuacamoleException("Session provider class not found", e); + } + catch (NoSuchMethodException e) { + throw new GuacamoleException("Default constructor for client provider not present", e); + } + catch (SecurityException e) { + throw new GuacamoleException("Creation of client provider disallowed; check your security settings", e); + } + catch (InstantiationException e) { + throw new GuacamoleException("Unable to instantiate client provider", e); + } + catch (IllegalAccessException e) { + throw new GuacamoleException("Unable to access default constructor of client provider", e); + } + catch (InvocationTargetException e) { + throw new GuacamoleException("Internal error in constructor of client provider", e.getTargetException()); + } + + } + public static String getProperty(String name) throws GuacamoleException { if (exception != null) throw exception; return properties.getProperty(name); } + protected static String humanReadableList(Object... values) { + + String list = ""; + for (int i=0; i= 1) + list += ", "; + + if (i == values.length -1) + list += " or "; + + list += "\"" + values[i] + "\""; + } + + return list; + + } + + public static String getProperty(String name, String defaultValue, String... allowedValues) throws GuacamoleException { + + String value = 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)); + } + + public static boolean getBooleanProperty(String name, Boolean defaultValue) throws GuacamoleException { + + String value = 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\"."); + + } + + public static int getIntProperty(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException { + + String parmString = 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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java deleted file mode 100644 index a1e713132..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java +++ /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 . - */ - -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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java index 57568e5ad..10699246e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -19,7 +19,6 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import java.util.HashMap; import java.util.concurrent.locks.ReentrantLock; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionBindingEvent; @@ -30,31 +29,10 @@ 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 HashMap parameters = new HashMap(); - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getParameter(String name) { - return parameters.get(name); - } - - public void setParameter(String name, String value) { - parameters.put(name, value); - } - public class SessionClient extends Client implements HttpSessionBindingListener { private Client client; @@ -96,34 +74,22 @@ public class GuacamoleSession { throw new GuacamoleException("User has no session."); this.session = session; - synchronized (session) { - // Read configuration parameters - config = new GuacamoleConfiguration(); + synchronized (session) { client = (SessionClient) session.getAttribute("CLIENT"); instructionStreamLock = (ReentrantLock) session.getAttribute("INSTRUCTION_STREAM_LOCK"); + } } - public void connect() throws GuacamoleException { + public void attachClient(GuacamoleClient client) throws GuacamoleException { synchronized (session) { - if (client != null) - client.disconnect(); - - client = new SessionClient( - new GuacamoleClient ( - config.getProxyHostname(), - config.getProxyPort() - ) - ); - - // TODO: Send "select" and "connect" messages here. - - session.setAttribute("CLIENT", client); + this.client = new SessionClient(client); + session.setAttribute("CLIENT", this.client); instructionStreamLock = new ReentrantLock(); session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock); @@ -132,21 +98,11 @@ public class GuacamoleSession { } - public boolean isConnected() { - synchronized (session) { - return client != null; - } - } - - public GuacamoleConfiguration getConfiguration() { - return config; - } - public SessionClient getClient() throws GuacamoleException { synchronized (session) { if (client == null) - throw new GuacamoleException("Client not yet connected."); + throw new GuacamoleException("Client not yet attached."); return client; } @@ -156,7 +112,7 @@ public class GuacamoleSession { session.invalidate(); } - public void disconnect() throws GuacamoleException { + public void detachClient() throws GuacamoleException { synchronized (session) { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java similarity index 82% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java index bbe82a2de..a4989dcac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java @@ -2,8 +2,8 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; /* * Guacamole - Clientless Remote Desktop @@ -23,8 +23,8 @@ import net.sourceforge.guacamole.net.GuacamoleSession; * along with this program. If not, see . */ -public interface GuacamoleSessionProvider { +public interface GuacamoleClientProvider { - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException; + public GuacamoleClient createClient(HttpSession session) throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java similarity index 80% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java index a46d0fe57..786939553 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java @@ -2,8 +2,8 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; /* * Guacamole - Clientless Remote Desktop @@ -23,10 +23,10 @@ import net.sourceforge.guacamole.net.GuacamoleSession; * along with this program. If not, see . */ -public class NullGuacamoleSessionProvider implements GuacamoleSessionProvider { +public class NullGuacamoleClientProvider implements GuacamoleClientProvider { - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { - throw new GuacamoleException("Null provider will not create sessions"); + public GuacamoleClient createClient(HttpSession session) throws GuacamoleException { + throw new GuacamoleException("Null provider will not create clients."); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java index 273aab895..322578dec 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java @@ -18,30 +18,35 @@ package net.sourceforge.guacamole.net.tunnel; * along with this program. If not, see . */ -import net.sourceforge.guacamole.GuacamoleException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import net.sourceforge.guacamole.net.GuacamoleServlet; - +import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleProperties; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Connect extends GuacamoleServlet { + +public class Connect extends HttpServlet { @Override - protected boolean shouldCreateSession() { - return true; - } + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + HttpSession httpSession = request.getSession(false); - // Disconnect if already connected - if (session.isConnected()) - session.disconnect(); + try { - // Obtain new connection - session.connect(); + GuacamoleSession session = new GuacamoleSession(httpSession); + session.attachClient( + GuacamoleProperties.getClientProvider().createClient(httpSession) + ); + + } + catch (GuacamoleException e) { + throw new ServletException(e); + } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java index 8a939c07c..87007b14b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java @@ -22,33 +22,43 @@ import net.sourceforge.guacamole.GuacamoleException; import java.io.Reader; import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import net.sourceforge.guacamole.net.GuacamoleServlet; - +import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Inbound extends GuacamoleServlet { + +public class Inbound extends HttpServlet { @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { - - // Send data + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + HttpSession httpSession = request.getSession(false); + try { - Reader input = request.getReader(); - char[] buffer = new char[8192]; + GuacamoleSession session = new GuacamoleSession(httpSession); - int length; - while ((length = input.read(buffer, 0, buffer.length)) != -1) - session.getClient().write(buffer, 0, length); + // 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 (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); + throw new ServletException(e); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java index 942a2d72d..5b09c463e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java @@ -22,73 +22,86 @@ import java.io.Writer; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.concurrent.locks.ReentrantLock; +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.Client; -import net.sourceforge.guacamole.net.GuacamoleServlet; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Outbound extends GuacamoleServlet { +public class Outbound extends HttpServlet { @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); - instructionStreamLock.lock(); + HttpSession httpSession = request.getSession(false); try { - response.setContentType("text/plain"); - Writer out = response.getWriter(); + GuacamoleSession session = new GuacamoleSession(httpSession); + + ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); + instructionStreamLock.lock(); try { - // Query new update from server - Client client = session.getClient(); + response.setContentType("text/plain"); + Writer out = response.getWriter(); - // For all messages, until another stream is ready (we send at least one message) - char[] message; - while ((message = client.read()) != null) { + try { - // Get message output bytes - out.write(message, 0, message.length); + // 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.detachClient(); + throw new GuacamoleException("Disconnected."); + } + + } + catch (GuacamoleException e) { + out.write("error:" + e.getMessage() + ";"); 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() + ";"); + // End-of-instructions marker + out.write(';'); out.flush(); response.flushBuffer(); + + } + catch (UnsupportedEncodingException e) { + throw new ServletException("UTF-8 not supported by Java.", e); + } + catch (IOException e) { + throw new ServletException("I/O error writing to servlet output stream.", e); + } + finally { + instructionStreamLock.unlock(); } - // 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(); + catch (GuacamoleException e) { + throw new ServletException(e); } } From a54c413420bfb2b4dd1f721f0759fa18b679a70a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 14:27:44 -0800 Subject: [PATCH 011/116] More API improvements --- .../net/sourceforge/guacamole/Client.java | 28 ---- .../guacamole/GuacamoleClient.java | 108 ++------------- .../guacamole/GuacamoleTCPClient.java | 126 ++++++++++++++++++ .../guacamole/net/GuacamoleProperties.java | 8 -- .../guacamole/net/GuacamoleSession.java | 10 +- .../GuacamoleClientProvider.java | 4 +- .../NullGuacamoleClientProvider.java | 4 +- .../guacamole/net/tunnel/Outbound.java | 4 +- 8 files changed, 147 insertions(+), 145 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java deleted file mode 100644 index 076f0c371..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/Client.java +++ /dev/null @@ -1,28 +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 . - */ - -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/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java index 1dc4f69f2..80f0c1bf5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java @@ -1,6 +1,8 @@ package net.sourceforge.guacamole; +import net.sourceforge.guacamole.net.Configuration; + /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -19,107 +21,17 @@ package net.sourceforge.guacamole; * along with this program. If not, see . */ -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; +public abstract class GuacamoleClient { -import java.io.Reader; -import java.io.InputStreamReader; + public abstract void write(char[] chunk, int off, int len) throws GuacamoleException; + public abstract char[] read() throws GuacamoleException; + public abstract void disconnect() throws GuacamoleException; -import java.io.Writer; -import java.io.OutputStreamWriter; + public void connect(Configuration config) throws 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); - } + // TODO: Send "select" and "connect" messages in client connect function (based on config) ... to be implemented. + char[] initMessages = "select:vnc;connect:localhost,5901,potato;".toCharArray(); + write(initMessages, 0, initMessages.length); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java new file mode 100644 index 000000000..f0c0b23c1 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java @@ -0,0 +1,126 @@ + +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 . + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import java.io.Reader; +import java.io.InputStreamReader; + +import java.io.Writer; +import java.io.OutputStreamWriter; + + +public class GuacamoleTCPClient extends GuacamoleClient { + + private Socket sock; + private Reader input; + private Writer output; + + public GuacamoleTCPClient(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/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java index f68c2e4a6..97dff3552 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java @@ -49,14 +49,6 @@ public class GuacamoleProperties { } - public static String getProxyHostname() throws GuacamoleException { - return GuacamoleProperties.getProperty("guacd-hostname"); - } - - public static int getProxyPort() throws GuacamoleException { - return GuacamoleProperties.getIntProperty("guacd-port", null); - } - public static GuacamoleClientProvider getClientProvider() throws GuacamoleException { // Get client provider instance diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java index 10699246e..430a4aae5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -23,8 +23,8 @@ import java.util.concurrent.locks.ReentrantLock; 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.GuacamoleTCPClient; import net.sourceforge.guacamole.GuacamoleException; public class GuacamoleSession { @@ -33,11 +33,11 @@ public class GuacamoleSession { private SessionClient client; private ReentrantLock instructionStreamLock; - public class SessionClient extends Client implements HttpSessionBindingListener { + public class SessionClient extends GuacamoleClient implements HttpSessionBindingListener { - private Client client; + private GuacamoleClient client; - public SessionClient(Client client) { + public SessionClient(GuacamoleClient client) { this.client = client; } @@ -84,7 +84,7 @@ public class GuacamoleSession { } - public void attachClient(GuacamoleClient client) throws GuacamoleException { + public void attachClient(GuacamoleTCPClient client) throws GuacamoleException { synchronized (session) { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java index a4989dcac..07e029cfa 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java @@ -2,7 +2,7 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleTCPClient; import net.sourceforge.guacamole.GuacamoleException; /* @@ -25,6 +25,6 @@ import net.sourceforge.guacamole.GuacamoleException; public interface GuacamoleClientProvider { - public GuacamoleClient createClient(HttpSession session) throws GuacamoleException; + public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java index 786939553..d69908f63 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java @@ -2,7 +2,7 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleTCPClient; import net.sourceforge.guacamole.GuacamoleException; /* @@ -25,7 +25,7 @@ import net.sourceforge.guacamole.GuacamoleException; public class NullGuacamoleClientProvider implements GuacamoleClientProvider { - public GuacamoleClient createClient(HttpSession session) throws GuacamoleException { + public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException { throw new GuacamoleException("Null provider will not create clients."); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java index 5b09c463e..46ca3e891 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java @@ -27,7 +27,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.Client; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleSession; @@ -54,7 +54,7 @@ public class Outbound extends HttpServlet { try { // Query new update from server - Client client = session.getClient(); + GuacamoleClient client = session.getClient(); // For all messages, until another stream is ready (we send at least one message) char[] message; From 573f92af025e876547dd1121eb93e4b6e3ec878b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 15:16:21 -0800 Subject: [PATCH 012/116] Added opcode enum --- .../guacamole/GuacamoleClient.java | 21 +++- .../guacamole/GuacamoleInstruction.java | 95 +++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java index 80f0c1bf5..c9e18afc9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java @@ -1,6 +1,7 @@ package net.sourceforge.guacamole; +import net.sourceforge.guacamole.GuacamoleInstruction.Operation; import net.sourceforge.guacamole.net.Configuration; /* @@ -24,14 +25,28 @@ import net.sourceforge.guacamole.net.Configuration; public abstract class GuacamoleClient { public abstract void write(char[] chunk, int off, int len) throws GuacamoleException; + + public void write(char[] chunk) throws GuacamoleException { + write(chunk, 0, chunk.length); + } + + public void write(GuacamoleInstruction instruction) throws GuacamoleException { + write(instruction.toString().toCharArray()); + } + public abstract char[] read() throws GuacamoleException; + public abstract void disconnect() throws GuacamoleException; public void connect(Configuration config) throws GuacamoleException { - // TODO: Send "select" and "connect" messages in client connect function (based on config) ... to be implemented. - char[] initMessages = "select:vnc;connect:localhost,5901,potato;".toCharArray(); - write(initMessages, 0, initMessages.length); + // Send protocol + write(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); + + // TODO: Wait for and read args message + + // Send args + write(new GuacamoleInstruction(Operation.CLIENT_CONNECT, "localhost", "5901", "potato")); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java new file mode 100644 index 000000000..e86ab6467 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java @@ -0,0 +1,95 @@ + +package net.sourceforge.guacamole; + +import java.util.HashMap; + +/* + * 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 . + */ + +public class GuacamoleInstruction { + + public enum Operation { + + CLIENT_SELECT("select"), + CLIENT_CONNECT("connect"), + + SERVER_ARGS("args"); + + private String opcode; + private Operation(String opcode) { this.opcode = opcode; } + + public String getOpcode() { + return opcode; + } + + // Maintain static hash of all opcodes + private static final HashMap opcodeToOperation; + static { + + opcodeToOperation = new HashMap(); + + for (Operation operation : Operation.values()) + opcodeToOperation.put(operation.getOpcode(), operation); + + } + + public Operation fromOpcode(String opcode) { + return opcodeToOperation.get(opcode); + } + + } + + private Operation operation; + private String[] args; + + public GuacamoleInstruction(Operation operation, String... args) { + this.operation = operation; + this.args = args; + } + + public Operation getOperation() { + return operation; + } + + public String[] getArgs() { + return args; + } + + @Override + public String toString() { + + StringBuilder buff = new StringBuilder(); + + buff.append(operation); + + if (args.length >= 1) + buff.append(':'); + + for (int i=0; i 0) + buff.append(','); + buff.append(args[i]); + } + + buff.append(';'); + + return buff.toString(); + + } + +} From adb577ca8e9f7635f3695cc413e7c71a5179af3a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 17:08:27 -0800 Subject: [PATCH 013/116] Implemented parsing of instructions --- .../guacamole/GuacamoleClient.java | 85 ++++++++++++++++++- .../guacamole/GuacamoleInstruction.java | 4 +- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java index c9e18afc9..ac1176975 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java @@ -1,6 +1,7 @@ package net.sourceforge.guacamole; +import java.util.LinkedList; import net.sourceforge.guacamole.GuacamoleInstruction.Operation; import net.sourceforge.guacamole.net.Configuration; @@ -36,6 +37,68 @@ public abstract class GuacamoleClient { public abstract char[] read() throws GuacamoleException; + private int instructionStart; + private char[] buffer; + + public GuacamoleInstruction readInstruction() throws GuacamoleException { + + // Fill buffer if not already filled + if (buffer == null) { + buffer = read(); + instructionStart = 0; + } + + // Locate end-of-opcode and end-of-instruction + int opcodeEnd = -1; + int instructionEnd = -1; + + for (int i=instructionStart; i opcodeEnd) + args = new String(buffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(","); + else + args = new String[0]; + + // Create instruction + GuacamoleInstruction instruction = new GuacamoleInstruction( + Operation.fromOpcode(opcode), + args + ); + + // Advance buffer + instructionStart = instructionEnd + 1; + if (instructionStart >= buffer.length) + buffer = null; + + return instruction; + + } + public abstract void disconnect() throws GuacamoleException; public void connect(Configuration config) throws GuacamoleException { @@ -43,10 +106,28 @@ public abstract class GuacamoleClient { // Send protocol write(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); - // TODO: Wait for and read args message + // Wait for server args + GuacamoleInstruction instruction; + do { + instruction = readInstruction(); + } while (instruction.getOperation() != Operation.SERVER_ARGS); + + // Build args list off provided names and config + String[] args = new String[instruction.getArgs().length]; + for (int i=0; i= 1) buff.append(':'); From b39dc62167837a3febbe91825279c63326c2d7c8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 23 Jan 2011 15:24:00 -0800 Subject: [PATCH 014/116] Created new tunnel servlet API, removed old Connect/Inbound/Outbound servlets, removed ClientProviders, updated GuacamoleProperties accordingly. --- .../guacamole/net/GuacamoleProperties.java | 34 ---- .../GuacamoleClientProvider.java | 30 ---- .../NullGuacamoleClientProvider.java | 32 ---- .../guacamole/net/tunnel/Connect.java | 54 ------ .../net/tunnel/GuacamoleTunnelServlet.java | 163 ++++++++++++++++++ .../guacamole/net/tunnel/Inbound.java | 67 ------- .../guacamole/net/tunnel/Outbound.java | 110 ------------ 7 files changed, 163 insertions(+), 327 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java index 97dff3552..647ffc44b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java @@ -21,10 +21,8 @@ package net.sourceforge.guacamole.net; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; import java.util.Properties; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; public class GuacamoleProperties { @@ -49,38 +47,6 @@ public class GuacamoleProperties { } - public static GuacamoleClientProvider getClientProvider() throws GuacamoleException { - - // Get client provider instance - try { - String sessionProviderClassName = GuacamoleProperties.getProperty("client-provider"); - Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance(); - if (!(obj instanceof GuacamoleClientProvider)) - throw new GuacamoleException("Specified client provider class is not a GuacamoleClientProvider"); - - return (GuacamoleClientProvider) obj; - } - catch (ClassNotFoundException e) { - throw new GuacamoleException("Session provider class not found", e); - } - catch (NoSuchMethodException e) { - throw new GuacamoleException("Default constructor for client provider not present", e); - } - catch (SecurityException e) { - throw new GuacamoleException("Creation of client provider disallowed; check your security settings", e); - } - catch (InstantiationException e) { - throw new GuacamoleException("Unable to instantiate client provider", e); - } - catch (IllegalAccessException e) { - throw new GuacamoleException("Unable to access default constructor of client provider", e); - } - catch (InvocationTargetException e) { - throw new GuacamoleException("Internal error in constructor of client provider", e.getTargetException()); - } - - } - public static String getProperty(String name) throws GuacamoleException { if (exception != null) throw exception; return properties.getProperty(name); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java deleted file mode 100644 index 07e029cfa..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java +++ /dev/null @@ -1,30 +0,0 @@ - -package net.sourceforge.guacamole.net.authentication; - -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleTCPClient; -import net.sourceforge.guacamole.GuacamoleException; - -/* - * 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 . - */ - -public interface GuacamoleClientProvider { - - public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException; - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java deleted file mode 100644 index d69908f63..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java +++ /dev/null @@ -1,32 +0,0 @@ - -package net.sourceforge.guacamole.net.authentication; - -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleTCPClient; -import net.sourceforge.guacamole.GuacamoleException; - -/* - * 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 . - */ - -public class NullGuacamoleClientProvider implements GuacamoleClientProvider { - - public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException { - throw new GuacamoleException("Null provider will not create clients."); - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java deleted file mode 100644 index 322578dec..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java +++ /dev/null @@ -1,54 +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 . - */ - -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.GuacamoleProperties; -import net.sourceforge.guacamole.net.GuacamoleSession; - - -public class Connect extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - GuacamoleSession session = new GuacamoleSession(httpSession); - session.attachClient( - GuacamoleProperties.getClientProvider().createClient(httpSession) - ); - - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - - } - -} - diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java new file mode 100644 index 000000000..68fbbe549 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -0,0 +1,163 @@ +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 . + */ + +import java.io.IOException; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.concurrent.locks.ReentrantLock; +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.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleSession; + + +public abstract class GuacamoleTunnelServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + service(request, response); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + service(request, response); + } + + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + try { + + String query = request.getQueryString(); + if (query == null) + throw new GuacamoleException("No query string provided."); + + if (query.equals("connect")) + doConnect(request, response); + + else if(query.equals("read")) + doRead(request, response); + + else if(query.equals("write")) + doWrite(request, response); + + else + throw new GuacamoleException("Invalid tunnel operation: " + query); + } + catch (GuacamoleException e) { + throw new ServletException(e); + } + + } + + protected abstract void doConnect(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException; + + protected void doRead(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + + HttpSession httpSession = request.getSession(false); + GuacamoleSession session = new GuacamoleSession(httpSession); + + ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); + instructionStreamLock.lock(); + + try { + + response.setContentType("text/plain"); + Writer out = response.getWriter(); + + try { + + // Query new update from server + GuacamoleClient 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.detachClient(); + 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(); + } + + } + + protected void doWrite(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + + HttpSession httpSession = request.getSession(false); + GuacamoleSession session = new GuacamoleSession(httpSession); + + // 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); + } + + } + +} + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java deleted file mode 100644 index 87007b14b..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java +++ /dev/null @@ -1,67 +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 . - */ - -import net.sourceforge.guacamole.GuacamoleException; - -import java.io.Reader; -import java.io.IOException; -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.net.GuacamoleSession; - - -public class Inbound extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - GuacamoleSession session = new GuacamoleSession(httpSession); - - // 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 ServletException(e); - } - - } - -} - diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java deleted file mode 100644 index 46ca3e891..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ /dev/null @@ -1,110 +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 . - */ - -import java.io.Writer; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.concurrent.locks.ReentrantLock; -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.GuacamoleClient; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; - - -public class Outbound extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - GuacamoleSession session = new GuacamoleSession(httpSession); - - ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); - instructionStreamLock.lock(); - - try { - - response.setContentType("text/plain"); - Writer out = response.getWriter(); - - try { - - // Query new update from server - GuacamoleClient 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.detachClient(); - 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 ServletException("UTF-8 not supported by Java.", e); - } - catch (IOException e) { - throw new ServletException("I/O error writing to servlet output stream.", e); - } - finally { - instructionStreamLock.unlock(); - } - - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - - } - -} - From 64c49232dcf6a6ce1b51493691566457dbd1834b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 23 Jan 2011 17:02:13 -0800 Subject: [PATCH 015/116] Using UTF-8 source encoding. --- guacamole-common/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index aa2f37ad0..dfc80ba55 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -9,6 +9,10 @@ guacamole-common http://guacamole.sourceforge.net/ + + UTF-8 + + From 8312d74997f2ec415517393a095ea054d69f1dfb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 17 Feb 2011 19:19:39 -0800 Subject: [PATCH 016/116] Removed SNAPSHOT --- guacamole-common/pom.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index dfc80ba55..be3d39b5b 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.3.0-SNAPSHOT + 0.3.0 guacamole-common http://guacamole.sourceforge.net/ @@ -48,11 +48,6 @@ guac-dev http://guac-dev.org/repo - - true - always - fail - From 1c8cbd000c453cd523c9d82a090297f3c0f09c81 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 18 Feb 2011 22:42:12 -0800 Subject: [PATCH 017/116] Fixed buffering issue with Chrome/Webkit --- .../guacamole/net/tunnel/GuacamoleTunnelServlet.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java index 68fbbe549..8cb1ddaff 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -84,7 +84,11 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { try { - response.setContentType("text/plain"); + // Note that although we are sending text, Webkit browsers will + // buffer 1024 bytes before starting a normal stream if we use + // anything but application/octet-stream. + response.setContentType("application/octet-stream"); + Writer out = response.getWriter(); try { From 1243360a385bd066dbb0df6f20988f180d669a07 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 1 Mar 2011 01:06:28 -0800 Subject: [PATCH 018/116] Added COPYING --- guacamole-common/COPYING | 661 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 guacamole-common/COPYING diff --git a/guacamole-common/COPYING b/guacamole-common/COPYING new file mode 100644 index 000000000..dba13ed2d --- /dev/null +++ b/guacamole-common/COPYING @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. From 09f1ecc52772c5c6909619ab4ccb3bc93acd890f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 8 Mar 2011 22:04:49 -0800 Subject: [PATCH 019/116] Fixed issue with repeated "no element found" errors --- .../guacamole/net/tunnel/GuacamoleTunnelServlet.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java index 8cb1ddaff..6a09fa0f7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -146,6 +146,13 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { HttpSession httpSession = request.getSession(false); GuacamoleSession session = new GuacamoleSession(httpSession); + // We still need to set the content type to avoid the default of + // text/html, as such a content type would cause some browsers to + // attempt to parse the result, even though the JavaScript client + // does not explicitly request such parsing. + response.setContentType("application/octet-stream"); + response.setContentLength(0); + // Send data try { From e063f1f21d70b817a7ac91016a8c39424cb80250 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 20 Mar 2011 16:57:47 -0700 Subject: [PATCH 020/116] Added socket connect timeout --- .../guacamole/GuacamoleTCPClient.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java index f0c0b23c1..a46c5c2dc 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java @@ -28,10 +28,14 @@ import java.io.InputStreamReader; import java.io.Writer; import java.io.OutputStreamWriter; +import java.net.InetSocketAddress; +import java.net.SocketAddress; public class GuacamoleTCPClient extends GuacamoleClient { + private static final int SOCKET_TIMEOUT = 5000; + private Socket sock; private Reader input; private Writer output; @@ -39,9 +43,21 @@ public class GuacamoleTCPClient extends GuacamoleClient { public GuacamoleTCPClient(String hostname, int port) throws GuacamoleException { try { - sock = new Socket(InetAddress.getByName(hostname), port); + + // Get address + SocketAddress address = new InetSocketAddress( + InetAddress.getByName(hostname), + port + ); + + // Connect with timeout + sock = new Socket(); + sock.connect(address, SOCKET_TIMEOUT); + + // On successful connect, retrieve I/O streams input = new InputStreamReader(sock.getInputStream()); output = new OutputStreamWriter(sock.getOutputStream()); + } catch (IOException e) { throw new GuacamoleException(e); From a52476de0578c6e989e48de588fce6ca55798aae Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 20 Mar 2011 19:33:19 -0700 Subject: [PATCH 021/116] Added read timeout. --- .../java/net/sourceforge/guacamole/GuacamoleTCPClient.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java index a46c5c2dc..0a1c254e7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java @@ -34,7 +34,7 @@ import java.net.SocketAddress; public class GuacamoleTCPClient extends GuacamoleClient { - private static final int SOCKET_TIMEOUT = 5000; + private static final int SOCKET_TIMEOUT = 15000; private Socket sock; private Reader input; @@ -54,6 +54,9 @@ public class GuacamoleTCPClient extends GuacamoleClient { sock = new Socket(); sock.connect(address, SOCKET_TIMEOUT); + // Set read timeout + sock.setSoTimeout(SOCKET_TIMEOUT); + // On successful connect, retrieve I/O streams input = new InputStreamReader(sock.getInputStream()); output = new OutputStreamWriter(sock.getOutputStream()); From c0205653979794e3a5f26b8309d3f1e10cce401f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 8 Apr 2011 16:28:12 -0700 Subject: [PATCH 022/116] Added tunnel registry and support for multiple tunnels per session. --- .../guacamole/net/GuacamoleSession.java | 109 ++++-------------- .../guacamole/net/tunnel/GuacamoleTunnel.java | 53 +++++++++ .../net/tunnel/GuacamoleTunnelServlet.java | 47 +++++--- 3 files changed, 109 insertions(+), 100 deletions(-) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnel.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java index 430a4aae5..7cd90d93a 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -19,54 +19,16 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import java.util.concurrent.locks.ReentrantLock; +import net.sourceforge.guacamole.net.tunnel.GuacamoleTunnel; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import net.sourceforge.guacamole.GuacamoleClient; -import net.sourceforge.guacamole.GuacamoleTCPClient; import net.sourceforge.guacamole.GuacamoleException; public class GuacamoleSession { private final HttpSession session; - private SessionClient client; - private ReentrantLock instructionStreamLock; - - public class SessionClient extends GuacamoleClient implements HttpSessionBindingListener { - - private GuacamoleClient client; - - public SessionClient(GuacamoleClient client) { - this.client = client; - } - - 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(); - } - - } + private ConcurrentMap tunnels; public GuacamoleSession(HttpSession session) throws GuacamoleException { @@ -77,57 +39,30 @@ public class GuacamoleSession { synchronized (session) { - client = (SessionClient) session.getAttribute("CLIENT"); - instructionStreamLock = (ReentrantLock) session.getAttribute("INSTRUCTION_STREAM_LOCK"); - - } - - } - - public void attachClient(GuacamoleTCPClient client) throws GuacamoleException { - - synchronized (session) { - - this.client = new SessionClient(client); - session.setAttribute("CLIENT", this.client); - - instructionStreamLock = new ReentrantLock(); - session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock); - - } - - } - - public SessionClient getClient() throws GuacamoleException { - synchronized (session) { - - if (client == null) - throw new GuacamoleException("Client not yet attached."); - - return client; - } - } - - public void invalidate() { - session.invalidate(); - } - - public void detachClient() throws GuacamoleException { - - synchronized (session) { - - if (client != null) { - client.disconnect(); - session.removeAttribute("CLIENT"); - client = null; + tunnels = (ConcurrentMap) session.getAttribute("GUAC_TUNNELS"); + if (tunnels == null) { + tunnels = new ConcurrentHashMap(); + session.setAttribute("GUAC_TUNNELS", tunnels); } } } - public ReentrantLock getInstructionStreamLock() { - return instructionStreamLock; + public void invalidate() { + session.invalidate(); + } + + public void attachTunnel(GuacamoleTunnel tunnel) throws GuacamoleException { + tunnels.put(tunnel.getUUID().toString(), tunnel); + } + + public void detachTunnel(GuacamoleTunnel tunnel) throws GuacamoleException { + tunnels.remove(tunnel.getUUID().toString()); + } + + public GuacamoleTunnel getTunnel(String tunnelUUID) { + return tunnels.get(tunnelUUID); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnel.java new file mode 100644 index 000000000..8f324141e --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnel.java @@ -0,0 +1,53 @@ + +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 . + */ + +import java.util.UUID; +import java.util.concurrent.locks.ReentrantLock; +import net.sourceforge.guacamole.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleException; + +public class GuacamoleTunnel { + + private UUID uuid; + private GuacamoleClient client; + private ReentrantLock instructionStreamLock; + + public GuacamoleTunnel(GuacamoleClient client) throws GuacamoleException { + + this.client = client; + instructionStreamLock = new ReentrantLock(); + uuid = UUID.randomUUID(); + + } + + public GuacamoleClient getClient() throws GuacamoleException { + return client; + } + + public ReentrantLock getInstructionStreamLock() { + return instructionStreamLock; + } + + public UUID getUUID() { + return uuid; + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java index 6a09fa0f7..fa270fc86 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -54,14 +54,25 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { if (query == null) throw new GuacamoleException("No query string provided."); - if (query.equals("connect")) - doConnect(request, response); + if (query.equals("connect")) { - else if(query.equals("read")) - doRead(request, response); + GuacamoleTunnel tunnel = doConnect(request); + if (tunnel != null) { + try { + response.getWriter().println(tunnel.getUUID().toString()); + } + catch (IOException e) { + throw new GuacamoleException(e); + } + } - else if(query.equals("write")) - doWrite(request, response); + } + + else if(query.startsWith("read:")) + doRead(request, response, query.substring(5)); + + else if(query.startsWith("write:")) + doWrite(request, response, query.substring(6)); else throw new GuacamoleException("Invalid tunnel operation: " + query); @@ -72,14 +83,18 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } - protected abstract void doConnect(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException; + protected abstract GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException; - protected void doRead(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + protected void doRead(HttpServletRequest request, HttpServletResponse response, String tunnelUUID) throws GuacamoleException { HttpSession httpSession = request.getSession(false); GuacamoleSession session = new GuacamoleSession(httpSession); - ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); + GuacamoleTunnel tunnel = session.getTunnel(tunnelUUID); + if (tunnel == null) + throw new GuacamoleException("No such tunnel."); + + ReentrantLock instructionStreamLock = tunnel.getInstructionStreamLock(); instructionStreamLock.lock(); try { @@ -94,7 +109,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { try { // Query new update from server - GuacamoleClient client = session.getClient(); + GuacamoleClient client = tunnel.getClient(); // For all messages, until another stream is ready (we send at least one message) char[] message; @@ -112,7 +127,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } if (message == null) { - session.detachClient(); + session.detachTunnel(tunnel); throw new GuacamoleException("Disconnected."); } @@ -141,11 +156,15 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } - protected void doWrite(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + protected void doWrite(HttpServletRequest request, HttpServletResponse response, String tunnelUUID) throws GuacamoleException { HttpSession httpSession = request.getSession(false); GuacamoleSession session = new GuacamoleSession(httpSession); + GuacamoleTunnel tunnel = session.getTunnel(tunnelUUID); + if (tunnel == null) + throw new GuacamoleException("No such tunnel."); + // We still need to set the content type to avoid the default of // text/html, as such a content type would cause some browsers to // attempt to parse the result, even though the JavaScript client @@ -156,12 +175,14 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { // Send data try { + GuacamoleClient client = tunnel.getClient(); + 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); + client.write(buffer, 0, length); } catch (IOException e) { From 2778429fbaba067fe2d0788f602de2f69301e67c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 8 Apr 2011 22:40:25 -0700 Subject: [PATCH 023/116] Improved error handling --- .../net/tunnel/GuacamoleTunnelServlet.java | 78 ++++++++++++------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java index fa270fc86..92ee60505 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -54,6 +54,8 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { if (query == null) throw new GuacamoleException("No query string provided."); + // If connect operation, call doConnect() and return tunnel UUID + // in response. if (query.equals("connect")) { GuacamoleTunnel tunnel = doConnect(request); @@ -68,17 +70,48 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } + // If read operation, call doRead() with tunnel UUID else if(query.startsWith("read:")) doRead(request, response, query.substring(5)); + // If write operation, call doWrite() with tunnel UUID else if(query.startsWith("write:")) doWrite(request, response, query.substring(6)); + // Otherwise, invalid operation else throw new GuacamoleException("Invalid tunnel operation: " + query); } + + // Catch any thrown guacamole exception and attempt to pass within the + // HTTP response. catch (GuacamoleException e) { - throw new ServletException(e); + + try { + + // If response not committed, send error code along with + // message. + if (!response.isCommitted()) { + response.setHeader("X-Guacamole-Error-Message", e.getMessage()); + response.sendError( + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + e.getMessage() + ); + } + + // If unable to send error code, rethrow as servlet exception + else + throw new ServletException(e); + + } + catch (IOException ioe) { + + // If unable to send error at all due to I/O problems, + // rethrow as servlet exception + throw new ServletException(ioe); + + } + } } @@ -106,36 +139,27 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { Writer out = response.getWriter(); - try { + // Query new update from server + GuacamoleClient client = tunnel.getClient(); - // Query new update from server - GuacamoleClient client = tunnel.getClient(); + // For all messages, until another stream is ready (we send at least one message) + char[] message; + while ((message = client.read()) != null) { - // 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.detachTunnel(tunnel); - throw new GuacamoleException("Disconnected."); - } - - } - catch (GuacamoleException e) { - out.write("error:" + e.getMessage() + ";"); + // 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.detachTunnel(tunnel); + throw new GuacamoleException("Disconnected."); } // End-of-instructions marker From 11b29d8709fdb156644d93b35715e28c8491a6c2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 May 2011 23:05:32 -0700 Subject: [PATCH 024/116] Major refactor of API (new interfaces, semantic changes) --- .../guacamole/GuacamoleClient.java | 134 ----------------- .../{net => }/GuacamoleProperties.java | 2 +- .../guacamole/io/GuacamoleReader.java | 30 ++++ .../guacamole/io/GuacamoleWriter.java | 31 ++++ .../ReaderGuacamoleReader.java} | 140 ++++++++++-------- .../guacamole/io/WriterGuacamoleWriter.java | 59 ++++++++ .../net/AbstractGuacamoleSocket.java | 69 +++++++++ ...camoleTunnel.java => GuacamoleSocket.java} | 40 ++--- .../guacamole/net/GuacamoleTunnel.java | 77 ++++++++++ .../guacamole/net/TCPGuacamoleSocket.java | 95 ++++++++++++ .../{net => protocol}/Configuration.java | 2 +- .../{ => protocol}/GuacamoleInstruction.java | 2 +- .../{net => servlet}/GuacamoleSession.java | 4 +- .../GuacamoleTunnelServlet.java | 29 ++-- 14 files changed, 468 insertions(+), 246 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/{net => }/GuacamoleProperties.java (99%) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/{GuacamoleTCPClient.java => io/ReaderGuacamoleReader.java} (53%) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/{tunnel/GuacamoleTunnel.java => GuacamoleSocket.java} (52%) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/{net => protocol}/Configuration.java (96%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/{ => protocol}/GuacamoleInstruction.java (98%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/{net => servlet}/GuacamoleSession.java (95%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/{net/tunnel => servlet}/GuacamoleTunnelServlet.java (90%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java deleted file mode 100644 index ac1176975..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java +++ /dev/null @@ -1,134 +0,0 @@ - -package net.sourceforge.guacamole; - -import java.util.LinkedList; -import net.sourceforge.guacamole.GuacamoleInstruction.Operation; -import net.sourceforge.guacamole.net.Configuration; - -/* - * 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 . - */ - -public abstract class GuacamoleClient { - - public abstract void write(char[] chunk, int off, int len) throws GuacamoleException; - - public void write(char[] chunk) throws GuacamoleException { - write(chunk, 0, chunk.length); - } - - public void write(GuacamoleInstruction instruction) throws GuacamoleException { - write(instruction.toString().toCharArray()); - } - - public abstract char[] read() throws GuacamoleException; - - private int instructionStart; - private char[] buffer; - - public GuacamoleInstruction readInstruction() throws GuacamoleException { - - // Fill buffer if not already filled - if (buffer == null) { - buffer = read(); - instructionStart = 0; - } - - // Locate end-of-opcode and end-of-instruction - int opcodeEnd = -1; - int instructionEnd = -1; - - for (int i=instructionStart; i opcodeEnd) - args = new String(buffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(","); - else - args = new String[0]; - - // Create instruction - GuacamoleInstruction instruction = new GuacamoleInstruction( - Operation.fromOpcode(opcode), - args - ); - - // Advance buffer - instructionStart = instructionEnd + 1; - if (instructionStart >= buffer.length) - buffer = null; - - return instruction; - - } - - public abstract void disconnect() throws GuacamoleException; - - public void connect(Configuration config) throws GuacamoleException { - - // Send protocol - write(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); - - // Wait for server args - GuacamoleInstruction instruction; - do { - instruction = readInstruction(); - } while (instruction.getOperation() != Operation.SERVER_ARGS); - - // Build args list off provided names and config - String[] args = new String[instruction.getArgs().length]; - for (int i=0; i. + */ + +public interface GuacamoleReader { + + public char[] read() throws GuacamoleException; + public GuacamoleInstruction readInstruction() throws GuacamoleException; + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java new file mode 100644 index 000000000..2d0168ed1 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java @@ -0,0 +1,31 @@ + +package net.sourceforge.guacamole.io; + +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; + +/* + * 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 . + */ + +public interface GuacamoleWriter { + + public void write(char[] chunk, int off, int len) throws GuacamoleException; + public void write(char[] chunk) throws GuacamoleException; + public void writeInstruction(GuacamoleInstruction instruction) throws GuacamoleException; + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java similarity index 53% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 0a1c254e7..a99f4055f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -1,5 +1,13 @@ -package net.sourceforge.guacamole; +package net.sourceforge.guacamole.io; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; +import net.sourceforge.guacamole.protocol.Configuration; /* * Guacamole - Clientless Remote Desktop @@ -19,77 +27,21 @@ package net.sourceforge.guacamole; * along with this program. If not, see . */ -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; +public class ReaderGuacamoleReader implements GuacamoleReader { -import java.io.Reader; -import java.io.InputStreamReader; - -import java.io.Writer; -import java.io.OutputStreamWriter; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - - -public class GuacamoleTCPClient extends GuacamoleClient { - - private static final int SOCKET_TIMEOUT = 15000; - - private Socket sock; private Reader input; - private Writer output; - public GuacamoleTCPClient(String hostname, int port) throws GuacamoleException { - - try { - - // Get address - SocketAddress address = new InetSocketAddress( - InetAddress.getByName(hostname), - port - ); - - // Connect with timeout - sock = new Socket(); - sock.connect(address, SOCKET_TIMEOUT); - - // Set read timeout - sock.setSoTimeout(SOCKET_TIMEOUT); - - // On successful connect, retrieve I/O streams - 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); - } + public ReaderGuacamoleReader(Reader input) { + this.input = input; } private int usedLength = 0; private char[] buffer = new char[20000]; + private int instructionStart; + private char[] instructionBuffer; + + @Override public char[] read() throws GuacamoleException { try { @@ -142,4 +94,64 @@ public class GuacamoleTCPClient extends GuacamoleClient { } + @Override + public GuacamoleInstruction readInstruction() throws GuacamoleException { + + // Fill instructionBuffer if not already filled + if (instructionBuffer == null) { + instructionBuffer = read(); + instructionStart = 0; + } + + // Locate end-of-opcode and end-of-instruction + int opcodeEnd = -1; + int instructionEnd = -1; + + for (int i=instructionStart; i opcodeEnd) + args = new String(instructionBuffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(","); + else + args = new String[0]; + + // Create instruction + GuacamoleInstruction instruction = new GuacamoleInstruction( + Operation.fromOpcode(opcode), + args + ); + + // Advance instructionBuffer + instructionStart = instructionEnd + 1; + if (instructionStart >= instructionBuffer.length) + instructionBuffer = null; + + return instruction; + + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java new file mode 100644 index 000000000..db6fc849b --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -0,0 +1,59 @@ + +package net.sourceforge.guacamole.io; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; +import net.sourceforge.guacamole.protocol.Configuration; + +/* + * 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 . + */ + +public class WriterGuacamoleWriter implements GuacamoleWriter { + + private Writer output; + + public WriterGuacamoleWriter(Writer output) { + this.output = output; + } + + @Override + 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); + } + } + + @Override + public void write(char[] chunk) throws GuacamoleException { + write(chunk, 0, chunk.length); + } + + @Override + public void writeInstruction(GuacamoleInstruction instruction) throws GuacamoleException { + write(instruction.toString().toCharArray()); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java new file mode 100644 index 000000000..3d999ce06 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java @@ -0,0 +1,69 @@ + +package net.sourceforge.guacamole.net; + +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.io.GuacamoleWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; +import net.sourceforge.guacamole.protocol.Configuration; + +/* + * 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 . + */ + +public abstract class AbstractGuacamoleSocket implements GuacamoleSocket { + + @Override + public void connect(Configuration config) throws GuacamoleException { + + // Get reader and writer + GuacamoleReader reader = getReader(); + GuacamoleWriter writer = getWriter(); + + // Send protocol + writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); + + // Wait for server args + GuacamoleInstruction instruction; + do { + instruction = reader.readInstruction(); + } while (instruction.getOperation() != Operation.SERVER_ARGS); + + // Build args list off provided names and config + String[] args = new String[instruction.getArgs().length]; + for (int i=0; i. */ -import java.util.UUID; -import java.util.concurrent.locks.ReentrantLock; -import net.sourceforge.guacamole.GuacamoleClient; -import net.sourceforge.guacamole.GuacamoleException; +public interface GuacamoleSocket { -public class GuacamoleTunnel { + public GuacamoleReader getReader(); + public GuacamoleWriter getWriter(); - private UUID uuid; - private GuacamoleClient client; - private ReentrantLock instructionStreamLock; - - public GuacamoleTunnel(GuacamoleClient client) throws GuacamoleException { - - this.client = client; - instructionStreamLock = new ReentrantLock(); - uuid = UUID.randomUUID(); - - } - - public GuacamoleClient getClient() throws GuacamoleException { - return client; - } - - public ReentrantLock getInstructionStreamLock() { - return instructionStreamLock; - } - - public UUID getUUID() { - return uuid; - } + public void connect(Configuration config) throws GuacamoleException; + public void disconnect() throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java new file mode 100644 index 000000000..3d586ff41 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -0,0 +1,77 @@ + +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 . + */ + +import java.util.UUID; +import java.util.concurrent.locks.ReentrantLock; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.net.GuacamoleSocket; +import net.sourceforge.guacamole.io.GuacamoleWriter; + +public class GuacamoleTunnel { + + private UUID uuid; + private GuacamoleSocket socket; + + private ReentrantLock readerLock; + private ReentrantLock writerLock; + + public GuacamoleTunnel(GuacamoleSocket socket) throws GuacamoleException { + + this.socket = socket; + uuid = UUID.randomUUID(); + + readerLock = new ReentrantLock(); + writerLock = new ReentrantLock(); + + } + + public GuacamoleReader acquireReader() { + readerLock.lock(); + return socket.getReader(); + } + + public void releaseReader() { + readerLock.unlock(); + } + + public boolean hasQueuedReaderThreads() { + return readerLock.hasQueuedThreads(); + } + + public GuacamoleWriter acquireWriter() { + writerLock.lock(); + return socket.getWriter(); + } + + public void releaseWriter() { + writerLock.unlock(); + } + + public boolean hasQueuedWriterThreads() { + return writerLock.hasQueuedThreads(); + } + + public UUID getUUID() { + return uuid; + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java new file mode 100644 index 000000000..15feafb34 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java @@ -0,0 +1,95 @@ + +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 . + */ + +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.io.ReaderGuacamoleReader; +import net.sourceforge.guacamole.io.WriterGuacamoleWriter; +import net.sourceforge.guacamole.io.GuacamoleWriter; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import java.io.InputStreamReader; + +import java.io.OutputStreamWriter; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import net.sourceforge.guacamole.GuacamoleException; + + +public class TCPGuacamoleSocket extends AbstractGuacamoleSocket { + + private GuacamoleReader reader; + private GuacamoleWriter writer; + + private static final int SOCKET_TIMEOUT = 15000; + private Socket sock; + + public TCPGuacamoleSocket(String hostname, int port) throws GuacamoleException { + + try { + + // Get address + SocketAddress address = new InetSocketAddress( + InetAddress.getByName(hostname), + port + ); + + // Connect with timeout + sock = new Socket(); + sock.connect(address, SOCKET_TIMEOUT); + + // Set read timeout + sock.setSoTimeout(SOCKET_TIMEOUT); + + // On successful connect, retrieve I/O streams + reader = new ReaderGuacamoleReader(new InputStreamReader(sock.getInputStream())); + writer = new WriterGuacamoleWriter(new OutputStreamWriter(sock.getOutputStream())); + + } + catch (IOException e) { + throw new GuacamoleException(e); + } + + } + + @Override + public void disconnect() throws GuacamoleException { + try { + sock.close(); + } + catch (IOException e) { + throw new GuacamoleException(e); + } + } + + @Override + public GuacamoleReader getReader() { + return reader; + } + + @Override + public GuacamoleWriter getWriter() { + return writer; + } + + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java similarity index 96% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java index b086cf1ac..7e4362590 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java @@ -1,5 +1,5 @@ -package net.sourceforge.guacamole.net; +package net.sourceforge.guacamole.protocol; import java.util.HashMap; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java similarity index 98% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index d6d3e9c62..153b9e20f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -1,5 +1,5 @@ -package net.sourceforge.guacamole; +package net.sourceforge.guacamole.protocol; import java.util.HashMap; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java similarity index 95% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index 7cd90d93a..dcaaf394d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -1,5 +1,5 @@ -package net.sourceforge.guacamole.net; +package net.sourceforge.guacamole.servlet; /* * Guacamole - Clientless Remote Desktop @@ -19,11 +19,11 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import net.sourceforge.guacamole.net.tunnel.GuacamoleTunnel; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleTunnel; public class GuacamoleSession { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java similarity index 90% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 92ee60505..7848b2431 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -1,4 +1,4 @@ -package net.sourceforge.guacamole.net.tunnel; +package net.sourceforge.guacamole.servlet; /* * Guacamole - Clientless Remote Desktop @@ -18,20 +18,21 @@ package net.sourceforge.guacamole.net.tunnel; * along with this program. If not, see . */ +import net.sourceforge.guacamole.net.GuacamoleTunnel; import java.io.IOException; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.io.Writer; -import java.util.concurrent.locks.ReentrantLock; 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.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.net.GuacamoleSocket; +import net.sourceforge.guacamole.io.GuacamoleWriter; public abstract class GuacamoleTunnelServlet extends HttpServlet { @@ -127,8 +128,8 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { if (tunnel == null) throw new GuacamoleException("No such tunnel."); - ReentrantLock instructionStreamLock = tunnel.getInstructionStreamLock(); - instructionStreamLock.lock(); + // Obtain exclusive read access + GuacamoleReader reader = tunnel.acquireReader(); try { @@ -139,12 +140,9 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { Writer out = response.getWriter(); - // Query new update from server - GuacamoleClient client = tunnel.getClient(); - // For all messages, until another stream is ready (we send at least one message) char[] message; - while ((message = client.read()) != null) { + while ((message = reader.read()) != null) { // Get message output bytes out.write(message, 0, message.length); @@ -152,7 +150,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { response.flushBuffer(); // No more messages another stream can take over - if (instructionStreamLock.hasQueuedThreads()) + if (tunnel.hasQueuedReaderThreads()) break; } @@ -175,7 +173,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { throw new GuacamoleException("I/O error writing to servlet output stream.", e); } finally { - instructionStreamLock.unlock(); + tunnel.releaseReader(); } } @@ -199,19 +197,22 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { // Send data try { - GuacamoleClient client = tunnel.getClient(); + GuacamoleWriter writer = tunnel.acquireWriter(); Reader input = request.getReader(); char[] buffer = new char[8192]; int length; while ((length = input.read(buffer, 0, buffer.length)) != -1) - client.write(buffer, 0, length); + writer.write(buffer, 0, length); } catch (IOException e) { throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e); } + finally { + tunnel.releaseWriter(); + } } From 3b7e71a4028dde2b2bb6933ef55e3c38f6254a09 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 May 2011 23:41:10 -0700 Subject: [PATCH 025/116] Removed connect() from GuacamoleSocket. Added ConfiguredSocket for providing restricted pre-configured (finished with handshake and connect) GuacamoleSockets. --- .../guacamole/GuacamoleProperties.java | 1 - .../guacamole/io/ReaderGuacamoleReader.java | 2 -- .../guacamole/io/WriterGuacamoleWriter.java | 3 -- .../guacamole/net/GuacamoleSocket.java | 4 +-- .../guacamole/net/GuacamoleTunnel.java | 1 - .../guacamole/net/TCPGuacamoleSocket.java | 4 +-- .../ConfiguredSocket.java} | 36 +++++++++++++------ .../servlet/GuacamoleTunnelServlet.java | 2 +- 8 files changed, 29 insertions(+), 24 deletions(-) rename guacamole-common/src/main/java/net/sourceforge/guacamole/{net/AbstractGuacamoleSocket.java => protocol/ConfiguredSocket.java} (73%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java index d96b1d580..9bf3ebf3b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java @@ -22,7 +22,6 @@ package net.sourceforge.guacamole; import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import net.sourceforge.guacamole.GuacamoleException; public class GuacamoleProperties { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index a99f4055f..8b21d5be9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -3,11 +3,9 @@ package net.sourceforge.guacamole.io; import java.io.IOException; import java.io.Reader; -import java.io.Writer; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; -import net.sourceforge.guacamole.protocol.Configuration; /* * Guacamole - Clientless Remote Desktop diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index db6fc849b..a92337e50 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -2,12 +2,9 @@ package net.sourceforge.guacamole.io; import java.io.IOException; -import java.io.Reader; import java.io.Writer; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; -import net.sourceforge.guacamole.protocol.Configuration; /* * Guacamole - Clientless Remote Desktop diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index 8edb44b6e..2ad5af5a4 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -1,7 +1,6 @@ package net.sourceforge.guacamole.net; -import net.sourceforge.guacamole.protocol.Configuration; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; @@ -29,7 +28,6 @@ public interface GuacamoleSocket { public GuacamoleReader getReader(); public GuacamoleWriter getWriter(); - public void connect(Configuration config) throws GuacamoleException; - public void disconnect() throws GuacamoleException; + public void close() throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 3d586ff41..f03492e7c 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -23,7 +23,6 @@ import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; -import net.sourceforge.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.io.GuacamoleWriter; public class GuacamoleTunnel { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java index 15feafb34..cf21e0f6d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java @@ -35,7 +35,7 @@ import java.net.SocketAddress; import net.sourceforge.guacamole.GuacamoleException; -public class TCPGuacamoleSocket extends AbstractGuacamoleSocket { +public class TCPGuacamoleSocket implements GuacamoleSocket { private GuacamoleReader reader; private GuacamoleWriter writer; @@ -72,7 +72,7 @@ public class TCPGuacamoleSocket extends AbstractGuacamoleSocket { } @Override - public void disconnect() throws GuacamoleException { + public void close() throws GuacamoleException { try { sock.close(); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java similarity index 73% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java index 3d999ce06..594c20f8d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java @@ -1,15 +1,11 @@ -package net.sourceforge.guacamole.net; +package net.sourceforge.guacamole.protocol; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction; +import net.sourceforge.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; -import net.sourceforge.guacamole.protocol.Configuration; /* * Guacamole - Clientless Remote Desktop @@ -29,14 +25,17 @@ import net.sourceforge.guacamole.protocol.Configuration; * along with this program. If not, see . */ -public abstract class AbstractGuacamoleSocket implements GuacamoleSocket { +public class ConfiguredSocket implements GuacamoleSocket { - @Override - public void connect(Configuration config) throws GuacamoleException { + private GuacamoleSocket socket; + + public ConfiguredSocket(GuacamoleSocket socket, Configuration config) throws GuacamoleException { + + this.socket = socket; // Get reader and writer - GuacamoleReader reader = getReader(); - GuacamoleWriter writer = getWriter(); + GuacamoleReader reader = socket.getReader(); + GuacamoleWriter writer = socket.getWriter(); // Send protocol writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); @@ -66,4 +65,19 @@ public abstract class AbstractGuacamoleSocket implements GuacamoleSocket { } + @Override + public GuacamoleWriter getWriter() { + return socket.getWriter(); + } + + @Override + public GuacamoleReader getReader() { + return socket.getReader(); + } + + @Override + public void close() throws GuacamoleException { + socket.close(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 7848b2431..27106b9b8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; -import net.sourceforge.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.io.GuacamoleWriter; @@ -47,6 +46,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { service(request, response); } + @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { From 78a957b9788d9975b14a1198f8adbf635fb9b805 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 May 2011 23:47:01 -0700 Subject: [PATCH 026/116] Renamed. --- .../{ConfiguredSocket.java => ConfiguredGuacamoleSocket.java} | 4 ++-- .../{Configuration.java => GuacamoleConfiguration.java} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/{ConfiguredSocket.java => ConfiguredGuacamoleSocket.java} (93%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/{Configuration.java => GuacamoleConfiguration.java} (97%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java similarity index 93% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 594c20f8d..f177b083e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -25,11 +25,11 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; * along with this program. If not, see . */ -public class ConfiguredSocket implements GuacamoleSocket { +public class ConfiguredGuacamoleSocket implements GuacamoleSocket { private GuacamoleSocket socket; - public ConfiguredSocket(GuacamoleSocket socket, Configuration config) throws GuacamoleException { + public ConfiguredGuacamoleSocket(GuacamoleSocket socket, GuacamoleConfiguration config) throws GuacamoleException { this.socket = socket; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java similarity index 97% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 7e4362590..690887ae9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -21,7 +21,7 @@ import java.util.HashMap; * along with this program. If not, see . */ -public class Configuration { +public class GuacamoleConfiguration { private String protocol; private HashMap parameters = new HashMap(); From 3dd0c20ba967cfdfec3ef446f079d0aaa549c98b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 12 May 2011 23:49:09 -0700 Subject: [PATCH 027/116] TCP -> Inet --- .../net/{TCPGuacamoleSocket.java => InetGuacamoleSocket.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/{TCPGuacamoleSocket.java => InetGuacamoleSocket.java} (94%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java similarity index 94% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index cf21e0f6d..5f56c695a 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -35,7 +35,7 @@ import java.net.SocketAddress; import net.sourceforge.guacamole.GuacamoleException; -public class TCPGuacamoleSocket implements GuacamoleSocket { +public class InetGuacamoleSocket implements GuacamoleSocket { private GuacamoleReader reader; private GuacamoleWriter writer; @@ -43,7 +43,7 @@ public class TCPGuacamoleSocket implements GuacamoleSocket { private static final int SOCKET_TIMEOUT = 15000; private Socket sock; - public TCPGuacamoleSocket(String hostname, int port) throws GuacamoleException { + public InetGuacamoleSocket(String hostname, int port) throws GuacamoleException { try { From a8f58624391de7806b35b8dad0e323fc505942dd Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 13 May 2011 00:48:15 -0700 Subject: [PATCH 028/116] JavaDoc, refactored properties API. --- .../guacamole/GuacamoleException.java | 25 +++ .../guacamole/GuacamoleProperties.java | 151 ------------------ .../properties/FileGuacamoleProperty.java | 32 ++++ .../properties/GuacamoleProperties.java | 74 +++++++++ .../properties/GuacamoleProperty.java | 31 ++++ .../properties/IntegerGuacamoleProperty.java | 39 +++++ .../properties/StringGuacamoleProperty.java | 31 ++++ 7 files changed, 232 insertions(+), 151 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java index 3a09c5ac7..cb2e586fa 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java @@ -19,16 +19,41 @@ package net.sourceforge.guacamole; * along with this program. If not, see . */ + +/** + * A generic exception thrown when parts of the Guacamole API encounter + * errors. + * + * @author Michael Jumper + */ public class GuacamoleException extends Exception { + /** + * Creates a new GuacamoleException with the given message and cause. + * + * @param message A human readable description of the exception that + * occurred. + * @param cause The cause of this exception. + */ public GuacamoleException(String message, Throwable cause) { super(message, cause); } + /** + * Creates a new GuacamoleException with the given message. + * + * @param message A human readable description of the exception that + * occurred. + */ public GuacamoleException(String message) { super(message); } + /** + * Creates a new GuacamoleException with the given cause. + * + * @param cause The cause of this exception. + */ public GuacamoleException(Throwable cause) { super(cause); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java deleted file mode 100644 index 9bf3ebf3b..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleProperties.java +++ /dev/null @@ -1,151 +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 . - */ - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -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); - } - - protected static String humanReadableList(Object... values) { - - String list = ""; - for (int i=0; i= 1) - list += ", "; - - if (i == values.length -1) - list += " or "; - - list += "\"" + values[i] + "\""; - } - - return list; - - } - - public static String getProperty(String name, String defaultValue, String... allowedValues) throws GuacamoleException { - - String value = 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)); - } - - public static boolean getBooleanProperty(String name, Boolean defaultValue) throws GuacamoleException { - - String value = 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\"."); - - } - - public static int getIntProperty(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException { - - String parmString = 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/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java new file mode 100644 index 000000000..c51e86dd8 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -0,0 +1,32 @@ + +package net.sourceforge.guacamole.properties; + +/* + * 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 . + */ + +import java.io.File; +import net.sourceforge.guacamole.GuacamoleException; + +public abstract class FileGuacamoleProperty implements GuacamoleProperty { + + @Override + public File parseValue(String value) throws GuacamoleException { + return new File(value); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java new file mode 100644 index 000000000..76f713849 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -0,0 +1,74 @@ + +package net.sourceforge.guacamole.properties; + +/* + * 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 . + */ + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import net.sourceforge.guacamole.GuacamoleException; + +public class GuacamoleProperties { + + public static final StringGuacamoleProperty GUACD_HOSTNAME = new StringGuacamoleProperty() { + + @Override + public String getName() { return "guacd-hostname"; } + + }; + + public static final IntegerGuacamoleProperty GUACD_PORT = new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "guacd-port"; } + + }; + + 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 Type getProperty(GuacamoleProperty property) throws GuacamoleException { + + if (exception != null) + throw exception; + + return property.parseValue(properties.getProperty(property.getName())); + + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java new file mode 100644 index 000000000..b32072554 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java @@ -0,0 +1,31 @@ + +package net.sourceforge.guacamole.properties; + +import net.sourceforge.guacamole.GuacamoleException; + +/* + * 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 . + */ + + +public interface GuacamoleProperty { + + public String getName(); + + public Type parseValue(String value) throws GuacamoleException; + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java new file mode 100644 index 000000000..6c6919d08 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java @@ -0,0 +1,39 @@ + +package net.sourceforge.guacamole.properties; + +/* + * 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 . + */ + +import net.sourceforge.guacamole.GuacamoleException; + +public abstract class IntegerGuacamoleProperty implements GuacamoleProperty { + + @Override + public Integer parseValue(String value) throws GuacamoleException { + + try { + Integer integer = new Integer(value); + return integer; + } + catch (NumberFormatException e) { + throw new GuacamoleException("Property \"" + getName() + "\" must be an integer.", e); + } + + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java new file mode 100644 index 000000000..05a3509ef --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java @@ -0,0 +1,31 @@ + +package net.sourceforge.guacamole.properties; + +/* + * 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 . + */ + +import net.sourceforge.guacamole.GuacamoleException; + +public abstract class StringGuacamoleProperty implements GuacamoleProperty { + + @Override + public String parseValue(String value) throws GuacamoleException { + return value; + } + +} From 3bcb7c979ce4346ef934f8bba9cb10be991ee4ae Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 13 May 2011 00:49:10 -0700 Subject: [PATCH 029/116] GuacamoleProperties should not be instantiated. --- .../sourceforge/guacamole/properties/GuacamoleProperties.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 76f713849..fa1239bdf 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -26,6 +26,8 @@ import net.sourceforge.guacamole.GuacamoleException; public class GuacamoleProperties { + private GuacamoleProperties() {} + public static final StringGuacamoleProperty GUACD_HOSTNAME = new StringGuacamoleProperty() { @Override From 2fb2a9dbc93012993851b1a3046f147726ee422e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 13 May 2011 23:55:09 -0700 Subject: [PATCH 030/116] JavaDoc for I/O classes. --- .../guacamole/io/GuacamoleReader.java | 28 +++++++++++++++ .../guacamole/io/GuacamoleWriter.java | 36 +++++++++++++++++++ .../guacamole/io/ReaderGuacamoleReader.java | 12 +++++++ .../guacamole/io/WriterGuacamoleWriter.java | 12 +++++++ 4 files changed, 88 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java index 65d071e4b..c61399196 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java @@ -22,9 +22,37 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +/** + * Provides abstract and raw character read access to a stream of Guacamole + * instructions. + * + * @author Michael Jumper + */ public interface GuacamoleReader { + /** + * Reads at least one complete Guacamole instruction, returning a buffer + * containing one or more complete Guacamole instructions and no + * incomplete Guacamole instructions. This function will block until at + * least one complete instruction is available. + * + * @return A buffer containing at least one complete Guacamole instruction, + * or null if no more instructions are available for reading. + * @throws GuacamoleException If an error occurs while reading from the + * stream. + */ public char[] read() throws GuacamoleException; + + /** + * Reads exactly one complete Guacamole instruction and returns the fully + * parsed instruction. + * + * @return The next complete instruction from the stream, fully parsed, or + * null if no more instructions are available for reading. + * @throws GuacamoleException If an error occurs while reading from the + * stream, or if the instruction cannot be + * parsed. + */ public GuacamoleInstruction readInstruction() throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java index 2d0168ed1..71ceb6b6e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java @@ -22,10 +22,46 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +/** + * Provides abstract and raw character write access to a stream of Guacamole + * instructions. + * + * @author Michael Jumper + */ public interface GuacamoleWriter { + /** + * Writes a portion of the given array of characters to the Guacamole + * instruction stream. The portion must contain only complete Guacamole + * instructions. + * + * @param chunk An array of characters containing Guacamole instructions. + * @param off The start offset of the portion of the array to write. + * @param len The length of the portion of the array to write. + * @throws GuacamoleException If an error occurred while writing the + * portion of the array specified. + */ public void write(char[] chunk, int off, int len) throws GuacamoleException; + + /** + * Writes the entire given array of characters to the Guacamole instruction + * stream. The array must consist only of complete Guacamole instructions. + * + * @param chunk An array of characters consisting only of complete + * Guacamole instructions. + * @throws GuacamoleException If an error occurred while writing the + * the specified array. + */ public void write(char[] chunk) throws GuacamoleException; + + /** + * Writes the given fully parsed instruction to the Guacamole instruction + * stream. + * + * @param instruction The Guacamole instruction to write. + * @throws GuacamoleException If an error occurred while writing the + * instruction. + */ public void writeInstruction(GuacamoleInstruction instruction) throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 8b21d5be9..66638b1ca 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -25,10 +25,22 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; * along with this program. If not, see . */ +/** + * A GuacamoleReader which wraps a standard Java Reader, using that Reader as + * the Guacamole instruction stream. + * + * @author Michael Jumper + */ public class ReaderGuacamoleReader implements GuacamoleReader { private Reader input; + /** + * Creates a new ReaderGuacamoleReader which will use the given Reader as + * the Guacamole instruction stream. + * + * @param input The Reader to use as the Guacamole instruction stream. + */ public ReaderGuacamoleReader(Reader input) { this.input = input; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index a92337e50..cfa8a6d0f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -24,10 +24,22 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +/** + * A GuacamoleWriter which wraps a standard Java Writer, using that Writer as + * the Guacamole instruction stream. + * + * @author Michael Jumper + */ public class WriterGuacamoleWriter implements GuacamoleWriter { private Writer output; + /** + * Creates a new WriterGuacamoleWriter which will use the given Writer as + * the Guacamole instruction stream. + * + * @param output The Writer to use as the Guacamole instruction stream. + */ public WriterGuacamoleWriter(Writer output) { this.output = output; } From 3fe4aab695a961904a8178a0e58eceea025c837e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 14 May 2011 00:18:33 -0700 Subject: [PATCH 031/116] JavaDoc for network classes. --- .../guacamole/net/GuacamoleSocket.java | 28 +++++++++ .../guacamole/net/GuacamoleTunnel.java | 58 ++++++++++++++++++- .../guacamole/net/InetGuacamoleSocket.java | 16 +++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index 2ad5af5a4..bb6b58722 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -23,11 +23,39 @@ import net.sourceforge.guacamole.io.GuacamoleWriter; * along with this program. If not, see . */ +/** + * Provides abstract socket-like access to a Guacamole connection. + * + * @author Michael Jumper + */ public interface GuacamoleSocket { + /** + * Returns a GuacamoleReader which can be used to read from the + * Guacamole instruction stream associated with the connection + * represented by this GuacamoleSocket. + * + * @return A GuacamoleReader which can be used to read from the + * Guacamole instruction stream. + */ public GuacamoleReader getReader(); + + /** + * Returns a GuacamoleWriter which can be used to write to the + * Guacamole instruction stream associated with the connection + * represented by this GuacamoleSocket. + * + * @return A GuacamoleWriter which can be used to write to the + * Guacamole instruction stream. + */ public GuacamoleWriter getWriter(); + /** + * Releases all resources in use by the connection represented by this + * GuacamoleSocket. + * + * @throws GuacamoleException If an error occurs while releasing resources. + */ public void close() throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index f03492e7c..438a8c03e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -21,10 +21,15 @@ package net.sourceforge.guacamole.net; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; -import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; +/** + * Provides a unique identifier and synchronized access to the GuacamoleReader + * and GuacamoleWriter associated with a GuacamoleSocket. + * + * @author Michael Jumper + */ public class GuacamoleTunnel { private UUID uuid; @@ -33,7 +38,13 @@ public class GuacamoleTunnel { private ReentrantLock readerLock; private ReentrantLock writerLock; - public GuacamoleTunnel(GuacamoleSocket socket) throws GuacamoleException { + /** + * Creates a new GuacamoleTunnel which synchronizes access to the + * Guacamole instruction stream associated with the given GuacamoleSocket. + * + * @param socket The GuacamoleSocket to provide synchronized access for. + */ + public GuacamoleTunnel(GuacamoleSocket socket) { this.socket = socket; uuid = UUID.randomUUID(); @@ -43,32 +54,75 @@ public class GuacamoleTunnel { } + /** + * Acquires exclusive read access to the Guacamole instruction stream + * and returns a GuacamoleReader for reading from that stream. + * + * @return A GuacamoleReader for reading from the Guacamole instruction + * stream. + */ public GuacamoleReader acquireReader() { readerLock.lock(); return socket.getReader(); } + /** + * Relinquishes exclusive read access to the Guacamole instruction + * stream. This function should be called whenever a thread finishes using + * a GuacamoleTunnel's GuacamoleReader. + */ public void releaseReader() { readerLock.unlock(); } + /** + * Returns whether there are threads waiting for read access to the + * Guacamole instruction stream. + * + * @return true if threads are waiting for read access the Guacamole + * instruction stream, false otherwise. + */ public boolean hasQueuedReaderThreads() { return readerLock.hasQueuedThreads(); } + /** + * Acquires exclusive write access to the Guacamole instruction stream + * and returns a GuacamoleWriter for writing to that stream. + * + * @return A GuacamoleWriter for writing to the Guacamole instruction + * stream. + */ public GuacamoleWriter acquireWriter() { writerLock.lock(); return socket.getWriter(); } + /** + * Relinquishes exclusive write access to the Guacamole instruction + * stream. This function should be called whenever a thread finishes using + * a GuacamoleTunnel's GuacamoleWriter. + */ public void releaseWriter() { writerLock.unlock(); } + /** + * Returns whether there are threads waiting for write access to the + * Guacamole instruction stream. + * + * @return true if threads are waiting for write access the Guacamole + * instruction stream, false otherwise. + */ public boolean hasQueuedWriterThreads() { return writerLock.hasQueuedThreads(); } + /** + * Returns the unique identifier associated with this GuacamoleTunnel. + * + * @return The unique identifier associated with this GuacamoleTunnel. + */ public UUID getUUID() { return uuid; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index 5f56c695a..d966f2c2b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -35,6 +35,12 @@ import java.net.SocketAddress; import net.sourceforge.guacamole.GuacamoleException; +/** + * Provides abstract socket-like access to a Guacamole connection over a given + * hostname and port. + * + * @author Michael Jumper + */ public class InetGuacamoleSocket implements GuacamoleSocket { private GuacamoleReader reader; @@ -43,6 +49,16 @@ public class InetGuacamoleSocket implements GuacamoleSocket { private static final int SOCKET_TIMEOUT = 15000; private Socket sock; + /** + * Creates a new InetGuacamoleSocket which reads and writes instructions + * to the Guacamole instruction stream of the Guacamole proxy server + * running at the given hostname and port. + * + * @param hostname The hostname of the Guacamole proxy server to connect to. + * @param port The port of the Guacamole proxy server to connect to. + * @throws GuacamoleException If an error occurs while connecting to the + * Guacamole proxy server. + */ public InetGuacamoleSocket(String hostname, int port) throws GuacamoleException { try { From 65b0f08fd959bde2b9998f9236a3218c64b8ac84 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 14 May 2011 23:40:27 -0700 Subject: [PATCH 032/116] JavaDoc for properties classes. --- .../properties/FileGuacamoleProperty.java | 5 ++++ .../properties/GuacamoleProperties.java | 25 +++++++++++++++++++ .../properties/GuacamoleProperty.java | 24 +++++++++++++++++- .../properties/IntegerGuacamoleProperty.java | 5 ++++ .../properties/StringGuacamoleProperty.java | 5 ++++ 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java index c51e86dd8..7cdf8dbd9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -22,6 +22,11 @@ package net.sourceforge.guacamole.properties; import java.io.File; import net.sourceforge.guacamole.GuacamoleException; +/** + * A GuacamoleProperty whose value is a filename. + * + * @author Michael Jumper + */ public abstract class FileGuacamoleProperty implements GuacamoleProperty { @Override diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index fa1239bdf..820b50540 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -24,10 +24,20 @@ import java.io.InputStream; import java.util.Properties; import net.sourceforge.guacamole.GuacamoleException; +/** + * Simple utility class for reading properties from the guacamole.properties + * file in the root of the classpath. + * + * @author Michael Jumper + */ public class GuacamoleProperties { private GuacamoleProperties() {} + /** + * The hostname of the server where guacd (the Guacamole proxy server) is + * running. + */ public static final StringGuacamoleProperty GUACD_HOSTNAME = new StringGuacamoleProperty() { @Override @@ -35,6 +45,9 @@ public class GuacamoleProperties { }; + /** + * The port that guacd (the Guacamole proxy server) is listening on. + */ public static final IntegerGuacamoleProperty GUACD_PORT = new IntegerGuacamoleProperty() { @Override @@ -64,6 +77,18 @@ public class GuacamoleProperties { } + /** + * Given a GuacamoleProperty, parses and returns the value set for that + * property in guacamole.properties, if any. + * + * @param The type that the given property is parsed into. + * @param property The property to read from guacamole.properties. + * @return The parsed value of the property as read from + * guacamole.properties. + * @throws GuacamoleException If an error occurs while parsing the value + * for the given property in + * guacamole.properties. + */ public static Type getProperty(GuacamoleProperty property) throws GuacamoleException { if (exception != null) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java index b32072554..145df86ff 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java @@ -21,11 +21,33 @@ import net.sourceforge.guacamole.GuacamoleException; * along with this program. If not, see . */ - +/** + * An abstract representation of a property in the guacamole.properties file, + * which parses into a specific type. + * + * @author Michael Jumper + * @param The type this GuacamoleProperty will parse into. + */ public interface GuacamoleProperty { + /** + * Returns the name of the property in guacamole.properties that this + * GuacamoleProperty will parse. + * + * @return The name of the property in guacamole.properties that this + * GuacamoleProperty will parse. + */ public String getName(); + /** + * Parses the given string value into the type associated with this + * GuacamoleProperty. + * + * @param value The string value to parse. + * @return The parsed value. + * @throws GuacamoleException If an error occurs while parsing the + * provided value. + */ public Type parseValue(String value) throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java index 6c6919d08..570140778 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java @@ -21,6 +21,11 @@ package net.sourceforge.guacamole.properties; import net.sourceforge.guacamole.GuacamoleException; +/** + * A GuacamoleProperty whose value is an integer. + * + * @author Michael Jumper + */ public abstract class IntegerGuacamoleProperty implements GuacamoleProperty { @Override diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java index 05a3509ef..258a88571 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java @@ -21,6 +21,11 @@ package net.sourceforge.guacamole.properties; import net.sourceforge.guacamole.GuacamoleException; +/** + * A GuacamoleProperty whose value is a simple string. + * + * @author Michael Jumper + */ public abstract class StringGuacamoleProperty implements GuacamoleProperty { @Override From 2bb7516d3097efdee8d9fa622918832dea13d635 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 15 May 2011 00:15:55 -0700 Subject: [PATCH 033/116] JavaDoc for protocol classes. --- .../protocol/ConfiguredGuacamoleSocket.java | 23 +++++++ .../protocol/GuacamoleConfiguration.java | 26 +++++++ .../protocol/GuacamoleInstruction.java | 69 ++++++++++++++++++- 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index f177b083e..afa5ad8d0 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -25,10 +25,33 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; * along with this program. If not, see . */ +/** + * A GuacamoleSocket which pre-configures the connection based on a given + * GuacamoleConfiguration, completing the initial protocol handshake before + * accepting data for read or write. + * + * This is useful for forcing a connection to the Guacamole proxy server with + * a specific configuration while disallowing the client that will be using + * this GuacamoleSocket from manually controlling the initial protocol + * handshake. + * + * @author Michael Jumper + */ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { private GuacamoleSocket socket; + /** + * Creates a new ConfiguredGuacamoleSocket which uses the given + * GuacamoleConfiguration to complete the initial protocol handshake over + * the given GuacamoleSocket. + * + * @param socket The GuacamoleSocket to wrap. + * @param config The GuacamoleConfiguration to use to complete the initial + * protocol handshake. + * @throws GuacamoleException If an error occurs while completing the + * initial protocol handshake. + */ public ConfiguredGuacamoleSocket(GuacamoleSocket socket, GuacamoleConfiguration config) throws GuacamoleException { this.socket = socket; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 690887ae9..728e3f8e8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -21,23 +21,49 @@ import java.util.HashMap; * along with this program. If not, see . */ +/** + * All information necessary to complete the initial protocol handshake of a + * Guacamole session. + * + * @author Michael Jumper + */ public class GuacamoleConfiguration { private String protocol; private HashMap parameters = new HashMap(); + /** + * Returns the name of the protocol to be used. + * @return The name of the protocol to be used. + */ public String getProtocol() { return protocol; } + /** + * Sets the name of the protocol to be used. + * @param protocol The name of the protocol to be used. + */ public void setProtocol(String protocol) { this.protocol = protocol; } + /** + * Returns the value set for the parameter with the given name, if any. + * @param name The name of the parameter to return the value for. + * @return The value of the parameter with the given name, or null if + * that parameter has not been set. + */ public String getParameter(String name) { return parameters.get(name); } + /** + * Sets the value for the parameter with the given name. + * + * @param name The name of the parameter to set the value for. + * @param value The value to set for the parameter with the given name. + */ public void setParameter(String name, String value) { parameters.put(name, value); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index 153b9e20f..f0d65a3f0 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -21,23 +21,55 @@ import java.util.HashMap; * along with this program. If not, see . */ +/** + * An abstract representation of a Guacamole instruction, as defined by the + * Guacamole protocol. + * + * @author Michael Jumper + */ public class GuacamoleInstruction { + /** + * The operation performed by a particular Guacamole instruction. Each + * Operation is associated with a unique opcode. + */ public enum Operation { + /** + * Message sent from client to server specifying which protocol is + * to be used. + */ CLIENT_SELECT("select"), + + /** + * Message sent from client to server specifying which argument + * values correspond to the arguments required by the selected + * protocol. + */ CLIENT_CONNECT("connect"), + /** + * Message sent from server to client specifying which arguments + * are required by the selected protocol. + */ SERVER_ARGS("args"); private String opcode; - private Operation(String opcode) { this.opcode = opcode; } + private Operation(String opcode) { + this.opcode = opcode; + } + /** + * Returns the unique opcode associated with this Operation. + * @return The unique opcode associated with this Operation. + */ public String getOpcode() { return opcode; } - // Maintain static hash of all opcodes + /** + * Static hash of all opcodes and their corresponding Operations. + */ private static final HashMap opcodeToOperation; static { @@ -48,6 +80,13 @@ public class GuacamoleInstruction { } + /** + * Returns the corresponding Operation having the given opcode, if any. + * + * @param opcode The unique opcode associated with an Operation. + * @return The Operation associated with the given opcode, or null if + * no such Operation is defined. + */ public static Operation fromOpcode(String opcode) { return opcodeToOperation.get(opcode); } @@ -57,19 +96,45 @@ public class GuacamoleInstruction { private Operation operation; private String[] args; + /** + * Creates a new GuacamoleInstruction having the given Operation and + * list of arguments values. + * + * @param operation The Operation of the instruction to create. + * @param args The list of argument values to provide in the new + * instruction if any. + */ public GuacamoleInstruction(Operation operation, String... args) { this.operation = operation; this.args = args; } + /** + * Returns the Operation associated with this GuacamoleInstruction. + * @return The Operation associated with this GuacamoleInstruction. + */ public Operation getOperation() { return operation; } + /** + * Returns an array of all argument values specified for this + * GuacamoleInstruction. + * + * @return An array of all argument values specified for this + * GuacamoleInstruction. + */ public String[] getArgs() { return args; } + /** + * Returns this GuacamoleInstruction in the form it would be sent over the + * Guacamole protocol. + * + * @return This GuacamoleInstruction in the form it would be sent over the + * Guacamole protocol. + */ @Override public String toString() { From 9b682770b4da73312abc1ce63ad4259c1072bb6c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 15 May 2011 00:39:47 -0700 Subject: [PATCH 034/116] JavaDoc for servlet classes. --- .../guacamole/servlet/GuacamoleSession.java | 43 +++++++++++--- .../servlet/GuacamoleTunnelServlet.java | 56 ++++++++++++++++++- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index dcaaf394d..5ef731398 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -25,18 +25,31 @@ import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleTunnel; +/** + * Provides abstract access to the tunnels associated with a Guacamole session. + * + * @author Michael Jumper + */ public class GuacamoleSession { - private final HttpSession session; private ConcurrentMap tunnels; + /** + * Creates a new GuacamoleSession, storing and retrieving tunnels from the + * given HttpSession. Note that the true Guacamole session is tied to the + * HttpSession provided, thus creating a new GuacamoleSession does not + * create a new Guacamole session; it merely creates a new object for + * accessing the tunnels of an existing Guacamole session represented by + * the provided HttpSession. + * + * @param session The HttpSession to use as tunnel storage. + * @throws GuacamoleException If session is null. + */ public GuacamoleSession(HttpSession session) throws GuacamoleException { if (session == null) throw new GuacamoleException("User has no session."); - this.session = session; - synchronized (session) { tunnels = (ConcurrentMap) session.getAttribute("GUAC_TUNNELS"); @@ -49,18 +62,30 @@ public class GuacamoleSession { } - public void invalidate() { - session.invalidate(); - } - - public void attachTunnel(GuacamoleTunnel tunnel) throws GuacamoleException { + /** + * Attaches the given tunnel to this GuacamoleSession. + * @param tunnel The tunnel to attach to this GucacamoleSession. + */ + public void attachTunnel(GuacamoleTunnel tunnel) { tunnels.put(tunnel.getUUID().toString(), tunnel); } - public void detachTunnel(GuacamoleTunnel tunnel) throws GuacamoleException { + /** + * Detaches the given tunnel to this GuacamoleSession. + * @param tunnel The tunnel to detach to this GucacamoleSession. + */ + public void detachTunnel(GuacamoleTunnel tunnel) { tunnels.remove(tunnel.getUUID().toString()); } + /** + * Returns the tunnel with the given UUID attached to this GuacamoleSession, + * if any. + * + * @param tunnelUUID The UUID of an attached tunnel. + * @return The tunnel corresponding to the given UUID, if attached, or null + * if no such tunnel is attached. + */ public GuacamoleTunnel getTunnel(String tunnelUUID) { return tunnels.get(tunnelUUID); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 27106b9b8..67a1ca4fd 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -33,7 +33,12 @@ import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; - +/** + * A HttpServlet implementing and abstracting the operations required by the + * JavaScript Guacamole client's tunnel. + * + * @author Michael Jumper + */ public abstract class GuacamoleTunnelServlet extends HttpServlet { @Override @@ -117,8 +122,41 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } + /** + * Called whenever the JavaScript Guacamole client makes a connection + * request. It it up to the implementor of this function to define what + * conditions must be met for a tunnel to be configured and returned as a + * result of this connection request (whether some sort of credentials must + * be specified, for example). + * + * @param request The HttpServletRequest associated with the connection + * request received. Any parameters specified along with + * the connection request can be read from this object. + * @return A newly constructed GuacamoleTunnel if successful, + * null otherwise. + * @throws GuacamoleException If an error occurs while constructing the + * GuacamoleTunnel, or if the conditions + * required for connection are not met. + */ protected abstract GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException; + /** + * Called whenever the JavaScript Guacamole client makes a read request. + * This function should in general not be overridden, as it already + * contains a proper implementation of the read operation. + * + * @param request The HttpServletRequest associated with the read request + * received. + * @param response The HttpServletResponse associated with the write request + * received. Any data to be sent to the client in response + * to the write request should be written to the response + * body of this HttpServletResponse. + * @param tunnelUUID The UUID of the tunnel to read from, as specified in + * the write request. This tunnel must be attached to + * the Guacamole session. + * @throws GuacamoleException If an error occurs while handling the read + * request. + */ protected void doRead(HttpServletRequest request, HttpServletResponse response, String tunnelUUID) throws GuacamoleException { HttpSession httpSession = request.getSession(false); @@ -178,6 +216,22 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } + /** + * Called whenever the JavaScript Guacamole client makes a write request. + * This function should in general not be overridden, as it already + * contains a proper implementation of the write operation. + * + * @param request The HttpServletRequest associated with the write request + * received. Any data to be written will be specified within + * the body of this request. + * @param response The HttpServletResponse associated with the write request + * received. + * @param tunnelUUID The UUID of the tunnel to write to, as specified in + * the write request. This tunnel must be attached to + * the Guacamole session. + * @throws GuacamoleException If an error occurs while handling the write + * request. + */ protected void doWrite(HttpServletRequest request, HttpServletResponse response, String tunnelUUID) throws GuacamoleException { HttpSession httpSession = request.getSession(false); From 8b49b22a0d5fc773701411445aee0ba2b7a43cb8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 27 May 2011 13:45:55 -0700 Subject: [PATCH 035/116] Updated version numbers to 0.4.0 --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index be3d39b5b..9ce28c816 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.3.0 + 0.4.0 guacamole-common http://guacamole.sourceforge.net/ From 6959b74d763ba365b93e1975f2d58ab4a7e226fc Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 4 Jun 2011 22:22:58 -0700 Subject: [PATCH 036/116] Fix for read() vs. readInstruction() issue. Consistency with placement of import vs. license --- .../guacamole/io/GuacamoleReader.java | 6 ++--- .../guacamole/io/GuacamoleWriter.java | 6 ++--- .../guacamole/io/ReaderGuacamoleReader.java | 23 ++++++++++++++----- .../guacamole/io/WriterGuacamoleWriter.java | 10 ++++---- .../guacamole/net/GuacamoleSocket.java | 8 +++---- .../properties/GuacamoleProperty.java | 4 ++-- .../protocol/ConfiguredGuacamoleSocket.java | 12 +++++----- .../protocol/GuacamoleConfiguration.java | 4 ++-- .../protocol/GuacamoleInstruction.java | 4 ++-- 9 files changed, 44 insertions(+), 33 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java index c61399196..040a917e3 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java @@ -1,9 +1,6 @@ package net.sourceforge.guacamole.io; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -22,6 +19,9 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; + /** * Provides abstract and raw character read access to a stream of Guacamole * instructions. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java index 71ceb6b6e..a4bb7c041 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java @@ -1,9 +1,6 @@ package net.sourceforge.guacamole.io; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -22,6 +19,9 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; + /** * Provides abstract and raw character write access to a stream of Guacamole * instructions. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 66638b1ca..7443d56c8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -1,12 +1,6 @@ package net.sourceforge.guacamole.io; -import java.io.IOException; -import java.io.Reader; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -25,6 +19,12 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; * along with this program. If not, see . */ +import java.io.IOException; +import java.io.Reader; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; + /** * A GuacamoleReader which wraps a standard Java Reader, using that Reader as * the Guacamole instruction stream. @@ -54,6 +54,17 @@ public class ReaderGuacamoleReader implements GuacamoleReader { @Override public char[] read() throws GuacamoleException { + // If data was previously read via readInstruction(), return remaining + // data instead of reading more. + if (instructionBuffer != null) { + + char[] chunk = new char[instructionBuffer.length - instructionStart]; + System.arraycopy(instructionBuffer, instructionStart, chunk, 0, chunk.length); + instructionBuffer = null; + + return chunk; + } + try { // While we're blocking, or input is available diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index cfa8a6d0f..78f425519 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -1,11 +1,6 @@ package net.sourceforge.guacamole.io; -import java.io.IOException; -import java.io.Writer; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -24,6 +19,11 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; * along with this program. If not, see . */ +import java.io.IOException; +import java.io.Writer; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction; + /** * A GuacamoleWriter which wraps a standard Java Writer, using that Writer as * the Guacamole instruction stream. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index bb6b58722..a61b12508 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -1,10 +1,6 @@ package net.sourceforge.guacamole.net; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.io.GuacamoleReader; -import net.sourceforge.guacamole.io.GuacamoleWriter; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -23,6 +19,10 @@ import net.sourceforge.guacamole.io.GuacamoleWriter; * along with this program. If not, see . */ +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.io.GuacamoleWriter; + /** * Provides abstract socket-like access to a Guacamole connection. * diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java index 145df86ff..0db73caac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java @@ -1,8 +1,6 @@ package net.sourceforge.guacamole.properties; -import net.sourceforge.guacamole.GuacamoleException; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -21,6 +19,8 @@ import net.sourceforge.guacamole.GuacamoleException; * along with this program. If not, see . */ +import net.sourceforge.guacamole.GuacamoleException; + /** * An abstract representation of a property in the guacamole.properties file, * which parses into a specific type. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index afa5ad8d0..3406da582 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -1,12 +1,6 @@ package net.sourceforge.guacamole.protocol; -import net.sourceforge.guacamole.io.GuacamoleReader; -import net.sourceforge.guacamole.io.GuacamoleWriter; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSocket; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -25,6 +19,12 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; * along with this program. If not, see . */ +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.io.GuacamoleWriter; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleSocket; +import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; + /** * A GuacamoleSocket which pre-configures the connection based on a given * GuacamoleConfiguration, completing the initial protocol handshake before diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 728e3f8e8..878dbb2de 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -1,8 +1,6 @@ package net.sourceforge.guacamole.protocol; -import java.util.HashMap; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -21,6 +19,8 @@ import java.util.HashMap; * along with this program. If not, see . */ +import java.util.HashMap; + /** * All information necessary to complete the initial protocol handshake of a * Guacamole session. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index f0d65a3f0..bf8f7f614 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -1,8 +1,6 @@ package net.sourceforge.guacamole.protocol; -import java.util.HashMap; - /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -21,6 +19,8 @@ import java.util.HashMap; * along with this program. If not, see . */ +import java.util.HashMap; + /** * An abstract representation of a Guacamole instruction, as defined by the * Guacamole protocol. From e6a6ebe724fccd372d5484f37d20b2776d46f549 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 25 Jun 2011 23:33:14 -0700 Subject: [PATCH 037/116] Use own function, rather than override service(). --- .../servlet/GuacamoleTunnelServlet.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 67a1ca4fd..55ad9c2ac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -43,16 +43,25 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { - service(request, response); + handleTunnelRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - service(request, response); + handleTunnelRequest(request, response); } - @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException { + /** + * Dispatches every HTTP GET and POST request to the appropriate handler + * function based on the query string. + * + * @param request The HttpServletRequest associated with the GET or POST + * request received. + * @param response The HttpServletResponse associated with the GET or POST + * request received. + * @throws ServletException If an error occurs while servicing the request. + */ + protected void handleTunnelRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { From 423d1a6268b5458abed875e45b48718b83bed777 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Jul 2011 15:34:00 -0700 Subject: [PATCH 038/116] Suppress unchecked warnings for tunnels typecast. --- .../java/net/sourceforge/guacamole/servlet/GuacamoleSession.java | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index 5ef731398..32c8468fb 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -45,6 +45,7 @@ public class GuacamoleSession { * @param session The HttpSession to use as tunnel storage. * @throws GuacamoleException If session is null. */ + @SuppressWarnings("unchecked") public GuacamoleSession(HttpSession session) throws GuacamoleException { if (session == null) From 88b186a856a8a673b03ce1d92073b82a96b83f4b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 4 Jul 2011 14:24:40 -0700 Subject: [PATCH 039/116] Fix race condition where tunnel is detached before client has chance to retrieve error message in header via second request. --- .../servlet/GuacamoleTunnelServlet.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 55ad9c2ac..233eac4e7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -187,9 +187,16 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { Writer out = response.getWriter(); + // Detach tunnel and throw error if EOF (and we haven't sent any + // data yet. + char[] message = reader.read(); + if (message == null) { + session.detachTunnel(tunnel); + throw new GuacamoleException("Disconnected."); + } + // For all messages, until another stream is ready (we send at least one message) - char[] message; - while ((message = reader.read()) != null) { + do { // Get message output bytes out.write(message, 0, message.length); @@ -200,12 +207,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { if (tunnel.hasQueuedReaderThreads()) break; - } - - if (message == null) { - session.detachTunnel(tunnel); - throw new GuacamoleException("Disconnected."); - } + } while ((message = reader.read()) != null); // End-of-instructions marker out.write(';'); From 01c3c943d437ebc141f80a6c415cc3a7bc03ba23 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 12 Jul 2011 15:18:44 -0700 Subject: [PATCH 040/116] Add close() to tunnel, properly detach and close tunnel on error. --- .../guacamole/net/GuacamoleTunnel.java | 11 ++++++++ .../servlet/GuacamoleTunnelServlet.java | 27 ++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 438a8c03e..4e69051a0 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -21,6 +21,7 @@ package net.sourceforge.guacamole.net; import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; +import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; @@ -127,4 +128,14 @@ public class GuacamoleTunnel { return uuid; } + /** + * Release all resources allocated to this GuacamoleTunnel. + * + * @throws GuacamoleException if an error occurs while releasing + * resources. + */ + public void close() throws GuacamoleException { + socket.close(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 233eac4e7..728afb237 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -190,10 +190,8 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { // Detach tunnel and throw error if EOF (and we haven't sent any // data yet. char[] message = reader.read(); - if (message == null) { - session.detachTunnel(tunnel); + if (message == null) throw new GuacamoleException("Disconnected."); - } // For all messages, until another stream is ready (we send at least one message) do { @@ -215,10 +213,28 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { response.flushBuffer(); } + catch (GuacamoleException e) { + + // Detach and close + session.detachTunnel(tunnel); + tunnel.close(); + + throw e; + } catch (UnsupportedEncodingException e) { + + // Detach and close + session.detachTunnel(tunnel); + tunnel.close(); + throw new GuacamoleException("UTF-8 not supported by Java.", e); } catch (IOException e) { + + // Detach and close + session.detachTunnel(tunnel); + tunnel.close(); + throw new GuacamoleException("I/O error writing to servlet output stream.", e); } finally { @@ -273,6 +289,11 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } catch (IOException e) { + + // Detach and close + session.detachTunnel(tunnel); + tunnel.close(); + throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e); } finally { From 69f166f85b0cdf7cd2f1a43fed8ba96800e43e3b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 13 Jul 2011 18:08:30 -0700 Subject: [PATCH 041/116] Added logging via SLF4J --- guacamole-common/pom.xml | 33 ++++++------------- .../guacamole/net/InetGuacamoleSocket.java | 7 ++++ .../guacamole/servlet/GuacamoleSession.java | 6 ++++ .../servlet/GuacamoleTunnelServlet.java | 15 ++++++++- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 9ce28c816..514f9140b 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -24,38 +24,25 @@ - - - - - org.apache.maven.wagon - wagon-ssh-external - - - + + javax.servlet servlet-api 2.5 provided + + + + org.slf4j + slf4j-api + 1.6.1 + + - - - guac-dev - http://guac-dev.org/repo - - - - - - guac-dev - ${guac-dev.dist.repo} - - - diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index d966f2c2b..28add9689 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -33,6 +33,8 @@ import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.SocketAddress; import net.sourceforge.guacamole.GuacamoleException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @@ -43,6 +45,8 @@ import net.sourceforge.guacamole.GuacamoleException; */ public class InetGuacamoleSocket implements GuacamoleSocket { + private Logger logger = LoggerFactory.getLogger(InetGuacamoleSocket.class); + private GuacamoleReader reader; private GuacamoleWriter writer; @@ -63,6 +67,8 @@ public class InetGuacamoleSocket implements GuacamoleSocket { try { + logger.debug("Connecting to guacd at {}:{}.", hostname, port); + // Get address SocketAddress address = new InetSocketAddress( InetAddress.getByName(hostname), @@ -90,6 +96,7 @@ public class InetGuacamoleSocket implements GuacamoleSocket { @Override public void close() throws GuacamoleException { try { + logger.debug("Closing socket to guacd."); sock.close(); } catch (IOException e) { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index 32c8468fb..762775372 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -24,6 +24,8 @@ import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleTunnel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides abstract access to the tunnels associated with a Guacamole session. @@ -32,6 +34,8 @@ import net.sourceforge.guacamole.net.GuacamoleTunnel; */ public class GuacamoleSession { + private Logger logger = LoggerFactory.getLogger(GuacamoleSession.class); + private ConcurrentMap tunnels; /** @@ -69,6 +73,7 @@ public class GuacamoleSession { */ public void attachTunnel(GuacamoleTunnel tunnel) { tunnels.put(tunnel.getUUID().toString(), tunnel); + logger.debug("Attached tunnel {}.", tunnel.getUUID()); } /** @@ -77,6 +82,7 @@ public class GuacamoleSession { */ public void detachTunnel(GuacamoleTunnel tunnel) { tunnels.remove(tunnel.getUUID().toString()); + logger.debug("Detached tunnel {}.", tunnel.getUUID()); } /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 728afb237..3e7a34433 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -25,13 +25,14 @@ import java.io.UnsupportedEncodingException; import java.io.Writer; 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.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A HttpServlet implementing and abstracting the operations required by the @@ -41,6 +42,8 @@ import net.sourceforge.guacamole.io.GuacamoleWriter; */ public abstract class GuacamoleTunnelServlet extends HttpServlet { + private Logger logger = LoggerFactory.getLogger(GuacamoleTunnelServlet.class); + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { handleTunnelRequest(request, response); @@ -75,13 +78,19 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { GuacamoleTunnel tunnel = doConnect(request); if (tunnel != null) { + + logger.info("Connection from {} succeeded.", request.getRemoteAddr()); + try { response.getWriter().println(tunnel.getUUID().toString()); } catch (IOException e) { throw new GuacamoleException(e); } + } + else + logger.info("Connection from {} failed.", request.getRemoteAddr()); } @@ -207,6 +216,10 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } while ((message = reader.read()) != null); + // Close tunnel immediately upon EOF + if (message == null) + tunnel.close(); + // End-of-instructions marker out.write(';'); out.flush(); From de526911a5687a8e4d0bbaee9a057489fabb69bf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 10 Aug 2011 15:14:04 -0700 Subject: [PATCH 042/116] Removed unused file. --- guacamole-common/.package.dsc | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 guacamole-common/.package.dsc diff --git a/guacamole-common/.package.dsc b/guacamole-common/.package.dsc deleted file mode 100644 index 98ecc5b07..000000000 --- a/guacamole-common/.package.dsc +++ /dev/null @@ -1,2 +0,0 @@ -PKGNAME=guacamole-common -VERSION=0.0.1 From e3260ca3e9ffb6c029141748f9983e28920f8c3a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 25 Aug 2011 00:22:14 -0700 Subject: [PATCH 043/116] Fixed NPE in reader when connection closed during negotiaion. Added getRequiredProperty(). --- .../guacamole/io/ReaderGuacamoleReader.java | 4 ++++ .../properties/GuacamoleProperties.java | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 7443d56c8..96997ac61 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -124,6 +124,10 @@ public class ReaderGuacamoleReader implements GuacamoleReader { instructionStart = 0; } + // If EOF, return EOF + if (instructionBuffer == null) + return null; + // Locate end-of-opcode and end-of-instruction int opcodeEnd = -1; int instructionEnd = -1; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 820b50540..6d272058d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -98,4 +98,28 @@ public class GuacamoleProperties { } + /** + * Given a GuacamoleProperty, parses and returns the value set for that + * property in guacamole.properties. An exception is thrown if the value + * is not provided. + * + * @param The type that the given property is parsed into. + * @param property The property to read from guacamole.properties. + * @return The parsed value of the property as read from + * guacamole.properties. + * @throws GuacamoleException If an error occurs while parsing the value + * for the given property in + * guacamole.properties, or if the property is + * not specified. + */ + public static Type getRequiredProperty(GuacamoleProperty property) + throws GuacamoleException { + + Type value = getProperty(property); + if (value == null) + throw new GuacamoleException("Property " + property.getName() + " is required."); + + return value; + + } } From 12717e038ccd1b389b99ce2f610973081b06c311 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 10 Sep 2011 19:08:42 -0700 Subject: [PATCH 044/116] Support for new instruction format, dependency on Apache commons --- guacamole-common/pom.xml | 7 ++ .../guacamole/io/ReaderGuacamoleReader.java | 71 +++++++++++-------- .../servlet/GuacamoleTunnelServlet.java | 2 +- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 514f9140b..051c2c88b 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -43,6 +43,13 @@ 1.6.1 + + + org.apache.commons + commons-lang3 + 3.0.1 + + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 96997ac61..a7df9bd22 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -21,9 +21,13 @@ package net.sourceforge.guacamole.io; import java.io.IOException; import java.io.Reader; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; +import org.apache.commons.lang3.ArrayUtils; /** * A GuacamoleReader which wraps a standard Java Reader, using that Reader as @@ -127,54 +131,59 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // If EOF, return EOF if (instructionBuffer == null) return null; + + // Build list of elements + LinkedList elements = new LinkedList(); + while (instructionStart < instructionBuffer.length) { - // Locate end-of-opcode and end-of-instruction - int opcodeEnd = -1; - int instructionEnd = -1; + // Find end of length + int lengthEnd = ArrayUtils.indexOf(instructionBuffer, '.', instructionStart); - for (int i=instructionStart; i opcodeEnd) - args = new String(instructionBuffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(","); - else - args = new String[0]; - + // Pull opcode off elements list + String opcode = elements.removeFirst(); + // Create instruction GuacamoleInstruction instruction = new GuacamoleInstruction( Operation.fromOpcode(opcode), - args + elements.toArray(new String[elements.size()]) ); - // Advance instructionBuffer - instructionStart = instructionEnd + 1; + // Detect end of buffer if (instructionStart >= instructionBuffer.length) instructionBuffer = null; + // Return parsed instruction return instruction; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index 3e7a34433..d74cd82ee 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -221,7 +221,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { tunnel.close(); // End-of-instructions marker - out.write(';'); + out.write("0.;"); out.flush(); response.flushBuffer(); From dfbe62e65ff9c494e8c58ca419783d74199047e9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 16 Sep 2011 17:03:05 +0000 Subject: [PATCH 045/116] New instruction format for output. --- .../guacamole/protocol/GuacamoleInstruction.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index bf8f7f614..595114204 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -140,14 +140,14 @@ public class GuacamoleInstruction { StringBuilder buff = new StringBuilder(); + buff.append(operation.getOpcode().length()); + buff.append('.'); buff.append(operation.getOpcode()); - if (args.length >= 1) - buff.append(':'); - for (int i=0; i 0) - buff.append(','); + buff.append(','); + buff.append(args[i].length()); + buff.append('.'); buff.append(args[i]); } From 73b7304ab7c912b90baaa08c6aef0af5667ba4e0 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 4 Nov 2011 15:20:33 -0700 Subject: [PATCH 046/116] Bumped versions to 0.5.0. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 051c2c88b..83e2f391a 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.4.0 + 0.5.0 guacamole-common http://guacamole.sourceforge.net/ From c927d9f2ff4f0ad10b0f5589c8510105da7a4922 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 20 Nov 2011 00:44:39 -0800 Subject: [PATCH 047/116] UUID output should contain no newline. At least one browser (Konqueror) includes the trailing newline in responseText. --- .../sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index d74cd82ee..df5968ce3 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -82,7 +82,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { logger.info("Connection from {} succeeded.", request.getRemoteAddr()); try { - response.getWriter().println(tunnel.getUUID().toString()); + response.getWriter().print(tunnel.getUUID().toString()); } catch (IOException e) { throw new GuacamoleException(e); From 6f79b3f93b8f997610605ec9e4588c7919178c47 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 25 Nov 2011 18:48:34 -0800 Subject: [PATCH 048/116] Added Doxyfile. --- guacamole-common/Doxyfile | 1551 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1551 insertions(+) create mode 100644 guacamole-common/Doxyfile diff --git a/guacamole-common/Doxyfile b/guacamole-common/Doxyfile new file mode 100644 index 000000000..e0eb69760 --- /dev/null +++ b/guacamole-common/Doxyfile @@ -0,0 +1,1551 @@ +# Doxyfile 1.6.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = guacamole-common + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.5.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = YES + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = YES + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES From 92508bb91a32bc57ca89423ff7978a13961c470f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 16:17:45 -0800 Subject: [PATCH 049/116] Hide "scope" (package) names from Doxygen generated docs. --- guacamole-common/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/Doxyfile b/guacamole-common/Doxyfile index e0eb69760..339015afd 100644 --- a/guacamole-common/Doxyfile +++ b/guacamole-common/Doxyfile @@ -378,7 +378,7 @@ CASE_SENSE_NAMES = YES # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. -HIDE_SCOPE_NAMES = NO +HIDE_SCOPE_NAMES = YES # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation From 5437cb338a4375afea7a6c10c353847428fa38a7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 16:48:44 -0800 Subject: [PATCH 050/116] Improved doc layout --- guacamole-common/.gitignore | 8 ++++++++ guacamole-common/{ => doc}/Doxyfile | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) rename guacamole-common/{ => doc}/Doxyfile (99%) diff --git a/guacamole-common/.gitignore b/guacamole-common/.gitignore index 42f4a1a64..533192e5f 100644 --- a/guacamole-common/.gitignore +++ b/guacamole-common/.gitignore @@ -1,2 +1,10 @@ + +# Compiled code target/ + +# Backup files *~ + +# Generated docs +doc/doxygen-output + diff --git a/guacamole-common/Doxyfile b/guacamole-common/doc/Doxyfile similarity index 99% rename from guacamole-common/Doxyfile rename to guacamole-common/doc/Doxyfile index 339015afd..f9150ec95 100644 --- a/guacamole-common/Doxyfile +++ b/guacamole-common/doc/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NUMBER = 0.5.0 # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = doc +OUTPUT_DIRECTORY = doxygen-output # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output @@ -574,7 +574,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = +INPUT = ../src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is From 8bb0892747a5292e7981af2103bd4117b68e63a9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 18:01:32 -0800 Subject: [PATCH 051/116] Strip ../src from path --- guacamole-common/doc/Doxyfile | 2 +- guacamole-common/doc/DoxygenLayout.xml | 184 +++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 guacamole-common/doc/DoxygenLayout.xml diff --git a/guacamole-common/doc/Doxyfile b/guacamole-common/doc/Doxyfile index f9150ec95..3e3b89186 100644 --- a/guacamole-common/doc/Doxyfile +++ b/guacamole-common/doc/Doxyfile @@ -114,7 +114,7 @@ FULL_PATH_NAMES = YES # If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = +STRIP_FROM_PATH = ../src # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells diff --git a/guacamole-common/doc/DoxygenLayout.xml b/guacamole-common/doc/DoxygenLayout.xml new file mode 100644 index 000000000..1c8525c36 --- /dev/null +++ b/guacamole-common/doc/DoxygenLayout.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4ae8aa1219d881be4a89c80b11332561d5cdfd2d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 18:03:30 -0800 Subject: [PATCH 052/116] Removing DoxygenLayout.xml for now --- guacamole-common/doc/DoxygenLayout.xml | 184 ------------------------- 1 file changed, 184 deletions(-) delete mode 100644 guacamole-common/doc/DoxygenLayout.xml diff --git a/guacamole-common/doc/DoxygenLayout.xml b/guacamole-common/doc/DoxygenLayout.xml deleted file mode 100644 index 1c8525c36..000000000 --- a/guacamole-common/doc/DoxygenLayout.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From d3f6993acf2a6ed78da77ea06da8fcbf51b6a806 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 18:08:49 -0800 Subject: [PATCH 053/116] Added example from guacamole-example --- guacamole-common/doc/Doxyfile | 4 +- .../example/DummyGuacamoleTunnelServlet.java | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java diff --git a/guacamole-common/doc/Doxyfile b/guacamole-common/doc/Doxyfile index 3e3b89186..8319dd93c 100644 --- a/guacamole-common/doc/Doxyfile +++ b/guacamole-common/doc/Doxyfile @@ -631,7 +631,7 @@ EXCLUDE_SYMBOLS = # directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = example # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp @@ -645,7 +645,7 @@ EXAMPLE_PATTERNS = # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. -EXAMPLE_RECURSIVE = NO +EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see diff --git a/guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java b/guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java new file mode 100644 index 000000000..ead4901ba --- /dev/null +++ b/guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java @@ -0,0 +1,65 @@ + +package net.sourceforge.guacamole.net.example; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.properties.GuacamoleProperties; +import net.sourceforge.guacamole.net.GuacamoleSocket; +import net.sourceforge.guacamole.net.GuacamoleTunnel; +import net.sourceforge.guacamole.net.InetGuacamoleSocket; +import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; +import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket; +import net.sourceforge.guacamole.servlet.GuacamoleSession; +import net.sourceforge.guacamole.servlet.GuacamoleTunnelServlet; + +/* + * 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 . + */ + +public class DummyGuacamoleTunnelServlet extends GuacamoleTunnelServlet { + + @Override + protected GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException { + + HttpSession httpSession = request.getSession(true); + + String hostname = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME); + int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT); + + GuacamoleConfiguration config = new GuacamoleConfiguration(); + config.setProtocol("vnc"); + config.setParameter("hostname", "localhost"); + config.setParameter("port", "5901"); + config.setParameter("password", "potato"); + + GuacamoleSocket socket = new ConfiguredGuacamoleSocket( + new InetGuacamoleSocket(hostname, port), + config + ); + + GuacamoleTunnel tunnel = new GuacamoleTunnel(socket); + + // Attach tunnel + GuacamoleSession session = new GuacamoleSession(httpSession); + session.attachTunnel(tunnel); + + return tunnel; + + } + +} From e8f83c19ccb07c804330696358d4985b0b5b3465 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 18:23:45 -0800 Subject: [PATCH 054/116] Renamed and reformatted example, removed unapplicable license terms. --- ...Servlet.java => ExampleTunnelServlet.java} | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) rename guacamole-common/doc/example/{net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java => ExampleTunnelServlet.java} (56%) diff --git a/guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java b/guacamole-common/doc/example/ExampleTunnelServlet.java similarity index 56% rename from guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java rename to guacamole-common/doc/example/ExampleTunnelServlet.java index ead4901ba..d335754f6 100644 --- a/guacamole-common/doc/example/net/sourceforge/guacamole/net/example/DummyGuacamoleTunnelServlet.java +++ b/guacamole-common/doc/example/ExampleTunnelServlet.java @@ -1,6 +1,4 @@ -package net.sourceforge.guacamole.net.example; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; @@ -13,33 +11,19 @@ import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket; import net.sourceforge.guacamole.servlet.GuacamoleSession; import net.sourceforge.guacamole.servlet.GuacamoleTunnelServlet; -/* - * 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 . - */ - -public class DummyGuacamoleTunnelServlet extends GuacamoleTunnelServlet { +public class ExampleTunnelServlet extends GuacamoleTunnelServlet { @Override - protected GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException { + protected GuacamoleTunnel doConnect(HttpServletRequest request) + throws GuacamoleException { HttpSession httpSession = request.getSession(true); - String hostname = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME); - int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT); + String hostname = GuacamoleProperties.getProperty( + GuacamoleProperties.GUACD_HOSTNAME); + + int port = GuacamoleProperties.getProperty( + GuacamoleProperties.GUACD_PORT); GuacamoleConfiguration config = new GuacamoleConfiguration(); config.setProtocol("vnc"); From 01cd2cb846b3d848ea227ffdb5f10e1a4fa9c2d9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Nov 2011 18:33:47 -0800 Subject: [PATCH 055/116] Referencing example in GuacamoleTunnelServlet. --- .../guacamole/servlet/GuacamoleTunnelServlet.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index df5968ce3..a10b7b0d9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -317,3 +317,11 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { } +/** + * \example ExampleTunnelServlet.java + * + * A basic example demonstrating extending GuacamoleTunnelServlet and + * implementing doConnect() to configure the Guacamole connection as + * desired. + */ + From 70b522cacd20850eb78c1db12a4ed54d658c0ea9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 4 Dec 2011 17:09:48 -0800 Subject: [PATCH 056/116] Relicensed as Mozilla/LGPL/GPL. --- guacamole-common/COPYING | 661 ------------------ guacamole-common/LICENSE | 470 +++++++++++++ .../guacamole/GuacamoleException.java | 47 +- .../guacamole/io/GuacamoleReader.java | 46 +- .../guacamole/io/GuacamoleWriter.java | 46 +- .../guacamole/io/ReaderGuacamoleReader.java | 48 +- .../guacamole/io/WriterGuacamoleWriter.java | 46 +- .../guacamole/net/GuacamoleSocket.java | 46 +- .../guacamole/net/GuacamoleTunnel.java | 46 +- .../guacamole/net/InetGuacamoleSocket.java | 46 +- .../properties/FileGuacamoleProperty.java | 46 +- .../properties/GuacamoleProperties.java | 46 +- .../properties/GuacamoleProperty.java | 46 +- .../properties/IntegerGuacamoleProperty.java | 46 +- .../properties/StringGuacamoleProperty.java | 46 +- .../protocol/ConfiguredGuacamoleSocket.java | 46 +- .../protocol/GuacamoleConfiguration.java | 46 +- .../protocol/GuacamoleInstruction.java | 46 +- .../guacamole/servlet/GuacamoleSession.java | 46 +- .../servlet/GuacamoleTunnelServlet.java | 55 +- 20 files changed, 1046 insertions(+), 925 deletions(-) delete mode 100644 guacamole-common/COPYING create mode 100644 guacamole-common/LICENSE diff --git a/guacamole-common/COPYING b/guacamole-common/COPYING deleted file mode 100644 index dba13ed2d..000000000 --- a/guacamole-common/COPYING +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/guacamole-common/LICENSE b/guacamole-common/LICENSE new file mode 100644 index 000000000..7714141d1 --- /dev/null +++ b/guacamole-common/LICENSE @@ -0,0 +1,470 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java index cb2e586fa..9859f4ecd 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleException.java @@ -1,24 +1,41 @@ package net.sourceforge.guacamole; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ /** * A generic exception thrown when parts of the Guacamole API encounter diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java index 040a917e3..5d4677149 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.io; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java index a4bb7c041..cb685b72d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.io; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index a7df9bd22..2ee05bacc 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -1,29 +1,45 @@ package net.sourceforge.guacamole.io; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.io.IOException; import java.io.Reader; -import java.util.Arrays; import java.util.LinkedList; -import java.util.List; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index 78f425519..ded7cf82d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.io; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.io.IOException; import java.io.Writer; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index a61b12508..55713acf2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.net; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.io.GuacamoleReader; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 4e69051a0..cb1020cd7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.net; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index 28add9689..bb3268c01 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.net; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.ReaderGuacamoleReader; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java index 7cdf8dbd9..3b00dd6e8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.properties; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.io.File; import net.sourceforge.guacamole.GuacamoleException; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 6d272058d..00128a0c5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.properties; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.io.IOException; import java.io.InputStream; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java index 0db73caac..2ae7ac67d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.properties; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java index 570140778..44bff8ecb 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.properties; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java index 258a88571..fb794b83d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.properties; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 3406da582..a3de88cd7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.protocol; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 878dbb2de..638f8ccf3 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.protocol; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.util.HashMap; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index 595114204..0f2a81bf5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.protocol; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.util.HashMap; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index 762775372..a62f8e848 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -1,23 +1,41 @@ package net.sourceforge.guacamole.servlet; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index a10b7b0d9..b1cef01a9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -1,27 +1,44 @@ package net.sourceforge.guacamole.servlet; -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * 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. + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ * - * 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. + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.net.GuacamoleTunnel; import java.io.IOException; import java.io.Reader; -import java.io.UnsupportedEncodingException; import java.io.Writer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -234,14 +251,6 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { throw e; } - catch (UnsupportedEncodingException e) { - - // Detach and close - session.detachTunnel(tunnel); - tunnel.close(); - - throw new GuacamoleException("UTF-8 not supported by Java.", e); - } catch (IOException e) { // Detach and close From e0b1427e59a07749c0758352f537fa838a20f3a9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 5 Dec 2011 18:20:58 -0800 Subject: [PATCH 057/116] Converted ReaderGuacamoleReader to real parser of new instruction format (should be more efficient, and no more chance of invalid reads due to semicolons). --- .../guacamole/io/ReaderGuacamoleReader.java | 144 +++++++++++------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 2ee05bacc..4d4c5b9b7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -65,31 +65,88 @@ public class ReaderGuacamoleReader implements GuacamoleReader { this.input = input; } - private int usedLength = 0; - private char[] buffer = new char[20000]; + private int parseStart; - private int instructionStart; - private char[] instructionBuffer; + private char[] buffer = new char[20480]; + private int usedLength = 0; @Override public char[] read() throws GuacamoleException { - // If data was previously read via readInstruction(), return remaining - // data instead of reading more. - if (instructionBuffer != null) { - - char[] chunk = new char[instructionBuffer.length - instructionStart]; - System.arraycopy(instructionBuffer, instructionStart, chunk, 0, chunk.length); - instructionBuffer = null; - - return chunk; - } - try { // While we're blocking, or input is available for (;;) { + // Length of element + int elementLength = 0; + + // Resume where we left off + int i = parseStart; + + // Parse instruction in buffer + while (i < usedLength) { + + // Read character + char readChar = buffer[i++]; + + // If digit, update length + if (readChar >= '0' && readChar <= '9') + elementLength = elementLength * 10 + readChar - '0'; + + // If not digit, check for end-of-length character + else if (readChar == '.') { + + // Check if element present in buffer + if (i + elementLength < usedLength) { + + // Get terminator + char terminator = buffer[i + elementLength]; + + // Move to character after terminator + i += elementLength + 1; + + // Reset length + elementLength = 0; + + // Continue here if necessary + parseStart = i; + + // If terminator is semicolon, we have a full + // instruction. + if (terminator == ';') { + + // Copy instruction data + char[] instruction = new char[i]; + System.arraycopy(buffer, 0, instruction, 0, i); + + // Update buffer + usedLength -= i; + parseStart = 0; + System.arraycopy(buffer, i, buffer, 0, usedLength); + + return instruction; + + } + + // Handle invalid terminator characters + else if (terminator != ',') + throw new GuacamoleException("Element terminator of instruction was not ';' nor ','"); + + } + + // Otherwise, read more data + else + break; + + } + + // Otherwise, parse error + else + throw new GuacamoleException("Non-numeric character in element length."); + + } + // If past threshold, resize buffer before reading if (usedLength > buffer.length/2) { char[] biggerBuffer = new char[buffer.length*2]; @@ -102,30 +159,9 @@ public class ReaderGuacamoleReader implements GuacamoleReader { if (numRead == -1) return null; - int prevLength = usedLength; + // Update used length 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 } @@ -138,35 +174,35 @@ public class ReaderGuacamoleReader implements GuacamoleReader { @Override public GuacamoleInstruction readInstruction() throws GuacamoleException { - // Fill instructionBuffer if not already filled - if (instructionBuffer == null) { - instructionBuffer = read(); - instructionStart = 0; - } - + // Get instruction + char[] instructionBuffer = read(); + // If EOF, return EOF if (instructionBuffer == null) return null; + // Start of element + int elementStart = 0; + // Build list of elements LinkedList elements = new LinkedList(); - while (instructionStart < instructionBuffer.length) { + while (elementStart < instructionBuffer.length) { // Find end of length - int lengthEnd = ArrayUtils.indexOf(instructionBuffer, '.', instructionStart); + int lengthEnd = ArrayUtils.indexOf(instructionBuffer, '.', elementStart); // Parse length int length = Integer.parseInt(new String( instructionBuffer, - instructionStart, - lengthEnd - instructionStart + elementStart, + lengthEnd - elementStart )); // Parse element from just after period - instructionStart = lengthEnd + 1; + elementStart = lengthEnd + 1; String element = new String( instructionBuffer, - instructionStart, + elementStart, length ); @@ -174,11 +210,11 @@ public class ReaderGuacamoleReader implements GuacamoleReader { elements.addLast(element); // Read terminator after element - instructionStart += length; - char terminator = instructionBuffer[instructionStart]; + elementStart += length; + char terminator = instructionBuffer[elementStart]; // Continue reading instructions after terminator - instructionStart++; + elementStart++; // If we've reached the end of the instruction if (terminator == ';') @@ -195,10 +231,6 @@ public class ReaderGuacamoleReader implements GuacamoleReader { elements.toArray(new String[elements.size()]) ); - // Detect end of buffer - if (instructionStart >= instructionBuffer.length) - instructionBuffer = null; - // Return parsed instruction return instruction; From f9bcd5f7cf3c234eb6414078dc00364f92e84c60 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 5 Dec 2011 18:54:52 -0800 Subject: [PATCH 058/116] Added GuacamoleReader.available(), using to determine appropriate times to flush tunnel servlet output. --- .../sourceforge/guacamole/io/GuacamoleReader.java | 13 +++++++++++++ .../guacamole/io/ReaderGuacamoleReader.java | 10 ++++++++++ .../guacamole/servlet/GuacamoleTunnelServlet.java | 8 ++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java index 5d4677149..db2c1c1ff 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java @@ -48,6 +48,19 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; */ public interface GuacamoleReader { + /** + * Returns whether instruction data is available for reading. Note that + * this does not guarantee an entire instruction is available. If a full + * instruction is not available, this function can return true, and a call + * to read() will still block. + * + * @return true if instruction data is available for reading, false + * otherwise. + * @throws GuacamoleException If an error occurs while checking for + * available data. + */ + public boolean available() throws GuacamoleException; + /** * Reads at least one complete Guacamole instruction, returning a buffer * containing one or more complete Guacamole instructions and no diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 4d4c5b9b7..c5de457da 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -70,6 +70,16 @@ public class ReaderGuacamoleReader implements GuacamoleReader { private char[] buffer = new char[20480]; private int usedLength = 0; + @Override + public boolean available() throws GuacamoleException { + try { + return input.ready() || usedLength != 0; + } + catch (IOException e) { + throw new GuacamoleException(e); + } + } + @Override public char[] read() throws GuacamoleException { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java index b1cef01a9..0d735d17e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java @@ -224,8 +224,12 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet { // Get message output bytes out.write(message, 0, message.length); - out.flush(); - response.flushBuffer(); + + // Flush if we expect to wait + if (!reader.available()) { + out.flush(); + response.flushBuffer(); + } // No more messages another stream can take over if (tunnel.hasQueuedReaderThreads()) From 5da93b15c061e5588935944532a1bc799bad3161 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 10 Dec 2011 14:44:38 -0800 Subject: [PATCH 059/116] Rename GuacamoleTunnelServlet to GuacamoleHTTPTunnelServlet. --- ...leTunnelServlet.java => GuacamoleHTTPTunnelServlet.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/{GuacamoleTunnelServlet.java => GuacamoleHTTPTunnelServlet.java} (98%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java similarity index 98% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 0d735d17e..464b3fc60 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -53,13 +53,13 @@ import org.slf4j.LoggerFactory; /** * A HttpServlet implementing and abstracting the operations required by the - * JavaScript Guacamole client's tunnel. + * HTTP implementation of the JavaScript Guacamole client's tunnel. * * @author Michael Jumper */ -public abstract class GuacamoleTunnelServlet extends HttpServlet { +public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { - private Logger logger = LoggerFactory.getLogger(GuacamoleTunnelServlet.class); + private Logger logger = LoggerFactory.getLogger(GuacamoleHTTPTunnelServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { From 93b186f8cd2a35a52901945c8190863ef04c4b32 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 13 Dec 2011 18:04:14 -0800 Subject: [PATCH 060/116] Added README --- guacamole-common/README | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 guacamole-common/README diff --git a/guacamole-common/README b/guacamole-common/README new file mode 100644 index 000000000..f3769e311 --- /dev/null +++ b/guacamole-common/README @@ -0,0 +1,76 @@ + +------------------------------------------------------------ + About this README +------------------------------------------------------------ + +This README is intended to provide quick and to-the-point documentation for +technical users intending to compile parts of Guacamole themselves. + +Distribution-specific packages are available from the files section of the main +project page: + + http://sourceforge.net/projects/guacamole/files/ + +Distribution-specific documentation is provided on the Guacamole wiki: + + http://guac-dev.org/ + + +------------------------------------------------------------ + What is guacamole-common? +------------------------------------------------------------ + +guacamole-common is the core Java library used by the Guacamole web +application. + +guacamole-common provides abstract means of connecting to guacd, interfacing +with the JavaScript client and tunnel provided by guacamole-common-js, and +reading configuration from a standard location (guacamole.properties). + + +------------------------------------------------------------ + Compiling and installing guacamole-common +------------------------------------------------------------ + +guacamole-common is built using Maven. Building guacamole-common-js +compiles all classes and packages them into a redistributable .jar file. This +.jar file can be easily included in other Maven-based projects (like Guacamole). + +Note that prebuilt versions of guacamole-common are available from the +main guac-dev.org Maven repository which is referenced in all Maven +projects in Guacamole. Unless you want to make changes to guacamole-common +or you want to use a newer, unreleased version (such as the unstable branch), +you do not need to build this manually. You can let Maven download it for +you when you build Guacamole. + +1) Run mvn package + + $ mvn package + + Maven will download any needed dependencies for building the .jar file. + Once all dependencies have been downloaded, the .jar file will be + created in the target/ subdirectory of the current directory. + +2) Run mvn install + + $ mvn install + + DO NOT RUN THIS AS ROOT! + + Maven will install guacamole-common to your user's local Maven + repository where it can be used in future builds. It will not install + into a system-wide repository and does not require root privileges. + + Once installed, building other Maven projects that depend on + guacamole-common (such as Guacamole) will be possible. + + +------------------------------------------------------------ + Reporting problems +------------------------------------------------------------ + +Please report any bugs encountered by opening a new ticket at the Trac system +hosted at: + + http://guac-dev.org/trac/ + From 75dd6a4ffac8907bd982796c47c097a68be71563 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 18 Dec 2011 12:34:56 -0800 Subject: [PATCH 061/116] Added changelog. --- guacamole-common/ChangeLog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 guacamole-common/ChangeLog diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog new file mode 100644 index 000000000..7563099b6 --- /dev/null +++ b/guacamole-common/ChangeLog @@ -0,0 +1,19 @@ +2011-12-11 Michael Jumper + + * Implemented improved instruction format + * Fixed failed connections when using Konqueror + * Relicensed as Mozilla/LGPL/GPL + +2011-07-13 Michael Jumper + + * Fixed "no element found" errors + * Added timeouts + * Multiple tunnel support + * Better error handling + * Added JavaDoc + * Added logging + +2011-03-02 Michael Jumper + + * Initial release + From 3a95a270acec819e0d4ffb3806ea50bbf99e2d7e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 18 Dec 2011 14:56:02 -0800 Subject: [PATCH 062/116] Fixed typo README --- guacamole-common/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/README b/guacamole-common/README index f3769e311..68bf72358 100644 --- a/guacamole-common/README +++ b/guacamole-common/README @@ -32,7 +32,7 @@ reading configuration from a standard location (guacamole.properties). Compiling and installing guacamole-common ------------------------------------------------------------ -guacamole-common is built using Maven. Building guacamole-common-js +guacamole-common is built using Maven. Building guacamole-common compiles all classes and packages them into a redistributable .jar file. This .jar file can be easily included in other Maven-based projects (like Guacamole). From 2f3e8d3643191d5846ef9562be30d2003aeb6cf6 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 18 Dec 2011 21:31:56 -0800 Subject: [PATCH 063/116] Fixed comments. --- guacamole-common/doc/example/ExampleTunnelServlet.java | 4 ++-- .../net/sourceforge/guacamole/io/ReaderGuacamoleReader.java | 3 +++ .../net/sourceforge/guacamole/io/WriterGuacamoleWriter.java | 3 +++ .../net/sourceforge/guacamole/net/InetGuacamoleSocket.java | 1 - 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/guacamole-common/doc/example/ExampleTunnelServlet.java b/guacamole-common/doc/example/ExampleTunnelServlet.java index d335754f6..00f409859 100644 --- a/guacamole-common/doc/example/ExampleTunnelServlet.java +++ b/guacamole-common/doc/example/ExampleTunnelServlet.java @@ -9,9 +9,9 @@ import net.sourceforge.guacamole.net.InetGuacamoleSocket; import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket; import net.sourceforge.guacamole.servlet.GuacamoleSession; -import net.sourceforge.guacamole.servlet.GuacamoleTunnelServlet; +import net.sourceforge.guacamole.servlet.GuacamoleHTTPTunnelServlet; -public class ExampleTunnelServlet extends GuacamoleTunnelServlet { +public class ExampleTunnelServlet extends GuacamoleHTTPTunnelServlet { @Override protected GuacamoleTunnel doConnect(HttpServletRequest request) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index c5de457da..0d1164083 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -53,6 +53,9 @@ import org.apache.commons.lang3.ArrayUtils; */ public class ReaderGuacamoleReader implements GuacamoleReader { + /** + * Wrapped Reader to be used for all input. + */ private Reader input; /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index ded7cf82d..fca0d6bf7 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -50,6 +50,9 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction; */ public class WriterGuacamoleWriter implements GuacamoleWriter { + /** + * Wrapped Writer to be used for all output. + */ private Writer output; /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index bb3268c01..af38242d6 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -54,7 +54,6 @@ import net.sourceforge.guacamole.GuacamoleException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Provides abstract socket-like access to a Guacamole connection over a given * hostname and port. From b6b3f625846f87308b1761b2a739c3ef8e350232 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Tue, 20 Dec 2011 11:00:06 -0800 Subject: [PATCH 064/116] fixed file read error discovered while trying to use old style authentication --- .../guacamole/properties/FileGuacamoleProperty.java | 6 +++++- .../guacamole/properties/GuacamoleProperties.java | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java index 3b00dd6e8..112e8a696 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -49,7 +49,11 @@ public abstract class FileGuacamoleProperty implements GuacamoleProperty { @Override public File parseValue(String value) throws GuacamoleException { - return new File(value); + // having a null value is acceptable. If value is null, no error thrown. + if(value != null) + return new File(value); + else + return null; } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 00128a0c5..585bd46fc 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -108,7 +108,6 @@ public class GuacamoleProperties { * guacamole.properties. */ public static Type getProperty(GuacamoleProperty property) throws GuacamoleException { - if (exception != null) throw exception; From f89020ef0fcd3963c5f98f63a8f1623db8af7a92 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 20 Dec 2011 21:40:41 -0800 Subject: [PATCH 065/116] Style fixes. --- .../guacamole/properties/FileGuacamoleProperty.java | 10 ++++++---- .../guacamole/properties/GuacamoleProperties.java | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java index 112e8a696..58b3c6626 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -49,11 +49,13 @@ public abstract class FileGuacamoleProperty implements GuacamoleProperty { @Override public File parseValue(String value) throws GuacamoleException { - // having a null value is acceptable. If value is null, no error thrown. - if(value != null) - return new File(value); - else + + // If no property provided, return null. + if (value == null) return null; + + return new File(value); + } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 585bd46fc..00128a0c5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -108,6 +108,7 @@ public class GuacamoleProperties { * guacamole.properties. */ public static Type getProperty(GuacamoleProperty property) throws GuacamoleException { + if (exception != null) throw exception; From 882f52a5e2576cc7b4080d2a21300c9ef21bae76 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 20 Dec 2011 21:41:24 -0800 Subject: [PATCH 066/116] If Integer property not provided, parseValue() should return null. --- .../guacamole/properties/IntegerGuacamoleProperty.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java index 44bff8ecb..c57003e2d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java @@ -49,6 +49,10 @@ public abstract class IntegerGuacamoleProperty implements GuacamoleProperty Date: Tue, 13 Mar 2012 14:59:23 -0700 Subject: [PATCH 067/116] GuacamoleConfiguration should be serializable (ticket #111). --- .../guacamole/protocol/GuacamoleConfiguration.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 638f8ccf3..17096ec02 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -37,6 +37,7 @@ package net.sourceforge.guacamole.protocol; * * ***** END LICENSE BLOCK ***** */ +import java.io.Serializable; import java.util.HashMap; /** @@ -45,8 +46,10 @@ import java.util.HashMap; * * @author Michael Jumper */ -public class GuacamoleConfiguration { +public class GuacamoleConfiguration implements Serializable { + private static final long serialVersionUID = 1L; + private String protocol; private HashMap parameters = new HashMap(); From f084f7fbea003dcc328630034a6f3e9cb3937e92 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 15 Mar 2012 15:53:06 -0700 Subject: [PATCH 068/116] Bumping version to 0.6.0. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 83e2f391a..6b170617c 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.5.0 + 0.6.0 guacamole-common http://guacamole.sourceforge.net/ From fa10dba56610fed3051f2dc51cf4be30eb27e1e8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 23 Mar 2012 16:03:36 -0700 Subject: [PATCH 069/116] Automatically attach tunnel. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 464b3fc60..ed71e51d4 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -96,6 +96,13 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { GuacamoleTunnel tunnel = doConnect(request); if (tunnel != null) { + // Get session + HttpSession httpSession = request.getSession(true); + GuacamoleSession session = new GuacamoleSession(httpSession); + + // Attach tunnel to session + session.attachTunnel(tunnel); + logger.info("Connection from {} succeeded.", request.getRemoteAddr()); try { From d2198016c092087a86319d334c8f7816215989bd Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 24 Mar 2012 20:09:12 -0700 Subject: [PATCH 070/116] Added three new exception types. --- .../guacamole/GuacamoleInternalException.java | 79 +++++++++++++++++++ .../GuacamoleResourceNotFoundException.java | 79 +++++++++++++++++++ .../guacamole/GuacamoleSecurityException.java | 78 ++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java new file mode 100644 index 000000000..691527fea --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java @@ -0,0 +1,79 @@ + +package net.sourceforge.guacamole; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * A generic exception thrown when part of the Guacamole API encounters + * an unexpected, internal error. An internal error, if correctable, would + * require correction on the server side, not the client. + * + * @author Michael Jumper + */ +public class GuacamoleInternalException extends GuacamoleException { + + /** + * Creates a new GuacamoleException with the given message and cause. + * + * @param message A human readable description of the exception that + * occurred. + * @param cause The cause of this exception. + */ + public GuacamoleInternalException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new GuacamoleException with the given message. + * + * @param message A human readable description of the exception that + * occurred. + */ + public GuacamoleInternalException(String message) { + super(message); + } + + /** + * Creates a new GuacamoleException with the given cause. + * + * @param cause The cause of this exception. + */ + public GuacamoleInternalException(Throwable cause) { + super(cause); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java new file mode 100644 index 000000000..0bedb3dc3 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java @@ -0,0 +1,79 @@ + +package net.sourceforge.guacamole; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * A generic exception thrown when part of the Guacamole API fails to find + * a requested resource, such as a configuration or tunnel. + * + * @author Michael Jumper + */ +public class GuacamoleResourceNotFoundException extends GuacamoleException { + + /** + * Creates a new GuacamoleResourceNotFoundException with the given message + * and cause. + * + * @param message A human readable description of the exception that + * occurred. + * @param cause The cause of this exception. + */ + public GuacamoleResourceNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new GuacamoleResourceNotFoundException with the given message. + * + * @param message A human readable description of the exception that + * occurred. + */ + public GuacamoleResourceNotFoundException(String message) { + super(message); + } + + /** + * Creates a new GuacamoleResourceNotFoundException with the given cause. + * + * @param cause The cause of this exception. + */ + public GuacamoleResourceNotFoundException(Throwable cause) { + super(cause); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java new file mode 100644 index 000000000..bd4acd77e --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java @@ -0,0 +1,78 @@ + +package net.sourceforge.guacamole; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * A security-related exception thrown when parts of the Guacamole API is + * denying access to a resource. + * + * @author Michael Jumper + */ +public class GuacamoleSecurityException extends GuacamoleException { + + /** + * Creates a new GuacamoleSecurityException with the given message and cause. + * + * @param message A human readable description of the exception that + * occurred. + * @param cause The cause of this exception. + */ + public GuacamoleSecurityException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new GuacamoleSecurityException with the given message. + * + * @param message A human readable description of the exception that + * occurred. + */ + public GuacamoleSecurityException(String message) { + super(message); + } + + /** + * Creates a new GuacamoleSecurityException with the given cause. + * + * @param cause The cause of this exception. + */ + public GuacamoleSecurityException(Throwable cause) { + super(cause); + } + +} From f42fe962e273806b7033cefa7af8d95b9f60b565 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 24 Mar 2012 20:16:05 -0700 Subject: [PATCH 071/116] Distinct client/server exceptions. --- .../guacamole/GuacamoleClientException.java | 79 +++++++++++++++++++ .../GuacamoleResourceNotFoundException.java | 2 +- .../guacamole/GuacamoleSecurityException.java | 2 +- ...ion.java => GuacamoleServerException.java} | 8 +- 4 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClientException.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/{GuacamoleInternalException.java => GuacamoleServerException.java} (91%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClientException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClientException.java new file mode 100644 index 000000000..d162344cb --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClientException.java @@ -0,0 +1,79 @@ + +package net.sourceforge.guacamole; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * A generic exception thrown when part of the Guacamole API encounters + * an error in the client's request. Such an error, if correctable, usually + * requires correction on the client side, not the server. + * + * @author Michael Jumper + */ +public class GuacamoleClientException extends GuacamoleException { + + /** + * Creates a new GuacamoleException with the given message and cause. + * + * @param message A human readable description of the exception that + * occurred. + * @param cause The cause of this exception. + */ + public GuacamoleClientException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a new GuacamoleException with the given message. + * + * @param message A human readable description of the exception that + * occurred. + */ + public GuacamoleClientException(String message) { + super(message); + } + + /** + * Creates a new GuacamoleException with the given cause. + * + * @param cause The cause of this exception. + */ + public GuacamoleClientException(Throwable cause) { + super(cause); + } + +} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java index 0bedb3dc3..c6aec4a86 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.java @@ -43,7 +43,7 @@ package net.sourceforge.guacamole; * * @author Michael Jumper */ -public class GuacamoleResourceNotFoundException extends GuacamoleException { +public class GuacamoleResourceNotFoundException extends GuacamoleClientException { /** * Creates a new GuacamoleResourceNotFoundException with the given message diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java index bd4acd77e..f7cbe4c2e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleSecurityException.java @@ -43,7 +43,7 @@ package net.sourceforge.guacamole; * * @author Michael Jumper */ -public class GuacamoleSecurityException extends GuacamoleException { +public class GuacamoleSecurityException extends GuacamoleClientException { /** * Creates a new GuacamoleSecurityException with the given message and cause. diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleServerException.java similarity index 91% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleServerException.java index 691527fea..7d64f0099 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInternalException.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleServerException.java @@ -44,7 +44,7 @@ package net.sourceforge.guacamole; * * @author Michael Jumper */ -public class GuacamoleInternalException extends GuacamoleException { +public class GuacamoleServerException extends GuacamoleException { /** * Creates a new GuacamoleException with the given message and cause. @@ -53,7 +53,7 @@ public class GuacamoleInternalException extends GuacamoleException { * occurred. * @param cause The cause of this exception. */ - public GuacamoleInternalException(String message, Throwable cause) { + public GuacamoleServerException(String message, Throwable cause) { super(message, cause); } @@ -63,7 +63,7 @@ public class GuacamoleInternalException extends GuacamoleException { * @param message A human readable description of the exception that * occurred. */ - public GuacamoleInternalException(String message) { + public GuacamoleServerException(String message) { super(message); } @@ -72,7 +72,7 @@ public class GuacamoleInternalException extends GuacamoleException { * * @param cause The cause of this exception. */ - public GuacamoleInternalException(Throwable cause) { + public GuacamoleServerException(Throwable cause) { super(cause); } From 9b36638bf339243a0c38bda52946389f1013e334 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 24 Mar 2012 22:03:52 -0700 Subject: [PATCH 072/116] Use appropriate exceptions where possible, turn exceptions into appropriate error codes. --- .../guacamole/io/ReaderGuacamoleReader.java | 9 +- .../guacamole/io/WriterGuacamoleWriter.java | 3 +- .../guacamole/net/InetGuacamoleSocket.java | 5 +- .../properties/GuacamoleProperties.java | 5 +- .../properties/IntegerGuacamoleProperty.java | 3 +- .../servlet/GuacamoleHTTPTunnelServlet.java | 95 +++++++++++-------- .../guacamole/servlet/GuacamoleSession.java | 3 +- 7 files changed, 75 insertions(+), 48 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 0d1164083..d7ccf9bdf 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.io.Reader; import java.util.LinkedList; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; import org.apache.commons.lang3.ArrayUtils; @@ -79,7 +80,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { return input.ready() || usedLength != 0; } catch (IOException e) { - throw new GuacamoleException(e); + throw new GuacamoleServerException(e); } } @@ -144,7 +145,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Handle invalid terminator characters else if (terminator != ',') - throw new GuacamoleException("Element terminator of instruction was not ';' nor ','"); + throw new GuacamoleServerException("Element terminator of instruction was not ';' nor ','"); } @@ -156,7 +157,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Otherwise, parse error else - throw new GuacamoleException("Non-numeric character in element length."); + throw new GuacamoleServerException("Non-numeric character in element length."); } @@ -179,7 +180,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { } catch (IOException e) { - throw new GuacamoleException(e); + throw new GuacamoleServerException(e); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java index fca0d6bf7..fb0bddc53 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java @@ -40,6 +40,7 @@ package net.sourceforge.guacamole.io; import java.io.IOException; import java.io.Writer; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; /** @@ -72,7 +73,7 @@ public class WriterGuacamoleWriter implements GuacamoleWriter { output.flush(); } catch (IOException e) { - throw new GuacamoleException(e); + throw new GuacamoleServerException(e); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index af38242d6..cd5783023 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -51,6 +51,7 @@ import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.SocketAddress; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,7 +106,7 @@ public class InetGuacamoleSocket implements GuacamoleSocket { } catch (IOException e) { - throw new GuacamoleException(e); + throw new GuacamoleServerException(e); } } @@ -117,7 +118,7 @@ public class InetGuacamoleSocket implements GuacamoleSocket { sock.close(); } catch (IOException e) { - throw new GuacamoleException(e); + throw new GuacamoleServerException(e); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 00128a0c5..4a9d0c67f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; /** * Simple utility class for reading properties from the guacamole.properties @@ -90,7 +91,7 @@ public class GuacamoleProperties { } catch (IOException e) { - exception = new GuacamoleException("Error reading guacamole.properties", e); + exception = new GuacamoleServerException("Error reading guacamole.properties", e); } } @@ -135,7 +136,7 @@ public class GuacamoleProperties { Type value = getProperty(property); if (value == null) - throw new GuacamoleException("Property " + property.getName() + " is required."); + throw new GuacamoleServerException("Property " + property.getName() + " is required."); return value; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java index c57003e2d..cc7615c1f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java @@ -38,6 +38,7 @@ package net.sourceforge.guacamole.properties; * ***** END LICENSE BLOCK ***** */ import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; /** * A GuacamoleProperty whose value is an integer. @@ -58,7 +59,7 @@ public abstract class IntegerGuacamoleProperty implements GuacamoleProperty Date: Sat, 24 Mar 2012 22:06:15 -0700 Subject: [PATCH 073/116] JavaDoc. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index ecc5437da..16e2ee51f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -71,6 +71,15 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { handleTunnelRequest(request, response); } + /** + * Sends an error on the given HTTP response with the given integer error + * code. + * + * @param response The HTTP response to use to send the error. + * @param code The HTTP status code of the error. + * @throws ServletException If an error prevents sending of the error + * code. + */ private void sendError(HttpServletResponse response, int code) throws ServletException { try { From aa7c16f67d17e386db9492f79bef18f91d5dda8f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 24 Mar 2012 22:19:24 -0700 Subject: [PATCH 074/116] Improved handling of no tunnel. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 16e2ee51f..4f85a9e50 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -148,14 +148,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Failed to connect else { logger.info("Connection from {} failed.", request.getRemoteAddr()); - - try { - // Send error to client - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } - catch (IOException e) { - throw new GuacamoleServerException(e); - } + throw new GuacamoleResourceNotFoundException("No tunnel created."); } } From fbec97f356d53ba7c914f86a2de38bfb4e7c00f8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 24 Mar 2012 22:45:47 -0700 Subject: [PATCH 075/116] Actually send the error code specified... --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 4f85a9e50..44583e30c 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -86,7 +86,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // If response not committed, send error code if (!response.isCommitted()) - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.sendError(code); } catch (IOException ioe) { From fd4b4610ae1aa71c6f493446c9f864942de373c3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 25 Mar 2012 23:09:40 -0700 Subject: [PATCH 076/116] Should send "403 - Forbidden" for security exceptions, not "401 - Unauthorized". --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 44583e30c..90d91ab60 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -170,7 +170,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // HTTP response, logging each error appropriately. catch (GuacamoleSecurityException e) { logger.warn("Authorization failed.", e); - sendError(response, HttpServletResponse.SC_UNAUTHORIZED); + sendError(response, HttpServletResponse.SC_FORBIDDEN); } catch (GuacamoleResourceNotFoundException e) { logger.debug("Resource not found.", e); From 4b72a166ec200a1443f062944cc77ac7bd341157 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 26 Mar 2012 11:14:27 -0700 Subject: [PATCH 077/116] Remove use of Apache Commons. --- guacamole-common/pom.xml | 7 ------- .../guacamole/io/ReaderGuacamoleReader.java | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 6b170617c..3dd269ea0 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -43,13 +43,6 @@ 1.6.1 - - - org.apache.commons - commons-lang3 - 3.0.1 - - diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index d7ccf9bdf..cb35a4ac2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -44,7 +44,6 @@ import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; -import org.apache.commons.lang3.ArrayUtils; /** * A GuacamoleReader which wraps a standard Java Reader, using that Reader as @@ -202,8 +201,19 @@ public class ReaderGuacamoleReader implements GuacamoleReader { LinkedList elements = new LinkedList(); while (elementStart < instructionBuffer.length) { - // Find end of length - int lengthEnd = ArrayUtils.indexOf(instructionBuffer, '.', elementStart); + // Find end of length + int lengthEnd = -1; + for (int i=elementStart; i Date: Mon, 26 Mar 2012 11:34:42 -0700 Subject: [PATCH 078/116] Add isOpen() to socket and tunnel. Add getSocket() to tunnel. --- .../guacamole/net/GuacamoleSocket.java | 8 +++++++ .../guacamole/net/GuacamoleTunnel.java | 21 +++++++++++++++++++ .../guacamole/net/InetGuacamoleSocket.java | 5 +++++ .../protocol/ConfiguredGuacamoleSocket.java | 5 +++++ .../servlet/GuacamoleHTTPTunnelServlet.java | 10 +++++++-- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index 55713acf2..2aa8da52a 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -76,4 +76,12 @@ public interface GuacamoleSocket { */ public void close() throws GuacamoleException; + /** + * Returns whether this GuacamoleSocket is open and can be used for reading + * and writing. + * + * @return true if this GuacamoleSocket is open, false otherwise. + */ + public boolean isOpen(); + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index cb1020cd7..4a7bc0fd5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -57,6 +57,8 @@ public class GuacamoleTunnel { private ReentrantLock readerLock; private ReentrantLock writerLock; + private boolean open = true; + /** * Creates a new GuacamoleTunnel which synchronizes access to the * Guacamole instruction stream associated with the given GuacamoleSocket. @@ -146,6 +148,16 @@ public class GuacamoleTunnel { return uuid; } + /** + * Returns the GuacamoleSocket used by this GuacamoleTunnel for reading + * and writing. + * + * @return The GuacamoleSocket used by this GuacamoleTunnel. + */ + public GuacamoleSocket getSocket() { + return socket; + } + /** * Release all resources allocated to this GuacamoleTunnel. * @@ -156,4 +168,13 @@ public class GuacamoleTunnel { socket.close(); } + /** + * Returns whether this GuacamoleTunnel is open, or has been closed. + * + * @return true if this GuacamoleTunnel is open, false if it is closed. + */ + public boolean isOpen() { + return socket.isOpen(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index cd5783023..9a0e19893 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -132,5 +132,10 @@ public class InetGuacamoleSocket implements GuacamoleSocket { return writer; } + @Override + public boolean isOpen() { + return !sock.isClosed(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index a3de88cd7..192c32ca2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -121,4 +121,9 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { socket.close(); } + @Override + public boolean isOpen() { + return socket.isOpen(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 90d91ab60..e652f154d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -227,10 +227,15 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { HttpSession httpSession = request.getSession(false); GuacamoleSession session = new GuacamoleSession(httpSession); + // Get tunnel, ensure tunnel exists GuacamoleTunnel tunnel = session.getTunnel(tunnelUUID); if (tunnel == null) throw new GuacamoleResourceNotFoundException("No such tunnel."); + // Ensure tunnel is open + if (!tunnel.isOpen()) + throw new GuacamoleResourceNotFoundException("Tunnel is closed."); + // Obtain exclusive read access GuacamoleReader reader = tunnel.acquireReader(); @@ -265,7 +270,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { if (tunnel.hasQueuedReaderThreads()) break; - } while ((message = reader.read()) != null); + } while (tunnel.isOpen() && (message = reader.read()) != null); // Close tunnel immediately upon EOF if (message == null) @@ -340,7 +345,8 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { char[] buffer = new char[8192]; int length; - while ((length = input.read(buffer, 0, buffer.length)) != -1) + while (tunnel.isOpen() && + (length = input.read(buffer, 0, buffer.length)) != -1) writer.write(buffer, 0, length); } From 13d82c6a386d50bd02eb7ecd08e819affcc5252a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 26 Mar 2012 12:05:45 -0700 Subject: [PATCH 079/116] Removed unused field. --- .../java/net/sourceforge/guacamole/net/GuacamoleTunnel.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 4a7bc0fd5..3ed3f1677 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -57,8 +57,6 @@ public class GuacamoleTunnel { private ReentrantLock readerLock; private ReentrantLock writerLock; - private boolean open = true; - /** * Creates a new GuacamoleTunnel which synchronizes access to the * Guacamole instruction stream associated with the given GuacamoleSocket. From 5027be97bcec0d36843ceb2f5fed2fca50bd8d4d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 26 Mar 2012 12:33:36 -0700 Subject: [PATCH 080/116] Close guacamole.properties when done. --- .../sourceforge/guacamole/properties/GuacamoleProperties.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index 4a9d0c67f..cb626d54a 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -87,7 +87,9 @@ public class GuacamoleProperties { if (stream == null) throw new IOException("Resource /guacamole.properties not found."); - properties.load(stream); + // Load properties, always close stream + try { properties.load(stream); } + finally { stream.close(); } } catch (IOException e) { From 147829ad7c2e980de6b6d7636945f8b6151cb90e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 26 Mar 2012 13:46:20 -0700 Subject: [PATCH 081/116] Should be able to retrieve the configuration associated with a socket. --- .../protocol/ConfiguredGuacamoleSocket.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 192c32ca2..d546bc4e3 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -58,6 +58,7 @@ import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; public class ConfiguredGuacamoleSocket implements GuacamoleSocket { private GuacamoleSocket socket; + private GuacamoleConfiguration config; /** * Creates a new ConfiguredGuacamoleSocket which uses the given @@ -70,7 +71,8 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { * @throws GuacamoleException If an error occurs while completing the * initial protocol handshake. */ - public ConfiguredGuacamoleSocket(GuacamoleSocket socket, GuacamoleConfiguration config) throws GuacamoleException { + public ConfiguredGuacamoleSocket(GuacamoleSocket socket, + GuacamoleConfiguration config) throws GuacamoleException { this.socket = socket; @@ -106,6 +108,17 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { } + /** + * Returns the GuacamoleConfiguration used to configure this + * ConfiguredGuacamoleSocket. + * + * @return The GuacamoleConfiguration used to configure this + * ConfiguredGuacamoleSocket. + */ + public GuacamoleConfiguration getConfiguration() { + return config; + } + @Override public GuacamoleWriter getWriter() { return socket.getWriter(); From 34e0292e0e40876573f0c0894542db6fd0f8ffef Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 26 Mar 2012 18:51:23 -0700 Subject: [PATCH 082/116] Fixed project URL. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 3dd269ea0..a48cfc2ed 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -7,7 +7,7 @@ jar 0.6.0 guacamole-common - http://guacamole.sourceforge.net/ + http://guac-dev.org/ UTF-8 From fc903e1dd2391d3dcc5835b76be2e989dec08056 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 19 Apr 2012 14:33:31 -0700 Subject: [PATCH 083/116] Improve logging. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index e652f154d..7c790b200 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -292,11 +292,13 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { } catch (IOException e) { + // Log typically frequent I/O error if desired + logger.debug("Error writing to servlet output stream", e); + // Detach and close session.detachTunnel(tunnel); tunnel.close(); - throw new GuacamoleServerException("I/O error writing to servlet output stream.", e); } finally { tunnel.releaseReader(); From caafb7536a3a85bfccf1fbba4b5ee39771c39584 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 4 May 2012 18:38:49 -0700 Subject: [PATCH 084/116] Updated ChangeLog --- guacamole-common/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog index 7563099b6..0348ca77b 100644 --- a/guacamole-common/ChangeLog +++ b/guacamole-common/ChangeLog @@ -1,3 +1,9 @@ +2012-05-04 Michael Jumper + + * Improved logging and exception handling + * Removed minor dependency on Apache Commons + * Improved API usability + 2011-12-11 Michael Jumper * Implemented improved instruction format From 48ca5200b9b4f116997585226f20693179c09baf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 24 Jul 2012 15:33:44 -0700 Subject: [PATCH 085/116] Always read/write Guacamole protocol in UTF-8. --- .../sourceforge/guacamole/net/InetGuacamoleSocket.java | 4 ++-- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index 9a0e19893..d31e149bf 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -101,8 +101,8 @@ public class InetGuacamoleSocket implements GuacamoleSocket { sock.setSoTimeout(SOCKET_TIMEOUT); // On successful connect, retrieve I/O streams - reader = new ReaderGuacamoleReader(new InputStreamReader(sock.getInputStream())); - writer = new WriterGuacamoleWriter(new OutputStreamWriter(sock.getOutputStream())); + reader = new ReaderGuacamoleReader(new InputStreamReader(sock.getInputStream(), "UTF-8")); + writer = new WriterGuacamoleWriter(new OutputStreamWriter(sock.getOutputStream(), "UTF-8")); } catch (IOException e) { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 7c790b200..b3bd6dbde 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -36,10 +36,8 @@ package net.sourceforge.guacamole.servlet; * * ***** END LICENSE BLOCK ***** */ +import java.io.*; import net.sourceforge.guacamole.net.GuacamoleTunnel; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -246,7 +244,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // anything but application/octet-stream. response.setContentType("application/octet-stream"); - Writer out = response.getWriter(); + Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); // Detach tunnel and throw error if EOF (and we haven't sent any // data yet. @@ -343,7 +341,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { GuacamoleWriter writer = tunnel.acquireWriter(); - Reader input = request.getReader(); + Reader input = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8")); char[] buffer = new char[8192]; int length; From 4e72a2d4a637adbfc1aa79b03fb8879d470fa24c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 25 Jul 2012 10:11:10 -0700 Subject: [PATCH 086/116] Remove excessive layer of buffering. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index b3bd6dbde..626a42e82 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -37,7 +37,6 @@ package net.sourceforge.guacamole.servlet; * ***** END LICENSE BLOCK ***** */ import java.io.*; -import net.sourceforge.guacamole.net.GuacamoleTunnel; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -46,6 +45,7 @@ import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.*; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; +import net.sourceforge.guacamole.net.GuacamoleTunnel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -341,7 +341,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { GuacamoleWriter writer = tunnel.acquireWriter(); - Reader input = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8")); + Reader input = new InputStreamReader(request.getInputStream(), "UTF-8"); char[] buffer = new char[8192]; int length; From 211348c82f3d4d2e0cf212848693e168c9fac994 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 9 Aug 2012 11:43:33 -0700 Subject: [PATCH 087/116] Removed trailing whitespace. --- .../guacamole/io/GuacamoleReader.java | 4 ++-- .../guacamole/io/ReaderGuacamoleReader.java | 22 +++++++++---------- .../guacamole/net/GuacamoleSocket.java | 2 +- .../guacamole/net/GuacamoleTunnel.java | 8 +++---- .../guacamole/net/InetGuacamoleSocket.java | 6 ++--- .../properties/FileGuacamoleProperty.java | 2 +- .../properties/GuacamoleProperties.java | 2 +- .../protocol/ConfiguredGuacamoleSocket.java | 4 ++-- .../protocol/GuacamoleConfiguration.java | 2 +- .../servlet/GuacamoleHTTPTunnelServlet.java | 20 ++++++++--------- .../guacamole/servlet/GuacamoleSession.java | 2 +- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java index db2c1c1ff..c77e186fc 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleReader.java @@ -53,14 +53,14 @@ public interface GuacamoleReader { * this does not guarantee an entire instruction is available. If a full * instruction is not available, this function can return true, and a call * to read() will still block. - * + * * @return true if instruction data is available for reading, false * otherwise. * @throws GuacamoleException If an error occurs while checking for * available data. */ public boolean available() throws GuacamoleException; - + /** * Reads at least one complete Guacamole instruction, returning a buffer * containing one or more complete Guacamole instructions and no diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index cb35a4ac2..cb57eaaec 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -93,7 +93,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Length of element int elementLength = 0; - + // Resume where we left off int i = parseStart; @@ -115,7 +115,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Get terminator char terminator = buffer[i + elementLength]; - + // Move to character after terminator i += elementLength + 1; @@ -139,19 +139,19 @@ public class ReaderGuacamoleReader implements GuacamoleReader { System.arraycopy(buffer, i, buffer, 0, usedLength); return instruction; - + } // Handle invalid terminator characters else if (terminator != ',') throw new GuacamoleServerException("Element terminator of instruction was not ';' nor ','"); - + } // Otherwise, read more data else break; - + } // Otherwise, parse error @@ -189,14 +189,14 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Get instruction char[] instructionBuffer = read(); - + // If EOF, return EOF if (instructionBuffer == null) return null; - + // Start of element int elementStart = 0; - + // Build list of elements LinkedList elements = new LinkedList(); while (elementStart < instructionBuffer.length) { @@ -232,14 +232,14 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Append element to list of elements elements.addLast(element); - + // Read terminator after element elementStart += length; char terminator = instructionBuffer[elementStart]; // Continue reading instructions after terminator elementStart++; - + // If we've reached the end of the instruction if (terminator == ';') break; @@ -248,7 +248,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Pull opcode off elements list String opcode = elements.removeFirst(); - + // Create instruction GuacamoleInstruction instruction = new GuacamoleInstruction( Operation.fromOpcode(opcode), diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index 2aa8da52a..2d800fc0e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -79,7 +79,7 @@ public interface GuacamoleSocket { /** * Returns whether this GuacamoleSocket is open and can be used for reading * and writing. - * + * * @return true if this GuacamoleSocket is open, false otherwise. */ public boolean isOpen(); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 3ed3f1677..134ac07d8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -149,7 +149,7 @@ public class GuacamoleTunnel { /** * Returns the GuacamoleSocket used by this GuacamoleTunnel for reading * and writing. - * + * * @return The GuacamoleSocket used by this GuacamoleTunnel. */ public GuacamoleSocket getSocket() { @@ -158,7 +158,7 @@ public class GuacamoleTunnel { /** * Release all resources allocated to this GuacamoleTunnel. - * + * * @throws GuacamoleException if an error occurs while releasing * resources. */ @@ -168,11 +168,11 @@ public class GuacamoleTunnel { /** * Returns whether this GuacamoleTunnel is open, or has been closed. - * + * * @return true if this GuacamoleTunnel is open, false if it is closed. */ public boolean isOpen() { return socket.isOpen(); } - + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index d31e149bf..37e42e8e2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -64,7 +64,7 @@ import org.slf4j.LoggerFactory; public class InetGuacamoleSocket implements GuacamoleSocket { private Logger logger = LoggerFactory.getLogger(InetGuacamoleSocket.class); - + private GuacamoleReader reader; private GuacamoleWriter writer; @@ -86,7 +86,7 @@ public class InetGuacamoleSocket implements GuacamoleSocket { try { logger.debug("Connecting to guacd at {}:{}.", hostname, port); - + // Get address SocketAddress address = new InetSocketAddress( InetAddress.getByName(hostname), @@ -136,6 +136,6 @@ public class InetGuacamoleSocket implements GuacamoleSocket { public boolean isOpen() { return !sock.isClosed(); } - + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java index 58b3c6626..360cd6b59 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java @@ -49,7 +49,7 @@ public abstract class FileGuacamoleProperty implements GuacamoleProperty { @Override public File parseValue(String value) throws GuacamoleException { - + // If no property provided, return null. if (value == null) return null; diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index cb626d54a..a0e98b667 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -141,6 +141,6 @@ public class GuacamoleProperties { throw new GuacamoleServerException("Property " + property.getName() + " is required."); return value; - + } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index d546bc4e3..d361d5040 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -100,7 +100,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { args[i] = value; else args[i] = ""; - + } // Send args @@ -111,7 +111,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { /** * Returns the GuacamoleConfiguration used to configure this * ConfiguredGuacamoleSocket. - * + * * @return The GuacamoleConfiguration used to configure this * ConfiguredGuacamoleSocket. */ diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 17096ec02..d199ef0bd 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -49,7 +49,7 @@ import java.util.HashMap; public class GuacamoleConfiguration implements Serializable { private static final long serialVersionUID = 1L; - + private String protocol; private HashMap parameters = new HashMap(); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 626a42e82..1bfc61dbb 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -58,7 +58,7 @@ import org.slf4j.LoggerFactory; public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(GuacamoleHTTPTunnelServlet.class); - + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { handleTunnelRequest(request, response); @@ -72,7 +72,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { /** * Sends an error on the given HTTP response with the given integer error * code. - * + * * @param response The HTTP response to use to send the error. * @param code The HTTP status code of the error. * @throws ServletException If an error prevents sending of the error @@ -98,7 +98,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { } - + /** * Dispatches every HTTP GET and POST request to the appropriate handler * function based on the query string. @@ -132,7 +132,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { session.attachTunnel(tunnel); logger.info("Connection from {} succeeded.", request.getRemoteAddr()); - + try { // Send UUID to client response.getWriter().print(tunnel.getUUID().toString()); @@ -140,7 +140,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { catch (IOException e) { throw new GuacamoleServerException(e); } - + } // Failed to connect @@ -233,7 +233,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Ensure tunnel is open if (!tunnel.isOpen()) throw new GuacamoleResourceNotFoundException("Tunnel is closed."); - + // Obtain exclusive read access GuacamoleReader reader = tunnel.acquireReader(); @@ -273,7 +273,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Close tunnel immediately upon EOF if (message == null) tunnel.close(); - + // End-of-instructions marker out.write("0.;"); out.flush(); @@ -292,11 +292,11 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Log typically frequent I/O error if desired logger.debug("Error writing to servlet output stream", e); - + // Detach and close session.detachTunnel(tunnel); tunnel.close(); - + } finally { tunnel.releaseReader(); @@ -345,7 +345,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { char[] buffer = new char[8192]; int length; - while (tunnel.isOpen() && + while (tunnel.isOpen() && (length = input.read(buffer, 0, buffer.length)) != -1) writer.write(buffer, 0, length); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index 808bd0ee0..f89e44bef 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -54,7 +54,7 @@ import org.slf4j.LoggerFactory; public class GuacamoleSession { private Logger logger = LoggerFactory.getLogger(GuacamoleSession.class); - + private ConcurrentMap tunnels; /** From b3c721e159c2ccf3f79e441590353b3a198dd4c7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 9 Aug 2012 23:11:05 -0700 Subject: [PATCH 088/116] Add package-info.java files for all packages. --- .../java/net/sourceforge/guacamole/io/package-info.java | 6 ++++++ .../java/net/sourceforge/guacamole/net/package-info.java | 7 +++++++ .../main/java/net/sourceforge/guacamole/package-info.java | 8 ++++++++ .../sourceforge/guacamole/properties/package-info.java | 7 +++++++ .../net/sourceforge/guacamole/protocol/package-info.java | 6 ++++++ .../net/sourceforge/guacamole/servlet/package-info.java | 7 +++++++ 6 files changed, 41 insertions(+) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/io/package-info.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/package-info.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/package-info.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/package-info.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/package-info.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/package-info.java new file mode 100644 index 000000000..d903211ba --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/package-info.java @@ -0,0 +1,6 @@ + +/** + * All classes relating directly to data input or output. + */ +package net.sourceforge.guacamole.io; + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/package-info.java new file mode 100644 index 000000000..97ddc99d2 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/package-info.java @@ -0,0 +1,7 @@ + +/** + * Classes which apply to network-specific concepts, such as low-level sockets + * and tunnels. + */ +package net.sourceforge.guacamole.net; + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/package-info.java new file mode 100644 index 000000000..2d895938d --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/package-info.java @@ -0,0 +1,8 @@ + +/** + * All classes which apply generally across the Guacamole web application + * and all other web applications which use the API provided by the + * Guacamole project. + */ +package net.sourceforge.guacamole; + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java new file mode 100644 index 000000000..1c01c62c4 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java @@ -0,0 +1,7 @@ + +/** + * Provides classes for reading properties from the web-application-wide + * guacamole.properties file. + */ +package net.sourceforge.guacamole.properties; + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/package-info.java new file mode 100644 index 000000000..fc1e627e9 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/package-info.java @@ -0,0 +1,6 @@ + +/** + * Classes relating directly to the Guacamole protocol. + */ +package net.sourceforge.guacamole.protocol; + diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/package-info.java new file mode 100644 index 000000000..979a04dd5 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/package-info.java @@ -0,0 +1,7 @@ + +/** + * Classes which build upon the Java Servlet API, providing an HTTP-based + * tunnel and session management. + */ +package net.sourceforge.guacamole.servlet; + From ed4dd27a0538c331b25b0b89a50a0e27b821007d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 11 Aug 2012 14:08:23 -0700 Subject: [PATCH 089/116] Update changelog and version. --- guacamole-common/ChangeLog | 8 ++++++++ guacamole-common/pom.xml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog index 0348ca77b..531f0d230 100644 --- a/guacamole-common/ChangeLog +++ b/guacamole-common/ChangeLog @@ -1,3 +1,11 @@ +2012-08-09 Michael Jumper + + * Improve documentation + +2012-07-24 Michael Jumper + + * Fix Unicode bug + 2012-05-04 Michael Jumper * Improved logging and exception handling diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index a48cfc2ed..24d99b09a 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.6.0 + 0.6.1 guacamole-common http://guac-dev.org/ From 13db41f7049b9ff7240ac59d981efd333b0c7538 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 3 Oct 2012 10:27:53 -0700 Subject: [PATCH 090/116] Fix NPE if end-of-stream encountered during handshake (fixes #195). --- .../guacamole/protocol/ConfiguredGuacamoleSocket.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index d361d5040..1e57b171e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -40,6 +40,7 @@ package net.sourceforge.guacamole.protocol; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; @@ -86,7 +87,12 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { // Wait for server args GuacamoleInstruction instruction; do { + + // Read instruction, fail if end-of-stream instruction = reader.readInstruction(); + if (instruction == null) + throw new GuacamoleServerException("End of stream during initial handshake."); + } while (instruction.getOperation() != Operation.SERVER_ARGS); // Build args list off provided names and config From ad331a5704d7123e77c73932afe3ca76d1b5be26 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 3 Oct 2012 10:29:28 -0700 Subject: [PATCH 091/116] Update ChangeLog --- guacamole-common/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog index 531f0d230..3b07259a5 100644 --- a/guacamole-common/ChangeLog +++ b/guacamole-common/ChangeLog @@ -1,3 +1,7 @@ +2012-10-03 Michael Jumper + + * Fix NPE in handshake if end-of-stream encountered (ticket #195) + 2012-08-09 Michael Jumper * Improve documentation From 2a89f9ff09bd147d7c5f434a58cada36f32b9696 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 15 Oct 2012 10:43:52 -0700 Subject: [PATCH 092/116] Bump version. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 24d99b09a..c47a78191 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.6.1 + 0.6.2 guacamole-common http://guac-dev.org/ From 361b3149a57fa05c1894e3073495ae55f3176df6 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 16 Oct 2012 14:13:48 -0700 Subject: [PATCH 093/116] Ignore anything after UUID in tunnel requests (required for fix to #201). --- .../servlet/GuacamoleHTTPTunnelServlet.java | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 1bfc61dbb..b79a1249f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -59,6 +59,31 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { private Logger logger = LoggerFactory.getLogger(GuacamoleHTTPTunnelServlet.class); + /** + * The prefix of the query string which denotes a tunnel read operation. + */ + private static final String READ_PREFIX = "read:"; + + /** + * The prefix of the query string which denotes a tunnel write operation. + */ + private static final String WRITE_PREFIX = "write:"; + + /** + * The length of the read prefix, in characters. + */ + private static final int READ_PREFIX_LENGTH = READ_PREFIX.length(); + + /** + * The length of the write prefix, in characters. + */ + private static final int WRITE_PREFIX_LENGTH = WRITE_PREFIX.length(); + + /** + * The length of every tunnel UUID, in characters. + */ + private static final int UUID_LENGTH = 36; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { handleTunnelRequest(request, response); @@ -151,13 +176,19 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { } - // If read operation, call doRead() with tunnel UUID - else if(query.startsWith("read:")) - doRead(request, response, query.substring(5)); + // If read operation, call doRead() with tunnel UUID, ignoring any + // characters following the tunnel UUID. + else if(query.startsWith(READ_PREFIX)) + doRead(request, response, query.substring( + READ_PREFIX_LENGTH, + READ_PREFIX_LENGTH + UUID_LENGTH)); - // If write operation, call doWrite() with tunnel UUID - else if(query.startsWith("write:")) - doWrite(request, response, query.substring(6)); + // If write operation, call doWrite() with tunnel UUID, ignoring any + // characters following the tunnel UUID. + else if(query.startsWith(WRITE_PREFIX)) + doWrite(request, response, query.substring( + WRITE_PREFIX_LENGTH, + WRITE_PREFIX_LENGTH + UUID_LENGTH)); // Otherwise, invalid operation else From 76162ce14a0586c9d739f82147aa7af1ab1dbf75 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 16 Oct 2012 18:17:04 -0700 Subject: [PATCH 094/116] Update ChangeLog --- guacamole-common/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog index 3b07259a5..b2a9b8b92 100644 --- a/guacamole-common/ChangeLog +++ b/guacamole-common/ChangeLog @@ -1,3 +1,7 @@ +2012-10-16 Michael Jumper + + * Ignore data after tunnel UUID (part of fix for ticket #201) + 2012-10-03 Michael Jumper * Fix NPE in handshake if end-of-stream encountered (ticket #195) From dbc4a7f915aebcf00361735380402ad2b1c6add1 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 22 Oct 2012 17:06:30 -0700 Subject: [PATCH 095/116] Add audio/video/size instructions. --- .../protocol/GuacamoleInstruction.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index 0f2a81bf5..028955c28 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -53,6 +53,25 @@ public class GuacamoleInstruction { */ public enum Operation { + + /** + * Message sent from client to server specifying the optimal or + * desired screen size. + */ + CLIENT_SIZE("size"), + + /** + * Message sent from client to server specifying which audio mimetypes + * are supported. + */ + CLIENT_AUDIO("audio"), + + /** + * Message sent from client to server specifying which video mimetypes + * are supported. + */ + CLIENT_VIDEO("video"), + /** * Message sent from client to server specifying which protocol is * to be used. From ca579c6bc9bca75839d127c0ffd7de864e87a119 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Oct 2012 00:36:22 -0700 Subject: [PATCH 096/116] Implement client information object. --- .../protocol/GuacamoleClientInformation.java | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java new file mode 100644 index 000000000..6896947fd --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java @@ -0,0 +1,125 @@ + +package net.sourceforge.guacamole.protocol; + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is guacamole-common. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +import java.util.HashSet; +import java.util.Set; + +/** + * An abstract representation of Guacamole client information, including all + * information required by the Guacamole protocol during the preamble. + * + * @author Michael Jumper + */ +public class GuacamoleClientInformation { + + /** + * The optimal screen width requested by the client, in pixels. + */ + private int optimalScreenWidth = 1024; + + /** + * The optimal screen height requested by the client, in pixels. + */ + private int optimalScreenHeight = 768; + + /** + * The set of audio mimetypes reported by the client to be supported¾. + */ + private Set audioMimetypes = new HashSet(); + + /** + * The set of audio mimetypes reported by the client to be supported¾. + */ + private Set videoMimetypes = new HashSet(); + + /** + * Returns the optimal screen width requested by the client, in pixels. + * @return The optimal screen width requested by the client, in pixels. + */ + public int getOptimalScreenWidth() { + return optimalScreenWidth; + } + + /** + * Sets the client's optimal screen width. + * @param optimalScreenWidth The optimal screen width of the client. + */ + public void setOptimalScreenWidth(int optimalScreenWidth) { + this.optimalScreenWidth = optimalScreenWidth; + } + + /** + * Returns the optimal screen height requested by the client, in pixels. + * @return The optimal screen height requested by the client, in pixels. + */ + public int getOptimalScreenHeight() { + return optimalScreenHeight; + } + + /** + * Sets the client's optimal screen height. + * @param optimalScreenHeight The optimal screen height of the client. + */ + public void setOptimalScreenHeight(int optimalScreenHeight) { + this.optimalScreenHeight = optimalScreenHeight; + } + + /** + * Returns the set of audio mimetypes supported by the client. To add or + * removed supported mimetypes, the set returned by this function can be + * modified. + * + * @return The set of audio mimetypes supported by the client. + */ + public Set getAudioMimetypes() { + return audioMimetypes; + } + + /** + * Returns the set of video mimetypes supported by the client. To add or + * removed supported mimetypes, the set returned by this function can be + * modified. + * + * @return The set of video mimetypes supported by the client. + */ + public Set getVideoMimetypes() { + return videoMimetypes; + } + +} From 2c3a3a53f0f0c4e83ae4e15a3e9b372b2bd944ea Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Oct 2012 00:36:55 -0700 Subject: [PATCH 097/116] Use client information object to complete handshake. --- .../protocol/ConfiguredGuacamoleSocket.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 1e57b171e..2fe2bcb14 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -64,7 +64,8 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { /** * Creates a new ConfiguredGuacamoleSocket which uses the given * GuacamoleConfiguration to complete the initial protocol handshake over - * the given GuacamoleSocket. + * the given GuacamoleSocket. A default GuacamoleClientInformation object + * is used to provide basic client information. * * @param socket The GuacamoleSocket to wrap. * @param config The GuacamoleConfiguration to use to complete the initial @@ -74,6 +75,26 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { */ public ConfiguredGuacamoleSocket(GuacamoleSocket socket, GuacamoleConfiguration config) throws GuacamoleException { + this(socket, config, new GuacamoleClientInformation()); + } + + + /** + * Creates a new ConfiguredGuacamoleSocket which uses the given + * GuacamoleConfiguration and GuacamoleClientInformation to complete the + * initial protocol handshake over the given GuacamoleSocket. + * + * @param socket The GuacamoleSocket to wrap. + * @param config The GuacamoleConfiguration to use to complete the initial + * protocol handshake. + * @param info The GuacamoleClientInformation to use to complete the initial + * protocol handshake. + * @throws GuacamoleException If an error occurs while completing the + * initial protocol handshake. + */ + public ConfiguredGuacamoleSocket(GuacamoleSocket socket, + GuacamoleConfiguration config, + GuacamoleClientInformation info) throws GuacamoleException { this.socket = socket; @@ -109,6 +130,21 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { } + // Send size + writer.writeInstruction( + new GuacamoleInstruction( + Operation.CLIENT_SIZE, + Integer.toString(info.getOptimalScreenWidth()), + Integer.toString(info.getOptimalScreenHeight()) + ) + ); + + // Send supported audio formats (STUB) + writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_AUDIO)); + + // Send supported video formats (STUB) + writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_VIDEO)); + // Send args writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_CONNECT, args)); From d2006ec3d362aa24dc0047fba7fcc6c87b576e97 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Oct 2012 00:48:06 -0700 Subject: [PATCH 098/116] Bump version. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index c47a78191..b001974a6 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.6.2 + 0.7.0 guacamole-common http://guac-dev.org/ From 142c71a9efef888e2ff2ed05c5e97fedab834e63 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Oct 2012 19:32:34 -0700 Subject: [PATCH 099/116] Use List rather than Set to represent supported mimetypes (as they will be prioritized). --- .../protocol/GuacamoleClientInformation.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java index 6896947fd..424fc598c 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java @@ -37,7 +37,8 @@ package net.sourceforge.guacamole.protocol; * * ***** END LICENSE BLOCK ***** */ -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.Set; /** @@ -59,14 +60,14 @@ public class GuacamoleClientInformation { private int optimalScreenHeight = 768; /** - * The set of audio mimetypes reported by the client to be supported¾. + * The list of audio mimetypes reported by the client to be supported. */ - private Set audioMimetypes = new HashSet(); + private List audioMimetypes = new ArrayList(); /** - * The set of audio mimetypes reported by the client to be supported¾. + * The list of audio mimetypes reported by the client to be supported. */ - private Set videoMimetypes = new HashSet(); + private List videoMimetypes = new ArrayList(); /** * Returns the optimal screen width requested by the client, in pixels. @@ -101,24 +102,24 @@ public class GuacamoleClientInformation { } /** - * Returns the set of audio mimetypes supported by the client. To add or - * removed supported mimetypes, the set returned by this function can be + * Returns the list of audio mimetypes supported by the client. To add or + * removed supported mimetypes, the list returned by this function can be * modified. * * @return The set of audio mimetypes supported by the client. */ - public Set getAudioMimetypes() { + public List getAudioMimetypes() { return audioMimetypes; } /** - * Returns the set of video mimetypes supported by the client. To add or - * removed supported mimetypes, the set returned by this function can be + * Returns the list of video mimetypes supported by the client. To add or + * removed supported mimetypes, the list returned by this function can be * modified. * * @return The set of video mimetypes supported by the client. */ - public Set getVideoMimetypes() { + public List getVideoMimetypes() { return videoMimetypes; } From 4e43b79f0e8ce82ebb957f6df7280d85571662da Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 23 Oct 2012 19:45:16 -0700 Subject: [PATCH 100/116] Actually implement audio and video parts of preamble. --- .../protocol/ConfiguredGuacamoleSocket.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 2fe2bcb14..0a7605ddb 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -37,10 +37,10 @@ package net.sourceforge.guacamole.protocol; * * ***** END LICENSE BLOCK ***** */ -import net.sourceforge.guacamole.io.GuacamoleReader; -import net.sourceforge.guacamole.io.GuacamoleWriter; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleServerException; +import net.sourceforge.guacamole.io.GuacamoleReader; +import net.sourceforge.guacamole.io.GuacamoleWriter; import net.sourceforge.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; @@ -139,11 +139,19 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { ) ); - // Send supported audio formats (STUB) - writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_AUDIO)); + // Send supported audio formats + writer.writeInstruction( + new GuacamoleInstruction( + Operation.CLIENT_AUDIO, + info.getAudioMimetypes().toArray(new String[0]) + )); - // Send supported video formats (STUB) - writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_VIDEO)); + // Send supported video formats + writer.writeInstruction( + new GuacamoleInstruction( + Operation.CLIENT_VIDEO, + info.getAudioMimetypes().toArray(new String[0]) + )); // Send args writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_CONNECT, args)); From 59fa48d95705c41905f247b52d5e3fe7b77cf60d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 24 Oct 2012 11:59:23 -0700 Subject: [PATCH 101/116] Update ChangeLog --- guacamole-common/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guacamole-common/ChangeLog b/guacamole-common/ChangeLog index b2a9b8b92..9ccf90988 100644 --- a/guacamole-common/ChangeLog +++ b/guacamole-common/ChangeLog @@ -1,3 +1,7 @@ +2012-10-24 Michael Jumper + + * Implement audio/video/size preamble in handshake + 2012-10-16 Michael Jumper * Ignore data after tunnel UUID (part of fix for ticket #201) From fa5c060fad3c0b3f89a3c77f36a2a1768e4dcca7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 25 Oct 2012 19:05:59 -0700 Subject: [PATCH 102/116] Send video mimetypes for video (using wrong collection). --- .../guacamole/protocol/ConfiguredGuacamoleSocket.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 0a7605ddb..b103453a4 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -150,7 +150,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { writer.writeInstruction( new GuacamoleInstruction( Operation.CLIENT_VIDEO, - info.getAudioMimetypes().toArray(new String[0]) + info.getVideoMimetypes().toArray(new String[0]) )); // Send args From d5f5e6651423fe09ef4dc30275fb908b4c75a90a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 10 Nov 2012 23:16:39 -0800 Subject: [PATCH 103/116] Fixes #213 - iOS 6 caching bug. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index b79a1249f..45a60ca56 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -159,6 +159,9 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { logger.info("Connection from {} succeeded.", request.getRemoteAddr()); try { + // Ensure buggy browsers do not cache response + response.setHeader("Cache-Control", "no-cache"); + // Send UUID to client response.getWriter().print(tunnel.getUUID().toString()); } From 32cdb3b3cd09e5a94fba2409315eb4bf72fec77b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 10 Nov 2012 23:18:31 -0800 Subject: [PATCH 104/116] Avoid caching for all responses. --- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 45a60ca56..7b976928b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -277,6 +277,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // buffer 1024 bytes before starting a normal stream if we use // anything but application/octet-stream. response.setContentType("application/octet-stream"); + response.setHeader("Cache-Control", "no-cache"); Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); @@ -368,6 +369,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // attempt to parse the result, even though the JavaScript client // does not explicitly request such parsing. response.setContentType("application/octet-stream"); + response.setHeader("Cache-Control", "no-cache"); response.setContentLength(0); // Send data From 1f81b952fee0a8c8a4bce9b44e71f045c0070d2c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 28 Jan 2013 17:06:10 -0800 Subject: [PATCH 105/116] Configuration should be stored. --- .../guacamole/protocol/ConfiguredGuacamoleSocket.java | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index b103453a4..a8bb31bd3 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -97,6 +97,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { GuacamoleClientInformation info) throws GuacamoleException { this.socket = socket; + this.config = config; // Get reader and writer GuacamoleReader reader = socket.getReader(); From c1c744f6fb683013af4ce669539fa5c8f0b3bf29 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 29 Jan 2013 14:03:32 -0800 Subject: [PATCH 106/116] Bump version. --- guacamole-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index b001974a6..9a2c74e7e 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.7.0 + 0.7.1 guacamole-common http://guac-dev.org/ From 1b103f80a8f14bce8b76637a65900b84c9e4f7b0 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 11 Jan 2013 12:08:35 -0800 Subject: [PATCH 107/116] Remove operation enum - just use opcode. --- guacamole-common/pom.xml | 2 +- .../guacamole/io/ReaderGuacamoleReader.java | 3 +- .../protocol/ConfiguredGuacamoleSocket.java | 13 +-- .../protocol/GuacamoleInstruction.java | 105 ++---------------- 4 files changed, 18 insertions(+), 105 deletions(-) diff --git a/guacamole-common/pom.xml b/guacamole-common/pom.xml index 9a2c74e7e..0e03c342d 100644 --- a/guacamole-common/pom.xml +++ b/guacamole-common/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common jar - 0.7.1 + 0.8.0 guacamole-common http://guac-dev.org/ diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index cb57eaaec..ed4ed4580 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -43,7 +43,6 @@ import java.util.LinkedList; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.protocol.GuacamoleInstruction; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; /** * A GuacamoleReader which wraps a standard Java Reader, using that Reader as @@ -251,7 +250,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { // Create instruction GuacamoleInstruction instruction = new GuacamoleInstruction( - Operation.fromOpcode(opcode), + opcode, elements.toArray(new String[elements.size()]) ); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index a8bb31bd3..0dd34abe8 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -42,7 +42,6 @@ import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; import net.sourceforge.guacamole.net.GuacamoleSocket; -import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation; /** * A GuacamoleSocket which pre-configures the connection based on a given @@ -104,7 +103,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { GuacamoleWriter writer = socket.getWriter(); // Send protocol - writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol())); + writer.writeInstruction(new GuacamoleInstruction("select", config.getProtocol())); // Wait for server args GuacamoleInstruction instruction; @@ -115,7 +114,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { if (instruction == null) throw new GuacamoleServerException("End of stream during initial handshake."); - } while (instruction.getOperation() != Operation.SERVER_ARGS); + } while (!instruction.getOpcode().equals("args")); // Build args list off provided names and config String[] args = new String[instruction.getArgs().length]; @@ -134,7 +133,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { // Send size writer.writeInstruction( new GuacamoleInstruction( - Operation.CLIENT_SIZE, + "size", Integer.toString(info.getOptimalScreenWidth()), Integer.toString(info.getOptimalScreenHeight()) ) @@ -143,19 +142,19 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { // Send supported audio formats writer.writeInstruction( new GuacamoleInstruction( - Operation.CLIENT_AUDIO, + "audio", info.getAudioMimetypes().toArray(new String[0]) )); // Send supported video formats writer.writeInstruction( new GuacamoleInstruction( - Operation.CLIENT_VIDEO, + "video", info.getVideoMimetypes().toArray(new String[0]) )); // Send args - writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_CONNECT, args)); + writer.writeInstruction(new GuacamoleInstruction("connect", args)); } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index 028955c28..75032d352 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -37,8 +37,6 @@ package net.sourceforge.guacamole.protocol; * * ***** END LICENSE BLOCK ***** */ -import java.util.HashMap; - /** * An abstract representation of a Guacamole instruction, as defined by the * Guacamole protocol. @@ -47,111 +45,28 @@ import java.util.HashMap; */ public class GuacamoleInstruction { - /** - * The operation performed by a particular Guacamole instruction. Each - * Operation is associated with a unique opcode. - */ - public enum Operation { - - - /** - * Message sent from client to server specifying the optimal or - * desired screen size. - */ - CLIENT_SIZE("size"), - - /** - * Message sent from client to server specifying which audio mimetypes - * are supported. - */ - CLIENT_AUDIO("audio"), - - /** - * Message sent from client to server specifying which video mimetypes - * are supported. - */ - CLIENT_VIDEO("video"), - - /** - * Message sent from client to server specifying which protocol is - * to be used. - */ - CLIENT_SELECT("select"), - - /** - * Message sent from client to server specifying which argument - * values correspond to the arguments required by the selected - * protocol. - */ - CLIENT_CONNECT("connect"), - - /** - * Message sent from server to client specifying which arguments - * are required by the selected protocol. - */ - SERVER_ARGS("args"); - - private String opcode; - private Operation(String opcode) { - this.opcode = opcode; - } - - /** - * Returns the unique opcode associated with this Operation. - * @return The unique opcode associated with this Operation. - */ - public String getOpcode() { - return opcode; - } - - /** - * Static hash of all opcodes and their corresponding Operations. - */ - private static final HashMap opcodeToOperation; - static { - - opcodeToOperation = new HashMap(); - - for (Operation operation : Operation.values()) - opcodeToOperation.put(operation.getOpcode(), operation); - - } - - /** - * Returns the corresponding Operation having the given opcode, if any. - * - * @param opcode The unique opcode associated with an Operation. - * @return The Operation associated with the given opcode, or null if - * no such Operation is defined. - */ - public static Operation fromOpcode(String opcode) { - return opcodeToOperation.get(opcode); - } - - } - - private Operation operation; + private String opcode; private String[] args; /** * Creates a new GuacamoleInstruction having the given Operation and * list of arguments values. * - * @param operation The Operation of the instruction to create. + * @param operation The opcode of the instruction to create. * @param args The list of argument values to provide in the new * instruction if any. */ - public GuacamoleInstruction(Operation operation, String... args) { - this.operation = operation; + public GuacamoleInstruction(String opcode, String... args) { + this.opcode = opcode; this.args = args; } /** - * Returns the Operation associated with this GuacamoleInstruction. - * @return The Operation associated with this GuacamoleInstruction. + * Returns the opcode associated with this GuacamoleInstruction. + * @return The opcode associated with this GuacamoleInstruction. */ - public Operation getOperation() { - return operation; + public String getOpcode() { + return opcode; } /** @@ -177,9 +92,9 @@ public class GuacamoleInstruction { StringBuilder buff = new StringBuilder(); - buff.append(operation.getOpcode().length()); + buff.append(opcode.length()); buff.append('.'); - buff.append(operation.getOpcode()); + buff.append(opcode); for (int i=0; i Date: Tue, 29 Jan 2013 14:17:11 -0800 Subject: [PATCH 108/116] Expose immutable List rather than array in GuacamoleInstruction. Bump version to 0.8.0. --- .../protocol/ConfiguredGuacamoleSocket.java | 24 +++++++++----- .../protocol/GuacamoleInstruction.java | 33 ++++++++++++++----- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 0dd34abe8..4fafc54a2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -37,6 +37,7 @@ package net.sourceforge.guacamole.protocol; * * ***** END LICENSE BLOCK ***** */ +import java.util.List; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.io.GuacamoleReader; @@ -117,16 +118,21 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { } while (!instruction.getOpcode().equals("args")); // Build args list off provided names and config - String[] args = new String[instruction.getArgs().length]; - for (int i=0; i arg_names = instruction.getArgs(); + String[] arg_values = new String[arg_names.size()]; + for (int i=0; i args; /** * Creates a new GuacamoleInstruction having the given Operation and @@ -58,7 +69,7 @@ public class GuacamoleInstruction { */ public GuacamoleInstruction(String opcode, String... args) { this.opcode = opcode; - this.args = args; + this.args = Collections.unmodifiableList(Arrays.asList(args)); } /** @@ -70,13 +81,14 @@ public class GuacamoleInstruction { } /** - * Returns an array of all argument values specified for this - * GuacamoleInstruction. + * Returns a List of all argument values specified for this + * GuacamoleInstruction. Note that the List returned is immutable. + * Attempts to modify the list will result in exceptions. * - * @return An array of all argument values specified for this + * @return A List of all argument values specified for this * GuacamoleInstruction. */ - public String[] getArgs() { + public List getArgs() { return args; } @@ -92,17 +104,20 @@ public class GuacamoleInstruction { StringBuilder buff = new StringBuilder(); + // Write opcode buff.append(opcode.length()); buff.append('.'); buff.append(opcode); - for (int i=0; i Date: Tue, 29 Jan 2013 15:00:12 -0800 Subject: [PATCH 109/116] Ensure I/O streams are closed when done in GuacamoleHTTPTunnelServlet. --- .../servlet/GuacamoleHTTPTunnelServlet.java | 92 ++++++++++++------- 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 7b976928b..36d5517d6 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -279,40 +279,51 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { response.setContentType("application/octet-stream"); response.setHeader("Cache-Control", "no-cache"); - Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); + // Get writer for response + Writer out = new BufferedWriter(new OutputStreamWriter( + response.getOutputStream(), "UTF-8")); - // Detach tunnel and throw error if EOF (and we haven't sent any - // data yet. - char[] message = reader.read(); - if (message == null) - throw new GuacamoleResourceNotFoundException("Tunnel reached end of stream."); + // Stream data to response, ensuring output stream is closed + try { - // For all messages, until another stream is ready (we send at least one message) - do { + // Detach tunnel and throw error if EOF (and we haven't sent any + // data yet. + char[] message = reader.read(); + if (message == null) + throw new GuacamoleResourceNotFoundException("Tunnel reached end of stream."); - // Get message output bytes - out.write(message, 0, message.length); + // For all messages, until another stream is ready (we send at least one message) + do { - // Flush if we expect to wait - if (!reader.available()) { - out.flush(); - response.flushBuffer(); - } + // Get message output bytes + out.write(message, 0, message.length); - // No more messages another stream can take over - if (tunnel.hasQueuedReaderThreads()) - break; + // Flush if we expect to wait + if (!reader.available()) { + out.flush(); + response.flushBuffer(); + } - } while (tunnel.isOpen() && (message = reader.read()) != null); + // No more messages another stream can take over + if (tunnel.hasQueuedReaderThreads()) + break; - // Close tunnel immediately upon EOF - if (message == null) - tunnel.close(); + } while (tunnel.isOpen() && (message = reader.read()) != null); - // End-of-instructions marker - out.write("0.;"); - out.flush(); - response.flushBuffer(); + // Close tunnel immediately upon EOF + if (message == null) + tunnel.close(); + + // End-of-instructions marker + out.write("0.;"); + out.flush(); + response.flushBuffer(); + } + + // Always close output stream + finally { + out.close(); + } } catch (GuacamoleException e) { @@ -375,15 +386,32 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Send data try { + // Get writer from tunnel GuacamoleWriter writer = tunnel.acquireWriter(); - Reader input = new InputStreamReader(request.getInputStream(), "UTF-8"); - char[] buffer = new char[8192]; + // Get input reader for HTTP stream + Reader input = new InputStreamReader( + request.getInputStream(), "UTF-8"); - int length; - while (tunnel.isOpen() && - (length = input.read(buffer, 0, buffer.length)) != -1) - writer.write(buffer, 0, length); + // Transfer data from input stream to tunnel output, ensuring + // input is always closed + try { + + // Buffer + int length; + char[] buffer = new char[8192]; + + // Transfer data using buffer + while (tunnel.isOpen() && + (length = input.read(buffer, 0, buffer.length)) != -1) + writer.write(buffer, 0, length); + + } + + // Close input stream in all cases + finally { + input.close(); + } } catch (IOException e) { From 69b7d7ead7f8d6905a72675be536968fc57f8e04 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 31 Jan 2013 10:01:55 -0800 Subject: [PATCH 110/116] Read guacamole.properties from home directory first. --- .../properties/GuacamoleProperties.java | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java index a0e98b667..2706fa7bb 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java @@ -37,6 +37,8 @@ package net.sourceforge.guacamole.properties; * * ***** END LICENSE BLOCK ***** */ +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; @@ -83,9 +85,36 @@ public class GuacamoleProperties { try { - InputStream stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties"); - if (stream == null) - throw new IOException("Resource /guacamole.properties not found."); + // Attempt to find Guacamole home + File guacHome; + + // Get explicitly specified directory, if any + String desiredDir = System.getProperty("guacamole.home"); + if (desiredDir != null) + guacHome = new File(desiredDir); + + // If not explicitly-define directory, use ~/.guacamole + else + guacHome = new File(System.getProperty("user.home"), ".guacamole"); + + InputStream stream; + + // If not a directory, load from classpath + if (!guacHome.isDirectory()) { + + // Read from classpath + stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties"); + if (stream == null) + throw new IOException( + "guacamole.properties not loaded from " + guacHome + + " (not a directory), and guacamole.properties could" + + " not be found as a resource in the classpath."); + + } + + // Otherwise, try to load from file + else + stream = new FileInputStream(new File(guacHome, "guacamole.properties")); // Load properties, always close stream try { properties.load(stream); } From c003a2c2253b9d90beb7c615bca823ac1e8a92a5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 31 Jan 2013 10:07:00 -0800 Subject: [PATCH 111/116] Move GuacamoleProperties stuff to guacamole-ext. --- .../properties/FileGuacamoleProperty.java | 61 ------ .../properties/GuacamoleProperties.java | 175 ------------------ .../properties/GuacamoleProperty.java | 71 ------- .../properties/IntegerGuacamoleProperty.java | 67 ------- .../properties/StringGuacamoleProperty.java | 54 ------ .../guacamole/properties/package-info.java | 7 - 6 files changed, 435 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java deleted file mode 100644 index 360cd6b59..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java +++ /dev/null @@ -1,61 +0,0 @@ - -package net.sourceforge.guacamole.properties; - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is guacamole-common. - * - * The Initial Developer of the Original Code is - * Michael Jumper. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -import java.io.File; -import net.sourceforge.guacamole.GuacamoleException; - -/** - * A GuacamoleProperty whose value is a filename. - * - * @author Michael Jumper - */ -public abstract class FileGuacamoleProperty implements GuacamoleProperty { - - @Override - public File parseValue(String value) throws GuacamoleException { - - // If no property provided, return null. - if (value == null) - return null; - - return new File(value); - - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java deleted file mode 100644 index 2706fa7bb..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java +++ /dev/null @@ -1,175 +0,0 @@ - -package net.sourceforge.guacamole.properties; - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is guacamole-common. - * - * The Initial Developer of the Original Code is - * Michael Jumper. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.GuacamoleServerException; - -/** - * Simple utility class for reading properties from the guacamole.properties - * file in the root of the classpath. - * - * @author Michael Jumper - */ -public class GuacamoleProperties { - - private GuacamoleProperties() {} - - /** - * The hostname of the server where guacd (the Guacamole proxy server) is - * running. - */ - public static final StringGuacamoleProperty GUACD_HOSTNAME = new StringGuacamoleProperty() { - - @Override - public String getName() { return "guacd-hostname"; } - - }; - - /** - * The port that guacd (the Guacamole proxy server) is listening on. - */ - public static final IntegerGuacamoleProperty GUACD_PORT = new IntegerGuacamoleProperty() { - - @Override - public String getName() { return "guacd-port"; } - - }; - - private static final Properties properties; - private static GuacamoleException exception; - - static { - - properties = new Properties(); - - try { - - // Attempt to find Guacamole home - File guacHome; - - // Get explicitly specified directory, if any - String desiredDir = System.getProperty("guacamole.home"); - if (desiredDir != null) - guacHome = new File(desiredDir); - - // If not explicitly-define directory, use ~/.guacamole - else - guacHome = new File(System.getProperty("user.home"), ".guacamole"); - - InputStream stream; - - // If not a directory, load from classpath - if (!guacHome.isDirectory()) { - - // Read from classpath - stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties"); - if (stream == null) - throw new IOException( - "guacamole.properties not loaded from " + guacHome - + " (not a directory), and guacamole.properties could" - + " not be found as a resource in the classpath."); - - } - - // Otherwise, try to load from file - else - stream = new FileInputStream(new File(guacHome, "guacamole.properties")); - - // Load properties, always close stream - try { properties.load(stream); } - finally { stream.close(); } - - } - catch (IOException e) { - exception = new GuacamoleServerException("Error reading guacamole.properties", e); - } - - } - - /** - * Given a GuacamoleProperty, parses and returns the value set for that - * property in guacamole.properties, if any. - * - * @param The type that the given property is parsed into. - * @param property The property to read from guacamole.properties. - * @return The parsed value of the property as read from - * guacamole.properties. - * @throws GuacamoleException If an error occurs while parsing the value - * for the given property in - * guacamole.properties. - */ - public static Type getProperty(GuacamoleProperty property) throws GuacamoleException { - - if (exception != null) - throw exception; - - return property.parseValue(properties.getProperty(property.getName())); - - } - - /** - * Given a GuacamoleProperty, parses and returns the value set for that - * property in guacamole.properties. An exception is thrown if the value - * is not provided. - * - * @param The type that the given property is parsed into. - * @param property The property to read from guacamole.properties. - * @return The parsed value of the property as read from - * guacamole.properties. - * @throws GuacamoleException If an error occurs while parsing the value - * for the given property in - * guacamole.properties, or if the property is - * not specified. - */ - public static Type getRequiredProperty(GuacamoleProperty property) - throws GuacamoleException { - - Type value = getProperty(property); - if (value == null) - throw new GuacamoleServerException("Property " + property.getName() + " is required."); - - return value; - - } -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java deleted file mode 100644 index 2ae7ac67d..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java +++ /dev/null @@ -1,71 +0,0 @@ - -package net.sourceforge.guacamole.properties; - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is guacamole-common. - * - * The Initial Developer of the Original Code is - * Michael Jumper. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -import net.sourceforge.guacamole.GuacamoleException; - -/** - * An abstract representation of a property in the guacamole.properties file, - * which parses into a specific type. - * - * @author Michael Jumper - * @param The type this GuacamoleProperty will parse into. - */ -public interface GuacamoleProperty { - - /** - * Returns the name of the property in guacamole.properties that this - * GuacamoleProperty will parse. - * - * @return The name of the property in guacamole.properties that this - * GuacamoleProperty will parse. - */ - public String getName(); - - /** - * Parses the given string value into the type associated with this - * GuacamoleProperty. - * - * @param value The string value to parse. - * @return The parsed value. - * @throws GuacamoleException If an error occurs while parsing the - * provided value. - */ - public Type parseValue(String value) throws GuacamoleException; - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java deleted file mode 100644 index cc7615c1f..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.java +++ /dev/null @@ -1,67 +0,0 @@ - -package net.sourceforge.guacamole.properties; - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is guacamole-common. - * - * The Initial Developer of the Original Code is - * Michael Jumper. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.GuacamoleServerException; - -/** - * A GuacamoleProperty whose value is an integer. - * - * @author Michael Jumper - */ -public abstract class IntegerGuacamoleProperty implements GuacamoleProperty { - - @Override - public Integer parseValue(String value) throws GuacamoleException { - - // If no property provided, return null. - if (value == null) - return null; - - try { - Integer integer = new Integer(value); - return integer; - } - catch (NumberFormatException e) { - throw new GuacamoleServerException("Property \"" + getName() + "\" must be an integer.", e); - } - - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java deleted file mode 100644 index fb794b83d..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.java +++ /dev/null @@ -1,54 +0,0 @@ - -package net.sourceforge.guacamole.properties; - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is guacamole-common. - * - * The Initial Developer of the Original Code is - * Michael Jumper. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -import net.sourceforge.guacamole.GuacamoleException; - -/** - * A GuacamoleProperty whose value is a simple string. - * - * @author Michael Jumper - */ -public abstract class StringGuacamoleProperty implements GuacamoleProperty { - - @Override - public String parseValue(String value) throws GuacamoleException { - return value; - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java deleted file mode 100644 index 1c01c62c4..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/properties/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ - -/** - * Provides classes for reading properties from the web-application-wide - * guacamole.properties file. - */ -package net.sourceforge.guacamole.properties; - From fc4fa4004dbe5cedebd276812d51b7be84447bf7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 9 Feb 2013 15:02:40 -0800 Subject: [PATCH 112/116] Declaration should be generic. --- .../sourceforge/guacamole/protocol/GuacamoleConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index d199ef0bd..3474bd7cf 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -39,6 +39,7 @@ package net.sourceforge.guacamole.protocol; import java.io.Serializable; import java.util.HashMap; +import java.util.Map; /** * All information necessary to complete the initial protocol handshake of a @@ -51,7 +52,7 @@ public class GuacamoleConfiguration implements Serializable { private static final long serialVersionUID = 1L; private String protocol; - private HashMap parameters = new HashMap(); + private Map parameters = new HashMap(); /** * Returns the name of the protocol to be used. From a86f1a7c7f87cbcb02888850e1a229b34a5e340a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 14 Feb 2013 02:02:25 -0800 Subject: [PATCH 113/116] Add parameter list/remove. --- .../protocol/GuacamoleConfiguration.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 3474bd7cf..dca225261 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -38,8 +38,10 @@ package net.sourceforge.guacamole.protocol; * ***** END LICENSE BLOCK ***** */ import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * All information necessary to complete the initial protocol handshake of a @@ -90,4 +92,24 @@ public class GuacamoleConfiguration implements Serializable { parameters.put(name, value); } + /** + * Removes the value set for the parameter with the given name. + * + * @param name The name of the parameter to remove the value of. + */ + public void unsetParameter(String name) { + parameters.remove(name); + } + + /** + * Returns a set of all currently defined parameter names. Each name + * corresponds to a parameter that has a value set on this + * GuacamoleConfiguration via setParameter(). + * + * @return A set of all currently defined parameter names. + */ + public Set getParameterNames() { + return Collections.unmodifiableSet(parameters.keySet()); + } + } From 586c9b4f8310c09d14ce7a0c729f367399ec9389 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 20 Feb 2013 21:51:09 -0800 Subject: [PATCH 114/116] Add missing JavaDoc. --- .../guacamole/io/ReaderGuacamoleReader.java | 13 +++++++++++++ .../guacamole/net/GuacamoleTunnel.java | 17 +++++++++++++++++ .../guacamole/net/InetGuacamoleSocket.java | 19 +++++++++++++++++++ .../protocol/ConfiguredGuacamoleSocket.java | 8 ++++++++ .../protocol/GuacamoleConfiguration.java | 10 ++++++++++ .../protocol/GuacamoleInstruction.java | 10 +++++----- .../servlet/GuacamoleHTTPTunnelServlet.java | 3 +++ .../guacamole/servlet/GuacamoleSession.java | 6 ++++++ 8 files changed, 81 insertions(+), 5 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index ed4ed4580..2d7bf685e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -67,9 +67,22 @@ public class ReaderGuacamoleReader implements GuacamoleReader { this.input = input; } + /** + * The location within the received data buffer that parsing should begin + * when more data is read. + */ private int parseStart; + /** + * The buffer holding all received, unparsed data. + */ private char[] buffer = new char[20480]; + + /** + * The number of characters currently used within the data buffer. All + * other characters within the buffer are free space available for + * future reads. + */ private int usedLength = 0; @Override diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index 134ac07d8..93577ae81 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -51,10 +51,27 @@ import net.sourceforge.guacamole.io.GuacamoleWriter; */ public class GuacamoleTunnel { + /** + * The UUID associated with this tunnel. Every tunnel must have a + * corresponding UUID such that tunnel read/write requests can be + * directed to the proper tunnel. + */ private UUID uuid; + + /** + * The GuacamoleSocket that tunnel should use for communication on + * behalf of the connecting user. + */ private GuacamoleSocket socket; + /** + * Lock acquired when a read operation is in progress. + */ private ReentrantLock readerLock; + + /** + * Lock acquired when a write operation is in progress. + */ private ReentrantLock writerLock; /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index 37e42e8e2..113148192 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -63,12 +63,31 @@ import org.slf4j.LoggerFactory; */ public class InetGuacamoleSocket implements GuacamoleSocket { + /** + * Logger for this class. + */ private Logger logger = LoggerFactory.getLogger(InetGuacamoleSocket.class); + /** + * The GuacamoleReader this socket should read from. + */ private GuacamoleReader reader; + + /** + * The GuacamoleWriter this socket should write to. + */ private GuacamoleWriter writer; + /** + * The number of milliseconds to wait for data on the TCP socket before + * timing out. + */ private static final int SOCKET_TIMEOUT = 15000; + + /** + * The TCP socket that the GuacamoleReader and GuacamoleWriter exposed + * by this class should affect. + */ private Socket sock; /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index 4fafc54a2..bf713b3d9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -58,7 +58,15 @@ import net.sourceforge.guacamole.net.GuacamoleSocket; */ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { + /** + * The wrapped socket. + */ private GuacamoleSocket socket; + + /** + * The configuration to use when performing the Guacamole protocol + * handshake. + */ private GuacamoleConfiguration config; /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index dca225261..2e67a9cca 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -51,9 +51,19 @@ import java.util.Set; */ public class GuacamoleConfiguration implements Serializable { + /** + * Identifier unique to this version of GuacamoleConfiguration. + */ private static final long serialVersionUID = 1L; + /** + * The name of the protocol associated with this configuration. + */ private String protocol; + + /** + * Map of all associated parameter values, indexed by parameter name. + */ private Map parameters = new HashMap(); /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java index dd8319b8c..d3d10a74e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java @@ -1,10 +1,6 @@ package net.sourceforge.guacamole.protocol; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -41,6 +37,10 @@ import java.util.List; * * ***** END LICENSE BLOCK ***** */ +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + /** * An abstract representation of a Guacamole instruction, as defined by the * Guacamole protocol. @@ -63,7 +63,7 @@ public class GuacamoleInstruction { * Creates a new GuacamoleInstruction having the given Operation and * list of arguments values. * - * @param operation The opcode of the instruction to create. + * @param opcode The opcode of the instruction to create. * @param args The list of argument values to provide in the new * instruction if any. */ diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 36d5517d6..7ab97d0d2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -57,6 +57,9 @@ import org.slf4j.LoggerFactory; */ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { + /** + * Logger for this class. + */ private Logger logger = LoggerFactory.getLogger(GuacamoleHTTPTunnelServlet.class); /** diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java index f89e44bef..ef049e8c9 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java @@ -53,8 +53,14 @@ import org.slf4j.LoggerFactory; */ public class GuacamoleSession { + /** + * Logger for this class. + */ private Logger logger = LoggerFactory.getLogger(GuacamoleSession.class); + /** + * Map of all currently attached tunnels, indexed by tunnel UUID. + */ private ConcurrentMap tunnels; /** From 3ea725ae3adc2cc0d18347a7090efdc5bbe8c4a5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 21 Feb 2013 11:30:50 -0800 Subject: [PATCH 115/116] Remove trailing whitespace from lines. --- .../guacamole/protocol/ConfiguredGuacamoleSocket.java | 6 +++--- .../guacamole/protocol/GuacamoleClientInformation.java | 8 ++++---- .../guacamole/protocol/GuacamoleConfiguration.java | 6 +++--- .../guacamole/servlet/GuacamoleHTTPTunnelServlet.java | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index bf713b3d9..99d68643f 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -117,12 +117,12 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { // Wait for server args GuacamoleInstruction instruction; do { - + // Read instruction, fail if end-of-stream instruction = reader.readInstruction(); if (instruction == null) throw new GuacamoleServerException("End of stream during initial handshake."); - + } while (!instruction.getOpcode().equals("args")); // Build args list off provided names and config @@ -144,7 +144,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { } - // Send size + // Send size writer.writeInstruction( new GuacamoleInstruction( "size", diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java index 424fc598c..c2fc48c48 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java @@ -58,12 +58,12 @@ public class GuacamoleClientInformation { * The optimal screen height requested by the client, in pixels. */ private int optimalScreenHeight = 768; - + /** * The list of audio mimetypes reported by the client to be supported. */ private List audioMimetypes = new ArrayList(); - + /** * The list of audio mimetypes reported by the client to be supported. */ @@ -105,7 +105,7 @@ public class GuacamoleClientInformation { * Returns the list of audio mimetypes supported by the client. To add or * removed supported mimetypes, the list returned by this function can be * modified. - * + * * @return The set of audio mimetypes supported by the client. */ public List getAudioMimetypes() { @@ -116,7 +116,7 @@ public class GuacamoleClientInformation { * Returns the list of video mimetypes supported by the client. To add or * removed supported mimetypes, the list returned by this function can be * modified. - * + * * @return The set of video mimetypes supported by the client. */ public List getVideoMimetypes() { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java index 2e67a9cca..ac56fb315 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleConfiguration.java @@ -104,18 +104,18 @@ public class GuacamoleConfiguration implements Serializable { /** * Removes the value set for the parameter with the given name. - * + * * @param name The name of the parameter to remove the value of. */ public void unsetParameter(String name) { parameters.remove(name); } - + /** * Returns a set of all currently defined parameter names. Each name * corresponds to a parameter that has a value set on this * GuacamoleConfiguration via setParameter(). - * + * * @return A set of all currently defined parameter names. */ public Set getParameterNames() { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 7ab97d0d2..1c178e063 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -164,7 +164,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { try { // Ensure buggy browsers do not cache response response.setHeader("Cache-Control", "no-cache"); - + // Send UUID to client response.getWriter().print(tunnel.getUUID().toString()); } @@ -403,12 +403,12 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // Buffer int length; char[] buffer = new char[8192]; - + // Transfer data using buffer while (tunnel.isOpen() && (length = input.read(buffer, 0, buffer.length)) != -1) writer.write(buffer, 0, length); - + } // Close input stream in all cases From 75408f5224ed3a108d32cf105d6618f494bf4f8a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 21 Feb 2013 11:52:47 -0800 Subject: [PATCH 116/116] Fix style issues. --- .../guacamole/io/ReaderGuacamoleReader.java | 3 ++- .../protocol/GuacamoleClientInformation.java | 1 - .../servlet/GuacamoleHTTPTunnelServlet.java | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java index 2d7bf685e..257c8ba96 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java @@ -39,6 +39,7 @@ package net.sourceforge.guacamole.io; import java.io.IOException; import java.io.Reader; +import java.util.Deque; import java.util.LinkedList; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleServerException; @@ -210,7 +211,7 @@ public class ReaderGuacamoleReader implements GuacamoleReader { int elementStart = 0; // Build list of elements - LinkedList elements = new LinkedList(); + Deque elements = new LinkedList(); while (elementStart < instructionBuffer.length) { // Find end of length diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java index c2fc48c48..78f9f031b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleClientInformation.java @@ -39,7 +39,6 @@ package net.sourceforge.guacamole.protocol; import java.util.ArrayList; import java.util.List; -import java.util.Set; /** * An abstract representation of Guacamole client information, including all diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 1c178e063..039e91565 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -36,13 +36,22 @@ package net.sourceforge.guacamole.servlet; * * ***** END LICENSE BLOCK ***** */ -import java.io.*; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; 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.*; +import net.sourceforge.guacamole.GuacamoleClientException; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.GuacamoleResourceNotFoundException; +import net.sourceforge.guacamole.GuacamoleSecurityException; +import net.sourceforge.guacamole.GuacamoleServerException; import net.sourceforge.guacamole.io.GuacamoleReader; import net.sourceforge.guacamole.io.GuacamoleWriter; import net.sourceforge.guacamole.net.GuacamoleTunnel;