Skip to content

Commit

Permalink
ISPN-3931 Use a SecurityManager to track security from internal classes
Browse files Browse the repository at this point in the history
  • Loading branch information
tristantarrant authored and Mircea Markus committed Apr 10, 2014
1 parent a39af35 commit d46c658
Show file tree
Hide file tree
Showing 51 changed files with 1,602 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.infinispan.commons.api.BasicCacheContainer;
import org.infinispan.cli.interpreter.codec.CodecRegistry;
import org.infinispan.cli.interpreter.logging.Log;
import org.infinispan.cli.interpreter.result.EmptyResult;
Expand All @@ -27,6 +26,7 @@
import org.infinispan.cli.interpreter.session.Session;
import org.infinispan.cli.interpreter.session.SessionImpl;
import org.infinispan.cli.interpreter.statement.Statement;
import org.infinispan.commons.api.BasicCacheContainer;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.annotations.Stop;
Expand All @@ -36,7 +36,6 @@
import org.infinispan.jmx.annotations.ManagedAttribute;
import org.infinispan.jmx.annotations.ManagedOperation;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.commons.util.SysPropertyActions;
import org.infinispan.util.TimeService;
import org.infinispan.util.logging.LogFactory;

Expand Down Expand Up @@ -129,7 +128,7 @@ void expireSessions() {
@ManagedOperation(description = "Parses and executes IspnCliQL statements")
public Map<String, String> execute(final String sessionId, final String s) throws Exception {
Session session = null;
ClassLoader oldCL = SysPropertyActions.setThreadContextClassLoader(cacheManager.getCacheManagerConfiguration().classLoader());
ClassLoader oldCL = SecurityActions.setThreadContextClassLoader(cacheManager.getCacheManagerConfiguration().classLoader());
Map<String, String> response = new HashMap<String, String>();
try {
session = validateSession(sessionId);
Expand Down Expand Up @@ -167,7 +166,7 @@ public Map<String, String> execute(final String sessionId, final String s) throw
session.reset();
response.put(ResultKeys.CACHE.toString(), session.getCurrentCacheName());
}
SysPropertyActions.setThreadContextClassLoader(oldCL);
SecurityActions.setThreadContextClassLoader(oldCL);

}
return response;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.infinispan.cli.interpreter;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* SecurityActions for package org.infinispan.cli.interpreter
*
* Do not move. Do not change class and method visibility to avoid being called from other
* {@link java.security.CodeSource}s, thus granting privilege escalation to external code.
*
* @author Tristan Tarrant
* @since 7.0
*/
final class SecurityActions {
interface SetThreadContextClassLoaderAction {

ClassLoader setThreadContextClassLoader(Class cl);

ClassLoader setThreadContextClassLoader(ClassLoader cl);

SetThreadContextClassLoaderAction NON_PRIVILEGED = new SetThreadContextClassLoaderAction() {
@Override
public ClassLoader setThreadContextClassLoader(Class cl) {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl.getClassLoader());
return old;
}

@Override
public ClassLoader setThreadContextClassLoader(ClassLoader cl) {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
return old;
}
};

SetThreadContextClassLoaderAction PRIVILEGED = new SetThreadContextClassLoaderAction() {

@Override
public ClassLoader setThreadContextClassLoader(final Class cl) {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl.getClassLoader());
return old;
}
});
}

@Override
public ClassLoader setThreadContextClassLoader(final ClassLoader cl) {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
return old;
}
});
}
};
}

public static ClassLoader setThreadContextClassLoader(Class cl) {
if (System.getSecurityManager() == null) {
return SetThreadContextClassLoaderAction.NON_PRIVILEGED.setThreadContextClassLoader(cl);
} else {
return SetThreadContextClassLoaderAction.PRIVILEGED.setThreadContextClassLoader(cl);
}
}

public static ClassLoader setThreadContextClassLoader(ClassLoader cl) {
if (System.getSecurityManager() == null) {
return SetThreadContextClassLoaderAction.NON_PRIVILEGED.setThreadContextClassLoader(cl);
} else {
return SetThreadContextClassLoaderAction.PRIVILEGED.setThreadContextClassLoader(cl);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.infinispan.commons.executors.ExecutorFactory;
import org.infinispan.commons.marshall.Marshaller;
import org.infinispan.commons.util.FileLookupFactory;
import org.infinispan.commons.util.SysPropertyActions;
import org.infinispan.commons.util.TypedProperties;
import org.infinispan.commons.util.Util;

Expand Down Expand Up @@ -140,7 +139,7 @@ public class RemoteCacheManager implements BasicCacheContainer {
private volatile boolean started = false;
private final Map<String, RemoteCacheHolder> cacheName2RemoteCache = new HashMap<String, RemoteCacheHolder>();
// Use an invalid topologyID (-1) so we always get a topology update on connection.
private AtomicInteger topologyId = new AtomicInteger(-1);
private final AtomicInteger topologyId = new AtomicInteger(-1);
private Configuration configuration;
private Codec codec;

Expand Down Expand Up @@ -545,7 +544,7 @@ public <K, V> RemoteCache<K, V> getCache(boolean forceReturnValue) {
@Override
public void start() {
// Workaround for JDK6 NPE: http://bugs.sun.com/view_bug.do?bug_id=6427854
SysPropertyActions.setProperty("sun.nio.ch.bugLevel", "\"\"");
SecurityActions.setProperty("sun.nio.ch.bugLevel", "\"\"");

codec = CodecFactory.getCodec(configuration.protocolVersion());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.infinispan.client.hotrod;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* Privileged actions for package org.infinispan.client.hotrod
*
* Do not move. Do not change class and method visibility to avoid being called from other
* {@link java.security.CodeSource}s, thus granting privilege escalation to external code.
*
* @author Scott.Stark@jboss.org
* @since 4.2
*/
final class SecurityActions {

interface SysProps {

SysProps NON_PRIVILEGED = new SysProps() {
@Override
public String getProperty(final String name, final String defaultValue) {
return System.getProperty(name, defaultValue);
}

@Override
public String getProperty(final String name) {
return System.getProperty(name);
}

@Override
public String setProperty(String name, String value) {
return System.setProperty(name, value);
}
};

SysProps PRIVILEGED = new SysProps() {
@Override
public String getProperty(final String name, final String defaultValue) {
PrivilegedAction<String> action = new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(name, defaultValue);
}
};
return AccessController.doPrivileged(action);
}

@Override
public String getProperty(final String name) {
PrivilegedAction<String> action = new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(name);
}
};
return AccessController.doPrivileged(action);
}

@Override
public String setProperty(final String name, final String value) {
PrivilegedAction<String> action = new PrivilegedAction<String>() {
@Override
public String run() {
return System.setProperty(name, value);
}
};
return AccessController.doPrivileged(action);
}
};

String getProperty(String name, String defaultValue);

String getProperty(String name);

String setProperty(String name, String value);
}

static String getProperty(String name, String defaultValue) {
if (System.getSecurityManager() == null)
return SysProps.NON_PRIVILEGED.getProperty(name, defaultValue);

return SysProps.PRIVILEGED.getProperty(name, defaultValue);
}

static String getProperty(String name) {
if (System.getSecurityManager() == null)
return SysProps.NON_PRIVILEGED.getProperty(name);

return SysProps.PRIVILEGED.getProperty(name);
}

static String setProperty(String name, String value) {
if (System.getSecurityManager() == null) {
return SysProps.NON_PRIVILEGED.setProperty(name, value);
} else {
return SysProps.PRIVILEGED.setProperty(name, value);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class ClassFinder {

private static final Log log = LogFactory.getLog(ClassFinder.class);

public static final String PATH = SysPropertyActions.getProperty("java.class.path") + File.pathSeparator
+ SysPropertyActions.getProperty("surefire.test.class.path");
public static final String PATH = SecurityActions.getProperty("java.class.path") + File.pathSeparator
+ SecurityActions.getProperty("surefire.test.class.path");

public static List<Class<?>> withAnnotationPresent(List<Class<?>> classes, Class<? extends Annotation> c) {
List<Class<?>> clazzes = new ArrayList<Class<?>>(classes.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ private static void warnLegacy(String oldKey, String newKey) {
}

public static String getProperty(String key, String legacyKey) {
String val = SysPropertyActions.getProperty(key);
String val = SecurityActions.getProperty(key);
if (val == null) {
val = SysPropertyActions.getProperty(legacyKey);
val = SecurityActions.getProperty(legacyKey);
if (val != null) warnLegacy(legacyKey, key);
}
return val;
}

public static String getProperty(String key, String legacyKey, String defaultValue) {
String val = SysPropertyActions.getProperty(key);
String val = SecurityActions.getProperty(key);
if (val == null) {
val = SysPropertyActions.getProperty(legacyKey);
val = SecurityActions.getProperty(legacyKey);
if (val != null)
warnLegacy(legacyKey, key);
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;

/**
* Basic reflection utilities to enhance what the JDK provides.
*
Expand Down Expand Up @@ -148,18 +145,6 @@ private static boolean notFound(Method m, Collection<Method> s) {
return true;
}

public static void setValue(Object instance, String fieldName, Object value) {
try {
Field f = findFieldRecursively(instance.getClass(), fieldName);
if (f == null)
throw new NoSuchMethodException("Cannot find field " + fieldName + " on " + instance.getClass() + " or superclasses");
f.setAccessible(true);
f.set(instance, value);
} catch (Exception e) {
log.unableToSetValue(e);
}
}

private static Field findFieldRecursively(Class<?> c, String fieldName) {
Field f = null;
try {
Expand Down Expand Up @@ -361,12 +346,6 @@ public static Field getField(String fieldName, Class<?> objectClass) {
}
}

public static void applyProperties(Object o, Properties p) {
for(Entry<Object, Object> entry : p.entrySet()) {
setValue(o, (String) entry.getKey(), entry.getValue());
}
}

public static <T> T unwrap(Object obj, Class<T> clazz) {
if (clazz != null && clazz.isAssignableFrom(obj.getClass()))
return clazz.cast(obj);
Expand Down
Loading

0 comments on commit d46c658

Please sign in to comment.