001 /*
002 * Copyright 2012-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 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.unboundidds;
022
023
024
025 import com.unboundid.asn1.ASN1OctetString;
026 import com.unboundid.ldap.sdk.BindResult;
027 import com.unboundid.ldap.sdk.Control;
028 import com.unboundid.ldap.sdk.InternalSDKHelper;
029 import com.unboundid.ldap.sdk.LDAPConnection;
030 import com.unboundid.ldap.sdk.LDAPException;
031 import com.unboundid.ldap.sdk.SASLBindRequest;
032 import com.unboundid.util.ThreadSafety;
033 import com.unboundid.util.ThreadSafetyLevel;
034 import com.unboundid.util.Validator;
035
036
037
038 /**
039 * <BLOCKQUOTE>
040 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
041 * LDAP SDK for Java. It is not available for use in applications that
042 * include only the Standard Edition of the LDAP SDK, and is not supported for
043 * use in conjunction with non-UnboundID products.
044 * </BLOCKQUOTE>
045 * This class provides support for an UnboundID-proprietary SASL mechanism that
046 * provides multifactor authentication using the combination of a client
047 * certificate (presented during SSL/TLS negotiation) and a static password.
048 * <BR><BR>
049 * The name for this SASL mechanism is "UNBOUNDID-CERTIFICATE-PLUS-PASSWORD".
050 * The SASL credentials consist simply of the static password for the user
051 * identified by the certificate, to make the SASL mechanism as easy as possible
052 * to use from other client APIs.
053 */
054 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
055 public final class UnboundIDCertificatePlusPasswordBindRequest
056 extends SASLBindRequest
057 {
058 /**
059 * The name for the UnboundID certificate plus password SASL mechanism.
060 */
061 public static final String UNBOUNDID_CERT_PLUS_PW_MECHANISM_NAME =
062 "UNBOUNDID-CERTIFICATE-PLUS-PASSWORD";
063
064
065
066 /**
067 * The serial version UID for this serializable class.
068 */
069 private static final long serialVersionUID = 8863298749835036708L;
070
071
072
073 // The password to use to authenticate.
074 private final ASN1OctetString password;
075
076 // The message ID from the last LDAP message sent from this request.
077 private volatile int messageID = -1;
078
079
080
081 /**
082 * Creates a new certificate plus password bind request with the provided
083 * information.
084 *
085 * @param password The password to use to authenticate as user identified by
086 * the certificate. It must not be {@code null} or empty.
087 * @param controls The set of controls to include in the bind request. It
088 * may be {@code null} or empty if no request controls are
089 * needed.
090 */
091 public UnboundIDCertificatePlusPasswordBindRequest(final String password,
092 final Control... controls)
093 {
094 this(new ASN1OctetString(CRED_TYPE_SASL, password), controls);
095 }
096
097
098
099 /**
100 * Creates a new certificate plus password bind request with the provided
101 * information.
102 *
103 * @param password The password to use to authenticate as user identified by
104 * the certificate. It must not be {@code null} or empty.
105 * @param controls The set of controls to include in the bind request. It
106 * may be {@code null} or empty if no request controls are
107 * needed.
108 */
109 public UnboundIDCertificatePlusPasswordBindRequest(final byte[] password,
110 final Control... controls)
111 {
112 this(new ASN1OctetString(CRED_TYPE_SASL, password), controls);
113 }
114
115
116
117 /**
118 * Creates a new certificate plus password bind request with the provided
119 * information.
120 *
121 * @param password The password to use to authenticate as user identified by
122 * the certificate. It must not be {@code null} or empty.
123 * @param controls The set of controls to include in the bind request. It
124 * may be {@code null} or empty if no request controls are
125 * needed.
126 */
127 private UnboundIDCertificatePlusPasswordBindRequest(
128 final ASN1OctetString password, final Control... controls)
129 {
130 super(controls);
131
132 Validator.ensureFalse((password.getValueLength() == 0),
133 "The bind password must not be empty");
134
135 this.password = password;
136 }
137
138
139
140 /**
141 * Retrieves the password to use to authenticate as the user identified by the
142 * certificate.
143 *
144 * @return The password to use to authenticate as the user identified by the
145 * certificate.
146 */
147 public ASN1OctetString getPassword()
148 {
149 return password;
150 }
151
152
153
154 /**
155 * {@inheritDoc}
156 */
157 @Override()
158 public String getSASLMechanismName()
159 {
160 return UNBOUNDID_CERT_PLUS_PW_MECHANISM_NAME;
161 }
162
163
164
165 /**
166 * {@inheritDoc}
167 */
168 @Override()
169 protected BindResult process(final LDAPConnection connection, final int depth)
170 throws LDAPException
171 {
172 messageID = InternalSDKHelper.nextMessageID(connection);
173 return sendBindRequest(connection, "", password, getControls(),
174 getResponseTimeoutMillis(connection));
175 }
176
177
178
179 /**
180 * {@inheritDoc}
181 */
182 @Override()
183 public int getLastMessageID()
184 {
185 return messageID;
186 }
187
188
189
190 /**
191 * {@inheritDoc}
192 */
193 @Override()
194 public UnboundIDCertificatePlusPasswordBindRequest duplicate()
195 {
196 return duplicate(getControls());
197 }
198
199
200
201 /**
202 * {@inheritDoc}
203 */
204 @Override()
205 public UnboundIDCertificatePlusPasswordBindRequest duplicate(
206 final Control[] controls)
207 {
208 final UnboundIDCertificatePlusPasswordBindRequest bindRequest =
209 new UnboundIDCertificatePlusPasswordBindRequest(password, controls);
210 bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
211 return bindRequest;
212 }
213
214
215
216 /**
217 * {@inheritDoc}
218 */
219 @Override()
220 public UnboundIDCertificatePlusPasswordBindRequest getRebindRequest(
221 final String host, final int port)
222 {
223 return duplicate();
224 }
225
226
227
228 /**
229 * {@inheritDoc}
230 */
231 @Override()
232 public void toString(final StringBuilder buffer)
233 {
234 buffer.append("UnboundIDCertificatePlusPasswordBindRequest(");
235
236 final Control[] controls = getControls();
237 if (controls.length > 0)
238 {
239 buffer.append("controls={");
240 for (int i=0; i < controls.length; i++)
241 {
242 if (i > 0)
243 {
244 buffer.append(", ");
245 }
246
247 buffer.append(controls[i]);
248 }
249 buffer.append('}');
250 }
251
252 buffer.append(')');
253 }
254 }