GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* SecurityManager.java -- security checks for privileged actions 2: Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.lang; 40: 41: import gnu.classpath.VMStackWalker; 42: 43: import java.awt.AWTPermission; 44: import java.io.File; 45: import java.io.FileDescriptor; 46: import java.io.FilePermission; 47: import java.lang.reflect.Member; 48: import java.net.InetAddress; 49: import java.net.SocketPermission; 50: import java.security.AccessControlContext; 51: import java.security.AccessController; 52: import java.security.AllPermission; 53: import java.security.Permission; 54: import java.security.PrivilegedAction; 55: import java.security.Security; 56: import java.security.SecurityPermission; 57: import java.util.PropertyPermission; 58: import java.util.StringTokenizer; 59: 60: /** 61: * SecurityManager is a class you can extend to create your own Java 62: * security policy. By default, there is no SecurityManager installed in 63: * 1.1, which means that all things are permitted to all people. The security 64: * manager, if set, is consulted before doing anything with potentially 65: * dangerous results, and throws a <code>SecurityException</code> if the 66: * action is forbidden. 67: * 68: * <p>A typical check is as follows, just before the dangerous operation:<br> 69: * <pre> 70: * SecurityManager sm = System.getSecurityManager(); 71: * if (sm != null) 72: * sm.checkABC(<em>argument</em>, ...); 73: * </pre> 74: * Note that this is thread-safe, by caching the security manager in a local 75: * variable rather than risking a NullPointerException if the mangager is 76: * changed between the check for null and before the permission check. 77: * 78: * <p>The special method <code>checkPermission</code> is a catchall, and 79: * the default implementation calls 80: * <code>AccessController.checkPermission</code>. In fact, all the other 81: * methods default to calling checkPermission. 82: * 83: * <p>Sometimes, the security check needs to happen from a different context, 84: * such as when called from a worker thread. In such cases, use 85: * <code>getSecurityContext</code> to take a snapshot that can be passed 86: * to the worker thread:<br> 87: * <pre> 88: * Object context = null; 89: * SecurityManager sm = System.getSecurityManager(); 90: * if (sm != null) 91: * context = sm.getSecurityContext(); // defaults to an AccessControlContext 92: * // now, in worker thread 93: * if (sm != null) 94: * sm.checkPermission(permission, context); 95: * </pre> 96: * 97: * <p>Permissions fall into these categories: File, Socket, Net, Security, 98: * Runtime, Property, AWT, Reflect, and Serializable. Each of these 99: * permissions have a property naming convention, that follows a hierarchical 100: * naming convention, to make it easy to grant or deny several permissions 101: * at once. Some permissions also take a list of permitted actions, such 102: * as "read" or "write", to fine-tune control even more. The permission 103: * <code>java.security.AllPermission</code> grants all permissions. 104: * 105: * <p>The default methods in this class deny all things to all people. You 106: * must explicitly grant permission for anything you want to be legal when 107: * subclassing this class. 108: * 109: * @author John Keiser 110: * @author Eric Blake (ebb9@email.byu.edu) 111: * @see ClassLoader 112: * @see SecurityException 113: * @see #checkTopLevelWindow(Object) 114: * @see System#getSecurityManager() 115: * @see System#setSecurityManager(SecurityManager) 116: * @see AccessController 117: * @see AccessControlContext 118: * @see AccessControlException 119: * @see Permission 120: * @see BasicPermission 121: * @see java.io.FilePermission 122: * @see java.net.SocketPermission 123: * @see java.util.PropertyPermission 124: * @see RuntimePermission 125: * @see java.awt.AWTPermission 126: * @see Policy 127: * @see SecurityPermission 128: * @see ProtectionDomain 129: * @since 1.0 130: * @status still missing 1.4 functionality 131: */ 132: public class SecurityManager 133: { 134: /** 135: * The current security manager. This is located here instead of in 136: * System, to avoid security problems, as well as bootstrap issues. 137: * Make sure to access it in a thread-safe manner; it is package visible 138: * to avoid overhead in java.lang. 139: */ 140: static volatile SecurityManager current; 141: 142: /** 143: * Tells whether or not the SecurityManager is currently performing a 144: * security check. 145: * @deprecated Use {@link #checkPermission(Permission)} instead. 146: */ 147: protected boolean inCheck; 148: 149: /** 150: * Construct a new security manager. There may be a security check, of 151: * <code>RuntimePermission("createSecurityManager")</code>. 152: * 153: * @throws SecurityException if permission is denied 154: */ 155: public SecurityManager() 156: { 157: SecurityManager sm = System.getSecurityManager(); 158: if (sm != null) 159: sm.checkPermission(new RuntimePermission("createSecurityManager")); 160: } 161: 162: /** 163: * Tells whether or not the SecurityManager is currently performing a 164: * security check. 165: * 166: * @return true if the SecurityManager is in a security check 167: * @see #inCheck 168: * @deprecated use {@link #checkPermission(Permission)} instead 169: */ 170: public boolean getInCheck() 171: { 172: return inCheck; 173: } 174: 175: /** 176: * Get a list of all the classes currently executing methods on the Java 177: * stack. getClassContext()[0] is the currently executing method (ie. the 178: * class that CALLED getClassContext, not SecurityManager). 179: * 180: * @return an array of classes on the Java execution stack 181: */ 182: protected Class[] getClassContext() 183: { 184: Class[] stack1 = VMStackWalker.getClassContext(); 185: Class[] stack2 = new Class[stack1.length - 1]; 186: System.arraycopy(stack1, 1, stack2, 0, stack1.length - 1); 187: return stack2; 188: } 189: 190: /** 191: * Find the ClassLoader of the first non-system class on the execution 192: * stack. A non-system class is one whose ClassLoader is not equal to 193: * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This 194: * will return null in three cases: 195: * 196: * <ul> 197: * <li>All methods on the stack are from system classes</li> 198: * <li>All methods on the stack up to the first "privileged" caller, as 199: * created by {@link AccessController.doPrivileged(PrivilegedAction)}, 200: * are from system classes</li> 201: * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> 202: * </ul> 203: * 204: * @return the most recent non-system ClassLoader on the execution stack 205: * @deprecated use {@link #checkPermission(Permission)} instead 206: */ 207: protected ClassLoader currentClassLoader() 208: { 209: Class cl = currentLoadedClass(); 210: return cl != null ? cl.getClassLoader() : null; 211: } 212: 213: /** 214: * Find the first non-system class on the execution stack. A non-system 215: * class is one whose ClassLoader is not equal to 216: * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This 217: * will return null in three cases: 218: * 219: * <ul> 220: * <li>All methods on the stack are from system classes</li> 221: * <li>All methods on the stack up to the first "privileged" caller, as 222: * created by {@link AccessController.doPrivileged(PrivilegedAction)}, 223: * are from system classes</li> 224: * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> 225: * </ul> 226: * 227: * @return the most recent non-system Class on the execution stack 228: * @deprecated use {@link #checkPermission(Permission)} instead 229: */ 230: protected Class currentLoadedClass() 231: { 232: int i = classLoaderDepth(); 233: return i >= 0 ? getClassContext()[i] : null; 234: } 235: 236: /** 237: * Get the depth of a particular class on the execution stack. 238: * 239: * @param className the fully-qualified name to search for 240: * @return the index of the class on the stack, or -1 241: * @deprecated use {@link #checkPermission(Permission)} instead 242: */ 243: protected int classDepth(String className) 244: { 245: Class[] c = getClassContext(); 246: for (int i = 0; i < c.length; i++) 247: if (className.equals(c[i].getName())) 248: return i; 249: return -1; 250: } 251: 252: /** 253: * Get the depth on the execution stack of the most recent non-system class. 254: * A non-system class is one whose ClassLoader is not equal to 255: * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This 256: * will return -1 in three cases: 257: * 258: * <ul> 259: * <li>All methods on the stack are from system classes</li> 260: * <li>All methods on the stack up to the first "privileged" caller, as 261: * created by {@link AccessController.doPrivileged(PrivilegedAction)}, 262: * are from system classes</li> 263: * <li>A check of <code>java.security.AllPermission</code> succeeds.</li> 264: * </ul> 265: * 266: * @return the index of the most recent non-system Class on the stack 267: * @deprecated use {@link #checkPermission(Permission)} instead 268: */ 269: protected int classLoaderDepth() 270: { 271: try 272: { 273: checkPermission(new AllPermission()); 274: } 275: catch (SecurityException e) 276: { 277: Class[] c = getClassContext(); 278: for (int i = 0; i < c.length; i++) 279: if (c[i].getClassLoader() != null) 280: // XXX Check if c[i] is AccessController, or a system class. 281: return i; 282: } 283: return -1; 284: } 285: 286: /** 287: * Tell whether the specified class is on the execution stack. 288: * 289: * @param className the fully-qualified name of the class to find 290: * @return whether the specified class is on the execution stack 291: * @deprecated use {@link #checkPermission(Permission)} instead 292: */ 293: protected boolean inClass(String className) 294: { 295: return classDepth(className) != -1; 296: } 297: 298: /** 299: * Tell whether there is a class loaded with an explicit ClassLoader on 300: * the stack. 301: * 302: * @return whether a class with an explicit ClassLoader is on the stack 303: * @deprecated use {@link #checkPermission(Permission)} instead 304: */ 305: protected boolean inClassLoader() 306: { 307: return classLoaderDepth() != -1; 308: } 309: 310: /** 311: * Get an implementation-dependent Object that contains enough information 312: * about the current environment to be able to perform standard security 313: * checks later. This is used by trusted methods that need to verify that 314: * their callers have sufficient access to perform certain operations. 315: * 316: * <p>Currently the only methods that use this are checkRead() and 317: * checkConnect(). The default implementation returns an 318: * <code>AccessControlContext</code>. 319: * 320: * @return a security context 321: * @see #checkConnect(String, int, Object) 322: * @see #checkRead(String, Object) 323: * @see AccessControlContext 324: * @see AccessController#getContext() 325: */ 326: public Object getSecurityContext() 327: { 328: return AccessController.getContext(); 329: } 330: 331: /** 332: * Check if the current thread is allowed to perform an operation that 333: * requires the specified <code>Permission</code>. This defaults to 334: * <code>AccessController.checkPermission</code>. 335: * 336: * @param perm the <code>Permission</code> required 337: * @throws SecurityException if permission is denied 338: * @throws NullPointerException if perm is null 339: * @since 1.2 340: */ 341: public void checkPermission(Permission perm) 342: { 343: AccessController.checkPermission(perm); 344: } 345: 346: /** 347: * Check if the current thread is allowed to perform an operation that 348: * requires the specified <code>Permission</code>. This is done in a 349: * context previously returned by <code>getSecurityContext()</code>. The 350: * default implementation expects context to be an AccessControlContext, 351: * and it calls <code>AccessControlContext.checkPermission(perm)</code>. 352: * 353: * @param perm the <code>Permission</code> required 354: * @param context a security context 355: * @throws SecurityException if permission is denied, or if context is 356: * not an AccessControlContext 357: * @throws NullPointerException if perm is null 358: * @see #getSecurityContext() 359: * @see AccessControlContext#checkPermission(Permission) 360: * @since 1.2 361: */ 362: public void checkPermission(Permission perm, Object context) 363: { 364: if (! (context instanceof AccessControlContext)) 365: throw new SecurityException("Missing context"); 366: ((AccessControlContext) context).checkPermission(perm); 367: } 368: 369: /** 370: * Check if the current thread is allowed to create a ClassLoader. This 371: * method is called from ClassLoader.ClassLoader(), and checks 372: * <code>RuntimePermission("createClassLoader")</code>. If you override 373: * this, you should call <code>super.checkCreateClassLoader()</code> rather 374: * than throwing an exception. 375: * 376: * @throws SecurityException if permission is denied 377: * @see ClassLoader#ClassLoader() 378: */ 379: public void checkCreateClassLoader() 380: { 381: checkPermission(new RuntimePermission("createClassLoader")); 382: } 383: 384: /** 385: * Check if the current thread is allowed to modify another Thread. This is 386: * called by Thread.stop(), suspend(), resume(), interrupt(), destroy(), 387: * setPriority(), setName(), and setDaemon(). The default implementation 388: * checks <code>RuntimePermission("modifyThread")</code> on system threads 389: * (ie. threads in ThreadGroup with a null parent), and returns silently on 390: * other threads. 391: * 392: * <p>If you override this, you must do two things. First, call 393: * <code>super.checkAccess(t)</code>, to make sure you are not relaxing 394: * requirements. Second, if the calling thread has 395: * <code>RuntimePermission("modifyThread")</code>, return silently, so that 396: * core classes (the Classpath library!) can modify any thread. 397: * 398: * @param thread the other Thread to check 399: * @throws SecurityException if permission is denied 400: * @throws NullPointerException if thread is null 401: * @see Thread#stop() 402: * @see Thread#suspend() 403: * @see Thread#resume() 404: * @see Thread#setPriority(int) 405: * @see Thread#setName(String) 406: * @see Thread#setDaemon(boolean) 407: */ 408: public void checkAccess(Thread thread) 409: { 410: if (thread.getThreadGroup() != null 411: && thread.getThreadGroup().getParent() != null) 412: checkPermission(new RuntimePermission("modifyThread")); 413: } 414: 415: /** 416: * Check if the current thread is allowed to modify a ThreadGroup. This is 417: * called by Thread.Thread() (to add a thread to the ThreadGroup), 418: * ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent), 419: * ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(), 420: * setDaemon(), and setMaxPriority(). The default implementation 421: * checks <code>RuntimePermission("modifyThread")</code> on the system group 422: * (ie. the one with a null parent), and returns silently on other groups. 423: * 424: * <p>If you override this, you must do two things. First, call 425: * <code>super.checkAccess(t)</code>, to make sure you are not relaxing 426: * requirements. Second, if the calling thread has 427: * <code>RuntimePermission("modifyThreadGroup")</code>, return silently, 428: * so that core classes (the Classpath library!) can modify any thread. 429: * 430: * @param g the ThreadGroup to check 431: * @throws SecurityException if permission is denied 432: * @throws NullPointerException if g is null 433: * @see Thread#Thread() 434: * @see ThreadGroup#ThreadGroup() 435: * @see ThreadGroup#stop() 436: * @see ThreadGroup#suspend() 437: * @see ThreadGroup#resume() 438: * @see ThreadGroup#interrupt() 439: * @see ThreadGroup#setDaemon(boolean) 440: * @see ThreadGroup#setMaxPriority(int) 441: */ 442: public void checkAccess(ThreadGroup g) 443: { 444: if (g.getParent() != null) 445: checkPermission(new RuntimePermission("modifyThreadGroup")); 446: } 447: 448: /** 449: * Check if the current thread is allowed to exit the JVM with the given 450: * status. This method is called from Runtime.exit() and Runtime.halt(). 451: * The default implementation checks 452: * <code>RuntimePermission("exitVM")</code>. If you override this, call 453: * <code>super.checkExit</code> rather than throwing an exception. 454: * 455: * @param status the status to exit with 456: * @throws SecurityException if permission is denied 457: * @see Runtime#exit(int) 458: * @see Runtime#halt(int) 459: */ 460: public void checkExit(int status) 461: { 462: checkPermission(new RuntimePermission("exitVM")); 463: } 464: 465: /** 466: * Check if the current thread is allowed to execute the given program. This 467: * method is called from Runtime.exec(). If the name is an absolute path, 468: * the default implementation checks 469: * <code>FilePermission(program, "execute")</code>, otherwise it checks 470: * <code>FilePermission("<<ALL FILES>>", "execute")</code>. If 471: * you override this, call <code>super.checkExec</code> rather than 472: * throwing an exception. 473: * 474: * @param program the name of the program to exec 475: * @throws SecurityException if permission is denied 476: * @throws NullPointerException if program is null 477: * @see Runtime#exec(String[], String[], File) 478: */ 479: public void checkExec(String program) 480: { 481: if (! program.equals(new File(program).getAbsolutePath())) 482: program = "<<ALL FILES>>"; 483: checkPermission(new FilePermission(program, "execute")); 484: } 485: 486: /** 487: * Check if the current thread is allowed to link in the given native 488: * library. This method is called from Runtime.load() (and hence, by 489: * loadLibrary() as well). The default implementation checks 490: * <code>RuntimePermission("loadLibrary." + filename)</code>. If you 491: * override this, call <code>super.checkLink</code> rather than throwing 492: * an exception. 493: * 494: * @param filename the full name of the library to load 495: * @throws SecurityException if permission is denied 496: * @throws NullPointerException if filename is null 497: * @see Runtime#load(String) 498: */ 499: public void checkLink(String filename) 500: { 501: // Use the toString() hack to do the null check. 502: checkPermission(new RuntimePermission("loadLibrary." 503: + filename.toString())); 504: } 505: 506: /** 507: * Check if the current thread is allowed to read the given file using the 508: * FileDescriptor. This method is called from 509: * FileInputStream.FileInputStream(). The default implementation checks 510: * <code>RuntimePermission("readFileDescriptor")</code>. If you override 511: * this, call <code>super.checkRead</code> rather than throwing an 512: * exception. 513: * 514: * @param desc the FileDescriptor representing the file to access 515: * @throws SecurityException if permission is denied 516: * @throws NullPointerException if desc is null 517: * @see FileInputStream#FileInputStream(FileDescriptor) 518: */ 519: public void checkRead(FileDescriptor desc) 520: { 521: if (desc == null) 522: throw new NullPointerException(); 523: checkPermission(new RuntimePermission("readFileDescriptor")); 524: } 525: 526: /** 527: * Check if the current thread is allowed to read the given file. This 528: * method is called from FileInputStream.FileInputStream(), 529: * RandomAccessFile.RandomAccessFile(), File.exists(), canRead(), isFile(), 530: * isDirectory(), lastModified(), length() and list(). The default 531: * implementation checks <code>FilePermission(filename, "read")</code>. If 532: * you override this, call <code>super.checkRead</code> rather than 533: * throwing an exception. 534: * 535: * @param filename the full name of the file to access 536: * @throws SecurityException if permission is denied 537: * @throws NullPointerException if filename is null 538: * @see File 539: * @see FileInputStream#FileInputStream(String) 540: * @see RandomAccessFile#RandomAccessFile(String) 541: */ 542: public void checkRead(String filename) 543: { 544: checkPermission(new FilePermission(filename, "read")); 545: } 546: 547: /** 548: * Check if the current thread is allowed to read the given file. using the 549: * given security context. The context must be a result of a previous call 550: * to <code>getSecurityContext()</code>. The default implementation checks 551: * <code>AccessControlContext.checkPermission(new FilePermission(filename, 552: * "read"))</code>. If you override this, call <code>super.checkRead</code> 553: * rather than throwing an exception. 554: * 555: * @param filename the full name of the file to access 556: * @param context the context to determine access for 557: * @throws SecurityException if permission is denied, or if context is 558: * not an AccessControlContext 559: * @throws NullPointerException if filename is null 560: * @see #getSecurityContext() 561: * @see AccessControlContext#checkPermission(Permission) 562: */ 563: public void checkRead(String filename, Object context) 564: { 565: if (! (context instanceof AccessControlContext)) 566: throw new SecurityException("Missing context"); 567: AccessControlContext ac = (AccessControlContext) context; 568: ac.checkPermission(new FilePermission(filename, "read")); 569: } 570: 571: /** 572: * Check if the current thread is allowed to write the given file using the 573: * FileDescriptor. This method is called from 574: * FileOutputStream.FileOutputStream(). The default implementation checks 575: * <code>RuntimePermission("writeFileDescriptor")</code>. If you override 576: * this, call <code>super.checkWrite</code> rather than throwing an 577: * exception. 578: * 579: * @param desc the FileDescriptor representing the file to access 580: * @throws SecurityException if permission is denied 581: * @throws NullPointerException if desc is null 582: * @see FileOutputStream#FileOutputStream(FileDescriptor) 583: */ 584: public void checkWrite(FileDescriptor desc) 585: { 586: if (desc == null) 587: throw new NullPointerException(); 588: checkPermission(new RuntimePermission("writeFileDescriptor")); 589: } 590: 591: /** 592: * Check if the current thread is allowed to write the given file. This 593: * method is called from FileOutputStream.FileOutputStream(), 594: * RandomAccessFile.RandomAccessFile(), File.canWrite(), mkdir(), and 595: * renameTo(). The default implementation checks 596: * <code>FilePermission(filename, "write")</code>. If you override this, 597: * call <code>super.checkWrite</code> rather than throwing an exception. 598: * 599: * @param filename the full name of the file to access 600: * @throws SecurityException if permission is denied 601: * @throws NullPointerException if filename is null 602: * @see File 603: * @see File#canWrite() 604: * @see File#mkdir() 605: * @see File#renameTo() 606: * @see FileOutputStream#FileOutputStream(String) 607: * @see RandomAccessFile#RandomAccessFile(String) 608: */ 609: public void checkWrite(String filename) 610: { 611: checkPermission(new FilePermission(filename, "write")); 612: } 613: 614: /** 615: * Check if the current thread is allowed to delete the given file. This 616: * method is called from File.delete(). The default implementation checks 617: * <code>FilePermission(filename, "delete")</code>. If you override this, 618: * call <code>super.checkDelete</code> rather than throwing an exception. 619: * 620: * @param filename the full name of the file to delete 621: * @throws SecurityException if permission is denied 622: * @throws NullPointerException if filename is null 623: * @see File#delete() 624: */ 625: public void checkDelete(String filename) 626: { 627: checkPermission(new FilePermission(filename, "delete")); 628: } 629: 630: /** 631: * Check if the current thread is allowed to connect to a given host on a 632: * given port. This method is called from Socket.Socket(). A port number 633: * of -1 indicates the caller is attempting to determine an IP address, so 634: * the default implementation checks 635: * <code>SocketPermission(host, "resolve")</code>. Otherwise, the default 636: * implementation checks 637: * <code>SocketPermission(host + ":" + port, "connect")</code>. If you 638: * override this, call <code>super.checkConnect</code> rather than throwing 639: * an exception. 640: * 641: * @param host the host to connect to 642: * @param port the port to connect on 643: * @throws SecurityException if permission is denied 644: * @throws NullPointerException if host is null 645: * @see Socket#Socket() 646: */ 647: public void checkConnect(String host, int port) 648: { 649: if (port == -1) 650: checkPermission(new SocketPermission(host, "resolve")); 651: else 652: // Use the toString() hack to do the null check. 653: checkPermission(new SocketPermission(host.toString() + ":" + port, 654: "connect")); 655: } 656: 657: /** 658: * Check if the current thread is allowed to connect to a given host on a 659: * given port, using the given security context. The context must be a 660: * result of a previous call to <code>getSecurityContext</code>. A port 661: * number of -1 indicates the caller is attempting to determine an IP 662: * address, so the default implementation checks 663: * <code>AccessControlContext.checkPermission(new SocketPermission(host, 664: * "resolve"))</code>. Otherwise, the default implementation checks 665: * <code>AccessControlContext.checkPermission(new SocketPermission(host 666: * + ":" + port, "connect"))</code>. If you override this, call 667: * <code>super.checkConnect</code> rather than throwing an exception. 668: * 669: * @param host the host to connect to 670: * @param port the port to connect on 671: * @param context the context to determine access for 672: * 673: * @throws SecurityException if permission is denied, or if context is 674: * not an AccessControlContext 675: * @throws NullPointerException if host is null 676: * 677: * @see #getSecurityContext() 678: * @see AccessControlContext#checkPermission(Permission) 679: */ 680: public void checkConnect(String host, int port, Object context) 681: { 682: if (! (context instanceof AccessControlContext)) 683: throw new SecurityException("Missing context"); 684: AccessControlContext ac = (AccessControlContext) context; 685: if (port == -1) 686: ac.checkPermission(new SocketPermission(host, "resolve")); 687: else 688: // Use the toString() hack to do the null check. 689: ac.checkPermission(new SocketPermission(host.toString() + ":" + port, 690: "connect")); 691: } 692: 693: /** 694: * Check if the current thread is allowed to listen to a specific port for 695: * data. This method is called by ServerSocket.ServerSocket(). The default 696: * implementation checks 697: * <code>SocketPermission("localhost:" + (port == 0 ? "1024-" : "" + port), 698: * "listen")</code>. If you override this, call 699: * <code>super.checkListen</code> rather than throwing an exception. 700: * 701: * @param port the port to listen on 702: * @throws SecurityException if permission is denied 703: * @see ServerSocket#ServerSocket(int) 704: */ 705: public void checkListen(int port) 706: { 707: checkPermission(new SocketPermission("localhost:" 708: + (port == 0 ? "1024-" : "" +port), 709: "listen")); 710: } 711: 712: /** 713: * Check if the current thread is allowed to accept a connection from a 714: * particular host on a particular port. This method is called by 715: * ServerSocket.implAccept(). The default implementation checks 716: * <code>SocketPermission(host + ":" + port, "accept")</code>. If you 717: * override this, call <code>super.checkAccept</code> rather than throwing 718: * an exception. 719: * 720: * @param host the host which wishes to connect 721: * @param port the port the connection will be on 722: * @throws SecurityException if permission is denied 723: * @throws NullPointerException if host is null 724: * @see ServerSocket#accept() 725: */ 726: public void checkAccept(String host, int port) 727: { 728: // Use the toString() hack to do the null check. 729: checkPermission(new SocketPermission(host.toString() + ":" + port, 730: "accept")); 731: } 732: 733: /** 734: * Check if the current thread is allowed to read and write multicast to 735: * a particular address. The default implementation checks 736: * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>. 737: * If you override this, call <code>super.checkMulticast</code> rather than 738: * throwing an exception. 739: * 740: * @param addr the address to multicast to 741: * @throws SecurityException if permission is denied 742: * @throws NullPointerException if host is null 743: * @since 1.1 744: */ 745: public void checkMulticast(InetAddress addr) 746: { 747: checkPermission(new SocketPermission(addr.getHostAddress(), 748: "accept,connect")); 749: } 750: 751: /** 752: *Check if the current thread is allowed to read and write multicast to 753: * a particular address with a particular ttl (time-to-live) value. The 754: * default implementation ignores ttl, and checks 755: * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>. 756: * If you override this, call <code>super.checkMulticast</code> rather than 757: * throwing an exception. 758: * 759: * @param addr the address to multicast to 760: * @param ttl value in use for multicast send 761: * @throws SecurityException if permission is denied 762: * @throws NullPointerException if host is null 763: * @since 1.1 764: * @deprecated use {@link #checkPermission(Permission)} instead 765: */ 766: public void checkMulticast(InetAddress addr, byte ttl) 767: { 768: checkPermission(new SocketPermission(addr.getHostAddress(), 769: "accept,connect")); 770: } 771: 772: /** 773: * Check if the current thread is allowed to read or write all the system 774: * properties at once. This method is called by System.getProperties() 775: * and setProperties(). The default implementation checks 776: * <code>PropertyPermission("*", "read,write")</code>. If you override 777: * this, call <code>super.checkPropertiesAccess</code> rather than 778: * throwing an exception. 779: * 780: * @throws SecurityException if permission is denied 781: * @see System#getProperties() 782: * @see System#setProperties(Properties) 783: */ 784: public void checkPropertiesAccess() 785: { 786: checkPermission(new PropertyPermission("*", "read,write")); 787: } 788: 789: /** 790: * Check if the current thread is allowed to read a particular system 791: * property (writes are checked directly via checkPermission). This method 792: * is called by System.getProperty() and setProperty(). The default 793: * implementation checks <code>PropertyPermission(key, "read")</code>. If 794: * you override this, call <code>super.checkPropertyAccess</code> rather 795: * than throwing an exception. 796: * 797: * @param key the key of the property to check 798: * 799: * @throws SecurityException if permission is denied 800: * @throws NullPointerException if key is null 801: * @throws IllegalArgumentException if key is "" 802: * 803: * @see System#getProperty(String) 804: */ 805: public void checkPropertyAccess(String key) 806: { 807: checkPermission(new PropertyPermission(key, "read")); 808: } 809: 810: /** 811: * Check if the current thread is allowed to create a top-level window. If 812: * it is not, the operation should still go through, but some sort of 813: * nonremovable warning should be placed on the window to show that it 814: * is untrusted. This method is called by Window.Window(). The default 815: * implementation checks 816: * <code>AWTPermission("showWindowWithoutWarningBanner")</code>, and returns 817: * true if no exception was thrown. If you override this, use 818: * <code>return super.checkTopLevelWindow</code> rather than returning 819: * false. 820: * 821: * @param window the window to create 822: * @return true if there is permission to show the window without warning 823: * @throws NullPointerException if window is null 824: * @see Window#Window(Frame) 825: */ 826: public boolean checkTopLevelWindow(Object window) 827: { 828: if (window == null) 829: throw new NullPointerException(); 830: try 831: { 832: checkPermission(new AWTPermission("showWindowWithoutWarningBanner")); 833: return true; 834: } 835: catch (SecurityException e) 836: { 837: return false; 838: } 839: } 840: 841: /** 842: * Check if the current thread is allowed to create a print job. This 843: * method is called by Toolkit.getPrintJob(). The default implementation 844: * checks <code>RuntimePermission("queuePrintJob")</code>. If you override 845: * this, call <code>super.checkPrintJobAccess</code> rather than throwing 846: * an exception. 847: * 848: * @throws SecurityException if permission is denied 849: * @see Toolkit#getPrintJob(Frame, String, Properties) 850: * @since 1.1 851: */ 852: public void checkPrintJobAccess() 853: { 854: checkPermission(new RuntimePermission("queuePrintJob")); 855: } 856: 857: /** 858: * Check if the current thread is allowed to use the system clipboard. This 859: * method is called by Toolkit.getSystemClipboard(). The default 860: * implementation checks <code>AWTPermission("accessClipboard")</code>. If 861: * you override this, call <code>super.checkSystemClipboardAccess</code> 862: * rather than throwing an exception. 863: * 864: * @throws SecurityException if permission is denied 865: * @see Toolkit#getSystemClipboard() 866: * @since 1.1 867: */ 868: public void checkSystemClipboardAccess() 869: { 870: checkPermission(new AWTPermission("accessClipboard")); 871: } 872: 873: /** 874: * Check if the current thread is allowed to use the AWT event queue. This 875: * method is called by Toolkit.getSystemEventQueue(). The default 876: * implementation checks <code>AWTPermission("accessEventQueue")</code>. 877: * you override this, call <code>super.checkAwtEventQueueAccess</code> 878: * rather than throwing an exception. 879: * 880: * @throws SecurityException if permission is denied 881: * @see Toolkit#getSystemEventQueue() 882: * @since 1.1 883: */ 884: public void checkAwtEventQueueAccess() 885: { 886: checkPermission(new AWTPermission("accessEventQueue")); 887: } 888: 889: /** 890: * Check if the current thread is allowed to access the specified package 891: * at all. This method is called by ClassLoader.loadClass() in user-created 892: * ClassLoaders. The default implementation gets a list of all restricted 893: * packages, via <code>Security.getProperty("package.access")</code>. Then, 894: * if packageName starts with or equals any restricted package, it checks 895: * <code>RuntimePermission("accessClassInPackage." + packageName)</code>. 896: * If you override this, you should call 897: * <code>super.checkPackageAccess</code> before doing anything else. 898: * 899: * @param packageName the package name to check access to 900: * @throws SecurityException if permission is denied 901: * @throws NullPointerException if packageName is null 902: * @see ClassLoader#loadClass(String, boolean) 903: * @see Security#getProperty(String) 904: */ 905: public void checkPackageAccess(String packageName) 906: { 907: checkPackageList(packageName, "package.access", "accessClassInPackage."); 908: } 909: 910: /** 911: * Check if the current thread is allowed to define a class into the 912: * specified package. This method is called by ClassLoader.loadClass() in 913: * user-created ClassLoaders. The default implementation gets a list of all 914: * restricted packages, via 915: * <code>Security.getProperty("package.definition")</code>. Then, if 916: * packageName starts with or equals any restricted package, it checks 917: * <code>RuntimePermission("defineClassInPackage." + packageName)</code>. 918: * If you override this, you should call 919: * <code>super.checkPackageDefinition</code> before doing anything else. 920: * 921: * @param packageName the package name to check access to 922: * @throws SecurityException if permission is denied 923: * @throws NullPointerException if packageName is null 924: * @see ClassLoader#loadClass(String, boolean) 925: * @see Security#getProperty(String) 926: */ 927: public void checkPackageDefinition(String packageName) 928: { 929: checkPackageList(packageName, "package.definition", "defineClassInPackage."); 930: } 931: 932: /** 933: * Check if the current thread is allowed to set the current socket factory. 934: * This method is called by Socket.setSocketImplFactory(), 935: * ServerSocket.setSocketFactory(), and URL.setURLStreamHandlerFactory(). 936: * The default implementation checks 937: * <code>RuntimePermission("setFactory")</code>. If you override this, call 938: * <code>super.checkSetFactory</code> rather than throwing an exception. 939: * 940: * @throws SecurityException if permission is denied 941: * @see Socket#setSocketImplFactory(SocketImplFactory) 942: * @see ServerSocket#setSocketFactory(SocketImplFactory) 943: * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory) 944: */ 945: public void checkSetFactory() 946: { 947: checkPermission(new RuntimePermission("setFactory")); 948: } 949: 950: /** 951: * Check if the current thread is allowed to get certain types of Methods, 952: * Fields and Constructors from a Class object. This method is called by 953: * Class.getMethod[s](), Class.getField[s](), Class.getConstructor[s], 954: * Class.getDeclaredMethod[s](), Class.getDeclaredField[s](), and 955: * Class.getDeclaredConstructor[s](). The default implementation allows 956: * PUBLIC access, and access to classes defined by the same classloader as 957: * the code performing the reflection. Otherwise, it checks 958: * <code>RuntimePermission("accessDeclaredMembers")</code>. If you override 959: * this, do not call <code>super.checkMemberAccess</code>, as this would 960: * mess up the stack depth check that determines the ClassLoader requesting 961: * the access. 962: * 963: * @param c the Class to check 964: * @param memberType either DECLARED or PUBLIC 965: * @throws SecurityException if permission is denied, including when 966: * memberType is not DECLARED or PUBLIC 967: * @throws NullPointerException if c is null 968: * @see Class 969: * @see Member#DECLARED 970: * @see Member#PUBLIC 971: * @since 1.1 972: */ 973: public void checkMemberAccess(Class c, int memberType) 974: { 975: if (c == null) 976: throw new NullPointerException(); 977: if (memberType == Member.PUBLIC) 978: return; 979: // XXX Allow access to classes created by same classloader before next 980: // check. 981: checkPermission(new RuntimePermission("accessDeclaredMembers")); 982: } 983: 984: /** 985: * Test whether a particular security action may be taken. The default 986: * implementation checks <code>SecurityPermission(action)</code>. If you 987: * override this, call <code>super.checkSecurityAccess</code> rather than 988: * throwing an exception. 989: * 990: * @param action the desired action to take 991: * @throws SecurityException if permission is denied 992: * @throws NullPointerException if action is null 993: * @throws IllegalArgumentException if action is "" 994: * @since 1.1 995: */ 996: public void checkSecurityAccess(String action) 997: { 998: checkPermission(new SecurityPermission(action)); 999: } 1000: 1001: /** 1002: * Get the ThreadGroup that a new Thread should belong to by default. Called 1003: * by Thread.Thread(). The default implementation returns the current 1004: * ThreadGroup of the current Thread. <STRONG>Spec Note:</STRONG> it is not 1005: * clear whether the new Thread is guaranteed to pass the 1006: * checkAccessThreadGroup() test when using this ThreadGroup, but I presume 1007: * so. 1008: * 1009: * @return the ThreadGroup to put the new Thread into 1010: * @since 1.1 1011: */ 1012: public ThreadGroup getThreadGroup() 1013: { 1014: return Thread.currentThread().getThreadGroup(); 1015: } 1016: 1017: /** 1018: * Helper that checks a comma-separated list of restricted packages, from 1019: * <code>Security.getProperty("package.definition")</code>, for the given 1020: * package access permission. If packageName starts with or equals any 1021: * restricted package, it checks 1022: * <code>RuntimePermission(permission + packageName)</code>. 1023: * 1024: * @param packageName the package name to check access to 1025: * @param restriction "package.access" or "package.definition" 1026: * @param permission the base permission, including the '.' 1027: * @throws SecurityException if permission is denied 1028: * @throws NullPointerException if packageName is null 1029: * @see #checkPackageAccess(String) 1030: * @see #checkPackageDefinition(String) 1031: */ 1032: void checkPackageList(String packageName, final String restriction, 1033: String permission) 1034: { 1035: if (packageName == null) 1036: throw new NullPointerException(); 1037: 1038: String list = (String)AccessController.doPrivileged(new PrivilegedAction() 1039: { 1040: public Object run() 1041: { 1042: return Security.getProperty(restriction); 1043: } 1044: }); 1045: 1046: if (list == null || list.equals("")) 1047: return; 1048: 1049: String packageNamePlusDot = packageName + "."; 1050: 1051: StringTokenizer st = new StringTokenizer(list, ","); 1052: while (st.hasMoreTokens()) 1053: { 1054: if (packageNamePlusDot.startsWith(st.nextToken())) 1055: { 1056: Permission p = new RuntimePermission(permission + packageName); 1057: checkPermission(p); 1058: return; 1059: } 1060: } 1061: } 1062: }
GNU Classpath (0.17) |