Package sos.net

Source Code of sos.net.SOSSSLSocketFactory

/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 Software- und Organisations-Service GmbH.
** All rights reserved.
**
** This file may be used under the terms of either the
**
**   GNU General Public License version 2.0 (GPL)
**
**   as published by the Free Software Foundation
**   http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
**   LICENSE.GPL included in the packaging of this file.
**
** or the
** 
**   Agreement for Purchase and Licensing
**
**   as offered by Software- und Organisations-Service GmbH
**   in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package sos.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

/**
* <p>Title: SOSSSLSocketFactory</p>
* <p>Description: factory for SSL sockets with HTTP Proxy support </p> 
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: SOS GmbH</p>
* @author <a href="mailto:ghassan.beydoun@sos-berlin.com">Ghassan Beydoun</a>
* @version $Id: SOSSSLSocketFactory.java 14434 2011-05-23 07:01:48Z sos $
*/

public class SOSSSLSocketFactory extends SSLSocketFactory /* implements org.apache.commons.net.ftp.FTPSocketFactory */  {

  private SSLSocketFactory  sslFactory;

  private String        proxyHost;

  private int          proxyPort      = 3128;
  private boolean        done        = false;

  private final String    SECURITY_PROTOCOL  = "TLS";

  private String        securityProtocol  = SECURITY_PROTOCOL;

  /**
   * @param pproxyHost
   *            HTTP Proxy
   * @param pproxyPort
   * @param psecurityProtocol for example TLS or SSL
   */
  public SOSSSLSocketFactory(String pproxyHost, int pproxyPort, String psecurityProtocol) {
    this();
    this.proxyHost = pproxyHost;
    this.proxyPort = pproxyPort;
    this.securityProtocol = psecurityProtocol;
  }

  /**
   * @param pproxyHost
   *            HTTP Proxy
   * @param pproxyPort
   */
  public SOSSSLSocketFactory(String pproxyHost, int pproxyPort) {
    this();
    this.proxyHost = pproxyHost;
    this.proxyPort = pproxyPort;
  }

  public SOSSSLSocketFactory() {

    SSLContext sslcontext = null;
    try {
      sslcontext = SSLContext.getInstance(securityProtocol);
    }
    catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
    if (sslcontext != null) {
      try {
        sslcontext.init(null, new TrustManager[] { new SOSTrustManager() }, new java.security.SecureRandom());
      }
      catch (KeyManagementException e) {
        e.printStackTrace();
      }
      sslFactory = sslcontext.getSocketFactory();
    }
  }

  public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
    return sslFactory.createSocket(host, port);
  }

  public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
    return sslFactory.createSocket(host, port, clientHost, clientPort);
  }

  public Socket createSocket(InetAddress host, int port) throws IOException {
    return createSocket(null, host.getHostName(), port, true);
  }

  public Socket createSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort) throws IOException {
    return createSocket(null, address.getHostName(), port, true);
  }

  public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {

    // http proxy is available
    if (proxyHost != null && proxyHost.length() > 0) {

      Socket tunnel = new Socket(proxyHost, proxyPort);

      doTunnelHandshake(tunnel, host, port);

      SSLSocket sslSocket = (SSLSocket) sslFactory.createSocket(tunnel, host, port, autoClose);

      sslSocket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
        public void handshakeCompleted(HandshakeCompletedEvent event) {
          // Handshake finished!"
          done = true;
        }
      });
      if (!done)
        sslSocket.startHandshake();

      return sslSocket;

    }
    else {
      return sslFactory.createSocket(socket, host, port, autoClose);
    }
  }

  private void doTunnelHandshake(Socket tunnel, String host, int port) throws IOException {
    OutputStream out = tunnel.getOutputStream();
    String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n" + "User-Agent: " + sun.net.www.protocol.http.HttpURLConnection.userAgent + "\r\n\r\n";
    byte b[];
    try {
      /*
       * We really do want ASCII7 -- the http protocol doesn't change with
       * locale.
       */
      b = msg.getBytes("ASCII7");
    }
    catch (UnsupportedEncodingException ignored) {
      /*
       * If ASCII7 isn't there, something serious is wrong, but Paranoia
       * Is Good (tm)
       */
      b = msg.getBytes();
    }
    out.write(b);
    out.flush();

    /*
     * We need to store the reply so we can create a detailed error message
     * to the user.
     */
    byte reply[] = new byte[200];
    int replyLen = 0;
    int newlinesSeen = 0;
    boolean headerDone = false; /* Done on first newline */

    InputStream in = tunnel.getInputStream();

    while (newlinesSeen < 2) {
      int i = in.read();
      if (i < 0) {
        throw new IOException("Unexpected EOF from proxy");
      }
      if (i == '\n') {
        headerDone = true;
        ++newlinesSeen;
      }
      else
        if (i != '\r') {
          newlinesSeen = 0;
          if (!headerDone && replyLen < reply.length) {
            reply[replyLen++] = (byte) i;
          }
        }
    }

    /*
     * Converting the byte array to a string is slightly wasteful in the
     * case where the connection was successful, but it's insignificant
     * compared to the network overhead.
     */
    String replyStr;
    try {
      replyStr = new String(reply, 0, replyLen, "ASCII7");
    }
    catch (UnsupportedEncodingException ignored) {
      replyStr = new String(reply, 0, replyLen);
    }

    /* Look for 200 connection established */
    if (replyStr.toLowerCase().indexOf("200 connection established") == -1) {
      throw new IOException("Unable to tunnel through " + proxyHost + ":" + proxyPort + ".  Proxy returns \"" + replyStr + "\"");
    }

    /* tunneling Handshake was successful! */
  }

  public String[] getDefaultCipherSuites() {
    return sslFactory.getDefaultCipherSuites();
  }

  public String[] getSupportedCipherSuites() {
    return sslFactory.getSupportedCipherSuites();
  }

  public ServerSocket createServerSocket(int arg0) throws IOException {
    // TODO Auto-generated method stub
    return null;
  }

  public ServerSocket createServerSocket(int arg0, int arg1) throws IOException {
    // TODO Auto-generated method stub
    return null;
  }

  public ServerSocket createServerSocket(int arg0, int arg1, InetAddress arg2) throws IOException {
    // TODO Auto-generated method stub
    return null;
  }

}
TOP

Related Classes of sos.net.SOSSSLSocketFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.