1 19 20 package org.netbeans; 21 22 import java.io.FileDescriptor ; 23 import java.lang.reflect.Field ; 24 import java.lang.reflect.Method ; 25 import java.net.InetAddress ; 26 import java.net.URL ; 27 import java.net.UnknownHostException ; 28 import java.security.AccessControlContext ; 29 import java.security.AccessController ; 30 import java.security.AllPermission ; 31 import java.security.Permission ; 32 import java.security.PrivilegedActionException ; 33 import java.security.PrivilegedExceptionAction ; 34 import java.util.ArrayList ; 35 import java.util.HashSet ; 36 import java.util.Iterator ; 37 import java.util.List ; 38 import java.util.Set ; 39 40 43 public class TopSecurityManager extends SecurityManager { 44 45 private static boolean check = !Boolean.getBoolean("netbeans.security.nocheck"); 47 private Permission allPermission; 48 49 52 private static final Class <?> classLoaderClass = ClassLoader .class; 53 private static final Class URLClass = URL .class; 54 private static final Class runtimePermissionClass = RuntimePermission .class; 55 private static final Class accessControllerClass = AccessController .class; 56 57 private static List <SecurityManager > delegates = new ArrayList <SecurityManager >(); 58 63 public static void register(SecurityManager sm) throws SecurityException { 64 77 synchronized (delegates) { 78 if (delegates.contains(sm)) throw new SecurityException (); 79 delegates.add(sm); 80 } 81 } 82 86 public static void unregister(SecurityManager sm) throws SecurityException { 87 91 synchronized (delegates) { 92 if (!delegates.contains(sm)) throw new SecurityException (); 93 delegates.remove(sm); 94 } 95 } 96 97 100 public TopSecurityManager () { 101 allPermission = new AllPermission (); 102 } 103 104 public void checkExit(int status) throws SecurityException { 105 if (! check) { 106 return; 107 } 108 109 synchronized (delegates) { 110 Iterator it = delegates.iterator(); 111 while (it.hasNext()) { 112 ((SecurityManager )it.next()).checkExit(status); 113 } 114 } 115 116 PrivilegedCheck.checkExit(status, this); 117 } 118 119 120 private static boolean officialExit = false; 121 126 public static void exit(int status) { 127 officialExit = true; 128 System.exit(status); 129 } 130 131 final void checkExitImpl(int status, AccessControlContext acc) throws SecurityException { 132 if (!officialExit) { 133 throw new ExitSecurityException("Illegal attempt to exit early"); } 135 136 super.checkExit(status); 137 } 138 139 public boolean checkTopLevelWindow(Object window) { 140 synchronized (delegates) { 141 Iterator it = delegates.iterator(); 142 while (it.hasNext()) { 143 ((SecurityManager )it.next()).checkTopLevelWindow(window); 144 } 145 } 146 147 return super.checkTopLevelWindow(window); 148 } 149 150 172 173 174 public final void checkPropertyAccess(String x) { 175 if ("netbeans.debug.exceptions".equals(x)) { Class [] ctxt = getClassContext(); 178 for (int i = 0; i < ctxt.length; i++) { 179 Class c = ctxt[i]; 180 if (c != TopSecurityManager.class && 181 c != System .class && 182 c != Boolean .class) { 183 String n = c.getName(); 184 synchronized (warnedClassesNDE) { 185 if (warnedClassesNDE.add(n)) { 186 System.err.println("Warning: use of system property netbeans.debug.exceptions in " + n + " has been obsoleted in favor of ErrorManager"); } 188 } 189 break; 190 } 191 } 192 } 193 if ("netbeans.home".equals(x)) { Class [] ctxt = getClassContext(); 196 for (int i = 0; i < ctxt.length; i++) { 197 Class c = ctxt[i]; 198 if (c != TopSecurityManager.class && 199 c != System .class && 200 c != Boolean .class) { 201 String n = c.getName(); 202 synchronized (warnedClassesNH) { 203 if (warnedClassesNH.add(n)) { 204 System.err.println("Warning: use of system property netbeans.home in " + n + " has been obsoleted in favor of InstalledFileLocator"); } 206 } 207 break; 208 } 209 } 210 } 211 212 if ("javax.xml.parsers.SAXParserFactory".equals(x)) { 213 if (Thread.currentThread().getContextClassLoader().getResource( 214 "org/netbeans/core/startup/SAXFactoryImpl.class") != null) return; 215 throw new SecurityException (""); 216 } 217 218 if ("javax.xml.parsers.DocumentBuilderFactory".equals(x)) { 219 if (Thread.currentThread().getContextClassLoader().getResource( 220 "org/netbeans/core/startup/DOMFactoryImpl.class") != null) return; 221 throw new SecurityException (""); 222 } 223 224 return; 225 } 226 private final Set <String > warnedClassesNDE = new HashSet <String >(25); 227 private static final Set <String > warnedClassesNH = new HashSet <String >(25); 228 static { 229 warnedClassesNH.add ("org.netbeans.core.LookupCache"); warnedClassesNH.add ("org.netbeans.updater.UpdateTracking"); warnedClassesNH.add("org.netbeans.core.ui.ProductInformationPanel"); } 233 234 235 236 240 public void checkRead(String file) { 241 } 243 244 public void checkRead(FileDescriptor fd) { 245 } 246 247 public void checkWrite(FileDescriptor fd) { 248 } 249 250 251 public void checkDelete(String file) { 252 try { 253 checkPermission(allPermission); 254 return; 255 } catch (SecurityException e) { 256 super.checkDelete(file); 257 } 258 } 259 260 public void checkWrite(String file) { 261 try { 262 checkPermission(allPermission); 263 return; 264 } catch (SecurityException e) { 265 super.checkWrite(file); 266 } 267 } 268 269 270 public void checkConnect(String host, int port) { 271 if (! check) { 272 return; 273 } 274 275 try { 276 checkPermission(allPermission); 277 return; 278 } catch (SecurityException e) { 279 } 280 281 try { 282 super.checkConnect(host, port); 283 return; 284 } catch (SecurityException e) { 285 } 286 287 PrivilegedCheck.checkConnect(host, port, this); 288 } 289 290 final void checkConnectImpl(String host, int port) { 291 Class insecure = getInsecureClass(); 292 if (insecure != null) { 293 URL ctx = getClassURL(insecure); 294 if (ctx != null) { 295 try { 296 String fromHost = ctx.getHost(); 297 InetAddress ia2 = InetAddress.getByName(host); 298 InetAddress ia3 = InetAddress.getByName(fromHost); 299 if (ia2.equals(ia3)) { 300 return; 301 } 302 } catch (UnknownHostException e) { e.printStackTrace(); 304 } 305 } 306 throw new SecurityException (); 307 } 308 } 309 310 public void checkConnect(String s, int port, Object context) { 311 checkConnect(s, port); 312 } 313 314 public void checkPermission(Permission perm) { 315 checkSetSecurityManager(perm); 316 317 if (perm instanceof java.awt.AWTPermission ) { 322 if ("accessClipboard".equals (perm.getName ())) { ThreadLocal <Object > t; 324 synchronized (TopSecurityManager.class) { 325 t = CLIPBOARD_FORBIDDEN; 326 } 327 if (t == null) { 328 return; 329 } 330 331 if (t.get () != null) { 332 t.set (this); 333 throw new SecurityException (); 334 } else { 335 checkWhetherAccessedFromSwingTransfer (); 336 } 337 } 338 } 339 return; 340 } 341 342 public void checkPermission(Permission perm, Object context) { 343 checkSetSecurityManager(perm); 344 return; 345 } 346 347 348 private static void checkSetSecurityManager(Permission perm) { 349 if (runtimePermissionClass.isInstance(perm)) { 350 if ("setSecurityManager".equals(perm.getName())) { throw new SecurityException (); 352 } 353 } 354 } 355 356 private Class getInsecureClass() { 367 368 Class [] ctx = getClassContext(); 369 boolean firstACClass = false; 370 371 LOOP: for (int i = 0; i < ctx.length; i++) { 372 373 if (ctx[i] == accessControllerClass) { 374 if (firstACClass) { 377 return null; 378 } else { 379 firstACClass = true; 380 continue LOOP; 381 } 382 } else if (ctx[i].getClassLoader() != null) { 383 384 if (isSecureClass(ctx[i])) { 385 if (classLoaderClass.isAssignableFrom(ctx[i])) { 386 return null; 387 } else { 388 continue LOOP; 390 } 391 } 392 393 return ctx[i]; 394 } else if (classLoaderClass.isAssignableFrom(ctx[i])) { return null; } 397 } 398 399 return null; 400 } 401 402 403 static boolean isSecureClass(final Class clazz) { 404 URL source = getClassURL(clazz); 405 if (source != null) { 406 return isSecureProtocol(source.getProtocol()); 407 } else { 408 return true; 409 } 410 } 411 412 414 static URL getClassURL(Class clazz) { 415 java.security.CodeSource cs = clazz.getProtectionDomain().getCodeSource(); 416 if (cs != null) { 417 URL url = cs.getLocation(); 418 return url; 419 } else { return null; 421 } 422 } 423 424 static Field getUrlField(Class clazz) { 425 if (urlField == null) { 426 try { 427 Field [] fds = clazz.getDeclaredFields(); 428 for (int i = 0; i < fds.length; i++) { 429 if (fds[i].getType() == URLClass) { 430 fds[i].setAccessible(true); 431 urlField = fds[i]; 432 break; 433 } 434 } 435 } catch (Exception e) { 436 e.printStackTrace(); 437 } 438 } 439 return urlField; 440 } 441 442 private static Field urlField; 443 444 445 static boolean isSecureProtocol(String protocol) { 446 if (protocol.equals("http") || protocol.equals("ftp") || protocol.equals("rmi")) { return false; 450 } else { 451 return true; 452 } 453 } 454 455 465 private static ThreadLocal <Object > CLIPBOARD_FORBIDDEN; 466 467 472 public static void makeSwingUseSpecialClipboard (java.awt.datatransfer.Clipboard clip) { 473 try { 474 synchronized (TopSecurityManager.class) { 475 assert System.getSecurityManager() instanceof TopSecurityManager : "Our manager has to be active: " + System.getSecurityManager(); if (CLIPBOARD_FORBIDDEN != null) { 477 return; 478 } 479 CLIPBOARD_FORBIDDEN = new ThreadLocal <Object >(); 480 CLIPBOARD_FORBIDDEN.set (clip); 481 } 482 483 javax.swing.JComponent source = new javax.swing.JPanel (); 484 javax.swing.TransferHandler.getPasteAction ().actionPerformed ( 485 new java.awt.event.ActionEvent (source, 0, "") 486 ); 487 javax.swing.TransferHandler.getCopyAction ().actionPerformed ( 488 new java.awt.event.ActionEvent (source, 0, "") 489 ); 490 javax.swing.TransferHandler.getCutAction ().actionPerformed ( 491 new java.awt.event.ActionEvent (source, 0, "") 492 ); 493 Object forb = CLIPBOARD_FORBIDDEN.get (); 494 CLIPBOARD_FORBIDDEN.set(null); 495 if (! (forb instanceof TopSecurityManager) ) { 496 System.err.println("Cannot install our clipboard to swing components, TopSecurityManager is not the security manager: " + forb); return; 498 } 499 500 Class <?> appContextClass = Class.forName ("sun.awt.AppContext"); Method getAppContext = appContextClass.getMethod ("getAppContext"); Object appContext = getAppContext.invoke (null, new Object [0]); 503 504 Class actionClass = javax.swing.TransferHandler.getCopyAction ().getClass (); 505 java.lang.reflect.Field sandboxKeyField = actionClass.getDeclaredField ("SandboxClipboardKey"); sandboxKeyField.setAccessible (true); 507 Object value = sandboxKeyField.get (null); 508 509 Method put = appContextClass.getMethod ("put", Object .class, Object .class); put.invoke (appContext, new Object [] { value, clip }); 511 } catch (ThreadDeath ex) { 512 throw ex; 513 } catch (Throwable t) { 514 t.printStackTrace(); 515 } finally { 516 CLIPBOARD_FORBIDDEN.set (null); 517 } 518 } 519 520 521 private static Class transferHandlerTransferAction; 522 524 private void checkWhetherAccessedFromSwingTransfer () throws SecurityException { 525 if (transferHandlerTransferAction == null) { 526 try { 527 transferHandlerTransferAction = Class.forName ("javax.swing.TransferHandler$TransferAction"); } catch (ClassNotFoundException ex) { 529 ex.printStackTrace(); 530 throw new SecurityException (ex.getMessage ()); 531 } 532 } 533 Class [] arr = getClassContext (); 534 for (int i = 0; i < arr.length; i++) { 535 if (arr[i] == transferHandlerTransferAction) { 536 throw new SecurityException ("All swing access to clipboard should be redirected to ExClipboard"); } 538 } 539 } 540 541 542 private static final class PrivilegedCheck implements PrivilegedExceptionAction <Object > { 543 int action; 544 TopSecurityManager tsm; 545 546 int status; 548 AccessControlContext acc; 549 550 String host; 552 int port; 553 554 555 public PrivilegedCheck(int action, TopSecurityManager tsm) { 556 this.action = action; 557 this.tsm = tsm; 558 559 if (action == 0) { 560 acc = AccessController.getContext(); 561 } 562 } 563 564 public Object run() throws Exception { 565 switch (action) { 566 case 0 : 567 tsm.checkExitImpl(status, acc); 568 break; 569 case 1 : 570 tsm.checkConnectImpl(host, port); 571 break; 572 default : 573 } 574 return null; 575 } 576 577 static void checkExit(int status, TopSecurityManager tsm) { 578 PrivilegedCheck pea = new PrivilegedCheck(0, tsm); 579 pea.status = status; 580 check(pea); 581 } 582 583 static void checkConnect(String host, int port, TopSecurityManager tsm) { 584 PrivilegedCheck pea = new PrivilegedCheck(1, tsm); 585 pea.host = host; 586 pea.port = port; 587 check(pea); 588 } 589 590 private static void check(PrivilegedCheck action) { 591 try { 592 AccessController.doPrivileged(action); 593 } catch (PrivilegedActionException e) { 594 Exception orig = e.getException(); 595 if (orig instanceof RuntimeException ) { 596 throw ((RuntimeException ) orig); 597 } 598 orig.printStackTrace(); 599 } 600 } 601 } 602 603 } 604 | Popular Tags |