001/*
002 * Copyright 2011-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2011-2019 Ping Identity Corporation
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 */
021package com.unboundid.ldap.sdk;
022
023
024
025import java.io.Serializable;
026import java.util.ArrayList;
027import java.util.Collection;
028import java.util.Collections;
029import java.util.Iterator;
030import java.util.LinkedHashSet;
031import java.util.List;
032import java.util.Set;
033
034import com.unboundid.asn1.ASN1OctetString;
035import com.unboundid.util.Mutable;
036import com.unboundid.util.StaticUtils;
037import com.unboundid.util.ThreadSafety;
038import com.unboundid.util.ThreadSafetyLevel;
039import com.unboundid.util.Validator;
040
041
042
043/**
044 * This class provides a data structure that may be used to hold a number of
045 * properties that may be used during processing for a SASL GSSAPI bind
046 * operation.
047 */
048@Mutable()
049@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
050public final class GSSAPIBindRequestProperties
051       implements Serializable
052{
053  /**
054   * The serial version UID for this serializable class.
055   */
056  private static final long serialVersionUID = 6872295509330315713L;
057
058
059
060  // The password for the GSSAPI bind request.
061  private ASN1OctetString password;
062
063  // Indicates whether to enable JVM-level debugging for GSSAPI processing.
064  private boolean enableGSSAPIDebugging;
065
066  // Indicates whether the client should be considered the GSSAPI initiator or
067  // the acceptor.
068  private Boolean isInitiator;
069
070  // Indicates whether to attempt to refresh the configuration before the JAAS
071  // login method is called.
072  private boolean refreshKrb5Config;
073
074  // Indicates whether to attempt to renew the client's existing ticket-granting
075  // ticket if authentication uses an existing Kerberos session.
076  private boolean renewTGT;
077
078  // Indicates whether to require that the credentials be obtained from the
079  // ticket cache such that authentication will fail if the client does not have
080  // an existing Kerberos session.
081  private boolean requireCachedCredentials;
082
083  // Indicates whether to allow the to obtain the credentials to be obtained
084  // from a keytab.
085  private boolean useKeyTab;
086
087  // Indicates whether to allow the client to use credentials that are outside
088  // of the current subject.
089  private boolean useSubjectCredentialsOnly;
090
091  // Indicates whether to enable the use of a ticket cache.
092  private boolean useTicketCache;
093
094  // The SASL quality of protection value(s) allowed for the DIGEST-MD5 bind
095  // request.
096  private List<SASLQualityOfProtection> allowedQoP;
097
098  // The names of any system properties that should not be altered by GSSAPI
099  // processing.
100  private Set<String> suppressedSystemProperties;
101
102  // The authentication ID string for the GSSAPI bind request.
103  private String authenticationID;
104
105  // The authorization ID string for the GSSAPI bind request, if available.
106  private String authorizationID;
107
108  // The path to the JAAS configuration file to use for bind processing.
109  private String configFilePath;
110
111  // The name that will be used to identify this client in the JAAS framework.
112  private String jaasClientName;
113
114  // The KDC address for the GSSAPI bind request, if available.
115  private String kdcAddress;
116
117  // The path to the keytab file to use if useKeyTab is true.
118  private String keyTabPath;
119
120  // The realm for the GSSAPI bind request, if available.
121  private String realm;
122
123  // The server name to use when creating the SASL client.
124  private String saslClientServerName;
125
126  // The protocol that should be used in the Kerberos service principal for
127  // the server system.
128  private String servicePrincipalProtocol;
129
130  // The path to the Kerberos ticket cache to use.
131  private String ticketCachePath;
132
133
134
135  /**
136   * Creates a new set of GSSAPI bind request properties with the provided
137   * information.
138   *
139   * @param  authenticationID  The authentication ID for the GSSAPI bind
140   *                           request.  It may be {@code null} if an existing
141   *                           Kerberos session should be used.
142   * @param  password          The password for the GSSAPI bind request.  It may
143   *                           be {@code null} if an existing Kerberos session
144   *                           should be used.
145   */
146  public GSSAPIBindRequestProperties(final String authenticationID,
147                                     final String password)
148  {
149    this(authenticationID, null,
150         (password == null ? null : new ASN1OctetString(password)), null, null,
151         null);
152  }
153
154
155
156  /**
157   * Creates a new set of GSSAPI bind request properties with the provided
158   * information.
159   *
160   * @param  authenticationID  The authentication ID for the GSSAPI bind
161   *                           request.  It may be {@code null} if an existing
162   *                           Kerberos session should be used.
163   * @param  password          The password for the GSSAPI bind request.  It may
164   *                           be {@code null} if an existing Kerberos session
165   *                           should be used.
166   */
167  public GSSAPIBindRequestProperties(final String authenticationID,
168                                     final byte[] password)
169  {
170    this(authenticationID, null,
171         (password == null ? null : new ASN1OctetString(password)), null, null,
172         null);
173  }
174
175
176
177  /**
178   * Creates a new set of GSSAPI bind request properties with the provided
179   * information.
180   *
181   * @param  authenticationID  The authentication ID for the GSSAPI bind
182   *                           request.  It may be {@code null} if an existing
183   *                           Kerberos session should be used.
184   * @param  authorizationID   The authorization ID for the GSSAPI bind request.
185   *                           It may be {@code null} if the authorization ID
186   *                           should be the same as the authentication ID.
187   * @param  password          The password for the GSSAPI bind request.  It may
188   *                           be {@code null} if an existing Kerberos session
189   *                           should be used.
190   * @param  realm             The realm to use for the authentication.  It may
191   *                           be {@code null} to attempt to use the default
192   *                           realm from the system configuration.
193   * @param  kdcAddress        The address of the Kerberos key distribution
194   *                           center.  It may be {@code null} to attempt to use
195   *                           the default KDC from the system configuration.
196   * @param  configFilePath    The path to the JAAS configuration file to use
197   *                           for the authentication processing.  It may be
198   *                           {@code null} to use the default JAAS
199   *                           configuration.
200   */
201  GSSAPIBindRequestProperties(final String authenticationID,
202                              final String authorizationID,
203                              final ASN1OctetString password,
204                              final String realm,
205                              final String kdcAddress,
206                              final String configFilePath)
207  {
208    this.authenticationID = authenticationID;
209    this.authorizationID  = authorizationID;
210    this.password         = password;
211    this.realm            = realm;
212    this.kdcAddress       = kdcAddress;
213    this.configFilePath   = configFilePath;
214
215    servicePrincipalProtocol   = "ldap";
216    enableGSSAPIDebugging      = false;
217    jaasClientName             = "GSSAPIBindRequest";
218    isInitiator                = null;
219    refreshKrb5Config          = false;
220    renewTGT                   = false;
221    useKeyTab                  = false;
222    useSubjectCredentialsOnly  = true;
223    useTicketCache             = true;
224    requireCachedCredentials   = false;
225    saslClientServerName       = null;
226    keyTabPath                 = null;
227    ticketCachePath            = null;
228    suppressedSystemProperties = Collections.emptySet();
229    allowedQoP                 =
230         Collections.singletonList(SASLQualityOfProtection.AUTH);
231  }
232
233
234
235  /**
236   * Retrieves the authentication ID for the GSSAPI bind request, if defined.
237   *
238   * @return  The authentication ID for the GSSAPI bind request, or {@code null}
239   *          if an existing Kerberos session should be used.
240   */
241  public String getAuthenticationID()
242  {
243    return authenticationID;
244  }
245
246
247
248  /**
249   * Sets the authentication ID for the GSSAPI bind request.
250   *
251   * @param  authenticationID  The authentication ID for the GSSAPI bind
252   *                           request.  It may be {@code null} if an existing
253   *                           Kerberos session should be used.
254   */
255  public void setAuthenticationID(final String authenticationID)
256  {
257    this.authenticationID = authenticationID;
258  }
259
260
261
262  /**
263   * Retrieves the authorization ID for the GSSAPI bind request, if defined.
264   *
265   * @return  The authorizationID for the GSSAPI bind request, or {@code null}
266   *          if the authorization ID should be the same as the authentication
267   *          ID.
268   */
269  public String getAuthorizationID()
270  {
271    return authorizationID;
272  }
273
274
275
276  /**
277   * Specifies the authorization ID for the GSSAPI bind request.
278   *
279   * @param  authorizationID  The authorization ID for the GSSAPI bind request.
280   *                          It may be {@code null} if the authorization ID
281   *                          should be the same as the authentication ID.
282   */
283  public void setAuthorizationID(final String authorizationID)
284  {
285    this.authorizationID = authorizationID;
286  }
287
288
289
290  /**
291   * Retrieves the password that should be used for the GSSAPI bind request, if
292   * defined.
293   *
294   * @return  The password that should be used for the GSSAPI bind request, or
295   *          {@code null} if an existing Kerberos session should be used.
296   */
297  public ASN1OctetString getPassword()
298  {
299    return password;
300  }
301
302
303
304  /**
305   * Specifies the password that should be used for the GSSAPI bind request.
306   *
307   * @param  password  The password that should be used for the GSSAPI bind
308   *                   request.  It may be {@code null} if an existing
309   *                   Kerberos session should be used.
310   */
311  public void setPassword(final String password)
312  {
313    if (password == null)
314    {
315      this.password = null;
316    }
317    else
318    {
319      this.password = new ASN1OctetString(password);
320    }
321  }
322
323
324
325  /**
326   * Specifies the password that should be used for the GSSAPI bind request.
327   *
328   * @param  password  The password that should be used for the GSSAPI bind
329   *                   request.  It may be {@code null} if an existing
330   *                   Kerberos session should be used.
331   */
332  public void setPassword(final byte[] password)
333  {
334    if (password == null)
335    {
336      this.password = null;
337    }
338    else
339    {
340      this.password = new ASN1OctetString(password);
341    }
342  }
343
344
345
346  /**
347   * Specifies the password that should be used for the GSSAPI bind request.
348   *
349   * @param  password  The password that should be used for the GSSAPI bind
350   *                   request.  It may be {@code null} if an existing
351   *                   Kerberos session should be used.
352   */
353  public void setPassword(final ASN1OctetString password)
354  {
355    this.password = password;
356  }
357
358
359
360  /**
361   * Retrieves the realm to use for the GSSAPI bind request, if defined.
362   *
363   * @return  The realm to use for the GSSAPI bind request, or {@code null} if
364   *          the request should attempt to use the default realm from the
365   *          system configuration.
366   */
367  public String getRealm()
368  {
369    return realm;
370  }
371
372
373
374  /**
375   * Specifies the realm to use for the GSSAPI bind request.
376   *
377   * @param  realm  The realm to use for the GSSAPI bind request.  It may be
378   *                {@code null} if the request should attempt to use the
379   *                default realm from the system configuration.
380   */
381  public void setRealm(final String realm)
382  {
383    this.realm = realm;
384  }
385
386
387
388  /**
389   * Retrieves the list of allowed qualities of protection that may be used for
390   * communication that occurs on the connection after the authentication has
391   * completed, in order from most preferred to least preferred.
392   *
393   * @return  The list of allowed qualities of protection that may be used for
394   *          communication that occurs on the connection after the
395   *          authentication has completed, in order from most preferred to
396   *          least preferred.
397   */
398  public List<SASLQualityOfProtection> getAllowedQoP()
399  {
400    return allowedQoP;
401  }
402
403
404
405  /**
406   * Specifies the list of allowed qualities of protection that may be used for
407   * communication that occurs on the connection after the authentication has
408   * completed, in order from most preferred to least preferred.
409   *
410   * @param  allowedQoP  The list of allowed qualities of protection that may be
411   *                     used for communication that occurs on the connection
412   *                     after the authentication has completed, in order from
413   *                     most preferred to least preferred.  If this is
414   *                     {@code null} or empty, then a list containing only the
415   *                     {@link SASLQualityOfProtection#AUTH} quality of
416   *                     protection value will be used.
417   */
418  public void setAllowedQoP(final List<SASLQualityOfProtection> allowedQoP)
419  {
420    if ((allowedQoP == null) || allowedQoP.isEmpty())
421    {
422      this.allowedQoP = Collections.singletonList(SASLQualityOfProtection.AUTH);
423    }
424    else
425    {
426      this.allowedQoP =
427           Collections.unmodifiableList(new ArrayList<>(allowedQoP));
428    }
429  }
430
431
432
433  /**
434   * Specifies the list of allowed qualities of protection that may be used for
435   * communication that occurs on the connection after the authentication has
436   * completed, in order from most preferred to least preferred.
437   *
438   * @param  allowedQoP  The list of allowed qualities of protection that may be
439   *                     used for communication that occurs on the connection
440   *                     after the authentication has completed, in order from
441   *                     most preferred to least preferred.  If this is
442   *                     {@code null} or empty, then a list containing only the
443   *                     {@link SASLQualityOfProtection#AUTH} quality of
444   *                     protection value will be used.
445   */
446  public void setAllowedQoP(final SASLQualityOfProtection... allowedQoP)
447  {
448    setAllowedQoP(StaticUtils.toList(allowedQoP));
449  }
450
451
452
453  /**
454   * Retrieves the address to use for the Kerberos key distribution center,
455   * if defined.
456   *
457   * @return  The address to use for the Kerberos key distribution center, or
458   *          {@code null} if request should attempt to determine the KDC
459   *          address from the system configuration.
460   */
461  public String getKDCAddress()
462  {
463    return kdcAddress;
464  }
465
466
467
468  /**
469   * Specifies the address to use for the Kerberos key distribution center.
470   *
471   * @param  kdcAddress  The address to use for the Kerberos key distribution
472   *                     center.  It may be {@code null} if the request should
473   *                     attempt to determine the KDC address from the system
474   *                     configuration.
475   */
476  public void setKDCAddress(final String kdcAddress)
477  {
478    this.kdcAddress = kdcAddress;
479  }
480
481
482
483  /**
484   * Retrieves the name that will be used to identify this client in the JAAS
485   * framework.
486   *
487   * @return  The name that will be used to identify this client in the JAAS
488   *          framework.
489   */
490  public String getJAASClientName()
491  {
492    return jaasClientName;
493  }
494
495
496
497  /**
498   * Specifies the name that will be used to identify this client in the JAAS
499   * framework.
500   *
501   * @param  jaasClientName  The name that will be used to identify this client
502   *                         in the JAAS framework.  It must not be
503   *                         {@code null} or empty.
504   */
505  public void setJAASClientName(final String jaasClientName)
506  {
507    Validator.ensureNotNull(jaasClientName);
508
509    this.jaasClientName = jaasClientName;
510  }
511
512
513
514  /**
515   * Retrieves the path to a JAAS configuration file that should be used when
516   * processing the GSSAPI bind request, if defined.
517   *
518   * @return  The path to a JAAS configuration file that should be used when
519   *          processing the GSSAPI bind request, or {@code null} if a JAAS
520   *          configuration file should be automatically constructed for the
521   *          bind request.
522   */
523  public String getConfigFilePath()
524  {
525    return configFilePath;
526  }
527
528
529
530  /**
531   * Specifies the path to a JAAS configuration file that should be used when
532   * processing the GSSAPI bind request.
533   *
534   * @param  configFilePath  The path to a JAAS configuration file that should
535   *                         be used when processing the GSSAPI bind request.
536   *                         It may be {@code null} if a configuration file
537   *                         should be automatically constructed for the bind
538   *                         request.
539   */
540  public void setConfigFilePath(final String configFilePath)
541  {
542    this.configFilePath = configFilePath;
543  }
544
545
546
547  /**
548   * Retrieves the server name that should be used when creating the Java
549   * {@code SaslClient}, if one is defined.
550   *
551   * @return  The server name that should be used when creating the Java
552   *          {@code SaslClient}, or {@code null} if none is defined and the
553   *          {@code SaslClient} should use the address specified when
554   *          establishing the connection.
555   */
556  public String getSASLClientServerName()
557  {
558    return saslClientServerName;
559  }
560
561
562
563  /**
564   * Specifies the server name that should be used when creating the Java
565   * {@code SaslClient}.
566   *
567   * @param  saslClientServerName  The server name that should be used when
568   *                               creating the Java {@code SaslClient}.  It may
569   *                               be {@code null} to indicate that the
570   *                               {@code SaslClient} should use the address
571   *                               specified when establishing the connection.
572   */
573  public void setSASLClientServerName(final String saslClientServerName)
574  {
575    this.saslClientServerName = saslClientServerName;
576  }
577
578
579
580  /**
581   * Retrieves the protocol specified in the service principal that the
582   * directory server uses for its communication with the KDC.  The service
583   * principal is usually something like "ldap/directory.example.com", where
584   * "ldap" is the protocol and "directory.example.com" is the fully-qualified
585   * address of the directory server system, but some servers may allow
586   * authentication with a service principal with a protocol other than "ldap".
587   *
588   * @return  The protocol specified in the service principal that the directory
589   *          server uses for its communication with the KDC.
590   */
591  public String getServicePrincipalProtocol()
592  {
593    return servicePrincipalProtocol;
594  }
595
596
597
598  /**
599   * Specifies the protocol specified in the service principal that the
600   * directory server uses for its communication with the KDC.  This should
601   * generally be "ldap", but some servers may allow a service principal with a
602   * protocol other than "ldap".
603   *
604   * @param  servicePrincipalProtocol  The protocol specified in the service
605   *                                   principal that the directory server uses
606   *                                   for its communication with the KDC.
607   */
608  public void setServicePrincipalProtocol(final String servicePrincipalProtocol)
609  {
610    Validator.ensureNotNull(servicePrincipalProtocol);
611
612    this.servicePrincipalProtocol = servicePrincipalProtocol;
613  }
614
615
616
617  /**
618   * Indicates whether to refresh the configuration before the JAAS
619   * {@code login} method is called.
620   *
621   * @return  {@code true} if the GSSAPI implementation should refresh the
622   *          configuration before the JAAS {@code login} method is called, or
623   *          {@code false} if not.
624   */
625  public boolean refreshKrb5Config()
626  {
627    return refreshKrb5Config;
628  }
629
630
631
632  /**
633   * Specifies whether to refresh the configuration before the JAAS
634   * {@code login} method is called.
635   *
636   * @param  refreshKrb5Config  Indicates whether to refresh the configuration
637   *                            before the JAAS {@code login} method is called.
638   */
639  public void setRefreshKrb5Config(final boolean refreshKrb5Config)
640  {
641    this.refreshKrb5Config = refreshKrb5Config;
642  }
643
644
645
646  /**
647   * Indicates whether to allow the client to use credentials that are outside
648   * of the current subject, obtained via some system-specific mechanism.
649   *
650   * @return  {@code true} if the client will only be allowed to use credentials
651   *          that are within the current subject, or {@code false} if the
652   *          client will be allowed to use credentials outside the current
653   *          subject.
654   */
655  public boolean useSubjectCredentialsOnly()
656  {
657    return useSubjectCredentialsOnly;
658  }
659
660
661
662  /**
663   * Specifies whether to allow the client to use credentials that are outside
664   * the current subject.  If this is {@code false}, then a system-specific
665   * mechanism may be used in an attempt to obtain credentials from an
666   * existing session.
667   *
668   * @param  useSubjectCredentialsOnly  Indicates whether to allow the client to
669   *                                    use credentials that are outside of the
670   *                                    current subject.
671   */
672  public void setUseSubjectCredentialsOnly(
673                   final boolean useSubjectCredentialsOnly)
674  {
675    this.useSubjectCredentialsOnly = useSubjectCredentialsOnly;
676  }
677
678
679
680  /**
681   * Indicates whether to use a keytab to obtain the user credentials.
682   *
683   * @return  {@code true} if the GSSAPI login attempt should use a keytab to
684   *          obtain the user credentials, or {@code false} if not.
685   */
686  public boolean useKeyTab()
687  {
688    return useKeyTab;
689  }
690
691
692
693  /**
694   * Specifies whether to use a keytab to obtain the user credentials.
695   *
696   * @param  useKeyTab  Indicates whether to use a keytab to obtain the user
697   *                    credentials.
698   */
699  public void setUseKeyTab(final boolean useKeyTab)
700  {
701    this.useKeyTab = useKeyTab;
702  }
703
704
705
706  /**
707   * Retrieves the path to the keytab file from which to obtain the user
708   * credentials.  This will only be used if {@link #useKeyTab} returns
709   * {@code true}.
710   *
711   * @return  The path to the keytab file from which to obtain the user
712   *          credentials, or {@code null} if the default keytab location should
713   *          be used.
714   */
715  public String getKeyTabPath()
716  {
717    return keyTabPath;
718  }
719
720
721
722  /**
723   * Specifies the path to the keytab file from which to obtain the user
724   * credentials.
725   *
726   * @param  keyTabPath  The path to the keytab file from which to obtain the
727   *                     user credentials.  It may be {@code null} if the
728   *                     default keytab location should be used.
729   */
730  public void setKeyTabPath(final String keyTabPath)
731  {
732    this.keyTabPath = keyTabPath;
733  }
734
735
736
737  /**
738   * Indicates whether to enable the use of a ticket cache to to avoid the need
739   * to supply credentials if the client already has an existing Kerberos
740   * session.
741   *
742   * @return  {@code true} if a ticket cache may be used to take advantage of an
743   *          existing Kerberos session, or {@code false} if Kerberos
744   *          credentials should always be provided.
745   */
746  public boolean useTicketCache()
747  {
748    return useTicketCache;
749  }
750
751
752
753  /**
754   * Specifies whether to enable the use of a ticket cache to to avoid the need
755   * to supply credentials if the client already has an existing Kerberos
756   * session.
757   *
758   * @param  useTicketCache  Indicates whether to enable the use of a ticket
759   *                         cache to to avoid the need to supply credentials if
760   *                         the client already has an existing Kerberos
761   *                         session.
762   */
763  public void setUseTicketCache(final boolean useTicketCache)
764  {
765    this.useTicketCache = useTicketCache;
766  }
767
768
769
770  /**
771   * Indicates whether GSSAPI authentication should only occur using an existing
772   * Kerberos session.
773   *
774   * @return  {@code true} if GSSAPI authentication should only use an existing
775   *          Kerberos session and should fail if the client does not have an
776   *          existing session, or {@code false} if the client will be allowed
777   *          to create a new session if one does not already exist.
778   */
779  public boolean requireCachedCredentials()
780  {
781    return requireCachedCredentials;
782  }
783
784
785
786  /**
787   * Specifies whether an GSSAPI authentication should only occur using an
788   * existing Kerberos session.
789   *
790   * @param  requireCachedCredentials  Indicates whether an existing Kerberos
791   *                                   session will be required for
792   *                                   authentication.  If {@code true}, then
793   *                                   authentication will fail if the client
794   *                                   does not already have an existing
795   *                                   Kerberos session.  This will be ignored
796   *                                   if {@code useTicketCache} is false.
797   */
798  public void setRequireCachedCredentials(
799                   final boolean requireCachedCredentials)
800  {
801    this.requireCachedCredentials = requireCachedCredentials;
802  }
803
804
805
806  /**
807   * Retrieves the path to the Kerberos ticket cache file that should be used
808   * during authentication, if defined.
809   *
810   * @return  The path to the Kerberos ticket cache file that should be used
811   *          during authentication, or {@code null} if the default ticket cache
812   *          file should be used.
813   */
814  public String getTicketCachePath()
815  {
816    return ticketCachePath;
817  }
818
819
820
821  /**
822   * Specifies the path to the Kerberos ticket cache file that should be used
823   * during authentication.
824   *
825   * @param  ticketCachePath  The path to the Kerberos ticket cache file that
826   *                          should be used during authentication.  It may be
827   *                          {@code null} if the default ticket cache file
828   *                          should be used.
829   */
830  public void setTicketCachePath(final String ticketCachePath)
831  {
832    this.ticketCachePath = ticketCachePath;
833  }
834
835
836
837  /**
838   * Indicates whether to attempt to renew the client's ticket-granting ticket
839   * (TGT) if an existing Kerberos session is used to authenticate.
840   *
841   * @return  {@code true} if the client should attempt to renew its
842   *          ticket-granting ticket if the authentication is processed using an
843   *          existing Kerberos session, or {@code false} if not.
844   */
845  public boolean renewTGT()
846  {
847    return renewTGT;
848  }
849
850
851
852  /**
853   * Specifies whether to attempt to renew the client's ticket-granting ticket
854   * (TGT) if an existing Kerberos session is used to authenticate.
855   *
856   * @param  renewTGT  Indicates whether to attempt to renew the client's
857   *                   ticket-granting ticket if an existing Kerberos session is
858   *                   used to authenticate.
859   */
860  public void setRenewTGT(final boolean renewTGT)
861  {
862    this.renewTGT = renewTGT;
863  }
864
865
866
867  /**
868   * Indicates whether the client should be configured so that it explicitly
869   * indicates whether it is the initiator or the acceptor.
870   *
871   * @return  {@code Boolean.TRUE} if the client should explicitly indicate that
872   *          it is the GSSAPI initiator, {@code Boolean.FALSE} if the client
873   *          should explicitly indicate that it is the GSSAPI acceptor, or
874   *          {@code null} if the client should not explicitly indicate either
875   *          state (which is the default if the {@link #setIsInitiator}  method
876   *          has not been called).
877   */
878  public Boolean getIsInitiator()
879  {
880    return isInitiator;
881  }
882
883
884
885  /**
886   * Specifies whether the client should explicitly indicate whether it is the
887   * GSSAPI initiator or acceptor.
888   *
889   * @param  isInitiator  Indicates whether the client should be considered the
890   *                      GSSAPI initiator.  A value of {@code Boolean.TRUE}
891   *                      means the client should explicitly indicate that it is
892   *                      the GSSAPI initiator.  A value of
893   *                      {@code Boolean.FALSE} means the client should
894   *                      explicitly indicate that it is the GSSAPI acceptor.  A
895   *                      value of  {@code null} means that the client will not
896   *                      explicitly indicate one way or the other (although
897   *                      this behavior will only apply to Sun/Oracle-based
898   *                      implementations; on the IBM implementation, the client
899   *                      will always be the initiator unless explicitly
900   *                      configured otherwise).
901   */
902  public void setIsInitiator(final Boolean isInitiator)
903  {
904    this.isInitiator = isInitiator;
905  }
906
907
908
909  /**
910   * Retrieves a set of system properties that will not be altered by GSSAPI
911   * processing.
912   *
913   * @return  A set of system properties that will not be altered by GSSAPI
914   *          processing.
915   */
916  public Set<String> getSuppressedSystemProperties()
917  {
918    return suppressedSystemProperties;
919  }
920
921
922
923  /**
924   * Specifies a set of system properties that will not be altered by GSSAPI
925   * processing.  This should generally only be used in cases in which the
926   * specified system properties are known to already be set correctly for the
927   * desired authentication processing.
928   *
929   * @param  suppressedSystemProperties  A set of system properties that will
930   *                                     not be altered by GSSAPI processing.
931   *                                     It may be {@code null} or empty to
932   *                                     indicate that no properties should be
933   *                                     suppressed.
934   */
935  public void setSuppressedSystemProperties(
936                   final Collection<String> suppressedSystemProperties)
937  {
938    if (suppressedSystemProperties == null)
939    {
940      this.suppressedSystemProperties = Collections.emptySet();
941    }
942    else
943    {
944      this.suppressedSystemProperties = Collections.unmodifiableSet(
945           new LinkedHashSet<>(suppressedSystemProperties));
946    }
947  }
948
949
950
951  /**
952   * Indicates whether JVM-level debugging should be enabled for GSSAPI bind
953   * processing.  If this is enabled, then debug information may be written to
954   * standard error when performing GSSAPI processing that could be useful for
955   * debugging authentication problems.
956   *
957   * @return  {@code true} if JVM-level debugging should be enabled for GSSAPI
958   *          bind processing, or {@code false} if not.
959   */
960  public boolean enableGSSAPIDebugging()
961  {
962    return enableGSSAPIDebugging;
963  }
964
965
966
967  /**
968   * Specifies whether JVM-level debugging should be enabled for GSSAPI bind
969   * processing.  If this is enabled, then debug information may be written to
970   * standard error when performing GSSAPI processing that could be useful for
971   * debugging authentication problems.
972   *
973   * @param  enableGSSAPIDebugging  Specifies whether JVM-level debugging should
974   *                                be enabled for GSSAPI bind processing.
975   */
976  public void setEnableGSSAPIDebugging(final boolean enableGSSAPIDebugging)
977  {
978    this.enableGSSAPIDebugging = enableGSSAPIDebugging;
979  }
980
981
982
983  /**
984   * Retrieves a string representation of the GSSAPI bind request properties.
985   *
986   * @return  A string representation of the GSSAPI bind request properties.
987   */
988  @Override()
989  public String toString()
990  {
991    final StringBuilder buffer = new StringBuilder();
992    toString(buffer);
993    return buffer.toString();
994  }
995
996
997
998  /**
999   * Appends a string representation of the GSSAPI bind request properties to
1000   * the provided buffer.
1001   *
1002   * @param  buffer  The buffer to which the information should be appended.
1003   */
1004  public void toString(final StringBuilder buffer)
1005  {
1006    buffer.append("GSSAPIBindRequestProperties(");
1007    if (authenticationID != null)
1008    {
1009      buffer.append("authenticationID='");
1010      buffer.append(authenticationID);
1011      buffer.append("', ");
1012    }
1013
1014    if (authorizationID != null)
1015    {
1016      buffer.append("authorizationID='");
1017      buffer.append(authorizationID);
1018      buffer.append("', ");
1019    }
1020
1021    if (realm != null)
1022    {
1023      buffer.append("realm='");
1024      buffer.append(realm);
1025      buffer.append("', ");
1026    }
1027
1028    buffer.append("qop='");
1029    buffer.append(SASLQualityOfProtection.toString(allowedQoP));
1030    buffer.append("', ");
1031
1032    if (kdcAddress != null)
1033    {
1034      buffer.append("kdcAddress='");
1035      buffer.append(kdcAddress);
1036      buffer.append("', ");
1037    }
1038
1039    buffer.append(", refreshKrb5Config=");
1040    buffer.append(refreshKrb5Config);
1041    buffer.append(", useSubjectCredentialsOnly=");
1042    buffer.append(useSubjectCredentialsOnly);
1043    buffer.append(", useKeyTab=");
1044    buffer.append(useKeyTab);
1045    buffer.append(", ");
1046
1047    if (keyTabPath != null)
1048    {
1049      buffer.append("keyTabPath='");
1050      buffer.append(keyTabPath);
1051      buffer.append("', ");
1052    }
1053
1054    if (useTicketCache)
1055    {
1056      buffer.append("useTicketCache=true, requireCachedCredentials=");
1057      buffer.append(requireCachedCredentials);
1058      buffer.append(", renewTGT=");
1059      buffer.append(renewTGT);
1060      buffer.append(", ");
1061
1062      if (ticketCachePath != null)
1063      {
1064        buffer.append("ticketCachePath='");
1065        buffer.append(ticketCachePath);
1066        buffer.append("', ");
1067      }
1068    }
1069    else
1070    {
1071      buffer.append("useTicketCache=false, ");
1072    }
1073
1074    if (isInitiator != null)
1075    {
1076      buffer.append("isInitiator=");
1077      buffer.append(isInitiator);
1078      buffer.append(", ");
1079    }
1080
1081    buffer.append("jaasClientName='");
1082    buffer.append(jaasClientName);
1083    buffer.append("', ");
1084
1085    if (configFilePath != null)
1086    {
1087      buffer.append("configFilePath='");
1088      buffer.append(configFilePath);
1089      buffer.append("', ");
1090    }
1091
1092    if (saslClientServerName != null)
1093    {
1094      buffer.append("saslClientServerName='");
1095      buffer.append(saslClientServerName);
1096      buffer.append("', ");
1097    }
1098
1099    buffer.append("servicePrincipalProtocol='");
1100    buffer.append(servicePrincipalProtocol);
1101    buffer.append("', suppressedSystemProperties={");
1102
1103    final Iterator<String> propIterator = suppressedSystemProperties.iterator();
1104    while (propIterator.hasNext())
1105    {
1106      buffer.append('\'');
1107      buffer.append(propIterator.next());
1108      buffer.append('\'');
1109
1110      if (propIterator.hasNext())
1111      {
1112        buffer.append(", ");
1113      }
1114    }
1115
1116    buffer.append("}, enableGSSAPIDebugging=");
1117    buffer.append(enableGSSAPIDebugging);
1118    buffer.append(')');
1119  }
1120}