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         * Creates a ssl transport server for the specified url using the provided
050         * serverSocketFactory
051         *
052         * @param transportFactory The factory used to create transports when connections arrive.
053         * @param location The location of the broker to bind to.
054         * @param serverSocketFactory The factory used to create this server.
055         * @throws IOException passed up from TcpTransportFactory.
056         * @throws URISyntaxException passed up from TcpTransportFactory.
057         */
058        public SslTransportServer(SslTransportFactory transportFactory, URI location, SSLServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
059            super(transportFactory, location, serverSocketFactory);
060        }
061    
062        /**
063         * Sets whether client authentication should be required
064         * Must be called before {@link #bind()}
065         * Note: Calling this method clears the wantClientAuth flag
066         * in the underlying implementation.
067         */
068        public void setNeedClientAuth(boolean needAuth) {
069            this.needClientAuth = needAuth;
070        }
071    
072        /**
073         * Returns whether client authentication should be required.
074         */
075        public boolean getNeedClientAuth() {
076            return this.needClientAuth;
077        }
078    
079        /**
080         * Returns whether client authentication should be requested.
081         */
082        public boolean getWantClientAuth() {
083            return this.wantClientAuth;
084        }
085    
086        /**
087         * Sets whether client authentication should be requested.
088         * Must be called before {@link #bind()}
089         * Note: Calling this method clears the needClientAuth flag
090         * in the underlying implementation.
091         */
092        public void setWantClientAuth(boolean wantAuth) {
093            this.wantClientAuth = wantAuth;
094        }
095    
096        /**
097         * Binds this socket to the previously specified URI.
098         *
099         * Overridden to allow for proper handling of needClientAuth.
100         *
101         * @throws IOException passed up from TcpTransportServer.
102         */
103        public void bind() throws IOException {
104            super.bind();
105            if (needClientAuth) {
106                ((SSLServerSocket)this.serverSocket).setNeedClientAuth(true);
107            } else if (wantClientAuth) {
108                ((SSLServerSocket)this.serverSocket).setWantClientAuth(true);
109            }
110        }
111    
112        /**
113         * Used to create Transports for this server.
114         *
115         * Overridden to allow the use of SslTransports (instead of TcpTransports).
116         *
117         * @param socket The incoming socket that will be wrapped into the new Transport.
118         * @param format The WireFormat being used.
119         * @return The newly return (SSL) Transport.
120         * @throws IOException
121         */
122        protected Transport createTransport(Socket socket, WireFormat format) throws IOException {
123            return new SslTransport(format, (SSLSocket)socket);
124        }
125    
126        @Override
127        public boolean isSslServer() {
128            return true;
129        }
130    
131    }