} }); // createClassLoader permission needed to create loader in context perms.add(new RuntimePermission("createClassLoader")); // add permissions to read any "java.*" property perms.add(new java.util.PropertyPermission("java.*","read")); // add permissions reuiqred to load from codebase URL path addPermissionsForURLs(urls, perms, true); /* * Create an AccessControlContext that consists of a single * protection domain with only the permissions calculated above. */ ProtectionDomain pd = new ProtectionDomain( new CodeSource((urls.length > 0 ? urls[0] : null), (java.security.cert.Certificate[]) null), perms); return new AccessControlContext(new ProtectionDomain[] { pd }); } /** * Adds to the specified permission collection the permissions * necessary to load classes from a loader with the specified URL * path; if "forLoader" is true, also adds URL-specific * permissions necessary for the security context that such a * loader operates within, such as permissions necessary for * granting automatic permissions to classes defined by the * loader. A given permission is only added to the collection if * it is not already implied by the collection. */ private static void addPermissionsForURLs(URL[] urls, PermissionCollection perms, boolean forLoader) { for (int i = 0; i < urls.length; i++) { URL url = urls[i]; try { URLConnection urlConnection = url.openConnection(); Permission p = urlConnection.getPermission(); if (p != null) { if (p instanceof FilePermission) { /* * If the codebase is a file, the permission required * to actually read classes from the codebase URL is * the permission to read all files beneath the last * directory in the file path, either because JAR * files can refer to other JAR files in the same * directory, or because permission to read a * directory is not implied by permission to read the * contents of a directory, which all that might be * granted. */ String path = p.getName(); int endIndex = path.lastIndexOf(File.separatorChar); if (endIndex != -1) { path = path.substring(0, endIndex+1); if (path.endsWith(File.separator)) { path += "-"; } Permission p2 = new FilePermission(path, "read"); if (!perms.implies(p2)) { perms.add(p2); } perms.add(new FilePermission(path, "read")); } else { /* * No directory separator: use permission to * read the file. */ if (!perms.implies(p)) { perms.add(p); } } } else { if (!perms.implies(p)) { perms.add(p); } /* * If the purpose of these permissions is to grant * them to an instance of a URLClassLoader subclass, * we must add permission to connect to and accept * from the host of non-"file:" URLs, otherwise the * getPermissions() method of URLClassLoader will * throw a security exception. */ if (forLoader) { // get URL with meaningful host component URL hostURL = url; for (URLConnection conn = urlConnection; conn instanceof JarURLConnection;) { hostURL = ((JarURLConnection) conn).getJarFileURL(); conn = hostURL.openConnection(); } String host = hostURL.getHost(); if (host != null && p.implies(new SocketPermission(host, "resolve"))) { Permission p2 = new SocketPermission(host, "connect,accept"); if (!perms.implies(p2)) { perms.add(p2); } } } } } } catch (IOException e) { /* * This shouldn't happen, although it is declared to be * thrown by openConnection() and getPermission(). If it * does, don't bother granting or requiring any permissions * for this URL. */ } } } /** * Loader is the actual class of the RMI class loaders created * by the RMIClassLoader static methods. */ private static class Loader extends URLClassLoader { /** parent class loader, kept here as an optimization */ private ClassLoader parent; /** string form of loader's codebase URL path, also an optimization */ private String annotation; /** permissions required to access loader through public API */ private Permissions permissions; private Loader(URL[] urls, ClassLoader parent) { super(urls, parent); this.parent = parent; /* * Precompute the permissions required to access the loader. */ permissions = new Permissions(); addPermissionsForURLs(urls, permissions, false); /* * Caching the value of class annotation string here assumes * that the protected method addURL() is never called on this * class loader. */ annotation = urlsToPath(urls); } /** * Return the string to be annotated with all classes loaded from * this class loader. */ public String getClassAnnotation() { return annotation; } /** * Check that the current access control context has all of the * permissions necessary to load classes from this loader. */ private void checkPermissions() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { // should never be null? Enumeration enum_ = permissions.elements(); while (enum_.hasMoreElements()) { sm.checkPermission((Permission) enum_.nextElement()); } } } /** * Return the permissions to be granted to code loaded from the * given code source. */ protected PermissionCollection getPermissions(CodeSource codesource) { PermissionCollection perms = super.getPermissions(codesource); /* * Grant the same permissions that URLClassLoader would grant. */ return perms; } /** * Return a string representation of this loader (useful for * debugging). */ public String toString() { return super.toString() + "[\"" + annotation + "\"]"; } }}Lines 1001–1201 of 1201. Previous lines
} }); // createClassLoader permission needed to create loader in context perms.add(new RuntimePermission("createClassLoader")); // add permissions to read any "java.*" property perms.add(new java.util.PropertyPermission("java.*","read")); // add permissions reuiqred to load from codebase URL path addPermissionsForURLs(urls, perms, true); /* * Create an AccessControlContext that consists of a single * protection domain with only the permissions calculated above. */ ProtectionDomain pd = new ProtectionDomain( new CodeSource((urls.length > 0 ? urls[0] : null), (java.security.cert.Certificate[]) null), perms); return new AccessControlContext(new ProtectionDomain[] { pd }); } /** * Adds to the specified permission collection the permissions * necessary to load classes from a loader with the specified URL * path; if "forLoader" is true, also adds URL-specific * permissions necessary for the security context that such a * loader operates within, such as permissions necessary for * granting automatic permissions to classes defined by the * loader. A given permission is only added to the collection if * it is not already implied by the collection. */ private static void addPermissionsForURLs(URL[] urls, PermissionCollection perms, boolean forLoader) { for (int i = 0; i < urls.length; i++) { URL url = urls[i]; try { URLConnection urlConnection = url.openConnection(); Permission p = urlConnection.getPermission(); if (p != null) { if (p instanceof FilePermission) { /* * If the codebase is a file, the permission required * to actually read classes from the codebase URL is * the permission to read all files beneath the last * directory in the file path, either because JAR * files can refer to other JAR files in the same * directory, or because permission to read a * directory is not implied by permission to read the * contents of a directory, which all that might be * granted. */ String path = p.getName(); int endIndex = path.lastIndexOf(File.separatorChar); if (endIndex != -1) { path = path.substring(0, endIndex+1); if (path.endsWith(File.separator)) { path += "-"; } Permission p2 = new FilePermission(path, "read"); if (!perms.implies(p2)) { perms.add(p2); } perms.add(new FilePermission(path, "read")); } else { /* * No directory separator: use permission to * read the file. */ if (!perms.implies(p)) { perms.add(p); } } } else { if (!perms.implies(p)) { perms.add(p); } /* * If the purpose of these permissions is to grant * them to an instance of a URLClassLoader subclass, * we must add permission to connect to and accept * from the host of non-"file:" URLs, otherwise the * getPermissions() method of URLClassLoader will * throw a security exception. */ if (forLoader) { // get URL with meaningful host component URL hostURL = url; for (URLConnection conn = urlConnection; conn instanceof JarURLConnection;) { hostURL = ((JarURLConnection) conn).getJarFileURL(); conn = hostURL.openConnection(); } String host = hostURL.getHost(); if (host != null && p.implies(new SocketPermission(host, "resolve"))) { Permission p2 = new SocketPermission(host, "connect,accept"); if (!perms.implies(p2)) { perms.add(p2); } } } } } } catch (IOException e) { /* * This shouldn't happen, although it is declared to be * thrown by openConnection() and getPermission(). If it * does, don't bother granting or requiring any permissions * for this URL. */ } } } /** * Loader is the actual class of the RMI class loaders created * by the RMIClassLoader static methods. */ private static class Loader extends URLClassLoader { /** parent class loader, kept here as an optimization */ private ClassLoader parent; /** string form of loader's codebase URL path, also an optimization */ private String annotation; /** permissions required to access loader through public API */ private Permissions permissions; private Loader(URL[] urls, ClassLoader parent) { super(urls, parent); this.parent = parent; /* * Precompute the permissions required to access the loader. */ permissions = new Permissions(); addPermissionsForURLs(urls, permissions, false); /* * Caching the value of class annotation string here assumes * that the protected method addURL() is never called on this * class loader. */ annotation = urlsToPath(urls); } /** * Return the string to be annotated with all classes loaded from * this class loader. */ public String getClassAnnotation() { return annotation; } /** * Check that the current access control context has all of the * permissions necessary to load classes from this loader. */ private void checkPermissions() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { // should never be null? Enumeration enum_ = permissions.elements(); while (enum_.hasMoreElements()) { sm.checkPermission((Permission) enum_.nextElement()); } } } /** * Return the permissions to be granted to code loaded from the * given code source. */ protected PermissionCollection getPermissions(CodeSource codesource) { PermissionCollection perms = super.getPermissions(codesource); /* * Grant the same permissions that URLClassLoader would grant. */ return perms; } /** * Return a string representation of this loader (useful for * debugging). */ public String toString() { return super.toString() + "[\"" + annotation + "\"]"; } } }