1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.common.config.attribute.resolver.dataConnector;
18
19 import java.io.IOException;
20 import java.security.GeneralSecurityException;
21 import java.security.KeyStore;
22 import java.security.cert.X509Certificate;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.net.ssl.KeyManager;
28 import javax.net.ssl.KeyManagerFactory;
29 import javax.net.ssl.SSLContext;
30 import javax.net.ssl.TrustManager;
31 import javax.net.ssl.TrustManagerFactory;
32
33 import net.sf.ehcache.Cache;
34 import net.sf.ehcache.CacheManager;
35
36 import org.opensaml.xml.security.x509.X509Credential;
37 import org.opensaml.xml.util.DatatypeHelper;
38
39 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.LdapDataConnector;
40 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.LdapPoolStrategy;
41 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.TemplateEngine;
42 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.LdapDataConnector.AUTHENTICATION_TYPE;
43 import edu.vt.middleware.ldap.LdapConfig;
44 import edu.vt.middleware.ldap.LdapConfig.SearchScope;
45 import edu.vt.middleware.ldap.handler.BinarySearchResultHandler;
46 import edu.vt.middleware.ldap.handler.CaseChangeSearchResultHandler;
47 import edu.vt.middleware.ldap.handler.CaseChangeSearchResultHandler.CaseChange;
48 import edu.vt.middleware.ldap.handler.ConnectionHandler.ConnectionStrategy;
49 import edu.vt.middleware.ldap.handler.EntryDnSearchResultHandler;
50 import edu.vt.middleware.ldap.handler.FqdnSearchResultHandler;
51 import edu.vt.middleware.ldap.handler.MergeSearchResultHandler;
52 import edu.vt.middleware.ldap.handler.SearchResultHandler;
53 import edu.vt.middleware.ldap.pool.DefaultLdapFactory;
54 import edu.vt.middleware.ldap.pool.LdapValidator;
55
56
57
58
59 public class LdapDataConnectorFactoryBean extends BaseDataConnectorFactoryBean {
60
61
62 private LdapPoolStrategy ldapPoolStrategy;
63
64
65 private LdapConfig ldapConfig = new LdapConfig();
66
67
68 private ConnectionStrategy connStrategy;
69
70
71 private Map<String, String> ldapProperties;
72
73
74 private LdapValidator ldapValidator;
75
76
77 private TemplateEngine templateEngine;
78
79
80 private String filterTemplate;
81
82
83 private List<String> returnAttributes;
84
85
86 private X509Credential trustCredential;
87
88
89 private X509Credential connectionCredential;
90
91
92 private boolean mergeResults;
93
94
95 private boolean noResultsIsError;
96
97
98 private boolean lowercaseAttributeNames;
99
100
101 private CacheManager cacheManager;
102
103
104 private int maximumCachedElements;
105
106
107 private long cacheElementTtl;
108
109
110 protected Object createInstance() throws Exception {
111 List<SearchResultHandler> resultHandlers = new ArrayList<SearchResultHandler>();
112 resultHandlers.add(new FqdnSearchResultHandler());
113 resultHandlers.add(new EntryDnSearchResultHandler());
114 if (mergeResults) {
115 resultHandlers.add(new MergeSearchResultHandler());
116 }
117 if (lowercaseAttributeNames) {
118 final CaseChangeSearchResultHandler srh = new CaseChangeSearchResultHandler();
119 srh.setAttributeNameCaseChange(CaseChange.LOWER);
120 resultHandlers.add(srh);
121 }
122 resultHandlers.add(new BinarySearchResultHandler());
123 ldapConfig.setSearchResultHandlers(resultHandlers.toArray(new SearchResultHandler[resultHandlers.size()]));
124 ldapConfig.getConnectionHandler().setConnectionStrategy(connStrategy);
125
126
127 if (ldapProperties != null) {
128 for (Map.Entry<String, String> entry : ldapProperties.entrySet()) {
129 ldapConfig.setEnvironmentProperties(entry.getKey(), entry.getValue());
130 }
131 }
132
133 SSLContext ctx = createSSLContext();
134 if (ctx != null) {
135 ldapConfig.setSslSocketFactory(ctx.getSocketFactory());
136 }
137
138 Cache resultsCache = null;
139 if (cacheManager != null) {
140 resultsCache = cacheManager.getCache(getPluginId());
141 if (resultsCache == null) {
142 long ttlInSeconds = cacheElementTtl / 1000;
143 resultsCache = new Cache(
144 getPluginId(), maximumCachedElements, false, false, ttlInSeconds, ttlInSeconds);
145 cacheManager.addCache(resultsCache);
146 }
147 }
148
149
150 DefaultLdapFactory ldapFactory = new DefaultLdapFactory(ldapConfig);
151 if (ldapValidator != null) {
152 ldapFactory.setLdapValidator(ldapValidator);
153 }
154 ldapPoolStrategy.setLdapFactory(ldapFactory);
155 ldapPoolStrategy.initialize();
156 LdapDataConnector connector = new LdapDataConnector(ldapPoolStrategy, resultsCache);
157 populateDataConnector(connector);
158 connector.setNoResultsIsError(noResultsIsError);
159 if (returnAttributes != null) {
160 connector.setReturnAttributes(returnAttributes.toArray(new String[returnAttributes.size()]));
161 }
162 connector.registerTemplate(templateEngine, filterTemplate);
163
164 return connector;
165 }
166
167
168
169
170
171
172
173
174 protected SSLContext createSSLContext() throws Exception {
175
176 TrustManager[] sslTrustManagers = null;
177 if (trustCredential != null) {
178 try {
179 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
180 KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
181 keystore.load(null, null);
182 for (X509Certificate c : trustCredential.getEntityCertificateChain()) {
183 keystore.setCertificateEntry("ldap_tls_trust_" + c.getSerialNumber(), c);
184 }
185 tmf.init(keystore);
186 sslTrustManagers = tmf.getTrustManagers();
187 } catch (GeneralSecurityException e) {
188 logger.error("Error initializing trust managers", e);
189 } catch (IOException e) {
190 logger.error("Error initializing trust managers", e);
191 }
192 }
193
194 KeyManager[] sslKeyManagers = null;
195 if (connectionCredential != null) {
196 try {
197 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
198 KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
199 keystore.load(null, null);
200 keystore.setKeyEntry("ldap_tls_client_auth", connectionCredential.getPrivateKey(), "changeit"
201 .toCharArray(), connectionCredential.getEntityCertificateChain()
202 .toArray(new X509Certificate[0]));
203 kmf.init(keystore, "changeit".toCharArray());
204 sslKeyManagers = kmf.getKeyManagers();
205 } catch (GeneralSecurityException e) {
206 logger.error("Error initializing key managers", e);
207 } catch (IOException e) {
208 logger.error("Error initializing key managers", e);
209 }
210 }
211
212 SSLContext ctx = null;
213 if (sslTrustManagers != null || sslKeyManagers != null) {
214 ctx = SSLContext.getInstance("TLS");
215 ctx.init(sslKeyManagers, sslTrustManagers, null);
216 }
217 return ctx;
218 }
219
220
221
222
223
224
225 public AUTHENTICATION_TYPE getAuthenticationType() {
226 return AUTHENTICATION_TYPE.getAuthenticationTypeByName(ldapConfig.getAuthtype());
227 }
228
229
230
231
232
233
234 public String getBaseDN() {
235 return this.ldapConfig.getBaseDn();
236 }
237
238
239
240
241
242
243 public long getCacheElementTimeToLive() {
244 return cacheElementTtl;
245 }
246
247
248
249
250
251
252 public CacheManager getCacheManager() {
253 return cacheManager;
254 }
255
256
257
258
259
260
261 public X509Credential getConnectionCredential() {
262 return connectionCredential;
263 }
264
265
266
267
268
269
270 public String getFilterTemplate() {
271 return filterTemplate;
272 }
273
274
275
276
277
278
279 public Map<String, String> getLdapProperties() {
280 return ldapProperties;
281 }
282
283
284
285
286
287
288 public String getLdapUrl() {
289 return ldapConfig.getLdapUrl();
290 }
291
292
293
294
295
296
297 public ConnectionStrategy getConnectionStrategy() {
298 return connStrategy;
299 }
300
301
302
303
304
305
306 public int getMaximumCachedElements() {
307 return maximumCachedElements;
308 }
309
310
311
312
313
314
315 public int getMaxResultSize() {
316 return (int) ldapConfig.getCountLimit();
317 }
318
319
320 public Class<?> getObjectType() {
321 return LdapDataConnector.class;
322 }
323
324
325
326
327
328
329 public LdapPoolStrategy getPoolStrategy() {
330 return ldapPoolStrategy;
331 }
332
333
334
335
336
337
338 public LdapValidator getPoolValidator() {
339 return ldapValidator;
340 }
341
342
343
344
345
346
347 public String getPrincipal() {
348 return ldapConfig.getBindDn();
349 }
350
351
352
353
354
355
356 public String getPrincipalCredential() {
357 return (String) ldapConfig.getBindCredential();
358 }
359
360
361
362
363
364
365 public List<String> getReturnAttributes() {
366 return returnAttributes;
367 }
368
369
370
371
372
373
374 public SearchScope getSearchScope() {
375 return ldapConfig.getSearchScope();
376 }
377
378
379
380
381
382
383 public int getSearchTimeLimit() {
384 return ldapConfig.getTimeLimit();
385 }
386
387
388
389
390
391
392 public TemplateEngine getTemplateEngine() {
393 return templateEngine;
394 }
395
396
397
398
399
400
401 public X509Credential getTrustCredential() {
402 return trustCredential;
403 }
404
405
406
407
408
409
410 public boolean getUseStartTLS() {
411 return ldapConfig.isTlsEnabled();
412 }
413
414
415
416
417
418
419 public boolean isLowercaseAttributeNames() {
420 return lowercaseAttributeNames;
421 }
422
423
424
425
426
427
428 public boolean isMergeResults() {
429 return mergeResults;
430 }
431
432
433
434
435
436
437 public boolean isNoResultsIsError() {
438 return noResultsIsError;
439 }
440
441
442
443
444
445
446 public void setAuthenticationType(AUTHENTICATION_TYPE type) {
447 ldapConfig.setAuthtype(type.getAuthTypeName());
448 }
449
450
451
452
453
454
455 public void setBaseDN(String dn) {
456 String trimmedDN = DatatypeHelper.safeTrimOrNullString(dn);
457 if(trimmedDN != null){
458 ldapConfig.setBaseDn(trimmedDN);
459 }else{
460 ldapConfig.setBaseDn("");
461 }
462 }
463
464
465
466
467
468
469 public void setCacheElementTimeToLive(long ttl) {
470 cacheElementTtl = ttl;
471 }
472
473
474
475
476
477
478 public void setCacheManager(CacheManager manager) {
479 cacheManager = manager;
480 }
481
482
483
484
485
486
487 public void setConnectionCredential(X509Credential credential) {
488 connectionCredential = credential;
489 }
490
491
492
493
494
495
496 public void setFilterTemplate(String template) {
497 filterTemplate = DatatypeHelper.safeTrimOrNullString(template);
498 }
499
500
501
502
503
504
505 public void setLdapProperties(Map<String, String> properties) {
506 ldapProperties = properties;
507 }
508
509
510
511
512
513
514 public void setLdapUrl(String url) {
515 ldapConfig.setLdapUrl(DatatypeHelper.safeTrimOrNullString(url));
516 }
517
518
519
520
521
522
523 public void setConnectionStrategy(ConnectionStrategy strategy) {
524 connStrategy = strategy;
525 }
526
527
528
529
530
531
532 public void setLowercaseAttributeNames(boolean lowercase) {
533 lowercaseAttributeNames = lowercase;
534 }
535
536
537
538
539
540
541 public void setMaximumCachedElements(int max) {
542 maximumCachedElements = max;
543 }
544
545
546
547
548
549
550 public void setMaxResultSize(int max) {
551 ldapConfig.setCountLimit(max);
552 }
553
554
555
556
557
558
559 public void setMergeResults(boolean merge) {
560 mergeResults = merge;
561 }
562
563
564
565
566
567
568 public void setNoResultsIsError(boolean isError) {
569 noResultsIsError = isError;
570 }
571
572
573
574
575
576
577 public void setPoolStrategy(LdapPoolStrategy strategy) {
578 ldapPoolStrategy = strategy;
579 }
580
581
582
583
584
585
586 public void setPoolValidator(LdapValidator validator) {
587 ldapValidator = validator;
588 }
589
590
591
592
593
594
595 public void setPrincipal(String principalName) {
596 ldapConfig.setBindDn(DatatypeHelper.safeTrimOrNullString(principalName));
597 }
598
599
600
601
602
603
604 public void setPrincipalCredential(String credential) {
605 ldapConfig.setBindCredential(DatatypeHelper.safeTrimOrNullString(credential));
606 }
607
608
609
610
611
612
613 public void setReturnAttributes(List<String> attributes) {
614 returnAttributes = attributes;
615 }
616
617
618
619
620
621
622 public void setSearchScope(SearchScope scope) {
623 ldapConfig.setSearchScope(scope);
624 }
625
626
627
628
629
630
631 public void setSearchTimeLimit(int timeLimit) {
632 ldapConfig.setTimeLimit(timeLimit);
633 }
634
635
636
637
638
639
640 public void setTemplateEngine(TemplateEngine engine) {
641 templateEngine = engine;
642 }
643
644
645
646
647
648
649 public void setTrustCredential(X509Credential credential) {
650 trustCredential = credential;
651 }
652
653
654
655
656
657
658 public void setUseStartTLS(boolean startTLS) {
659 ldapConfig.setTls(startTLS);
660 }
661 }