001/* 002 * Copyright 2007-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-2020 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) 2008-2020 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.ThreadSafety; 046import com.unboundid.util.ThreadSafetyLevel; 047 048 049 050/** 051 * This class provides a SASL ANONYMOUS bind request implementation as described 052 * in <A HREF="http://www.ietf.org/rfc/rfc4505.txt">RFC 4505</A>. Binding with 053 * The ANONYMOUS SASL mechanism is essentially equivalent to using an anonymous 054 * simple bind (i.e., a simple bind with an empty password), although the SASL 055 * ANONYMOUS mechanism does provide the ability to include additional trace 056 * information with the request that may be logged or otherwise handled by 057 * the server. 058 * <BR><BR> 059 * <H2>Example</H2> 060 * The following example demonstrates the process for performing an ANONYMOUS 061 * bind, including a trace string of "Demo Application" against a directory 062 * server: 063 * <PRE> 064 * ANONYMOUSBindRequest bindRequest = 065 * new ANONYMOUSBindRequest("Demo Application"); 066 * BindResult bindResult; 067 * try 068 * { 069 * bindResult = connection.bind(bindRequest); 070 * // If we get here, then the bind was successful. 071 * } 072 * catch (LDAPException le) 073 * { 074 * // The bind failed for some reason. 075 * bindResult = new BindResult(le.toLDAPResult()); 076 * ResultCode resultCode = le.getResultCode(); 077 * String errorMessageFromServer = le.getDiagnosticMessage(); 078 * } 079 * </PRE> 080 */ 081@NotMutable() 082@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 083public final class ANONYMOUSBindRequest 084 extends SASLBindRequest 085{ 086 /** 087 * The name for the ANONYMOUS SASL mechanism. 088 */ 089 public static final String ANONYMOUS_MECHANISM_NAME = "ANONYMOUS"; 090 091 092 093 /** 094 * The serial version UID for this serializable class. 095 */ 096 private static final long serialVersionUID = 4259102841471750866L; 097 098 099 100 // The trace string that should be included in the bind request, if available. 101 private final String traceString; 102 103 104 105 /** 106 * Creates a new SASL ANONYMOUS bind request with no trace string and no 107 * controls. 108 */ 109 public ANONYMOUSBindRequest() 110 { 111 this(null, NO_CONTROLS); 112 } 113 114 115 116 /** 117 * Creates a new SASL ANONYMOUS bind request with the provided trace string 118 * and no controls. 119 * 120 * @param traceString The trace string to include in the bind request, or 121 * {@code null} if no trace string is to be provided. 122 */ 123 public ANONYMOUSBindRequest(final String traceString) 124 { 125 this(traceString, NO_CONTROLS); 126 } 127 128 129 130 /** 131 * Creates a new SASL ANONYMOUS bind request with the provided set of controls 132 * and no trace string. 133 * 134 * @param controls The set of controls to include in the request. 135 */ 136 public ANONYMOUSBindRequest(final Control... controls) 137 { 138 this(null, controls); 139 } 140 141 142 143 /** 144 * Creates a new SASL ANONYMOUS bind request with the provided trace string 145 * and controls. 146 * 147 * @param traceString The trace string to include in the bind request, or 148 * {@code null} if no trace string is to be provided. 149 * @param controls The set of controls to include in the request. 150 */ 151 public ANONYMOUSBindRequest(final String traceString, 152 final Control... controls) 153 { 154 super(controls); 155 156 this.traceString = traceString; 157 } 158 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override() 165 public String getSASLMechanismName() 166 { 167 return ANONYMOUS_MECHANISM_NAME; 168 } 169 170 171 172 /** 173 * Retrieves the trace string that will be included with the bind request. 174 * 175 * @return The trace string that will be included with the bind request, or 176 * {@code null} if there is to be no trace string. 177 */ 178 public String getTraceString() 179 { 180 return traceString; 181 } 182 183 184 185 /** 186 * Sends this bind request to the target server over the provided connection 187 * and returns the corresponding response. 188 * 189 * @param connection The connection to use to send this bind request to the 190 * server and read the associated response. 191 * @param depth The current referral depth for this request. It should 192 * always be one for the initial request, and should only 193 * be incremented when following referrals. 194 * 195 * @return The bind response read from the server. 196 * 197 * @throws LDAPException If a problem occurs while sending the request or 198 * reading the response. 199 */ 200 @Override() 201 protected BindResult process(final LDAPConnection connection, final int depth) 202 throws LDAPException 203 { 204 ASN1OctetString credentials = null; 205 if ((traceString != null) && (! traceString.isEmpty())) 206 { 207 credentials = new ASN1OctetString(traceString); 208 } 209 210 return sendBindRequest(connection, null, credentials, getControls(), 211 getResponseTimeoutMillis(connection)); 212 } 213 214 215 216 /** 217 * {@inheritDoc} 218 */ 219 @Override() 220 public ANONYMOUSBindRequest getRebindRequest(final String host, 221 final int port) 222 { 223 return new ANONYMOUSBindRequest(traceString, getControls()); 224 } 225 226 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override() 232 public ANONYMOUSBindRequest duplicate() 233 { 234 return duplicate(getControls()); 235 } 236 237 238 239 /** 240 * {@inheritDoc} 241 */ 242 @Override() 243 public ANONYMOUSBindRequest duplicate(final Control[] controls) 244 { 245 final ANONYMOUSBindRequest bindRequest = 246 new ANONYMOUSBindRequest(traceString, controls); 247 bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 248 return bindRequest; 249 } 250 251 252 253 /** 254 * {@inheritDoc} 255 */ 256 @Override() 257 public void toString(final StringBuilder buffer) 258 { 259 buffer.append("ANONYMOUSBindRequest("); 260 if (traceString != null) 261 { 262 buffer.append(", trace='"); 263 buffer.append(traceString); 264 buffer.append('\''); 265 } 266 267 final Control[] controls = getControls(); 268 if (controls.length > 0) 269 { 270 buffer.append(", controls={"); 271 for (int i=0; i < controls.length; i++) 272 { 273 if (i > 0) 274 { 275 buffer.append(", "); 276 } 277 278 buffer.append(controls[i]); 279 } 280 buffer.append('}'); 281 } 282 283 buffer.append(')'); 284 } 285 286 287 288 /** 289 * {@inheritDoc} 290 */ 291 @Override() 292 public void toCode(final List<String> lineList, final String requestID, 293 final int indentSpaces, final boolean includeProcessing) 294 { 295 // Create the request variable. 296 final ArrayList<ToCodeArgHelper> constructorArgs = new ArrayList<>(2); 297 constructorArgs.add(ToCodeArgHelper.createString(traceString, 298 "Trace String")); 299 300 final Control[] controls = getControls(); 301 if (controls.length > 0) 302 { 303 constructorArgs.add(ToCodeArgHelper.createControlArray(controls, 304 "Bind Controls")); 305 } 306 307 ToCodeHelper.generateMethodCall(lineList, indentSpaces, 308 "ANONYMOUSBindRequest", requestID + "Request", 309 "new ANONYMOUSBindRequest", constructorArgs); 310 311 312 // Add lines for processing the request and obtaining the result. 313 if (includeProcessing) 314 { 315 // Generate a string with the appropriate indent. 316 final StringBuilder buffer = new StringBuilder(); 317 for (int i=0; i < indentSpaces; i++) 318 { 319 buffer.append(' '); 320 } 321 final String indent = buffer.toString(); 322 323 lineList.add(""); 324 lineList.add(indent + "try"); 325 lineList.add(indent + '{'); 326 lineList.add(indent + " BindResult " + requestID + 327 "Result = connection.bind(" + requestID + "Request);"); 328 lineList.add(indent + " // The bind was processed successfully."); 329 lineList.add(indent + '}'); 330 lineList.add(indent + "catch (LDAPException e)"); 331 lineList.add(indent + '{'); 332 lineList.add(indent + " // The bind failed. Maybe the following will " + 333 "help explain why."); 334 lineList.add(indent + " // Note that the connection is now likely in " + 335 "an unauthenticated state."); 336 lineList.add(indent + " ResultCode resultCode = e.getResultCode();"); 337 lineList.add(indent + " String message = e.getMessage();"); 338 lineList.add(indent + " String matchedDN = e.getMatchedDN();"); 339 lineList.add(indent + " String[] referralURLs = e.getReferralURLs();"); 340 lineList.add(indent + " Control[] responseControls = " + 341 "e.getResponseControls();"); 342 lineList.add(indent + '}'); 343 } 344 } 345}