77import com .unboundid .ldap .sdk .LDAPConnection ;
88import com .unboundid .ldap .sdk .LDAPException ;
99import com .unboundid .ldap .sdk .LDAPInterface ;
10+ import net .bytebuddy .ByteBuddy ;
11+ import net .bytebuddy .dynamic .loading .ClassLoadingStrategy ;
12+ import net .bytebuddy .implementation .FixedValue ;
1013import org .slf4j .Logger ;
1114import org .slf4j .LoggerFactory ;
1215import org .zapodot .junit .ldap .EmbeddedLdapServer ;
1821import javax .naming .directory .DirContext ;
1922import javax .naming .directory .InitialDirContext ;
2023import javax .naming .ldap .LdapContext ;
24+ import javax .net .SocketFactory ;
25+ import javax .net .ssl .SSLSocketFactory ;
26+ import java .io .IOException ;
2127import java .io .UnsupportedEncodingException ;
28+ import java .lang .reflect .Modifier ;
29+ import java .net .InetAddress ;
30+ import java .net .Socket ;
2231import java .net .URLDecoder ;
32+ import java .net .UnknownHostException ;
2333import java .util .Hashtable ;
2434import java .util .List ;
2535
@@ -34,11 +44,16 @@ abstract class EmbeddedLdapServerImpl implements EmbeddedLdapServer {
3444 private LDAPConnection ldapConnection ;
3545 private InitialDirContext initialDirContext ;
3646 private boolean isStarted = false ;
47+ private final boolean useTls ;
48+ private final SSLSocketFactory socketFactory ;
3749
3850 public EmbeddedLdapServerImpl (final InMemoryDirectoryServer inMemoryDirectoryServer ,
39- final AuthenticationConfiguration authenticationConfiguration1 ) {
51+ final AuthenticationConfiguration authenticationConfiguration1 ,
52+ final boolean useTls , SSLSocketFactory socketFactory ) {
4053 this .inMemoryDirectoryServer = inMemoryDirectoryServer ;
4154 this .authenticationConfiguration = authenticationConfiguration1 ;
55+ this .useTls = useTls ;
56+ this .socketFactory = socketFactory ;
4257 }
4358
4459 protected static InMemoryDirectoryServer createServer (final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig ,
@@ -112,10 +127,63 @@ private InitialDirContext createOrGetInitialDirContext() throws NamingException
112127 }
113128 }
114129
130+ public static abstract class AbstractDelegatingSocketFactory extends SocketFactory {
131+ public static AbstractDelegatingSocketFactory INSTANCE ;
132+
133+ public static AbstractDelegatingSocketFactory getDefault () {
134+ return INSTANCE ;
135+ }
136+
137+ protected abstract SocketFactory getDelegate ();
138+
139+ @ Override
140+ public Socket createSocket () throws IOException , UnknownHostException {
141+ return getDelegate ().createSocket ();
142+ }
143+
144+ @ Override
145+ public Socket createSocket (String host , int port ) throws IOException , UnknownHostException {
146+ return getDelegate ().createSocket (host , port );
147+ }
148+
149+ @ Override
150+ public Socket createSocket (String host , int port , InetAddress localHost , int localPort )
151+ throws IOException , UnknownHostException {
152+ return getDelegate ().createSocket (host , port , localHost , localPort );
153+ }
154+
155+ @ Override
156+ public Socket createSocket (InetAddress host , int port ) throws IOException {
157+ return getDelegate ().createSocket (host , port );
158+ }
159+
160+ @ Override
161+ public Socket createSocket (InetAddress address , int port , InetAddress localAddress , int localPort )
162+ throws IOException {
163+ return getDelegate ().createSocket (address , port , localAddress , localPort );
164+ }
165+ }
166+
115167 private Hashtable <String , String > createLdapEnvironment () {
116168 final Hashtable <String , String > environment = new Hashtable <>();
169+ if (socketFactory != null ) {
170+ final Class <?> delegator = (new ByteBuddy ()).subclass (AbstractDelegatingSocketFactory .class )
171+ .defineMethod ("getDelegate" , SocketFactory .class , Modifier .PROTECTED )
172+ .intercept (FixedValue .value (socketFactory ))
173+ .make ()
174+ .load (getClass ().getClassLoader (), ClassLoadingStrategy .Default .INJECTION )
175+ .getLoaded ();
176+ try {
177+ final Object instance = delegator .newInstance ();
178+ delegator .getField ("INSTANCE" ).set (instance , instance );
179+ } catch (InstantiationException | IllegalAccessException | NoSuchFieldException e ) {
180+ throw new IllegalStateException (e );
181+ }
182+ environment .put ("java.naming.ldap.factory.socket" , delegator .getCanonicalName ());
183+ }
117184 environment .put (LdapContext .CONTROL_FACTORIES , JAVA_RT_CONTROL_FACTORY );
118- environment .put (Context .PROVIDER_URL , String .format ("ldap://%s:%s" ,
185+ environment .put (Context .PROVIDER_URL , String .format ("%s://%s:%s" ,
186+ useTls ? "ldaps" : "ldap" ,
119187 inMemoryDirectoryServer .getListenAddress ().getHostName (),
120188 embeddedServerPort ()));
121189 environment .put (Context .INITIAL_CONTEXT_FACTORY , JAVA_RT_CONTEXT_FACTORY );
0 commit comments