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
018package org.apache.activemq.transport.tcp;
019
020import java.io.IOException;
021import java.net.Socket;
022import java.net.URI;
023import java.net.URISyntaxException;
024
025import javax.net.ssl.SSLServerSocket;
026import javax.net.ssl.SSLServerSocketFactory;
027import javax.net.ssl.SSLSocket;
028
029import org.apache.activemq.transport.Transport;
030import 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 */
040public 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}