mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Add source from existing guacamole-auth-ldap.
This commit is contained in:
54
extensions/guacamole-auth-ldap/src/main/assembly/dist.xml
Normal file
54
extensions/guacamole-auth-ldap/src/main/assembly/dist.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
|
||||
<id>dist</id>
|
||||
<baseDirectory>${project.artifactId}-${project.version}</baseDirectory>
|
||||
|
||||
<!-- Output tar.gz -->
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
|
||||
<!-- Include docs and schema -->
|
||||
<fileSets>
|
||||
|
||||
<!-- Include docs -->
|
||||
<fileSet>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<directory>doc</directory>
|
||||
</fileSet>
|
||||
|
||||
<!-- Include schema -->
|
||||
<fileSet>
|
||||
<outputDirectory>/schema</outputDirectory>
|
||||
<directory>schema</directory>
|
||||
</fileSet>
|
||||
|
||||
</fileSets>
|
||||
|
||||
<!-- Include self and all dependencies except guacamole-common
|
||||
and guacamole-ext -->
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<scope>runtime</scope>
|
||||
<unpack>false</unpack>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
|
||||
<excludes>
|
||||
|
||||
<!-- Do not include guacamole-common -->
|
||||
<exclude>net.sourceforge.guacamole:guacamole-common</exclude>
|
||||
|
||||
<!-- Do not include guacamole-ext -->
|
||||
<exclude>net.sourceforge.guacamole:guacamole-ext</exclude>
|
||||
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
</assembly>
|
@@ -0,0 +1,266 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.ldap;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-ldap.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Jumper.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.novell.ldap.LDAPAttribute;
|
||||
import com.novell.ldap.LDAPConnection;
|
||||
import com.novell.ldap.LDAPEntry;
|
||||
import com.novell.ldap.LDAPException;
|
||||
import com.novell.ldap.LDAPSearchResults;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.Credentials;
|
||||
import net.sourceforge.guacamole.net.auth.ldap.properties.LDAPGuacamoleProperties;
|
||||
import net.sourceforge.guacamole.net.auth.simple.SimpleAuthenticationProvider;
|
||||
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
/**
|
||||
* Allows users to be authenticated against an LDAP server. Each user may have
|
||||
* any number of authorized configurations. Authorized configurations may be
|
||||
* shared.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class LDAPAuthenticationProvider extends SimpleAuthenticationProvider {
|
||||
|
||||
// Courtesy of OWASP: https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java
|
||||
private static String escapeLDAPSearchFilter(String filter) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < filter.length(); i++) {
|
||||
char curChar = filter.charAt(i);
|
||||
switch (curChar) {
|
||||
case '\\':
|
||||
sb.append("\\5c");
|
||||
break;
|
||||
case '*':
|
||||
sb.append("\\2a");
|
||||
break;
|
||||
case '(':
|
||||
sb.append("\\28");
|
||||
break;
|
||||
case ')':
|
||||
sb.append("\\29");
|
||||
break;
|
||||
case '\u0000':
|
||||
sb.append("\\00");
|
||||
break;
|
||||
default:
|
||||
sb.append(curChar);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// Courtesy of OWASP: https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java
|
||||
private static String escapeDN(String name) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if ((name.length() > 0) && ((name.charAt(0) == ' ') || (name.charAt(0) == '#'))) {
|
||||
sb.append('\\'); // add the leading backslash if needed
|
||||
}
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char curChar = name.charAt(i);
|
||||
switch (curChar) {
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
case ',':
|
||||
sb.append("\\,");
|
||||
break;
|
||||
case '+':
|
||||
sb.append("\\+");
|
||||
break;
|
||||
case '"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '<':
|
||||
sb.append("\\<");
|
||||
break;
|
||||
case '>':
|
||||
sb.append("\\>");
|
||||
break;
|
||||
case ';':
|
||||
sb.append("\\;");
|
||||
break;
|
||||
default:
|
||||
sb.append(curChar);
|
||||
}
|
||||
}
|
||||
if ((name.length() > 1) && (name.charAt(name.length() - 1) == ' ')) {
|
||||
sb.insert(sb.length() - 1, '\\'); // add the trailing backslash if needed
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, GuacamoleConfiguration> getAuthorizedConfigurations(Credentials credentials) throws GuacamoleException {
|
||||
|
||||
try {
|
||||
|
||||
// Require username
|
||||
if (credentials.getUsername() == null) {
|
||||
// TODO: log "LDAP authentication requires a username."
|
||||
return null;
|
||||
}
|
||||
|
||||
// Require password, and do not allow anonymous binding
|
||||
if (credentials.getPassword() == null
|
||||
|| credentials.getPassword().length() == 0) {
|
||||
// TODO: log "LDAP authentication requires a password."
|
||||
return null;
|
||||
}
|
||||
|
||||
// Connect to LDAP server
|
||||
LDAPConnection ldapConnection = new LDAPConnection();
|
||||
ldapConnection.connect(
|
||||
GuacamoleProperties.getRequiredProperty(LDAPGuacamoleProperties.LDAP_HOSTNAME),
|
||||
GuacamoleProperties.getRequiredProperty(LDAPGuacamoleProperties.LDAP_PORT)
|
||||
);
|
||||
|
||||
// Get username attribute
|
||||
String username_attribute = GuacamoleProperties.getRequiredProperty(
|
||||
LDAPGuacamoleProperties.LDAP_USERNAME_ATTRIBUTE
|
||||
);
|
||||
|
||||
// Get user base DN
|
||||
String user_base_dn = GuacamoleProperties.getRequiredProperty(
|
||||
LDAPGuacamoleProperties.LDAP_USER_BASE_DN
|
||||
);
|
||||
|
||||
// Construct user DN
|
||||
String user_dn =
|
||||
escapeDN(username_attribute) + "=" + escapeDN(credentials.getUsername())
|
||||
+ "," + user_base_dn;
|
||||
|
||||
// Bind as user
|
||||
try {
|
||||
ldapConnection.bind(
|
||||
LDAPConnection.LDAP_V3,
|
||||
user_dn,
|
||||
credentials.getPassword().getBytes("UTF-8")
|
||||
);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
|
||||
// Get config base DN
|
||||
String config_base_dn = GuacamoleProperties.getRequiredProperty(
|
||||
LDAPGuacamoleProperties.LDAP_CONFIG_BASE_DN
|
||||
);
|
||||
|
||||
// Find all guac configs for this user
|
||||
LDAPSearchResults results = ldapConnection.search(
|
||||
config_base_dn,
|
||||
LDAPConnection.SCOPE_SUB,
|
||||
"(&(objectClass=guacConfigGroup)(member=" + escapeLDAPSearchFilter(user_dn) + "))",
|
||||
null,
|
||||
false
|
||||
);
|
||||
|
||||
// Add all configs
|
||||
Map<String, GuacamoleConfiguration> configs = new TreeMap<String, GuacamoleConfiguration>();
|
||||
while (results.hasMore()) {
|
||||
|
||||
LDAPEntry entry = results.next();
|
||||
|
||||
// New empty configuration
|
||||
GuacamoleConfiguration config = new GuacamoleConfiguration();
|
||||
|
||||
// Get CN
|
||||
LDAPAttribute cn = entry.getAttribute("cn");
|
||||
if (cn == null)
|
||||
throw new GuacamoleException("guacConfigGroup without cn");
|
||||
|
||||
// Get protocol
|
||||
LDAPAttribute protocol = entry.getAttribute("guacConfigProtocol");
|
||||
if (protocol == null)
|
||||
throw new GuacamoleException("guacConfigGroup without guacConfigProtocol");
|
||||
|
||||
// Set protocol
|
||||
config.setProtocol(protocol.getStringValue());
|
||||
|
||||
// Get parameters, if any
|
||||
LDAPAttribute parameterAttribute = entry.getAttribute("guacConfigParameter");
|
||||
if (parameterAttribute != null) {
|
||||
|
||||
// For each parameter
|
||||
Enumeration<String> parameters = parameterAttribute.getStringValues();
|
||||
while (parameters.hasMoreElements()) {
|
||||
|
||||
String parameter = parameters.nextElement();
|
||||
|
||||
// Parse parameter
|
||||
int equals = parameter.indexOf('=');
|
||||
if (equals != -1) {
|
||||
|
||||
// Parse name
|
||||
String name = parameter.substring(0, equals);
|
||||
String value = parameter.substring(equals+1);
|
||||
|
||||
config.setParameter(name, value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Store config by CN
|
||||
configs.put(cn.getStringValue(), config);
|
||||
|
||||
}
|
||||
|
||||
// Disconnect
|
||||
ldapConnection.disconnect();
|
||||
return configs;
|
||||
|
||||
}
|
||||
catch (LDAPException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,110 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.ldap.properties;
|
||||
|
||||
import net.sourceforge.guacamole.properties.IntegerGuacamoleProperty;
|
||||
import net.sourceforge.guacamole.properties.StringGuacamoleProperty;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-ldap.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Jumper.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Provides properties required for use of the LDAP authentication provider.
|
||||
* These properties will be read from guacamole.properties when the LDAP
|
||||
* authentication provider is used.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class LDAPGuacamoleProperties {
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private LDAPGuacamoleProperties() {}
|
||||
|
||||
/**
|
||||
* The base DN to search for Guacamole configurations.
|
||||
*/
|
||||
public static final StringGuacamoleProperty LDAP_CONFIG_BASE_DN = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-config-base-dn"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The base DN of users. All users must be direct children of this DN,
|
||||
* varying only by LDAP_USERNAME_ATTRIBUTE.
|
||||
*/
|
||||
public static final StringGuacamoleProperty LDAP_USER_BASE_DN = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-user-base-dn"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The attribute which identifies users. This attribute must be part of
|
||||
* each user's DN such that the concatenation of this attribute and
|
||||
* LDAP_USER_BASE_DN equals the users full DN.
|
||||
*/
|
||||
public static final StringGuacamoleProperty LDAP_USERNAME_ATTRIBUTE = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-username-attribute"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The port on the LDAP server to connect to when authenticating users.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty LDAP_PORT = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-port"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The hostname of the LDAP server to connect to when authenticating users.
|
||||
*/
|
||||
public static final StringGuacamoleProperty LDAP_HOSTNAME = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "ldap-hostname"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
Reference in New Issue
Block a user