001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.activemq.transport.tcp;
019    
020    import java.io.IOException;
021    import java.net.Socket;
022    import java.net.URI;
023    import java.net.URISyntaxException;
024    
025    import javax.net.ssl.SSLServerSocket;
026    import javax.net.ssl.SSLServerSocketFactory;
027    import javax.net.ssl.SSLSocket;
028    
029    import org.apache.activemq.transport.Transport;
030    import org.apache.activemq.wireformat.WireFormat;
031    
032    /**
033     *  An SSL TransportServer.
034     * 
035     *  Allows for client certificate authentication (refer to setNeedClientAuth for
036     *      details).
037     *  NOTE: Client certificate authentication is disabled by default. 
038     *
039     */
040    public class SslTransportServer extends TcpTransportServer {
041        
042        // Specifies if sockets created from this server should needClientAuth.
043        private boolean needClientAuth;
044        
045        // Specifies if sockets created from this server should wantClientAuth.
046        private boolean wantClientAuth;
047        
048        
049        /**
050         * Creates a ssl transport server for the specified url using the provided
051         * serverSocketFactory
052         * 
053         * @param transportFactory The factory used to create transports when connections arrive.
054         * @param location The location of the broker to bind to.
055         * @param serverSocketFactory The factory used to create this server.
056         * @throws IOException passed up from TcpTransportFactory.
057         * @throws URISyntaxException passed up from TcpTransportFactory.
058         */
059        public SslTransportServer(
060                SslTransportFactory transportFactory,
061                URI location,
062                SSLServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
063            super(transportFactory, location, serverSocketFactory);
064        }
065        
066        /**
067         * Sets whether client authentication should be required
068         * Must be called before {@link #bind()}
069         * Note: Calling this method clears the wantClientAuth flag
070         * in the underlying implementation.
071         */
072        public void setNeedClientAuth(boolean needAuth) {
073            this.needClientAuth = needAuth;
074        }
075        
076        /**
077         * Returns whether client authentication should be required.
078         */
079        public boolean getNeedClientAuth() {
080            return this.needClientAuth;
081        }
082        
083        /**
084         * Returns whether client authentication should be requested.
085         */
086        public boolean getWantClientAuth() {
087            return this.wantClientAuth;
088        }
089        
090        /**
091         * Sets whether client authentication should be requested.
092         * Must be called before {@link #bind()}
093         * Note: Calling this method clears the needClientAuth flag
094         * in the underlying implementation.
095         */
096        public void setWantClientAuth(boolean wantAuth) {
097            this.wantClientAuth = wantAuth;
098        }
099        
100        /**
101         * Binds this socket to the previously specified URI.
102         * 
103         * Overridden to allow for proper handling of needClientAuth.
104         * 
105         * @throws IOException passed up from TcpTransportServer. 
106         */
107        public void bind() throws IOException {
108            super.bind();
109            if (needClientAuth) {
110                ((SSLServerSocket)this.serverSocket).setNeedClientAuth(true);
111            } else if (wantClientAuth) {
112                ((SSLServerSocket)this.serverSocket).setWantClientAuth(true);
113            }
114        }
115        
116        /**
117         * Used to create Transports for this server.
118         * 
119         * Overridden to allow the use of SslTransports (instead of TcpTransports).
120         * 
121         * @param socket The incoming socket that will be wrapped into the new Transport. 
122         * @param format The WireFormat being used.
123         * @return The newly return (SSL) Transport.
124         * @throws IOException
125         */
126        protected Transport createTransport(Socket socket, WireFormat format) throws IOException {
127            return new SslTransport(format, (SSLSocket)socket);
128        }
129    }