Package com.dbxml.labrador.http

Source Code of com.dbxml.labrador.http.SecureHTTPServer

package com.dbxml.labrador.http;

/*
* The dbXML Labrador Software License, Version 1.0
*
*
* Copyright (c) 2003 The dbXML Group, L.L.C.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by The
*        dbXML Group, L.L.C. (http://www.dbxml.com/)."
*    Alternately, this acknowledgment may appear in the software
*    itself, if and wherever such third-party acknowledgments normally
*    appear.
*
* 4. The names "Labrador" and "dbXML Group" must not be used to
*    endorse or promote products derived from this software without
*    prior written permission. For written permission, please contact
*    info@dbxml.com
*
* 5. Products derived from this software may not be called "Labrador",
*    nor may "Labrador" appear in their name, without prior written
*    permission of The dbXML Group, L.L.C..
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 DBXML GROUP, L.L.C. OR ITS
* 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.
* ====================================================================
*
* $Id: SecureHTTPServer.java,v 1.14 2004/02/27 16:20:36 bradford Exp $
*/

import javax.net.ssl.*;

import com.dbxml.labrador.broker.Broker;
import com.sun.net.ssl.internal.ssl.Provider;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Stack;

/**
* SecureHTTPServer is an incredibly simple HTTP Server implementation with
* the sole purpose of handling Labrador requests.  No static content, no
* virtual servers, no bells, no whistles.  Because Java 1.4.1 still doesn't
* support non-blocking SSL, this code is based on the older implementation.
* <br /><br />
* This server is implemented as a Daemon Thread, so in order to keep the
* VM alive, you'll have to either call setDaemon(false) or you'll need to
* have some other Thread keeping the VM alive.
* <br /><br />
* The Default port for this Secure HTTP Server is 7643.
*/

public final class SecureHTTPServer extends HTTPServerBase {
   private static final int ACCEPT_BACKLOG = 5;

   private static final String KEYSTORE_TYPE = "JKS";
   private static final String SSL_PROTOCOL = "TLS";
   private static final String CERT_ALGORITHM = "SunX509";

   public static final Object PROP_SSL_SESSION = new Object();

   private SSLServerSocket sock = null;
   private Stack workers = new Stack(); // of HTTPSWorker

   private String keyFile;
   private String keyPass;
   private String trustFile;
   private String trustPass;
   private boolean clientAuth;

   /**
    * main starts the SecureHTTPServer in standalone mode
    */
   public static void main(String[] args) {
      try {
         SecureHTTPServer server = new SecureHTTPServer();

         Broker.println(server.getName());

         server.setDaemon(false);

         // Start the server, and wait until it's ready
         synchronized ( server ) {
            server.start();
            server.wait();
         }

         Broker.println("Listening on " + server.getHostName() + " at port " + server.getPort());
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
         System.exit(1);
      }
   }

   public SecureHTTPServer() {
   }

   public SecureHTTPServer(String url) {
      super(url);
   }

   public SecureHTTPServer(URL url) {
      super(url);
   }

   protected String getThreadName() {
      return "Labrador Secure HTTP Server";
   }

   protected String getProtocol() {
      return "https";
   }

   protected int getDefaultPort() {
      return 7643;
   }

   /**
    * setKeyFile sets the name of the file that stores the Server's
    * keys.
    *
    * @param keyFile The Server Key file
    */
   public void setKeyFile(String keyFile) {
      this.keyFile = keyFile;
   }

   /**
    * getKeyFile returns the name of the file that stores the Server's
    * keys.
    *
    * @return The Server Key file
    */
   public String getKeyFile() {
      return keyFile;
   }

   /**
    * setKeyPass sets the pass phrase that will be used to decrypt
    * the Server's keys.
    *
    * @param keyPass The pass phrase
    */
   public void setKeyPass(String keyPass) {
      this.keyPass = keyPass;
   }

   /**
    * getKeyPass returns the pass phrase that will be used to decrypt
    * the Server's keys.
    *
    * @return The pass phrase
    */
   public String getKeyPass() {
      return keyPass;
   }

   /**
    * setTrustFile sets the name of the file that stores the Server's
    * trusted certs.
    *
    * @param trustFile The Server Trust file
    */
   public void setTrustFile(String trustFile) {
      this.trustFile = trustFile;
   }

   /**
    * getTrustFile returns the name of the file that stores the Server's
    * trusted certs.
    *
    * @return The Server Trust file
    */
   public String getTrustFile() {
      return trustFile;
   }

   /**
    * setTrustPass sets the pass phrase that will be used to decrypt
    * the Server's trusted certs.
    *
    * @param trustPass The pass phrase
    */
   public void setTrustPass(String trustPass) {
      this.trustPass = trustPass;
   }

   /**
    * getTrustPass returns the pass phrase that will be used to decrypt
    * the Server's trusted certs.
    *
    * @return The pass phrase
    */
   public String getTrustPass() {
      return trustPass;
   }

   /**
    * setClientAuth sets whether or not SSL client authentication will
    * be used for this server.
    *
    * @param clientAuth The client authentication setting
    */
   public void setClientAuth(boolean clientAuth) {
      this.clientAuth = clientAuth;
   }

   /**
    * getClientAuth returns whether or not SSL client authentication will
    * be used for this server.
    *
    * @return The client authentication setting
    */
   public boolean getClientAuth() {
      return clientAuth;
   }

   public void shutdown() {
      try {
         sock.close();
      }
      catch ( Exception e ) {
         Broker.printwarning("Error Closing Secure HTTP server socket");
         e.printStackTrace(System.err);
      }
   }

   protected void createServerSocket(InetAddress bindaddr) throws Exception {
      KeyManager[] kms = null;
      TrustManager[] tms = null;

      if ( keyFile != null && keyFile.length() > 0 ) {
         char[] pc = null;
         if ( keyPass != null )
            pc = keyPass.toCharArray();

         KeyStore ks = loadKeyStore(keyFile, pc);
         // Retrieve The Key Managers
         KeyManagerFactory kmf = KeyManagerFactory.getInstance(CERT_ALGORITHM);
         kmf.init(ks, pc);
         kms = kmf.getKeyManagers();
      }

      if ( trustFile != null && trustFile.length() > 0 ) {
         char[] pc = null;
         if ( trustPass != null )
            pc = trustPass.toCharArray();

         KeyStore ks = loadKeyStore(trustFile, pc);
         // Retrieve The Trust Managers
         TrustManagerFactory tmf = TrustManagerFactory.getInstance(CERT_ALGORITHM);
         tmf.init(ks);
         tms = tmf.getTrustManagers();
      }

      // Add the SSL Provider (if needed)
      try {
         Security.addProvider(new Provider());
      }
      catch ( Throwable t ) {
         t.printStackTrace(System.err);
      }

      // Create the SSL context
      SSLContext ctx = SSLContext.getInstance(SSL_PROTOCOL);

      // Initialize the context with key managers
      ctx.init(kms, tms, new SecureRandom());

      SSLServerSocketFactory ssf = ctx.getServerSocketFactory();
      if ( bindaddr != null )
         sock = (SSLServerSocket)ssf.createServerSocket(port, ACCEPT_BACKLOG, bindaddr);
      else
         sock = (SSLServerSocket)ssf.createServerSocket(port, ACCEPT_BACKLOG);

      sock.setNeedClientAuth(clientAuth);
   }

   private KeyStore loadKeyStore(String filename, char[] pass) throws Exception {
      KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
      FileInputStream fis = new FileInputStream(filename);
      ks.load(fis, pass);
      fis.close();
      return ks;
   }

   private void prepareSocket(Socket socket) {
      try {
         socket.setTcpNoDelay(true);
         socket.setSoLinger(true, linger);
         socket.setSoTimeout(timeout);
      }
      catch ( Exception e ) {
      }
   }

   public void acceptConnections() {
      try {
         while ( true ) {
            Socket socket = sock.accept();
            prepareSocket(socket);

            if ( !workers.isEmpty() ) {
               HTTPSWorker worker = (HTTPSWorker)workers.pop();
               worker.setSocket(socket);
               synchronized ( worker ) {
                  worker.notify();
               }
            }
            else
               new HTTPSWorker(socket).start();
         }
      }
      catch ( SocketException e ) {
         // If we get an exception here, it's probably because
         // the server is being shut down
      }
      catch ( Exception e ) {
         Broker.printerr("Error in Labrador Secure HTTP Server");
         e.printStackTrace(System.err);
      }
   }


   /**
    * HTTPSWorker
    */

   private class HTTPSWorker extends Worker {
      private Socket sock;
      private boolean keepalive = true;
      private boolean connected = true;

      public HTTPSWorker(Socket sock) {
         setSocket(sock);
      }

      protected String getThreadName() {
         return "Labrador Secure HTTP Worker";
      }

      public void handleConnection() {
         while ( true ) {
            do {
               remoteHost = sock.getInetAddress().getHostAddress();

               initRequest();

               try {
                  InputStream is = sock.getInputStream();
                  readRequest(is);
                  processRequest();
               }
               catch ( Exception e ) {
                  keepalive = false;
                  connected = false;
               }
            }
            while ( connected && keepalive );

            try {
               sock.close();
            }
            catch ( Exception e ) {
               Broker.printwarning("Error Closing HTTP client socket");
            }

            synchronized ( this ) {
               workers.push(this);
               try {
                  wait();
               }
               catch ( InterruptedException e ) {
                  e.printStackTrace(System.err);
               }
            }
         }
      }

      private void setSocket(Socket sock) {
         this.sock = sock;
         if ( sock instanceof SSLSocket )
            properties.put(PROP_SSL_SESSION, ((SSLSocket)sock).getSession());
      }

      public void send(int code, String message) {
         try {
            OutputStream os = sock.getOutputStream();
            send(os, code, message);
         }
         catch ( Exception e ) {
            keepalive = false;
            connected = false;
         }
      }
   }
}
TOP

Related Classes of com.dbxml.labrador.http.SecureHTTPServer

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.