https://issues.apache.org/jira/browse/AMQ-6077 - define object message trusted packages on connection factory

This commit is contained in:
Dejan Bosanac 2015-12-14 13:50:27 +01:00
parent c78eddce7e
commit 94446e53dc
5 changed files with 101 additions and 27 deletions

View File

@ -19,9 +19,7 @@ package org.apache.activemq;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
@ -206,6 +204,9 @@ public class ActiveMQConnection implements Connection, TopicConnection, QueueCon
private int maxThreadPoolSize = DEFAULT_THREAD_POOL_SIZE;
private RejectedExecutionHandler rejectedTaskHandler = null;
private List<String> trustedPackages = new ArrayList<String>();
private boolean trustAllPackages = false;
/**
* Construct an <code>ActiveMQConnection</code>
*
@ -2585,4 +2586,20 @@ public class ActiveMQConnection implements Connection, TopicConnection, QueueCon
public void setConsumerExpiryCheckEnabled(boolean consumerExpiryCheckEnabled) {
this.consumerExpiryCheckEnabled = consumerExpiryCheckEnabled;
}
public List<String> getTrustedPackages() {
return trustedPackages;
}
public void setTrustedPackages(List<String> trustedPackages) {
this.trustedPackages = trustedPackages;
}
public boolean isTrustAllPackages() {
return trustAllPackages;
}
public void setTrustAllPackages(boolean trustAllPackages) {
this.trustAllPackages = trustAllPackages;
}
}

View File

@ -21,9 +21,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.RejectedExecutionHandler;
import javax.jms.Connection;
@ -183,6 +181,8 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
protected int xaAckMode = -1; // ensure default init before setting via brokerUrl introspection in sub class
private boolean rmIdFromConnectionId = false;
private boolean consumerExpiryCheckEnabled = true;
private List<String> trustedPackages = new ArrayList<String>();
private boolean trustAllPackages = false;
// /////////////////////////////////////////////
//
@ -422,6 +422,8 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
connection.setNestedMapAndListEnabled(isNestedMapAndListEnabled());
connection.setRmIdFromConnectionId(isRmIdFromConnectionId());
connection.setConsumerExpiryCheckEnabled(isConsumerExpiryCheckEnabled());
connection.setTrustedPackages(getTrustedPackages());
connection.setTrustAllPackages(isTrustAllPackages());
if (transportListener != null) {
connection.addTransportListener(transportListener);
}
@ -1260,4 +1262,20 @@ public class ActiveMQConnectionFactory extends JNDIBaseStorable implements Conne
public void setConsumerExpiryCheckEnabled(boolean consumerExpiryCheckEnabled) {
this.consumerExpiryCheckEnabled = consumerExpiryCheckEnabled;
}
public List<String> getTrustedPackages() {
return trustedPackages;
}
public void setTrustedPackages(List<String> trustedPackages) {
this.trustedPackages = trustedPackages;
}
public boolean isTrustAllPackages() {
return trustAllPackages;
}
public void setTrustAllPackages(boolean trustAllPackages) {
this.trustAllPackages = trustAllPackages;
}
}

View File

@ -40,19 +40,7 @@ import javax.jms.MessageListener;
import javax.jms.TransactionRolledBackException;
import org.apache.activemq.blob.BlobDownloader;
import org.apache.activemq.command.ActiveMQBlobMessage;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ActiveMQTempDestination;
import org.apache.activemq.command.CommandTypes;
import org.apache.activemq.command.ConsumerId;
import org.apache.activemq.command.ConsumerInfo;
import org.apache.activemq.command.MessageAck;
import org.apache.activemq.command.MessageDispatch;
import org.apache.activemq.command.MessageId;
import org.apache.activemq.command.MessagePull;
import org.apache.activemq.command.RemoveInfo;
import org.apache.activemq.command.TransactionId;
import org.apache.activemq.command.*;
import org.apache.activemq.management.JMSConsumerStatsImpl;
import org.apache.activemq.management.StatsCapable;
import org.apache.activemq.management.StatsImpl;
@ -588,6 +576,10 @@ public class ActiveMQMessageConsumer implements MessageAvailableConsumer, StatsC
if (m.getDataStructureType()==CommandTypes.ACTIVEMQ_BLOB_MESSAGE) {
((ActiveMQBlobMessage)m).setBlobDownloader(new BlobDownloader(session.getBlobTransferPolicy()));
}
if (m.getDataStructureType() == CommandTypes.ACTIVEMQ_OBJECT_MESSAGE) {
((ActiveMQObjectMessage)m).setTrustAllPackages(session.getConnection().isTrustAllPackages());
((ActiveMQObjectMessage)m).setTrustedPackages(session.getConnection().getTrustedPackages());
}
if (transformer != null) {
Message transformedMessage = transformer.consumerTransform(session, this, m);
if (transformedMessage != null) {

View File

@ -24,6 +24,8 @@ import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
@ -65,15 +67,18 @@ import org.apache.activemq.wireformat.WireFormat;
*/
public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMessage {
// TODO: verify classloader
public static final byte DATA_STRUCTURE_TYPE = CommandTypes.ACTIVEMQ_OBJECT_MESSAGE;
static final ClassLoader ACTIVEMQ_CLASSLOADER = ActiveMQObjectMessage.class.getClassLoader();
private List<String> trustedPackages = new ArrayList<String>();
private boolean trustAllPackages = false;
protected transient Serializable object;
public Message copy() {
ActiveMQObjectMessage copy = new ActiveMQObjectMessage();
copy(copy);
copy.setTrustAllPackages(trustAllPackages);
copy.setTrustedPackages(trustedPackages);
return copy;
}
@ -187,6 +192,8 @@ public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMess
}
DataInputStream dataIn = new DataInputStream(is);
ClassLoadingAwareObjectInputStream objIn = new ClassLoadingAwareObjectInputStream(dataIn);
objIn.setTrustedPackages(trustedPackages);
objIn.setTrustAllPackages(trustAllPackages);
try {
object = (Serializable)objIn.readObject();
} catch (ClassNotFoundException ce) {
@ -234,4 +241,20 @@ public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMess
}
return super.toString();
}
public List<String> getTrustedPackages() {
return trustedPackages;
}
public void setTrustedPackages(List<String> trustedPackages) {
this.trustedPackages = trustedPackages;
}
public boolean isTrustAllPackages() {
return trustAllPackages;
}
public void setTrustAllPackages(boolean trustAllPackages) {
this.trustAllPackages = trustAllPackages;
}
}

View File

@ -21,9 +21,7 @@ import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,6 +34,9 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
public static final String[] serializablePackages;
private List<String> trustedPackages = new ArrayList<String>();
private boolean trustAllPackages = false;
private final ClassLoader inLoader;
static {
@ -46,6 +47,7 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
public ClassLoadingAwareObjectInputStream(InputStream in) throws IOException {
super(in);
inLoader = in.getClass().getClassLoader();
trustedPackages.addAll(Arrays.asList(serializablePackages));
}
@Override
@ -92,17 +94,20 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
return serializablePackages.length == 1 && serializablePackages[0].equals("*");
}
private boolean trustAllPackages() {
return trustAllPackages || (trustedPackages.size() == 1 && trustedPackages.get(0).equals("*"));
}
private void checkSecurity(Class clazz) throws ClassNotFoundException {
if (!clazz.isPrimitive()) {
if (clazz.getPackage() != null && !isAllAllowed()) {
if (clazz.getPackage() != null && !trustAllPackages()) {
boolean found = false;
for (String packageName : serializablePackages) {
for (String packageName : getTrustedPackages()) {
if (clazz.getPackage().getName().equals(packageName) || clazz.getPackage().getName().startsWith(packageName + ".")) {
found = true;
break;
}
}
if (!found) {
throw new ClassNotFoundException("Forbidden " + clazz + "! This class is not allowed to be serialized. Add package with 'org.apache.activemq.SERIALIZABLE_PACKAGES' system property.");
}
@ -193,4 +198,23 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
return null;
}
public List<String> getTrustedPackages() {
return trustedPackages;
}
public void setTrustedPackages(List<String> trustedPackages) {
this.trustedPackages = trustedPackages;
}
public void addTrustedPackage(String trustedPackage) {
this.trustedPackages.add(trustedPackage);
}
public boolean isTrustAllPackages() {
return trustAllPackages;
}
public void setTrustAllPackages(boolean trustAllPackages) {
this.trustAllPackages = trustAllPackages;
}
}