Merge branch 'master' of ssh://guacamole.git.sourceforge.net/gitroot/guacamole/guacamole

This commit is contained in:
Michael Jumper
2011-01-02 23:55:18 -08:00
5 changed files with 176 additions and 217 deletions

36
guacamole/.gitignore vendored
View File

@@ -1,35 +1 @@
target/
# 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

View File

@@ -64,7 +64,7 @@
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>guac-dev</id> <id>guac-dev</id>
<url>scpexe://guac-dev.org/var/www/repo</url> <url>${guac-dev.dist.repo}</url>
</repository> </repository>
</distributionManagement> </distributionManagement>

View File

@@ -27,6 +27,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.Configuration;
import net.sourceforge.guacamole.net.GuacamoleProperties; import net.sourceforge.guacamole.net.GuacamoleProperties;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@@ -80,7 +81,7 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
} }
@Override @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 // Check mapping file mod time
File userMappingFile = getUserMappingFile(); File userMappingFile = getUserMappingFile();
@@ -96,12 +97,7 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
AuthInfo info = mapping.get(username); AuthInfo info = mapping.get(username);
if (info != null && info.validate(username, password)) if (info != null && info.validate(username, password))
return new BasicLogin.AuthorizedConfiguration( return info.getConfiguration();
info.getProtocol(),
info.getHostname(),
info.getPort(),
info.getPassword()
);
return null; return null;
@@ -118,15 +114,14 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
private String auth_password; private String auth_password;
private Encoding auth_encoding; private Encoding auth_encoding;
private String protocol; private Configuration config;
private String hostname;
private int port;
private String password;
public AuthInfo(String auth_username, String auth_password, Encoding auth_encoding) { public AuthInfo(String auth_username, String auth_password, Encoding auth_encoding) {
this.auth_username = auth_username; this.auth_username = auth_username;
this.auth_password = auth_password; this.auth_password = auth_password;
this.auth_encoding = auth_encoding; this.auth_encoding = auth_encoding;
config = new Configuration();
} }
private static final char HEX_CHARS[] = { private static final char HEX_CHARS[] = {
@@ -182,20 +177,8 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
} }
public String getHostname() { public Configuration getConfiguration() {
return hostname; return config;
}
public String getPassword() {
return password;
}
public int getPort() {
return port;
}
public String getProtocol() {
return protocol;
} }
} }
@@ -209,75 +192,142 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
return Collections.unmodifiableMap(authMapping); return Collections.unmodifiableMap(authMapping);
} }
private AuthInfo current; private enum State {
ROOT,
private enum AUTH_INFO_STATE { USER_MAPPING,
AUTH_INFO,
PROTOCOL, PROTOCOL,
HOSTNAME, PARAMETER,
PORT, END;
PASSWORD }
};
private AUTH_INFO_STATE infoState; private State state = State.ROOT;
private AuthInfo current = null;
private String currentParameter = null;
@Override @Override
public void endElement(String uri, String localName, String qName) throws SAXException { public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equals("authorize")) { switch (state) {
// Finalize mapping for this user case USER_MAPPING:
authMapping.put(
current.auth_username, if (localName.equals("user-mapping")) {
current 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 @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("authorize")) { switch (state) {
AuthInfo.Encoding encoding; // Document must be <user-mapping>
String encodingString = attributes.getValue("encoding"); case ROOT:
if (encodingString == null)
encoding = AuthInfo.Encoding.PLAIN_TEXT; if (localName.equals("user-mapping")) {
else if (encodingString.equals("plain")) state = State.USER_MAPPING;
encoding = AuthInfo.Encoding.PLAIN_TEXT; return;
else if (encodingString.equals("md5")) }
encoding = AuthInfo.Encoding.MD5;
else break;
throw new SAXException("Invalid encoding type");
// Only <authorize> 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( current = new AuthInfo(
attributes.getValue("username"), attributes.getValue("username"),
attributes.getValue("password"), attributes.getValue("password"),
encoding 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")) throw new SAXException("Unexpected tag: " + localName);
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;
} }
@@ -285,30 +335,21 @@ public class BasicFileAuthenticationProvider implements BasicLogin.Authenticatio
public void characters(char[] ch, int start, int length) throws SAXException { public void characters(char[] ch, int start, int length) throws SAXException {
String str = new String(ch, start, length); String str = new String(ch, start, length);
switch (state) {
if (infoState == null)
return;
switch (infoState) {
case PROTOCOL: case PROTOCOL:
current.protocol = str; current.getConfiguration().setProtocol(str);
break; return;
case HOSTNAME:
current.hostname = str;
break;
case PORT:
current.port = Integer.parseInt(str);
break;
case PASSWORD:
current.password = str;
break;
case PARAMETER:
current.getConfiguration().setParameter(currentParameter, str);
return;
} }
if (str.trim().length() != 0)
throw new SAXException("Unexpected character data.");
} }

View File

@@ -2,9 +2,11 @@
package net.sourceforge.guacamole.net.authentication.basic; package net.sourceforge.guacamole.net.authentication.basic;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.sourceforge.guacamole.GuacamoleTCPClient;
import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.GuacamoleSession; import net.sourceforge.guacamole.net.Configuration;
import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider; import net.sourceforge.guacamole.net.GuacamoleProperties;
import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider;
/* /*
* Guacamole - Clientless Remote Desktop * Guacamole - Clientless Remote Desktop
@@ -24,26 +26,25 @@ import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider;
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
public class BasicGuacamoleSessionProvider implements GuacamoleSessionProvider { public class BasicGuacamoleClientProvider implements GuacamoleClientProvider {
public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException {
// Retrieve authorized config data from session // Retrieve authorized config data from session
BasicLogin.AuthorizedConfiguration config = (BasicLogin.AuthorizedConfiguration) Configuration config = (Configuration) session.getAttribute("BASIC-LOGIN-AUTH");
session.getAttribute("BASIC-LOGIN-AUTH");
// If no data, not authorized // If no data, not authorized
if (config == null) if (config == null)
throw new GuacamoleException("Unauthorized"); throw new GuacamoleException("Unauthorized");
// Configure session from authorized config info String hostname = GuacamoleProperties.getProperty("guacd-hostname");
GuacamoleSession guacSession = new GuacamoleSession(session); int port = GuacamoleProperties.getIntProperty("guacd-port", null);
guacSession.setConnection(config.getProtocol(), config.getHostname(), config.getPort());
if (config.getPassword() != null) GuacamoleTCPClient client = new GuacamoleTCPClient(hostname, port);
guacSession.setPassword(config.getPassword()); client.connect(config);
// Return authorized session // Return authorized session
return guacSession; return client;
} }

View File

@@ -28,99 +28,50 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.Configuration; import net.sourceforge.guacamole.net.Configuration;
import net.sourceforge.guacamole.net.GuacamoleProperties;
public class BasicLogin extends HttpServlet { public class BasicLogin extends HttpServlet {
private Config config; private AuthenticationProvider authProvider;
@Override @Override
public void init() throws ServletException { public void init() throws ServletException {
// Get auth provider instance
try { 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) { catch (GuacamoleException e) {
throw new ServletException(e); throw new ServletException(e);
} }
} catch (ClassNotFoundException e) {
throw new ServletException("Authentication provider class not found", 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 (NoSuchMethodException e) {
public AuthenticationProvider getAuthenticationProvider() { throw new ServletException("Default constructor for authentication provider not present", e);
return authProvider; }
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 static interface AuthenticationProvider {
public AuthorizedConfiguration getAuthorizedConfiguration(String username, String password) throws GuacamoleException; public Configuration 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 @Override
@@ -133,14 +84,14 @@ public class BasicLogin extends HttpServlet {
// Validate username and password // Validate username and password
try { try {
AuthorizedConfiguration info = config.getAuthenticationProvider().getAuthorizedConfiguration(username, password); Configuration config = authProvider.getAuthorizedConfiguration(username, password);
if (info != null) { if (config != null) {
// Store authorized configuration // Store authorized configuration
HttpSession session = req.getSession(true); HttpSession session = req.getSession(true);
session.setAttribute( session.setAttribute(
"BASIC-LOGIN-AUTH", "BASIC-LOGIN-AUTH",
info config
); );
// Success // Success