mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Implement multiple authorized connections per user.
This commit is contained in:
committed by
Michael Jumper
parent
b701b0e6b0
commit
5508a5b393
@@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
<!-- Per-user authentication and config information -->
|
<!-- Per-user authentication and config information -->
|
||||||
<authorize username="USERNAME" password="PASSWORD">
|
<authorize username="USERNAME" password="PASSWORD">
|
||||||
<protocol>vnc</protocol>
|
|
||||||
<param name="hostname">localhost</param>
|
<!-- Single authorized connection -->
|
||||||
<param name="port">5900</param>
|
<remote-server servername="localhost">
|
||||||
<param name="password">VNCPASS</param>
|
<protocol>vnc</protocol>
|
||||||
|
<param name="hostname">localhost</param>
|
||||||
|
<param name="port">5900</param>
|
||||||
|
<param name="password">VNCPASS</param>
|
||||||
|
</remote-server>
|
||||||
|
|
||||||
</authorize>
|
</authorize>
|
||||||
|
|
||||||
<!-- Another user, but using md5 to hash the password
|
<!-- Another user, but using md5 to hash the password
|
||||||
@@ -14,10 +19,23 @@
|
|||||||
username="USERNAME2"
|
username="USERNAME2"
|
||||||
password="319f4d26e3c536b5dd871bb2c52e3178"
|
password="319f4d26e3c536b5dd871bb2c52e3178"
|
||||||
encoding="md5">
|
encoding="md5">
|
||||||
<protocol>vnc</protocol>
|
|
||||||
<param name="hostname">localhost</param>
|
<!-- First authorized connection -->
|
||||||
<param name="port">5901</param>
|
<remote-server servername="localhost">
|
||||||
<param name="password">VNCPASS</param>
|
<protocol>vnc</protocol>
|
||||||
</authorize>
|
<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>
|
</user-mapping>
|
||||||
|
@@ -46,10 +46,12 @@ import org.xml.sax.helpers.XMLReaderFactory;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates users against a static list of username/password pairs.
|
* 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.
|
* 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 {
|
public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
@@ -136,8 +138,12 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
// Validate and return info for given user and pass
|
// Validate and return info for given user and pass
|
||||||
AuthInfo info = mapping.get(credentials.getUsername());
|
AuthInfo info = mapping.get(credentials.getUsername());
|
||||||
if (info != null && info.validate(credentials.getUsername(), credentials.getPassword())) {
|
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;
|
return configs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,14 +163,14 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
private String auth_password;
|
private String auth_password;
|
||||||
private Encoding auth_encoding;
|
private Encoding auth_encoding;
|
||||||
|
|
||||||
private GuacamoleConfiguration config;
|
private Map<String, GuacamoleConfiguration> configs;
|
||||||
|
|
||||||
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 GuacamoleConfiguration();
|
configs = new HashMap<String, GuacamoleConfiguration>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final char HEX_CHARS[] = {
|
private static final char HEX_CHARS[] = {
|
||||||
@@ -220,13 +226,19 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GuacamoleConfiguration getConfiguration() {
|
public GuacamoleConfiguration getConfiguration(String name) {
|
||||||
return config;
|
//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 static class BasicUserMappingContentHandler extends DefaultHandler {
|
||||||
|
|
||||||
private Map<String, AuthInfo> authMapping = new HashMap<String, AuthInfo>();
|
private Map<String, AuthInfo> authMapping = new HashMap<String, AuthInfo>();
|
||||||
@@ -238,6 +250,7 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
private enum State {
|
private enum State {
|
||||||
ROOT,
|
ROOT,
|
||||||
USER_MAPPING,
|
USER_MAPPING,
|
||||||
|
REMOTE_SERVER,
|
||||||
AUTH_INFO,
|
AUTH_INFO,
|
||||||
PROTOCOL,
|
PROTOCOL,
|
||||||
PARAMETER,
|
PARAMETER,
|
||||||
@@ -247,56 +260,66 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
private State state = State.ROOT;
|
private State state = State.ROOT;
|
||||||
private AuthInfo current = null;
|
private AuthInfo current = null;
|
||||||
private String currentParameter = null;
|
private String currentParameter = null;
|
||||||
|
private String currentRemoteServer = 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 {
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
||||||
case USER_MAPPING:
|
case USER_MAPPING:
|
||||||
|
|
||||||
if (localName.equals("user-mapping")) {
|
if (localName.equals("user-mapping")) {
|
||||||
state = State.END;
|
state = State.END;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUTH_INFO:
|
case AUTH_INFO:
|
||||||
|
|
||||||
if (localName.equals("authorize")) {
|
if (localName.equals("authorize")) {
|
||||||
|
|
||||||
// Finalize mapping for this user
|
// Finalize mapping for this user
|
||||||
authMapping.put(
|
authMapping.put(
|
||||||
current.auth_username,
|
current.auth_username,
|
||||||
current
|
current
|
||||||
);
|
);
|
||||||
|
|
||||||
state = State.USER_MAPPING;
|
state = State.USER_MAPPING;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case REMOTE_SERVER:
|
||||||
|
|
||||||
case PROTOCOL:
|
if (localName.equals("remote-server")) {
|
||||||
|
state = State.AUTH_INFO;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (localName.equals("protocol")) {
|
break;
|
||||||
state = State.AUTH_INFO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case PROTOCOL:
|
||||||
|
|
||||||
case PARAMETER:
|
if (localName.equals("protocol")) {
|
||||||
|
state = State.REMOTE_SERVER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (localName.equals("param")) {
|
break;
|
||||||
state = State.AUTH_INFO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case PARAMETER:
|
||||||
|
|
||||||
}
|
if (localName.equals("param")) {
|
||||||
|
state = State.REMOTE_SERVER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
throw new SAXException("Tag not yet complete: " + localName);
|
throw new SAXException("Tag not yet complete: " + localName);
|
||||||
|
|
||||||
@@ -317,7 +340,6 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Only <authorize> tags allowed in main document
|
|
||||||
case USER_MAPPING:
|
case USER_MAPPING:
|
||||||
|
|
||||||
if (localName.equals("authorize")) {
|
if (localName.equals("authorize")) {
|
||||||
@@ -349,6 +371,23 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
|
|
||||||
case AUTH_INFO:
|
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")) {
|
if (localName.equals("protocol")) {
|
||||||
// Next state
|
// Next state
|
||||||
state = State.PROTOCOL;
|
state = State.PROTOCOL;
|
||||||
@@ -366,7 +405,7 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,15 +417,16 @@ public class BasicFileAuthenticationProvider implements AuthenticationProvider {
|
|||||||
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) {
|
switch (state) {
|
||||||
|
|
||||||
case PROTOCOL:
|
case PROTOCOL:
|
||||||
current.getConfiguration()
|
current.getConfiguration(currentRemoteServer)
|
||||||
.setProtocol(str);
|
.setProtocol(str);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case PARAMETER:
|
case PARAMETER:
|
||||||
current.getConfiguration()
|
current.getConfiguration(currentRemoteServer)
|
||||||
.setParameter(currentParameter, str);
|
.setParameter(currentParameter, str);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user