mirror of https://github.com/apache/activemq.git
Applied patch for https://issues.apache.org/activemq/browse/AMQ-2449
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@825008 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
43bd686a2c
commit
f866f770e3
|
@ -361,7 +361,11 @@ public class ProtocolConverter {
|
|||
}
|
||||
for (Iterator<StompSubscription> iter = subscriptionsByConsumerId.values().iterator(); iter.hasNext();) {
|
||||
StompSubscription sub = iter.next();
|
||||
sub.onStompAbort(activemqTx);
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,23 +86,29 @@ public class SslTransport extends TcpTransport {
|
|||
// now.
|
||||
if (command instanceof ConnectionInfo) {
|
||||
ConnectionInfo connectionInfo = (ConnectionInfo)command;
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket)this.socket;
|
||||
|
||||
SSLSession sslSession = sslSocket.getSession();
|
||||
|
||||
X509Certificate[] clientCertChain;
|
||||
try {
|
||||
clientCertChain = (X509Certificate[])sslSession.getPeerCertificates();
|
||||
} catch (SSLPeerUnverifiedException e) {
|
||||
clientCertChain = null;
|
||||
}
|
||||
|
||||
connectionInfo.setTransportContext(clientCertChain);
|
||||
}
|
||||
|
||||
connectionInfo.setTransportContext(getPeerCertificates());
|
||||
}
|
||||
super.doConsume(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return peer certificate chain associated with the ssl socket
|
||||
*/
|
||||
public X509Certificate[] getPeerCertificates() {
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket)this.socket;
|
||||
|
||||
SSLSession sslSession = sslSocket.getSession();
|
||||
|
||||
X509Certificate[] clientCertChain;
|
||||
try {
|
||||
clientCertChain = (X509Certificate[])sslSession.getPeerCertificates();
|
||||
} catch (SSLPeerUnverifiedException e) {
|
||||
clientCertChain = null;
|
||||
}
|
||||
|
||||
return clientCertChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pretty print of 'this'
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 $
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
|
@ -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,9 +133,14 @@ public class StompTest extends CombinationTestSupport {
|
|||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
connection.close();
|
||||
stompDisconnect();
|
||||
broker.stop();
|
||||
try {
|
||||
connection.close();
|
||||
stompDisconnect();
|
||||
} catch(Exception e) {
|
||||
// Some tests explicitly disconnect from stomp so can ignore
|
||||
} finally {
|
||||
broker.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void stompDisconnect() throws IOException {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue