001/* 002 * Copyright 2007-2022 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-2022 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2007-2022 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk; 037 038 039 040import java.util.ArrayList; 041import java.util.List; 042 043import com.unboundid.asn1.ASN1OctetString; 044import com.unboundid.util.NotMutable; 045import com.unboundid.util.NotNull; 046import com.unboundid.util.Nullable; 047import com.unboundid.util.ThreadSafety; 048import com.unboundid.util.ThreadSafetyLevel; 049 050 051 052/** 053 * This class provides a SASL ANONYMOUS bind request implementation as described 054 * in <A HREF="http://www.ietf.org/rfc/rfc4505.txt">RFC 4505</A>. Binding with 055 * The ANONYMOUS SASL mechanism is essentially equivalent to using an anonymous 056 * simple bind (i.e., a simple bind with an empty password), although the SASL 057 * ANONYMOUS mechanism does provide the ability to include additional trace 058 * information with the request that may be logged or otherwise handled by 059 * the server. 060 * <BR><BR> 061 * <H2>Example</H2> 062 * The following example demonstrates the process for performing an ANONYMOUS 063 * bind, including a trace string of "Demo Application" against a directory 064 * server: 065 * <PRE> 066 * ANONYMOUSBindRequest bindRequest = 067 * new ANONYMOUSBindRequest("Demo Application"); 068 * BindResult bindResult; 069 * try 070 * { 071 * bindResult = connection.bind(bindRequest); 072 * // If we get here, then the bind was successful. 073 * } 074 * catch (LDAPException le) 075 * { 076 * // The bind failed for some reason. 077 * bindResult = new BindResult(le.toLDAPResult()); 078 * ResultCode resultCode = le.getResultCode(); 079 * String errorMessageFromServer = le.getDiagnosticMessage(); 080 * } 081 * </PRE> 082 */ 083@NotMutable() 084@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 085public final class ANONYMOUSBindRequest 086 extends SASLBindRequest 087{ 088 /** 089 * The name for the ANONYMOUS SASL mechanism. 090 */ 091 @NotNull public static final String ANONYMOUS_MECHANISM_NAME = "ANONYMOUS"; 092 093 094 095 /** 096 * The serial version UID for this serializable class. 097 */ 098 private static final long serialVersionUID = 4259102841471750866L; 099 100 101 102 // The trace string that should be included in the bind request, if available. 103 @Nullable private final String traceString; 104 105 106 107 /** 108 * Creates a new SASL ANONYMOUS bind request with no trace string and no 109 * controls. 110 */ 111 public ANONYMOUSBindRequest() 112 { 113 this(null, NO_CONTROLS); 114 } 115 116 117 118 /** 119 * Creates a new SASL ANONYMOUS bind request with the provided trace string 120 * and no controls. 121 * 122 * @param traceString The trace string to include in the bind request, or 123 * {@code null} if no trace string is to be provided. 124 */ 125 public ANONYMOUSBindRequest(@Nullable final String traceString) 126 { 127 this(traceString, NO_CONTROLS); 128 } 129 130 131 132 /** 133 * Creates a new SASL ANONYMOUS bind request with the provided set of controls 134 * and no trace string. 135 * 136 * @param controls The set of controls to include in the request. 137 */ 138 public ANONYMOUSBindRequest(@Nullable final Control... controls) 139 { 140 this(null, controls); 141 } 142 143 144 145 /** 146 * Creates a new SASL ANONYMOUS bind request with the provided trace string 147 * and controls. 148 * 149 * @param traceString The trace string to include in the bind request, or 150 * {@code null} if no trace string is to be provided. 151 * @param controls The set of controls to include in the request. 152 */ 153 public ANONYMOUSBindRequest(@Nullable final String traceString, 154 @Nullable final Control... controls) 155 { 156 super(controls); 157 158 this.traceString = traceString; 159 } 160 161 162 163 /** 164 * {@inheritDoc} 165 */ 166 @Override() 167 @NotNull() 168 public String getSASLMechanismName() 169 { 170 return ANONYMOUS_MECHANISM_NAME; 171 } 172 173 174 175 /** 176 * Retrieves the trace string that will be included with the bind request. 177 * 178 * @return The trace string that will be included with the bind request, or 179 * {@code null} if there is to be no trace string. 180 */ 181 @Nullable() 182 public String getTraceString() 183 { 184 return traceString; 185 } 186 187 188 189 /** 190 * Sends this bind request to the target server over the provided connection 191 * and returns the corresponding response. 192 * 193 * @param connection The connection to use to send this bind request to the 194 * server and read the associated response. 195 * @param depth The current referral depth for this request. It should 196 * always be one for the initial request, and should only 197 * be incremented when following referrals. 198 * 199 * @return The bind response read from the server. 200 * 201 * @throws LDAPException If a problem occurs while sending the request or 202 * reading the response. 203 */ 204 @Override() 205 @NotNull() 206 protected BindResult process(@NotNull final LDAPConnection connection, 207 final int depth) 208 throws LDAPException 209 { 210 ASN1OctetString credentials = null; 211 if ((traceString != null) && (! traceString.isEmpty())) 212 { 213 credentials = new ASN1OctetString(traceString); 214 } 215 216 return sendBindRequest(connection, null, credentials, getControls(), 217 getResponseTimeoutMillis(connection)); 218 } 219 220 221 222 /** 223 * {@inheritDoc} 224 */ 225 @Override() 226 @NotNull() 227 public ANONYMOUSBindRequest getRebindRequest(@NotNull final String host, 228 final int port) 229 { 230 return new ANONYMOUSBindRequest(traceString, getControls()); 231 } 232 233 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override() 239 @NotNull() 240 public ANONYMOUSBindRequest duplicate() 241 { 242 return duplicate(getControls()); 243 } 244 245 246 247 /** 248 * {@inheritDoc} 249 */ 250 @Override() 251 @NotNull() 252 public ANONYMOUSBindRequest duplicate(@Nullable final Control[] controls) 253 { 254 final ANONYMOUSBindRequest bindRequest = 255 new ANONYMOUSBindRequest(traceString, controls); 256 bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 257 return bindRequest; 258 } 259 260 261 262 /** 263 * {@inheritDoc} 264 */ 265 @Override() 266 public void toString(@NotNull final StringBuilder buffer) 267 { 268 buffer.append("ANONYMOUSBindRequest("); 269 if (traceString != null) 270 { 271 buffer.append(", trace='"); 272 buffer.append(traceString); 273 buffer.append('\''); 274 } 275 276 final Control[] controls = getControls(); 277 if (controls.length > 0) 278 { 279 buffer.append(", controls={"); 280 for (int i=0; i < controls.length; i++) 281 { 282 if (i > 0) 283 { 284 buffer.append(", "); 285 } 286 287 buffer.append(controls[i]); 288 } 289 buffer.append('}'); 290 } 291 292 buffer.append(')'); 293 } 294 295 296 297 /** 298 * {@inheritDoc} 299 */ 300 @Override() 301 public void toCode(@NotNull final List<String> lineList, 302 @NotNull final String requestID, 303 final int indentSpaces, final boolean includeProcessing) 304 { 305 // Create the request variable. 306 final ArrayList<ToCodeArgHelper> constructorArgs = new ArrayList<>(2); 307 constructorArgs.add(ToCodeArgHelper.createString(traceString, 308 "Trace String")); 309 310 final Control[] controls = getControls(); 311 if (controls.length > 0) 312 { 313 constructorArgs.add(ToCodeArgHelper.createControlArray(controls, 314 "Bind Controls")); 315 } 316 317 ToCodeHelper.generateMethodCall(lineList, indentSpaces, 318 "ANONYMOUSBindRequest", requestID + "Request", 319 "new ANONYMOUSBindRequest", constructorArgs); 320 321 322 // Add lines for processing the request and obtaining the result. 323 if (includeProcessing) 324 { 325 // Generate a string with the appropriate indent. 326 final StringBuilder buffer = new StringBuilder(); 327 for (int i=0; i < indentSpaces; i++) 328 { 329 buffer.append(' '); 330 } 331 final String indent = buffer.toString(); 332 333 lineList.add(""); 334 lineList.add(indent + "try"); 335 lineList.add(indent + '{'); 336 lineList.add(indent + " BindResult " + requestID + 337 "Result = connection.bind(" + requestID + "Request);"); 338 lineList.add(indent + " // The bind was processed successfully."); 339 lineList.add(indent + '}'); 340 lineList.add(indent + "catch (LDAPException e)"); 341 lineList.add(indent + '{'); 342 lineList.add(indent + " // The bind failed. Maybe the following will " + 343 "help explain why."); 344 lineList.add(indent + " // Note that the connection is now likely in " + 345 "an unauthenticated state."); 346 lineList.add(indent + " ResultCode resultCode = e.getResultCode();"); 347 lineList.add(indent + " String message = e.getMessage();"); 348 lineList.add(indent + " String matchedDN = e.getMatchedDN();"); 349 lineList.add(indent + " String[] referralURLs = e.getReferralURLs();"); 350 lineList.add(indent + " Control[] responseControls = " + 351 "e.getResponseControls();"); 352 lineList.add(indent + '}'); 353 } 354 } 355}