1 7 8 package java.net; 9 10 import java.lang.reflect.Method ; 11 import java.lang.reflect.Modifier ; 12 import java.io.File ; 13 import java.io.FilePermission ; 14 import java.io.InputStream ; 15 import java.io.IOException ; 16 import java.net.URL ; 17 import java.net.URLConnection ; 18 import java.net.URLStreamHandlerFactory ; 19 import java.util.Enumeration ; 20 import java.util.NoSuchElementException ; 21 import java.util.StringTokenizer ; 22 import java.util.jar.Manifest ; 23 import java.util.jar.Attributes ; 24 import java.util.jar.Attributes.Name; 25 import java.security.CodeSigner ; 26 import java.security.PrivilegedAction ; 27 import java.security.PrivilegedExceptionAction ; 28 import java.security.AccessController ; 29 import java.security.AccessControlContext ; 30 import java.security.SecureClassLoader ; 31 import java.security.CodeSource ; 32 import java.security.Permission ; 33 import java.security.PermissionCollection ; 34 import sun.misc.Resource; 35 import sun.misc.URLClassPath; 36 import sun.net.www.ParseUtil; 37 import sun.security.util.SecurityConstants; 38 39 56 public class URLClassLoader extends SecureClassLoader { 57 58 URLClassPath ucp; 59 60 61 private AccessControlContext acc; 62 63 81 public URLClassLoader(URL [] urls, ClassLoader parent) { 82 super(parent); 83 SecurityManager security = System.getSecurityManager(); 85 if (security != null) { 86 security.checkCreateClassLoader(); 87 } 88 ucp = new URLClassPath(urls); 89 acc = AccessController.getContext(); 90 } 91 92 112 public URLClassLoader(URL [] urls) { 113 super(); 114 SecurityManager security = System.getSecurityManager(); 116 if (security != null) { 117 security.checkCreateClassLoader(); 118 } 119 ucp = new URLClassPath(urls); 120 acc = AccessController.getContext(); 121 } 122 123 143 public URLClassLoader(URL [] urls, ClassLoader parent, 144 URLStreamHandlerFactory factory) { 145 super(parent); 146 SecurityManager security = System.getSecurityManager(); 148 if (security != null) { 149 security.checkCreateClassLoader(); 150 } 151 ucp = new URLClassPath(urls, factory); 152 acc = AccessController.getContext(); 153 } 154 155 161 protected void addURL(URL url) { 162 ucp.addURL(url); 163 } 164 165 171 public URL [] getURLs() { 172 return ucp.getURLs(); 173 } 174 175 184 protected Class <?> findClass(final String name) 185 throws ClassNotFoundException 186 { 187 try { 188 return (Class ) 189 AccessController.doPrivileged(new PrivilegedExceptionAction () { 190 public Object run() throws ClassNotFoundException { 191 String path = name.replace('.', '/').concat(".class"); 192 Resource res = ucp.getResource(path, false); 193 if (res != null) { 194 try { 195 return defineClass(name, res); 196 } catch (IOException e) { 197 throw new ClassNotFoundException (name, e); 198 } 199 } else { 200 throw new ClassNotFoundException (name); 201 } 202 } 203 }, acc); 204 } catch (java.security.PrivilegedActionException pae) { 205 throw (ClassNotFoundException ) pae.getException(); 206 } 207 } 208 209 214 private Class defineClass(String name, Resource res) throws IOException { 215 int i = name.lastIndexOf('.'); 216 URL url = res.getCodeSourceURL(); 217 if (i != -1) { 218 String pkgname = name.substring(0, i); 219 Package pkg = getPackage(pkgname); 221 Manifest man = res.getManifest(); 222 if (pkg != null) { 223 if (pkg.isSealed()) { 225 if (!pkg.isSealed(url)) { 227 throw new SecurityException ( 228 "sealing violation: package " + pkgname + " is sealed"); 229 } 230 231 } else { 232 if ((man != null) && isSealed(pkgname, man)) { 235 throw new SecurityException ( 236 "sealing violation: can't seal package " + pkgname + 237 ": already loaded"); 238 } 239 } 240 } else { 241 if (man != null) { 242 definePackage(pkgname, man, url); 243 } else { 244 definePackage(pkgname, null, null, null, null, null, null, null); 245 } 246 } 247 } 248 java.nio.ByteBuffer bb = res.getByteBuffer(); 250 if (bb != null) { 251 CodeSigner [] signers = res.getCodeSigners(); 253 CodeSource cs = new CodeSource (url, signers); 254 return defineClass(name, bb, cs); 255 } else { 256 byte[] b = res.getBytes(); 257 CodeSigner [] signers = res.getCodeSigners(); 259 CodeSource cs = new CodeSource (url, signers); 260 return defineClass(name, b, 0, b.length, cs); 261 } 262 } 263 264 279 protected Package definePackage(String name, Manifest man, URL url) 280 throws IllegalArgumentException 281 { 282 String path = name.replace('.', '/').concat("/"); 283 String specTitle = null, specVersion = null, specVendor = null; 284 String implTitle = null, implVersion = null, implVendor = null; 285 String sealed = null; 286 URL sealBase = null; 287 288 Attributes attr = man.getAttributes(path); 289 if (attr != null) { 290 specTitle = attr.getValue(Name.SPECIFICATION_TITLE); 291 specVersion = attr.getValue(Name.SPECIFICATION_VERSION); 292 specVendor = attr.getValue(Name.SPECIFICATION_VENDOR); 293 implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE); 294 implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION); 295 implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR); 296 sealed = attr.getValue(Name.SEALED); 297 } 298 attr = man.getMainAttributes(); 299 if (attr != null) { 300 if (specTitle == null) { 301 specTitle = attr.getValue(Name.SPECIFICATION_TITLE); 302 } 303 if (specVersion == null) { 304 specVersion = attr.getValue(Name.SPECIFICATION_VERSION); 305 } 306 if (specVendor == null) { 307 specVendor = attr.getValue(Name.SPECIFICATION_VENDOR); 308 } 309 if (implTitle == null) { 310 implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE); 311 } 312 if (implVersion == null) { 313 implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION); 314 } 315 if (implVendor == null) { 316 implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR); 317 } 318 if (sealed == null) { 319 sealed = attr.getValue(Name.SEALED); 320 } 321 } 322 if ("true".equalsIgnoreCase(sealed)) { 323 sealBase = url; 324 } 325 return definePackage(name, specTitle, specVersion, specVendor, 326 implTitle, implVersion, implVendor, sealBase); 327 } 328 329 333 private boolean isSealed(String name, Manifest man) { 334 String path = name.replace('.', '/').concat("/"); 335 Attributes attr = man.getAttributes(path); 336 String sealed = null; 337 if (attr != null) { 338 sealed = attr.getValue(Name.SEALED); 339 } 340 if (sealed == null) { 341 if ((attr = man.getMainAttributes()) != null) { 342 sealed = attr.getValue(Name.SEALED); 343 } 344 } 345 return "true".equalsIgnoreCase(sealed); 346 } 347 348 355 public URL findResource(final String name) { 356 359 URL url = 360 (URL ) AccessController.doPrivileged(new PrivilegedAction () { 361 public Object run() { 362 return ucp.findResource(name, true); 363 } 364 }, acc); 365 366 return url != null ? ucp.checkURL(url) : null; 367 } 368 369 377 public Enumeration <URL > findResources(final String name) 378 throws IOException 379 { 380 final Enumeration e = ucp.findResources(name, true); 381 382 return new Enumeration <URL >() { 383 private URL url = null; 384 385 private boolean next() { 386 if (url != null) { 387 return true; 388 } 389 do { 390 URL u = (URL ) 391 AccessController.doPrivileged(new PrivilegedAction () { 392 public Object run() { 393 if (!e.hasMoreElements()) 394 return null; 395 return e.nextElement(); 396 } 397 }, acc); 398 if (u == null) 399 break; 400 url = ucp.checkURL(u); 401 } while (url == null); 402 return url != null; 403 } 404 405 public URL nextElement() { 406 if (!next()) { 407 throw new NoSuchElementException (); 408 } 409 URL u = url; 410 url = null; 411 return u; 412 } 413 414 public boolean hasMoreElements() { 415 return next(); 416 } 417 }; 418 } 419 420 441 protected PermissionCollection getPermissions(CodeSource codesource) 442 { 443 PermissionCollection perms = super.getPermissions(codesource); 444 445 URL url = codesource.getLocation(); 446 447 Permission p; 448 URLConnection urlConnection; 449 450 try { 451 urlConnection = url.openConnection(); 452 p = urlConnection.getPermission(); 453 } catch (java.io.IOException ioe) { 454 p = null; 455 urlConnection = null; 456 } 457 458 if (p instanceof FilePermission ) { 459 String path = p.getName(); 463 if (path.endsWith(File.separator)) { 464 path += "-"; 465 p = new FilePermission (path, SecurityConstants.FILE_READ_ACTION); 466 } 467 } else if ((p == null) && (url.getProtocol().equals("file"))) { 468 String path = url.getFile().replace('/', File.separatorChar); 469 path = ParseUtil.decode(path); 470 if (path.endsWith(File.separator)) 471 path += "-"; 472 p = new FilePermission (path, SecurityConstants.FILE_READ_ACTION); 473 } else { 474 URL locUrl = url; 475 if (urlConnection instanceof JarURLConnection ) { 476 locUrl = ((JarURLConnection )urlConnection).getJarFileURL(); 477 } 478 String host = locUrl.getHost(); 479 if (host != null && (host.length() > 0)) 480 p = new SocketPermission (host, 481 SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION); 482 } 483 486 if (p != null) { 487 final SecurityManager sm = System.getSecurityManager(); 488 if (sm != null) { 489 final Permission fp = p; 490 AccessController.doPrivileged(new PrivilegedAction () { 491 public Object run() throws SecurityException { 492 sm.checkPermission(fp); 493 return null; 494 } 495 }, acc); 496 } 497 perms.add(p); 498 } 499 return perms; 500 } 501 502 514 public static URLClassLoader newInstance(final URL [] urls, 515 final ClassLoader parent) { 516 AccessControlContext acc = AccessController.getContext(); 518 URLClassLoader ucl = 520 (URLClassLoader ) AccessController.doPrivileged(new PrivilegedAction () { 521 public Object run() { 522 return new FactoryURLClassLoader(urls, parent); 523 } 524 }); 525 ucl.acc = acc; 528 return ucl; 529 } 530 531 542 public static URLClassLoader newInstance(final URL [] urls) { 543 AccessControlContext acc = AccessController.getContext(); 545 URLClassLoader ucl = (URLClassLoader ) 547 AccessController.doPrivileged(new PrivilegedAction () { 548 public Object run() { 549 return new FactoryURLClassLoader(urls); 550 } 551 }); 552 553 ucl.acc = acc; 556 return ucl; 557 } 558 559 static { 560 sun.misc.SharedSecrets.setJavaNetAccess ( 561 new sun.misc.JavaNetAccess() { 562 public URLClassPath getURLClassPath (URLClassLoader u) { 563 return u.ucp; 564 } 565 } 566 ); 567 } 568 } 569 570 final class FactoryURLClassLoader extends URLClassLoader { 571 572 FactoryURLClassLoader(URL [] urls, ClassLoader parent) { 573 super(urls, parent); 574 } 575 576 FactoryURLClassLoader(URL [] urls) { 577 super(urls); 578 } 579 580 public final synchronized Class loadClass(String name, boolean resolve) 581 throws ClassNotFoundException 582 { 583 SecurityManager sm = System.getSecurityManager(); 586 if (sm != null) { 587 int i = name.lastIndexOf('.'); 588 if (i != -1) { 589 sm.checkPackageAccess(name.substring(0, i)); 590 } 591 } 592 return super.loadClass(name, resolve); 593 } 594 } 595 | Popular Tags |