Implement multiple authorized connections per user.

This commit is contained in:
Michal Kotas
2012-04-18 12:01:34 -07:00
committed by Michael Jumper
parent b701b0e6b0
commit 5508a5b393
2 changed files with 111 additions and 53 deletions

View File

@@ -2,10 +2,15 @@
<!-- Per-user authentication and config information -->
<authorize username="USERNAME" password="PASSWORD">
<!-- Single authorized connection -->
<remote-server servername="localhost">
<protocol>vnc</protocol>
<param name="hostname">localhost</param>
<param name="port">5900</param>
<param name="password">VNCPASS</param>
</remote-server>
</authorize>
<!-- Another user, but using md5 to hash the password
@@ -14,10 +19,23 @@
username="USERNAME2"
password="319f4d26e3c536b5dd871bb2c52e3178"
encoding="md5">
<!-- First authorized connection -->
<remote-server servername="localhost">
<protocol>vnc</protocol>
<param name="hostname">localhost</param>
<param name="port">5901</param>
<param name="password">VNCPASS</param>
</remote-server>
<!-- Second authorized connection -->
<remote-server servername="otherhost">
<protocol>vnc</protocol>
<param name="hostname">otherhost</param>
<param name="port">5900</param>
<param name="password">VNCPASS</param>
</remote-server>
</authorize>
</user-mapping>

View File

@@ -46,10 +46,12 @@ import org.xml.sax.helpers.XMLReaderFactory;
/**
* Authenticates users against a static list of username/password pairs.
* Each username/password may be associated with exactly one configuration.
* Each username/password may be associated with multiple configurations.
* This list is stored in an XML file which is reread if modified.
*
* @author Michael Jumper
* This is modified version of BasicFileAuthenticationProvider written by Michael Jumper.
*
* @author Michal Kotas
*/
public class BasicFileAuthenticationProvider implements AuthenticationProvider {
@@ -136,8 +138,12 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
// Validate and return info for given user and pass
AuthInfo info = mapping.get(credentials.getUsername());
if (info != null && info.validate(credentials.getUsername(), credentials.getPassword())) {
Map<String, GuacamoleConfiguration> configs = new HashMap<String, GuacamoleConfiguration>();
configs.put("DEFAULT", info.getConfiguration());
//Map<String, GuacamoleConfiguration> configs = new HashMap<String, GuacamoleConfiguration>();
//configs.put("DEFAULT", info.getConfiguration());
//return configs;
Map<String, GuacamoleConfiguration> configs = info.getConfigurations();
return configs;
}
@@ -157,14 +163,14 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
private String auth_password;
private Encoding auth_encoding;
private GuacamoleConfiguration config;
private Map<String, GuacamoleConfiguration> configs;
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 GuacamoleConfiguration();
configs = new HashMap<String, GuacamoleConfiguration>();
}
private static final char HEX_CHARS[] = {
@@ -220,13 +226,19 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
}
public GuacamoleConfiguration getConfiguration() {
return config;
public GuacamoleConfiguration getConfiguration(String name) {
//return configs;
return configs.get(name);
}
public Map<String, GuacamoleConfiguration> getConfigurations() {
return configs;
}
public void addConfiguration(String name) {
configs.put(name, new GuacamoleConfiguration());
}
}
private static class BasicUserMappingContentHandler extends DefaultHandler {
private Map<String, AuthInfo> authMapping = new HashMap<String, AuthInfo>();
@@ -238,6 +250,7 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
private enum State {
ROOT,
USER_MAPPING,
REMOTE_SERVER,
AUTH_INFO,
PROTOCOL,
PARAMETER,
@@ -247,6 +260,7 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
private State state = State.ROOT;
private AuthInfo current = null;
private String currentParameter = null;
private String currentRemoteServer = null;
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
@@ -278,10 +292,19 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
break;
case REMOTE_SERVER:
if (localName.equals("remote-server")) {
state = State.AUTH_INFO;
return;
}
break;
case PROTOCOL:
if (localName.equals("protocol")) {
state = State.AUTH_INFO;
state = State.REMOTE_SERVER;
return;
}
@@ -290,7 +313,7 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
case PARAMETER:
if (localName.equals("param")) {
state = State.AUTH_INFO;
state = State.REMOTE_SERVER;
return;
}
@@ -317,7 +340,6 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
break;
// Only <authorize> tags allowed in main document
case USER_MAPPING:
if (localName.equals("authorize")) {
@@ -349,6 +371,23 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
case AUTH_INFO:
if (localName.equals("remote-server")) {
currentRemoteServer = attributes.getValue("servername");
if (currentRemoteServer == null)
throw new SAXException("Attribute \"servername\" required for param tag.");
current.addConfiguration(currentRemoteServer);
// Next state
state = State.REMOTE_SERVER;
return;
}
break;
case REMOTE_SERVER:
if (localName.equals("protocol")) {
// Next state
state = State.PROTOCOL;
@@ -378,15 +417,16 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
public void characters(char[] ch, int start, int length) throws SAXException {
String str = new String(ch, start, length);
switch (state) {
case PROTOCOL:
current.getConfiguration()
current.getConfiguration(currentRemoteServer)
.setProtocol(str);
return;
case PARAMETER:
current.getConfiguration()
current.getConfiguration(currentRemoteServer)
.setParameter(currentParameter, str);
return;