001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2010 Sun Microsystems, Inc. 025 * Portions copyright 2012-2015 ForgeRock AS. 026 */ 027 028package org.forgerock.opendj.ldap; 029 030import java.util.LinkedList; 031import java.util.List; 032import java.util.concurrent.TimeUnit; 033 034import javax.net.ssl.SSLContext; 035 036import org.forgerock.util.Reject; 037 038/** 039 * Common options for LDAP client connections. 040 * <p> 041 * For example you set LDAP options when you want to use StartTLS. 042 * 043 * <pre> 044 * LDAPOptions options = new LDAPOptions(); 045 * SSLContext sslContext = 046 * new SSLContextBuilder().setTrustManager(...).getSSLContext(); 047 * options.setSSLContext(sslContext); 048 * options.setUseStartTLS(true); 049 * 050 * String host = ...; 051 * int port = ...; 052 * LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port, options); 053 * Connection connection = factory.getConnection(); 054 * // Connection uses StartTLS... 055 * </pre> 056 */ 057public final class LDAPOptions extends CommonLDAPOptions<LDAPOptions> { 058 /** Default values for options taken from Java properties. */ 059 private static final long DEFAULT_TIMEOUT; 060 private static final long DEFAULT_CONNECT_TIMEOUT; 061 static { 062 DEFAULT_TIMEOUT = getIntProperty("org.forgerock.opendj.io.timeout", 0); 063 DEFAULT_CONNECT_TIMEOUT = getIntProperty("org.forgerock.opendj.io.connectTimeout", 5000); 064 } 065 066 private SSLContext sslContext; 067 private boolean useStartTLS; 068 private long timeoutInMillis = DEFAULT_TIMEOUT; 069 private long connectTimeoutInMillis = DEFAULT_CONNECT_TIMEOUT; 070 private final List<String> enabledCipherSuites = new LinkedList<>(); 071 private final List<String> enabledProtocols = new LinkedList<>(); 072 073 /** 074 * Creates a new set of connection options with default settings. SSL will 075 * not be enabled, and a default set of decode options will be used. 076 */ 077 public LDAPOptions() { 078 super(); 079 } 080 081 /** 082 * Creates a new set of connection options having the same initial set of 083 * options as the provided set of connection options. 084 * 085 * @param options 086 * The set of connection options to be copied. 087 */ 088 public LDAPOptions(final LDAPOptions options) { 089 super(options); 090 this.sslContext = options.sslContext; 091 this.timeoutInMillis = options.timeoutInMillis; 092 this.useStartTLS = options.useStartTLS; 093 this.enabledCipherSuites.addAll(options.getEnabledCipherSuites()); 094 this.enabledProtocols.addAll(options.getEnabledProtocols()); 095 this.connectTimeoutInMillis = options.connectTimeoutInMillis; 096 } 097 098 /** 099 * Adds the cipher suites enabled for secure connections with the Directory 100 * Server. 101 * <p> 102 * The suites must be supported by the SSLContext specified in 103 * {@link #setSSLContext(SSLContext)}. Following a successful call to this 104 * method, only the suites listed in the protocols parameter are enabled for 105 * use. 106 * 107 * @param suites 108 * Names of all the suites to enable. 109 * @return A reference to this set of options. 110 */ 111 public LDAPOptions addEnabledCipherSuite(final String... suites) { 112 for (final String suite : suites) { 113 enabledCipherSuites.add(Reject.checkNotNull(suite)); 114 } 115 return this; 116 } 117 118 /** 119 * Adds the protocol versions enabled for secure connections with the 120 * Directory Server. 121 * <p> 122 * The protocols must be supported by the SSLContext specified in 123 * {@link #setSSLContext(SSLContext)}. Following a successful call to this 124 * method, only the protocols listed in the protocols parameter are enabled 125 * for use. 126 * 127 * @param protocols 128 * Names of all the protocols to enable. 129 * @return A reference to this set of options. 130 */ 131 public LDAPOptions addEnabledProtocol(final String... protocols) { 132 for (final String protocol : protocols) { 133 enabledProtocols.add(Reject.checkNotNull(protocol)); 134 } 135 return this; 136 } 137 138 /** 139 * Returns the connect timeout in the specified unit. If a connection is not 140 * established within the timeout period, then a 141 * {@link TimeoutResultException} error result will be returned. A timeout 142 * setting of 0 causes the OS connect timeout to be used. 143 * <p> 144 * The default operation timeout is 10 seconds and may be configured using 145 * the {@code org.forgerock.opendj.io.connectTimeout} property. 146 * 147 * @param unit 148 * The time unit. 149 * @return The connect timeout, which may be 0 if there is no connect 150 * timeout. 151 */ 152 public long getConnectTimeout(final TimeUnit unit) { 153 return unit.convert(connectTimeoutInMillis, TimeUnit.MILLISECONDS); 154 } 155 156 /** 157 * Returns the names of the protocol versions which are currently enabled 158 * for secure connections with the Directory Server. 159 * 160 * @return An array of protocols or empty set if the default protocols are 161 * to be used. 162 */ 163 public List<String> getEnabledCipherSuites() { 164 return enabledCipherSuites; 165 } 166 167 /** 168 * Returns the names of the protocol versions which are currently enabled 169 * for secure connections with the Directory Server. 170 * 171 * @return An array of protocols or empty set if the default protocols are 172 * to be used. 173 */ 174 public List<String> getEnabledProtocols() { 175 return enabledProtocols; 176 } 177 178 /** 179 * Returns the SSL context which will be used when initiating connections 180 * with the Directory Server. 181 * <p> 182 * By default no SSL context will be used, indicating that connections will 183 * not be secured. If a non-{@code null} SSL context is returned then 184 * connections will be secured using either SSL or StartTLS depending on 185 * {@link #useStartTLS()}. 186 * 187 * @return The SSL context which will be used when initiating secure 188 * connections with the Directory Server, which may be {@code null} 189 * indicating that connections will not be secured. 190 */ 191 public SSLContext getSSLContext() { 192 return sslContext; 193 } 194 195 /** 196 * Returns the operation timeout in the specified unit. If a response is not 197 * received from the Directory Server within the timeout period, then the 198 * operation will be abandoned and a {@link TimeoutResultException} error 199 * result returned. A timeout setting of 0 disables operation timeout 200 * limits. 201 * <p> 202 * The default operation timeout is 0 (no timeout) and may be configured 203 * using the {@code org.forgerock.opendj.io.timeout} property. 204 * 205 * @param unit 206 * The time unit. 207 * @return The operation timeout, which may be 0 if there is no operation 208 * timeout. 209 */ 210 public long getTimeout(final TimeUnit unit) { 211 return unit.convert(timeoutInMillis, TimeUnit.MILLISECONDS); 212 } 213 214 /** 215 * Sets the connect timeout. If a connection is not established within the 216 * timeout period, then a {@link TimeoutResultException} error result will 217 * be returned. A timeout setting of 0 causes the OS connect timeout to be 218 * used. 219 * <p> 220 * The default operation timeout is 10 seconds and may be configured using 221 * the {@code org.forgerock.opendj.io.connectTimeout} property. 222 * 223 * @param timeout 224 * The connect timeout, which may be 0 if there is no connect 225 * timeout. 226 * @param unit 227 * The time unit. 228 * @return A reference to this set of options. 229 */ 230 public LDAPOptions setConnectTimeout(final long timeout, final TimeUnit unit) { 231 this.connectTimeoutInMillis = unit.toMillis(timeout); 232 return this; 233 } 234 235 /** 236 * Sets the SSL context which will be used when initiating connections with 237 * the Directory Server. 238 * <p> 239 * By default no SSL context will be used, indicating that connections will 240 * not be secured. If a non-{@code null} SSL context is returned then 241 * connections will be secured using either SSL or StartTLS depending on 242 * {@link #useStartTLS()}. 243 * 244 * @param sslContext 245 * The SSL context which will be used when initiating secure 246 * connections with the Directory Server, which may be 247 * {@code null} indicating that connections will not be secured. 248 * @return A reference to this set of options. 249 */ 250 public LDAPOptions setSSLContext(final SSLContext sslContext) { 251 this.sslContext = sslContext; 252 return this; 253 } 254 255 /** 256 * Sets the operation timeout. If a response is not received from the 257 * Directory Server within the timeout period, then the operation will be 258 * abandoned and a {@link TimeoutResultException} error result returned. A 259 * timeout setting of 0 disables operation timeout limits. 260 * <p> 261 * The default operation timeout is 0 (no timeout) and may be configured 262 * using the {@code org.forgerock.opendj.io.timeout} property. 263 * 264 * @param timeout 265 * The operation timeout, which may be 0 if there is no operation 266 * timeout. 267 * @param unit 268 * The time unit. 269 * @return A reference to this set of options. 270 */ 271 public LDAPOptions setTimeout(final long timeout, final TimeUnit unit) { 272 this.timeoutInMillis = unit.toMillis(timeout); 273 return this; 274 } 275 276 /** 277 * Specifies whether or not SSL or StartTLS should be used for securing 278 * connections when an SSL context is specified. 279 * <p> 280 * By default SSL will be used in preference to StartTLS. 281 * 282 * @param useStartTLS 283 * {@code true} if StartTLS should be used for securing 284 * connections when an SSL context is specified, otherwise 285 * {@code false} indicating that SSL should be used. 286 * @return A reference to this set of options. 287 */ 288 public LDAPOptions setUseStartTLS(final boolean useStartTLS) { 289 this.useStartTLS = useStartTLS; 290 return this; 291 } 292 293 /** 294 * Indicates whether or not SSL or StartTLS should be used for securing 295 * connections when an SSL context is specified. 296 * <p> 297 * By default SSL will be used in preference to StartTLS. 298 * 299 * @return {@code true} if StartTLS should be used for securing connections 300 * when an SSL context is specified, otherwise {@code false} 301 * indicating that SSL should be used. 302 */ 303 public boolean useStartTLS() { 304 return useStartTLS; 305 } 306 307 @Override 308 LDAPOptions getThis() { 309 return this; 310 } 311}