guacamole-common-0.6.0/0000755361546300001440000000000011751110442013505 5ustar zhzusersguacamole-common-0.6.0/pom.xml0000644361546300001440000000267011751110442015027 0ustar zhzusers 4.0.0 net.sourceforge.guacamole guacamole-common jar 0.6.0 guacamole-common http://guac-dev.org/ UTF-8 org.apache.maven.plugins maven-compiler-plugin 1.6 1.6 javax.servlet servlet-api 2.5 provided org.slf4j slf4j-api 1.6.1 guacamole-common-0.6.0/src/0000755361546300001440000000000011751110442014274 5ustar zhzusersguacamole-common-0.6.0/src/main/0000755361546300001440000000000011751110442015220 5ustar zhzusersguacamole-common-0.6.0/src/main/java/0000755361546300001440000000000011751110442016141 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/0000755361546300001440000000000011751110442016727 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/0000755361546300001440000000000011751110442021252 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/0000755361546300001440000000000011751110442023207 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/GuacamoleException.java0000644361546300001440000000525011751110442027630 0ustar zhzusers 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 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); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/GuacamoleResourceNotFoundException.ja0000644361546300001440000000554211751110442032472 0ustar zhzusers 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 GuacamoleClientException { /** * 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); } } guacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/0000755361546300001440000000000011751110442025403 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperty.java0000644361546300001440000000524011751110442031711 0ustar zhzusers 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; } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/StringGuacamoleProperty.ja0000644361546300001440000000403311751110442032550 0ustar zhzusers 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; } } guacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/GuacamoleProperties.java0000644361546300001440000001222711751110442032224 0ustar zhzusers 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.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 { InputStream stream = GuacamoleProperties.class.getResourceAsStream("/guacamole.properties"); if (stream == null) throw new IOException("Resource /guacamole.properties not found."); // 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; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/IntegerGuacamoleProperty.j0000644361546300001440000000465111751110442032544 0ustar zhzusers 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); } } } ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/properties/FileGuacamoleProperty.java0000644361546300001440000000423711751110442032516 0ustar zhzusers 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); } } guacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/servlet/0000755361546300001440000000000011751110442024673 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java0000644361546300001440000001070211751110442030777 0ustar zhzusers package net.sourceforge.guacamole.servlet; /* ***** 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.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleSecurityException; 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. * * @author Michael Jumper */ public class GuacamoleSession { private Logger logger = LoggerFactory.getLogger(GuacamoleSession.class); 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. */ @SuppressWarnings("unchecked") public GuacamoleSession(HttpSession session) throws GuacamoleException { if (session == null) throw new GuacamoleSecurityException("User has no session."); synchronized (session) { tunnels = (ConcurrentMap) session.getAttribute("GUAC_TUNNELS"); if (tunnels == null) { tunnels = new ConcurrentHashMap(); session.setAttribute("GUAC_TUNNELS", tunnels); } } } /** * 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); logger.debug("Attached tunnel {}.", tunnel.getUUID()); } /** * 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()); logger.debug("Detached tunnel {}.", tunnel.getUUID()); } /** * 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); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.ja0000644361546300001440000003434411751110442032347 0ustar zhzuserspackage net.sourceforge.guacamole.servlet; /* ***** 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.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; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.*; 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 * HTTP implementation of the JavaScript Guacamole client's tunnel. * * @author Michael Jumper */ 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); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { 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 { // If response not committed, send error code if (!response.isCommitted()) response.sendError(code); } catch (IOException ioe) { // If unable to send error at all due to I/O problems, // rethrow as servlet exception throw new ServletException(ioe); } } /** * 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 { String query = request.getQueryString(); if (query == null) throw new GuacamoleClientException("No query string provided."); // If connect operation, call doConnect() and return tunnel UUID // in response. if (query.equals("connect")) { 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 { // Send UUID to client response.getWriter().print(tunnel.getUUID().toString()); } catch (IOException e) { throw new GuacamoleServerException(e); } } // Failed to connect else { logger.info("Connection from {} failed.", request.getRemoteAddr()); throw new GuacamoleResourceNotFoundException("No tunnel created."); } } // 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 GuacamoleClientException("Invalid tunnel operation: " + query); } // Catch any thrown guacamole exception and attempt to pass within the // HTTP response, logging each error appropriately. catch (GuacamoleSecurityException e) { logger.warn("Authorization failed.", e); sendError(response, HttpServletResponse.SC_FORBIDDEN); } catch (GuacamoleResourceNotFoundException e) { logger.debug("Resource not found.", e); sendError(response, HttpServletResponse.SC_NOT_FOUND); } catch (GuacamoleClientException e) { logger.warn("Error in client request.", e); sendError(response, HttpServletResponse.SC_BAD_REQUEST); } catch (GuacamoleException e) { logger.error("Server error in tunnel", e); sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } /** * 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); 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(); try { // 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(); // 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."); // For all messages, until another stream is ready (we send at least one message) do { // Get message output bytes out.write(message, 0, message.length); // Flush if we expect to wait if (!reader.available()) { out.flush(); response.flushBuffer(); } // No more messages another stream can take over if (tunnel.hasQueuedReaderThreads()) break; } while (tunnel.isOpen() && (message = reader.read()) != null); // Close tunnel immediately upon EOF if (message == null) tunnel.close(); // End-of-instructions marker out.write("0.;"); out.flush(); response.flushBuffer(); } catch (GuacamoleException e) { // Detach and close session.detachTunnel(tunnel); tunnel.close(); throw e; } 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(); } finally { tunnel.releaseReader(); } } /** * 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); GuacamoleSession session = new GuacamoleSession(httpSession); GuacamoleTunnel tunnel = session.getTunnel(tunnelUUID); if (tunnel == null) throw new GuacamoleResourceNotFoundException("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 // does not explicitly request such parsing. response.setContentType("application/octet-stream"); response.setContentLength(0); // Send data try { GuacamoleWriter writer = tunnel.acquireWriter(); Reader input = request.getReader(); char[] buffer = new char[8192]; int length; while (tunnel.isOpen() && (length = input.read(buffer, 0, buffer.length)) != -1) writer.write(buffer, 0, length); } catch (IOException e) { // Detach and close session.detachTunnel(tunnel); tunnel.close(); throw new GuacamoleServerException("I/O Error sending data to server: " + e.getMessage(), e); } finally { tunnel.releaseWriter(); } } } /** * \example ExampleTunnelServlet.java * * A basic example demonstrating extending GuacamoleTunnelServlet and * implementing doConnect() to configure the Guacamole connection as * desired. */ guacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/GuacamoleServerException.java0000644361546300001440000000550311751110442031020 0ustar zhzusers 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 GuacamoleServerException 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 GuacamoleServerException(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 GuacamoleServerException(String message) { super(message); } /** * Creates a new GuacamoleException with the given cause. * * @param cause The cause of this exception. */ public GuacamoleServerException(Throwable cause) { super(cause); } } guacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/io/0000755361546300001440000000000011751110442023616 5ustar zhzusersguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java0000644361546300001440000002135711751110442030634 0ustar zhzusers package net.sourceforge.guacamole.io; /* ***** 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.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; /** * A GuacamoleReader which wraps a standard Java Reader, using that Reader as * the Guacamole instruction stream. * * @author Michael Jumper */ public class ReaderGuacamoleReader implements GuacamoleReader { /** * Wrapped Reader to be used for all input. */ 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; } private int parseStart; 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 GuacamoleServerException(e); } } @Override public char[] read() throws GuacamoleException { 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 GuacamoleServerException("Element terminator of instruction was not ';' nor ','"); } // Otherwise, read more data else break; } // Otherwise, parse error else throw new GuacamoleServerException("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]; 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; // Update used length usedLength += numRead; } // End read loop } catch (IOException e) { throw new GuacamoleServerException(e); } } @Override public GuacamoleInstruction readInstruction() throws GuacamoleException { // 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) { // Find end of length int lengthEnd = -1; for (int i=elementStart; i 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[] 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() { StringBuilder buff = new StringBuilder(); buff.append(operation.getOpcode().length()); buff.append('.'); buff.append(operation.getOpcode()); for (int i=0; i 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); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.javaguacamole-common-0.6.0/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.ja0000644361546300001440000001165411751110442032447 0ustar zhzusers 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 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 * 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; private GuacamoleConfiguration config; /** * 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; // Get reader and writer GuacamoleReader reader = socket.getReader(); GuacamoleWriter writer = socket.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