001    /*
002     * Copyright 2011-2013 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2011-2013 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    
027    import com.unboundid.asn1.ASN1OctetString;
028    import com.unboundid.util.Mutable;
029    import com.unboundid.util.ThreadSafety;
030    import com.unboundid.util.ThreadSafetyLevel;
031    import com.unboundid.util.Validator;
032    
033    
034    
035    /**
036     * This class provides a data structure that may be used to hold a number of
037     * properties that may be used during processing for a SASL GSSAPI bind
038     * operation.
039     */
040    @Mutable()
041    @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
042    public final class GSSAPIBindRequestProperties
043           implements Serializable
044    {
045      /**
046       * The serial version UID for this serializable class.
047       */
048      private static final long serialVersionUID = -8177334654843710502L;
049    
050    
051    
052      // The password for the GSSAPI bind request.
053      private ASN1OctetString password;
054    
055      // Indicates whether to enable JVM-level debugging for GSSAPI processing.
056      private boolean enableGSSAPIDebugging;
057    
058      // Indicates whether to attempt to renew the client's existing ticket-granting
059      // ticket if authentication uses an existing Kerberos session.
060      private boolean renewTGT;
061    
062      // Indicates whether to require that the credentials be obtained from the
063      // ticket cache such that authentication will fail if the client does not have
064      // an existing Kerberos session.
065      private boolean requireCachedCredentials;
066    
067      // Indicates whether to enable the use of a ticket cache.
068      private boolean useTicketCache;
069    
070      // The authentication ID string for the GSSAPI bind request.
071      private String authenticationID;
072    
073      // The authorization ID string for the GSSAPI bind request, if available.
074      private String authorizationID;
075    
076      // The path to the JAAS configuration file to use for bind processing.
077      private String configFilePath;
078    
079      // The KDC address for the GSSAPI bind request, if available.
080      private String kdcAddress;
081    
082      // The realm for the GSSAPI bind request, if available.
083      private String realm;
084    
085      // The protocol that should be used in the Kerberos service principal for
086      // the server system.
087      private String servicePrincipalProtocol;
088    
089      // The path to the Kerberos ticket cache to use.
090      private String ticketCachePath;
091    
092    
093    
094      /**
095       * Creates a new set of GSSAPI bind request properties with the provided
096       * information.
097       *
098       * @param  authenticationID  The authentication ID for the GSSAPI bind
099       *                           request.  It may be {@code null} if an existing
100       *                           Kerberos session should be used.
101       * @param  password          The password for the GSSAPI bind request.  It may
102       *                           be {@code null} if an existing Kerberos session
103       *                           should be used.
104       */
105      public GSSAPIBindRequestProperties(final String authenticationID,
106                                         final String password)
107      {
108        this(authenticationID, null,
109             (password == null ? null : new ASN1OctetString(password)), null, null,
110             null);
111      }
112    
113    
114    
115      /**
116       * Creates a new set of GSSAPI bind request properties with the provided
117       * information.
118       *
119       * @param  authenticationID  The authentication ID for the GSSAPI bind
120       *                           request.  It may be {@code null} if an existing
121       *                           Kerberos session should be used.
122       * @param  password          The password for the GSSAPI bind request.  It may
123       *                           be {@code null} if an existing Kerberos session
124       *                           should be used.
125       */
126      public GSSAPIBindRequestProperties(final String authenticationID,
127                                         final byte[] password)
128      {
129        this(authenticationID, null,
130             (password == null ? null : new ASN1OctetString(password)), null, null,
131             null);
132      }
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  authorizationID   The authorization ID for the GSSAPI bind request.
144       *                           It may be {@code null} if the authorization ID
145       *                           should be the same as the authentication ID.
146       * @param  password          The password for the GSSAPI bind request.  It may
147       *                           be {@code null} if an existing Kerberos session
148       *                           should be used.
149       * @param  realm             The realm to use for the authentication.  It may
150       *                           be {@code null} to attempt to use the default
151       *                           realm from the system configuration.
152       * @param  kdcAddress        The address of the Kerberos key distribution
153       *                           center.  It may be {@code null} to attempt to use
154       *                           the default KDC from the system configuration.
155       * @param  configFilePath    The path to the JAAS configuration file to use
156       *                           for the authentication processing.  It may be
157       *                           {@code null} to use the default JAAS
158       *                           configuration.
159       */
160      GSSAPIBindRequestProperties(final String authenticationID,
161                                  final String authorizationID,
162                                  final ASN1OctetString password,
163                                  final String realm,
164                                  final String kdcAddress,
165                                  final String configFilePath)
166      {
167        this.authenticationID = authenticationID;
168        this.authorizationID  = authorizationID;
169        this.password         = password;
170        this.realm            = realm;
171        this.kdcAddress       = kdcAddress;
172        this.configFilePath   = configFilePath;
173    
174        servicePrincipalProtocol = "ldap";
175        enableGSSAPIDebugging    = false;
176        renewTGT                 = false;
177        useTicketCache           = true;
178        requireCachedCredentials = false;
179        ticketCachePath          = null;
180      }
181    
182    
183    
184      /**
185       * Retrieves the authentication ID for the GSSAPI bind request, if defined.
186       *
187       * @return  The authentication ID for the GSSAPI bind request, or {@code null}
188       *          if an existing Kerberos session should be used.
189       */
190      public String getAuthenticationID()
191      {
192        return authenticationID;
193      }
194    
195    
196    
197      /**
198       * Sets the authentication ID for the GSSAPI bind request.
199       *
200       * @param  authenticationID  The authentication ID for the GSSAPI bind
201       *                           request.  It may be {@code null} if an existing
202       *                           Kerberos session should be used.
203       */
204      public void setAuthenticationID(final String authenticationID)
205      {
206        this.authenticationID = authenticationID;
207      }
208    
209    
210    
211      /**
212       * Retrieves the authorization ID for the GSSAPI bind request, if defined.
213       *
214       * @return  The authorizationID for the GSSAPI bind request, or {@code null}
215       *          if the authorization ID should be the same as the authentication
216       *          ID.
217       */
218      public String getAuthorizationID()
219      {
220        return authorizationID;
221      }
222    
223    
224    
225      /**
226       * Specifies the authorization ID for the GSSAPI bind request.
227       *
228       * @param  authorizationID  The authorization ID for the GSSAPI bind request.
229       *                          It may be {@code null} if the authorization ID
230       *                          should be the same as the authentication ID.
231       */
232      public void setAuthorizationID(final String authorizationID)
233      {
234        this.authorizationID = authorizationID;
235      }
236    
237    
238    
239      /**
240       * Retrieves the password that should be used for the GSSAPI bind request, if
241       * defined.
242       *
243       * @return  The password that should be used for the GSSAPI bind request, or
244       *          {@code null} if an existing Kerberos session should be used.
245       */
246      public ASN1OctetString getPassword()
247      {
248        return password;
249      }
250    
251    
252    
253      /**
254       * Specifies the password that should be used for the GSSAPI bind request.
255       *
256       * @param  password  The password that should be used for the GSSAPI bind
257       *                   request.  It may be {@code null} if an existing
258       *                   Kerberos session should be used.
259       */
260      public void setPassword(final String password)
261      {
262        if (password == null)
263        {
264          this.password = null;
265        }
266        else
267        {
268          this.password = new ASN1OctetString(password);
269        }
270      }
271    
272    
273    
274      /**
275       * Specifies the password that should be used for the GSSAPI bind request.
276       *
277       * @param  password  The password that should be used for the GSSAPI bind
278       *                   request.  It may be {@code null} if an existing
279       *                   Kerberos session should be used.
280       */
281      public void setPassword(final byte[] password)
282      {
283        if (password == null)
284        {
285          this.password = null;
286        }
287        else
288        {
289          this.password = new ASN1OctetString(password);
290        }
291      }
292    
293    
294    
295      /**
296       * Specifies the password that should be used for the GSSAPI bind request.
297       *
298       * @param  password  The password that should be used for the GSSAPI bind
299       *                   request.  It may be {@code null} if an existing
300       *                   Kerberos session should be used.
301       */
302      public void setPassword(final ASN1OctetString password)
303      {
304        this.password = password;
305      }
306    
307    
308    
309      /**
310       * Retrieves the realm to use for the GSSAPI bind request, if defined.
311       *
312       * @return  The realm to use for the GSSAPI bind request, or {@code null} if
313       *          the request should attempt to use the default realm from the
314       *          system configuration.
315       */
316      public String getRealm()
317      {
318        return realm;
319      }
320    
321    
322    
323      /**
324       * Specifies the realm to use for the GSSAPI bind request.
325       *
326       * @param  realm  The realm to use for the GSSAPI bind request.  It may be
327       *                {@code null} if the request should attempt to use the
328       *                default realm from the system configuration.
329       */
330      public void setRealm(final String realm)
331      {
332        this.realm = realm;
333      }
334    
335    
336    
337      /**
338       * Retrieves the address to use for the Kerberos key distribution center,
339       * if defined.
340       *
341       * @return  The address to use for the Kerberos key distribution center, or
342       *          {@code null} if request should attempt to determine the KDC
343       *          address from the system configuration.
344       */
345      public String getKDCAddress()
346      {
347        return kdcAddress;
348      }
349    
350    
351    
352      /**
353       * Specifies the address to use for the Kerberos key distribution center.
354       *
355       * @param  kdcAddress  The address to use for the Kerberos key distribution
356       *                     center.  It may be {@code null} if the request should
357       *                     attempt to determine the KDC address from the system
358       *                     configuration.
359       */
360      public void setKDCAddress(final String kdcAddress)
361      {
362        this.kdcAddress = kdcAddress;
363      }
364    
365    
366    
367      /**
368       * Retrieves the path to a JAAS configuration file that should be used when
369       * processing the GSSAPI bind request, if defined.
370       *
371       * @return  The path to a JAAS configuration file that should be used when
372       *          processing the GSSAPI bind request, or {@code null} if a JAAS
373       *          configuration file should be automatically constructed for the
374       *          bind request.
375       */
376      public String getConfigFilePath()
377      {
378        return configFilePath;
379      }
380    
381    
382    
383      /**
384       * Specifies the path to a JAAS configuration file that should be used when
385       * processing the GSSAPI bind request.
386       *
387       * @param  configFilePath  The path to a JAAS configuration file that should
388       *                         be used when processing the GSSAPI bind request.
389       *                         It may be {@code null} if a configuration file
390       *                         should be automatically constructed for the bind
391       *                         request.
392       */
393      public void setConfigFilePath(final String configFilePath)
394      {
395        this.configFilePath = configFilePath;
396      }
397    
398    
399    
400      /**
401       * Retrieves the protocol specified in the service principal that the
402       * directory server uses for its communication with the KDC.  The service
403       * principal is usually something like "ldap/directory.example.com", where
404       * "ldap" is the protocol and "directory.example.com" is the fully-qualified
405       * address of the directory server system, but some servers may allow
406       * authentication with a service principal with a protocol other than "ldap".
407       *
408       * @return  The protocol specified in the service principal that the directory
409       *          server uses for its communication with the KDC.
410       */
411      public String getServicePrincipalProtocol()
412      {
413        return servicePrincipalProtocol;
414      }
415    
416    
417    
418      /**
419       * Specifies the protocol specified in the service principal that the
420       * directory server uses for its communication with the KDC.  This should
421       * generally be "ldap", but some servers may allow a service principal with a
422       * protocol other than "ldap".
423       *
424       * @param  servicePrincipalProtocol  The protocol specified in the service
425       *                                   principal that the directory server uses
426       *                                   for its communication with the KDC.
427       */
428      public void setServicePrincipalProtocol(final String servicePrincipalProtocol)
429      {
430        Validator.ensureNotNull(servicePrincipalProtocol);
431    
432        this.servicePrincipalProtocol = servicePrincipalProtocol;
433      }
434    
435    
436    
437      /**
438       * Indicates whether to enable the use of a ticket cache to to avoid the need
439       * to supply credentials if the client already has an existing Kerberos
440       * session.
441       *
442       * @return  {@code true} if a ticket cache may be used to take advantage of an
443       *          existing Kerberos session, or {@code false} if Kerberos
444       *          credentials should always be provided.
445       */
446      public boolean useTicketCache()
447      {
448        return useTicketCache;
449      }
450    
451    
452    
453      /**
454       * Specifies whether to enable the use of a ticket cache to to avoid the need
455       * to supply credentials if the client already has an existing Kerberos
456       * session.
457       *
458       * @param  useTicketCache  Indicates whether to enable the use of a ticket
459       *                         cache to to avoid the need to supply credentials if
460       *                         the client already has an existing Kerberos
461       *                         session.
462       */
463      public void setUseTicketCache(final boolean useTicketCache)
464      {
465        this.useTicketCache = useTicketCache;
466      }
467    
468    
469    
470      /**
471       * Indicates whether GSSAPI authentication should only occur using an existing
472       * Kerberos session.
473       *
474       * @return  {@code true} if GSSAPI authentication should only use an existing
475       *          Kerberos session and should fail if the client does not have an
476       *          existing session, or {@code false} if the client will be allowed
477       *          to create a new session if one does not already exist.
478       */
479      public boolean requireCachedCredentials()
480      {
481        return requireCachedCredentials;
482      }
483    
484    
485    
486      /**
487       * Specifies whether an GSSAPI authentication should only occur using an
488       * existing Kerberos session.
489       *
490       * @param  requireCachedCredentials  Indicates whether an existing Kerberos
491       *                                   session will be required for
492       *                                   authentication.  If {@code true}, then
493       *                                   authentication will fail if the client
494       *                                   does not already have an existing
495       *                                   Kerberos session.  This will be ignored
496       *                                   if {@code useTicketCache} is false.
497       */
498      public void setRequireCachedCredentials(
499                       final boolean requireCachedCredentials)
500      {
501        this.requireCachedCredentials = requireCachedCredentials;
502      }
503    
504    
505    
506      /**
507       * Retrieves the path to the Kerberos ticket cache file that should be used
508       * during authentication, if defined.
509       *
510       * @return  The path to the Kerberos ticket cache file that should be used
511       *          during authentication, or {@code null} if the default ticket cache
512       *          file should be used.
513       */
514      public String getTicketCachePath()
515      {
516        return ticketCachePath;
517      }
518    
519    
520    
521      /**
522       * Specifies the path to the Kerberos ticket cache file that should be used
523       * during authentication.
524       *
525       * @param  ticketCachePath  The path to the Kerberos ticket cache file that
526       *                          should be used during authentication.  It may be
527       *                          {@code null} if the default ticket cache file
528       *                          should be used.
529       */
530      public void setTicketCachePath(final String ticketCachePath)
531      {
532        this.ticketCachePath = ticketCachePath;
533      }
534    
535    
536    
537      /**
538       * Indicates whether to attempt to renew the client's ticket-granting ticket
539       * (TGT) if an existing Kerberos session is used to authenticate.
540       *
541       * @return  {@code true} if the client should attempt to renew its
542       *          ticket-granting ticket if the authentication is processed using an
543       *          existing Kerberos session, or {@code false} if not.
544       */
545      public boolean renewTGT()
546      {
547        return renewTGT;
548      }
549    
550    
551    
552      /**
553       * Specifies whether to attempt to renew the client's ticket-granting ticket
554       * (TGT) if an existing Kerberos session is used to authenticate.
555       *
556       * @param  renewTGT  Indicates whether to attempt to renew the client's
557       *                   ticket-granting ticket if an existing Kerberos session is
558       *                   used to authenticate.
559       */
560      public void setRenewTGT(final boolean renewTGT)
561      {
562        this.renewTGT = renewTGT;
563      }
564    
565    
566    
567      /**
568       * Indicates whether JVM-level debugging should be enabled for GSSAPI bind
569       * processing.  If this is enabled, then debug information may be written to
570       * standard error when performing GSSAPI processing that could be useful for
571       * debugging authentication problems.
572       *
573       * @return  {@code true} if JVM-level debugging should be enabled for GSSAPI
574       *          bind processing, or {@code false} if not.
575       */
576      public boolean enableGSSAPIDebugging()
577      {
578        return enableGSSAPIDebugging;
579      }
580    
581    
582    
583      /**
584       * Specifies whether JVM-level debugging should be enabled for GSSAPI bind
585       * processing.  If this is enabled, then debug information may be written to
586       * standard error when performing GSSAPI processing that could be useful for
587       * debugging authentication problems.
588       *
589       * @param  enableGSSAPIDebugging  Specifies whether JVM-level debugging should
590       *                                be enabled for GSSAPI bind processing.
591       */
592      public void setEnableGSSAPIDebugging(final boolean enableGSSAPIDebugging)
593      {
594        this.enableGSSAPIDebugging = enableGSSAPIDebugging;
595      }
596    
597    
598    
599      /**
600       * Retrieves a string representation of the GSSAPI bind request properties.
601       *
602       * @return  A string representation of the GSSAPI bind request properties.
603       */
604      @Override()
605      public String toString()
606      {
607        final StringBuilder buffer = new StringBuilder();
608        toString(buffer);
609        return buffer.toString();
610      }
611    
612    
613    
614      /**
615       * Appends a string representation of the GSSAPI bind request properties to
616       * the provided buffer.
617       *
618       * @param  buffer  The buffer to which the information should be appended.
619       */
620      public void toString(final StringBuilder buffer)
621      {
622        buffer.append("GSSAPIBindRequestProperties(");
623        if (authenticationID != null)
624        {
625          buffer.append("authenticationID='");
626          buffer.append(authenticationID);
627          buffer.append("', ");
628        }
629    
630        if (authorizationID != null)
631        {
632          buffer.append("authorizationID='");
633          buffer.append(authorizationID);
634          buffer.append("', ");
635        }
636    
637        if (realm != null)
638        {
639          buffer.append("realm='");
640          buffer.append(realm);
641          buffer.append("', ");
642        }
643    
644        if (kdcAddress != null)
645        {
646          buffer.append("kdcAddress='");
647          buffer.append(kdcAddress);
648          buffer.append("', ");
649        }
650    
651        if (useTicketCache)
652        {
653          buffer.append("useTicketCache=true, requireCachedCredentials=");
654          buffer.append(requireCachedCredentials);
655          buffer.append(", renewTGT=");
656          buffer.append(renewTGT);
657          buffer.append(", ");
658    
659          if (ticketCachePath != null)
660          {
661            buffer.append("ticketCachePath='");
662            buffer.append(ticketCachePath);
663            buffer.append("', ");
664          }
665        }
666        else
667        {
668          buffer.append("useTicketCache=false, ");
669        }
670    
671        if (configFilePath != null)
672        {
673          buffer.append("configFilePath='");
674          buffer.append(configFilePath);
675          buffer.append("', ");
676        }
677    
678        buffer.append("servicePrincipalProtocol='");
679        buffer.append(servicePrincipalProtocol);
680        buffer.append("', enableGSSAPIDebugging=");
681        buffer.append(enableGSSAPIDebugging);
682        buffer.append(')');
683      }
684    }