/***************************************************************************** * Copyright (c) 2006-2007, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. *****************************************************************************/ package org.eclipse.buckminster.jnlp.cache; import java.io.FileDescriptor; import java.net.InetAddress; import java.security.Permission; import java.util.ArrayList; import java.util.List; /** * @author Filip Hrbek * * This security manager grants executing potentially dangerous actions to all threads belonging to registered * thread groups or their descendants. * * If a security check is required from a thread which is not considered as trusted, then the security check is * delegated to the original security manager which was registered at the time of loading this security manager * class. * * If this security manager is used, no other threads should call System.setSecurityManager() directly, * otherwise the behavior of the process is unpredictable. */ public final class SimpleJNLPCacheSecurityManager extends SecurityManager { private static SimpleJNLPCacheSecurityManager s_manager = new SimpleJNLPCacheSecurityManager(); public static SimpleJNLPCacheSecurityManager getInstance() { return s_manager; } private SecurityManager m_origManager; private List<ThreadGroup> m_trustedThreadGroups; private boolean m_grantGroupAccess; private SimpleJNLPCacheSecurityManager() { m_trustedThreadGroups = new ArrayList<ThreadGroup>(); m_origManager = System.getSecurityManager(); m_grantGroupAccess = false; } public void addTrustedThreadGroup(ThreadGroup group) { m_trustedThreadGroups.add(group); if(!s_manager.equals(System.getSecurityManager())) System.setSecurityManager(s_manager); } @Override public void checkAccept(String host, int port) { if(!isTrusted() && m_origManager != null) m_origManager.checkAccept(host, port); } @Override public void checkAccess(Thread t) { if(!isTrusted() && m_origManager != null) m_origManager.checkAccess(t); } @Override public synchronized void checkAccess(ThreadGroup g) { if(!m_grantGroupAccess && !isTrusted() && m_origManager != null) m_origManager.checkAccess(g); } @Override public void checkAwtEventQueueAccess() { if(!isTrusted() && m_origManager != null) m_origManager.checkAwtEventQueueAccess(); } @Override public void checkConnect(String host, int port) { if(!isTrusted() && m_origManager != null) m_origManager.checkConnect(host, port); } @Override public void checkConnect(String host, int port, Object context) { if(!isTrusted() && m_origManager != null) m_origManager.checkConnect(host, port, context); } @Override public void checkCreateClassLoader() { if(!isTrusted() && m_origManager != null) m_origManager.checkCreateClassLoader(); } @Override public void checkDelete(String file) { if(!isTrusted() && m_origManager != null) m_origManager.checkDelete(file); } @Override public void checkExec(String cmd) { if(!isTrusted() && m_origManager != null) m_origManager.checkExec(cmd); } @Override public void checkExit(int status) { if(!isTrusted() && m_origManager != null) m_origManager.checkExit(status); } @Override public void checkLink(String lib) { if(!isTrusted() && m_origManager != null) m_origManager.checkLink(lib); } @Override public void checkListen(int port) { if(!isTrusted() && m_origManager != null) m_origManager.checkListen(port); } @Override public void checkMemberAccess(Class<?> clazz, int which) { if(!isTrusted() && m_origManager != null) m_origManager.checkMemberAccess(clazz, which); } @Override public void checkMulticast(InetAddress maddr) { if(!isTrusted() && m_origManager != null) m_origManager.checkMulticast(maddr); } @SuppressWarnings("deprecation") @Override public void checkMulticast(InetAddress maddr, byte ttl) { if(!isTrusted() && m_origManager != null) m_origManager.checkMulticast(maddr, ttl); } @Override public void checkPackageAccess(String pkg) { if(!isTrusted() && m_origManager != null) m_origManager.checkPackageAccess(pkg); } @Override public void checkPackageDefinition(String pkg) { if(!isTrusted() && m_origManager != null) m_origManager.checkPackageDefinition(pkg); } @Override public void checkPermission(Permission perm) { if(!isTrusted() && m_origManager != null) m_origManager.checkPermission(perm); } @Override public void checkPermission(Permission perm, Object context) { if(!isTrusted() && m_origManager != null) m_origManager.checkPermission(perm, context); } @Override public void checkPrintJobAccess() { if(!isTrusted() && m_origManager != null) m_origManager.checkPrintJobAccess(); } @Override public void checkPropertiesAccess() { if(!isTrusted() && m_origManager != null) m_origManager.checkPropertiesAccess(); } @Override public void checkPropertyAccess(String key) { if(!isTrusted() && m_origManager != null) m_origManager.checkPropertyAccess(key); } @Override public void checkRead(FileDescriptor fd) { if(!isTrusted() && m_origManager != null) m_origManager.checkRead(fd); } @Override public void checkRead(String file) { if(!isTrusted() && m_origManager != null) m_origManager.checkRead(file); } @Override public void checkRead(String file, Object context) { if(!isTrusted() && m_origManager != null) m_origManager.checkRead(file, context); } @Override public void checkSecurityAccess(String target) { if(!isTrusted() && m_origManager != null) m_origManager.checkSecurityAccess(target); } @Override public void checkSetFactory() { if(!isTrusted() && m_origManager != null) m_origManager.checkSetFactory(); } @Override public void checkSystemClipboardAccess() { if(!isTrusted() && m_origManager != null) m_origManager.checkSystemClipboardAccess(); } @Override public boolean checkTopLevelWindow(Object window) { if(!isTrusted() && m_origManager != null) return m_origManager.checkTopLevelWindow(window); return true; } @Override public void checkWrite(FileDescriptor fd) { if(!isTrusted() && m_origManager != null) m_origManager.checkWrite(fd); } @Override public void checkWrite(String file) { if(!isTrusted() && m_origManager != null) m_origManager.checkWrite(file); } @SuppressWarnings("deprecation") @Override public boolean getInCheck() { if(m_origManager != null) return m_origManager.getInCheck(); return super.getInCheck(); } @Override public Object getSecurityContext() { if(m_origManager != null) return m_origManager.getSecurityContext(); return super.getSecurityContext(); } @Override public ThreadGroup getThreadGroup() { if(m_origManager != null) return m_origManager.getThreadGroup(); return super.getThreadGroup(); } public void removeTrustedThreadGroup(ThreadGroup group) { m_trustedThreadGroups.remove(group); if(m_trustedThreadGroups.size() == 0 && s_manager.equals(System.getSecurityManager()) && m_origManager != null && !m_origManager.equals(System.getSecurityManager())) System.setSecurityManager(m_origManager); } private boolean isTrusted() { return isTrusted(Thread.currentThread().getThreadGroup()); } private synchronized boolean isTrusted(ThreadGroup group) { try { m_grantGroupAccess = true; if(m_trustedThreadGroups.contains(group)) return true; ThreadGroup parent = group.getParent(); if(parent != null && !parent.equals(group)) return isTrusted(parent); return false; } catch(SecurityException e) { return false; } catch(RuntimeException e) { return false; } finally { m_grantGroupAccess = false; } } }