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