/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.directory.studio.connection.core.io.jndi; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.directory.studio.connection.core.io.StudioTrustManager; /** * A {@link SSLSocketFactory} that uses a custom {@link TrustManager} ({@link StudioTrustManager}). * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class StudioSSLSocketFactory extends SSLSocketFactory { /** * Gets the default instance. In fact just creates a new * instance on each call to make sure the underlying * TrustManagers are newly initialized. * * Note: This method is invoked from Sun JNDI when * creating a ldaps:// connection. Must be public static! * * @return the default instance */ public static SSLSocketFactory getDefault() { return new StudioSSLSocketFactory(); } /** The delegate. */ private SSLSocketFactory delegate; /** The trust managers. */ private StudioTrustManager[] trustManagers; /** * Creates a new instance of StudioSSLSocketFactory. * * Note: This default constructor is invoked from Apache Harmony JNDI * when creating a ldaps:// connection. Must be public! */ public StudioSSLSocketFactory() { try { // get default trust managers (using JVM "cacerts" key store) TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); factory.init( ( KeyStore ) null ); TrustManager[] defaultTrustManagers = factory.getTrustManagers(); // create wrappers around the trust managers trustManagers = new StudioTrustManager[defaultTrustManagers.length]; for ( int i = 0; i < defaultTrustManagers.length; i++ ) { trustManagers[i] = new StudioTrustManager( ( X509TrustManager ) defaultTrustManagers[i] ); } // create the real socket factory SSLContext sc = SSLContext.getInstance( "TLS" ); //$NON-NLS-1$ sc.init( null, trustManagers, null ); delegate = sc.getSocketFactory(); } catch ( Exception e ) { e.printStackTrace(); throw new RuntimeException( e ); } } /** * {@inheritDoc} */ public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } /** * {@inheritDoc} */ public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } /** * {@inheritDoc} */ public Socket createSocket( Socket s, String host, int port, boolean autoClose ) throws IOException { try { updateTrustManagers( host ); return delegate.createSocket( s, host, port, autoClose ); } catch ( IOException e ) { e.printStackTrace(); throw e; } } /** * {@inheritDoc} */ public Socket createSocket( String host, int port ) throws IOException, UnknownHostException { try { updateTrustManagers( host ); return delegate.createSocket( host, port ); } catch ( IOException e ) { e.printStackTrace(); throw e; } } /** * {@inheritDoc} */ public Socket createSocket( InetAddress host, int port ) throws IOException { try { updateTrustManagers( host ); return delegate.createSocket( host, port ); } catch ( IOException e ) { e.printStackTrace(); throw e; } } /** * {@inheritDoc} */ public Socket createSocket( String host, int port, InetAddress localHost, int localPort ) throws IOException, UnknownHostException { try { updateTrustManagers( host ); return delegate.createSocket( host, port, localHost, localPort ); } catch ( IOException e ) { e.printStackTrace(); throw e; } } /** * {@inheritDoc} */ public Socket createSocket( InetAddress address, int port, InetAddress localAddress, int localPort ) throws IOException { try { updateTrustManagers( address ); return delegate.createSocket( address, port, localAddress, localPort ); } catch ( IOException e ) { e.printStackTrace(); throw e; } } private void updateTrustManagers( InetAddress address ) { updateTrustManagers( address.getHostName() ); } private void updateTrustManagers( String host ) { for ( StudioTrustManager trustManager : trustManagers ) { trustManager.setHost( host ); } } }