001    /*
002     * Copyright 2011-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2011-2015 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 com.unboundid.asn1.ASN1OctetString;
026    import com.unboundid.util.NotMutable;
027    import com.unboundid.util.ThreadSafety;
028    import com.unboundid.util.ThreadSafetyLevel;
029    import com.unboundid.util.Validator;
030    
031    
032    
033    /**
034     * This class provides a mechanism for performing SASL authentication in a
035     * generic manner.  The caller is responsible for properly encoding the
036     * credentials (if any) and interpreting the result.  Further, if the requested
037     * SASL mechanism is one that requires multiple stages, then the caller is
038     * responsible for all processing in each stage.
039     */
040    @NotMutable()
041    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
042    public final class GenericSASLBindRequest
043           extends SASLBindRequest
044    {
045      /**
046       * The serial version UID for this serializable class.
047       */
048      private static final long serialVersionUID = 7740968332104559230L;
049    
050    
051    
052      // The SASL credentials that should be used for the bind request.
053      private final ASN1OctetString credentials;
054    
055      // The bind DN to use for the bind request.
056      private final String bindDN;
057    
058      // The name of the SASL mechanism that should be used for the bind request.
059      private final String mechanism;
060    
061    
062    
063      /**
064       * Creates a new generic SASL bind request with the provided information.
065       *
066       * @param  bindDN       The bind DN that should be used for the request.  It
067       *                      may be {@code null} if the target identity should be
068       *                      derived from the credentials or some other source.
069       * @param  mechanism    The name of the mechanism that should be used for the
070       *                      SASL bind.  It must not be {@code null}.
071       * @param  credentials  The credentials that should be used for the SASL bind.
072       *                      It may be {@code null} if no credentials should be
073       *                      used.
074       * @param  controls     The set of controls to include in the SASL bind
075       *                      request.  It may be {@code null} or empty if no
076       *                      request controls are needed.
077       */
078      public GenericSASLBindRequest(final String bindDN, final String mechanism,
079                                    final ASN1OctetString credentials,
080                                    final Control... controls)
081      {
082        super(controls);
083    
084        Validator.ensureNotNull(mechanism);
085    
086        this.bindDN      = bindDN;
087        this.mechanism   = mechanism;
088        this.credentials = credentials;
089      }
090    
091    
092    
093      /**
094       * Retrieves the bind DN for this SASL bind request, if any.
095       *
096       * @return  The bind DN for this SASL bind request, or {@code null} if the
097       *          target identity should be determined from the credentials or some
098       *          other mechanism.
099       */
100      public String getBindDN()
101      {
102        return bindDN;
103      }
104    
105    
106    
107      /**
108       * {@inheritDoc}
109       */
110      @Override()
111      public String getSASLMechanismName()
112      {
113        return mechanism;
114      }
115    
116    
117    
118      /**
119       * Retrieves the credentials for the SASL bind request, if any.
120       *
121       * @return  The credentials for the SASL bind request, or {@code null} if
122       *          there are none.
123       */
124      public ASN1OctetString getCredentials()
125      {
126        return credentials;
127      }
128    
129    
130    
131      /**
132       * {@inheritDoc}
133       */
134      @Override()
135      protected BindResult process(final LDAPConnection connection, final int depth)
136                throws LDAPException
137      {
138        return sendBindRequest(connection, bindDN, credentials, getControls(),
139             getResponseTimeoutMillis(connection));
140      }
141    
142    
143    
144      /**
145       * {@inheritDoc}
146       */
147      @Override()
148      public GenericSASLBindRequest duplicate()
149      {
150        return duplicate(getControls());
151      }
152    
153    
154    
155      /**
156       * {@inheritDoc}
157       */
158      @Override()
159      public GenericSASLBindRequest duplicate(final Control[] controls)
160      {
161        return new GenericSASLBindRequest(bindDN, mechanism, credentials,
162             controls);
163      }
164    
165    
166    
167      /**
168       * {@inheritDoc}
169       */
170      @Override()
171      public void toString(final StringBuilder buffer)
172      {
173        buffer.append("GenericSASLBindRequest(mechanism='");
174        buffer.append(mechanism);
175        buffer.append('\'');
176    
177        if (bindDN != null)
178        {
179          buffer.append(", bindDN='");
180          buffer.append(bindDN);
181          buffer.append('\'');
182        }
183    
184        if (credentials != null)
185        {
186          buffer.append(", credentials=byte[");
187          buffer.append(credentials.getValueLength());
188          buffer.append(']');
189        }
190    
191        final Control[] controls = getControls();
192        if (controls.length > 0)
193        {
194          buffer.append(", controls={");
195          for (int i=0; i < controls.length; i++)
196          {
197            if (i > 0)
198            {
199              buffer.append(", ");
200            }
201    
202            buffer.append(controls[i]);
203          }
204          buffer.append('}');
205        }
206    
207        buffer.append(')');
208      }
209    }