summaryrefslogtreecommitdiff
path: root/sandbox
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2005-03-21 10:38:47 +0000
committerKurt Zenker <kz@openoffice.org>2005-03-21 10:38:47 +0000
commitca3246acc95470172db3fe9aa3e1f56815f2d1ef (patch)
treeaf7326e6cc19be9a50438a2fb55b49bde8dd1fd6 /sandbox
parenta7af05f689ddd4f3583865eb21eb5ae1464c572b (diff)
INTEGRATION: CWS fwkpostbeta1 (1.4.96); FILE MERGED
2005/03/10 14:21:22 jl 1.4.96.3: #i41066# workaround for security functions, such as SecurityManager.currentClassLoader. They use in their implementation features of the new security mechanism. 2005/02/04 10:26:14 jl 1.4.96.2: #41066# use thread local storage for flag that signals recursion 2005/02/02 09:59:49 jl 1.4.96.1: #41066# changes to SecurityManager to allow Java components full permissions
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/com/sun/star/lib/sandbox/SandboxSecurity.java960
1 files changed, 650 insertions, 310 deletions
diff --git a/sandbox/com/sun/star/lib/sandbox/SandboxSecurity.java b/sandbox/com/sun/star/lib/sandbox/SandboxSecurity.java
index 7c0e03a95f..5ab9dbcea2 100644
--- a/sandbox/com/sun/star/lib/sandbox/SandboxSecurity.java
+++ b/sandbox/com/sun/star/lib/sandbox/SandboxSecurity.java
@@ -2,9 +2,9 @@
*
* $RCSfile: SandboxSecurity.java,v $
*
- * $Revision: 1.4 $
+ * $Revision: 1.5 $
*
- * last change: $Author: jl $ $Date: 2002-10-16 10:36:47 $
+ * last change: $Author: kz $ $Date: 2005-03-21 11:38:47 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -71,7 +71,6 @@ import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Hashtable;
import java.security.*;
-
import sun.security.provider.*;
/**
@@ -96,7 +95,12 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
String writeACL[];
int networkMode;
boolean bCheckSecurity;
-
+ RecursionCounter InCheck = new RecursionCounter();
+ RecursionCounter InIsSecureLoader = new RecursionCounter();
+ RecursionCounter InInClassLoader = new RecursionCounter();
+ RecursionCounter InClassLoaderDepth = new RecursionCounter();
+ java.security.AllPermission allPerm = new java.security.AllPermission();
+
// where we look for identities
IdentityScope scope;
// local cache for network-loaded classes
@@ -191,27 +195,40 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
// /**
// * True if called indirectly from an <it>untrusted</it> applet.
// */
- boolean inApplet() {
- return inClassLoader();
+ synchronized boolean inApplet() {
+ boolean ret = false;
+ try {
+ InCheck.acquire();
+ ret = inClassLoader();
+ } finally {
+ InCheck.release();
+ }
+ return ret;
}
/**
* The only variable that currently affects whether an applet can
* perform certain operations is the host it came from.
*/
- public Object getSecurityContext() {
- ClassLoader loader = currentClassLoader();
-
- if (loader == null) {
- return null;
- } else
- if (loader instanceof ClassContextImpl) {
- ClassContext appletLoader = (ClassContextImpl)loader;
- return appletLoader.getBase();
- } else {
- throw(new SandboxSecurityException("getsecuritycontext.unknown"));
-// return null;
+ public synchronized Object getSecurityContext() {
+ Object ret = null;
+ try {
+ InCheck.acquire();
+ ClassLoader loader = currentClassLoader();
+
+ if (loader != null) {
+ if (loader instanceof ClassContextImpl) {
+ ClassContext appletLoader = (ClassContextImpl)loader;
+ ret = appletLoader.getBase();
+ } else {
+ throw(new SandboxSecurityException("getsecuritycontext.unknown"));
+ }
+ }
}
+ finally {
+ InCheck.release();
+ }
+ return ret;
}
/**
@@ -220,9 +237,14 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* checkClassLoaderOperation or somesuch.
*/
public synchronized void checkCreateClassLoader() {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (classLoaderDepth() == 2)
- throw(new SandboxSecurityException("checkcreateclassloader"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (classLoaderDepth() == 2)
+ throw(new SandboxSecurityException("checkcreateclassloader"));
+ }
+ } finally {
+ InCheck.release();
}
}
@@ -231,26 +253,40 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* group. This will return false if there is no current class
* loader.
*/
- protected boolean inThreadGroup(ThreadGroup g) {
- ClassLoader loader = currentClassLoader();
+ protected synchronized boolean inThreadGroup(ThreadGroup g) {
+ boolean ret = false;
+ try {
+ InCheck.acquire();
+ ClassLoader loader = currentClassLoader();
- /* If this class wasn't loaded by an AppletClassLoader, we have
- not eay of telling, for now. */
-
- if (loader instanceof ClassContextImpl) {
- ClassContext appletLoader = (ClassContextImpl)loader;
- ThreadGroup appletGroup = appletLoader.getThreadGroup();
- return appletGroup.parentOf(g);
+ /* If this class wasn't loaded by an AppletClassLoader, we have
+ not eay of telling, for now. */
+
+ if (loader instanceof ClassContextImpl) {
+ ClassContext appletLoader = (ClassContextImpl)loader;
+ ThreadGroup appletGroup = appletLoader.getThreadGroup();
+ ret = appletGroup.parentOf(g);
+ }
+ } finally {
+ InCheck.release();
}
- return false;
+ return ret;
}
/**
* Returns true of the threadgroup of thread is in the applet's
* own threadgroup.
*/
- protected boolean inThreadGroup(Thread thread) {
- return inThreadGroup(thread.getThreadGroup());
+ protected synchronized boolean inThreadGroup(Thread thread) {
+ boolean ret = false;
+ try {
+ InCheck.acquire();
+ ret = inThreadGroup(thread.getThreadGroup());
+ }
+ finally {
+ InCheck.release();
+ }
+ return ret;
}
/**
@@ -258,10 +294,15 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* applet thread groups.
*/
public synchronized void checkAccess(Thread t) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (classLoaderDepth()==3 && (! inThreadGroup(t))) {
- throw(new SandboxSecurityException("checkaccess.thread"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (classLoaderDepth()==3 && (! inThreadGroup(t))) {
+ throw(new SandboxSecurityException("checkaccess.thread"));
+ }
}
+ } finally {
+ InCheck.release();
}
}
@@ -270,24 +311,35 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* applet thread groups.
*/
public synchronized void checkAccess(ThreadGroup g) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (classLoaderDepth() == 4 && (! inThreadGroup(g))) {
- throw(new SandboxSecurityException("checkaccess.threadgroup", g.toString()));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (classLoaderDepth() == 4 && (! inThreadGroup(g))) {
+ throw(new SandboxSecurityException("checkaccess.threadgroup", g.toString()));
+ }
}
+ } finally {
+ InCheck.release();
}
+
}
/**
* Applets are not allowed to exit the VM.
*/
public synchronized void checkExit(int status) {
- if( bNoExit ) {
- throw(new SandboxSecurityException("checkexit", String.valueOf(status)));
- }
- if( bCheckSecurity && !isSecureLoader() ) {
- if( inApplet() ) {
+ try {
+ InCheck.acquire();
+ if( bNoExit ) {
throw(new SandboxSecurityException("checkexit", String.valueOf(status)));
}
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if( inApplet() ) {
+ throw(new SandboxSecurityException("checkexit", String.valueOf(status)));
+ }
+ }
+ } finally {
+ InCheck.release();
}
}
@@ -295,25 +347,35 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Applets are not allowed to fork processes.
*/
public synchronized void checkExec(String cmd) {
- if( bCheckSecurity && !isSecureLoader()) {
- if (inApplet()) {
- throw(new SandboxSecurityException("checkexec", cmd));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader()) {
+ if (inApplet()) {
+ throw(new SandboxSecurityException("checkexec", cmd));
+ }
}
- }
+ } finally {
+ InCheck.release();
+ }
}
/**
* Applets are not allowed to link dynamic libraries.
*/
public synchronized void checkLink(String lib) {
- if( bCheckSecurity && !isSecureLoader() ) {
- switch (classLoaderDepth()) {
- case 2: // Runtime.load
- case 3: // System.loadLibrary
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ switch (classLoaderDepth()) {
+ case 2: // Runtime.load
+ case 3: // System.loadLibrary
throw(new SandboxSecurityException("checklink", lib));
- default:
- break;
+ default:
+ break;
+ }
}
+ } finally {
+ InCheck.release();
}
}
@@ -322,10 +384,15 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* list, only properties explicitly labeled as accessible to applets.
*/
public synchronized void checkPropertiesAccess() {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (classLoaderDepth() == 2) {
- throw(new SandboxSecurityException("checkpropsaccess"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (classLoaderDepth() == 2) {
+ throw(new SandboxSecurityException("checkpropsaccess"));
+ }
}
+ } finally {
+ InCheck.release();
}
}
@@ -336,14 +403,19 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* applets only if <code>java.home.applet</code> is <code>true</code>.
*/
public synchronized void checkPropertyAccess(String key) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (classLoaderDepth() == 2) {
- String prop = System.getProperty(key + ".applet");
- boolean allow = new Boolean(prop).booleanValue();
- if ( !allow ) {
- throw(new SandboxSecurityException("checkpropsaccess.key", prop));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (classLoaderDepth() == 2) {
+ String prop = System.getProperty(key + ".applet");
+ boolean allow = new Boolean(prop).booleanValue();
+ if ( !allow ) {
+ throw(new SandboxSecurityException("checkpropsaccess.key", prop));
+ }
}
}
+ } finally {
+ InCheck.release();
}
}
@@ -402,74 +474,93 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Check if an applet can read a particular file.
*/
public synchronized void checkRead(String file) {
- if( bCheckSecurity && !isSecureLoader() ) {
- ClassLoader loader = currentClassLoader();
-
- /* If no class loader, it's a system class. */
- if (loader == null)
- return;
-
- /* If not an AppletClassLoader, we don't know what to do */
- if (! (loader instanceof ClassContextImpl))
- throw(new SandboxSecurityException("checkread.unknown", file));
- ClassContext appletLoader = (ClassContextImpl)loader;
- URL base = appletLoader.getBase();
- checkRead(file, base);
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ ClassLoader loader = currentClassLoader();
+
+ /* If no class loader, it's a system class. */
+ if (loader != null)
+ {
+ /* If not an AppletClassLoader, we don't know what to do */
+ if (! (loader instanceof ClassContextImpl))
+ throw(new SandboxSecurityException("checkread.unknown", file));
+ ClassContext appletLoader = (ClassContextImpl)loader;
+ URL base = appletLoader.getBase();
+ checkRead(file, base);
+ }
+ }
+ } finally {
+ InCheck.release();
}
}
public synchronized void checkRead(String file, URL base) {
- if( bCheckSecurity && (base != null) && !isSecureLoader() ) {
- if (!initACL)
- initializeACLs();
- if (readACL == null)
- return;
-
- String realPath = null;
- try {
- realPath = (new File(file)).getCanonicalPath();
- } catch (IOException e) {
- throw(new SandboxSecurityException("checkread.exception1", e.getMessage(), file));
- }
-
- for (int i = readACL.length ; i-- > 0 ;) {
- if (realPath.startsWith(readACL[i]))
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && (base != null) && !isSecureLoader() ) {
+ if (!initACL)
+ initializeACLs();
+ if (readACL == null)
+ {
+ InCheck.release();
return;
- }
-
- // if the applet is loaded from a file URL, allow reading
- // in that directory
- if (base.getProtocol().equals("file")) {
- String dir = null;
+ }
+
+ String realPath = null;
try {
- // If the file url contains spaces (i.e. %20) then URL.getFile() still contains %20
- // File.getCanonicalPath does not replace %20
- // create a string with real spaces instead of %20
- StringBuffer buf= new StringBuffer(256);
- String sSpace= "%20";
- String sFile= base.getFile();
- int begin= 0;
- int end= 0;
- while((end= sFile.indexOf(sSpace, begin)) != -1) {
- buf.append( sFile.substring(begin, end));
- buf.append(" ");
- begin= end + sSpace.length();
+ realPath = (new File(file)).getCanonicalPath();
+ } catch (IOException e) {
+ throw(new SandboxSecurityException("checkread.exception1", e.getMessage(), file));
+ }
+
+ for (int i = readACL.length ; i-- > 0 ;) {
+ if (realPath.startsWith(readACL[i]))
+ {
+ InCheck.release();
+ return;
}
- buf.append(sFile.substring(begin));
-
- String sWithSpaces= buf.toString();
- dir = (new File(sWithSpaces).getCanonicalPath());
- } catch (IOException e) { // shouldn't happen
- throw(new SandboxSecurityException("checkread.exception2", e.toString()));
}
- if (realPath.startsWith(dir))
- return;
+
+ // if the applet is loaded from a file URL, allow reading
+ // in that directory
+ if (base.getProtocol().equals("file")) {
+ String dir = null;
+ try {
+ // If the file url contains spaces (i.e. %20) then URL.getFile() still contains %20
+ // File.getCanonicalPath does not replace %20
+ // create a string with real spaces instead of %20
+ StringBuffer buf= new StringBuffer(256);
+ String sSpace= "%20";
+ String sFile= base.getFile();
+ int begin= 0;
+ int end= 0;
+ while((end= sFile.indexOf(sSpace, begin)) != -1) {
+ buf.append( sFile.substring(begin, end));
+ buf.append(" ");
+ begin= end + sSpace.length();
+ }
+ buf.append(sFile.substring(begin));
+
+ String sWithSpaces= buf.toString();
+ dir = (new File(sWithSpaces).getCanonicalPath());
+ } catch (IOException e) { // shouldn't happen
+ throw(new SandboxSecurityException("checkread.exception2", e.toString()));
+ }
+ if (realPath.startsWith(dir))
+ {
+ InCheck.release();
+ return;
+ }
+ }
+ throw new SandboxSecurityException("checkread", file, realPath);
}
- throw new SandboxSecurityException("checkread", file, realPath);
+ } finally {
+ InCheck.release();
}
+
}
-
- /**
+ /**
* Checks to see if the current context or the indicated context are
* both allowed to read the given file name.
* @param file the system dependent file name
@@ -477,36 +568,52 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* be checked
* @exception SecurityException If the file is not found.
*/
- public void checkRead(String file, Object context) {
- checkRead(file);
- if (context != null)
- checkRead(file, (URL) context);
+ public synchronized void checkRead(String file, Object context) {
+ try {
+ InCheck.acquire();
+ checkRead(file);
+ if (context != null)
+ checkRead(file, (URL) context);
+ } finally {
+ InCheck.release();
+ }
}
/**
* Check if an applet can write a particular file.
*/
public synchronized void checkWrite(String file) {
- if( bCheckSecurity && inApplet() && !isSecureLoader() ) {
- if (!initACL)
- initializeACLs();
- if (writeACL == null)
- return;
-
- String realPath = null;
- try {
- realPath = (new File(file)).getCanonicalPath();
- } catch (IOException e) {
- throw(new SandboxSecurityException("checkwrite.exception", e.getMessage(), file));
- }
-
- for (int i = writeACL.length ; i-- > 0 ;) {
- if (realPath.startsWith(writeACL[i]))
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inApplet() && !isSecureLoader() ) {
+ if (!initACL)
+ initializeACLs();
+ if (writeACL == null)
+ {
+ InCheck.release();
return;
+ }
+
+ String realPath = null;
+ try {
+ realPath = (new File(file)).getCanonicalPath();
+ } catch (IOException e) {
+ throw(new SandboxSecurityException("checkwrite.exception", e.getMessage(), file));
+ }
+
+ for (int i = writeACL.length ; i-- > 0 ;) {
+ if (realPath.startsWith(writeACL[i]))
+ {
+ InCheck.release();
+ return;
+ }
}
throw(new SandboxSecurityException("checkwrite", file, realPath));
}
- }
+ } finally {
+ InCheck.release();
+ }
+ }
/**
* Applets are not allowed to open file descriptors unless
@@ -514,9 +621,14 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* restrictions still apply.
*/
public synchronized void checkRead(FileDescriptor fd) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if( (inApplet() && !inClass("java.net.SocketInputStream") ) || (!fd.valid()) )
- throw(new SandboxSecurityException("checkread.fd"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if( (inApplet() && !inClass("java.net.SocketInputStream") ) || (!fd.valid()) )
+ throw(new SandboxSecurityException("checkread.fd"));
+ }
+ } finally {
+ InCheck.release();
}
}
@@ -526,9 +638,14 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* restrictions still apply.
*/
public synchronized void checkWrite(FileDescriptor fd) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if( (inApplet() && !inClass("java.net.SocketOutputStream")) || (!fd.valid()) )
- throw(new SandboxSecurityException("checkwrite.fd"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if( (inApplet() && !inClass("java.net.SocketOutputStream")) || (!fd.valid()) )
+ throw(new SandboxSecurityException("checkwrite.fd"));
+ }
+ } finally {
+ InCheck.release();
}
}
@@ -541,10 +658,15 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* cannot be subverted by ints that wrap around to an illegal u_short.
*/
public synchronized void checkListen(int port) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (inApplet() && port > 0 && port < PRIVELEGED_PORT)
- throw(new SandboxSecurityException("checklisten", String.valueOf(port)));
- }
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (inApplet() && port > 0 && port < PRIVELEGED_PORT)
+ throw(new SandboxSecurityException("checklisten", String.valueOf(port)));
+ }
+ } finally {
+ InCheck.release();
+ }
}
/**
@@ -553,10 +675,15 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* only, depending on the network security setting).
*/
public synchronized void checkAccept(String host, int port) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if( inApplet() && port < PRIVELEGED_PORT )
- throw(new SandboxSecurityException("checkaccept", host, String.valueOf(port)));
- checkConnect(host, port);
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if( inApplet() && port < PRIVELEGED_PORT )
+ throw(new SandboxSecurityException("checkaccept", host, String.valueOf(port)));
+ checkConnect(host, port);
+ }
+ } finally {
+ InCheck.release();
}
}
@@ -564,25 +691,39 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Check if an applet can connect to the given host:port.
*/
public synchronized void checkConnect(String host, int port) {
- if(bCheckSecurity && !isSecureLoader() ) {
- ClassLoader loader = currentClassLoader();
- if (loader == null)
- return; // Not called from an applet, so it is ok
+ try {
+ InCheck.acquire();
+ if(bCheckSecurity && !isSecureLoader() ) {
+ ClassLoader loader = currentClassLoader();
+ if (loader == null)
+ {
+ InCheck.release();
+ return; // Not called from an applet, so it is ok
+ }
- // REMIND: This is only appropriate for our protocol handlers.
- int depth = classDepth("sun.net.www.http.HttpClient");
- if (depth > 1)
- return; // Called through our http protocol handler
+ // REMIND: This is only appropriate for our protocol handlers.
+ int depth = classDepth("sun.net.www.http.HttpClient");
+ if (depth > 1)
+ {
+ InCheck.release();
+ return; // Called through our http protocol handler
+ }
- if(getInCheck())
- return;
+ if(getInCheck())
+ {
+ InCheck.release();
+ return;
+ }
- if (loader instanceof ClassContextImpl) {
- ClassContext appletLoader = (ClassContextImpl)loader;
- checkConnect(appletLoader.getBase().getHost(), host);
- } else {
- throw(new SandboxSecurityException("checkconnect.unknown"));
+ if (loader instanceof ClassContextImpl) {
+ ClassContext appletLoader = (ClassContextImpl)loader;
+ checkConnect(appletLoader.getBase().getHost(), host);
+ } else {
+ throw(new SandboxSecurityException("checkconnect.unknown"));
+ }
}
+ } finally {
+ InCheck.release();
}
}
@@ -590,139 +731,185 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Checks to see if the applet and the indicated execution context
* are both allowed to connect to the indicated host and port.
*/
- public void checkConnect(String host, int port, Object context) {
- checkConnect(host, port);
- if (context != null)
- checkConnect(((URL) context).getHost(), host);
+ public synchronized void checkConnect(String host, int port, Object context) {
+ try {
+ InCheck.acquire();
+ checkConnect(host, port);
+ if (context != null)
+ checkConnect(((URL) context).getHost(), host);
+ } finally {
+ InCheck.release();
+ }
}
public synchronized void checkConnect(String fromHost, String toHost, boolean trustP) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if (fromHost == null)
- return;
-
- switch (networkMode) {
- case NETWORK_NONE:
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if (fromHost == null)
+ {
+ InCheck.release();
+ return;
+ }
+
+ switch (networkMode) {
+ case NETWORK_NONE:
throw(new SandboxSecurityException("checkconnect.networknone", fromHost, toHost));
-
- case NETWORK_HOST:
- /*
- * The policy here is as follows:
- *
- * - if the strings match, and we know the IP address for it
- * we allow the connection. The calling code downstream will
- * substitute the IP in their request to the proxy if needed.
- * - if the strings don't match, and we can get the IP of
- * both hosts then
- * - if the IPs match, we allow the connection
- * - if they don't we throw(an exception
- * - if the string match works and we don't know the IP address
- * then we consult the trustProxy property, and if that is true,
- * we allow the connection.
- * set inCheck so InetAddress knows it doesn't have to
- * check security.
- */
- try {
- inCheck = true;
- InetAddress toHostAddr, fromHostAddr;
- if (!fromHost.equals(toHost)) {
- try {
- // the only time we allow non-matching strings
- // is when IPs and the IPs match.
- toHostAddr = InetAddress.getByName(toHost);
- fromHostAddr = InetAddress.getByName(fromHost);
-
- if( fromHostAddr.equals(toHostAddr) )
- return;
- else
- throw(new SandboxSecurityException("checkconnect.networkhost1", toHost, fromHost));
-
- } catch (UnknownHostException e) {
- throw(new SecurityException("checkconnect.networkhost2" + toHost + fromHost));
-// throw(new SandboxSecurityException("checkconnect.networkhost2", toHost, fromHost));
- }
- } else {
- try {
- toHostAddr = InetAddress.getByName(toHost);
- // strings match: if we have IP, we're homefree,
- // otherwise we check the properties.
- return;
- // getBoolean really defaults to false.
- } catch (UnknownHostException e) {
- if( trustP )
- return;
- else
- throw(new SandboxSecurityException("checkconnect.networkhost3", toHost));
+ case NETWORK_HOST:
+ /*
+ * The policy here is as follows:
+ *
+ * - if the strings match, and we know the IP address for it
+ * we allow the connection. The calling code downstream will
+ * substitute the IP in their request to the proxy if needed.
+ * - if the strings don't match, and we can get the IP of
+ * both hosts then
+ * - if the IPs match, we allow the connection
+ * - if they don't we throw(an exception
+ * - if the string match works and we don't know the IP address
+ * then we consult the trustProxy property, and if that is true,
+ * we allow the connection.
+ * set inCheck so InetAddress knows it doesn't have to
+ * check security.
+ */
+ try {
+ inCheck = true;
+ InetAddress toHostAddr, fromHostAddr;
+ if (!fromHost.equals(toHost)) {
+ try {
+ // the only time we allow non-matching strings
+ // is when IPs and the IPs match.
+ toHostAddr = InetAddress.getByName(toHost);
+ fromHostAddr = InetAddress.getByName(fromHost);
+
+ if( fromHostAddr.equals(toHostAddr) )
+ {
+ InCheck.release();
+ return;
+ }
+ else
+ {
+ throw(new SandboxSecurityException(
+ "checkconnect.networkhost1", toHost, fromHost));
+ }
+
+ } catch (UnknownHostException e) {
+ throw(new SecurityException("checkconnect.networkhost2" + toHost + fromHost));
+// throw(new SandboxSecurityException("checkconnect.networkhost2", toHost, fromHost));
+ }
+ } else {
+ try {
+ toHostAddr = InetAddress.getByName(toHost);
+ InCheck.release();
+ // strings match: if we have IP, we're homefree,
+ // otherwise we check the properties.
+ return;
+ // getBoolean really defaults to false.
+ } catch (UnknownHostException e) {
+ if( trustP )
+ {
+ InCheck.release();
+ return;
+ }
+ else
+ {
+ throw(new SandboxSecurityException(
+ "checkconnect.networkhost3", toHost));
+ }
+ }
}
+ } finally {
+ inCheck = false;
}
- } finally {
- inCheck = false;
+
+ case NETWORK_UNRESTRICTED:
+ InCheck.release();
+ return;
}
-
- case NETWORK_UNRESTRICTED:
- return;
- }
- throw(new SandboxSecurityException("checkconnect", fromHost, toHost));
+ throw(new SandboxSecurityException("checkconnect", fromHost, toHost));
+ }
+ } finally {
+ InCheck.release();
}
}
-
+
/**
- * Check if an applet from a host can connect to another
+ * check if an applet from a host can connect to another
* host. This usually means that you need to determine whether
* the hosts are inside or outside the firewall. For now applets
* can only access the host they came from.
*/
public synchronized void checkConnect(String fromHost, String toHost) {
- checkConnect(fromHost, toHost, Boolean.getBoolean("trustProxy"));
+ try {
+ InCheck.acquire();
+ checkConnect(fromHost, toHost, Boolean.getBoolean("trustProxy"));
+ } finally {
+ InCheck.release();
+ }
}
/**
* Checks to see if top-level windows can be created by the caller.
*/
public synchronized boolean checkTopLevelWindow(Object window) {
- if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
- /* XXX: this used to return depth > 3. However, this lets */
- /* some applets create frames without warning strings. */
- return false;
+ boolean ret = true;
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
+ /* XXX: this used to return depth > 3. However, this lets */
+ /* some applets create frames without warning strings. */
+ ret = false;
+ }
+ } finally {
+ InCheck.release();
}
- return true;
+ return ret;
}
/**
* Check if an applet can access a package.
*/
public synchronized void checkPackageAccess(String pkg) {
- if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
- if( pkg.equals( "stardiv.applet" )
- // Das AWT von StarDivision
- || pkg.equals( "stardiv.look" )
- || pkg.equals( "netscape.javascript" ) )
- return;
-
- final String forbidden[] = new String[]{
- "com.sun.star.uno",
- "com.sun.star.lib.uno",
- "com.sun.star.comp.connections",
- "com.sun.star.comp.loader",
- "com.sun.star.comp.servicemanager"
- };
-
-
- for(int j = 0; j < forbidden.length; ++ j) {
- if(pkg.startsWith(forbidden[j]))
- throw(new SandboxSecurityException("checkpackageaccess2", pkg));
- }
+ try {
+ InCheck.acquire();
+
+ if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
+ if( pkg.equals( "stardiv.applet" )
+ // Das AWT von StarDivision
+ || pkg.equals( "stardiv.look" )
+ || pkg.equals( "netscape.javascript" ) )
+ {
+ InCheck.release();
+ return;
+ }
+
+ final String forbidden[] = new String[]{
+ "com.sun.star.uno",
+ "com.sun.star.lib.uno",
+ "com.sun.star.comp.connections",
+ "com.sun.star.comp.loader",
+ "com.sun.star.comp.servicemanager"
+ };
- int i = pkg.indexOf('.');
- while (i > 0) {
- String subpkg = pkg.substring(0,i);
- if( Boolean.getBoolean("package.restrict.access." + subpkg) )
- throw(new SandboxSecurityException("checkpackageaccess", pkg));
- i = pkg.indexOf('.',i+1);
+
+ for(int j = 0; j < forbidden.length; ++ j) {
+ if(pkg.startsWith(forbidden[j]))
+ throw(new SandboxSecurityException("checkpackageaccess2", pkg));
+ }
+
+ int i = pkg.indexOf('.');
+ while (i > 0) {
+ String subpkg = pkg.substring(0,i);
+ if( Boolean.getBoolean("package.restrict.access." + subpkg) )
+ throw(new SandboxSecurityException("checkpackageaccess", pkg));
+ i = pkg.indexOf('.',i+1);
+ }
}
+ } finally {
+ InCheck.release();
}
}
@@ -730,6 +917,11 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Check if an applet can define classes in a package.
*/
public synchronized void checkPackageDefinition(String pkg) {
+ try {
+ InCheck.acquire();
+ } finally {
+ InCheck.release();
+ }
return;
/*
if (!inClassLoader())
@@ -751,8 +943,13 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
* Check if an applet can set a networking-related object factory.
*/
public synchronized void checkSetFactory() {
- if( bCheckSecurity && inApplet() && !isSecureLoader() )
- throw(new SandboxSecurityException("cannotsetfactory"));
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inApplet() && !isSecureLoader() )
+ throw(new SandboxSecurityException("cannotsetfactory"));
+ } finally {
+ InCheck.release();
+ }
}
/**
@@ -769,83 +966,226 @@ public class SandboxSecurity extends SecurityManager //implements SecurityManage
*
* XXX: Should VerifyClassAccess here? Should Class.forName do it?
*/
- public void checkMemberAccess(Class clazz, int which) {
- if( bCheckSecurity && !isSecureLoader() ) {
- if( which != java.lang.reflect.Member.PUBLIC ) {
- ClassLoader currentLoader = currentClassLoader();
- if( currentLoader != null && (classLoaderDepth() <= 3) )
- /* Client is an untrusted class loaded by currentLoader */
- if( currentLoader != clazz.getClassLoader() )
- throw(new SandboxSecurityException("checkmemberaccess"));
+ public synchronized void checkMemberAccess(Class clazz, int which) {
+ try {
+ InCheck.acquire();
+
+ if( bCheckSecurity && !isSecureLoader() ) {
+ if( which != java.lang.reflect.Member.PUBLIC ) {
+ ClassLoader currentLoader = currentClassLoader();
+ if( currentLoader != null && (classLoaderDepth() <= 3) )
+ /* Client is an untrusted class loaded by currentLoader */
+ if( currentLoader != clazz.getClassLoader() )
+ throw(new SandboxSecurityException("checkmemberaccess"));
+ }
}
+ } finally {
+ InCheck.release();
}
}
/**
* Checks to see if an applet can initiate a print job request.
*/
- public void checkPrintJobAccess() {
- if( bCheckSecurity && inApplet() && !isSecureLoader() )
- throw(new SandboxSecurityException("checkgetprintjob"));
+ public synchronized void checkPrintJobAccess() {
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inApplet() && !isSecureLoader() )
+ throw(new SandboxSecurityException("checkgetprintjob"));
+ } finally {
+ InCheck.release();
+ }
}
/**
* Checks to see if an applet can get System Clipboard access.
*/
- public void checkSystemClipboardAccess() {
- if( bCheckSecurity && inApplet() && !isSecureLoader() )
- throw(new SandboxSecurityException("checksystemclipboardaccess"));
+ public synchronized void checkSystemClipboardAccess() {
+ try {
+ InCheck.acquire();
+
+ if( bCheckSecurity && inApplet() && !isSecureLoader() )
+ throw(new SandboxSecurityException("checksystemclipboardaccess"));
+ } finally {
+ InCheck.release();
+ }
}
/**
* Checks to see if an applet can get EventQueue access.
*/
- public void checkAwtEventQueueAccess() {
- if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
+ public synchronized void checkAwtEventQueueAccess() {
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inClassLoader() && !isSecureLoader() ) {
// throw(new SandboxSecurityException("checkawteventqueueaccess"));
+ }
+ } finally {
+ InCheck.release();
}
}
/**
* Checks to see if an applet can perform a given operation.
*/
- public void checkSecurityAccess(String action) {
- if( bCheckSecurity && inApplet() && !isSecureLoader() )
- throw(new SandboxSecurityException("checksecurityaccess", action));
+ public synchronized void checkSecurityAccess(String action) {
+ try {
+ InCheck.acquire();
+ if( bCheckSecurity && inApplet() && !isSecureLoader() )
+ throw(new SandboxSecurityException("checksecurityaccess", action));
+ } finally {
+ InCheck.release();
+ }
}
/**
* Returns the thread group of the applet. We consult the classloader
* if there is one.
*/
- public ThreadGroup getThreadGroup() {
- /* First we check if any classloaded thing is on the stack. */
- ClassLoader loader = currentClassLoader();
- if (loader != null && (loader instanceof ClassContextImpl)) {
- if( inThreadGroup( Thread.currentThread() ) )
- return Thread.currentThread().getThreadGroup();
- ClassContextImpl appletLoader = (ClassContextImpl)loader;
- return appletLoader.getThreadGroup();
- } else
- return super.getThreadGroup();
+ public synchronized ThreadGroup getThreadGroup() {
+ ThreadGroup group = null;
+ try {
+ InCheck.acquire();
+ /* First we check if any classloaded thing is on the stack. */
+ ClassLoader loader = currentClassLoader();
+ if (loader != null && (loader instanceof ClassContextImpl))
+ {
+ if( inThreadGroup( Thread.currentThread() ) )
+ {
+ group = Thread.currentThread().getThreadGroup();
+ }
+ else
+ {
+ ClassContextImpl appletLoader = (ClassContextImpl)loader;
+ group = appletLoader.getThreadGroup();
+ }
+ }
+ else
+ {
+ group = super.getThreadGroup();
+ }
+ } finally {
+ InCheck.release();
+ }
+ return group;
}
-
+
public void debug(String s) {
if( debug )
System.err.println(s);
}
-
- private boolean isSecureLoader() {
- ClassLoader loader = currentClassLoader();
- if (loader != null) {
- if (loader instanceof ClassContextImpl) {
- return !((ClassContextImpl) loader).checkSecurity();
+
+ // This method is called from within the checkXXX method which
+ //already track if this class is on the stack by using InCheck.
+ private synchronized boolean isSecureLoader() {
+ InIsSecureLoader.acquire();
+ try {
+ boolean bReturn = false;
+ ClassLoader loader = currentClassLoader();
+ if (loader != null) {
+ if (loader instanceof ClassContextImpl) {
+ bReturn = !((ClassContextImpl) loader).checkSecurity();
+ } else {
+ bReturn = true; // fremder ClassLoader: kann machen was er will
+ }
} else {
- return true; // fremder ClassLoader: kann machen was er will
+ bReturn = true;
}
- } else {
- return true;
+ return bReturn;
+ } finally {
+ InIsSecureLoader.release();
}
}
+
+
+
+ /* In checkPermission we trap calls which are not covered by the old
+ (1.1) SecurityManager functions. This is necessary, because whenever
+ applets are used then the SecurityManager is set and Java components
+ may cause a checkPermission call. Then, if a user has not specified
+ permissions for this component, a SecurityException will be thrown
+ and the component fails to work.
+
+ Calls to java.lang.SecurityManager.inClassLoader result in
+ a call to this function. For example, a checkPackageAccess with the
+ package java.text resulted in a call to this function with the permission
+ All_Permission. We use the member InCheck in order to determine if we
+ are in one of the check functions. If we are then checkPermissions does
+ nothing. The calling checkXXX does the required check anyway.
+
+ We cannot override
+ void checkPermission(Permission perm, Object context)
+ because we do not know if in the thread, which is represented by context,
+ one of our security functions has been called. That is, we have no
+ access to InCheck or the class loaders to dertime if we grant permission.
+
+ */
+ public synchronized void checkPermission(java.security.Permission perm)
+ {
+ //isSecureClassLoader calls SecurityManager.currentClassLoader, which then
+ //calls this function to check if we have AllPermission. If so, then currentClassLoader
+ //returns null. Therefore we must throw and exception here. This is similar with
+ //the functions inClassLoader and classLoaderDepth.
+ if (InIsSecureLoader.inRecursion()
+ || InInClassLoader.inRecursion()
+ || InClassLoaderDepth.inRecursion())
+ {
+ if (perm.implies(allPerm))
+ throw(new SandboxSecurityException("checkPermission ", perm.toString()));
+ }
+ if (InCheck.inRecursion() == false
+ && isSecureLoader() == false)
+ {
+ throw(new SandboxSecurityException("checkPermission ", perm.toString()));
+ }
+ }
+
+ protected boolean inClassLoader()
+ {
+ InInClassLoader.acquire();
+ try
+ {
+ return super.inClassLoader();
+ } finally {
+ InInClassLoader.release();
+ }
+ }
+
+ protected int classLoaderDepth()
+ {
+ InClassLoaderDepth.acquire();
+ try
+ {
+ return super.classLoaderDepth();
+ } finally {
+ InClassLoaderDepth.release();
+ }
+
+ }
}
+class RecursionCounter
+{
+ void acquire()
+ {
+ int count = ((Integer)refCount.get()).intValue();
+ refCount.set(new Integer(++count));
+ }
+
+ void release()
+ {
+ int count = ((Integer)refCount.get()).intValue();
+ refCount.set(new Integer(--count));
+ }
+
+ boolean inRecursion() {
+ int count = ((Integer)refCount.get()).intValue();
+ return count > 0;
+ }
+
+ private ThreadLocal refCount = new ThreadLocal() {
+ protected synchronized Object initialValue() {
+ return new Integer(0);
+ }
+ };
+}