summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/com/jogamp/common/jvm/JNILibLoaderBase.java2
-rw-r--r--src/java/com/jogamp/common/os/DynamicLinker.java4
-rw-r--r--src/java/com/jogamp/common/os/Platform.java112
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java100
-rw-r--r--src/java/com/jogamp/common/util/PropertyAccess.java67
-rw-r--r--src/java/com/jogamp/common/util/SecurityUtil.java141
-rw-r--r--src/java/com/jogamp/common/util/cache/TempFileCache.java8
-rw-r--r--src/java/com/jogamp/gluegen/Logging.java5
-rw-r--r--src/java/jogamp/common/Debug.java28
-rw-r--r--src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java7
-rw-r--r--src/java/jogamp/common/os/UnixDynamicLinkerImpl.java7
-rw-r--r--src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java6
-rw-r--r--src/junit/com/jogamp/junit/sec/Applet01.java254
-rw-r--r--src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java209
14 files changed, 726 insertions, 224 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
index 5621396..456c35a 100644
--- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
+++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java
@@ -386,7 +386,7 @@ public class JNILibLoaderBase {
}
}
if(null==launcherClass) {
- String launcherClassName = PropertyAccess.getProperty("jnlp.launcher.class", false, null);
+ String launcherClassName = PropertyAccess.getProperty("jnlp.launcher.class", false);
if(null!=launcherClassName) {
try {
launcherClass = Class.forName(launcherClassName);
diff --git a/src/java/com/jogamp/common/os/DynamicLinker.java b/src/java/com/jogamp/common/os/DynamicLinker.java
index a0da9fb..32aa7eb 100644
--- a/src/java/com/jogamp/common/os/DynamicLinker.java
+++ b/src/java/com/jogamp/common/os/DynamicLinker.java
@@ -46,8 +46,8 @@ public interface DynamicLinker {
public static final boolean DEBUG = NativeLibrary.DEBUG;
public static final boolean DEBUG_LOOKUP = NativeLibrary.DEBUG_LOOKUP;
- public long openLibraryGlobal(String pathname, boolean debug);
- public long openLibraryLocal(String pathname, boolean debug);
+ public long openLibraryGlobal(String pathname, boolean debug) throws SecurityException;
+ public long openLibraryLocal(String pathname, boolean debug) throws SecurityException;
public long lookupSymbol(long libraryHandle, String symbolName);
public long lookupSymbolGlobal(String symbolName);
public void closeLibrary(long libraryHandle);
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index aa9bccd..0ae3cbb 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -162,49 +162,69 @@ public class Platform extends PlatformPropsImpl {
/** <code>true</code> if AWT is available and not in headless mode, otherwise <code>false</code>. */
public static final boolean AWT_AVAILABLE;
- private static final URI platformClassJarURI;
+ private static final boolean isRunningFromJarURL;
static {
- PlatformPropsImpl.initSingleton(); // just documenting the order of static initialization
-
- {
- URI _platformClassJarURI;
- try {
- _platformClassJarURI = JarUtil.getJarURI(Platform.class.getName(), Platform.class.getClassLoader());
- } catch (Exception e) {
- _platformClassJarURI = null;
- }
- platformClassJarURI = _platformClassJarURI;
- }
-
- USE_TEMP_JAR_CACHE = (OS_TYPE != OSType.ANDROID) && isRunningFromJarURL() &&
- Debug.getBooleanProperty(useTempJarCachePropName, true, true);
+ final boolean[] _isRunningFromJarURL = new boolean[] { false };
+ final boolean[] _USE_TEMP_JAR_CACHE = new boolean[] { false };
+ final boolean[] _AWT_AVAILABLE = new boolean[] { false };
+
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
- AWT_AVAILABLE = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
- public Boolean run() {
- // load GluegenRT native library
- loadGlueGenRTImpl();
+ PlatformPropsImpl.initSingleton(); // documenting the order of static initialization
- // JVM bug workaround
- JVMUtil.initSingleton(); // requires gluegen-rt, one-time init.
+ final ClassLoader cl = Platform.class.getClassLoader();
- // detect AWT availability
- boolean awtAvailable = false;
+ final URI platformClassJarURI;
{
- final ClassLoader cl = Platform.class.getClassLoader();
- if( !Debug.getBooleanProperty("java.awt.headless", true) &&
- ReflectionUtil.isClassAvailable(ReflectionUtil.AWTNames.ComponentClass, cl) &&
- ReflectionUtil.isClassAvailable(ReflectionUtil.AWTNames.GraphicsEnvironmentClass, cl) ) {
- try {
- awtAvailable = false == ((Boolean)ReflectionUtil.callStaticMethod(ReflectionUtil.AWTNames.GraphicsEnvironmentClass, ReflectionUtil.AWTNames.isHeadlessMethod, null, null, cl)).booleanValue();
- } catch (Throwable t) { }
+ URI _platformClassJarURI = null;
+ try {
+ _platformClassJarURI = JarUtil.getJarURI(Platform.class.getName(), cl);
+ } catch (Exception e) { }
+ platformClassJarURI = _platformClassJarURI;
+ }
+ _isRunningFromJarURL[0] = null != platformClassJarURI;
+
+ _USE_TEMP_JAR_CACHE[0] = ( OS_TYPE != OSType.ANDROID ) && ( null != platformClassJarURI ) &&
+ Debug.getBooleanProperty(useTempJarCachePropName, true, true);
+
+ // load GluegenRT native library
+ if(_USE_TEMP_JAR_CACHE[0] && TempJarCache.initSingleton()) {
+ String nativeJarName = null;
+ URI jarUriRoot = null;
+ URI nativeJarURI = null;
+ try {
+ final String jarName = JarUtil.getJarBasename( platformClassJarURI );
+ final String nativeJarBasename = jarName.substring(0, jarName.indexOf(".jar")); // ".jar" already validated w/ JarUtil.getJarBasename(..)
+ nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar";
+ jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( platformClassJarURI ) );
+ nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName);
+ TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURI);
+ } catch (Exception e0) {
+ // IllegalArgumentException, IOException
+ System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while TempJarCache.bootstrapNativeLib() of "+nativeJarURI+" ("+jarUriRoot+" + "+nativeJarName+")");
}
}
- return new Boolean(awtAvailable);
- }
- }).booleanValue();
-
-
+ DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false, cl);
+
+ // JVM bug workaround
+ JVMUtil.initSingleton(); // requires gluegen-rt, one-time init.
+
+ // AWT Headless determination
+ if( !Debug.getBooleanProperty("java.awt.headless", true) &&
+ ReflectionUtil.isClassAvailable(ReflectionUtil.AWTNames.ComponentClass, cl) &&
+ ReflectionUtil.isClassAvailable(ReflectionUtil.AWTNames.GraphicsEnvironmentClass, cl) ) {
+ try {
+ _AWT_AVAILABLE[0] = false == ((Boolean)ReflectionUtil.callStaticMethod(ReflectionUtil.AWTNames.GraphicsEnvironmentClass, ReflectionUtil.AWTNames.isHeadlessMethod, null, null, cl)).booleanValue();
+ } catch (Throwable t) { }
+ }
+ return null;
+ } } );
+ isRunningFromJarURL = _isRunningFromJarURL[0];
+ USE_TEMP_JAR_CACHE = _USE_TEMP_JAR_CACHE[0];
+ AWT_AVAILABLE = _AWT_AVAILABLE[0];
+
MachineDescription md = MachineDescriptionRuntime.getRuntime();
if(null == md) {
MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic();
@@ -228,27 +248,7 @@ public class Platform extends PlatformPropsImpl {
* @return true if we're running from a Jar URL, otherwise false
*/
public static final boolean isRunningFromJarURL() {
- return null != platformClassJarURI;
- }
-
- private static final void loadGlueGenRTImpl() {
- if(USE_TEMP_JAR_CACHE && TempJarCache.initSingleton()) {
- String nativeJarName = null;
- URI jarUriRoot = null;
- URI nativeJarURI = null;
- try {
- final String jarName = JarUtil.getJarBasename(platformClassJarURI);
- final String nativeJarBasename = jarName.substring(0, jarName.indexOf(".jar")); // ".jar" already validated w/ JarUtil.getJarBasename(..)
- nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar";
- jarUriRoot = JarUtil.getURIDirname( JarUtil.getJarSubURI( platformClassJarURI ) );
- nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName);
- TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJarURI);
- } catch (Exception e0) {
- // IllegalArgumentException, IOException
- System.err.println("Catched "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while TempJarCache.bootstrapNativeLib() of "+nativeJarURI+" ("+jarUriRoot+" + "+nativeJarName+")");
- }
- }
- DynamicLibraryBundle.GlueJNILibLoader.loadLibrary(libBaseName, false, Platform.class.getClassLoader());
+ return isRunningFromJarURL;
}
/**
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index 46d6b24..2f0c77f 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -33,12 +33,10 @@ import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.net.URISyntaxException;
@@ -817,20 +815,12 @@ public class IOUtil {
* @param dir the directory to process
* @param create true if the directory shall be created if not existing
* @param executable true if the user intents to launch executables from the temporary directory, otherwise false.
- * @param acc The security {@link AccessControlContext} to create directories and test <i>executability</i>
* @throws SecurityException if file creation and process execution is not allowed within the current security context
*/
- public static File testDir(final File dir, final boolean create, final boolean executable, AccessControlContext acc)
+ public static File testDir(final File dir, final boolean create, final boolean executable)
throws SecurityException
{
- if( null != acc ) {
- return AccessController.doPrivileged(new PrivilegedAction<File>() {
- public File run() {
- return testDirImpl(dir, create, executable);
- } }, acc);
- } else {
- return testDirImpl(dir, create, executable);
- }
+ return testDirImpl(dir, create, executable);
}
private static boolean isStringSet(String s) { return null != s && 0 < s.length(); }
@@ -873,9 +863,35 @@ public class IOUtil {
return tmpBaseDir;
}
- private static File getTempDirImpl(boolean executable)
+ /**
+ * Returns a platform independent writable directory for temporary files
+ * consisting of the platform's {@code temp-root} + {@link #tmpSubDir},
+ * e.g. {@code /tmp/jogamp_0000/}.
+ * <p>
+ * On standard Java the {@code temp-root} folder is specified by <code>java.io.tempdir</code>.
+ * </p>
+ * <p>
+ * On Android the {@code temp-root} folder is relative to the applications local folder
+ * (see {@link Context#getDir(String, int)}) is returned, if
+ * the Android application/activity has registered it's Application Context
+ * via {@link jogamp.common.os.android.StaticContext.StaticContext#init(Context, ClassLoader) StaticContext.init(..)}.
+ * This allows using the temp folder w/o the need for <code>sdcard</code>
+ * access, which would be the <code>java.io.tempdir</code> location on Android!
+ * </p>
+ * <p>
+ * In case {@code temp-root} is the users home folder,
+ * a dot is being prepended to {@link #tmpSubDir}, i.e.: {@code /home/user/.jogamp_0000/}.
+ * </p>
+ * @param executable true if the user intents to launch executables from the temporary directory, otherwise false.
+ * @throws RuntimeException if no temporary directory could be determined
+ * @throws SecurityException if access to <code>java.io.tmpdir</code> is not allowed within the current security context
+ *
+ * @see PropertyAccess#getProperty(String, boolean)
+ * @see Context#getDir(String, int)
+ */
+ public static File getTempDir(final boolean executable)
throws SecurityException, RuntimeException
- {
+ {
if(!tempRootSet) { // volatile: ok
synchronized(IOUtil.class) {
if(!tempRootSet) {
@@ -889,8 +905,8 @@ public class IOUtil {
}
}
- final String java_io_tmpdir = PropertyAccess.getProperty(java_io_tmpdir_propkey, false, null);
- final String user_home = PropertyAccess.getProperty(user_home_propkey, false, null);
+ final String java_io_tmpdir = PropertyAccess.getProperty(java_io_tmpdir_propkey, false);
+ final String user_home = PropertyAccess.getProperty(user_home_propkey, false);
final String xdg_cache_home;
{
@@ -951,6 +967,8 @@ public class IOUtil {
if(null == r) {
throw new RuntimeException("Could not determine a temporary directory");
}
+ final FilePermission fp = new FilePermission(r.getAbsolutePath(), "read,write,delete");
+ SecurityUtil.checkPermission(fp);
return r;
}
private static File tempRootExec = null; // writeable and executable
@@ -958,53 +976,13 @@ public class IOUtil {
private static volatile boolean tempRootSet = false;
/**
- * Returns a platform independent writable directory for temporary files
- * consisting of the platform's {@code temp-root} + {@link #tmpSubDir},
- * e.g. {@code /tmp/jogamp_0000/}.
- * <p>
- * On standard Java the {@code temp-root} folder is specified by <code>java.io.tempdir</code>.
- * </p>
- * <p>
- * On Android the {@code temp-root} folder is relative to the applications local folder
- * (see {@link Context#getDir(String, int)}) is returned, if
- * the Android application/activity has registered it's Application Context
- * via {@link jogamp.common.os.android.StaticContext.StaticContext#init(Context, ClassLoader) StaticContext.init(..)}.
- * This allows using the temp folder w/o the need for <code>sdcard</code>
- * access, which would be the <code>java.io.tempdir</code> location on Android!
- * </p>
- * <p>
- * In case {@code temp-root} is the users home folder,
- * a dot is being prepended to {@link #tmpSubDir}, i.e.: {@code /home/user/.jogamp_0000/}.
- * </p>
- * @param executable true if the user intents to launch executables from the temporary directory, otherwise false.
- * @param acc The security {@link AccessControlContext} to access properties, environment vars, create directories and test <i>executability</i>
- * @throws SecurityException if access to <code>java.io.tmpdir</code> is not allowed within the current security context
- * @throws RuntimeException if no temporary directory could be determined
- *
- * @see PropertyAccess#getProperty(String, boolean, java.security.AccessControlContext)
- * @see Context#getDir(String, int)
- */
- public static File getTempDir(final boolean executable, AccessControlContext acc)
- throws SecurityException, RuntimeException
- {
- if( null != acc ) {
- return AccessController.doPrivileged(new PrivilegedAction<File>() {
- public File run() {
- return getTempDirImpl(executable);
- } }, acc);
- } else {
- return getTempDirImpl(executable);
- }
- }
-
- /**
* Utilizing {@link File#createTempFile(String, String, File)} using
- * {@link #getTempRoot(AccessControlContext, boolean)} as the directory parameter, ie. location
+ * {@link #getTempDir(boolean)} as the directory parameter, ie. location
* of the root temp folder.
*
* @see File#createTempFile(String, String)
* @see File#createTempFile(String, String, File)
- * @see #getTempRoot(AccessControlContext, boolean)
+ * @see #getTempDir(boolean)
*
* @param prefix
* @param suffix
@@ -1014,10 +992,10 @@ public class IOUtil {
* @throws IOException
* @throws SecurityException
*/
- public static File createTempFile(String prefix, String suffix, boolean executable, AccessControlContext acc)
+ public static File createTempFile(String prefix, String suffix, boolean executable)
throws IllegalArgumentException, IOException, SecurityException
{
- return File.createTempFile( prefix, suffix, getTempDir(executable, acc) );
+ return File.createTempFile( prefix, suffix, getTempDir(executable) );
}
public static void close(Closeable stream, boolean throwRuntimeException) throws RuntimeException {
diff --git a/src/java/com/jogamp/common/util/PropertyAccess.java b/src/java/com/jogamp/common/util/PropertyAccess.java
index 51b9533..dde6b50 100644
--- a/src/java/com/jogamp/common/util/PropertyAccess.java
+++ b/src/java/com/jogamp/common/util/PropertyAccess.java
@@ -48,12 +48,13 @@ public class PropertyAccess {
// 'jogamp.' and maybe other trusted prefixes will be added later via 'addTrustedPrefix()'
}
- public static final void addTrustedPrefix(String prefix, Class<?> certClass) {
- if(SecurityUtil.equalsLocalCert(certClass)) {
- trustedPrefixes.add(prefix);
- } else {
- throw new SecurityException("Illegal Access - prefix "+prefix+", with cert class "+certClass);
- }
+ /**
+ * @param prefix New prefix to be registered as trusted.
+ * @throws AccessControlException as thrown by {@link SecurityUtil#checkAllPermissions()}.
+ */
+ protected static final void addTrustedPrefix(String prefix) throws AccessControlException {
+ SecurityUtil.checkAllPermissions();
+ trustedPrefixes.add(prefix);
}
public static final boolean isTrusted(String propertyKey) {
@@ -65,11 +66,11 @@ public class PropertyAccess {
}
}
- /** @see #getProperty(String, boolean, AccessControlContext) */
- public static final int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc, int defaultValue) {
+ /** @see #getProperty(String, boolean) */
+ public static final int getIntProperty(final String property, final boolean jnlpAlias, int defaultValue) {
int i=defaultValue;
try {
- final String sv = PropertyAccess.getProperty(property, jnlpAlias, acc);
+ final String sv = PropertyAccess.getProperty(property, jnlpAlias);
if(null!=sv) {
i = Integer.valueOf(sv).intValue();
}
@@ -77,11 +78,11 @@ public class PropertyAccess {
return i;
}
- /** @see #getProperty(String, boolean, AccessControlContext) */
- public static final long getLongProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc, long defaultValue) {
+ /** @see #getProperty(String, boolean) */
+ public static final long getLongProperty(final String property, final boolean jnlpAlias, long defaultValue) {
long l=defaultValue;
try {
- final String sv = PropertyAccess.getProperty(property, jnlpAlias, acc);
+ final String sv = PropertyAccess.getProperty(property, jnlpAlias);
if(null!=sv) {
l = Long.valueOf(sv).longValue();
}
@@ -89,23 +90,23 @@ public class PropertyAccess {
return l;
}
- /** @see #getProperty(String, boolean, AccessControlContext) */
- public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
- return Boolean.valueOf(PropertyAccess.getProperty(property, jnlpAlias, acc)).booleanValue();
+ /** @see #getProperty(String, boolean) */
+ public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
+ return Boolean.valueOf(PropertyAccess.getProperty(property, jnlpAlias)).booleanValue();
}
- /** @see #getProperty(String, boolean, AccessControlContext) */
- public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc, boolean defaultValue) {
- final String valueS = PropertyAccess.getProperty(property, jnlpAlias, acc);
+ /** @see #getProperty(String, boolean) */
+ public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias, boolean defaultValue) {
+ final String valueS = PropertyAccess.getProperty(property, jnlpAlias);
if(null != valueS) {
return Boolean.valueOf(valueS).booleanValue();
}
return defaultValue;
}
- /** @see #getProperty(String, boolean, AccessControlContext) */
- public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
- return (PropertyAccess.getProperty(property, jnlpAlias, acc) != null) ? true : false;
+ /** @see #getProperty(String, boolean) */
+ public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
+ return (PropertyAccess.getProperty(property, jnlpAlias) != null) ? true : false;
}
/**
@@ -119,8 +120,6 @@ public class PropertyAccess {
* @param propertyKey the property name to query.
* @param jnlpAlias true if a fallback attempt to query the JNLP aliased <i>trusted property</i> shall be made,
* otherwise false.
- * @param acc the AccessControlerContext to be used for privileged access to the system property, or null.
- *
* @return the property value if exists, or null
*
* @throws NullPointerException if the property name is null
@@ -129,7 +128,7 @@ public class PropertyAccess {
*
* @see System#getProperty(String)
*/
- public static final String getProperty(final String propertyKey, final boolean jnlpAlias, final AccessControlContext acc)
+ public static final String getProperty(final String propertyKey, final boolean jnlpAlias)
throws SecurityException, NullPointerException, IllegalArgumentException {
if(null == propertyKey) {
throw new NullPointerException("propertyKey is NULL");
@@ -138,23 +137,13 @@ public class PropertyAccess {
throw new IllegalArgumentException("propertyKey is empty");
}
String s=null;
- // int cause = 0;
if( isTrusted(propertyKey) ) {
// 'trusted' property (jnlp., javaws., jogamp., ..)
s = getTrustedPropKey(propertyKey);
- // cause = null != s ? 1 : 0;
} else {
- if( null != acc ) {
- s = AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(propertyKey);
- } }, acc);
- // cause = null != s ? 2 : 0;
- } else {
- s = System.getProperty(propertyKey);
- // cause = null != s ? 3 : 0;
- }
+ // may throw SecurityException, AccessControlerException
+ s = System.getProperty(propertyKey);
}
if( null == s && jnlpAlias ) {
// Try 'jnlp.' aliased property ..
@@ -162,11 +151,8 @@ public class PropertyAccess {
// Properties within the namespace "jnlp." or "javaws." should be considered trusted,
// i.e. always granted w/o special privileges.
s = getTrustedPropKey(jnlp_prefix + propertyKey);
- // cause = null != s ? 4 : 0;
}
- }
- // System.err.println("Prop: <"+propertyKey+"> = <"+s+">, cause "+cause);
-
+ }
return s;
}
@@ -177,7 +163,6 @@ public class PropertyAccess {
return System.getProperty(propertyKey);
} catch (SecurityException se) {
throw new SecurityException("Could not access trusted property '"+propertyKey+"'", se);
-
}
}
});
diff --git a/src/java/com/jogamp/common/util/SecurityUtil.java b/src/java/com/jogamp/common/util/SecurityUtil.java
index 4583201..4d7aa5d 100644
--- a/src/java/com/jogamp/common/util/SecurityUtil.java
+++ b/src/java/com/jogamp/common/util/SecurityUtil.java
@@ -27,30 +27,127 @@
*/
package com.jogamp.common.util;
-import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.AllPermission;
import java.security.CodeSource;
+import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
public class SecurityUtil {
- /* package private */ static final AccessControlContext localACC;
- /* package private */ static final Certificate[] localCerts;
+ private static final SecurityManager securityManager;
+ private static final Permission allPermissions;
+ private static final boolean DEBUG = false;
static {
- localACC = AccessController.doPrivileged(new PrivilegedAction<AccessControlContext>() {
- public AccessControlContext run() {
- return AccessController.getContext();
- } } );
- localCerts = getCerts(SecurityUtil.class);
+ allPermissions = new AllPermission();
+ securityManager = System.getSecurityManager();
+
+ if( DEBUG ) {
+ final boolean hasAllPermissions;
+ {
+ final ProtectionDomain insecPD = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
+ public ProtectionDomain run() {
+ return SecurityUtil.class.getProtectionDomain();
+ } } );
+ boolean _hasAllPermissions;
+ try {
+ insecPD.implies(allPermissions);
+ _hasAllPermissions = true;
+ } catch( SecurityException ace ) {
+ _hasAllPermissions = false;
+ }
+ hasAllPermissions = _hasAllPermissions;
+ }
+
+ System.err.println("SecurityUtil: Has SecurityManager: "+ ( null != securityManager ) ) ;
+ System.err.println("SecurityUtil: Has AllPermissions: "+hasAllPermissions);
+ final Certificate[] certs = AccessController.doPrivileged(new PrivilegedAction<Certificate[]>() {
+ public Certificate[] run() {
+ return getCerts(SecurityUtil.class);
+ } } );
+ System.err.println("SecurityUtil: Cert count: "+ ( null != certs ? certs.length : 0 ));
+ if( null != certs ) {
+ for(int i=0; i<certs.length; i++) {
+ System.err.println("\t cert["+i+"]: "+certs[i].toString());
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if no {@link SecurityManager} has been installed
+ * or the installed {@link SecurityManager}'s <code>checkPermission(new AllPermission())</code>
+ * passes. Otherwise method returns <code>false</code>.
+ */
+ public static final boolean hasAllPermissions() {
+ return hasPermission(allPermissions);
+ }
+
+ /**
+ * Returns <code>true</code> if no {@link SecurityManager} has been installed
+ * or the installed {@link SecurityManager}'s <code>checkPermission(perm)</code>
+ * passes. Otherwise method returns <code>false</code>.
+ */
+ public static final boolean hasPermission(Permission perm) {
+ try {
+ checkPermission(perm);
+ return true;
+ } catch( SecurityException ace ) {
+ return false;
+ }
+ }
+
+ /**
+ * Throws an {@link SecurityException} if an installed {@link SecurityManager}
+ * does not permit the requested {@link AllPermission}.
+ */
+ public static final void checkAllPermissions() throws SecurityException {
+ checkPermission(allPermissions);
+ }
+
+ /**
+ * Throws an {@link SecurityException} if an installed {@link SecurityManager}
+ * does not permit the requested {@link Permission}.
+ */
+ public static final void checkPermission(Permission perm) throws SecurityException {
+ if( null != securityManager ) {
+ securityManager.checkPermission(perm);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if no {@link SecurityManager} has been installed
+ * or the installed {@link SecurityManager}'s <code>checkLink(libName)</code>
+ * passes. Otherwise method returns <code>false</code>.
+ */
+ public static final boolean hasLinkPermission(String libName) {
+ try {
+ checkLinkPermission(libName);
+ return true;
+ } catch( SecurityException ace ) {
+ return false;
+ }
}
- public static final Certificate[] getCerts(final Class<?> clz) {
- final ProtectionDomain pd = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
- public ProtectionDomain run() {
- return clz.getProtectionDomain();
- } } );
+ /**
+ * Throws an {@link SecurityException} if an installed {@link SecurityManager}
+ * does not permit to dynamically link the given libName.
+ */
+ public static final void checkLinkPermission(String libName) throws SecurityException {
+ if( null != securityManager ) {
+ securityManager.checkLink(libName);
+ }
+ }
+
+ /**
+ * @param clz
+ * @return
+ * @throws SecurityException if the caller has no permission to access the ProtectedDomain of the given class.
+ */
+ public static final Certificate[] getCerts(final Class<?> clz) throws SecurityException {
+ final ProtectionDomain pd = clz.getProtectionDomain();
final CodeSource cs = (null != pd) ? pd.getCodeSource() : null;
final Certificate[] certs = (null != cs) ? cs.getCertificates() : null;
return (null != certs && certs.length>0) ? certs : null;
@@ -72,21 +169,5 @@ public class SecurityUtil {
i++;
}
return i == a.length;
- }
-
- public static final boolean equalsLocalCert(Certificate[] b) {
- return equals(localCerts, b);
- }
-
- public static final boolean equalsLocalCert(Class<?> clz) {
- return equalsLocalCert(getCerts(clz));
- }
-
- public static final AccessControlContext getCommonAccessControlContext(Class<?> clz) {
- if(equalsLocalCert(clz)) {
- return localACC;
- } else {
- return null;
- }
- }
+ }
}
diff --git a/src/java/com/jogamp/common/util/cache/TempFileCache.java b/src/java/com/jogamp/common/util/cache/TempFileCache.java
index 755ed7b..32f5c2a 100644
--- a/src/java/com/jogamp/common/util/cache/TempFileCache.java
+++ b/src/java/com/jogamp/common/util/cache/TempFileCache.java
@@ -33,10 +33,8 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
-import java.security.AccessControlContext;
import com.jogamp.common.util.IOUtil;
-import com.jogamp.common.util.SecurityUtil;
import jogamp.common.Debug;
@@ -72,8 +70,6 @@ public class TempFileCache {
private File individualTmpDir;
static {
- final AccessControlContext acc = SecurityUtil.getCommonAccessControlContext(TempFileCache.class);
-
// Global Lock !
synchronized (System.out) {
// Create / initialize the temp root directory, starting the Reaper
@@ -81,8 +77,8 @@ public class TempFileCache {
// exception, set an error code.
File _tmpBaseDir = null;
try {
- _tmpBaseDir = new File(IOUtil.getTempDir(true /* executable */, acc), tmpDirPrefix);
- _tmpBaseDir = IOUtil.testDir(_tmpBaseDir, true /* create */, false /* executable */, acc); // executable already checked
+ _tmpBaseDir = new File(IOUtil.getTempDir(true /* executable */), tmpDirPrefix);
+ _tmpBaseDir = IOUtil.testDir(_tmpBaseDir, true /* create */, false /* executable */); // executable already checked
} catch (Exception ex) {
System.err.println("Warning: Catched Exception while retrieving temp base directory:");
ex.printStackTrace();
diff --git a/src/java/com/jogamp/gluegen/Logging.java b/src/java/com/jogamp/gluegen/Logging.java
index 87d6196..d8c1b5a 100644
--- a/src/java/com/jogamp/gluegen/Logging.java
+++ b/src/java/com/jogamp/gluegen/Logging.java
@@ -38,7 +38,6 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import com.jogamp.common.util.PropertyAccess;
-import com.jogamp.common.util.SecurityUtil;
/**
*
@@ -48,11 +47,11 @@ public class Logging {
static void init() {
final String packageName = Logging.class.getPackage().getName();
- final String property = PropertyAccess.getProperty(packageName+".level", true, SecurityUtil.getCommonAccessControlContext(Logging.class));
+ final String property = PropertyAccess.getProperty(packageName+".level", true);
Level level;
if(property != null) {
level = Level.parse(property);
- }else{
+ } else {
level = Level.WARNING;
}
diff --git a/src/java/jogamp/common/Debug.java b/src/java/jogamp/common/Debug.java
index 19e2fd7..b8a32d8 100644
--- a/src/java/jogamp/common/Debug.java
+++ b/src/java/jogamp/common/Debug.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -39,6 +40,9 @@
package jogamp.common;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import com.jogamp.common.util.PropertyAccess;
/** Helper routines for logging and debugging. */
@@ -49,28 +53,16 @@ public class Debug extends PropertyAccess {
private static final boolean debugAll;
static {
- PropertyAccess.addTrustedPrefix("jogamp.", Debug.class);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ PropertyAccess.addTrustedPrefix("jogamp.");
+ return null;
+ } } );
verbose = isPropertyDefined("jogamp.verbose", true);
debugAll = isPropertyDefined("jogamp.debug", true);
}
- public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
- return PropertyAccess.isPropertyDefined(property, jnlpAlias, null);
- }
-
- public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
- return PropertyAccess.getBooleanProperty(property, jnlpAlias, null);
- }
-
- public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias, boolean defaultValue) {
- return PropertyAccess.getBooleanProperty(property, jnlpAlias, null, defaultValue);
- }
-
- public static final long getLongProperty(final String property, final boolean jnlpAlias, long defaultValue) {
- return PropertyAccess.getLongProperty(property, jnlpAlias, null, defaultValue);
- }
-
public static boolean verbose() {
return verbose;
}
diff --git a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
index 4eb381f..95f7e63 100644
--- a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
@@ -3,6 +3,7 @@
package jogamp.common.os;
import com.jogamp.common.os.DynamicLinker;
+import com.jogamp.common.util.SecurityUtil;
public class MacOSXDynamicLinkerImpl implements DynamicLinker {
@@ -28,7 +29,7 @@ public class MacOSXDynamicLinkerImpl implements DynamicLinker {
// --- Begin CustomJavaCode .cfg declarations
- public long openLibraryLocal(String pathname, boolean debug) {
+ public long openLibraryLocal(String pathname, boolean debug) throws SecurityException {
// Note we use RTLD_LOCAL visibility to _NOT_ allow this functionality to
// be used to pre-resolve dependent libraries of JNI code without
// requiring that all references to symbols in those libraries be
@@ -36,10 +37,11 @@ public class MacOSXDynamicLinkerImpl implements DynamicLinker {
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
+ SecurityUtil.checkLinkPermission(pathname);
return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
}
- public long openLibraryGlobal(String pathname, boolean debug) {
+ public long openLibraryGlobal(String pathname, boolean debug) throws SecurityException {
// Note we use RTLD_GLOBAL visibility to allow this functionality to
// be used to pre-resolve dependent libraries of JNI code without
// requiring that all references to symbols in those libraries be
@@ -47,6 +49,7 @@ public class MacOSXDynamicLinkerImpl implements DynamicLinker {
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
+ SecurityUtil.checkLinkPermission(pathname);
return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
diff --git a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
index 29998bd..2258dfa 100644
--- a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
@@ -3,6 +3,7 @@
package jogamp.common.os;
import com.jogamp.common.os.DynamicLinker;
+import com.jogamp.common.util.SecurityUtil;
public class UnixDynamicLinkerImpl implements DynamicLinker {
@@ -27,7 +28,7 @@ public class UnixDynamicLinkerImpl implements DynamicLinker {
// --- Begin CustomJavaCode .cfg declarations
- public long openLibraryLocal(String pathname, boolean debug) {
+ public long openLibraryLocal(String pathname, boolean debug) throws SecurityException {
// Note we use RTLD_GLOBAL visibility to _NOT_ allow this functionality to
// be used to pre-resolve dependent libraries of JNI code without
// requiring that all references to symbols in those libraries be
@@ -35,10 +36,11 @@ public class UnixDynamicLinkerImpl implements DynamicLinker {
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
+ SecurityUtil.checkLinkPermission(pathname);
return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
}
- public long openLibraryGlobal(String pathname, boolean debug) {
+ public long openLibraryGlobal(String pathname, boolean debug) throws SecurityException {
// Note we use RTLD_GLOBAL visibility to allow this functionality to
// be used to pre-resolve dependent libraries of JNI code without
// requiring that all references to symbols in those libraries be
@@ -46,6 +48,7 @@ public class UnixDynamicLinkerImpl implements DynamicLinker {
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
+ SecurityUtil.checkLinkPermission(pathname);
return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
diff --git a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
index e7f5b52..eb02584 100644
--- a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
@@ -3,6 +3,7 @@
package jogamp.common.os;
import com.jogamp.common.os.DynamicLinker;
+import com.jogamp.common.util.SecurityUtil;
public class WindowsDynamicLinkerImpl implements DynamicLinker {
@@ -20,13 +21,14 @@ public class WindowsDynamicLinkerImpl implements DynamicLinker {
// --- Begin CustomJavaCode .cfg declarations
- public long openLibraryLocal(String libraryName, boolean debug) {
+ public long openLibraryLocal(String libraryName, boolean debug) throws SecurityException {
// How does that work under Windows ?
// Don't know .. so it's an alias for the time being
return openLibraryGlobal(libraryName, debug);
}
- public long openLibraryGlobal(String libraryName, boolean debug) {
+ public long openLibraryGlobal(String libraryName, boolean debug) throws SecurityException {
+ SecurityUtil.checkLinkPermission(libraryName);
long handle = LoadLibraryW(libraryName);
if(0==handle && debug) {
int err = GetLastError();
diff --git a/src/junit/com/jogamp/junit/sec/Applet01.java b/src/junit/com/jogamp/junit/sec/Applet01.java
new file mode 100644
index 0000000..12e8f48
--- /dev/null
+++ b/src/junit/com/jogamp/junit/sec/Applet01.java
@@ -0,0 +1,254 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.junit.sec;
+
+import java.applet.Applet;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.AccessControlException;
+
+import com.jogamp.common.os.MachineDescription;
+import com.jogamp.common.os.NativeLibrary;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.JarUtil;
+
+/**
+ * Applet: Provoke AccessControlException while writing to file!
+ */
+@SuppressWarnings("serial")
+public class Applet01 extends Applet {
+ static final String java_io_tmpdir_propkey = "java.io.tmpdir";
+ static final String java_home_propkey = "java.home";
+ static final String os_name_propkey = "os.name";
+
+ static final String tfilename = "test.bin" ;
+ static final MachineDescription machine = Platform.getMachineDescription();
+ static final int tsz = machine.pageSizeInBytes();
+
+ static final boolean usesSecurityManager;
+
+ static {
+ if( null == System.getSecurityManager() ) {
+ usesSecurityManager = false;
+ System.err.println("No SecurityManager Installed");
+ } else {
+ usesSecurityManager = true;
+ System.err.println("SecurityManager Already Installed");
+ }
+ }
+
+ static void testPropImpl(String propKey, boolean isSecure) {
+ isSecure |= !usesSecurityManager;
+
+ Exception se0 = null;
+ try {
+ String p0 = System.getProperty(propKey);
+ System.err.println(propKey+": "+p0);
+ } catch (AccessControlException e) {
+ se0 = e;
+ if( !isSecure ) {
+ System.err.println("Expected exception for insecure property <"+propKey+">");
+ System.err.println("Message: "+se0.getMessage());
+ } else {
+ System.err.println("Unexpected exception for secure property <"+propKey+">");
+ se0.printStackTrace();
+ }
+ }
+ if( isSecure ) {
+ if( null != se0 ) {
+ throw new Error("AccessControlException thrown on secure property <"+propKey+">", se0);
+ }
+ } else {
+ if( null == se0 ) {
+ throw new Error("AccessControlException not thrown on secure property <"+propKey+">");
+ }
+ }
+ }
+
+ static void testTempDirImpl(boolean isSecure) {
+ isSecure |= !usesSecurityManager;
+
+ Exception se0 = null;
+ try {
+ File tmp = IOUtil.getTempDir(true);
+ System.err.println("Temp: "+tmp);
+ } catch (AccessControlException e) {
+ se0 = e;
+ if( !isSecure ) {
+ System.err.println("Expected exception for insecure temp dir");
+ System.err.println("Message: "+se0.getMessage());
+ } else {
+ System.err.println("Unexpected exception for secure temp dir");
+ se0.printStackTrace();
+ }
+ }
+ if( isSecure ) {
+ if( null != se0 ) {
+ throw new Error("AccessControlException thrown on secure temp dir", se0);
+ }
+ } else {
+ if( null == se0 ) {
+ throw new Error("AccessControlException not thrown on secure temp dir");
+ }
+ }
+ }
+
+ private void testWriteFile() {
+ AccessControlException sec01 = null;
+ try {
+ File tmp = IOUtil.getTempDir(true);
+ System.err.println("Temp: "+tmp);
+ byte[] orig = new byte[tsz];
+ final File tfile = new File(tmp, tfilename);
+ final OutputStream tout = new BufferedOutputStream(new FileOutputStream(tfile));
+ for(int i=0; i<tsz; i++) {
+ final byte b = (byte) (i%256);
+ orig[i] = b;
+ tout.write(b);
+ }
+ tout.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } catch (AccessControlException ace) {
+ // GOOD!
+ sec01 = ace;
+ System.err.println("Expected:"+ace.getMessage());
+ }
+ if( !usesSecurityManager ) {
+ if( null != sec01 ) {
+ throw new Error("SecurityException thrown on writing to temp", sec01);
+ }
+ } else {
+ if( null == sec01 ) {
+ throw new Error("SecurityException not thrown on writing to temp");
+ }
+ }
+ }
+
+ private void testOpenLibrary(boolean global) {
+ final ClassLoader cl = getClass().getClassLoader();
+ System.err.println("CL "+cl);
+
+ String libBaseName = null;
+ final Class<?> clazz = this.getClass();
+ URL libURL = clazz.getResource("/libtest1.so");
+ if( null != libURL ) {
+ libBaseName = "libtest1.so";
+ } else {
+ libURL = clazz.getResource("/test1.dll");
+ if( null != libURL ) {
+ libBaseName = "test1.dll";
+ }
+ }
+ System.err.println("Untrusted Library (URL): "+libURL);
+
+ String libDir1 = null;
+ if( null != libURL ) {
+ try {
+ libDir1 = JarUtil.getJarSubURI(libURL.toURI()).getPath();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if( null != libDir1 ) {
+ System.err.println("libDir1.1: "+libDir1);
+ try {
+ libDir1= IOUtil.getParentOf(libDir1);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ System.err.println("libDir1.2: "+libDir1);
+ }
+ }
+ System.err.println("Untrusted Library Dir1 (abs): "+libDir1);
+ final String absLib = libDir1 + "natives/" + libBaseName;
+ Exception sec01 = null;
+ try {
+ NativeLibrary nlib = NativeLibrary.open(absLib, cl);
+ System.err.println("NativeLibrary: "+nlib);
+ } catch (SecurityException e) {
+ sec01 = e;
+ if( usesSecurityManager ) {
+ System.err.println("Expected exception for loading native library");
+ System.err.println("Message: "+sec01.getMessage());
+ } else {
+ System.err.println("Unexpected exception for loading native library");
+ sec01.printStackTrace();
+ }
+ }
+ if( !usesSecurityManager ) {
+ if( null != sec01 ) {
+ throw new Error("SecurityException thrown on loading native library", sec01);
+ }
+ } else {
+ if( null == sec01 ) {
+ throw new Error("SecurityException not thrown on loading native library");
+ }
+ }
+ }
+
+ public void init() {
+
+ }
+
+ public void start() {
+ Platform.initSingleton();
+
+ {
+ testPropImpl(os_name_propkey, true);
+ }
+ System.err.println("p0: OK");
+ {
+ testPropImpl(java_home_propkey, false);
+ }
+ System.err.println("p1: OK");
+ {
+ testPropImpl(java_io_tmpdir_propkey, false);
+ }
+ System.err.println("p2: OK");
+ {
+ testTempDirImpl(false);
+ }
+ System.err.println("temp0: OK");
+
+ testWriteFile();
+ System.err.println("writeFile: OK");
+
+ testOpenLibrary(true);
+ System.err.println("lib0: OK");
+ }
+
+ public void stop() {
+
+ }
+}
diff --git a/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java b/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java
new file mode 100644
index 0000000..c47e2df
--- /dev/null
+++ b/src/junit/com/jogamp/junit/sec/TestSecIOUtil01.java
@@ -0,0 +1,209 @@
+/**
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.junit.sec;
+
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.common.os.NativeLibrary;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.JarUtil;
+import com.jogamp.junit.util.JunitTracer;
+
+public class TestSecIOUtil01 extends JunitTracer {
+ static final String java_io_tmpdir_propkey = "java.io.tmpdir";
+ static final String java_home_propkey = "java.home";
+ static final String os_name_propkey = "os.name";
+ static final boolean usesSecurityManager;
+
+ static {
+ if( null == System.getSecurityManager() ) {
+ usesSecurityManager = false;
+ System.err.println("No SecurityManager Installed");
+ } else {
+ usesSecurityManager = true;
+ System.err.println("SecurityManager Already Installed");
+ }
+ }
+
+ @BeforeClass
+ public static void setup() throws IOException {
+ Platform.initSingleton();
+ }
+
+ static void testPropImpl01(String propKey, boolean isSecure) {
+ isSecure |= !usesSecurityManager;
+
+ Exception se0 = null;
+ try {
+ String p0 = System.getProperty(propKey);
+ System.err.println(propKey+": "+p0);
+ } catch (AccessControlException e) {
+ se0 = e;
+ if( !isSecure ) {
+ System.err.println("Expected exception for insecure property <"+propKey+">");
+ System.err.println("Message: "+se0.getMessage());
+ } else {
+ System.err.println("Unexpected exception for secure property <"+propKey+">");
+ se0.printStackTrace();
+ }
+ }
+ if( isSecure ) {
+ Assert.assertNull("AccessControlException thrown on secure property <"+propKey+">", se0);
+ } else {
+ Assert.assertNotNull("AccessControlException not thrown on insecure property <"+propKey+">", se0);
+ }
+ }
+
+ @Test
+ public void testProp00_Temp() {
+ testPropImpl01(os_name_propkey, true);
+ }
+
+ @Test
+ public void testProp01_Temp() {
+ testPropImpl01(java_home_propkey, false);
+ }
+
+ @Test
+ public void testProp02_Temp() {
+ testPropImpl01(java_io_tmpdir_propkey, false);
+ }
+
+ static void testTempDirImpl(boolean isSecure) {
+ isSecure |= !usesSecurityManager;
+
+ Exception se0 = null;
+ try {
+ File tmp = IOUtil.getTempDir(true);
+ System.err.println("Temp: "+tmp);
+ } catch (AccessControlException e) {
+ se0 = e;
+ if( !isSecure ) {
+ System.err.println("Expected exception for insecure temp dir");
+ System.err.println("Message: "+se0.getMessage());
+ } else {
+ System.err.println("Unexpected exception for secure temp dir");
+ se0.printStackTrace();
+ }
+ }
+ if( isSecure ) {
+ Assert.assertNull("AccessControlException thrown on secure temp dir", se0);
+ } else {
+ Assert.assertNotNull("AccessControlException not thrown on insecure temp dir", se0);
+ }
+ }
+
+ @Test
+ public void testTempDir00() {
+ testTempDirImpl(false);
+ }
+
+ private void testOpenLibraryImpl(boolean global) {
+ final ClassLoader cl = getClass().getClassLoader();
+ System.err.println("CL "+cl);
+
+ String libBaseName = null;
+ final Class<?> clazz = this.getClass();
+ URL libURL = clazz.getResource("/libtest1.so");
+ if( null != libURL ) {
+ libBaseName = "libtest1.so";
+ } else {
+ libURL = clazz.getResource("/test1.dll");
+ if( null != libURL ) {
+ libBaseName = "test1.dll";
+ }
+ }
+ System.err.println("Untrusted Library (URL): "+libURL);
+
+ String libDir1 = null;
+ if( null != libURL ) {
+ try {
+ libDir1 = JarUtil.getJarSubURI(libURL.toURI()).getPath();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if( null != libDir1 ) {
+ System.err.println("libDir1.1: "+libDir1);
+ try {
+ libDir1= IOUtil.getParentOf(libDir1);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ System.err.println("libDir1.2: "+libDir1);
+ }
+ }
+ System.err.println("Untrusted Library Dir1 (abs): "+libDir1);
+ final String absLib = libDir1 + "natives/" + libBaseName;
+ Exception se0 = null;
+ try {
+ NativeLibrary nlib = NativeLibrary.open(absLib, cl);
+ System.err.println("NativeLibrary: "+nlib);
+ } catch (SecurityException e) {
+ se0 = e;
+ if( usesSecurityManager ) {
+ System.err.println("Expected exception for loading native library");
+ System.err.println("Message: "+se0.getMessage());
+ } else {
+ System.err.println("Unexpected exception for loading native library");
+ se0.printStackTrace();
+ }
+ }
+ if( !usesSecurityManager ) {
+ Assert.assertNull("SecurityException thrown on loading native library", se0);
+ } else {
+ Assert.assertNotNull("SecurityException not thrown on loading native library", se0);
+ }
+ }
+
+ public void testOpenLibrary() {
+ testOpenLibraryImpl(true);
+ }
+
+ public static void main(String args[]) throws IOException {
+ TestSecIOUtil01.setup();
+
+ TestSecIOUtil01 aa = new TestSecIOUtil01();
+ aa.testProp00_Temp();
+ aa.testProp01_Temp();
+ aa.testProp02_Temp();
+ aa.testTempDir00();
+ aa.testOpenLibrary();
+ }
+
+}