View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions Copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2009-2010 Sun Microsystems, Inc.
15   * Portions Copyright 2011-2016 ForgeRock AS.
16   */
17  
18  package org.forgerock.opendj.examples;
19  
20  import static org.forgerock.opendj.ldap.LDAPListener.*;
21  
22  import java.io.FileInputStream;
23  import java.io.IOException;
24  
25  import javax.net.ssl.SSLContext;
26  
27  import org.forgerock.opendj.ldap.Connections;
28  import org.forgerock.opendj.ldap.LdapException;
29  import org.forgerock.opendj.ldap.KeyManagers;
30  import org.forgerock.opendj.ldap.LDAPClientContext;
31  import org.forgerock.opendj.ldap.LDAPListener;
32  import org.forgerock.opendj.ldap.MemoryBackend;
33  import org.forgerock.opendj.ldap.ResultCode;
34  import org.forgerock.opendj.ldap.SSLContextBuilder;
35  import org.forgerock.opendj.ldap.ServerConnection;
36  import org.forgerock.opendj.ldap.ServerConnectionFactory;
37  import org.forgerock.opendj.ldap.TrustManagers;
38  import org.forgerock.opendj.ldif.LDIFEntryReader;
39  import org.forgerock.util.Options;
40  
41  import com.forgerock.reactive.ServerConnectionFactoryAdapter;
42  
43  /**
44   * An LDAP directory server which exposes data contained in an LDIF file. This
45   * is implementation is very simple and is only intended as an example:
46   * <ul>
47   * <li>It does not support StartTLS
48   * <li>It does not support Abandon or Cancel requests
49   * <li>Very basic authentication and authorization support.
50   * </ul>
51   * This example takes the following command line parameters:
52   *
53   * <pre>
54   *  {@code <listenAddress> <listenPort> <ldifFile> [<keyStoreFile> <keyStorePassword> <certNickname>]}
55   * </pre>
56   */
57  public final class Server {
58  
59      /**
60       * Main method.
61       *
62       * @param args
63       *            The command line arguments: listen address, listen port, ldifFile,
64       *            and optionally: key store, key store password and certificate nick name
65       */
66      public static void main(final String[] args) {
67          if (args.length != 3 && args.length != 6) {
68              System.err.println("Usage: listenAddress listenPort ldifFile "
69                      + "[keyStoreFile keyStorePassword certNickname]");
70              System.exit(1);
71          }
72  
73          // Parse command line arguments.
74          final String localAddress = args[0];
75          final int localPort = Integer.parseInt(args[1]);
76          final String ldifFileName = args[2];
77          final String keyStoreFileName = (args.length == 6) ? args[3] : null;
78          final String keyStorePassword = (args.length == 6) ? args[4] : null;
79          final String certNickname = (args.length == 6) ? args[5] : null;
80  
81          // Create the memory backend.
82          final MemoryBackend backend;
83          try {
84              backend = new MemoryBackend(new LDIFEntryReader(new FileInputStream(ldifFileName)));
85          } catch (final IOException e) {
86              System.err.println(e.getMessage());
87              System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
88              return; // Keep compiler quiet.
89          }
90  
91          // Create a server connection adapter.
92          final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler =
93                  Connections.newServerConnectionFactory(backend);
94  
95          // Create listener.
96          LDAPListener listener = null;
97          try {
98              final Options options = Options.defaultOptions().set(CONNECT_MAX_BACKLOG, 4096);
99  
100             if (keyStoreFileName != null) {
101                 // Configure SSL/TLS and enable it when connections are
102                 // accepted.
103                 final SSLContext sslContext =
104                         new SSLContextBuilder().setKeyManager(
105                                 KeyManagers.useSingleCertificate(certNickname, KeyManagers
106                                         .useKeyStoreFile(keyStoreFileName, keyStorePassword
107                                                 .toCharArray(), null))).setTrustManager(
108                                 TrustManagers.trustAll()).getSSLContext();
109 
110                 final ServerConnectionFactory<LDAPClientContext, Integer> sslWrapper =
111                         new ServerConnectionFactory<LDAPClientContext, Integer>() {
112 
113                             @Override
114                             public ServerConnection<Integer> handleAccept(final LDAPClientContext clientContext)
115                                     throws LdapException {
116                                 clientContext.enableTLS(sslContext.createSSLEngine(), false);
117                                 return connectionHandler.handleAccept(clientContext);
118                             }
119                         };
120 
121                 listener = new LDAPListener(localAddress, localPort,
122                         new ServerConnectionFactoryAdapter(options.get(LDAP_DECODE_OPTIONS), sslWrapper), options);
123             } else {
124                 // No SSL.
125                 listener = new LDAPListener(localAddress, localPort,
126                         new ServerConnectionFactoryAdapter(options.get(LDAP_DECODE_OPTIONS), connectionHandler),
127                         options);
128             }
129             System.out.println("Press any key to stop the server...");
130             System.in.read();
131         } catch (final Exception e) {
132             System.out.println("Error listening on " + localAddress + ":" + localPort);
133             e.printStackTrace();
134         } finally {
135             if (listener != null) {
136                 listener.close();
137             }
138         }
139     }
140 
141     private Server() {
142         // Not used.
143     }
144 }