From fa481e428b3623ad1e762ad1b0f6b88a42c0d579 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 00:40:11 -0800 Subject: [PATCH 1/6] Defining dist repo in property. --- guacamole/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole/pom.xml b/guacamole/pom.xml index 784a3725d..9ba65535f 100644 --- a/guacamole/pom.xml +++ b/guacamole/pom.xml @@ -64,7 +64,7 @@ guac-dev - scpexe://guac-dev.org/var/www/repo + ${guac-dev.dist.repo} From 6e7eeec5b0e7983a9e1b4e6df3998fe283803d73 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 1 Jan 2011 01:48:20 -0800 Subject: [PATCH 2/6] Ignore target dir --- guacamole/.gitignore | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/guacamole/.gitignore b/guacamole/.gitignore index e37f91669..2f7896d1d 100644 --- a/guacamole/.gitignore +++ b/guacamole/.gitignore @@ -1,35 +1 @@ - -# Object code -*.o -*.so -*.lo -*.la - -# Backup files -*~ - -# Release files -*.tar.gz - -# Files currently being edited by vim or vi -*.swp - -# automake/autoconf -.deps/ -.libs/ -Makefile -Makefile.in -aclocal.m4 -autom4te.cache/ -m4/ -config.guess -config.log -config.status -config.sub -configure -depcomp -install-sh -libtool -ltmain.sh -missing - +target/ From 1dec9e889b2c9c3ab1e93d2a9a2be9139ca594b9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 02:37:09 -0800 Subject: [PATCH 3/6] Migrated to improved API. --- .../BasicFileAuthenticationProvider.java | 23 ++-- ...java => BasicGuacamoleClientProvider.java} | 23 ++-- .../net/authentication/basic/BasicLogin.java | 109 +++++------------- 3 files changed, 57 insertions(+), 98 deletions(-) rename guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/{BasicGuacamoleSessionProvider.java => BasicGuacamoleClientProvider.java} (60%) diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java index 83fcfd34c..e0f24f33c 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.Configuration; import net.sourceforge.guacamole.net.GuacamoleProperties; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -80,7 +81,7 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio } @Override - public BasicLogin.AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException { + public Configuration getAuthorizedConfiguration(String username, String password) throws GuacamoleException { // Check mapping file mod time File userMappingFile = getUserMappingFile(); @@ -95,13 +96,19 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio } AuthInfo info = mapping.get(username); - if (info != null && info.validate(username, password)) - return new BasicLogin.AuthorizedConfiguration( - info.getProtocol(), - info.getHostname(), - info.getPort(), - info.getPassword() - ); + if (info != null && info.validate(username, password)) { + + Configuration config = new Configuration(); + + // TODO: Migrate user-mapping to general form + config.setProtocol(info.getProtocol()); + config.setParameter("hostname", info.getHostname()); + config.setParameter("port", Integer.toString(info.getPort())); + config.setParameter("password", info.getPassword()); + + return config; + + } return null; diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java similarity index 60% rename from guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java rename to guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java index 959bf0e6e..bbef84b94 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleSessionProvider.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java @@ -2,9 +2,11 @@ package net.sourceforge.guacamole.net.authentication.basic; import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.Configuration; import net.sourceforge.guacamole.net.GuacamoleSession; -import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider; +import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; /* * Guacamole - Clientless Remote Desktop @@ -24,26 +26,25 @@ import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider; * along with this program. If not, see . */ -public class BasicGuacamoleSessionProvider implements GuacamoleSessionProvider { +public class BasicGuacamoleClientProvider implements GuacamoleClientProvider { - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { + public GuacamoleClient createClient(HttpSession session) throws GuacamoleException { // Retrieve authorized config data from session - BasicLogin.AuthorizedConfiguration config = (BasicLogin.AuthorizedConfiguration) - session.getAttribute("BASIC-LOGIN-AUTH"); + Configuration config = (Configuration) 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()); + GuacamoleClient client = new GuacamoleClient("localhost", 4822); + + // 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(); + client.write(initMessages, 0, initMessages.length); // Return authorized session - return guacSession; + return client; } diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java index 43e8721d9..8347202ac 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicLogin.java @@ -28,99 +28,50 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.Configuration; +import net.sourceforge.guacamole.net.GuacamoleProperties; public class BasicLogin extends HttpServlet { - private Config config; + private AuthenticationProvider authProvider; @Override public void init() throws ServletException { + + // Get auth provider instance try { - config = new Config(); + String authProviderClassName = GuacamoleProperties.getProperty("auth-provider"); + Object obj = Class.forName(authProviderClassName).getConstructor().newInstance(); + if (!(obj instanceof AuthenticationProvider)) + throw new ServletException("Specified authentication provider class is not a AuthenticationProvider."); + + authProvider = (AuthenticationProvider) obj; } 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()); - } - + catch (ClassNotFoundException e) { + throw new ServletException("Authentication provider class not found", e); } - - public AuthenticationProvider getAuthenticationProvider() { - return authProvider; + catch (NoSuchMethodException e) { + throw new ServletException("Default constructor for authentication provider not present", e); + } + catch (SecurityException e) { + throw new ServletException("Creation of authentication provider disallowed; check your security settings", e); + } + catch (InstantiationException e) { + throw new ServletException("Unable to instantiate authentication provider", e); + } + catch (IllegalAccessException e) { + throw new ServletException("Unable to access default constructor of authentication provider", e); + } + catch (InvocationTargetException e) { + throw new ServletException("Internal error in constructor of authentication provider", e.getTargetException()); } } 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; - } - + public Configuration getAuthorizedConfiguration(String username, String password) throws GuacamoleException; } @Override @@ -133,14 +84,14 @@ public class BasicLogin extends HttpServlet { // Validate username and password try { - AuthorizedConfiguration info = config.getAuthenticationProvider().getAuthorizedConfiguration(username, password); - if (info != null) { + Configuration config = authProvider.getAuthorizedConfiguration(username, password); + if (config != null) { // Store authorized configuration HttpSession session = req.getSession(true); session.setAttribute( "BASIC-LOGIN-AUTH", - info + config ); // Success From 62332e9f65e367918152f6f16e5688a1dd39c41c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 14:28:06 -0800 Subject: [PATCH 4/6] Implementing API improvements made in guacamole-common --- .../basic/BasicGuacamoleClientProvider.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java index bbef84b94..f48af3874 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java @@ -2,10 +2,10 @@ package net.sourceforge.guacamole.net.authentication.basic; import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleTCPClient; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.Configuration; -import net.sourceforge.guacamole.net.GuacamoleSession; +import net.sourceforge.guacamole.net.GuacamoleProperties; import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; /* @@ -28,7 +28,7 @@ import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; public class BasicGuacamoleClientProvider implements GuacamoleClientProvider { - public GuacamoleClient createClient(HttpSession session) throws GuacamoleException { + public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException { // Retrieve authorized config data from session Configuration config = (Configuration) session.getAttribute("BASIC-LOGIN-AUTH"); @@ -37,11 +37,10 @@ public class BasicGuacamoleClientProvider implements GuacamoleClientProvider { if (config == null) throw new GuacamoleException("Unauthorized"); - GuacamoleClient client = new GuacamoleClient("localhost", 4822); + String hostname = GuacamoleProperties.getProperty("guacd-hostname"); + int port = GuacamoleProperties.getIntProperty("guacd-port", null); - // 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(); - client.write(initMessages, 0, initMessages.length); + GuacamoleTCPClient client = new GuacamoleTCPClient(hostname, port); // Return authorized session return client; From ac96427c08f9d97e9c533a12dd6f1a3ab5e07ce3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 17:08:46 -0800 Subject: [PATCH 5/6] Forgot to invoke connect() --- .../net/authentication/basic/BasicGuacamoleClientProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java index f48af3874..dfd9b384b 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicGuacamoleClientProvider.java @@ -41,6 +41,7 @@ public class BasicGuacamoleClientProvider implements GuacamoleClientProvider { int port = GuacamoleProperties.getIntProperty("guacd-port", null); GuacamoleTCPClient client = new GuacamoleTCPClient(hostname, port); + client.connect(config); // Return authorized session return client; From d536196e620371fc489789368e6cc6623b7461ae Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 22:35:17 -0800 Subject: [PATCH 6/6] Migrated to new format and new (more strict) parser. --- .../BasicFileAuthenticationProvider.java | 226 ++++++++++-------- 1 file changed, 130 insertions(+), 96 deletions(-) diff --git a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java index e0f24f33c..380d7ed42 100644 --- a/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java +++ b/guacamole/src/main/java/net/sourceforge/guacamole/net/authentication/basic/BasicFileAuthenticationProvider.java @@ -96,19 +96,8 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio } AuthInfo info = mapping.get(username); - if (info != null && info.validate(username, password)) { - - Configuration config = new Configuration(); - - // TODO: Migrate user-mapping to general form - config.setProtocol(info.getProtocol()); - config.setParameter("hostname", info.getHostname()); - config.setParameter("port", Integer.toString(info.getPort())); - config.setParameter("password", info.getPassword()); - - return config; - - } + if (info != null && info.validate(username, password)) + return info.getConfiguration(); return null; @@ -125,15 +114,14 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio private String auth_password; private Encoding auth_encoding; - private String protocol; - private String hostname; - private int port; - private String password; + private Configuration config; 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; + + config = new Configuration(); } private static final char HEX_CHARS[] = { @@ -189,20 +177,8 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio } - public String getHostname() { - return hostname; - } - - public String getPassword() { - return password; - } - - public int getPort() { - return port; - } - - public String getProtocol() { - return protocol; + public Configuration getConfiguration() { + return config; } } @@ -216,75 +192,142 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio return Collections.unmodifiableMap(authMapping); } - private AuthInfo current; - - private enum AUTH_INFO_STATE { + private enum State { + ROOT, + USER_MAPPING, + AUTH_INFO, PROTOCOL, - HOSTNAME, - PORT, - PASSWORD - }; + PARAMETER, + END; + } - private AUTH_INFO_STATE infoState; + private State state = State.ROOT; + private AuthInfo current = null; + private String currentParameter = null; @Override public void endElement(String uri, String localName, String qName) throws SAXException { - if (localName.equals("authorize")) { + switch (state) { - // Finalize mapping for this user - authMapping.put( - current.auth_username, - current - ); + case USER_MAPPING: + + if (localName.equals("user-mapping")) { + state = State.END; + return; + } + + break; + + case AUTH_INFO: + + if (localName.equals("authorize")) { + + // Finalize mapping for this user + authMapping.put( + current.auth_username, + current + ); + + state = State.USER_MAPPING; + return; + } + + break; + + case PROTOCOL: + + if (localName.equals("protocol")) { + state = State.AUTH_INFO; + return; + } + + break; + + case PARAMETER: + + if (localName.equals("param")) { + state = State.AUTH_INFO; + return; + } + + break; } - infoState = null; + throw new SAXException("Tag not yet complete: " + localName); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - if (localName.equals("authorize")) { + switch (state) { - 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"); + // Document must be + case ROOT: + + if (localName.equals("user-mapping")) { + state = State.USER_MAPPING; + return; + } + + break; + + // Only tags allowed in main document + case USER_MAPPING: + + 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 - ); + current = new AuthInfo( + attributes.getValue("username"), + attributes.getValue("password"), + encoding + ); - infoState = null; + // Next state + state = State.AUTH_INFO; + return; + } + + break; + + case AUTH_INFO: + + if (localName.equals("protocol")) { + // Next state + state = State.PROTOCOL; + return; + } + + if (localName.equals("param")) { + + currentParameter = attributes.getValue("name"); + if (currentParameter == null) + throw new SAXException("Attribute \"name\" required for param tag."); + + // Next state + state = State.PARAMETER; + return; + } + + break; } - 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; + throw new SAXException("Unexpected tag: " + localName); } @@ -292,30 +335,21 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio public void characters(char[] ch, int start, int length) throws SAXException { String str = new String(ch, start, length); - - if (infoState == null) - return; - - switch (infoState) { + switch (state) { 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; + current.getConfiguration().setProtocol(str); + return; + case PARAMETER: + current.getConfiguration().setParameter(currentParameter, str); + return; + } + if (str.trim().length() != 0) + throw new SAXException("Unexpected character data."); + }