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