1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang; 19 20 // BEGIN android-added 21 22 import dalvik.system.VMStack; 23 import java.io.File; 24 import java.io.FileDescriptor; 25 import java.io.FilePermission; 26 import java.lang.reflect.Constructor; 27 import java.lang.reflect.InvocationTargetException; 28 import java.lang.reflect.Member; 29 import java.net.InetAddress; 30 import java.net.SocketPermission; 31 import java.security.AccessControlContext; 32 import java.security.AccessController; 33 import java.security.AllPermission; 34 import java.security.Permission; 35 import java.security.Security; 36 import java.security.SecurityPermission; 37 import java.util.PropertyPermission; 38 import org.apache.harmony.luni.util.PriviAction; 39 40 /** 41 * <strong>Warning:</strong> security managers do <strong>not</strong> provide a 42 * secure environment for executing untrusted code. Untrusted code cannot be 43 * safely isolated within the Dalvik VM. 44 * 45 * <p>Provides security verification facilities for applications. {@code 46 * SecurityManager} contains a set of {@code checkXXX} methods which determine 47 * if it is safe to perform a specific operation such as establishing network 48 * connections, modifying files, and many more. In general, these methods simply 49 * return if they allow the application to perform the operation; if an 50 * operation is not allowed, then they throw a {@link SecurityException}. The 51 * only exception is {@link #checkTopLevelWindow(Object)}, which returns a 52 * boolean to indicate permission. 53 */ 54 public class SecurityManager { 55 56 private static final PropertyPermission READ_WRITE_ALL_PROPERTIES_PERMISSION = new PropertyPermission( 57 "*", "read,write"); 58 59 private static final String PKG_ACC_KEY = "package.access"; 60 61 private static final String PKG_DEF_KEY = "package.definition"; 62 63 /** 64 * Flag to indicate whether a security check is in progress. 65 * 66 * @deprecated Use {@link #checkPermission} 67 */ 68 @Deprecated 69 protected boolean inCheck; 70 71 /** 72 * Constructs a new {@code SecurityManager} instance. 73 * <p> 74 * The {@code RuntimePermission("createSecurityManager")} is checked if a 75 * security manager is installed. 76 */ SecurityManager()77 public SecurityManager() { 78 SecurityManager security = System.getSecurityManager(); 79 if (security != null) { 80 security 81 .checkPermission(RuntimePermission.permissionToCreateSecurityManager); 82 } 83 Class<?> type = Security.class; // initialize Security properties 84 if (type == null) { 85 throw new AssertionError(); 86 } 87 } 88 89 /** 90 * Checks whether the calling thread is allowed to accept socket 91 * connections. 92 * 93 * @param host 94 * the address of the host that attempts to connect. 95 * @param port 96 * the port number to check. 97 * @throws NullPointerException 98 * if {@code host} is {@code null}. 99 * @throws SecurityException 100 * if the calling thread is not allowed to accept socket 101 * connections from {@code host} through {@code port}. 102 */ checkAccept(String host, int port)103 public void checkAccept(String host, int port) { 104 if (host == null) { 105 throw new NullPointerException(); 106 } 107 checkPermission(new SocketPermission(host + ':' + port, "accept")); 108 } 109 110 /** 111 * Checks whether the calling thread is allowed to modify the specified 112 * thread. 113 * 114 * @param thread 115 * the thread to access. 116 * @throws SecurityException 117 * if the calling thread is not allowed to access {@code thread}. 118 */ checkAccess(Thread thread)119 public void checkAccess(Thread thread) { 120 // Only worry about system threads. Dead threads have a null group. 121 ThreadGroup group = thread.getThreadGroup(); 122 if ((group != null) && (group.parent == null)) { 123 checkPermission(RuntimePermission.permissionToModifyThread); 124 } 125 } 126 127 /** 128 * Checks whether the calling thread is allowed to modify the specified 129 * thread group. 130 * 131 * @param group 132 * the thread group to access. 133 * @throws NullPointerException 134 * if {@code group} is {@code null}. 135 * @throws SecurityException 136 * if the calling thread is not allowed to access {@code group}. 137 */ checkAccess(ThreadGroup group)138 public void checkAccess(ThreadGroup group) { 139 // Only worry about system threads. 140 if (group == null) { 141 throw new NullPointerException(); 142 } 143 if (group.parent == null) { 144 checkPermission(RuntimePermission.permissionToModifyThreadGroup); 145 } 146 } 147 148 /** 149 * Checks whether the calling thread is allowed to establish socket 150 * connections. A -1 port indicates the caller is trying to resolve the 151 * hostname. 152 * 153 * @param host 154 * the address of the host to connect to. 155 * @param port 156 * the port number to check, or -1 for resolve. 157 * @throws NullPointerException 158 * if {@code host} is {@code null}. 159 * @throws SecurityException 160 * if the calling thread is not allowed to connect to {@code 161 * host} through {@code port}. 162 */ checkConnect(String host, int port)163 public void checkConnect(String host, int port) { 164 if (host == null) { 165 throw new NullPointerException(); 166 } 167 if (port > 0) { 168 checkPermission(new SocketPermission(host + ':' + port, "connect")); 169 } else { 170 checkPermission(new SocketPermission(host, "resolve")); 171 } 172 } 173 174 /** 175 * Checks whether the specified security context is allowed to establish 176 * socket connections. A -1 port indicates the caller is trying to resolve 177 * the hostname. 178 * 179 * @param host 180 * the address of the host to connect to. 181 * @param port 182 * the port number to check, or -1 for resolve. 183 * @param context 184 * the security context to use for the check. 185 * @throws NullPointerException 186 * if {@code host} is {@code null}. 187 * @throws SecurityException 188 * if {@code context} is not allowed to connect to {@code host} 189 * through {@code port}. 190 */ checkConnect(String host, int port, Object context)191 public void checkConnect(String host, int port, Object context) { 192 // BEGIN android-added 193 if (host == null) { 194 throw new NullPointerException(); 195 } 196 // END android-added 197 if (port > 0) { 198 checkPermission(new SocketPermission(host + ':' + port, "connect"), 199 context); 200 } else { 201 checkPermission(new SocketPermission(host, "resolve"), context); 202 } 203 } 204 205 /** 206 * Checks whether the calling thread is allowed to create a class loader. 207 * 208 * @throws SecurityException 209 * if the calling thread is not allowed to create a class 210 * loader. 211 */ checkCreateClassLoader()212 public void checkCreateClassLoader() { 213 checkPermission(RuntimePermission.permissionToCreateClassLoader); 214 } 215 216 /** 217 * Checks whether the calling thread is allowed to delete the file with the 218 * specified name, which should be passed in canonical form. 219 * 220 * @param file 221 * the name of the file to delete. 222 * @throws SecurityException 223 * if the calling thread is not allowed to delete {@code file}. 224 */ checkDelete(String file)225 public void checkDelete(String file) { 226 checkPermission(new FilePermission(file, "delete")); 227 } 228 229 /** 230 * Checks whether the calling thread is allowed to execute the specified 231 * platform specific command. 232 * 233 * @param cmd 234 * the command line to execute. 235 * @throws SecurityException 236 * if the calling thread is not allowed to execute {@code cmd}. 237 */ checkExec(String cmd)238 public void checkExec(String cmd) { 239 checkPermission(new FilePermission(new File(cmd).isAbsolute() ? cmd 240 : "<<ALL FILES>>", "execute")); 241 } 242 243 /** 244 * Checks whether the calling thread is allowed to terminate the virtual 245 * machine. 246 * 247 * @param status 248 * the status that the virtual machine returns when it is 249 * terminated. 250 * @throws SecurityException 251 * if the calling thread is not allowed to terminate the virtual 252 * machine with {@code status}. 253 */ checkExit(int status)254 public void checkExit(int status) { 255 checkPermission(RuntimePermission.permissionToExitVM); 256 } 257 258 /** 259 * Checks whether the calling thread is allowed to load the specified native 260 * library. 261 * 262 * @param libName 263 * the name of the library to load. 264 * @throws SecurityException 265 * if the calling thread is not allowed to load {@code libName}. 266 */ checkLink(String libName)267 public void checkLink(String libName) { 268 if (libName == null) { 269 throw new NullPointerException(); 270 } 271 checkPermission(new RuntimePermission("loadLibrary." + libName)); 272 } 273 274 /** 275 * Checks whether the calling thread is allowed to listen on the specified 276 * port. 277 * 278 * @param port 279 * the port number to check. 280 * @throws SecurityException 281 * if the calling thread is not allowed listen on {@code port}. 282 */ checkListen(int port)283 public void checkListen(int port) { 284 if (port == 0) { 285 checkPermission(new SocketPermission("localhost:1024-", "listen")); 286 } else { 287 checkPermission(new SocketPermission("localhost:" + port, "listen")); 288 } 289 } 290 291 /** 292 * Checks whether the calling thread is allowed to access members. The 293 * default is to allow access to public members (that is, {@code 294 * java.lang.reflect.Member.PUBLIC}) and to classes loaded by the same 295 * loader as the original caller (that is, the method that called the 296 * reflect API). Due to the nature of the check, overriding implementations 297 * cannot call {@code super.checkMemberAccess()} since the stack would no 298 * longer be of the expected shape. 299 * 300 * @param cls 301 * the class of which members are accessed. 302 * @param type 303 * the access type, either {@code 304 * java.lang.reflect.Member.PUBLIC} or {@code 305 * java.lang.reflect.Member.DECLARED}. 306 * @throws SecurityException 307 * if the calling thread is not allowed to access members of 308 * {@code cls}. 309 */ checkMemberAccess(Class<?> cls, int type)310 public void checkMemberAccess(Class<?> cls, int type) { 311 if (cls == null) { 312 throw new NullPointerException(); 313 } 314 if (type == Member.PUBLIC) { 315 return; 316 } 317 // 318 // Need to compare the classloaders. 319 // Stack shape is 320 // <user code> <- want this class 321 // Class.getDeclared*(); 322 // Class.checkMemberAccess(); 323 // SecurityManager.checkMemberAccess(); <- current frame 324 // 325 // Use getClassLoaderImpl() since getClassLoader() 326 // returns null for the bootstrap class loader. 327 if (ClassLoader.getStackClassLoader(3) == cls.getClassLoaderImpl()) { 328 return; 329 } 330 331 // Forward off to the permission mechanism. 332 checkPermission(new RuntimePermission("accessDeclaredMembers")); 333 } 334 335 /** 336 * Checks whether the calling thread is allowed to use the specified IP 337 * multicast group address. 338 * 339 * @param maddr 340 * the internet group address to use. 341 * @throws SecurityException 342 * if the calling thread is not allowed to use {@code maddr}. 343 */ checkMulticast(InetAddress maddr)344 public void checkMulticast(InetAddress maddr) { 345 checkPermission(new SocketPermission(maddr.getHostAddress(), 346 "accept,connect")); 347 } 348 349 /** 350 * Checks whether the calling thread is allowed to use the specified IP 351 * multicast group address. 352 * 353 * @param maddr 354 * the internet group address to use. 355 * @param ttl 356 * the value in use for multicast send. This parameter is 357 * ignored. 358 * @throws SecurityException 359 * if the calling thread is not allowed to use {@code maddr}. 360 * @deprecated use {@link #checkMulticast(java.net.InetAddress)} 361 */ 362 @Deprecated checkMulticast(InetAddress maddr, byte ttl)363 public void checkMulticast(InetAddress maddr, byte ttl) { 364 checkPermission(new SocketPermission(maddr.getHostAddress(), 365 "accept,connect")); 366 } 367 368 /** 369 * Checks whether the calling thread is allowed to access the specified 370 * package. 371 * 372 * @param packageName 373 * the name of the package to access. 374 * @throws SecurityException 375 * if the calling thread is not allowed to access {@code 376 * packageName}. 377 */ checkPackageAccess(String packageName)378 public void checkPackageAccess(String packageName) { 379 if (packageName == null) { 380 throw new NullPointerException(); 381 } 382 if (checkPackageProperty(PKG_ACC_KEY, packageName)) { 383 checkPermission(new RuntimePermission("accessClassInPackage." 384 + packageName)); 385 } 386 } 387 388 /** 389 * Checks whether the calling thread is allowed to define new classes in the 390 * specified package. 391 * 392 * @param packageName 393 * the name of the package to add a class to. 394 * @throws SecurityException 395 * if the calling thread is not allowed to add classes to 396 * {@code packageName}. 397 */ checkPackageDefinition(String packageName)398 public void checkPackageDefinition(String packageName) { 399 if (packageName == null) { 400 throw new NullPointerException(); 401 } 402 if (checkPackageProperty(PKG_DEF_KEY, packageName)) { 403 checkPermission(new RuntimePermission("defineClassInPackage." 404 + packageName)); 405 } 406 } 407 408 /** 409 * Returns true if the package name is restricted by the specified security 410 * property. 411 */ checkPackageProperty(final String property, final String pkg)412 private static boolean checkPackageProperty(final String property, 413 final String pkg) { 414 String list = AccessController.doPrivileged(PriviAction 415 .getSecurityProperty(property)); 416 if (list != null) { 417 int plen = pkg.length(); 418 String[] tokens = list.split(", *"); 419 for (String token : tokens) { 420 int tlen = token.length(); 421 if (plen > tlen 422 && pkg.startsWith(token) 423 && (token.charAt(tlen - 1) == '.' || pkg.charAt(tlen) == '.')) { 424 return true; 425 } else if (plen == tlen && token.startsWith(pkg)) { 426 return true; 427 } else if (plen + 1 == tlen && token.startsWith(pkg) 428 && token.charAt(tlen - 1) == '.') { 429 return true; 430 } 431 } 432 } 433 434 return false; 435 } 436 437 /** 438 * Checks whether the calling thread is allowed to access the system 439 * properties. 440 * 441 * @throws SecurityException 442 * if the calling thread is not allowed to access system 443 * properties. 444 */ checkPropertiesAccess()445 public void checkPropertiesAccess() { 446 checkPermission(READ_WRITE_ALL_PROPERTIES_PERMISSION); 447 } 448 449 /** 450 * Checks whether the calling thread is allowed to access a particular 451 * system property. 452 * 453 * @param key 454 * the name of the property to access. 455 * @throws SecurityException 456 * if the calling thread is not allowed to access the {@code 457 * key} system property. 458 */ checkPropertyAccess(String key)459 public void checkPropertyAccess(String key) { 460 checkPermission(new PropertyPermission(key, "read")); 461 } 462 463 /** 464 * Checks whether the calling thread is allowed to read from the file with 465 * the specified file descriptor. 466 * 467 * @param fd 468 * the file descriptor of the file to read from. 469 * @throws SecurityException 470 * if the calling thread is not allowed to read from {@code fd}. 471 */ checkRead(FileDescriptor fd)472 public void checkRead(FileDescriptor fd) { 473 if (fd == null) { 474 throw new NullPointerException(); 475 } 476 checkPermission(RuntimePermission.permissionToReadFileDescriptor); 477 } 478 479 /** 480 * Checks whether the calling thread is allowed to read from the file with 481 * the specified name, which should be passed in canonical form. 482 * 483 * @param file 484 * the name of the file or directory to read from. 485 * @throws SecurityException 486 * if the calling thread is not allowed to read from {@code 487 * file}. 488 */ checkRead(String file)489 public void checkRead(String file) { 490 checkPermission(new FilePermission(file, "read")); 491 } 492 493 /** 494 * Checks whether the given security context is allowed to read from the 495 * file named by the argument, which should be passed in canonical form. 496 * 497 * @param file 498 * the name of the file or directory to check. 499 * @param context 500 * the security context to use for the check. 501 * @throws SecurityException 502 * if {@code context} is not allowed to read from {@code file}. 503 */ checkRead(String file, Object context)504 public void checkRead(String file, Object context) { 505 checkPermission(new FilePermission(file, "read"), context); 506 } 507 508 /** 509 * Checks whether the calling thread is allowed to perform the security 510 * operation named by the target. 511 * 512 * @param target 513 * the name of the operation to perform. 514 * @throws SecurityException 515 * if the calling thread is not allowed to perform 516 * {@code target}. 517 */ checkSecurityAccess(String target)518 public void checkSecurityAccess(String target) { 519 checkPermission(new SecurityPermission(target)); 520 } 521 522 /** 523 * Checks whether the calling thread is allowed to set the net object 524 * factories. 525 * 526 * @throws SecurityException 527 * if the calling thread is not allowed to set the net object 528 * factories. 529 */ checkSetFactory()530 public void checkSetFactory() { 531 checkPermission(RuntimePermission.permissionToSetFactory); 532 } 533 534 /** 535 * Checks whether the calling thread is trusted to show the specified top 536 * level window. 537 * 538 * @param window 539 * the window to show. 540 * @return {@code true} if the calling thread is allowed to show {@code 541 * window}; {@code false} otherwise. 542 * @throws NullPointerException 543 * if {@code window} is {@code null}. 544 */ checkTopLevelWindow(Object window)545 public boolean checkTopLevelWindow(Object window) { 546 if (window == null) { 547 throw new NullPointerException(); 548 } 549 try { 550 Class<?> awtPermission = Class.forName("java.awt.AWTPermission"); 551 Constructor<?> constructor = awtPermission 552 .getConstructor(String.class); 553 Object perm = constructor 554 .newInstance("showWindowWithoutWarningBanner"); 555 checkPermission((Permission) perm); 556 } catch (ClassNotFoundException e) { 557 } catch (NoSuchMethodException e) { 558 } catch (InstantiationException e) { 559 } catch (IllegalAccessException e) { 560 } catch (InvocationTargetException e) { 561 } catch (SecurityException e) { 562 return false; 563 } 564 return true; 565 } 566 567 /** 568 * Checks whether the calling thread is allowed to access the system 569 * clipboard. 570 * 571 * @throws SecurityException 572 * if the calling thread is not allowed to access the system 573 * clipboard. 574 */ checkSystemClipboardAccess()575 public void checkSystemClipboardAccess() { 576 try { 577 Class<?> awtPermission = Class.forName("java.awt.AWTPermission"); 578 Constructor<?> constructor = awtPermission 579 .getConstructor(String.class); 580 Object perm = constructor.newInstance("accessClipboard"); 581 checkPermission((Permission) perm); 582 return; 583 } catch (ClassNotFoundException e) { 584 } catch (NoSuchMethodException e) { 585 } catch (InstantiationException e) { 586 } catch (IllegalAccessException e) { 587 } catch (InvocationTargetException e) { 588 } 589 throw new SecurityException(); 590 } 591 592 /** 593 * Checks whether the calling thread is allowed to access the AWT event 594 * queue. 595 * 596 * @throws SecurityException 597 * if the calling thread is not allowed to access the AWT event 598 * queue. 599 */ checkAwtEventQueueAccess()600 public void checkAwtEventQueueAccess() { 601 try { 602 Class<?> awtPermission = Class.forName("java.awt.AWTPermission"); 603 Constructor<?> constructor = awtPermission 604 .getConstructor(String.class); 605 Object perm = constructor.newInstance("accessEventQueue"); 606 checkPermission((Permission) perm); 607 return; 608 } catch (ClassNotFoundException e) { 609 } catch (NoSuchMethodException e) { 610 } catch (InstantiationException e) { 611 } catch (IllegalAccessException e) { 612 } catch (InvocationTargetException e) { 613 } 614 throw new SecurityException(); 615 } 616 617 /** 618 * Checks whether the calling thread is allowed to start a new print job. 619 * 620 * @throws SecurityException 621 * if the calling thread is not allowed to start a new print 622 * job. 623 */ checkPrintJobAccess()624 public void checkPrintJobAccess() { 625 checkPermission(RuntimePermission.permissionToQueuePrintJob); 626 } 627 628 /** 629 * Checks whether the calling thread is allowed to write to the file with 630 * the specified file descriptor. 631 * 632 * @param fd 633 * the file descriptor of the file to write to. 634 * @throws SecurityException 635 * if the calling thread is not allowed to write to {@code fd}. 636 */ checkWrite(FileDescriptor fd)637 public void checkWrite(FileDescriptor fd) { 638 if (fd == null) { 639 throw new NullPointerException(); 640 } 641 checkPermission(RuntimePermission.permissionToWriteFileDescriptor); 642 } 643 644 /** 645 * Checks whether the calling thread is allowed to write to the file with 646 * the specified name, which should be passed in canonical form. 647 * 648 * @param file 649 * the name of the file or directory to write to. 650 * @throws SecurityException 651 * if the calling thread is not allowed to write to 652 * {@code file}. 653 */ checkWrite(String file)654 public void checkWrite(String file) { 655 checkPermission(new FilePermission(file, "write")); 656 } 657 658 /** 659 * Indicates if this security manager is currently checking something. 660 * 661 * @return {@code true} if this security manager is executing a security 662 * check method; {@code false} otherwise. 663 * @deprecated Use {@link #checkPermission}. 664 */ 665 @Deprecated getInCheck()666 public boolean getInCheck() { 667 return inCheck; 668 } 669 670 /** 671 * Returns an array containing one entry for each method in the current 672 * execution stack. Each entry is the {@code java.lang.Class} which 673 * represents the class in which the method is defined. 674 * 675 * @return all classes in the execution stack. 676 */ 677 @SuppressWarnings("unchecked") getClassContext()678 protected Class[] getClassContext() { 679 return VMStack.getClasses(-1, false); 680 } 681 682 /** 683 * Returns the class loader of the first class in the execution stack whose 684 * class loader is not a system class loader. 685 * 686 * @return the most recent non-system class loader. 687 * @deprecated Use {@link #checkPermission}. 688 */ 689 @Deprecated currentClassLoader()690 protected ClassLoader currentClassLoader() { 691 692 /* 693 * First, check if AllPermission is allowed. If so, then we are 694 * effectively running in an unsafe environment, so just answer null 695 * (==> everything is a system class). 696 */ 697 try { 698 checkPermission(new AllPermission()); 699 return null; 700 } catch (SecurityException ex) { 701 } 702 703 /* 704 * Now, check if there are any non-system class loaders in the stack up 705 * to the first privileged method (or the end of the stack. 706 */ 707 Class<?>[] classes = Class.getStackClasses(-1, true); 708 for (int i = 0; i < classes.length; i++) { 709 ClassLoader cl = classes[i].getClassLoaderImpl(); 710 if (!cl.isSystemClassLoader()) { 711 return cl; 712 } 713 } 714 return null; 715 } 716 717 /** 718 * Returns the index in the call stack of the first class whose class loader 719 * is not a system class loader. 720 * 721 * @return the frame index of the first method whose class was loaded by a 722 * non-system class loader. 723 * @deprecated Use {@link #checkPermission}. 724 */ 725 @Deprecated classLoaderDepth()726 protected int classLoaderDepth() { 727 /* 728 * First, check if AllPermission is allowed. If so, then we are 729 * effectively running in an unsafe environment, so just answer -1 (==> 730 * everything is a system class). 731 */ 732 try { 733 checkPermission(new AllPermission()); 734 return -1; 735 } catch (SecurityException ex) { 736 } 737 738 /* 739 * Now, check if there are any non-system class loaders in the stack up 740 * to the first privileged method (or the end of the stack. 741 */ 742 Class<?>[] classes = Class.getStackClasses(-1, true); 743 for (int i = 0; i < classes.length; i++) { 744 ClassLoader cl = classes[i].getClassLoaderImpl(); 745 if (!cl.isSystemClassLoader()) { 746 return i; 747 } 748 } 749 return -1; 750 } 751 752 /** 753 * Returns the first class in the call stack that was loaded by a class 754 * loader which is not a system class loader. 755 * 756 * @return the most recent class loaded by a non-system class loader. 757 * @deprecated Use {@link #checkPermission}. 758 */ 759 @Deprecated currentLoadedClass()760 protected Class<?> currentLoadedClass() { 761 /* 762 * First, check if AllPermission is allowed. If so, then we are 763 * effectively running in an unsafe environment, so just answer null 764 * (==> everything is a system class). 765 */ 766 try { 767 checkPermission(new AllPermission()); 768 return null; 769 } catch (SecurityException ex) { 770 } 771 772 /* 773 * Now, check if there are any non-system class loaders in the stack up 774 * to the first privileged method (or the end of the stack. 775 */ 776 Class<?>[] classes = Class.getStackClasses(-1, true); 777 for (int i = 0; i < classes.length; i++) { 778 ClassLoader cl = classes[i].getClassLoaderImpl(); 779 if (!cl.isSystemClassLoader()) { 780 return classes[i]; 781 } 782 } 783 return null; 784 } 785 786 /** 787 * Returns the index in the call stack of the first method which is 788 * contained in the class with the specified name. Returns -1 if no methods 789 * from this class are in the stack. 790 * 791 * @param name 792 * the name of the class to look for. 793 * @return the frame index of the first method found is contained in the 794 * class identified by {@code name}. 795 * @deprecated Use {@link #checkPermission}. 796 */ 797 @Deprecated classDepth(String name)798 protected int classDepth(String name) { 799 Class<?>[] classes = Class.getStackClasses(-1, false); 800 for (int i = 0; i < classes.length; i++) { 801 if (classes[i].getName().equals(name)) { 802 return i; 803 } 804 } 805 return -1; 806 } 807 808 /** 809 * Indicates whether there is a method in the call stack from the class with 810 * the specified name. 811 * 812 * @param name 813 * the name of the class to look for. 814 * @return {@code true} if a method from the class identified by {@code 815 * name} is executing; {@code false} otherwise. 816 * @deprecated Use {@link #checkPermission}. 817 */ 818 @Deprecated inClass(String name)819 protected boolean inClass(String name) { 820 return classDepth(name) != -1; 821 } 822 823 /** 824 * Indicates whether there is a method in the call stack from a class which 825 * was defined by a non-system class loader. 826 * 827 * @return {@code true} if a method from a class that was defined by a 828 * non-system class loader is executing; {@code false} otherwise. 829 * @deprecated Use {@link #checkPermission} 830 */ 831 @Deprecated inClassLoader()832 protected boolean inClassLoader() { 833 return currentClassLoader() != null; 834 } 835 836 /** 837 * Returns the thread group which should be used to instantiate new threads. 838 * By default, this is the same as the thread group of the thread running 839 * this method. 840 * 841 * @return ThreadGroup the thread group to create new threads in. 842 */ getThreadGroup()843 public ThreadGroup getThreadGroup() { 844 return Thread.currentThread().getThreadGroup(); 845 } 846 847 /** 848 * Returns an object which encapsulates the security state of the current 849 * point in the execution. In our case, this is an {@link 850 * java.security.AccessControlContext}. 851 * 852 * @return an object that encapsulates information about the current 853 * execution environment. 854 */ getSecurityContext()855 public Object getSecurityContext() { 856 return AccessController.getContext(); 857 } 858 859 /** 860 * Checks whether the calling thread is allowed to access the resource being 861 * guarded by the specified permission object. 862 * 863 * @param permission 864 * the permission to check. 865 * @throws SecurityException 866 * if the requested {@code permission} is denied according to 867 * the current security policy. 868 */ checkPermission(Permission permission)869 public void checkPermission(Permission permission) { 870 try { 871 inCheck = true; 872 AccessController.checkPermission(permission); 873 } finally { 874 inCheck = false; 875 } 876 } 877 878 /** 879 * Checks whether the specified security context is allowed to access the 880 * resource being guarded by the specified permission object. 881 * 882 * @param permission 883 * the permission to check. 884 * @param context 885 * the security context for which to check permission. 886 * @throws SecurityException 887 * if {@code context} is not an instance of {@code 888 * AccessControlContext} or if the requested {@code permission} 889 * is denied for {@code context} according to the current 890 * security policy. 891 */ checkPermission(Permission permission, Object context)892 public void checkPermission(Permission permission, Object context) { 893 try { 894 inCheck = true; 895 // Must be an AccessControlContext. If we don't check 896 // this, then applications could pass in an arbitrary 897 // object which circumvents the security check. 898 if (context instanceof AccessControlContext) { 899 ((AccessControlContext) context).checkPermission(permission); 900 } else { 901 throw new SecurityException(); 902 } 903 } finally { 904 inCheck = false; 905 } 906 } 907 } 908