content: package com._17od.upm.transport;
  
  /*
   * $HeadURL$
   * $Revision$
   * $Date$
   * 
   * ====================================================================
   *
   *  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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  import java.io.IOException;
  import java.net.InetAddress;
  import java.net.InetSocketAddress;
  import java.net.Socket;
  import java.net.SocketAddress;
  import java.net.UnknownHostException;
  
  import javax.net.SocketFactory;
  import javax.net.ssl.SSLContext;
  import javax.net.ssl.TrustManager;
  
  import org.apache.commons.httpclient.ConnectTimeoutException;
  import org.apache.commons.httpclient.HttpClientError;
  import org.apache.commons.httpclient.params.HttpConnectionParams;
  import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   * <p>
   * Copied from http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java?revision=661391&view=co
   * </p>
   * <p>
   * EasySSLProtocolSocketFactory can be used to create SSL {@link Socket}s 
   * that accept self-signed certificates. 
   * </p>
   * <p>
   * This socket factory SHOULD NOT be used for productive systems 
   * due to security reasons, unless it is a concious decision and 
   * you are perfectly aware of security implications of accepting 
   * self-signed certificates
   * </p>
   *
   * <p>
   * Example of using custom protocol socket factory for a specific host:
   *     <pre>
   *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
   *
   *     URI uri = new URI("https://localhost/", true);
   *     // use relative url only
   *     GetMethod httpget = new GetMethod(uri.getPathQuery());
   *     HostConfiguration hc = new HostConfiguration();
   *     hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
   *     HttpClient client = new HttpClient();
   *     client.executeMethod(hc, httpget);
   *     </pre>
   * </p>
   * <p>
   * Example of using custom protocol socket factory per default instead of the standard one:
   *     <pre>
   *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
   *     Protocol.registerProtocol("https", easyhttps);
   *
   *     HttpClient client = new HttpClient();
   *     GetMethod httpget = new GetMethod("https://localhost/");
   *     client.executeMethod(httpget);
   *     </pre>
   * </p>
   * 
   * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
   * 
   * <p>
   * DISCLAIMER: HttpClient developers DO NOT actively support this component.
   * The component is provided as a reference material, which may be inappropriate
   * for use without additional customization.
   * </p>
   */
  
  public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
  
      /** Log object for this class. */
      private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class);
  
      private SSLContext sslcontext = null;
  
      /**
       * Constructor for EasySSLProtocolSocketFactory.
       */
      public EasySSLProtocolSocketFactory() {
          super();
      }
  
      private static SSLContext createEasySSLContext() {
          try {
              SSLContext context = SSLContext.getInstance("SSL");
              context.init(
                null, 
                new TrustManager[] {new EasyX509TrustManager(null)}, 
                null);
              return context;
          } catch (Exception e) {
              LOG.error(e.getMessage(), e);
              throw new HttpClientError(e.toString());
          }
      }
  
      private SSLContext getSSLContext() {
          if (this.sslcontext == null) {
              this.sslcontext = createEasySSLContext();
          }
          return this.sslcontext;
      }
  
      /**
       * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
       */
      public Socket createSocket(
          String host,
          int port,
          InetAddress clientHost,
          int clientPort)
          throws IOException, UnknownHostException {
  
          return getSSLContext().getSocketFactory().createSocket(
              host,
              port,
              clientHost,
              clientPort
          );
      }
  
      /**
       * Attempts to get a new socket connection to the given host within the given time limit.
       * <p>
       * To circumvent the limitations of older JREs that do not support connect timeout a 
       * controller thread is executed. The controller thread attempts to create a new socket 
       * within the given limit of time. If socket constructor does not return until the 
       * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
       * </p>
       *  
       * @param host the host name/IP
       * @param port the port on the host
       * @param clientHost the local host name/IP to bind the socket to
       * @param clientPort the port on the local machine
       * @param params {@link HttpConnectionParams Http connection parameters}
       * 
       * @return Socket a new socket
       * 
       * @throws IOException if an I/O error occurs while creating the socket
       * @throws UnknownHostException if the IP address of the host cannot be
       * determined
       */
      public Socket createSocket(
          final String host,
          final int port,
          final InetAddress localAddress,
          final int localPort,
          final HttpConnectionParams params
      ) throws IOException, UnknownHostException, ConnectTimeoutException {
          if (params == null) {
              throw new IllegalArgumentException("Parameters may not be null");
          }
          int timeout = params.getConnectionTimeout();
          SocketFactory socketfactory = getSSLContext().getSocketFactory();
          if (timeout == 0) {
              return socketfactory.createSocket(host, port, localAddress, localPort);
          } else {
              Socket socket = socketfactory.createSocket();
              SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
              SocketAddress remoteaddr = new InetSocketAddress(host, port);
              socket.bind(localaddr);
              socket.connect(remoteaddr, timeout);
              return socket;
          }
      }
  
      /**
       * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
       */
      public Socket createSocket(String host, int port)
          throws IOException, UnknownHostException {
          return getSSLContext().getSocketFactory().createSocket(
              host,
              port
          );
      }
  
      /**
       * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
       */
      public Socket createSocket(
          Socket socket,
          String host,
          int port,
          boolean autoClose)
          throws IOException, UnknownHostException {
          return getSSLContext().getSocketFactory().createSocket(
              socket,
              host,
              port,
              autoClose
          );
      }
  
      public boolean equals(Object obj) {
          return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class));
      }
  
      public int hashCode() {
          return EasySSLProtocolSocketFactory.class.hashCode();
      }
  
  }
  