001 /*
002 * Copyright 2011-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2011-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk;
022
023
024
025 import java.io.Serializable;
026 import java.util.ArrayList;
027 import java.util.Arrays;
028 import java.util.Collections;
029 import java.util.List;
030
031 import com.unboundid.asn1.ASN1OctetString;
032 import com.unboundid.util.Mutable;
033 import com.unboundid.util.StaticUtils;
034 import com.unboundid.util.ThreadSafety;
035 import com.unboundid.util.ThreadSafetyLevel;
036 import com.unboundid.util.Validator;
037
038
039
040 /**
041 * This class provides a data structure that may be used to hold a number of
042 * properties that may be used during processing for a SASL GSSAPI bind
043 * operation.
044 */
045 @Mutable()
046 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
047 public final class GSSAPIBindRequestProperties
048 implements Serializable
049 {
050 /**
051 * The serial version UID for this serializable class.
052 */
053 private static final long serialVersionUID = 6872295509330315713L;
054
055
056
057 // The password for the GSSAPI bind request.
058 private ASN1OctetString password;
059
060 // Indicates whether to enable JVM-level debugging for GSSAPI processing.
061 private boolean enableGSSAPIDebugging;
062
063 // Indicates whether to attempt to renew the client's existing ticket-granting
064 // ticket if authentication uses an existing Kerberos session.
065 private boolean renewTGT;
066
067 // Indicates whether to require that the credentials be obtained from the
068 // ticket cache such that authentication will fail if the client does not have
069 // an existing Kerberos session.
070 private boolean requireCachedCredentials;
071
072 // Indicates whether to enable the use of a ticket cache.
073 private boolean useTicketCache;
074
075 // The SASL quality of protection value(s) allowed for the DIGEST-MD5 bind
076 // request.
077 private List<SASLQualityOfProtection> allowedQoP;
078
079 // The authentication ID string for the GSSAPI bind request.
080 private String authenticationID;
081
082 // The authorization ID string for the GSSAPI bind request, if available.
083 private String authorizationID;
084
085 // The path to the JAAS configuration file to use for bind processing.
086 private String configFilePath;
087
088 // The KDC address for the GSSAPI bind request, if available.
089 private String kdcAddress;
090
091 // The realm for the GSSAPI bind request, if available.
092 private String realm;
093
094 // The server name to use when creating the SASL client.
095 private String saslClientServerName;
096
097 // The protocol that should be used in the Kerberos service principal for
098 // the server system.
099 private String servicePrincipalProtocol;
100
101 // The path to the Kerberos ticket cache to use.
102 private String ticketCachePath;
103
104
105
106 /**
107 * Creates a new set of GSSAPI bind request properties with the provided
108 * information.
109 *
110 * @param authenticationID The authentication ID for the GSSAPI bind
111 * request. It may be {@code null} if an existing
112 * Kerberos session should be used.
113 * @param password The password for the GSSAPI bind request. It may
114 * be {@code null} if an existing Kerberos session
115 * should be used.
116 */
117 public GSSAPIBindRequestProperties(final String authenticationID,
118 final String password)
119 {
120 this(authenticationID, null,
121 (password == null ? null : new ASN1OctetString(password)), null, null,
122 null);
123 }
124
125
126
127 /**
128 * Creates a new set of GSSAPI bind request properties with the provided
129 * information.
130 *
131 * @param authenticationID The authentication ID for the GSSAPI bind
132 * request. It may be {@code null} if an existing
133 * Kerberos session should be used.
134 * @param password The password for the GSSAPI bind request. It may
135 * be {@code null} if an existing Kerberos session
136 * should be used.
137 */
138 public GSSAPIBindRequestProperties(final String authenticationID,
139 final byte[] password)
140 {
141 this(authenticationID, null,
142 (password == null ? null : new ASN1OctetString(password)), null, null,
143 null);
144 }
145
146
147
148 /**
149 * Creates a new set of GSSAPI bind request properties with the provided
150 * information.
151 *
152 * @param authenticationID The authentication ID for the GSSAPI bind
153 * request. It may be {@code null} if an existing
154 * Kerberos session should be used.
155 * @param authorizationID The authorization ID for the GSSAPI bind request.
156 * It may be {@code null} if the authorization ID
157 * should be the same as the authentication ID.
158 * @param password The password for the GSSAPI bind request. It may
159 * be {@code null} if an existing Kerberos session
160 * should be used.
161 * @param realm The realm to use for the authentication. It may
162 * be {@code null} to attempt to use the default
163 * realm from the system configuration.
164 * @param kdcAddress The address of the Kerberos key distribution
165 * center. It may be {@code null} to attempt to use
166 * the default KDC from the system configuration.
167 * @param configFilePath The path to the JAAS configuration file to use
168 * for the authentication processing. It may be
169 * {@code null} to use the default JAAS
170 * configuration.
171 */
172 GSSAPIBindRequestProperties(final String authenticationID,
173 final String authorizationID,
174 final ASN1OctetString password,
175 final String realm,
176 final String kdcAddress,
177 final String configFilePath)
178 {
179 this.authenticationID = authenticationID;
180 this.authorizationID = authorizationID;
181 this.password = password;
182 this.realm = realm;
183 this.kdcAddress = kdcAddress;
184 this.configFilePath = configFilePath;
185
186 servicePrincipalProtocol = "ldap";
187 enableGSSAPIDebugging = false;
188 renewTGT = false;
189 useTicketCache = true;
190 requireCachedCredentials = false;
191 saslClientServerName = null;
192 ticketCachePath = null;
193 allowedQoP = Collections.unmodifiableList(Arrays.asList(
194 SASLQualityOfProtection.AUTH));
195 }
196
197
198
199 /**
200 * Retrieves the authentication ID for the GSSAPI bind request, if defined.
201 *
202 * @return The authentication ID for the GSSAPI bind request, or {@code null}
203 * if an existing Kerberos session should be used.
204 */
205 public String getAuthenticationID()
206 {
207 return authenticationID;
208 }
209
210
211
212 /**
213 * Sets the authentication ID for the GSSAPI bind request.
214 *
215 * @param authenticationID The authentication ID for the GSSAPI bind
216 * request. It may be {@code null} if an existing
217 * Kerberos session should be used.
218 */
219 public void setAuthenticationID(final String authenticationID)
220 {
221 this.authenticationID = authenticationID;
222 }
223
224
225
226 /**
227 * Retrieves the authorization ID for the GSSAPI bind request, if defined.
228 *
229 * @return The authorizationID for the GSSAPI bind request, or {@code null}
230 * if the authorization ID should be the same as the authentication
231 * ID.
232 */
233 public String getAuthorizationID()
234 {
235 return authorizationID;
236 }
237
238
239
240 /**
241 * Specifies the authorization ID for the GSSAPI bind request.
242 *
243 * @param authorizationID The authorization ID for the GSSAPI bind request.
244 * It may be {@code null} if the authorization ID
245 * should be the same as the authentication ID.
246 */
247 public void setAuthorizationID(final String authorizationID)
248 {
249 this.authorizationID = authorizationID;
250 }
251
252
253
254 /**
255 * Retrieves the password that should be used for the GSSAPI bind request, if
256 * defined.
257 *
258 * @return The password that should be used for the GSSAPI bind request, or
259 * {@code null} if an existing Kerberos session should be used.
260 */
261 public ASN1OctetString getPassword()
262 {
263 return password;
264 }
265
266
267
268 /**
269 * Specifies the password that should be used for the GSSAPI bind request.
270 *
271 * @param password The password that should be used for the GSSAPI bind
272 * request. It may be {@code null} if an existing
273 * Kerberos session should be used.
274 */
275 public void setPassword(final String password)
276 {
277 if (password == null)
278 {
279 this.password = null;
280 }
281 else
282 {
283 this.password = new ASN1OctetString(password);
284 }
285 }
286
287
288
289 /**
290 * Specifies the password that should be used for the GSSAPI bind request.
291 *
292 * @param password The password that should be used for the GSSAPI bind
293 * request. It may be {@code null} if an existing
294 * Kerberos session should be used.
295 */
296 public void setPassword(final byte[] password)
297 {
298 if (password == null)
299 {
300 this.password = null;
301 }
302 else
303 {
304 this.password = new ASN1OctetString(password);
305 }
306 }
307
308
309
310 /**
311 * Specifies the password that should be used for the GSSAPI bind request.
312 *
313 * @param password The password that should be used for the GSSAPI bind
314 * request. It may be {@code null} if an existing
315 * Kerberos session should be used.
316 */
317 public void setPassword(final ASN1OctetString password)
318 {
319 this.password = password;
320 }
321
322
323
324 /**
325 * Retrieves the realm to use for the GSSAPI bind request, if defined.
326 *
327 * @return The realm to use for the GSSAPI bind request, or {@code null} if
328 * the request should attempt to use the default realm from the
329 * system configuration.
330 */
331 public String getRealm()
332 {
333 return realm;
334 }
335
336
337
338 /**
339 * Specifies the realm to use for the GSSAPI bind request.
340 *
341 * @param realm The realm to use for the GSSAPI bind request. It may be
342 * {@code null} if the request should attempt to use the
343 * default realm from the system configuration.
344 */
345 public void setRealm(final String realm)
346 {
347 this.realm = realm;
348 }
349
350
351
352 /**
353 * Retrieves the list of allowed qualities of protection that may be used for
354 * communication that occurs on the connection after the authentication has
355 * completed, in order from most preferred to least preferred.
356 *
357 * @return The list of allowed qualities of protection that may be used for
358 * communication that occurs on the connection after the
359 * authentication has completed, in order from most preferred to
360 * least preferred.
361 */
362 public List<SASLQualityOfProtection> getAllowedQoP()
363 {
364 return allowedQoP;
365 }
366
367
368
369 /**
370 * Specifies the list of allowed qualities of protection that may be used for
371 * communication that occurs on the connection after the authentication has
372 * completed, in order from most preferred to least preferred.
373 *
374 * @param allowedQoP The list of allowed qualities of protection that may be
375 * used for communication that occurs on the connection
376 * after the authentication has completed, in order from
377 * most preferred to least preferred. If this is
378 * {@code null} or empty, then a list containing only the
379 * {@link SASLQualityOfProtection#AUTH} quality of
380 * protection value will be used.
381 */
382 public void setAllowedQoP(final List<SASLQualityOfProtection> allowedQoP)
383 {
384 if ((allowedQoP == null) || allowedQoP.isEmpty())
385 {
386 this.allowedQoP = Collections.unmodifiableList(Arrays.asList(
387 SASLQualityOfProtection.AUTH));
388 }
389 else
390 {
391 this.allowedQoP = Collections.unmodifiableList(
392 new ArrayList<SASLQualityOfProtection>(allowedQoP));
393 }
394 }
395
396
397
398 /**
399 * Specifies the list of allowed qualities of protection that may be used for
400 * communication that occurs on the connection after the authentication has
401 * completed, in order from most preferred to least preferred.
402 *
403 * @param allowedQoP The list of allowed qualities of protection that may be
404 * used for communication that occurs on the connection
405 * after the authentication has completed, in order from
406 * most preferred to least preferred. If this is
407 * {@code null} or empty, then a list containing only the
408 * {@link SASLQualityOfProtection#AUTH} quality of
409 * protection value will be used.
410 */
411 public void setAllowedQoP(final SASLQualityOfProtection... allowedQoP)
412 {
413 setAllowedQoP(StaticUtils.toList(allowedQoP));
414 }
415
416
417
418 /**
419 * Retrieves the address to use for the Kerberos key distribution center,
420 * if defined.
421 *
422 * @return The address to use for the Kerberos key distribution center, or
423 * {@code null} if request should attempt to determine the KDC
424 * address from the system configuration.
425 */
426 public String getKDCAddress()
427 {
428 return kdcAddress;
429 }
430
431
432
433 /**
434 * Specifies the address to use for the Kerberos key distribution center.
435 *
436 * @param kdcAddress The address to use for the Kerberos key distribution
437 * center. It may be {@code null} if the request should
438 * attempt to determine the KDC address from the system
439 * configuration.
440 */
441 public void setKDCAddress(final String kdcAddress)
442 {
443 this.kdcAddress = kdcAddress;
444 }
445
446
447
448 /**
449 * Retrieves the path to a JAAS configuration file that should be used when
450 * processing the GSSAPI bind request, if defined.
451 *
452 * @return The path to a JAAS configuration file that should be used when
453 * processing the GSSAPI bind request, or {@code null} if a JAAS
454 * configuration file should be automatically constructed for the
455 * bind request.
456 */
457 public String getConfigFilePath()
458 {
459 return configFilePath;
460 }
461
462
463
464 /**
465 * Specifies the path to a JAAS configuration file that should be used when
466 * processing the GSSAPI bind request.
467 *
468 * @param configFilePath The path to a JAAS configuration file that should
469 * be used when processing the GSSAPI bind request.
470 * It may be {@code null} if a configuration file
471 * should be automatically constructed for the bind
472 * request.
473 */
474 public void setConfigFilePath(final String configFilePath)
475 {
476 this.configFilePath = configFilePath;
477 }
478
479
480
481 /**
482 * Retrieves the server name that should be used when creating the Java
483 * {@code SaslClient}, if one is defined.
484 *
485 * @return The server name that should be used when creating the Java
486 * {@code SaslClient}, or {@code null} if none is defined and the
487 * {@code SaslClient} should use the address specified when
488 * establishing the connection.
489 */
490 public String getSASLClientServerName()
491 {
492 return saslClientServerName;
493 }
494
495
496
497 /**
498 * Specifies the server name that should be used when creating the Java
499 * {@code SaslClient}.
500 *
501 * @param saslClientServerName The server name that should be used when
502 * creating the Java {@code SaslClient}. It may
503 * be {@code null} to indicate that the
504 * {@code SaslClient} should be created with the
505 *
506 */
507 public void setSASLClientServerName(final String saslClientServerName)
508 {
509 this.saslClientServerName = saslClientServerName;
510 }
511
512
513
514 /**
515 * Retrieves the protocol specified in the service principal that the
516 * directory server uses for its communication with the KDC. The service
517 * principal is usually something like "ldap/directory.example.com", where
518 * "ldap" is the protocol and "directory.example.com" is the fully-qualified
519 * address of the directory server system, but some servers may allow
520 * authentication with a service principal with a protocol other than "ldap".
521 *
522 * @return The protocol specified in the service principal that the directory
523 * server uses for its communication with the KDC.
524 */
525 public String getServicePrincipalProtocol()
526 {
527 return servicePrincipalProtocol;
528 }
529
530
531
532 /**
533 * Specifies the protocol specified in the service principal that the
534 * directory server uses for its communication with the KDC. This should
535 * generally be "ldap", but some servers may allow a service principal with a
536 * protocol other than "ldap".
537 *
538 * @param servicePrincipalProtocol The protocol specified in the service
539 * principal that the directory server uses
540 * for its communication with the KDC.
541 */
542 public void setServicePrincipalProtocol(final String servicePrincipalProtocol)
543 {
544 Validator.ensureNotNull(servicePrincipalProtocol);
545
546 this.servicePrincipalProtocol = servicePrincipalProtocol;
547 }
548
549
550
551 /**
552 * Indicates whether to enable the use of a ticket cache to to avoid the need
553 * to supply credentials if the client already has an existing Kerberos
554 * session.
555 *
556 * @return {@code true} if a ticket cache may be used to take advantage of an
557 * existing Kerberos session, or {@code false} if Kerberos
558 * credentials should always be provided.
559 */
560 public boolean useTicketCache()
561 {
562 return useTicketCache;
563 }
564
565
566
567 /**
568 * Specifies whether to enable the use of a ticket cache to to avoid the need
569 * to supply credentials if the client already has an existing Kerberos
570 * session.
571 *
572 * @param useTicketCache Indicates whether to enable the use of a ticket
573 * cache to to avoid the need to supply credentials if
574 * the client already has an existing Kerberos
575 * session.
576 */
577 public void setUseTicketCache(final boolean useTicketCache)
578 {
579 this.useTicketCache = useTicketCache;
580 }
581
582
583
584 /**
585 * Indicates whether GSSAPI authentication should only occur using an existing
586 * Kerberos session.
587 *
588 * @return {@code true} if GSSAPI authentication should only use an existing
589 * Kerberos session and should fail if the client does not have an
590 * existing session, or {@code false} if the client will be allowed
591 * to create a new session if one does not already exist.
592 */
593 public boolean requireCachedCredentials()
594 {
595 return requireCachedCredentials;
596 }
597
598
599
600 /**
601 * Specifies whether an GSSAPI authentication should only occur using an
602 * existing Kerberos session.
603 *
604 * @param requireCachedCredentials Indicates whether an existing Kerberos
605 * session will be required for
606 * authentication. If {@code true}, then
607 * authentication will fail if the client
608 * does not already have an existing
609 * Kerberos session. This will be ignored
610 * if {@code useTicketCache} is false.
611 */
612 public void setRequireCachedCredentials(
613 final boolean requireCachedCredentials)
614 {
615 this.requireCachedCredentials = requireCachedCredentials;
616 }
617
618
619
620 /**
621 * Retrieves the path to the Kerberos ticket cache file that should be used
622 * during authentication, if defined.
623 *
624 * @return The path to the Kerberos ticket cache file that should be used
625 * during authentication, or {@code null} if the default ticket cache
626 * file should be used.
627 */
628 public String getTicketCachePath()
629 {
630 return ticketCachePath;
631 }
632
633
634
635 /**
636 * Specifies the path to the Kerberos ticket cache file that should be used
637 * during authentication.
638 *
639 * @param ticketCachePath The path to the Kerberos ticket cache file that
640 * should be used during authentication. It may be
641 * {@code null} if the default ticket cache file
642 * should be used.
643 */
644 public void setTicketCachePath(final String ticketCachePath)
645 {
646 this.ticketCachePath = ticketCachePath;
647 }
648
649
650
651 /**
652 * Indicates whether to attempt to renew the client's ticket-granting ticket
653 * (TGT) if an existing Kerberos session is used to authenticate.
654 *
655 * @return {@code true} if the client should attempt to renew its
656 * ticket-granting ticket if the authentication is processed using an
657 * existing Kerberos session, or {@code false} if not.
658 */
659 public boolean renewTGT()
660 {
661 return renewTGT;
662 }
663
664
665
666 /**
667 * Specifies whether to attempt to renew the client's ticket-granting ticket
668 * (TGT) if an existing Kerberos session is used to authenticate.
669 *
670 * @param renewTGT Indicates whether to attempt to renew the client's
671 * ticket-granting ticket if an existing Kerberos session is
672 * used to authenticate.
673 */
674 public void setRenewTGT(final boolean renewTGT)
675 {
676 this.renewTGT = renewTGT;
677 }
678
679
680
681 /**
682 * Indicates whether JVM-level debugging should be enabled for GSSAPI bind
683 * processing. If this is enabled, then debug information may be written to
684 * standard error when performing GSSAPI processing that could be useful for
685 * debugging authentication problems.
686 *
687 * @return {@code true} if JVM-level debugging should be enabled for GSSAPI
688 * bind processing, or {@code false} if not.
689 */
690 public boolean enableGSSAPIDebugging()
691 {
692 return enableGSSAPIDebugging;
693 }
694
695
696
697 /**
698 * Specifies whether JVM-level debugging should be enabled for GSSAPI bind
699 * processing. If this is enabled, then debug information may be written to
700 * standard error when performing GSSAPI processing that could be useful for
701 * debugging authentication problems.
702 *
703 * @param enableGSSAPIDebugging Specifies whether JVM-level debugging should
704 * be enabled for GSSAPI bind processing.
705 */
706 public void setEnableGSSAPIDebugging(final boolean enableGSSAPIDebugging)
707 {
708 this.enableGSSAPIDebugging = enableGSSAPIDebugging;
709 }
710
711
712
713 /**
714 * Retrieves a string representation of the GSSAPI bind request properties.
715 *
716 * @return A string representation of the GSSAPI bind request properties.
717 */
718 @Override()
719 public String toString()
720 {
721 final StringBuilder buffer = new StringBuilder();
722 toString(buffer);
723 return buffer.toString();
724 }
725
726
727
728 /**
729 * Appends a string representation of the GSSAPI bind request properties to
730 * the provided buffer.
731 *
732 * @param buffer The buffer to which the information should be appended.
733 */
734 public void toString(final StringBuilder buffer)
735 {
736 buffer.append("GSSAPIBindRequestProperties(");
737 if (authenticationID != null)
738 {
739 buffer.append("authenticationID='");
740 buffer.append(authenticationID);
741 buffer.append("', ");
742 }
743
744 if (authorizationID != null)
745 {
746 buffer.append("authorizationID='");
747 buffer.append(authorizationID);
748 buffer.append("', ");
749 }
750
751 if (realm != null)
752 {
753 buffer.append("realm='");
754 buffer.append(realm);
755 buffer.append("', ");
756 }
757
758 buffer.append("qop='");
759 buffer.append(SASLQualityOfProtection.toString(allowedQoP));
760 buffer.append("', ");
761
762 if (kdcAddress != null)
763 {
764 buffer.append("kdcAddress='");
765 buffer.append(kdcAddress);
766 buffer.append("', ");
767 }
768
769 if (useTicketCache)
770 {
771 buffer.append("useTicketCache=true, requireCachedCredentials=");
772 buffer.append(requireCachedCredentials);
773 buffer.append(", renewTGT=");
774 buffer.append(renewTGT);
775 buffer.append(", ");
776
777 if (ticketCachePath != null)
778 {
779 buffer.append("ticketCachePath='");
780 buffer.append(ticketCachePath);
781 buffer.append("', ");
782 }
783 }
784 else
785 {
786 buffer.append("useTicketCache=false, ");
787 }
788
789 if (configFilePath != null)
790 {
791 buffer.append("configFilePath='");
792 buffer.append(configFilePath);
793 buffer.append("', ");
794 }
795
796 if (saslClientServerName != null)
797 {
798 buffer.append("saslClientServerName='");
799 buffer.append(saslClientServerName);
800 buffer.append("', ");
801 }
802
803 buffer.append("servicePrincipalProtocol='");
804 buffer.append(servicePrincipalProtocol);
805 buffer.append("', enableGSSAPIDebugging=");
806 buffer.append(enableGSSAPIDebugging);
807 buffer.append(')');
808 }
809 }