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     * 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    @Override
104    public void bind() throws IOException {
105        super.bind();
106        if (needClientAuth) {
107            ((SSLServerSocket)this.serverSocket).setNeedClientAuth(true);
108        } else if (wantClientAuth) {
109            ((SSLServerSocket)this.serverSocket).setWantClientAuth(true);
110        }
111    }
112
113    /**
114     * Used to create Transports for this server.
115     *
116     * Overridden to allow the use of SslTransports (instead of TcpTransports).
117     *
118     * @param socket The incoming socket that will be wrapped into the new Transport.
119     * @param format The WireFormat being used.
120     * @return The newly return (SSL) Transport.
121     * @throws IOException
122     */
123    @Override
124    protected Transport createTransport(Socket socket, WireFormat format) throws IOException {
125        return new SslTransport(format, (SSLSocket)socket);
126    }
127
128    @Override
129    public boolean isSslServer() {
130        return true;
131    }
132
133}