/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2014-2016 ForgeRock AS. */ package org.opends.server.protocols.jmx; import org.forgerock.i18n.slf4j.LocalizedLogger; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.rmi.server.RMIServerSocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; /** * A DirectoryRMIServerSocketFactory instance is used by the RMI * runtime in order to obtain server sockets for RMI calls via SSL. * *

* This class implements RMIServerSocketFactory over the Secure * Sockets Layer (SSL) or Transport Layer Security (TLS) protocols. *

*/ public class DirectoryRMIServerSocketFactory implements RMIServerSocketFactory { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The SSL socket factory associated with the connector. */ private SSLSocketFactory sslSocketFactory; /** Indicate if we required the client authentication via SSL. */ private final boolean needClientCertificate; /** * Constructs a new DirectoryRMIServerSocketFactory with the * specified SSL socket configuration. * * @param sslSocketFactory * the SSL socket factory to be used by this factory * * @param needClientCertificate * true to require client authentication on SSL * connections accepted by server sockets created by this * factory; false to not require client * authentication. */ public DirectoryRMIServerSocketFactory(SSLSocketFactory sslSocketFactory, boolean needClientCertificate) { // Initialize the configuration parameters. this.needClientCertificate = needClientCertificate; this.sslSocketFactory = sslSocketFactory; } /** *

* Returns true if client authentication is required on SSL * connections accepted by server sockets created by this factory. *

* * @return true if client authentication is required * * @see SSLSocket#setNeedClientAuth */ public final boolean getNeedClientCertificate() { return needClientCertificate; } /** * Creates a server socket that accepts SSL connections configured according * to this factory's SSL socket configuration parameters. * * @param port * the port number the socket listens to * * @return a server socket * * @throws IOException * if the socket cannot be created */ @Override public ServerSocket createServerSocket(int port) throws IOException { return new ServerSocket(port, 0, InetAddress.getByName("0.0.0.0")) { @Override public Socket accept() throws IOException { Socket socket = super.accept(); if (logger.isTraceEnabled()) { logger.trace("host/port: %s/%d", socket.getInetAddress().getHostName(), socket.getPort()); } SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket( socket, socket.getInetAddress().getHostName(), socket.getPort(), true); sslSocket.setUseClientMode(false); sslSocket.setNeedClientAuth(needClientCertificate); return sslSocket; } }; } /** *

* Indicates whether some other object is "equal to" this one. *

* *

* Two CacaoRMIServerSocketFactory objects are equal if they * have been constructed with the same SSL socket configuration parameters. *

* *

* A subclass should override this method (as well as {@link #hashCode()}) * if it adds instance state that affects equality. *

* * @param obj the reference object with which to compare. * * @return true if this object is the same as the obj * argument false otherwise. */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof DirectoryRMIServerSocketFactory)) { return false; } DirectoryRMIServerSocketFactory that = (DirectoryRMIServerSocketFactory) obj; return getClass().equals(that.getClass()) && checkParameters(that); } /** * Checks if inputs parameters are OK. * @param that the input parameter * @return true or false. */ private boolean checkParameters(DirectoryRMIServerSocketFactory that) { return needClientCertificate == that.needClientCertificate && sslSocketFactory.equals(that.sslSocketFactory); } /** *

Returns a hash code value for this * CacaoRMIServerSocketFactory.

* * @return a hash code value for this * CacaoRMIServerSocketFactory. */ @Override public int hashCode() { return getClass().hashCode() + Boolean.valueOf(needClientCertificate).hashCode() + sslSocketFactory.hashCode(); } }