/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ package netscape.ldap; import java.io.*; import java.net.*; import netscape.ldap.*; /** * Creates an SSL socket connection to an LDAP Server. This class * implements the LDAPSocketFactory interface. *

* * To construct an object of this class, you need to specify the * name of a class that implements the javax.net.ssl.SSLSocket * interface. If you do not specify a class name, the class * netscape.net.SSLSocket is used by default. This * class is included with Netscape Communicator 4.05. *

* * If you are using a Java VM that provides certificate database * management (such as Netscape Communicator), you can authenticate * your client to a secure LDAP server by using certificates. *

* * @version 1.0 * @see LDAPSocketFactory * @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory) */ public class LDAPSSLSocketFactory implements LDAPSocketFactory { /** * Indicates if client authentication is on. */ private boolean m_isClientAuth = false; /** * Name of class implementing SSLSocket. */ private String m_packageName = "netscape.net.SSLSocket"; /** * The cipher suites */ private Object m_cipherSuites = null; /** * Constructs an LDAPSSLSocketFactory object using * the default SSL socket implementation, * netscape.net.SSLSocket. (This class is provided * with Netscape Communicator 4.05.) */ public LDAPSSLSocketFactory() { } /** * Constructs an LDAPSSLSocketFactory object using * the specified class. The class must implement the interface * javax.net.ssl.SSLSocket. * @param className The name of a class implementing * the javax.net.ssl.SSLSocket interface. * Pass null for this parameter to use the * default SSL socket implementation, * netscape.net.SSLSocket, which is included with * Netscape Communicator 4.05. */ public LDAPSSLSocketFactory(String className) { m_packageName = new String(className); } /** * The constructor with the specified package for security and the specified * cipher suites. * @param className The name of a class implementing the interface * javax.net.ssl.SSLSocket * Pass null for this parameter to use the * default SSL socket implementation, * netscape.net.SSLSocket, which is included with * Netscape Communicator 4.05. * @param cipherSuites The cipher suites to use for SSL connections. */ public LDAPSSLSocketFactory(String className, Object cipherSuites) { m_packageName = new String(className); m_cipherSuites = cipherSuites; } /** * Enables certificate-based client authentication for an * application. The application must be running in a Java VM * that provides transparent certificate database management * (for example, Netscape Communicator's Java VM). * Call this method before you call makeSocket. * @see netscape.ldap.LDAPSSLSocketFactory#isClientAuth * @see netscape.ldap.LDAPSSLSocketFactory#makeSocket */ public void enableClientAuth() { m_isClientAuth = true; } /** * This method is currently not implemented. * Enables client authentication for an application that uses * an external (file-based) certificate database. * Call this method before you call makeSocket. * @param certdb The pathname for certificate database * @param keydb The pathname for private key database * @param keypwd The password for private key database * @param certnickname The alias for certificate * @param keynickname The alias for key * @see netscape.ldap.LDAPSSLSocketFactory#isClientAuth * @see netscape.ldap.LDAPSSLSocketFactory#makeSocket * @exception LDAPException Since this method is not yet implemented, * calling this method throws an exception. */ public void enableClientAuth(String certdb, String keydb, String keypwd, String certnickname, String keynickname) throws LDAPException { throw new LDAPException("Client auth not supported now"); } /** * Returns true if client authentication is enabled. * @see netscape.ldap.LDAPSSLSocketFactory#enableClientAuth */ public boolean isClientAuth() { return m_isClientAuth; } /** * Returns the name of the class that implements SSL sockets for this factory. * * @return The name of the class that implements SSL sockets for this factory. */ public String getSSLSocketImpl() { return m_packageName; } /** * Returns the suite of ciphers used for SSL connections made through * sockets created by this factory. * * @return The suite of ciphers used. */ public Object getCipherSuites() { return m_cipherSuites; } /** * Returns a socket to the LDAP server with the specified * host name and port number. Before calling this method, * call enableClientAuth. * @param host The host to connect to * @param port The port number * @return The socket to the host name and port number. * @exception LDAPException A socket to the specified host and port * could not be created. * @see netscape.ldap.LDAPSSLSocketFactory#enableClientAuth */ public Socket makeSocket(String host, int port) throws LDAPException { Socket s = null; if (m_isClientAuth) { try { /* Check if running in Communicator; if so, enable client auth */ java.lang.reflect.Method m = LDAPCheckComm.getMethod( "netscape.security.PrivilegeManager", "enablePrivilege"); if (m != null) { Object[] args = new Object[1]; args[0] = new String("ClientAuth"); m.invoke( null, args); } } catch (Exception e) { throw new LDAPException("Invoking enablePrivilege: " + e.toString(), LDAPException.PARAM_ERROR); } } try { String cipherClassName = null; if (m_cipherSuites != null) cipherClassName = m_cipherSuites.getClass().getName(); /* Instantiate the SSLSocketFactory implementation, and find the right constructor */ Class c = Class.forName(m_packageName); java.lang.reflect.Constructor[] m = c.getConstructors(); for (int i = 0; i < m.length; i++) { /* Check if the signature is right: String, int */ Class[] params = m[i].getParameterTypes(); if ( (m_cipherSuites == null) && (params.length == 2) && (params[0].getName().equals("java.lang.String")) && (params[1].getName().equals("int")) ) { Object[] args = new Object[2]; args[0] = host; args[1] = new Integer(port); s = (Socket)(m[i].newInstance(args)); return s; } else if ( (m_cipherSuites != null) && (params.length == 3) && (params[0].getName().equals("java.lang.String")) && (params[1].getName().equals("int")) && (params[2].getName().equals(cipherClassName)) ) { Object[] args = new Object[3]; args[0] = host; args[1] = new Integer(port); args[2] = m_cipherSuites; s = (Socket)(m[i].newInstance(args)); return s; } } throw new LDAPException("No appropriate constructor in " + m_packageName, LDAPException.PARAM_ERROR); } catch (ClassNotFoundException e) { throw new LDAPException("Class " + m_packageName + " not found", LDAPException.PARAM_ERROR); } catch (Exception e) { throw new LDAPException("Failed to create SSL socket", LDAPException.CONNECT_ERROR); } } }