Package org.jacorb.orb.iiop

Source Code of org.jacorb.orb.iiop.IIOPListener

package org.jacorb.orb.iiop;

/*
*        JacORB - a free Java ORB
*
*   Copyright (C) 1999-2004 Gerald Brose
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Library General Public
*   License as published by the Free Software Foundation; either
*   version 2 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Library General Public License for more details.
*
*   You should have received a copy of the GNU Library General Public
*   License along with this library; if not, write to the Free
*   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;

import org.omg.ETF.*;
import org.omg.CSIIOP.*;
import org.omg.SSLIOP.*;

import org.apache.avalon.framework.configuration.*;

import org.jacorb.orb.factory.*;
import org.jacorb.orb.etf.ProtocolAddressBase;

/**
* @author Andre Spiegel
* @version $Id: IIOPListener.java,v 1.28 2006/05/22 15:03:50 alphonse.bendt Exp $
*/
public class IIOPListener
    extends org.jacorb.orb.etf.ListenerBase
{
    /** the maximum set of security options supported by the SSL mechanism */
    private static final int MAX_SSL_OPTIONS = Integrity.value |
                                               Confidentiality.value |
                                               DetectReplay.value |
                                               DetectMisordering.value |
                                               EstablishTrustInTarget.value |
                                               EstablishTrustInClient.value;

    /**  the minimum set of security options supported by the SSL mechanism
     *   which cannot be turned off, so they are always supported
     */
    private static final int MIN_SSL_OPTIONS = Integrity.value |
                                               DetectReplay.value |
                                               DetectMisordering.value;


    private SocketFactoryManager socketFactoryManager = null;
    private ServerSocketFactory    serverSocketFactory    = null;
    private SSLServerSocketFactory sslServerSocketFactory = null;

    private SSLAcceptor sslAcceptor = null;
    private LoopbackAcceptor loopbackAcceptor ;

    private boolean supportSSL = false;
    //    private boolean dnsEnabled = false;
    private int serverTimeout = 0;
    private IIOPAddress address = null;
    private IIOPAddress sslAddress = null;
    private int target_supports = 0;
    private int target_requires = 0;
    private boolean generateSSLComponents = true;

    public IIOPListener()
    {
    }

    public void configure(Configuration configuration)
        throws ConfigurationException
    {
        this.configuration = (org.jacorb.config.Configuration)configuration;

        if (orb == null)
        {
            // c.f. with the constructor taking an ORB param.
            this.orb = this.configuration.getORB();
            socketFactoryManager = new SocketFactoryManager(this.orb);
        }

        logger = this.configuration.getNamedLogger("jacorb.iiop.listener");

        socketFactoryManager.configure(configuration);

        String address_str = configuration.getAttribute("OAAddress",null);
        if (address_str != null) {
            ProtocolAddressBase ep = orb.createAddress(address_str);
            if (ep instanceof IIOPAddress)
                address = (IIOPAddress)ep;
        }
        else {
            int oaPort = configuration.getAttributeAsInteger("OAPort",0);
            String oaHost = configuration.getAttribute("OAIAddr","");
            address = new IIOPAddress(oaHost,oaPort);
        }

        if (address != null)
            address.configure (configuration);

        address_str = configuration.getAttribute("OASSLAddress",null);
        if (address_str != null) {
            ProtocolAddressBase ep = orb.createAddress(address_str);
            if (ep instanceof IIOPAddress)
                sslAddress = (IIOPAddress)ep;
        }
        else {
            int sslPort = configuration.getAttributeAsInteger("OASSLPort",0);
            String sslHost = configuration.getAttribute("OAIAddr","");
            sslAddress = new IIOPAddress(sslHost,sslPort);
        }

        if (sslAddress != null)
            sslAddress.configure (configuration);

        serverTimeout =
            configuration.getAttributeAsInteger("jacorb.connection.server.timeout",0);

        supportSSL =
            configuration.getAttribute("jacorb.security.support_ssl","off").equals("on");

        target_supports =
            Integer.parseInt(
                configuration.getAttribute("jacorb.security.ssl.server.supported_options","20"),
                16); // 16 is the base as we take the string value as hex!

        // make sure that the minimum options are always in the set of supported options
        target_supports |= MIN_SSL_OPTIONS;

        target_requires =
            Integer.parseInt(
                configuration.getAttribute("jacorb.security.ssl.server.required_options","0"),
                16);


        generateSSLComponents =
            configuration.getAttribute("jacorb.security.ssl_components_added_by_ior_interceptor","off").equals("off");


        if (!isSSLRequired() ||
            configuration.getAttributeAsBoolean("jacorb.security.ssl.always_open_unsecured_address", false))
        {
            acceptor = new Acceptor("ServerSocketListener");
            ((Acceptor)acceptor).init();
        }

        if (supportSSL)
        {
            sslAcceptor = new SSLAcceptor();
            sslAcceptor.init();
        }

        loopbackAcceptor = new LoopbackAcceptor() ;

        profile = createAddressProfile();

    }


    /**
     * It is possible that connection requests arrive <i>after</i> the
     * initial creation of the Listener instance but <i>before</i> the
     * conclusion of the configuration of the specific address in this
     * plugin. In order to provide a clear end of this configuration state,
     * we added the listen() method. It is called by the ORB when it ready
     * for incoming connection and thus signals the Listener instance to
     * start processing the incoming connection requests. Therefore,
     * a Listener instance shall not deliver incoming connections to the
     * ORB before this method was called.
     */
    public void listen()
    {
        super.listen();

        if (sslAcceptor != null)
            sslAcceptor.start();

        loopbackAcceptor.start() ;
    }

    /**
     * The Listener is instructed to close its address. It shall no
     * longer accept any connection requests and shall close all
     * connections opened by it.
     */
    public void destroy()
    {
        loopbackAcceptor.terminate() ;

        if (sslAcceptor != null)
            sslAcceptor.terminate();

        super.destroy();
    }

    // internal methods below this line

    /**
     * Returns true if this Listener should support SSL connections.
     */
    private boolean isSSLSupported()
    {
        return  supportSSL;
    }

    /**
     * Returns true if this Listener should <i>require</i> SSL, and not
     * offer plain connections.
     */
    private boolean isSSLRequired()
        throws ConfigurationException
    {
        if (isSSLSupported())
        {
            // the following is used as a bit mask to check if any SSL
            // options are required
            return ((target_requires & MAX_SSL_OPTIONS ) != 0);
        }
        return false;
    }

    /**
     * Returns the server timeout that has been specified, or zero if none
     * has been set.
     */
    private int getServerTimeout()
    {
        return serverTimeout;
    }

    private ServerSocketFactory getServerSocketFactory()
    {
        if (serverSocketFactory == null)
        {
            serverSocketFactory =
                socketFactoryManager.getServerSocketFactory();
        }
        return serverSocketFactory;
    }

    /**
     * Returns the SSLServerSocketFactory that has been configured.
     * If no such factory is available, org.omg.CORBA.INITIALIZE() is thrown.
     */
    private SSLServerSocketFactory getSSLServerSocketFactory()
    {
        if (sslServerSocketFactory == null)
        {
            sslServerSocketFactory =
                orb.getBasicAdapter().getSSLSocketFactory();

            if (sslServerSocketFactory == null)
                throw new org.omg.CORBA.INITIALIZE("No SSL server socket factory found");
        }
        return sslServerSocketFactory;
    }

    /**
     * Creates a new IIOPProfile that describes this transport address.
     */
    private IIOPProfile createAddressProfile()
        throws ConfigurationException
    {
        if (acceptor != null)
        {

            if (address.getPort() == 0)
            {
                address.setPort(((Acceptor)acceptor).getLocalAddress().getPort());
            }
            else
            {
                if (logger.isDebugEnabled())
                {
                    logger.debug ("Using port " + address.getPort());
                }
            }
        }
        else if (sslAcceptor == null)
        {
            throw new org.omg.CORBA.INITIALIZE
                ("no acceptors found, cannot create address profile");
        }

        IIOPProfile result = new IIOPProfile(address,null);
        if (sslAcceptor != null && generateSSLComponents)
        {
             result.addComponent (TAG_SSL_SEC_TRANS.value,
                                  createSSL(), SSLHelper.class);
        }

        result.configure(configuration);
        return result;
    }

    private SSL createSSL()
    {
        return new SSL
        (
            (short)target_supports,
            (short)target_requires,
            (short)sslAcceptor.getLocalAddress().getPort()
        );
    }

    /**
     * Creates an ETF connection around a live socket and passes it
     * up to the ORB, using either the upcall mechanism or the
     * polling mechanism.
     */
    private void deliverConnection (Socket socket, boolean isSSL)
    {
        Connection result = null;
        try
        {
            result = createServerConnection(socket, isSSL);
        }
        catch (IOException ex)
        {
            if (logger.isErrorEnabled())
            {
                logger.error("Could not create connection from socket: " + ex);
            }
            return;
        }

        deliverConnection(result);
    }

    /**
     * Template method to create a server-side ETF Connection.
     * This can be overridden by subclasses to pass a different
     * kind of Connection up to the ORB.
     */
    protected Connection createServerConnection (Socket socket,
                                                 boolean is_ssl)
        throws IOException
    {
        ServerIIOPConnection result = new ServerIIOPConnection(socket, is_ssl);
        try
        {
            result.configure(configuration);
        }
        catch( ConfigurationException ce )
        {
            throw new org.omg.CORBA.INTERNAL("ConfigurationException: " + ce.toString());
        }
        return result;
    }

    // Acceptor classes below this line

    protected class Acceptor
        extends org.jacorb.orb.etf.ListenerBase.Acceptor
    {
        protected ServerSocket serverSocket;

        protected boolean terminated = false;

        protected Acceptor(String name)
        {
            super();
            // initialization deferred to init() method due to JDK bug
            setDaemon(true);
            setName(name);
        }

        public void init()
        {
            serverSocket = createServerSocket();

            if( logger.isDebugEnabled() )
            {
                logger.debug( "Created socket listener on " +
                              serverSocket.getInetAddress() + ":" + serverSocket.getLocalPort() );
            }
       }

        public void run()
        {
            while (!terminated)
            {
                try
                {
                    Socket socket = serverSocket.accept();
                    setup (socket);
                    deliverConnection (socket);
                }
                catch (Exception e)
                {
                    if (!terminated)
                    {
                        if (logger.isWarnEnabled())
                        {
                            logger.warn(e.toString());
                        }
                    }
                }
            }
            if (logger.isInfoEnabled())
            {
                logger.info( "Listener exited");
            }
        }

        /**
         * Terminates this Acceptor by closing the ServerSocket.
         */
        public void terminate()
        {
            terminated = true;
            try
            {
                serverSocket.close();
            }
            catch (java.io.IOException e)
            {
                if (logger.isWarnEnabled())
                {
                    logger.warn(e.toString());
                }
            }
        }

        public IIOPAddress getLocalAddress()
        {
            IIOPAddress ep = new IIOPAddress
            (
                serverSocket.getInetAddress().toString(),
                serverSocket.getLocalPort()
            );
            if (configuration != null)
                try {
                    ep.configure(configuration);
                }
                catch( ConfigurationException ce) {
                    if (logger.isWarnEnabled())
                        logger.warn("ConfigurationException", ce );
                }
            return ep;
        }

        /**
         * Template method that creates the server socket.
         */
        protected ServerSocket createServerSocket()
        {
            try
            {
                return getServerSocketFactory()
                           .createServerSocket (address.getPort(),
                                                20,
                                                address.getConfiguredHost());
            }
            catch (IOException ex)
            {
                logger.warn("could not create server socket", ex);
                throw new org.omg.CORBA.INITIALIZE ("Could not create server socket");
            }
        }

        /**
         * Template method that sets up the socket right after the
         * connection has been established.  Subclass implementations
         * must call super.setup() first.
         */
        protected void setup(Socket socket)
            throws IOException
        {
             socket.setSoTimeout(serverTimeout);
        }

        protected void deliverConnection(Socket socket)
        {
            IIOPListener.this.deliverConnection (socket, false);
        }
    }

    private class SSLAcceptor
        extends Acceptor
    {
        private SSLAcceptor()
        {
            super("SSLServerSocketListener");
        }

        protected ServerSocket createServerSocket()
        {
            try
            {
                return getSSLServerSocketFactory()
                            .createServerSocket (sslAddress.getPort(),
                                                 20,
                                                 sslAddress.getConfiguredHost());
            }
            catch (IOException e)
            {
                logger.warn("could not create SSL server socket", e);
                throw new org.omg.CORBA.INITIALIZE
                                           ("Could not create SSL server socket");
            }
        }

        protected void deliverConnection(Socket socket)
        {
            IIOPListener.this.deliverConnection (socket, true);
        }
    }

    private class LoopbackAcceptor implements IIOPLoopback
    {
        public void start()
        {
            IIOPLoopbackRegistry.getRegistry().register(getAddress(), this);
        }

        public void terminate()
        {
            IIOPLoopbackRegistry.getRegistry().unregister(getAddress());
        }

        public void initLoopback(final IIOPLoopbackInputStream lis,
                                 final IIOPLoopbackOutputStream los)
        {
            final IIOPLoopbackConnection connection =
                new IIOPLoopbackConnection(lis, los) ;
            deliverConnection(connection);
        }

        private IIOPAddress getAddress()
        {
            final IIOPProfile profile =
                (IIOPProfile)IIOPListener.this.profile;
            return (IIOPAddress)profile.getAddress();
        }
    }
}
TOP

Related Classes of org.jacorb.orb.iiop.IIOPListener

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.