blob: dbc2b47ee43b1ba800b262559998691e56fa44cb [file] [log] [blame]
/*
* 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.qpid.jms.policy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.UUID;
import java.util.Vector;
import org.apache.qpid.jms.JmsDestination;
import org.apache.qpid.jms.JmsQueue;
import org.apache.qpid.jms.util.ClassLoadingAwareObjectInputStream;
import org.apache.qpid.jms.util.ClassLoadingAwareObjectInputStream.TrustedClassFilter;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JmsDefaultDeserializationPolicyTest {
private static final Logger LOG = LoggerFactory.getLogger(JmsDefaultDeserializationPolicyTest.class);
@Test
public void testIsTrustedType() {
JmsDestination destination = new JmsQueue("test-queue");
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertTrue(policy.isTrustedType(destination, null));
assertTrue(policy.isTrustedType(destination, UUID.class));
assertTrue(policy.isTrustedType(destination, String.class));
assertTrue(policy.isTrustedType(destination, Boolean.class));
assertTrue(policy.isTrustedType(destination, Double.class));
assertTrue(policy.isTrustedType(destination, Object.class));
// Only types in lang
policy.setAllowList("java.lang");
assertTrue(policy.isTrustedType(destination, null));
assertFalse(policy.isTrustedType(destination, UUID.class));
assertTrue(policy.isTrustedType(destination, String.class));
assertTrue(policy.isTrustedType(destination, Boolean.class));
assertFalse(policy.isTrustedType(destination, getClass()));
// Entry must be complete package name prefix to match
// i.e while "java.n" is a prefix of "java.net", this
// wont match the socket class below.
policy.setAllowList("java.n");
assertFalse(policy.isTrustedType(destination, UUID.class));
assertFalse(policy.isTrustedType(destination, String.class));
assertFalse(policy.isTrustedType(destination, java.net.Socket.class));
// add a non-core package
policy.setAllowList("java.lang,org.apache.qpid.jms");
assertFalse(policy.isTrustedType(destination, UUID.class));
assertTrue(policy.isTrustedType(destination, String.class));
assertTrue(policy.isTrustedType(destination, getClass()));
// Try with a class-specific entry
policy.setAllowList("java.lang.Integer");
assertTrue(policy.isTrustedType(destination, Integer.class));
assertFalse(policy.isTrustedType(destination, Boolean.class));
// Verify deny list overrides allow list
policy.setAllowList("java.lang.Integer");
policy.setDenyList("java.lang.Integer");
assertFalse(policy.isTrustedType(destination, Integer.class));
// Verify deny list entry prefix overrides allow list
policy.setAllowList("java.lang.Integer");
policy.setDenyList("java.lang");
assertFalse(policy.isTrustedType(destination, Integer.class));
// Verify deny list catch-all overrides allow list
policy.setAllowList("java.lang.Integer");
policy.setDenyList("*");
assertFalse(policy.isTrustedType(destination, Integer.class));
}
@Test
public void testHashCode() {
JmsDeserializationPolicy policy1 = new JmsDefaultDeserializationPolicy();
JmsDeserializationPolicy policy2 = new JmsDefaultDeserializationPolicy();
assertTrue(policy1.hashCode() != 0);
assertEquals(policy1.hashCode(), policy2.hashCode());
assertEquals(policy2.hashCode(), policy1.hashCode());
((JmsDefaultDeserializationPolicy) policy1).setAllowList("java.util");
assertFalse(policy1.hashCode() == policy2.hashCode());
assertFalse(policy2.hashCode() == policy1.hashCode());
((JmsDefaultDeserializationPolicy) policy2).setAllowList("java.util");
assertTrue(policy1.hashCode() == policy2.hashCode());
assertTrue(policy2.hashCode() == policy1.hashCode());
((JmsDefaultDeserializationPolicy) policy1).setDenyList("java.util");
assertFalse(policy1.hashCode() == policy2.hashCode());
assertFalse(policy2.hashCode() == policy1.hashCode());
((JmsDefaultDeserializationPolicy) policy2).setDenyList("java.util");
assertTrue(policy1.hashCode() == policy2.hashCode());
assertTrue(policy2.hashCode() == policy1.hashCode());
}
@SuppressWarnings("unlikely-arg-type")
@Test
public void testEqualsObject() {
JmsDefaultDeserializationPolicy policy1 = new JmsDefaultDeserializationPolicy();
JmsDefaultDeserializationPolicy policy2 = new JmsDefaultDeserializationPolicy();
assertTrue(policy1.equals(policy1));
assertTrue(policy1.equals(policy2));
assertTrue(policy2.equals(policy1));
policy1.setAllowList("java.util");
assertFalse(policy1.equals(policy2));
assertFalse(policy2.equals(policy1));
assertFalse(policy1.equals(null));
assertFalse(policy1.equals(""));
assertFalse(policy1.equals(this));
policy2.setAllowList("java.util");
assertTrue(policy1.equals(policy2));
policy1.setDenyList("java.util");
assertFalse(policy1.equals(policy2));
assertFalse(policy2.equals(policy1));
policy2.setDenyList("java.util");
assertTrue(policy1.equals(policy2));
assertTrue(policy2.equals(policy1));
}
@Deprecated
@Test
public void testJmsDefaultDeserializationPolicyDeprecated() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertFalse(policy.getWhiteList().isEmpty());
assertTrue(policy.getBlackList().isEmpty());
}
@Test
public void testJmsDefaultDeserializationPolicy() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertFalse(policy.getAllowList().isEmpty());
assertTrue(policy.getDenyList().isEmpty());
}
@Deprecated
@Test
public void testJmsDefaultDeserializationPolicyCopyCtorDeprecated() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
policy.setWhiteList("a.b.c");
policy.setBlackList("d.e.f");
JmsDefaultDeserializationPolicy copy = new JmsDefaultDeserializationPolicy(policy);
assertEquals("a.b.c", copy.getWhiteList());
assertEquals("d.e.f", copy.getBlackList());
}
@Test
public void testJmsDefaultDeserializationPolicyCopyCtor() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
policy.setAllowList("a.b.c");
policy.setDenyList("d.e.f");
JmsDefaultDeserializationPolicy copy = new JmsDefaultDeserializationPolicy(policy);
assertEquals("a.b.c", copy.getAllowList());
assertEquals("d.e.f", copy.getDenyList());
}
@Deprecated
@Test
public void testJmsDefaultDeserializationPolicyCopyDeprecated() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
policy.setWhiteList("a.b.c");
policy.setBlackList("d.e.f");
JmsDefaultDeserializationPolicy copy = (JmsDefaultDeserializationPolicy) policy.copy();
assertEquals("a.b.c", copy.getWhiteList());
assertEquals("d.e.f", copy.getBlackList());
}
@Test
public void testJmsDefaultDeserializationPolicyCopy() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
policy.setAllowList("a.b.c");
policy.setDenyList("d.e.f");
JmsDefaultDeserializationPolicy copy = (JmsDefaultDeserializationPolicy) policy.copy();
assertEquals("a.b.c", copy.getAllowList());
assertEquals("d.e.f", copy.getDenyList());
}
@Deprecated
@Test
public void testSetWhiteList() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertNotNull(policy.getWhiteList());
policy.setWhiteList(null);
assertNotNull(policy.getWhiteList());
assertTrue(policy.getWhiteList().isEmpty());
assertNotNull(policy.getAllowList());
assertTrue(policy.getAllowList().isEmpty());
policy.setWhiteList("");
assertNotNull(policy.getWhiteList());
assertTrue(policy.getWhiteList().isEmpty());
assertNotNull(policy.getAllowList());
assertTrue(policy.getAllowList().isEmpty());
policy.setWhiteList("*");
assertNotNull(policy.getWhiteList());
assertFalse(policy.getWhiteList().isEmpty());
assertNotNull(policy.getAllowList());
assertFalse(policy.getAllowList().isEmpty());
policy.setWhiteList("a,b,c");
assertNotNull(policy.getWhiteList());
assertNotNull(policy.getAllowList());
assertFalse(policy.getWhiteList().isEmpty());
assertFalse(policy.getAllowList().isEmpty());
assertEquals("a,b,c", policy.getWhiteList());
assertEquals("a,b,c", policy.getAllowList());
}
@Test
public void testSetAllowList() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertNotNull(policy.getAllowList());
policy.setAllowList(null);
assertNotNull(policy.getAllowList());
assertTrue(policy.getAllowList().isEmpty());
policy.setAllowList("");
assertNotNull(policy.getAllowList());
assertTrue(policy.getAllowList().isEmpty());
policy.setAllowList("*");
assertNotNull(policy.getAllowList());
assertFalse(policy.getAllowList().isEmpty());
policy.setAllowList("a,b,c");
assertNotNull(policy.getAllowList());
assertFalse(policy.getAllowList().isEmpty());
assertEquals("a,b,c", policy.getAllowList());
}
@Deprecated
@Test
public void testSetBlackList() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertNotNull(policy.getBlackList());
policy.setBlackList(null);
assertNotNull(policy.getBlackList());
assertTrue(policy.getBlackList().isEmpty());
assertNotNull(policy.getDenyList());
assertTrue(policy.getDenyList().isEmpty());
policy.setBlackList("");
assertNotNull(policy.getBlackList());
assertTrue(policy.getBlackList().isEmpty());
assertNotNull(policy.getDenyList());
assertTrue(policy.getDenyList().isEmpty());
policy.setBlackList("*");
assertNotNull(policy.getBlackList());
assertFalse(policy.getBlackList().isEmpty());
assertNotNull(policy.getDenyList());
assertFalse(policy.getDenyList().isEmpty());
policy.setBlackList("a,b,c");
assertNotNull(policy.getBlackList());
assertFalse(policy.getBlackList().isEmpty());
assertEquals("a,b,c", policy.getBlackList());
assertNotNull(policy.getDenyList());
assertFalse(policy.getDenyList().isEmpty());
assertEquals("a,b,c", policy.getDenyList());
}
@Test
public void testSetDenyList() {
JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
assertNotNull(policy.getDenyList());
policy.setDenyList(null);
assertNotNull(policy.getDenyList());
assertTrue(policy.getDenyList().isEmpty());
policy.setDenyList("");
assertNotNull(policy.getDenyList());
assertTrue(policy.getDenyList().isEmpty());
policy.setDenyList("*");
assertNotNull(policy.getDenyList());
assertFalse(policy.getDenyList().isEmpty());
policy.setDenyList("a,b,c");
assertNotNull(policy.getDenyList());
assertFalse(policy.getDenyList().isEmpty());
assertEquals("a,b,c", policy.getDenyList());
}
@Test
public void testDeserializeVectorUsingPolicy() throws Exception {
Vector<Object> vector = new Vector<Object>();
vector.add("pi");
vector.add(Integer.valueOf(314159));
vector.add(new Vector<String>());
vector.add(Boolean.FALSE);
final JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
ByteArrayInputStream input = new ByteArrayInputStream(serializeObject(vector));
TrustedClassFilter filter = new TrustedClassFilter() {
@Override
public boolean isTrusted(Class<?> clazz) {
LOG.trace("Check for trust status of class: {}", clazz.getName());
return policy.isTrustedType(new JmsQueue(), clazz);
}
};
ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, filter);
Object result = null;
try {
result = reader.readObject();
} catch (Exception ex) {
fail("Should no throw any errors");
} finally {
reader.close();
}
assertNotNull(result);
assertTrue(result instanceof Vector);
assertEquals(4, ((Vector<?>) result).size());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserializeHashMapUsingPolicy() throws Exception {
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put("a", "Value");
map.put("b", Integer.valueOf(1));
map.put("c", new Vector<Object>());
map.put("d", Boolean.FALSE);
final JmsDefaultDeserializationPolicy policy = new JmsDefaultDeserializationPolicy();
ByteArrayInputStream input = new ByteArrayInputStream(serializeObject(map));
TrustedClassFilter filter = new TrustedClassFilter() {
@Override
public boolean isTrusted(Class<?> clazz) {
LOG.trace("Check for trust status of class: {}", clazz.getName());
return policy.isTrustedType(new JmsQueue(), clazz);
}
};
ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, filter);
Object result = null;
try {
result = reader.readObject();
} catch (Exception ex) {
fail("Should no throw any errors");
} finally {
reader.close();
}
assertNotNull(result);
assertTrue(result instanceof HashMap);
map = (HashMap<Object, Object>) result;
assertEquals(4, map.size());
assertEquals("Value", map.get("a"));
assertEquals(Integer.valueOf(1), map.get("b"));
assertEquals(new Vector<Object>(), map.get("c"));
assertEquals(Boolean.FALSE, map.get("d"));
}
//----- Internal methods -------------------------------------------------//
private byte[] serializeObject(Object value) throws IOException {
byte[] result = new byte[0];
if (value != null) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(value);
oos.flush();
oos.close();
result = baos.toByteArray();
}
}
return result;
}
}