Mercurial > hg > release > icedtea6-1.7
changeset 1959:eb2ab50f5a28
Track security descriptors per jar, and made permission decisions based on it.
author | Deepak Bhole <dbhole@redhat.com> |
---|---|
date | Thu, 22 Jul 2010 19:24:19 -0400 |
parents | cf334d2dae6e |
children | d88454e407dd |
files | ChangeLog rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java |
diffstat | 2 files changed, 95 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Jul 22 01:53:55 2010 -0400 +++ b/ChangeLog Thu Jul 22 19:24:19 2010 -0400 @@ -1,3 +1,16 @@ +2010-07-22 Deepak Bhole <dbhole@redhat.com> + + * rt/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-22 Deepak Bhole <dbhole@redhat.com> * rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java (getInstance):
--- a/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Thu Jul 22 01:53:55 2010 -0400 +++ b/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Thu Jul 22 19:24:19 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. * @@ -255,20 +259,14 @@ 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 { // if key is same and locations match, this is the loader we want @@ -424,6 +422,34 @@ //for permission on certain actions } } + + 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); } @@ -506,13 +532,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(); @@ -1099,6 +1127,45 @@ 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)); + } + } }