This closes #759

This commit is contained in:
Clebert Suconic 2016-09-08 15:39:27 -04:00
commit 795ddfc1f2
4 changed files with 96 additions and 2 deletions

View File

@ -126,6 +126,8 @@ public class ActiveMQJMSVendor implements JMSVendor {
return new ServerJMSMapMessage(wrapped, deliveryCount); return new ServerJMSMapMessage(wrapped, deliveryCount);
case org.apache.activemq.artemis.api.core.Message.TEXT_TYPE: case org.apache.activemq.artemis.api.core.Message.TEXT_TYPE:
return new ServerJMSTextMessage(wrapped, deliveryCount); return new ServerJMSTextMessage(wrapped, deliveryCount);
case org.apache.activemq.artemis.api.core.Message.OBJECT_TYPE:
return new ServerJMSObjectMessage(wrapped, deliveryCount);
default: default:
return new ServerJMSMessage(wrapped, deliveryCount); return new ServerJMSMessage(wrapped, deliveryCount);
} }

View File

@ -18,17 +18,26 @@ package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.core.message.impl.MessageInternal; import org.apache.activemq.artemis.core.message.impl.MessageInternal;
import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
import javax.jms.JMSException; import javax.jms.JMSException;
import javax.jms.ObjectMessage; import javax.jms.ObjectMessage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
public class ServerJMSObjectMessage extends ServerJMSMessage implements ObjectMessage { public class ServerJMSObjectMessage extends ServerJMSMessage implements ObjectMessage {
private static final String DEFAULT_WHITELIST;
private static final String DEFAULT_BLACKLIST;
static {
DEFAULT_WHITELIST = System.getProperty(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY,
"java.lang,java.math,javax.security,java.util,org.apache.activemq,org.apache.qpid.proton.amqp");
DEFAULT_BLACKLIST = System.getProperty(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY, null);
}
public static final byte TYPE = Message.STREAM_TYPE; public static final byte TYPE = Message.STREAM_TYPE;
private Serializable object; private Serializable object;
@ -62,7 +71,9 @@ public class ServerJMSObjectMessage extends ServerJMSMessage implements ObjectM
int size = getInnerMessage().getBodyBuffer().readableBytes(); int size = getInnerMessage().getBodyBuffer().readableBytes();
byte[] bytes = new byte[size]; byte[] bytes = new byte[size];
getInnerMessage().getBodyBuffer().readBytes(bytes); getInnerMessage().getBodyBuffer().readBytes(bytes);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(bytes));
ois.setWhiteList(DEFAULT_WHITELIST);
ois.setBlackList(DEFAULT_BLACKLIST);
object = (Serializable) ois.readObject(); object = (Serializable) ois.readObject();
} }
} }

View File

@ -16,7 +16,9 @@
*/ */
package org.apache.activemq.artemis.core.protocol.proton; package org.apache.activemq.artemis.core.protocol.proton;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
@ -26,7 +28,10 @@ import java.util.Map;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.PooledByteBufAllocator;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSObjectMessage;
import org.apache.activemq.artemis.core.protocol.proton.converter.message.EncodedMessage; import org.apache.activemq.artemis.core.protocol.proton.converter.message.EncodedMessage;
import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
import org.apache.blacklist.ABadClass;
import org.apache.qpid.proton.amqp.Binary; import org.apache.qpid.proton.amqp.Binary;
import org.apache.qpid.proton.amqp.messaging.AmqpSequence; import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
import org.apache.qpid.proton.amqp.messaging.AmqpValue; import org.apache.qpid.proton.amqp.messaging.AmqpValue;
@ -51,6 +56,60 @@ import org.proton.plug.util.NettyWritable;
public class TestConversions extends Assert { public class TestConversions extends Assert {
@Test
public void testObjectMessageWhiteList() throws Exception {
Map<String, Object> mapprop = createPropertiesMap();
ApplicationProperties properties = new ApplicationProperties(mapprop);
MessageImpl message = (MessageImpl) Message.Factory.create();
message.setApplicationProperties(properties);
byte[] bodyBytes = new byte[4];
for (int i = 0; i < bodyBytes.length; i++) {
bodyBytes[i] = (byte) 0xff;
}
message.setBody(new AmqpValue(new Boolean(true)));
EncodedMessage encodedMessage = encodeMessage(message);
ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
ServerJMSObjectMessage serverMessage = (ServerJMSObjectMessage) converter.inboundJMSType(encodedMessage);
verifyProperties(serverMessage);
assertEquals(true, serverMessage.getObject());
Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
AmqpValue value = (AmqpValue) ((Message)obj).getBody();
assertEquals(value.getValue(), true);
}
@Test
public void testObjectMessageNotOnWhiteList() throws Exception {
ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
ServerMessageImpl message = new ServerMessageImpl(1, 1024);
message.setType((byte) 2);
ServerJMSObjectMessage serverMessage = new ServerJMSObjectMessage(message, 1024);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream ois = new ObjectOutputStream(out);
ois.writeObject(new ABadClass());
serverMessage.getInnerMessage().getBodyBuffer().writeBytes(out.toByteArray());
try {
converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
fail("should throw ClassNotFoundException");
}
catch (ClassNotFoundException e) {
//ignore
}
}
@Test @Test
public void testSimpleConversionBytes() throws Exception { public void testSimpleConversionBytes() throws Exception {
Map<String, Object> mapprop = createPropertiesMap(); Map<String, Object> mapprop = createPropertiesMap();

View File

@ -0,0 +1,22 @@
/*
* 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.blacklist;
import java.io.Serializable;
public class ABadClass implements Serializable {
}