git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@825008 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Davies 2009-10-14 05:07:45 +00:00
parent 43bd686a2c
commit f866f770e3
13 changed files with 218 additions and 33 deletions

View File

@ -361,7 +361,11 @@ public class ProtocolConverter {
}
for (Iterator<StompSubscription> iter = subscriptionsByConsumerId.values().iterator(); iter.hasNext();) {
StompSubscription sub = iter.next();
try {
sub.onStompAbort(activemqTx);
} catch (Exception e) {
throw new ProtocolException("Transaction abort failed", false, e);
}
}
TransactionInfo tx = new TransactionInfo();
@ -483,6 +487,7 @@ public class ProtocolConverter {
connectionInfo.setResponseRequired(true);
connectionInfo.setUserName(login);
connectionInfo.setPassword(passcode);
connectionInfo.setTransportContext(transportFilter.getPeerCertificates());
sendToActiveMQ(connectionInfo, new ResponseHandler() {
public void onResponse(ProtocolConverter converter, Response response) throws IOException {

View File

@ -17,13 +17,16 @@
package org.apache.activemq.transport.stomp;
import java.io.IOException;
import java.security.cert.X509Certificate;
import javax.jms.JMSException;
import org.apache.activemq.command.Command;
import org.apache.activemq.transport.Transport;
import org.apache.activemq.transport.TransportFilter;
import org.apache.activemq.transport.TransportListener;
import org.apache.activemq.transport.tcp.SslTransport;
import org.apache.activemq.util.IOExceptionSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -64,6 +67,7 @@ public class StompTransportFilter extends TransportFilter {
if (trace) {
LOG.trace("Received: \n" + command);
}
protocolConverter.onStompCommand((StompFrame)command);
} catch (IOException e) {
onException(e);
@ -93,6 +97,17 @@ public class StompTransportFilter extends TransportFilter {
return frameTranslator;
}
public X509Certificate[] getPeerCertificates() {
if(next instanceof SslTransport) {
X509Certificate[] peerCerts = ((SslTransport)next).getPeerCertificates();
if (trace && peerCerts != null) {
LOG.debug("Peer Identity has been verified\n");
}
return peerCerts;
}
return null;
}
public boolean isTrace() {
return trace;
}

View File

@ -27,8 +27,8 @@ import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.apache.activemq.command.Command;
import org.apache.activemq.command.ConnectionInfo;
import org.apache.activemq.wireformat.WireFormat;
/**
@ -86,6 +86,15 @@ public class SslTransport extends TcpTransport {
// now.
if (command instanceof ConnectionInfo) {
ConnectionInfo connectionInfo = (ConnectionInfo)command;
connectionInfo.setTransportContext(getPeerCertificates());
}
super.doConsume(command);
}
/**
* @return peer certificate chain associated with the ssl socket
*/
public X509Certificate[] getPeerCertificates() {
SSLSocket sslSocket = (SSLSocket)this.socket;
@ -98,10 +107,7 @@ public class SslTransport extends TcpTransport {
clientCertChain = null;
}
connectionInfo.setTransportContext(clientCertChain);
}
super.doConsume(command);
return clientCertChain;
}
/**

View File

@ -22,6 +22,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("pojo")
public class SamplePojo implements Serializable {
private static final long serialVersionUID = 9118938642100015088L;
@XStreamAlias("name")
private String name;
@XStreamAlias("city")

View File

@ -16,12 +16,6 @@
*/
package org.apache.activemq.transport.stomp;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
/**
* @version $Revision: 732672 $

View File

@ -0,0 +1,69 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.transport.stomp;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
/**
* @version $Revision: 1461 $
*/
public class StompSslAuthTest extends StompTest {
protected void setUp() throws Exception {
// Test mutual authentication on both stomp and standard ssl transports
bindAddress = "stomp+ssl://localhost:61612";
confUri = "xbean:org/apache/activemq/transport/stomp/sslstomp-mutual-auth-broker.xml";
jmsUri="ssl://localhost:61617";
System.setProperty("javax.net.ssl.trustStore", "src/test/resources/client.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.keyStore", "src/test/resources/server.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.keyStoreType", "jks");
//System.setProperty("javax.net.debug","ssl,handshake");
super.setUp();
}
protected Socket createSocket(URI connectUri) throws IOException {
SocketFactory factory = SSLSocketFactory.getDefault();
return factory.createSocket("127.0.0.1", connectUri.getPort());
}
// NOOP - These operations handled by jaas cert login module
public void testConnectNotAuthenticatedWrongUser() throws Exception {
}
public void testConnectNotAuthenticatedWrongPassword() throws Exception {
}
public void testSendNotAuthorized() throws Exception {
}
public void testSubscribeNotAuthorized() throws Exception {
}
}

View File

@ -50,6 +50,8 @@ public class StompTest extends CombinationTestSupport {
protected String bindAddress = "stomp://localhost:61613";
protected String confUri = "xbean:org/apache/activemq/transport/stomp/stomp-auth-broker.xml";
protected String jmsUri = "vm://localhost";
private BrokerService broker;
private StompConnection stompConnection = new StompConnection();
@ -110,7 +112,7 @@ public class StompTest extends CombinationTestSupport {
stompConnect();
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(jmsUri);
connection = cf.createConnection("system", "manager");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
queue = new ActiveMQQueue(getQueueName());
@ -131,10 +133,15 @@ public class StompTest extends CombinationTestSupport {
}
protected void tearDown() throws Exception {
try {
connection.close();
stompDisconnect();
} catch(Exception e) {
// Some tests explicitly disconnect from stomp so can ignore
} finally {
broker.stop();
}
}
private void stompDisconnect() throws IOException {
if (stompConnection != null) {

View File

@ -18,9 +18,9 @@
#
# The logging properties used during tests..
#
log4j.rootLogger=INFO, out, stdout
log4j.rootLogger=DEBUG, out, stdout
log4j.logger.org.apache.activemq.spring=WARN
log4j.logger.org.apache.activemq=DEBUG
# CONSOLE appender not used by default
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

View File

@ -20,3 +20,12 @@ activemq-domain {
org.apache.activemq.jaas.properties.user="org/apache/activemq/security/users.properties"
org.apache.activemq.jaas.properties.group="org/apache/activemq/security/groups.properties";
};
cert-login {
org.apache.activemq.jaas.TextFileCertificateLoginModule required
debug=true
org.apache.activemq.jaas.textfiledn.user="org/apache/activemq/security/users.properties"
org.apache.activemq.jaas.textfiledn.group="org/apache/activemq/security/groups.properties";
};

View File

@ -15,7 +15,7 @@
## limitations under the License.
## ---------------------------------------------------------------------------
admins=system
tempDestinationAdmins=system,user
users=system,user
admins=system,sslclient
tempDestinationAdmins=system,user,sslclient
users=system,user,sslclient
guests=guest

View File

@ -18,3 +18,4 @@
system=manager
user=password
guest=password
sslclient=CN=localhost, OU=activemq.org, O=activemq.org, L=LA, ST=CA, C=US

View File

@ -25,7 +25,7 @@
<property name="annotatedClass"><value>org.apache.activemq.transport.stomp.SamplePojo</value></property>
</bean>
<broker useJmx="true" persistent="false" xmlns="http://activemq.apache.org/schema/core" populateJMSXUserID="true">
<broker start="false" useJmx="true" persistent="false" xmlns="http://activemq.apache.org/schema/core" populateJMSXUserID="true">
<transportConnectors>
<transportConnector name="stomp+ssl" uri="stomp+ssl://localhost:61612"/>
@ -65,3 +65,4 @@
</broker>
</beans>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
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.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- this file can only be parsed using the xbean-spring library -->
<!-- START SNIPPET: example -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.apache.activemq.util.XStreamFactoryBean" name="xstream">
<property name="annotatedClass"><value>org.apache.activemq.transport.stomp.SamplePojo</value></property>
</bean>
<!-- lets create an embedded ActiveMQ Broker -->
<amq:broker useJmx="true" persistent="false" start="false">
<amq:sslContext>
<amq:sslContext
keyStore="server.keystore" keyStorePassword="password"
trustStore="client.keystore" trustStorePassword="password"/>
</amq:sslContext>
<amq:transportConnectors>
<amq:transportConnector name="stomp+ssl" uri="stomp+ssl://localhost:61612?needClientAuth=true"/>
<amq:transportConnector name="ssl" uri="ssl://localhost:61617?needClientAuth=true"/>
</amq:transportConnectors>
<amq:plugins>
<amq:jaasCertificateAuthenticationPlugin configuration="cert-login"/>
<!-- lets configure a destination based authorization mechanism -->
<amq:authorizationPlugin>
<amq:map>
<amq:authorizationMap>
<amq:authorizationEntries>
<amq:authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<amq:authorizationEntry queue="USERS.>" read="users" write="users" admin="users" />
<amq:authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
<amq:authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<amq:authorizationEntry topic="USERS.>" read="users" write="users" admin="users" />
<amq:authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
<amq:authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/>
</amq:authorizationEntries>
<!-- let's assign roles to temporary destinations. comment this entry if we don't want any roles assigned to temp destinations -->
<amq:tempDestinationAuthorizationEntry>
<amq:tempDestinationAuthorizationEntry read="tempDestinationAdmins" write="tempDestinationAdmins" admin="tempDestinationAdmins"/>
</amq:tempDestinationAuthorizationEntry>
</amq:authorizationMap>
</amq:map>
</amq:authorizationPlugin>
</amq:plugins>
</amq:broker>
</beans>