mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
Merge pull request #297 from glyptodon/ldap-ssl-starttls
GUAC-1166: Add support for SSL/TLS and STARTTLS to LDAP.
This commit is contained in:
@@ -61,8 +61,9 @@ public class ConfigurationService {
|
||||
|
||||
/**
|
||||
* Returns the port of the LDAP server configured with
|
||||
* guacamole.properties. By default, this will be 389 - the standard LDAP
|
||||
* port.
|
||||
* guacamole.properties. The default value depends on which encryption
|
||||
* method is being used. For unencrypted LDAP and STARTTLS, this will be
|
||||
* 389. For LDAPS (LDAP over SSL) this will be 636.
|
||||
*
|
||||
* @return
|
||||
* The port of the LDAP server, as configured with
|
||||
@@ -74,7 +75,7 @@ public class ConfigurationService {
|
||||
public int getServerPort() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
LDAPGuacamoleProperties.LDAP_PORT,
|
||||
389
|
||||
getEncryptionMethod().DEFAULT_PORT
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,4 +173,22 @@ public class ConfigurationService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encryption method that should be used when connecting to the
|
||||
* LDAP server. By default, no encryption is used.
|
||||
*
|
||||
* @return
|
||||
* The encryption method that should be used when connecting to the
|
||||
* LDAP server.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public EncryptionMethod getEncryptionMethod() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
LDAPGuacamoleProperties.LDAP_ENCRYPTION_METHOD,
|
||||
EncryptionMethod.NONE
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.auth.ldap;
|
||||
|
||||
/**
|
||||
* All possible encryption methods which may be used when connecting to an LDAP
|
||||
* server.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public enum EncryptionMethod {
|
||||
|
||||
/**
|
||||
* No encryption will be used. All data will be sent to the LDAP server in
|
||||
* plaintext. Unencrypted LDAP connections use port 389 by default.
|
||||
*/
|
||||
NONE(389),
|
||||
|
||||
/**
|
||||
* The connection to the LDAP server will be encrypted with SSL. LDAP over
|
||||
* SSL (LDAPS) will use port 636 by default.
|
||||
*/
|
||||
SSL(636),
|
||||
|
||||
/**
|
||||
* The connection to the LDAP server will be encrypted using STARTTLS. TLS
|
||||
* connections are negotiated over the standard LDAP port of 389 - the same
|
||||
* port used for unencrypted traffic.
|
||||
*/
|
||||
STARTTLS(389);
|
||||
|
||||
/**
|
||||
* The default port of this specific encryption method. As with most
|
||||
* protocols, the default port for LDAP varies by whether SSL is used.
|
||||
*/
|
||||
public final int DEFAULT_PORT;
|
||||
|
||||
/**
|
||||
* Initializes this encryption method such that it is associated with the
|
||||
* given default port.
|
||||
*
|
||||
* @param defaultPort
|
||||
* The default port to associate with this encryption method.
|
||||
*/
|
||||
private EncryptionMethod(int defaultPort) {
|
||||
this.DEFAULT_PORT = defaultPort;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.auth.ldap;
|
||||
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerException;
|
||||
import org.glyptodon.guacamole.properties.GuacamoleProperty;
|
||||
|
||||
/**
|
||||
* A GuacamoleProperty whose value is an EncryptionMethod. The string values
|
||||
* "none", "ssl", and "starttls" are each parsed to their corresponding values
|
||||
* within the EncryptionMethod enum. All other string values result in parse
|
||||
* errors.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class EncryptionMethodProperty implements GuacamoleProperty<EncryptionMethod> {
|
||||
|
||||
@Override
|
||||
public EncryptionMethod parseValue(String value) throws GuacamoleException {
|
||||
|
||||
// If no value provided, return null.
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
// Plaintext (no encryption)
|
||||
if (value.equals("none"))
|
||||
return EncryptionMethod.NONE;
|
||||
|
||||
// SSL
|
||||
if (value.equals("ssl"))
|
||||
return EncryptionMethod.SSL;
|
||||
|
||||
// STARTTLS
|
||||
if (value.equals("starttls"))
|
||||
return EncryptionMethod.STARTTLS;
|
||||
|
||||
// The provided value is not legal
|
||||
throw new GuacamoleServerException("Encryption method must be one of \"none\", \"ssl\", or \"starttls\".");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -25,8 +25,11 @@ package org.glyptodon.guacamole.auth.ldap;
|
||||
import com.google.inject.Inject;
|
||||
import com.novell.ldap.LDAPConnection;
|
||||
import com.novell.ldap.LDAPException;
|
||||
import com.novell.ldap.LDAPJSSESecureSocketFactory;
|
||||
import com.novell.ldap.LDAPJSSEStartTLSFactory;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -48,6 +51,48 @@ public class LDAPConnectionService {
|
||||
@Inject
|
||||
private ConfigurationService confService;
|
||||
|
||||
/**
|
||||
* Creates a new instance of LDAPConnection, configured as required to use
|
||||
* whichever encryption method is requested within guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* A new LDAPConnection instance which has already been configured to
|
||||
* use the encryption method requested within guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while parsing guacamole.properties, or if the
|
||||
* requested encryption method is actually not implemented (a bug).
|
||||
*/
|
||||
private LDAPConnection createLDAPConnection() throws GuacamoleException {
|
||||
|
||||
// Map encryption method to proper connection and socket factory
|
||||
EncryptionMethod encryptionMethod = confService.getEncryptionMethod();
|
||||
switch (encryptionMethod) {
|
||||
|
||||
// Unencrypted LDAP connection
|
||||
case NONE:
|
||||
logger.debug("Connection to LDAP server without encryption.");
|
||||
return new LDAPConnection();
|
||||
|
||||
// LDAP over SSL (LDAPS)
|
||||
case SSL:
|
||||
logger.debug("Connecting to LDAP server using SSL/TLS.");
|
||||
return new LDAPConnection(new LDAPJSSESecureSocketFactory());
|
||||
|
||||
// LDAP + STARTTLS
|
||||
case STARTTLS:
|
||||
logger.debug("Connecting to LDAP server using STARTTLS.");
|
||||
return new LDAPConnection(new LDAPJSSEStartTLSFactory());
|
||||
|
||||
// The encryption method, though known, is not actually
|
||||
// implemented. If encountered, this would be a bug.
|
||||
default:
|
||||
throw new GuacamoleUnsupportedException("Unimplemented encryption method: " + encryptionMethod);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds to the LDAP server using the provided user DN and password.
|
||||
*
|
||||
@@ -68,15 +113,21 @@ public class LDAPConnectionService {
|
||||
public LDAPConnection bindAs(String userDN, String password)
|
||||
throws GuacamoleException {
|
||||
|
||||
LDAPConnection ldapConnection;
|
||||
// Obtain appropriately-configured LDAPConnection instance
|
||||
LDAPConnection ldapConnection = createLDAPConnection();
|
||||
|
||||
// Connect to LDAP server
|
||||
try {
|
||||
ldapConnection = new LDAPConnection();
|
||||
|
||||
// Connect to LDAP server
|
||||
ldapConnection.connect(
|
||||
confService.getServerHostname(),
|
||||
confService.getServerPort()
|
||||
);
|
||||
|
||||
// Explicitly start TLS if requested
|
||||
if (confService.getEncryptionMethod() == EncryptionMethod.STARTTLS)
|
||||
ldapConnection.startTLS();
|
||||
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
logger.error("Unable to connect to LDAP server: {}", e.getMessage());
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -124,4 +124,16 @@ public class LDAPGuacamoleProperties {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The encryption method to use when connecting to the LDAP server, if any.
|
||||
* The chosen method will also dictate the default port if not already
|
||||
* explicitly specified via LDAP_PORT.
|
||||
*/
|
||||
public static final EncryptionMethodProperty LDAP_ENCRYPTION_METHOD = new EncryptionMethodProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-encryption-method"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user