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