Updates TransportServer API so that JaasDualAuthenticationBroker can tell when its dealing with a TransportServer that will provide SSL connections and it can validate client certificate chains from ConnectionInfo.  Also updated the properties files to reflect the newly generated certificates. 

git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1400155 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Timothy A. Bish 2012-10-19 16:21:53 +00:00
parent 2db73e2b7e
commit 0fffe21720
14 changed files with 181 additions and 129 deletions

View File

@ -16,6 +16,16 @@
*/
package org.apache.activemq.transport.amqp;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import org.apache.activemq.broker.SslContext;
import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportServer;
@ -23,15 +33,6 @@ import org.apache.activemq.transport.tcp.TcpTransport;
import org.apache.activemq.transport.tcp.TcpTransportServer;
import org.apache.activemq.wireformat.WireFormat;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
public class AmqpNioSslTransportFactory extends AmqpNioTransportFactory {
SSLContext context;
@ -46,6 +47,11 @@ public class AmqpNioSslTransportFactory extends AmqpNioTransportFactory {
}
return transport;
}
@Override
public boolean isSslServer() {
return true;
}
};
}

View File

@ -17,10 +17,13 @@
package org.apache.activemq.security;
import org.apache.activemq.broker.*;
import org.apache.activemq.broker.jmx.ManagedTransportConnector;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.broker.Connector;
import org.apache.activemq.broker.EmptyBroker;
import org.apache.activemq.broker.TransportConnector;
import org.apache.activemq.command.ConnectionInfo;
import org.apache.activemq.transport.tcp.SslTransportServer;
/**
@ -86,7 +89,7 @@ public class JaasDualAuthenticationBroker extends BrokerFilter {
Connector connector = context.getConnector();
if (connector instanceof TransportConnector) {
TransportConnector transportConnector = (TransportConnector) connector;
isSSL = (transportConnector.getServer() instanceof SslTransportServer);
isSSL = transportConnector.getServer().isSslServer();
} else {
isSSL = false;
}

View File

@ -25,15 +25,15 @@ import org.apache.activemq.command.BrokerInfo;
/**
* A TransportServer asynchronously accepts {@see Transport} objects and then
* delivers those objects to a {@see TransportAcceptListener}.
*
*
*
*
*/
public interface TransportServer extends Service {
/**
* Registers an {@see TransportAcceptListener} which is notified of accepted
* channels.
*
*
* @param acceptListener
*/
void setAcceptListener(TransportAcceptListener acceptListener);
@ -41,7 +41,7 @@ public interface TransportServer extends Service {
/**
* Associates a broker info with the transport server so that the transport
* can do discovery advertisements of the broker.
*
*
* @param brokerInfo
*/
void setBrokerInfo(BrokerInfo brokerInfo);
@ -55,4 +55,14 @@ public interface TransportServer extends Service {
*/
InetSocketAddress getSocketAddress();
/**
* For TransportServers that provide SSL connections to their connected peers they should
* return true here if and only if they populate the ConnectionInfo command presented to
* the Broker with the peers certificate chain so that the broker knows it can use that
* information to authenticate the connected peer.
*
* @return true if this transport server provides SSL level security over its
* connections.
*/
boolean isSslServer();
}

View File

@ -24,7 +24,7 @@ import org.apache.activemq.command.BrokerInfo;
public class TransportServerFilter implements TransportServer {
protected final TransportServer next;
/**
* @param next
*/
@ -55,5 +55,8 @@ public class TransportServerFilter implements TransportServer {
public InetSocketAddress getSocketAddress() {
return next.getSocketAddress();
}
public boolean isSslServer() {
return next.isSslServer();
}
}

View File

@ -17,23 +17,6 @@
package org.apache.activemq.transport.nio;
import org.apache.activemq.broker.SslContext;
import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportServer;
import org.apache.activemq.transport.tcp.SslTransport;
import org.apache.activemq.transport.tcp.SslTransportFactory;
import org.apache.activemq.transport.tcp.TcpTransport;
import org.apache.activemq.transport.tcp.TcpTransportServer;
import org.apache.activemq.util.IOExceptionSupport;
import org.apache.activemq.util.IntrospectionSupport;
import org.apache.activemq.wireformat.WireFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
@ -41,6 +24,22 @@ import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Map;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.apache.activemq.broker.SslContext;
import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportServer;
import org.apache.activemq.transport.tcp.SslTransport;
import org.apache.activemq.transport.tcp.TcpTransportServer;
import org.apache.activemq.util.IOExceptionSupport;
import org.apache.activemq.util.IntrospectionSupport;
import org.apache.activemq.wireformat.WireFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NIOSSLTransportFactory extends NIOTransportFactory {
private static final Logger LOG = LoggerFactory.getLogger(NIOSSLTransportFactory.class);
SSLContext context;
@ -54,6 +53,11 @@ public class NIOSSLTransportFactory extends NIOTransportFactory {
}
return transport;
}
@Override
public boolean isSslServer() {
return true;
}
};
}

View File

@ -16,6 +16,16 @@
*/
package org.apache.activemq.transport.stomp;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import org.apache.activemq.broker.SslContext;
import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportServer;
@ -23,15 +33,6 @@ import org.apache.activemq.transport.tcp.TcpTransport;
import org.apache.activemq.transport.tcp.TcpTransportServer;
import org.apache.activemq.wireformat.WireFormat;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
public class StompNIOSSLTransportFactory extends StompNIOTransportFactory {
SSLContext context;
@ -46,6 +47,11 @@ public class StompNIOSSLTransportFactory extends StompNIOTransportFactory {
}
return transport;
}
@Override
public boolean isSslServer() {
return false;
}
};
}

View File

@ -31,38 +31,34 @@ import org.apache.activemq.wireformat.WireFormat;
/**
* An SSL TransportServer.
*
*
* Allows for client certificate authentication (refer to setNeedClientAuth for
* details).
* NOTE: Client certificate authentication is disabled by default.
* NOTE: Client certificate authentication is disabled by default.
*
*/
public class SslTransportServer extends TcpTransportServer {
// Specifies if sockets created from this server should needClientAuth.
private boolean needClientAuth;
// Specifies if sockets created from this server should wantClientAuth.
private boolean wantClientAuth;
/**
* Creates a ssl transport server for the specified url using the provided
* serverSocketFactory
*
*
* @param transportFactory The factory used to create transports when connections arrive.
* @param location The location of the broker to bind to.
* @param serverSocketFactory The factory used to create this server.
* @throws IOException passed up from TcpTransportFactory.
* @throws URISyntaxException passed up from TcpTransportFactory.
*/
public SslTransportServer(
SslTransportFactory transportFactory,
URI location,
SSLServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
public SslTransportServer(SslTransportFactory transportFactory, URI location, SSLServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
super(transportFactory, location, serverSocketFactory);
}
/**
* Sets whether client authentication should be required
* Must be called before {@link #bind()}
@ -72,21 +68,21 @@ public class SslTransportServer extends TcpTransportServer {
public void setNeedClientAuth(boolean needAuth) {
this.needClientAuth = needAuth;
}
/**
* Returns whether client authentication should be required.
*/
public boolean getNeedClientAuth() {
return this.needClientAuth;
}
/**
* Returns whether client authentication should be requested.
*/
public boolean getWantClientAuth() {
return this.wantClientAuth;
}
/**
* Sets whether client authentication should be requested.
* Must be called before {@link #bind()}
@ -96,13 +92,13 @@ public class SslTransportServer extends TcpTransportServer {
public void setWantClientAuth(boolean wantAuth) {
this.wantClientAuth = wantAuth;
}
/**
* Binds this socket to the previously specified URI.
*
*
* Overridden to allow for proper handling of needClientAuth.
*
* @throws IOException passed up from TcpTransportServer.
*
* @throws IOException passed up from TcpTransportServer.
*/
public void bind() throws IOException {
super.bind();
@ -112,13 +108,13 @@ public class SslTransportServer extends TcpTransportServer {
((SSLServerSocket)this.serverSocket).setWantClientAuth(true);
}
}
/**
* Used to create Transports for this server.
*
*
* Overridden to allow the use of SslTransports (instead of TcpTransports).
*
* @param socket The incoming socket that will be wrapped into the new Transport.
*
* @param socket The incoming socket that will be wrapped into the new Transport.
* @param format The WireFormat being used.
* @return The newly return (SSL) Transport.
* @throws IOException
@ -126,4 +122,10 @@ public class SslTransportServer extends TcpTransportServer {
protected Transport createTransport(Socket socket, WireFormat format) throws IOException {
return new SslTransport(format, (SSLSocket)socket);
}
@Override
public boolean isSslServer() {
return true;
}
}

View File

@ -54,9 +54,9 @@ import org.slf4j.LoggerFactory;
/**
* A TCP based implementation of {@link TransportServer}
*
*
* @author David Martin Clavo david(dot)martin(dot)clavo(at)gmail.com (logging improvement modifications)
*
*
*/
public class TcpTransportServer extends TransportServerThreadSupport implements ServiceListener{
@ -70,7 +70,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
protected long maxInactivityDurationInitalDelay = 10000;
protected int minmumWireFormatVersion;
protected boolean useQueueForAccept=true;
/**
* trace=true -> the Transport stack where this TcpTransport
* object will be, will have a TransportLogger layer
@ -114,12 +114,11 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
*/
protected int maximumConnections = Integer.MAX_VALUE;
protected int currentTransportCount=0;
public TcpTransportServer(TcpTransportFactory transportFactory, URI location, ServerSocketFactory serverSocketFactory) throws IOException, URISyntaxException {
super(location);
this.transportFactory = transportFactory;
this.serverSocketFactory = serverSocketFactory;
}
public void bind() throws IOException {
@ -130,10 +129,8 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
InetAddress addr = InetAddress.getByName(host);
try {
this.serverSocket = serverSocketFactory.createServerSocket(bind.getPort(), backlog, addr);
configureServerSocket(this.serverSocket);
} catch (IOException e) {
throw IOExceptionSupport.create("Failed to bind to server socket: " + bind + " due to: " + e, e);
}
@ -177,7 +174,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
/**
* Associates a broker info with the transport server so that the transport
* can do discovery advertisements of the broker.
*
*
* @param brokerInfo
*/
public void setBrokerInfo(BrokerInfo brokerInfo) {
@ -190,7 +187,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
public void setMaxInactivityDuration(long maxInactivityDuration) {
this.maxInactivityDuration = maxInactivityDuration;
}
public long getMaxInactivityDurationInitalDelay() {
return this.maxInactivityDurationInitalDelay;
}
@ -214,14 +211,14 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
public void setTrace(boolean trace) {
this.trace = trace;
}
public String getLogWriterName() {
return logWriterName;
}
public void setLogWriterName(String logFormat) {
this.logWriterName = logFormat;
}
}
public boolean isDynamicManagement() {
return dynamicManagement;
@ -235,11 +232,10 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
return startLogging;
}
public void setStartLogging(boolean startLogging) {
this.startLogging = startLogging;
}
/**
* @return the backlog
*/
@ -267,7 +263,6 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
public void setUseQueueForAccept(boolean useQueueForAccept) {
this.useQueueForAccept = useQueueForAccept;
}
/**
* pull Sockets from the ServerSocket
@ -304,7 +299,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
/**
* Allow derived classes to override the Transport implementation that this
* transport server creates.
*
*
* @param socket
* @param format
* @return
@ -322,7 +317,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
}
/**
* @param socket
* @param socket
* @param inetAddress
* @return real hostName
* @throws UnknownHostException
@ -341,7 +336,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
}
return result;
}
protected void doStart() throws Exception {
if(useQueueForAccept) {
Runnable run = new Runnable() {
@ -353,16 +348,16 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
handleSocket(sock);
}
}
} catch (InterruptedException e) {
LOG.info("socketQueue interuppted - stopping");
if (!isStopping()) {
onAcceptError(e);
}
}
}
};
socketHandlerThread = new Thread(null, run,
"ActiveMQ Transport Server Thread Handler: " + toString(),
@ -372,7 +367,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
socketHandlerThread.start();
}
super.doStart();
}
protected void doStop(ServiceStopper stopper) throws Exception {
@ -389,17 +384,17 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
protected final void handleSocket(Socket socket) {
try {
if (this.currentTransportCount >= this.maximumConnections) {
throw new ExceededMaximumConnectionsException("Exceeded the maximum " +
"number of allowed client connections. See the 'maximumConnections' " +
"property on the TCP transport configuration URI in the ActiveMQ " +
"configuration file (e.g., activemq.xml)");
throw new ExceededMaximumConnectionsException("Exceeded the maximum " +
"number of allowed client connections. See the 'maximumConnections' " +
"property on the TCP transport configuration URI in the ActiveMQ " +
"configuration file (e.g., activemq.xml)");
} else {
HashMap<String, Object> options = new HashMap<String, Object>();
options.put("maxInactivityDuration", Long.valueOf(maxInactivityDuration));
options.put("maxInactivityDurationInitalDelay",
options.put("maxInactivityDurationInitalDelay",
Long.valueOf(maxInactivityDurationInitalDelay));
options.put("minmumWireFormatVersion",
options.put("minmumWireFormatVersion",
Integer.valueOf(minmumWireFormatVersion));
options.put("trace", Boolean.valueOf(trace));
options.put("soTimeout", Integer.valueOf(soTimeout));
@ -417,7 +412,7 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
((ServiceSupport) transport).addServiceListener(this);
}
Transport configuredTransport =
Transport configuredTransport =
transportFactory.serverConfigure( transport, format, options);
getAcceptListener().onAccept(configuredTransport);
@ -432,32 +427,32 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
onAcceptError(e);
}
}
}
public int getSoTimeout() {
return soTimeout;
}
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
public int getSoTimeout() {
return soTimeout;
}
public int getSocketBufferSize() {
return socketBufferSize;
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
public void setSocketBufferSize(int socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
public int getSocketBufferSize() {
return socketBufferSize;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setSocketBufferSize(int socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
/**
* @return the maximumConnections
@ -473,7 +468,6 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
this.maximumConnections = maximumConnections;
}
public void started(Service service) {
this.currentTransportCount++;
}
@ -481,4 +475,9 @@ public class TcpTransportServer extends TransportServerThreadSupport implements
public void stopped(Service service) {
this.currentTransportCount--;
}
@Override
public boolean isSslServer() {
return false;
}
}

View File

@ -34,15 +34,14 @@ import org.apache.activemq.transport.TransportServer;
import org.apache.activemq.transport.TransportServerSupport;
import org.apache.activemq.transport.reliable.ReliableTransport;
import org.apache.activemq.transport.reliable.ReplayStrategy;
import org.apache.activemq.transport.reliable.Replayer;
import org.apache.activemq.util.ServiceStopper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A UDP based implementation of {@link TransportServer}
*
*
*
*
*/
public class UdpTransportServer extends TransportServerSupport {
@ -175,4 +174,9 @@ public class UdpTransportServer extends TransportServerSupport {
public InetSocketAddress getSocketAddress() {
return serverTransport.getLocalSocketAddress();
}
@Override
public boolean isSslServer() {
return false;
}
}

View File

@ -137,4 +137,9 @@ public class VMTransportServer implements TransportServer {
public int getConnectionCount() {
return connectionCount.intValue();
}
@Override
public boolean isSslServer() {
return false;
}
}

View File

@ -5,9 +5,9 @@
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
##
## http://www.apache.org/licenses/LICENSE-2.0
##
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,5 +15,5 @@
## limitations under the License.
## ---------------------------------------------------------------------------
client=CN=client, OU=activemq, O=apache, L=Unknown, ST=Unknown, C=Unknown
broker2=CN=broker2, OU=activemq, O=apache, L=Unknown, ST=Unknown, C=Unknown
client=CN=client, OU=activemq, O=apache
broker2=CN=broker2, OU=activemq, O=apache

View File

@ -5,9 +5,9 @@
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
##
## http://www.apache.org/licenses/LICENSE-2.0
##
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,5 +15,5 @@
## limitations under the License.
## ---------------------------------------------------------------------------
client=CN=client, OU=activemq, O=apache, L=Unknown, ST=Unknown, C=Unknown
broker1=CN=broker1, OU=activemq, O=apache, L=Unknown, ST=Unknown, C=Unknown
client=CN=client, OU=activemq, O=apache
broker1=CN=broker1, OU=activemq, O=apache

View File

@ -114,4 +114,9 @@ public class HttpTransportServer extends WebTransportServerSupport {
socketConnectorFactory.setTransportOptions(transportOptions);
super.setTransportOption(transportOptions);
}
@Override
public boolean isSslServer() {
return false;
}
}

View File

@ -100,4 +100,9 @@ public class WSTransportServer extends WebTransportServerSupport {
super.setTransportOption(transportOptions);
}
@Override
public boolean isSslServer() {
return false;
}
}