river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter_firmst...@apache.org
Subject svn commit: r1004236 - in /incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos: ./ SmartProxyIsolate.java
Date Mon, 04 Oct 2010 13:53:52 GMT
Author: peter_firmstone
Date: Mon Oct  4 13:53:52 2010
New Revision: 1004236

URL: http://svn.apache.org/viewvc?rev=1004236&view=rev
Log:
A very prelimary smart proxy isolation implementation.

Added:
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java
  (with props)

Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java?rev=1004236&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java
(added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java
Mon Oct  4 13:53:52 2010
@@ -0,0 +1,188 @@
+/*
+ * 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.river.imp.security.dos;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import net.jini.io.MarshalledInstance;
+
+/**
+ * A preliminary experiment into Isolating a Smart Proxy.
+ * 
+ * I think I'll investigate creating a Permission for additional threads
+ * for improved performance and also creating an event model so clients
+ * don't need to wait for remote method returns.  I'll create a new interface
+ * for this, that can be implemented by services directly too.
+ * 
+ * REMIND: Investigate subclass method returns, this would be simple, if the
+ * smart proxy is confined to it's own ClassLoader, we just check the class
+ * of the object returned isn't from that ClassLoader, unless the smart proxy
+ * has a ServiceAPISubclassPermission or something like that.
+ * 
+ * @author Peter Firmstone
+ */
+public class SmartProxyIsolate implements InvocationHandler {
+    private volatile Object smartProxy;
+    private volatile ExecutorService proxyExecutor;
+    private volatile Throwable thrown;
+    
+    @SuppressWarnings("unchecked")
+    public SmartProxyIsolate(MarshalledInstance proxy, 
+			    ClassLoader defaultLoader,
+			    boolean verifyCodebaseIntegrity, 
+			    ClassLoader verifierLoader,
+			    Collection context
+	    ){
+	
+	thrown = null;
+	proxyExecutor = Executors.newSingleThreadExecutor(new Factory(this));
+	UnmarshallProxyTask task = 
+		new UnmarshallProxyTask(proxy, defaultLoader,
+		verifyCodebaseIntegrity, verifierLoader, context);
+	try{
+	    smartProxy = proxyExecutor.submit(task).get();
+	} catch (InterruptedException ex) {
+	    thrown = ex;
+	    smartProxy = null;
+	} catch (ExecutionException ex) {
+	    thrown = ex;
+	    smartProxy = null;
+	}
+    }
+    
+    private Object taskInvoke(Object proxy, Method method, Object[] args) throws
+	    Exception {
+	String methodName = method.getName();
+	if (method.getDeclaringClass() == Object.class)  {
+	    // Handle the Object public methods.
+	    if (methodName.equals("hashCode"))  {
+		return new Integer(System.identityHashCode(proxy));   
+	    } else if (methodName.equals("equals")) {
+		return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
+	    } else if (methodName.equals("toString")) {
+		return proxy.getClass().getName() + '@' + Integer.toHexString(proxy.hashCode());
+	    }
+	}
+	return method.invoke(smartProxy, args);	
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+	if (isTerminated()) throw new IOException(thrown);
+	Callable task = new MethodInvocationTask(this, proxy, method, args);
+	return proxyExecutor.submit(task).get();
+    }
+    
+    private void terminate(Throwable e){
+	thrown = e;
+	smartProxy = null;
+	proxyExecutor.shutdown();	
+    }
+    
+    private boolean isTerminated(){
+	if (smartProxy == null) return true;
+	return false;
+    }
+    
+    private static class Factory implements ThreadFactory{
+	private static final ThreadGroup tg = new ThreadGroup("IsolatedProxy");
+	{
+	    tg.setDaemon(true);
+	    tg.setMaxPriority(4);
+	}
+	private final SmartProxyIsolate proxy;
+	Factory(SmartProxyIsolate spi){
+	    proxy = spi;
+	}
+
+	public Thread newThread(Runnable r) {
+	    Thread t = new Thread(tg, r);
+	    t.setUncaughtExceptionHandler(new ExceptionHandler(proxy));
+	    return t;
+	}	
+    }
+    
+    private static class ExceptionHandler implements Thread.UncaughtExceptionHandler{
+	private final SmartProxyIsolate proxy;
+	
+	ExceptionHandler(SmartProxyIsolate spi){
+	    proxy = spi;
+	}
+
+	public void uncaughtException(Thread t, Throwable e) {
+	    // For all other Exceptions we let the ExecutorService handle it.
+	    if ( e instanceof Error){
+		proxy.terminate(e);
+	    }
+	}
+	
+    }
+    
+    private static class UnmarshallProxyTask implements Callable{
+	private final MarshalledInstance mi;
+	private final ClassLoader defaultLoader;
+	private final boolean verifyCodebaseIntegrity;
+	private final ClassLoader verifierLoader;
+	private final Collection context;
+	
+	UnmarshallProxyTask(MarshalledInstance proxy, 
+		ClassLoader defaultLoader,
+		boolean verifyCodebaseIntegrity, 
+		ClassLoader verifierLoader,
+		Collection context)
+	{
+	    mi = proxy;
+	    this.defaultLoader = defaultLoader;
+	    this.verifyCodebaseIntegrity = verifyCodebaseIntegrity;
+	    this.verifierLoader = verifierLoader;
+	    this.context = context;
+	}	
+
+	public Object call() throws Exception {
+	    return mi.get(defaultLoader, verifyCodebaseIntegrity, 
+		    verifierLoader, context);
+	}
+	
+    }
+    
+    private static class MethodInvocationTask implements Callable {
+	private final SmartProxyIsolate smartProxy;
+	private final Object proxy;
+	private final Method method;
+	private final Object[] args;
+	MethodInvocationTask(SmartProxyIsolate target, Object proxy, Method method, Object[] args){
+	    smartProxy = target;
+	    this.proxy = proxy;
+	    this.method = method;
+	    this.args = args;	    
+	}
+	public Object call() throws Exception {
+	    return smartProxy.taskInvoke(proxy, method, args);
+	}
+	    
+    }
+
+}

Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/dos/SmartProxyIsolate.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message