You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2017/10/19 09:26:45 UTC

[camel] branch camel-2.20.x updated: CAMEL-11923 - Camel-Hessian: Add Whitelisting feature

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch camel-2.20.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-2.20.x by this push:
     new 448ba03  CAMEL-11923 - Camel-Hessian: Add Whitelisting feature
448ba03 is described below

commit 448ba03251360667b1864ad5fe744cef32d830ca
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Thu Oct 19 10:51:16 2017 +0200

    CAMEL-11923 - Camel-Hessian: Add Whitelisting feature
---
 .../camel/model/dataformat/HessianDataFormat.java  | 43 +++++++++-
 .../src/main/docs/hessian-dataformat.adoc          |  7 +-
 .../dataformat/hessian/HessianDataFormat.java      | 51 +++++++++++-
 .../camel/dataformat/hessian/AnotherObject.java    | 74 +++++++++++++++++
 .../hessian/HessianDataFormatWhitelistingTest.java | 96 ++++++++++++++++++++++
 .../src/test/resources/log4j2.properties           |  2 +-
 .../springboot/HessianDataFormatConfiguration.java | 36 ++++++++
 7 files changed, 301 insertions(+), 8 deletions(-)

diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/HessianDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/HessianDataFormat.java
index 7487338..c269d99 100644
--- a/camel-core/src/main/java/org/apache/camel/model/dataformat/HessianDataFormat.java
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/HessianDataFormat.java
@@ -18,6 +18,7 @@ package org.apache.camel.model.dataformat;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.camel.model.DataFormatDefinition;
@@ -31,9 +32,49 @@ import org.apache.camel.spi.Metadata;
 @XmlAccessorType(XmlAccessType.FIELD)
 @Deprecated
 public class HessianDataFormat extends DataFormatDefinition {
-
+    @XmlAttribute
+    private Boolean whitelistEnabled;
+    
+    @XmlAttribute
+    private String allowedUnmarshallObjects;
+    
+    @XmlAttribute
+    private String deniedUnmarshallObjects;
+    
     public HessianDataFormat() {
         super("hessian");
     }
 
+    public Boolean getWhitelistEnabled() {
+        return whitelistEnabled;
+    }
+
+    /**
+    * Define if Whitelist feature is enabled or not
+    */
+    public void setWhitelistEnabled(Boolean whitelistEnabled) {
+        this.whitelistEnabled = whitelistEnabled;
+    }
+
+    public String getAllowedUnmarshallObjects() {
+        return allowedUnmarshallObjects;
+    }
+
+    /**
+    * Define the allowed objects to be unmarshalled
+    */
+    public void setAllowedUnmarshallObjects(String allowedUnmarshallObjects) {
+        this.allowedUnmarshallObjects = allowedUnmarshallObjects;
+    }
+
+    public String getDeniedUnmarshallObjects() {
+        return deniedUnmarshallObjects;
+    }
+
+    /**
+    * Define the denied objects to be unmarshalled
+    */
+    public void setDeniedUnmarshallObjects(String deniedUnmarshallObjects) {
+        this.deniedUnmarshallObjects = deniedUnmarshallObjects;
+    }
 }
diff --git a/components/camel-hessian/src/main/docs/hessian-dataformat.adoc b/components/camel-hessian/src/main/docs/hessian-dataformat.adoc
index 60910bf..2db0087 100644
--- a/components/camel-hessian/src/main/docs/hessian-dataformat.adoc
+++ b/components/camel-hessian/src/main/docs/hessian-dataformat.adoc
@@ -19,13 +19,16 @@ If you want to use Hessian Data Format from Maven, add the following dependency
 ### Options
 
 // dataformat options: START
-The Hessian dataformat supports 1 options which are listed below.
+The Hessian dataformat supports 4 options which are listed below.
 
 
 
 [width="100%",cols="2s,1m,1m,6",options="header"]
 |===
 | Name | Default | Java Type | Description
+| whitelistEnabled | false | Boolean | Define if Whitelist feature is enabled or not
+| allowedUnmarshallObjects |  | String | Define the allowed objects to be unmarshalled
+| deniedUnmarshallObjects |  | String | Define the denied objects to be unmarshalled
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END
@@ -48,4 +51,4 @@ The Hessian dataformat supports 1 options which are listed below.
             <marshal ref="hessian"/>
         </route>
     </camelContext>
---------------------------------------------------------------------------------
\ No newline at end of file
+--------------------------------------------------------------------------------
diff --git a/components/camel-hessian/src/main/java/org/apache/camel/dataformat/hessian/HessianDataFormat.java b/components/camel-hessian/src/main/java/org/apache/camel/dataformat/hessian/HessianDataFormat.java
index 624138e..21e2b88 100644
--- a/components/camel-hessian/src/main/java/org/apache/camel/dataformat/hessian/HessianDataFormat.java
+++ b/components/camel-hessian/src/main/java/org/apache/camel/dataformat/hessian/HessianDataFormat.java
@@ -20,23 +20,29 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
-
 import com.caucho.hessian.io.Hessian2Input;
 import com.caucho.hessian.io.Hessian2Output;
+import com.caucho.hessian.io.HessianFactory;
+
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatName;
 import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 
 /**
- * The <a href="http://camel.apache.org/data-format.html">data format</a>
- * using <a href="http://hessian.caucho.com/doc/hessian-serialization.html">Hessian Serialization</a>.
+ * The <a href="http://camel.apache.org/data-format.html">data format</a> using
+ * <a href="http://hessian.caucho.com/doc/hessian-serialization.html">Hessian
+ * Serialization</a>.
  *
  * @since 2.17
  */
 public class HessianDataFormat extends ServiceSupport implements DataFormat, DataFormatName {
 
     private static final String FORMAT_NAME = "hessian";
+    private boolean whitelistEnabled;
+    private String allowedUnmarshallObjects;
+    private String deniedUnmarshallObjects;
 
     @Override
     public String getDataFormatName() {
@@ -62,7 +68,19 @@ public class HessianDataFormat extends ServiceSupport implements DataFormat, Dat
 
     @Override
     public Object unmarshal(final Exchange exchange, final InputStream inputStream) throws Exception {
-        final Hessian2Input in = new Hessian2Input(inputStream);
+        final Hessian2Input in;
+        if (!whitelistEnabled) {
+            in = new Hessian2Input(inputStream);
+        } else {
+            HessianFactory factory = new HessianFactory();
+            if (ObjectHelper.isNotEmpty(allowedUnmarshallObjects)) {
+                factory.allow(allowedUnmarshallObjects);
+            }
+            if (ObjectHelper.isNotEmpty(deniedUnmarshallObjects)) {
+                factory.deny(deniedUnmarshallObjects);
+            }
+            in = factory.createHessian2Input(inputStream);
+        }
         try {
             in.startMessage();
             final Object obj = in.readObject();
@@ -86,4 +104,29 @@ public class HessianDataFormat extends ServiceSupport implements DataFormat, Dat
     protected void doStop() throws Exception {
         // noop
     }
+
+    public boolean isWhitelistEnabled() {
+        return whitelistEnabled;
+    }
+
+    public void setWhitelistEnabled(boolean whitelistEnabled) {
+        this.whitelistEnabled = whitelistEnabled;
+    }
+
+    public String getAllowedUnmarshallObjects() {
+        return allowedUnmarshallObjects;
+    }
+
+    public void setAllowedUnmarshallObjects(String allowedUnmarshallObjects) {
+        this.allowedUnmarshallObjects = allowedUnmarshallObjects;
+    }
+
+    public String getDeniedUnmarshallObjects() {
+        return deniedUnmarshallObjects;
+    }
+
+    public void setDeniedUnmarshallObjects(String deniedUnmarshallObjects) {
+        this.deniedUnmarshallObjects = deniedUnmarshallObjects;
+    }
+
 }
diff --git a/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/AnotherObject.java b/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/AnotherObject.java
new file mode 100644
index 0000000..cdc450b
--- /dev/null
+++ b/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/AnotherObject.java
@@ -0,0 +1,74 @@
+/**
+ * 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.camel.dataformat.hessian;
+
+import java.io.Serializable;
+
+/** A simple object used used by {@link HessianDataFormatMarshallingTest}. */
+class AnotherObject implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private boolean bool;
+    private int intNumber;
+
+    public boolean isBool() {
+        return bool;
+    }
+
+    public void setBool(final boolean bool) {
+        this.bool = bool;
+    }
+
+    public int getIntNumber() {
+        return intNumber;
+    }
+
+    public void setIntNumber(final int intNumber) {
+        this.intNumber = intNumber;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (bool ? 1231 : 1237);
+        result = prime * result + intNumber;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AnotherObject other = (AnotherObject)obj;
+        if (bool != other.bool) {
+            return false;
+        }
+        if (intNumber != other.intNumber) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/HessianDataFormatWhitelistingTest.java b/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/HessianDataFormatWhitelistingTest.java
new file mode 100644
index 0000000..588c735
--- /dev/null
+++ b/components/camel-hessian/src/test/java/org/apache/camel/dataformat/hessian/HessianDataFormatWhitelistingTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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.camel.dataformat.hessian;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+/**
+ * Test for {@link HessianDataFormat}.
+ */
+public class HessianDataFormatWhitelistingTest extends CamelTestSupport {
+
+    @Test
+    public void testMarshalAndUnmarshalObject() throws Exception {
+        final TestObject object = new TestObject();
+        object.setBool(true);
+        object.setIntNumber(42);
+        object.setFloatNumber(3.14159f);
+        object.setCharacter('Z');
+        object.setText("random text");
+
+        testMarshalAndUnmarshalFailed(object);
+        
+        final AnotherObject diffObject = new AnotherObject();
+        object.setBool(true);
+        object.setIntNumber(45);
+
+        testMarshalAndUnmarshalSuccess(diffObject);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                final HessianDataFormat format = new HessianDataFormat();
+                format.setWhitelistEnabled(true);
+                format.setDeniedUnmarshallObjects("org.apache.camel.dataformat.hessian.TestObject");
+                format.setAllowedUnmarshallObjects("org.apache.camel.dataformat.hessian.AnotherObject");
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+            }
+        };
+    }
+    
+    private void testMarshalAndUnmarshalFailed(final Object object) throws Exception {
+        final MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+
+        if (object == null) {
+            mock.message(0).body().isNull();
+        } else {
+            mock.message(0).body().isNotNull();
+            mock.message(0).body().isNotEqualTo(object);
+        }
+
+        final Object marshalled = template.requestBody("direct:in", object);
+        template.sendBody("direct:back", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+    
+    private void testMarshalAndUnmarshalSuccess(final Object object) throws Exception {
+        final MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(2);
+
+        if (object == null) {
+            mock.message(1).body().isNull();
+        } else {
+            mock.message(1).body().isNotNull();
+            mock.message(1).body().isEqualTo(object);
+        }
+
+        final Object marshalled = template.requestBody("direct:in", object);
+        template.sendBody("direct:back", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+}
\ No newline at end of file
diff --git a/components/camel-hessian/src/test/resources/log4j2.properties b/components/camel-hessian/src/test/resources/log4j2.properties
index 3c0d32d..013ab63 100644
--- a/components/camel-hessian/src/test/resources/log4j2.properties
+++ b/components/camel-hessian/src/test/resources/log4j2.properties
@@ -24,5 +24,5 @@ appender.out.type = Console
 appender.out.name = out
 appender.out.layout.type = PatternLayout
 appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
-rootLogger.level = INFO
+rootLogger.level = DEBUG
 rootLogger.appenderRef.file.ref = file
diff --git a/platforms/spring-boot/components-starter/camel-hessian-starter/src/main/java/org/apache/camel/dataformat/hessian/springboot/HessianDataFormatConfiguration.java b/platforms/spring-boot/components-starter/camel-hessian-starter/src/main/java/org/apache/camel/dataformat/hessian/springboot/HessianDataFormatConfiguration.java
index 3f51339..552521d 100644
--- a/platforms/spring-boot/components-starter/camel-hessian-starter/src/main/java/org/apache/camel/dataformat/hessian/springboot/HessianDataFormatConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-hessian-starter/src/main/java/org/apache/camel/dataformat/hessian/springboot/HessianDataFormatConfiguration.java
@@ -33,6 +33,18 @@ public class HessianDataFormatConfiguration
             DataFormatConfigurationPropertiesCommon {
 
     /**
+     * Define if Whitelist feature is enabled or not
+     */
+    private Boolean whitelistEnabled = false;
+    /**
+     * Define the allowed objects to be unmarshalled
+     */
+    private String allowedUnmarshallObjects;
+    /**
+     * Define the denied objects to be unmarshalled
+     */
+    private String deniedUnmarshallObjects;
+    /**
      * Whether the data format should set the Content-Type header with the type
      * from the data format if the data format is capable of doing so. For
      * example application/xml for data formats marshalling to XML or
@@ -40,6 +52,30 @@ public class HessianDataFormatConfiguration
      */
     private Boolean contentTypeHeader = false;
 
+    public Boolean getWhitelistEnabled() {
+        return whitelistEnabled;
+    }
+
+    public void setWhitelistEnabled(Boolean whitelistEnabled) {
+        this.whitelistEnabled = whitelistEnabled;
+    }
+
+    public String getAllowedUnmarshallObjects() {
+        return allowedUnmarshallObjects;
+    }
+
+    public void setAllowedUnmarshallObjects(String allowedUnmarshallObjects) {
+        this.allowedUnmarshallObjects = allowedUnmarshallObjects;
+    }
+
+    public String getDeniedUnmarshallObjects() {
+        return deniedUnmarshallObjects;
+    }
+
+    public void setDeniedUnmarshallObjects(String deniedUnmarshallObjects) {
+        this.deniedUnmarshallObjects = deniedUnmarshallObjects;
+    }
+
     public Boolean getContentTypeHeader() {
         return contentTypeHeader;
     }

-- 
To stop receiving notification emails like this one, please contact
['"commits@camel.apache.org" <co...@camel.apache.org>'].