Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cloudfoundry.identity.uaa.security;

import javax.net.SocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
Expand All @@ -18,6 +19,14 @@ public static SocketFactory getDefault() {
return instance;
}

/**
* TLS endpoint identification algorithm for sockets from this factory, or {@code null} to
* disable hostname verification (as {@link SkipSslLdapSocketFactory} does).
*/
protected String getEndpointIdentificationAlgorithm() {
return "LDAPS";
}

@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
Expand All @@ -28,33 +37,40 @@ public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}

/**
* Ensures the target hostname is attached before the handshake; see {@link HostnameAwareSslSocket}.
*/
private Socket wrap(Socket socket, String knownHost) {
return new HostnameAwareSslSocket((SSLSocket) socket, getEndpointIdentificationAlgorithm(), knownHost);
}

@Override
public Socket createSocket() throws IOException {
return delegate.createSocket();
return wrap(delegate.createSocket(), null);
}

@Override
public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
return delegate.createSocket(socket, s, i, b);
return wrap(delegate.createSocket(socket, s, i, b), s);
}

@Override
public Socket createSocket(String s, int i) throws IOException {
return delegate.createSocket(s, i);
return wrap(delegate.createSocket(s, i), s);
}

@Override
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException {
return delegate.createSocket(s, i, inetAddress, i1);
return wrap(delegate.createSocket(s, i, inetAddress, i1), s);
}

@Override
public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
return delegate.createSocket(inetAddress, i);
return wrap(delegate.createSocket(inetAddress, i), HostnameAwareSslSocket.targetHost(inetAddress));
}

@Override
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
return delegate.createSocket(inetAddress, i, inetAddress1, i1);
return wrap(delegate.createSocket(inetAddress, i, inetAddress1, i1), HostnameAwareSslSocket.targetHost(inetAddress));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
Expand All @@ -29,6 +30,7 @@
*/
public class CaCertAwareLdapSocketFactory extends SSLSocketFactory {

private static final String ENDPOINT_ID_ALGORITHM = "LDAPS";
private static final SocketFactory instance = new CaCertAwareLdapSocketFactory();

private static final IdpOutboundTrustCache TRUST_CACHE = new IdpOutboundTrustCache();
Expand Down Expand Up @@ -62,6 +64,17 @@ private static SSLSocketFactory resolveDelegate() {
return sslContext != null ? sslContext.getSocketFactory() : (SSLSocketFactory) LdapSocketFactory.getDefault();
}

/**
* Same hostname wrapping as {@link BaseLdapSocketFactory}; default-trust fallback sockets are
* already wrapped, so they are not wrapped twice.
*/
private static Socket wrap(Socket socket, String knownHost) {
if (socket instanceof HostnameAwareSslSocket) {
return socket;
}
return new HostnameAwareSslSocket((SSLSocket) socket, ENDPOINT_ID_ALGORITHM, knownHost);
}

@Override
public String[] getDefaultCipherSuites() {
return resolveDelegate().getDefaultCipherSuites();
Expand All @@ -74,32 +87,32 @@ public String[] getSupportedCipherSuites() {

@Override
public Socket createSocket() throws IOException {
return resolveDelegate().createSocket();
return wrap(resolveDelegate().createSocket(), null);
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return resolveDelegate().createSocket(socket, host, port, autoClose);
return wrap(resolveDelegate().createSocket(socket, host, port, autoClose), host);
}

@Override
public Socket createSocket(String host, int port) throws IOException {
return resolveDelegate().createSocket(host, port);
return wrap(resolveDelegate().createSocket(host, port), host);
}

@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException {
return resolveDelegate().createSocket(host, port, localAddress, localPort);
return wrap(resolveDelegate().createSocket(host, port, localAddress, localPort), host);
}

@Override
public Socket createSocket(InetAddress address, int port) throws IOException {
return resolveDelegate().createSocket(address, port);
return wrap(resolveDelegate().createSocket(address, port), HostnameAwareSslSocket.targetHost(address));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return resolveDelegate().createSocket(address, port, localAddress, localPort);
return wrap(resolveDelegate().createSocket(address, port, localAddress, localPort), HostnameAwareSslSocket.targetHost(address));
}

private record ZoneLdapTrust(List<String> caCertificates, boolean skipSslValidation) {
Expand Down
Loading
Loading