1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.forgerock.opendj.examples;
18
19 import static org.forgerock.opendj.ldap.TrustManagers.checkHostName;
20 import static org.forgerock.util.Utils.closeSilently;
21 import static org.forgerock.opendj.ldap.LDAPConnectionFactory.SSL_USE_STARTTLS;
22 import static org.forgerock.opendj.ldap.LDAPConnectionFactory.SSL_CONTEXT;
23
24 import org.forgerock.opendj.ldap.Connection;
25 import org.forgerock.opendj.ldap.LDAPConnectionFactory;
26 import org.forgerock.opendj.ldap.LdapException;
27 import org.forgerock.opendj.ldap.ResultCode;
28 import org.forgerock.opendj.ldap.SSLContextBuilder;
29 import org.forgerock.opendj.ldap.TrustManagers;
30 import org.forgerock.opendj.ldap.requests.Requests;
31 import org.forgerock.opendj.ldap.responses.BindResult;
32 import org.forgerock.opendj.ldap.responses.Result;
33 import org.forgerock.util.AsyncFunction;
34 import org.forgerock.util.Options;
35 import org.forgerock.util.promise.ExceptionHandler;
36 import org.forgerock.util.promise.Promise;
37 import org.forgerock.util.promise.ResultHandler;
38
39 import javax.net.ssl.SSLContext;
40 import javax.net.ssl.TrustManager;
41 import java.io.File;
42 import java.security.GeneralSecurityException;
43 import java.util.concurrent.CountDownLatch;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public final class SimpleAuthAsync {
69
70 private static Connection connection;
71
72 private static int resultCode;
73
74 private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
75
76
77
78
79
80
81
82
83 public static void main(final String[] args) {
84 parseArgs(args);
85
86
87
88
89
90 new LDAPConnectionFactory(host, port, getTrustOptions(host, keystore, storepass))
91 .getConnectionAsync()
92 .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
93 @Override
94 public Promise<BindResult, LdapException> apply(Connection connection)
95 throws LdapException {
96 SimpleAuthAsync.connection = connection;
97 return connection.bindAsync(
98 Requests.newSimpleBindRequest(bindDN, bindPassword.toCharArray()));
99 }
100 })
101 .thenOnResult(new ResultHandler<Result>() {
102 @Override
103 public void handleResult(Result result) {
104 resultCode = result.getResultCode().intValue();
105 System.out.println("Authenticated as " + bindDN + ".");
106 COMPLETION_LATCH.countDown();
107 }
108 })
109 .thenOnException(new ExceptionHandler<LdapException>() {
110 @Override
111 public void handleException(LdapException e) {
112 System.err.println(e.getMessage());
113 resultCode = e.getResult().getResultCode().intValue();
114 COMPLETION_LATCH.countDown();
115 }
116 });
117
118 try {
119 COMPLETION_LATCH.await();
120 } catch (InterruptedException e) {
121 System.err.println(e.getMessage());
122 System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
123 return;
124 }
125
126 closeSilently(connection);
127 System.exit(resultCode);
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 private static Options getTrustOptions(final String hostname,
148 final String truststore,
149 final String storepass) {
150 Options options = Options.defaultOptions();
151 if (useSSL || useStartTLS) {
152 try {
153 TrustManager trustManager = TrustManagers.checkValidityDates(
154 checkHostName(hostname,
155 TrustManagers.checkUsingTrustStore(
156 truststore, storepass.toCharArray(), null)));
157 if (trustManager != null) {
158 SSLContext sslContext = new SSLContextBuilder()
159 .setTrustManager(trustManager).getSSLContext();
160 options.set(SSL_CONTEXT, sslContext);
161 }
162 options.set(SSL_USE_STARTTLS, useStartTLS);
163 } catch (Exception e) {
164 System.err.println(e.getMessage());
165 System.exit(ResultCode.CLIENT_SIDE_CONNECT_ERROR.intValue());
166 return null;
167 }
168 }
169 return options;
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184 private static Options getTrustAllOptions() {
185 try {
186 Options options = Options.defaultOptions();
187 SSLContext sslContext =
188 new SSLContextBuilder().setTrustManager(TrustManagers.trustAll())
189 .getSSLContext();
190 options.set(SSL_CONTEXT, sslContext);
191 options.set(SSL_USE_STARTTLS, useStartTLS);
192 return options;
193 } catch (GeneralSecurityException e) {
194 System.err.println(e.getMessage());
195 System.exit(ResultCode.CLIENT_SIDE_CONNECT_ERROR.intValue());
196 return null;
197 }
198 }
199
200 private static String host;
201 private static int port;
202 private static String bindDN;
203 private static String bindPassword;
204 private static boolean useStartTLS;
205 private static boolean useSSL;
206 private static String keystore;
207 private static String storepass;
208
209
210
211
212
213
214
215 private static void parseArgs(String[] args) {
216 if (args.length < 4 || args.length > 5) {
217 giveUp();
218 }
219
220 host = args[0];
221 port = Integer.parseInt(args[1]);
222 bindDN = args[2];
223 bindPassword = args[3];
224
225 if (args.length == 5) {
226 if ("use-starttls".equals(args[4].toLowerCase())) {
227 useStartTLS = true;
228 useSSL = false;
229 } else if ("use-ssl".equals(args[4].toLowerCase())) {
230 useStartTLS = false;
231 useSSL = true;
232 } else {
233 giveUp();
234 }
235 }
236
237 keystore = System.getProperty("javax.net.ssl.trustStore");
238 storepass = System.getProperty("javax.net.ssl.trustStorePassword");
239 if (keystore == null) {
240 keystore = System.getProperty("java.home") + File.separator
241 + "lib" + File.separator
242 + "security" + File.separator
243 + "cacerts";
244 storepass = "changeit";
245 }
246 }
247
248 private static void giveUp() {
249 printUsage();
250 System.exit(1);
251 }
252
253 private static void printUsage() {
254 System.err.println("Usage: host port bind-dn bind-password [ use-starttls | use-ssl ]");
255 System.err.println("\thost, port, bind-dn, and bind-password arguments are required.");
256 System.err.println("\tuse-starttls and use-ssl are optional and mutually exclusive.");
257 System.err.println("\tOptionally set javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword.");
258 }
259
260 private SimpleAuthAsync() {
261
262 }
263 }