1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.factory;
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.lang.annotation.Annotation;
25 import java.lang.reflect.Method;
26 import java.net.ServerSocket;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30
31 import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;
32 import org.apache.directory.api.util.Network;
33 import org.apache.directory.api.util.Strings;
34 import org.apache.directory.server.annotations.CreateChngPwdServer;
35 import org.apache.directory.server.annotations.CreateConsumer;
36 import org.apache.directory.server.annotations.CreateKdcServer;
37 import org.apache.directory.server.annotations.CreateLdapServer;
38 import org.apache.directory.server.annotations.CreateTransport;
39 import org.apache.directory.server.annotations.SaslMechanism;
40 import org.apache.directory.server.core.annotations.AnnotationUtils;
41 import org.apache.directory.server.core.api.DirectoryService;
42 import org.apache.directory.server.core.security.CertificateUtil;
43 import org.apache.directory.server.i18n.I18n;
44 import org.apache.directory.server.kerberos.ChangePasswordConfig;
45 import org.apache.directory.server.kerberos.KerberosConfig;
46 import org.apache.directory.server.kerberos.changepwd.ChangePasswordServer;
47 import org.apache.directory.server.kerberos.kdc.KdcServer;
48 import org.apache.directory.server.ldap.ExtendedOperationHandler;
49 import org.apache.directory.server.ldap.LdapServer;
50 import org.apache.directory.server.ldap.handlers.sasl.MechanismHandler;
51 import org.apache.directory.server.ldap.handlers.sasl.ntlm.NtlmMechanismHandler;
52 import org.apache.directory.server.ldap.handlers.sasl.ntlm.NtlmProvider;
53 import org.apache.directory.server.ldap.replication.SyncReplConfiguration;
54 import org.apache.directory.server.ldap.replication.consumer.ReplicationConsumer;
55 import org.apache.directory.server.ldap.replication.consumer.ReplicationConsumerImpl;
56 import org.apache.directory.server.protocol.shared.transport.TcpTransport;
57 import org.apache.directory.server.protocol.shared.transport.Transport;
58 import org.apache.directory.server.protocol.shared.transport.UdpTransport;
59 import org.junit.runner.Description;
60
61
62
63
64
65
66
67
68 public final class ServerAnnotationProcessor
69 {
70 private ServerAnnotationProcessor()
71 {
72 }
73
74
75 private static void createTransports( LdapServer ldapServer, CreateTransport[] transportBuilders )
76 {
77 if ( transportBuilders.length != 0 )
78 {
79 for ( CreateTransport transportBuilder : transportBuilders )
80 {
81 List< Transport > transports = createTransports( transportBuilder );
82
83 for ( Transport t : transports )
84 {
85 ldapServer.addTransports( t );
86 }
87 }
88 }
89 else
90 {
91
92 try
93 {
94 int port = getFreePort();
95 Transport ldap = new TcpTransport( port );
96 ldapServer.addTransports( ldap );
97 }
98 catch ( IOException ioe )
99 {
100
101 }
102
103 try
104 {
105 int port = getFreePort();
106 Transport ldaps = new TcpTransport( port );
107 ldaps.setEnableSSL( true );
108 ldapServer.addTransports( ldaps );
109 }
110 catch ( IOException ioe )
111 {
112
113 }
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126
127 public static LdapServer instantiateLdapServer( CreateLdapServer createLdapServer, DirectoryService directoryService )
128 {
129 if ( createLdapServer != null )
130 {
131 LdapServerLdapServer.html#LdapServer">LdapServer ldapServer = new LdapServer();
132
133 ldapServer.setServiceName( createLdapServer.name() );
134
135
136 createTransports( ldapServer, createLdapServer.transports() );
137
138
139 ldapServer.setDirectoryService( directoryService );
140
141
142 directoryService.setAllowAnonymousAccess( createLdapServer.allowAnonymousAccess() );
143
144 ldapServer.setSaslHost( createLdapServer.saslHost() );
145
146 ldapServer.setSaslPrincipal( createLdapServer.saslPrincipal() );
147
148 if ( !Strings.isEmpty( createLdapServer.keyStore() ) )
149 {
150 ldapServer.setKeystoreFile( createLdapServer.keyStore() );
151 ldapServer.setCertificatePassword( createLdapServer.certificatePassword() );
152 }
153 else
154 {
155 try
156 {
157
158 File keyStoreFile = CertificateUtil.createTempKeyStore( "testStore", "secret".toCharArray() );
159 ldapServer.setKeystoreFile( keyStoreFile.getAbsolutePath() );
160 ldapServer.setCertificatePassword( "secret" );
161 }
162 catch ( Exception e )
163 {
164
165 }
166 }
167
168 for ( Class<?> extOpClass : createLdapServer.extendedOpHandlers() )
169 {
170 try
171 {
172 ExtendedOperationHandler/directory/server/ldap/ExtendedOperationHandler.html#ExtendedOperationHandler">ExtendedOperationHandler extOpHandler = ( ExtendedOperationHandler ) extOpClass.newInstance();
173 ldapServer.addExtendedOperationHandler( extOpHandler );
174 }
175 catch ( Exception e )
176 {
177 throw new RuntimeException( I18n.err( I18n.ERR_690, extOpClass.getName() ), e );
178 }
179 }
180
181 for ( SaslMechanism saslMech : createLdapServer.saslMechanisms() )
182 {
183 try
184 {
185 MechanismHandler../org/apache/directory/server/ldap/handlers/sasl/MechanismHandler.html#MechanismHandler">MechanismHandler handler = ( MechanismHandler ) saslMech.implClass().newInstance();
186 ldapServer.addSaslMechanismHandler( saslMech.name(), handler );
187 }
188 catch ( Exception e )
189 {
190 throw new RuntimeException(
191 I18n.err( I18n.ERR_691, saslMech.name(), saslMech.implClass().getName() ), e );
192 }
193 }
194
195 NtlmMechanismHandlerpache/directory/server/ldap/handlers/sasl/ntlm/NtlmMechanismHandler.html#NtlmMechanismHandler">NtlmMechanismHandler ntlmHandler = ( NtlmMechanismHandler ) ldapServer.getSaslMechanismHandlers().get(
196 SupportedSaslMechanisms.NTLM );
197
198 if ( ntlmHandler != null )
199 {
200 Class<?> ntlmProviderClass = createLdapServer.ntlmProvider();
201
202 if ( ( ntlmProviderClass != null ) && ( ntlmProviderClass != Object.class ) )
203 {
204 try
205 {
206 ntlmHandler.setNtlmProvider( ( NtlmProvider ) ntlmProviderClass.newInstance() );
207 }
208 catch ( Exception e )
209 {
210 throw new RuntimeException( I18n.err( I18n.ERR_692 ), e );
211 }
212 }
213 }
214
215 List<String> realms = new ArrayList<>();
216 for ( String s : createLdapServer.saslRealms() )
217 {
218 realms.add( s );
219 }
220
221 ldapServer.setSaslRealms( realms );
222
223 return ldapServer;
224 }
225 else
226 {
227 return null;
228 }
229 }
230
231
232
233
234
235
236
237
238
239
240 public static LdapServer getLdapServer( DirectoryService directoryService ) throws ClassNotFoundException
241 {
242 Object instance = AnnotationUtils.getInstance( CreateLdapServer.class );
243 LdapServer ldapServer = null;
244
245 if ( instance != null )
246 {
247 CreateLdapServer createLdapServer = ( CreateLdapServer ) instance;
248
249 ldapServer = createLdapServer( createLdapServer, directoryService );
250 }
251
252 return ldapServer;
253 }
254
255
256
257
258
259 private static ReplicationConsumer createConsumer( CreateConsumer createConsumer )
260 {
261 ReplicationConsumer consumer = new ReplicationConsumerImpl();
262
263 SyncReplConfigurationtion/SyncReplConfiguration.html#SyncReplConfiguration">SyncReplConfiguration config = new SyncReplConfiguration();
264
265 String remoteHost = createConsumer.remoteHost();
266
267 if ( Strings.isEmpty( remoteHost ) )
268 {
269 remoteHost = Network.LOOPBACK_HOSTNAME;
270 }
271
272 config.setRemoteHost( remoteHost );
273 config.setRemotePort( createConsumer.remotePort() );
274 config.setReplUserDn( createConsumer.replUserDn() );
275 config.setReplUserPassword( Strings.getBytesUtf8( createConsumer.replUserPassword() ) );
276 config.setUseTls( createConsumer.useTls() );
277 config.setBaseDn( createConsumer.baseDn() );
278 config.setRefreshInterval( createConsumer.refreshInterval() );
279
280 consumer.setConfig( config );
281
282 return consumer;
283 }
284
285
286
287
288
289
290
291
292
293 public static ReplicationConsumer createConsumer() throws ClassNotFoundException
294 {
295 Object instance = AnnotationUtils.getInstance( CreateConsumer.class );
296 ReplicationConsumer consumer = null;
297
298 if ( instance != null )
299 {
300 CreateConsumer createConsumer = ( CreateConsumer ) instance;
301
302 consumer = createConsumer( createConsumer );
303 }
304
305 return consumer;
306 }
307
308
309
310
311
312
313
314
315
316 private static LdapServer createLdapServer( CreateLdapServer createLdapServer, DirectoryService directoryService )
317 {
318 LdapServer ldapServer = instantiateLdapServer( createLdapServer, directoryService );
319
320 if ( ldapServer == null )
321 {
322 return null;
323 }
324
325
326 try
327 {
328 ldapServer.start();
329 }
330 catch ( Exception e )
331 {
332 e.printStackTrace();
333 }
334
335 return ldapServer;
336 }
337
338
339
340
341
342
343
344
345
346 public static LdapServer createLdapServer( Description description, DirectoryService directoryService )
347 {
348 CreateLdapServer createLdapServer = description.getAnnotation( CreateLdapServer.class );
349
350
351 return createLdapServer( createLdapServer, directoryService );
352 }
353
354
355 @SuppressWarnings("unchecked")
356 private static Annotation getAnnotation( Class annotationClass ) throws Exception
357 {
358
359 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
360
361
362 int index = stackTrace[0].getMethodName().equals( "dumpThreads" ) ? 4 : 3;
363
364
365 Class<?> classCaller = Class.forName( stackTrace[index].getClassName() );
366
367
368 String methodCaller = stackTrace[index].getMethodName();
369
370
371 Method[] methods = classCaller.getMethods();
372
373 for ( Method method : methods )
374 {
375 if ( methodCaller.equals( method.getName() ) )
376 {
377 Annotation annotation = method.getAnnotation( annotationClass );
378
379 if ( annotation != null )
380 {
381 return annotation;
382 }
383 }
384 }
385
386
387 return classCaller.getAnnotation( annotationClass );
388 }
389
390
391 public static KdcServer getKdcServer( DirectoryService directoryService, int startPort ) throws Exception
392 {
393 CreateKdcServer createKdcServer = ( CreateKdcServer ) getAnnotation( CreateKdcServer.class );
394
395 return createKdcServer( createKdcServer, directoryService );
396 }
397
398
399 private static KdcServer createKdcServer( CreateKdcServer createKdcServer, DirectoryService directoryService )
400 {
401 if ( createKdcServer == null )
402 {
403 return null;
404 }
405
406 KerberosConfig/KerberosConfig.html#KerberosConfig">KerberosConfig kdcConfig = new KerberosConfig();
407 kdcConfig.setServicePrincipal( createKdcServer.kdcPrincipal() );
408 kdcConfig.setPrimaryRealm( createKdcServer.primaryRealm() );
409 kdcConfig.setMaximumTicketLifetime( createKdcServer.maxTicketLifetime() );
410 kdcConfig.setMaximumRenewableLifetime( createKdcServer.maxRenewableLifetime() );
411
412 KdcServerberos/kdc/KdcServer.html#KdcServer">KdcServer kdcServer = new KdcServer( kdcConfig );
413
414 kdcServer.setSearchBaseDn( createKdcServer.searchBaseDn() );
415
416 CreateTransport[] transportBuilders = createKdcServer.transports();
417
418 if ( transportBuilders == null )
419 {
420
421 int port = 0;
422 try
423 {
424 port = getFreePort();
425 }
426 catch ( IOException ioe )
427 {
428
429 }
430 UdpTransported/transport/UdpTransport.html#UdpTransport">UdpTransport defaultTransport = new UdpTransport( port );
431 kdcServer.addTransports( defaultTransport );
432 }
433 else if ( transportBuilders.length > 0 )
434 {
435 for ( CreateTransport transportBuilder : transportBuilders )
436 {
437 List< Transport > transports = createTransports( transportBuilder );
438 for ( Transport t : transports )
439 {
440 kdcServer.addTransports( t );
441 }
442 }
443 }
444
445 CreateChngPwdServer[] createChngPwdServers = createKdcServer.chngPwdServer();
446
447 if ( createChngPwdServers.length > 0 )
448 {
449
450 CreateChngPwdServer createChngPwdServer = createChngPwdServers[0];
451 ChangePasswordConfigangePasswordConfig.html#ChangePasswordConfig">ChangePasswordConfig config = new ChangePasswordConfig( kdcConfig );
452 config.setServicePrincipal( createChngPwdServer.srvPrincipal() );
453
454 ChangePasswordServer/ChangePasswordServer.html#ChangePasswordServer">ChangePasswordServer chngPwdServer = new ChangePasswordServer( config );
455
456 for ( CreateTransport transportBuilder : createChngPwdServer.transports() )
457 {
458 List< Transport > transports = createTransports( transportBuilder );
459 for ( Transport t : transports )
460 {
461 chngPwdServer.addTransports( t );
462 }
463 }
464
465 chngPwdServer.setDirectoryService( directoryService );
466
467 kdcServer.setChangePwdServer( chngPwdServer );
468 }
469
470 kdcServer.setDirectoryService( directoryService );
471
472
473 try
474 {
475 kdcServer.start();
476 }
477 catch ( Exception e )
478 {
479 e.printStackTrace();
480 }
481
482 return kdcServer;
483 }
484
485
486 private static List< Transport > createTransports( CreateTransport transportBuilder )
487 {
488 String protocol = transportBuilder.protocol();
489 int port = transportBuilder.port();
490 int nbThreads = transportBuilder.nbThreads();
491 int backlog = transportBuilder.backlog();
492 String address = transportBuilder.address();
493 boolean clientAuth = transportBuilder.clientAuth();
494
495 if ( Strings.isEmpty( address ) )
496 {
497 address = Network.LOOPBACK_HOSTNAME;
498 }
499
500 if ( port <= 0 )
501 {
502 try
503 {
504 port = getFreePort();
505 }
506 catch ( IOException ioe )
507 {
508
509 }
510 }
511
512 if ( protocol.equalsIgnoreCase( "TCP" ) || protocol.equalsIgnoreCase( "LDAP" ) )
513 {
514 Transport tcp = new TcpTransport( address, port, nbThreads, backlog );
515 return Collections.singletonList( tcp );
516 }
517 else if ( protocol.equalsIgnoreCase( "LDAPS" ) )
518 {
519 Transport tcp = new TcpTransport( address, port, nbThreads, backlog );
520 tcp.setEnableSSL( true );
521 ( ( TcpTransport ) tcp ).setWantClientAuth( clientAuth );
522 return Collections.singletonList( tcp );
523 }
524 else if ( protocol.equalsIgnoreCase( "UDP" ) )
525 {
526 Transport udp = new UdpTransport( address, port );
527 return Collections.singletonList( udp );
528 }
529 else if ( protocol.equalsIgnoreCase( "KRB" ) || protocol.equalsIgnoreCase( "CPW" ) )
530 {
531 Transport tcp = new TcpTransport( address, port, nbThreads, backlog );
532 List< Transport > transports = new ArrayList<>();
533 transports.add( tcp );
534
535 Transport udp = new UdpTransport( address, port );
536 transports.add( udp );
537 return transports;
538 }
539
540 throw new IllegalArgumentException( I18n.err( I18n.ERR_689, protocol ) );
541 }
542
543
544 private static int getFreePort() throws IOException
545 {
546 ServerSocket ss = new ServerSocket( 0 );
547 int port = ss.getLocalPort();
548 ss.close();
549
550 return port;
551 }
552
553
554 public static KdcServer getKdcServer( Description description, DirectoryService directoryService, int startPort )
555 {
556 CreateKdcServer createLdapServer = description.getAnnotation( CreateKdcServer.class );
557
558 return createKdcServer( createLdapServer, directoryService );
559 }
560 }