Mercurial > hg > release > icedtea8-3.0
changeset 2328:1da6f883f1d3
Track security descriptors per jar, and made permission decisions based on it.
author | Deepak Bhole <dbhole@redhat.com> |
---|---|
date | Wed, 28 Jul 2010 15:52:36 -0400 |
parents | b4d1a0a7ad8f |
children | a6702aa5f9e7 |
files | ChangeLog netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java |
diffstat | 2 files changed, 94 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Jul 28 15:42:55 2010 -0400 +++ b/ChangeLog Wed Jul 28 15:52:36 2010 -0400 @@ -1,3 +1,16 @@ +2010-07-28 Deepak Bhole <dbhole@redhat.com> + + * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Added a new + HashMap to map source locations to security descriptors for that location. + (getInstance): Use the new merge() method to merge loader data. + (initializeResources): Add map entries to the new jarLocationSecurityMap. + (getPermissions): Decide permissions based on security descriptor + associated with the calling code, rather than with the jnlp file. + (getCodeSourceSecurity): New method. Returns the security descriptor + associated with the given code source URL. + (merge): New method. Merges loader classpaths, native dir paths, and + security descriptor mappings. + 2010-07-28 Deepak Bhole <dbhole@redhat.com> * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java (activateJars): Add
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Wed Jul 28 15:42:55 2010 -0400 +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Wed Jul 28 15:52:36 2010 -0400 @@ -26,6 +26,7 @@ import java.net.URLClassLoader; import java.security.AccessControlContext; import java.security.AccessController; +import java.security.AllPermission; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; @@ -140,6 +141,9 @@ /** File entries in the jar files available to this classloader */ private TreeSet jarEntries = new TreeSet(); + /** Map of specific codesources to securitydesc */ + private HashMap<URL, SecurityDesc> jarLocationSecurityMap = new HashMap<URL, SecurityDesc>(); + /** * Create a new JNLPClassLoader from the specified file. * @@ -253,19 +257,13 @@ if (!SecurityWarningDialog.showNotAllSignedWarningDialog(file)) throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo")); - for (URL u : extLoader.getURLs()) - loader.addURL(u); - for (File nativeDirectory: extLoader.getNativeDirectories()) - loader.addNativeDirectory(nativeDirectory); + loader.merge(extLoader); } // loader is now current + ext. But we also need to think of // the baseLoader if (baseLoader != null && baseLoader != loader) { - for (URL u : baseLoader.getURLs()) - loader.addURL(u); - for (File nativeDirectory: baseLoader.getNativeDirectories()) - loader.addNativeDirectory(nativeDirectory); + loader.merge(baseLoader); } } else { @@ -424,6 +422,34 @@ } } + for (JARDesc jarDesc: file.getResources().getJARs()) { + try { + URL location = tracker.getCacheFile(jarDesc.getLocation()).toURI().toURL(); + SecurityDesc jarSecurity = file.getSecurity(); + + if (file instanceof PluginBridge) { + + URL codebase = null; + + if (file.getCodeBase() != null) { + codebase = file.getCodeBase(); + } else { + //Fixme: codebase should be the codebase of the Main Jar not + //the location. Although, it still works in the current state. + codebase = file.getResources().getMainJAR().getLocation(); + } + + jarSecurity = new SecurityDesc(file, + SecurityDesc.ALL_PERMISSIONS, + codebase.getHost()); + } + + jarLocationSecurityMap.put(location, jarSecurity); + } catch (MalformedURLException mfe) { + System.err.println(mfe.getMessage()); + } + } + activateJars(initialJars); } @@ -505,13 +531,15 @@ // set default perms PermissionCollection permissions = security.getSandBoxPermissions(); - // If more than default is needed, evaluate based on codesource - if (security.getSecurityType().equals(SecurityDesc.ALL_PERMISSIONS) || - security.getSecurityType().equals(SecurityDesc.J2EE_PERMISSIONS)) { + // If more than default is needed: + // 1. Code must be signed + // 2. ALL or J2EE permissions must be requested (note: plugin requests ALL automatically) + if (cs.getCodeSigners() != null && + (getCodeSourceSecurity(cs.getLocation()).getSecurityType().equals(SecurityDesc.ALL_PERMISSIONS) || + getCodeSourceSecurity(cs.getLocation()).getSecurityType().equals(SecurityDesc.J2EE_PERMISSIONS)) + ) { - if (cs.getCodeSigners() != null) { - permissions = security.getPermissions(); - } + permissions = getCodeSourceSecurity(cs.getLocation()).getPermissions(); } Enumeration<Permission> e = permissions.elements(); @@ -1121,4 +1149,43 @@ protected SecurityDesc getSecurity() { return security; } + + /** + * Returns the security descriptor for given code source URL + * + * @param source The code source + * @return The SecurityDescriptor for that source + */ + + protected SecurityDesc getCodeSourceSecurity(URL source) { + return jarLocationSecurityMap.get(source); + } + + /** + * Merges the code source/security descriptor mapping from another loader + * + * @param extLoader The loader form which to merge + * @throws SecurityException if the code is called from an untrusted source + */ + private void merge(JNLPClassLoader extLoader) { + + try { + System.getSecurityManager().checkPermission(new AllPermission()); + } catch (SecurityException se) { + throw new SecurityException("JNLPClassLoader() may only be called from trusted sources!"); + } + + // jars + for (URL u : extLoader.getURLs()) + addURL(u); + + // native search paths + for (File nativeDirectory: extLoader.getNativeDirectories()) + addNativeDirectory(nativeDirectory); + + // security descriptors + for (URL key: extLoader.jarLocationSecurityMap.keySet()) { + jarLocationSecurityMap.put(key, extLoader.jarLocationSecurityMap.get(key)); + } + } }