Repository: activemq Updated Branches: refs/heads/activemq-5.13.x 27b08b03c -> 5e02e305e
https://issues.apache.org/jira/browse/AMQ-6077 - define object message trusted packages on connection factory (cherry picked from commit 94446e53dc348b9109dff46e92484ed9e6cc1d72) Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/5e02e305 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/5e02e305 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/5e02e305 Branch: refs/heads/activemq-5.13.x Commit: 5e02e305ea39314589329643c164be62d5b35592 Parents: 27b08b0 Author: Dejan Bosanac <de...@nighttale.net> Authored: Mon Dec 14 13:50:27 2015 +0100 Committer: Christopher L. Shannon (cshannon) <christopher.l.shan...@gmail.com> Committed: Mon Dec 14 19:12:28 2015 +0000 ---------------------------------------------------------------------- .../org/apache/activemq/ActiveMQConnection.java | 23 +++++++++++-- .../activemq/ActiveMQConnectionFactory.java | 24 +++++++++++-- .../activemq/ActiveMQMessageConsumer.java | 18 +++------- .../activemq/command/ActiveMQObjectMessage.java | 27 +++++++++++++-- .../ClassLoadingAwareObjectInputStream.java | 36 ++++++++++++++++---- 5 files changed, 101 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/5e02e305/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java index 3b2833d..e35c9e1 100755 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnection.java @@ -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; + } } http://git-wip-us.apache.org/repos/asf/activemq/blob/5e02e305/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java index 10eebd3..171c8d4 100755 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionFactory.java @@ -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; + } } http://git-wip-us.apache.org/repos/asf/activemq/blob/5e02e305/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java index adbcf39..db9c395 100755 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQMessageConsumer.java @@ -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) { http://git-wip-us.apache.org/repos/asf/activemq/blob/5e02e305/activemq-client/src/main/java/org/apache/activemq/command/ActiveMQObjectMessage.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/command/ActiveMQObjectMessage.java b/activemq-client/src/main/java/org/apache/activemq/command/ActiveMQObjectMessage.java index 283cc00..0d762de 100755 --- a/activemq-client/src/main/java/org/apache/activemq/command/ActiveMQObjectMessage.java +++ b/activemq-client/src/main/java/org/apache/activemq/command/ActiveMQObjectMessage.java @@ -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; + } } http://git-wip-us.apache.org/repos/asf/activemq/blob/5e02e305/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java b/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java index d3e3110..9d05108 100644 --- a/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java +++ b/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java @@ -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; + } }