diff --git a/config/alfresco/subsystems/Authentication/common-ldap-context.xml b/config/alfresco/subsystems/Authentication/common-ldap-context.xml
index 744dc2b9fc..9208a160e3 100644
--- a/config/alfresco/subsystems/Authentication/common-ldap-context.xml
+++ b/config/alfresco/subsystems/Authentication/common-ldap-context.xml
@@ -127,6 +127,12 @@
${ldap.authentication.java.naming.provider.url}
+
+
+ ${ldap.java.naming.ldap.factory.socket:#{null}}
+
+
+
@@ -165,6 +171,13 @@
${ldap.authentication.java.naming.provider.url}
+
+
+
+ ${ldap.java.naming.ldap.factory.socket:#{null}}
+
+
+
diff --git a/config/alfresco/subsystems/Authentication/ldap-ad/ldap-ad-authentication.properties b/config/alfresco/subsystems/Authentication/ldap-ad/ldap-ad-authentication.properties
index 0a93ee02e9..4de2b1f0bd 100644
--- a/config/alfresco/subsystems/Authentication/ldap-ad/ldap-ad-authentication.properties
+++ b/config/alfresco/subsystems/Authentication/ldap-ad/ldap-ad-authentication.properties
@@ -19,6 +19,9 @@ ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
# The URL to connect to the LDAP server
ldap.authentication.java.naming.provider.url=ldap://domaincontroller.company.com:389
+#Custom Socket Factory.
+#ldap.java.naming.ldap.factory.socket=org.alfresco.repo.security.authentication.ldap.AlfrescoLdapSSLSocketFactory
+
# The authentication mechanism to use for password validation
ldap.authentication.java.naming.security.authentication=simple
diff --git a/config/alfresco/subsystems/Authentication/ldap/ldap-authentication.properties b/config/alfresco/subsystems/Authentication/ldap/ldap-authentication.properties
index 0fa288ce9a..13c5336c43 100644
--- a/config/alfresco/subsystems/Authentication/ldap/ldap-authentication.properties
+++ b/config/alfresco/subsystems/Authentication/ldap/ldap-authentication.properties
@@ -25,6 +25,9 @@ ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
# The URL to connect to the LDAP server
ldap.authentication.java.naming.provider.url=ldap://openldap.domain.com:389
+#Custom Socket Factory.
+#ldap.java.naming.ldap.factory.socket=org.alfresco.repo.security.authentication.ldap.AlfrescoLdapSSLSocketFactory
+
# The authentication mechanism to use for password validation
ldap.authentication.java.naming.security.authentication=simple
diff --git a/source/java/org/alfresco/repo/security/authentication/ldap/AlfrescoLdapSSLSocketFactory.java b/source/java/org/alfresco/repo/security/authentication/ldap/AlfrescoLdapSSLSocketFactory.java
new file mode 100755
index 0000000000..c6be543d0a
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/authentication/ldap/AlfrescoLdapSSLSocketFactory.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.authentication.ldap;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * SSL Socket Factory that adds Hostname Verification to sockets
+ */
+
+public class AlfrescoLdapSSLSocketFactory extends SocketFactory
+{
+ private static Log logger = LogFactory.getLog(AlfrescoLdapSSLSocketFactory.class);
+
+ private static Boolean useJava6CodeBase = null;
+ private static Boolean useJava7CodeBase = null;
+
+ public static SocketFactory getDefault()
+
+ {
+ return new AlfrescoLdapSSLSocketFactory();
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException
+ {
+ SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
+ addHostNameVerification(sslSocket);
+ return sslSocket;
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException
+ {
+ SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(host, port);
+ addHostNameVerification(sslSocket);
+ return sslSocket;
+ }
+
+ @Override
+ public Socket createSocket(String address, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException
+ {
+ SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port, localAddress, localPort);
+ addHostNameVerification(sslSocket);
+ return sslSocket;
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
+ {
+ SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port, localAddress, localPort);
+ addHostNameVerification(sslSocket);
+ return sslSocket;
+ }
+
+ private void addHostNameVerification(SSLSocket sslSocket)
+ {
+ if (useJava6CodeBase == null || useJava6CodeBase)
+ {
+ //Try to use SSLSocketImpl.trySetHostnameVerification method that is supported by java6 and lower
+ try
+ {
+ Method m = sslSocket.getClass().getMethod("trySetHostnameVerification", String.class);
+ m.invoke(sslSocket, "LDAP");
+ useJava6CodeBase = true;
+ useJava7CodeBase = false;
+ }
+ catch (Throwable e)
+ {
+ useJava6CodeBase = false;
+ }
+ }
+
+ if (useJava7CodeBase == null || useJava7CodeBase)
+ {
+ //Try to use sslParams.setEndpointIdentificationAlgorithm method that is supported by java 7 and higher
+ try
+ {
+ SSLParameters sslParams = new SSLParameters();
+ Method m = sslParams.getClass().getMethod("setEndpointIdentificationAlgorithm", String.class);
+ m.invoke(sslParams, "LDAPS");
+ sslSocket.setSSLParameters(sslParams);
+ useJava6CodeBase = false;
+ useJava7CodeBase = true;
+ }
+ catch (Throwable ee)
+ {
+ useJava7CodeBase = false;
+
+ if(useJava6CodeBase == false && logger.isWarnEnabled())
+ {
+ logger.warn("AlfrescoLdapSSLSocketFactory: Unable to turn on Hostname Verification");
+ }
+ }
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPInitialDirContextFactoryImpl.java b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPInitialDirContextFactoryImpl.java
index 9b730b5aa0..6c6bb8a204 100644
--- a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPInitialDirContextFactoryImpl.java
+++ b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPInitialDirContextFactoryImpl.java
@@ -123,6 +123,7 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
public void setInitialDirContextEnvironment(Map initialDirContextEnvironment)
{
this.authenticatedEnvironment = initialDirContextEnvironment;
+ this.authenticatedEnvironment.values().removeAll(Collections.singleton(null));
}
public Map getInitialDirContextEnvironment()
@@ -133,6 +134,7 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
public void setDefaultIntialDirContextEnvironment(Map defaultEnvironment)
{
this.defaultEnvironment = defaultEnvironment;
+ this.defaultEnvironment.values().removeAll(Collections.singleton(null));
}
public InitialDirContext getDefaultIntialDirContext() throws AuthenticationException