From 000548836db9acc2acc3572271ced73f11e9d69d Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Mon, 16 Nov 2015 11:11:27 +0000
Subject: [PATCH] SSDM-2805: Introducing
 WhiteListCodebaseAwareObjectInputStream extending spring class
 CodebaseAwareObjectInputStream. Also introducing WhiteListHttpInvokerExporter
 (for openBIS) and WhiteListStreamSupportingHttpInvokerExporter (for CIFEX)
 which using WhiteListCodebaseAwareObjectInputStream. All published services
 using the new white-list based HttpInvokerExporter.

SVN: 35057
---
 ...iteListCodebaseAwareObjectInputStream.java | 92 +++++++++++++++++++
 .../server/AbstractApiServiceExporter.java    |  2 +-
 .../WhiteListHttpInvokerServiceExporter.java  | 40 ++++++++
 .../generic/server/CommonServiceServer.java   |  4 +-
 .../generic/server/ETLServiceServer.java      |  4 +-
 ...erviceConversationClientManagerServer.java |  4 +-
 ...erviceConversationServerManagerServer.java |  4 +-
 .../generic/server/TrackingServiceServer.java |  4 +-
 .../generic/server/GenericServiceServer.java  |  4 +-
 9 files changed, 145 insertions(+), 13 deletions(-)
 create mode 100644 common/source/java/ch/systemsx/cisd/common/spring/WhiteListCodebaseAwareObjectInputStream.java
 create mode 100644 openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/WhiteListHttpInvokerServiceExporter.java

diff --git a/common/source/java/ch/systemsx/cisd/common/spring/WhiteListCodebaseAwareObjectInputStream.java b/common/source/java/ch/systemsx/cisd/common/spring/WhiteListCodebaseAwareObjectInputStream.java
new file mode 100644
index 00000000000..6287c585f12
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/spring/WhiteListCodebaseAwareObjectInputStream.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 ETH Zuerich, SIS
+ *
+ * Licensed 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 ch.systemsx.cisd.common.spring;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamClass;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+import org.springframework.remoting.rmi.CodebaseAwareObjectInputStream;
+
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class WhiteListCodebaseAwareObjectInputStream extends CodebaseAwareObjectInputStream
+{
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, 
+            WhiteListCodebaseAwareObjectInputStream.class);
+
+    private static final List<Pattern> whiteListPatterns = new LinkedList<>();
+
+    {
+        addToWhiteListPatterns("byte");
+        addToWhiteListPatterns("short");
+        addToWhiteListPatterns("int");
+        addToWhiteListPatterns("long");
+        addToWhiteListPatterns("float");
+        addToWhiteListPatterns("double");
+        addToWhiteListPatterns("boolean");
+        addToWhiteListPatterns("org\\.springframework\\.remoting\\.support\\.RemoteInvocation");
+        addToWhiteListPatterns("java\\..*");
+        addToWhiteListPatterns("ch\\.ethz\\.sis\\..*");
+        addToWhiteListPatterns("ch\\.systemsx\\.cisd\\..*");
+    }
+
+    private static void addToWhiteListPatterns(String regex)
+    {
+        whiteListPatterns.add(Pattern.compile(regex));
+    }
+
+    public WhiteListCodebaseAwareObjectInputStream(InputStream in, ClassLoader classLoader, boolean acceptProxyClasses) throws IOException
+    {
+        super(in, classLoader, acceptProxyClasses);
+    }
+
+    @Override
+    protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException
+    {
+        String className = classDesc.getName();
+        assertMatchingClassName(className);
+        return super.resolveClass(classDesc);
+    }
+    
+    private void assertMatchingClassName(String className) throws ClassNotFoundException
+    {
+        if (className.startsWith("[L") && className.endsWith(";"))
+        {
+            assertMatchingClassName(className.substring(2, className.length() - 1));
+        } else
+        {
+            for (Pattern pattern : whiteListPatterns)
+            {
+                if (pattern.matcher(className).matches())
+                {
+                    return;
+                }
+            }
+            operationLog.error("Attempt to load class " + className);
+            throw new IllegalArgumentException("Class not allowed to load: " + className);
+        }
+    }
+}
diff --git a/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/AbstractApiServiceExporter.java b/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/AbstractApiServiceExporter.java
index ee358ebd277..ab5eebfd7d6 100644
--- a/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/AbstractApiServiceExporter.java
+++ b/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/AbstractApiServiceExporter.java
@@ -30,7 +30,7 @@ import ch.systemsx.cisd.common.spring.ServiceExceptionTranslator;
  *
  * @author Franz-Josef Elmer
  */
-public abstract class AbstractApiServiceExporter extends HttpInvokerServiceExporter
+public abstract class AbstractApiServiceExporter extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = IRpcServiceNameServer.PREFFERED_BEAN_NAME)
     private RpcServiceNameServer nameServer;
diff --git a/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/WhiteListHttpInvokerServiceExporter.java b/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/WhiteListHttpInvokerServiceExporter.java
new file mode 100644
index 00000000000..282dcff88d1
--- /dev/null
+++ b/openbis-common/source/java/ch/systemsx/cisd/openbis/common/api/server/WhiteListHttpInvokerServiceExporter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 ETH Zuerich, SIS
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.common.api.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+
+import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
+
+import ch.systemsx.cisd.common.spring.WhiteListCodebaseAwareObjectInputStream;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public abstract class WhiteListHttpInvokerServiceExporter extends HttpInvokerServiceExporter
+{
+    @Override
+    protected ObjectInputStream createObjectInputStream(InputStream is) throws IOException
+    {
+        return new WhiteListCodebaseAwareObjectInputStream(is, getBeanClassLoader(), isAcceptProxyClasses());
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceServer.java
index 74d1932c26c..a5a1cfd47ae 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceServer.java
@@ -23,10 +23,10 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
@@ -34,7 +34,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
  * @author Izabela Adamczyk
  */
 @Controller
-public class CommonServiceServer extends HttpInvokerServiceExporter
+public class CommonServiceServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.COMMON_SERVER)
     private ICommonServer common;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceServer.java
index fecb0be3a01..1017b1abee1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceServer.java
@@ -25,11 +25,11 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import ch.systemsx.cisd.common.spring.ServiceExceptionTranslator;
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.generic.shared.IServiceForDataStoreServer;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
@@ -38,7 +38,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
  * @author Kaloyan Enimanev
  */
 @Controller
-public class ETLServiceServer extends HttpInvokerServiceExporter
+public class ETLServiceServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.ETL_SERVICE)
     private IServiceForDataStoreServer etlService;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationClientManagerServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationClientManagerServer.java
index 7fb33f91614..aa3cb378302 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationClientManagerServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationClientManagerServer.java
@@ -23,10 +23,10 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.common.conversation.manager.IServiceConversationClientManagerRemote;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
@@ -35,7 +35,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
  */
 
 @Controller
-public class ServiceConversationClientManagerServer extends HttpInvokerServiceExporter
+public class ServiceConversationClientManagerServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.SERVICE_CONVERSATION_CLIENT_MANAGER)
     private IServiceConversationClientManagerRemote clientManager;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationServerManagerServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationServerManagerServer.java
index 8961ab01e85..1e45aa188d4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationServerManagerServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceConversationServerManagerServer.java
@@ -23,10 +23,10 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.common.conversation.manager.IServiceConversationServerManagerRemote;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
@@ -35,7 +35,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
  */
 
 @Controller
-public class ServiceConversationServerManagerServer extends HttpInvokerServiceExporter
+public class ServiceConversationServerManagerServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.SERVICE_CONVERSATION_SERVER_MANAGER)
     private IServiceConversationServerManagerRemote serverManager;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServiceServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServiceServer.java
index 2d92fe43052..94c23280195 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServiceServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServiceServer.java
@@ -23,10 +23,10 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.generic.shared.ITrackingServer;
 import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
 
@@ -34,7 +34,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
  * @author Piotr Buczek
  */
 @Controller
-public class TrackingServiceServer extends HttpInvokerServiceExporter
+public class TrackingServiceServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.TRACKING_SERVER)
     private ITrackingServer server;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServiceServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServiceServer.java
index db9e528e4a3..d4c19451f97 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServiceServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServiceServer.java
@@ -23,10 +23,10 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import ch.systemsx.cisd.openbis.common.api.server.WhiteListHttpInvokerServiceExporter;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.ResourceNames;
 
@@ -34,7 +34,7 @@ import ch.systemsx.cisd.openbis.plugin.generic.shared.ResourceNames;
  * @author Izabela Adamczyk
  */
 @Controller
-public class GenericServiceServer extends HttpInvokerServiceExporter
+public class GenericServiceServer extends WhiteListHttpInvokerServiceExporter
 {
     @Resource(name = ResourceNames.GENERIC_PLUGIN_SERVER)
     private IGenericServer server;
-- 
GitLab