001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017 018package org.forgerock.opendj.examples; 019 020import static org.forgerock.opendj.ldap.LDAPListener.*; 021 022import java.io.FileInputStream; 023import java.io.IOException; 024 025import javax.net.ssl.SSLContext; 026 027import org.forgerock.opendj.ldap.Connections; 028import org.forgerock.opendj.ldap.LdapException; 029import org.forgerock.opendj.ldap.KeyManagers; 030import org.forgerock.opendj.ldap.LDAPClientContext; 031import org.forgerock.opendj.ldap.LDAPListener; 032import org.forgerock.opendj.ldap.MemoryBackend; 033import org.forgerock.opendj.ldap.ResultCode; 034import org.forgerock.opendj.ldap.SSLContextBuilder; 035import org.forgerock.opendj.ldap.ServerConnection; 036import org.forgerock.opendj.ldap.ServerConnectionFactory; 037import org.forgerock.opendj.ldap.TrustManagers; 038import org.forgerock.opendj.ldif.LDIFEntryReader; 039import org.forgerock.util.Options; 040 041import com.forgerock.reactive.ServerConnectionFactoryAdapter; 042 043/** 044 * An LDAP directory server which exposes data contained in an LDIF file. This 045 * is implementation is very simple and is only intended as an example: 046 * <ul> 047 * <li>It does not support StartTLS 048 * <li>It does not support Abandon or Cancel requests 049 * <li>Very basic authentication and authorization support. 050 * </ul> 051 * This example takes the following command line parameters: 052 * 053 * <pre> 054 * {@code <listenAddress> <listenPort> <ldifFile> [<keyStoreFile> <keyStorePassword> <certNickname>]} 055 * </pre> 056 */ 057public final class Server { 058 059 /** 060 * Main method. 061 * 062 * @param args 063 * The command line arguments: listen address, listen port, ldifFile, 064 * and optionally: key store, key store password and certificate nick name 065 */ 066 public static void main(final String[] args) { 067 if (args.length != 3 && args.length != 6) { 068 System.err.println("Usage: listenAddress listenPort ldifFile " 069 + "[keyStoreFile keyStorePassword certNickname]"); 070 System.exit(1); 071 } 072 073 // Parse command line arguments. 074 final String localAddress = args[0]; 075 final int localPort = Integer.parseInt(args[1]); 076 final String ldifFileName = args[2]; 077 final String keyStoreFileName = (args.length == 6) ? args[3] : null; 078 final String keyStorePassword = (args.length == 6) ? args[4] : null; 079 final String certNickname = (args.length == 6) ? args[5] : null; 080 081 // Create the memory backend. 082 final MemoryBackend backend; 083 try { 084 backend = new MemoryBackend(new LDIFEntryReader(new FileInputStream(ldifFileName))); 085 } catch (final IOException e) { 086 System.err.println(e.getMessage()); 087 System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue()); 088 return; // Keep compiler quiet. 089 } 090 091 // Create a server connection adapter. 092 final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler = 093 Connections.newServerConnectionFactory(backend); 094 095 // Create listener. 096 LDAPListener listener = null; 097 try { 098 final Options options = Options.defaultOptions().set(CONNECT_MAX_BACKLOG, 4096); 099 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}