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