View Javadoc

1   /*
2    * CDDL HEADER START
3    *
4    * The contents of this file are subject to the terms of the
5    * Common Development and Distribution License, Version 1.0 only
6    * (the "License").  You may not use this file except in compliance
7    * with the License.
8    *
9    * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
10   * or http://forgerock.org/license/CDDLv1.0.html.
11   * See the License for the specific language governing permissions
12   * and limitations under the License.
13   *
14   * When distributing Covered Code, include this CDDL HEADER in each
15   * file and include the License file at legal-notices/CDDLv1_0.txt.
16   * If applicable, add the following below this CDDL HEADER, with the
17   * fields enclosed by brackets "[]" replaced with your own identifying
18   * information:
19   *      Portions Copyright [yyyy] [name of copyright owner]
20   *
21   * CDDL HEADER END
22   *
23   *
24   *      Copyright 2011-2012 ForgeRock AS
25   */
26  
27  package org.forgerock.opendj.examples;
28  
29  import java.security.GeneralSecurityException;
30  
31  import javax.net.ssl.SSLContext;
32  
33  import org.forgerock.opendj.ldap.Connection;
34  import org.forgerock.opendj.ldap.ErrorResultException;
35  import org.forgerock.opendj.ldap.LDAPConnectionFactory;
36  import org.forgerock.opendj.ldap.LDAPOptions;
37  import org.forgerock.opendj.ldap.ResultCode;
38  import org.forgerock.opendj.ldap.SSLContextBuilder;
39  import org.forgerock.opendj.ldap.TrustManagers;
40  
41  /**
42   * An example client application which performs simple authentication to a
43   * directory server. This example takes the following command line parameters:
44   * <ul>
45   * <li>host - host name of the directory server</li>
46   * <li>port - port number of the directory server, e.g. 1389, 1636</li>
47   * <li>bind-dn - DN of the user to authenticate</li>
48   * <li>bind-password - Password of the user to authenticate</li>
49   * <li>use-starttls - (Optional) connect with StartTLS</li>
50   * <li>use-ssl - (Optional) connect over SSL</li>
51   * </ul>
52   * The host, port, bind-dn, and bind-password are required. The use-starttls and
53   * use-ssl parameters are optional and mutually exclusive.
54   */
55  public final class SimpleAuth {
56  
57      /**
58       * Authenticate to the directory either over LDAP, over LDAPS, or using
59       * StartTLS.
60       *
61       * @param args
62       *            The command line arguments
63       */
64      public static void main(final String[] args) {
65          parseArgs(args);
66          // Connect and bind to the server, then close the connection.
67          if (useStartTLS) {
68              connectStartTLS();
69          } else if (useSSL) {
70              connectSSL();
71          } else {
72              connect();
73          }
74      }
75  
76      /**
77       * Authenticate over LDAP.
78       */
79      private static void connect() {
80          final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port);
81          Connection connection = null;
82  
83          try {
84              connection = factory.getConnection();
85              connection.bind(bindDN, bindPassword.toCharArray());
86              System.out.println("Authenticated as " + bindDN + ".");
87          } catch (final ErrorResultException e) {
88              System.err.println(e.getMessage());
89              System.exit(e.getResult().getResultCode().intValue());
90              return;
91          } finally {
92              if (connection != null) {
93                  connection.close();
94              }
95          }
96      }
97  
98      /**
99       * For StartTLS and SSL the connection factory needs SSL context options. In
100      * the general case, a trust manager in the SSL context serves to check
101      * server certificates, and a key manager handles client keys when the
102      * server checks certificates from our client.
103      *
104      * OpenDJ directory server lets you install by default with a self-signed
105      * certificate that is not in the system trust store. To simplify this
106      * implementation trusts all server certificates.
107      */
108     private static LDAPOptions getTrustAllOptions() throws GeneralSecurityException {
109         LDAPOptions lo = new LDAPOptions();
110         SSLContext sslContext =
111                 new SSLContextBuilder().setTrustManager(TrustManagers.trustAll()).getSSLContext();
112         lo.setSSLContext(sslContext);
113         lo.setUseStartTLS(useStartTLS);
114         return lo;
115     }
116 
117     /**
118      * Perform authentication over a secure connection, trusting all server
119      * certificates.
120      */
121     private static void trustAllConnect() {
122         Connection connection = null;
123 
124         try {
125             final LDAPConnectionFactory factory =
126                     new LDAPConnectionFactory(host, port, getTrustAllOptions());
127             connection = factory.getConnection();
128             connection.bind(bindDN, bindPassword.toCharArray());
129             System.out.println("Authenticated as " + bindDN + ".");
130         } catch (final ErrorResultException e) {
131             System.err.println(e.getMessage());
132             System.exit(e.getResult().getResultCode().intValue());
133             return;
134         } catch (final GeneralSecurityException e) {
135             System.err.println(e.getMessage());
136             System.exit(ResultCode.CLIENT_SIDE_CONNECT_ERROR.intValue());
137         } finally {
138             if (connection != null) {
139                 connection.close();
140             }
141         }
142     }
143 
144     /**
145      * Authenticate using StartTLS.
146      */
147     private static void connectStartTLS() {
148         trustAllConnect();
149     }
150 
151     /**
152      * Authenticate over LDAPS.
153      */
154     private static void connectSSL() {
155         trustAllConnect();
156     }
157 
158     private static String host;
159     private static int port;
160     private static String bindDN;
161     private static String bindPassword;
162     private static boolean useStartTLS = false;
163     private static boolean useSSL = false;
164 
165     /**
166      * Parse command line arguments.
167      *
168      * @param args
169      *            host port bind-dn bind-password [ use-starttls | use-ssl ]
170      */
171     private static void parseArgs(String[] args) {
172         if (args.length < 4 || args.length > 5) {
173             giveUp();
174         }
175 
176         host = args[0];
177         port = Integer.parseInt(args[1]);
178         bindDN = args[2];
179         bindPassword = args[3];
180 
181         if (args.length == 5) {
182             if (args[4].toLowerCase().equals("use-starttls")) {
183                 useStartTLS = true;
184                 useSSL = false;
185             } else if (args[4].toLowerCase().equals("use-ssl")) {
186                 useStartTLS = false;
187                 useSSL = true;
188             } else {
189                 giveUp();
190             }
191         }
192     }
193 
194     private static void giveUp() {
195         printUsage();
196         System.exit(1);
197     }
198 
199     private static void printUsage() {
200         System.err.println("Usage: host port bind-dn bind-password [ use-starttls | use-ssl ]");
201         System.err.println("\thost, port, bind-dn, and bind-password arguments are required.");
202         System.err.println("\tuse-starttls and use-ssl are optional and mutually exclusive.");
203     }
204 
205     private SimpleAuth() {
206         // Not used.
207     }
208 }