38 |
|
|
39 |
package java.lang; |
package java.lang; |
40 |
|
|
41 |
|
import java.awt.AWTPermission; |
42 |
|
import java.io.File; |
43 |
import java.io.FileDescriptor; |
import java.io.FileDescriptor; |
44 |
|
import java.io.FilePermission; |
45 |
|
import java.lang.reflect.Member; |
46 |
import java.net.InetAddress; |
import java.net.InetAddress; |
47 |
|
import java.net.SocketPermission; |
48 |
|
import java.security.AllPermission; |
49 |
import java.security.Permission; |
import java.security.Permission; |
50 |
|
import java.security.Security; |
51 |
import java.security.SecurityPermission; |
import java.security.SecurityPermission; |
52 |
|
import java.util.PropertyPermission; |
53 |
|
|
54 |
/** |
/** |
55 |
* SecurityManager is a class you can extend to create your own Java |
* SecurityManager is a class you can extend to create your own Java |
63 |
* <pre> |
* <pre> |
64 |
* SecurityManager sm = System.getSecurityManager(); |
* SecurityManager sm = System.getSecurityManager(); |
65 |
* if (sm != null) |
* if (sm != null) |
66 |
* sm.checkXXX(<em>argument</em>, ...); |
* sm.checkABC(<em>argument</em>, ...); |
67 |
* </pre> |
* </pre> |
68 |
* Note that this is thread-safe, by caching the security manager in a local |
* Note that this is thread-safe, by caching the security manager in a local |
69 |
* variable rather than risking a NullPointerException if the mangager is |
* variable rather than risking a NullPointerException if the mangager is |
187 |
*/ |
*/ |
188 |
protected ClassLoader currentClassLoader() |
protected ClassLoader currentClassLoader() |
189 |
{ |
{ |
190 |
// XXX should be: |
Class c = currentLoadedClass(); |
191 |
// Class c = currentLoadedClass(); |
return c != null ? c.getClassLoader() : null; |
|
// return c != null ? c.getClassLoader() : null; |
|
|
return VMSecurityManager.currentClassLoader(); |
|
192 |
} |
} |
193 |
|
|
194 |
/** |
/** |
208 |
*/ |
*/ |
209 |
protected Class currentLoadedClass() |
protected Class currentLoadedClass() |
210 |
{ |
{ |
211 |
// XXX Should be: |
int i = classLoaderDepth(); |
212 |
// int i = classLoaderDepth(); |
return i >= 0 ? getClassContext()[i] : null; |
|
// return i >= 0 ? getClassContext(i) : null; |
|
|
Class[] c = getClassContext(); |
|
|
for (int i = 0; i < c.length; i++) |
|
|
if (c[i].getClassLoader() != null) |
|
|
return c[i]; |
|
|
return null; |
|
213 |
} |
} |
214 |
|
|
215 |
/** |
/** |
245 |
*/ |
*/ |
246 |
protected int classLoaderDepth() |
protected int classLoaderDepth() |
247 |
{ |
{ |
248 |
// XXX Check AllPermission first. |
try |
249 |
Class[] c = getClassContext(); |
{ |
250 |
for (int i = 0; i <c.length; i++) |
checkPermission(new AllPermission()); |
251 |
if (c[i].getClassLoader() != null) |
} |
252 |
// XXX Check if c[i] is AccessController, or a system class. |
catch (SecurityException e) |
253 |
return i; |
{ |
254 |
|
Class[] c = getClassContext(); |
255 |
|
for (int i = 0; i < c.length; i++) |
256 |
|
if (c[i].getClassLoader() != null) |
257 |
|
// XXX Check if c[i] is AccessController, or a system class. |
258 |
|
return i; |
259 |
|
} |
260 |
return -1; |
return -1; |
261 |
} |
} |
262 |
|
|
344 |
// if (! (context instanceof AccessControlContext)) |
// if (! (context instanceof AccessControlContext)) |
345 |
// throw new SecurityException("Missing context"); |
// throw new SecurityException("Missing context"); |
346 |
// ((AccessControlContext) context).checkPermission(perm); |
// ((AccessControlContext) context).checkPermission(perm); |
|
|
|
347 |
throw new SecurityException("Operation not allowed"); |
throw new SecurityException("Operation not allowed"); |
348 |
} |
} |
349 |
|
|
359 |
*/ |
*/ |
360 |
public void checkCreateClassLoader() |
public void checkCreateClassLoader() |
361 |
{ |
{ |
362 |
// XXX Should be: |
checkPermission(new RuntimePermission("createClassLoader")); |
|
// checkPermission(new RuntimePermission("createClassLoader")); |
|
|
throw new SecurityException("Cannot create new ClassLoaders."); |
|
363 |
} |
} |
364 |
|
|
365 |
/** |
/** |
388 |
*/ |
*/ |
389 |
public void checkAccess(Thread t) |
public void checkAccess(Thread t) |
390 |
{ |
{ |
391 |
// XXX Implement this correctly. |
if (t.group != null && t.group.getParent() != null) |
392 |
throw new SecurityException("Cannot modify Threads."); |
checkPermission(new RuntimePermission("modifyThread")); |
393 |
} |
} |
394 |
|
|
395 |
/** |
/** |
407 |
* <code>RuntimePermission("modifyThreadGroup")</code>, return silently, |
* <code>RuntimePermission("modifyThreadGroup")</code>, return silently, |
408 |
* so that core classes (the Classpath library!) can modify any thread. |
* so that core classes (the Classpath library!) can modify any thread. |
409 |
* |
* |
410 |
* @param t the other Thread to check |
* @param g the ThreadGroup to check |
411 |
* @throws SecurityException if permission is denied |
* @throws SecurityException if permission is denied |
412 |
* @throws NullPointerException if t is null |
* @throws NullPointerException if g is null |
413 |
* @see Thread#Thread() |
* @see Thread#Thread() |
414 |
* @see ThreadGroup#ThreadGroup() |
* @see ThreadGroup#ThreadGroup() |
415 |
* @see ThreadGroup#stop() |
* @see ThreadGroup#stop() |
421 |
*/ |
*/ |
422 |
public void checkAccess(ThreadGroup g) |
public void checkAccess(ThreadGroup g) |
423 |
{ |
{ |
424 |
// XXX Implement this correctly. |
if (g.getParent() != null) |
425 |
throw new SecurityException("Cannot modify ThreadGroups."); |
checkPermission(new RuntimePermission("modifyThreadGroup")); |
426 |
} |
} |
427 |
|
|
428 |
/** |
/** |
439 |
*/ |
*/ |
440 |
public void checkExit(int status) |
public void checkExit(int status) |
441 |
{ |
{ |
442 |
// XXX Should be: checkPermission(new RuntimePermission("exitVM")); |
checkPermission(new RuntimePermission("exitVM")); |
|
throw new SecurityException("Cannot exit JVM."); |
|
443 |
} |
} |
444 |
|
|
445 |
/** |
/** |
458 |
*/ |
*/ |
459 |
public void checkExec(String program) |
public void checkExec(String program) |
460 |
{ |
{ |
461 |
// XXX Implement this correctly. |
if (! program.equals(new File(program).getAbsolutePath())) |
462 |
throw new SecurityException("Cannot execute programs."); |
program = "<<ALL FILES>>"; |
463 |
|
checkPermission(new FilePermission(program, "execute")); |
464 |
} |
} |
465 |
|
|
466 |
/** |
/** |
479 |
public void checkLink(String filename) |
public void checkLink(String filename) |
480 |
{ |
{ |
481 |
// Use the toString() hack to do the null check. |
// Use the toString() hack to do the null check. |
482 |
// XXX Should be: |
checkPermission(new RuntimePermission("loadLibrary." |
483 |
// checkPermission(new RuntimePermission("loadLibrary." |
+ filename.toString())); |
|
// + filename.toString())); |
|
|
throw new SecurityException("Cannot link native libraries."); |
|
484 |
} |
} |
485 |
|
|
486 |
/** |
/** |
498 |
*/ |
*/ |
499 |
public void checkRead(FileDescriptor desc) |
public void checkRead(FileDescriptor desc) |
500 |
{ |
{ |
501 |
// XXX Should be: |
if (desc == null) |
502 |
// checkPermission(new RuntimePermission("readFileDescriptor")); |
throw new NullPointerException(); |
503 |
throw new SecurityException("Cannot read files via file descriptors."); |
checkPermission(new RuntimePermission("readFileDescriptor")); |
504 |
} |
} |
505 |
|
|
506 |
/** |
/** |
521 |
*/ |
*/ |
522 |
public void checkRead(String filename) |
public void checkRead(String filename) |
523 |
{ |
{ |
524 |
// XXX Should be: checkPermission(new FilePermission(filename, "read")); |
checkPermission(new FilePermission(filename, "read")); |
|
throw new SecurityException("Cannot read files via file names."); |
|
525 |
} |
} |
526 |
|
|
527 |
/** |
/** |
565 |
*/ |
*/ |
566 |
public void checkWrite(FileDescriptor desc) |
public void checkWrite(FileDescriptor desc) |
567 |
{ |
{ |
568 |
// XXX Should be: |
if (desc == null) |
569 |
// checkPermission(new RuntimePermission("writeFileDescriptor")); |
throw new NullPointerException(); |
570 |
throw new SecurityException("Cannot write files via file descriptors."); |
checkPermission(new RuntimePermission("writeFileDescriptor")); |
571 |
} |
} |
572 |
|
|
573 |
/** |
/** |
590 |
*/ |
*/ |
591 |
public void checkWrite(String filename) |
public void checkWrite(String filename) |
592 |
{ |
{ |
593 |
// XXX Should be: checkPermission(new FilePermission(filename, "write")); |
checkPermission(new FilePermission(filename, "write")); |
|
throw new SecurityException("Cannot write files via file names."); |
|
594 |
} |
} |
595 |
|
|
596 |
/** |
/** |
606 |
*/ |
*/ |
607 |
public void checkDelete(String filename) |
public void checkDelete(String filename) |
608 |
{ |
{ |
609 |
// XXX Should be: checkPermission(new FilePermission(filename, "delete")); |
checkPermission(new FilePermission(filename, "delete")); |
|
throw new SecurityException("Cannot delete files."); |
|
610 |
} |
} |
611 |
|
|
612 |
/** |
/** |
628 |
*/ |
*/ |
629 |
public void checkConnect(String host, int port) |
public void checkConnect(String host, int port) |
630 |
{ |
{ |
631 |
// XXX Should be: |
if (port == -1) |
632 |
// if (port == -1) |
checkPermission(new SocketPermission(host, "resolve")); |
633 |
// checkPermission(new SocketPermission(host, "resolve")); |
else |
634 |
// else |
// Use the toString() hack to do the null check. |
635 |
// checkPermission(new SocketPermission(host + ":" + port, "connect")); |
checkPermission(new SocketPermission(host.toString() + ":" + port, |
636 |
throw new SecurityException("Cannot make network connections."); |
"connect")); |
637 |
} |
} |
638 |
|
|
639 |
/** |
/** |
666 |
// if (port == -1) |
// if (port == -1) |
667 |
// ac.checkPermission(new SocketPermission(host, "resolve")); |
// ac.checkPermission(new SocketPermission(host, "resolve")); |
668 |
// else |
// else |
669 |
// ac.checkPermission(new SocketPermission(host + ":" +port, "connect")); |
// // Use the toString() hack to do the null check. |
670 |
|
// ac.checkPermission(new SocketPermission(host.toString + ":" +port, |
671 |
|
// "connect")); |
672 |
throw new SecurityException("Cannot make network connections."); |
throw new SecurityException("Cannot make network connections."); |
673 |
} |
} |
674 |
|
|
686 |
*/ |
*/ |
687 |
public void checkListen(int port) |
public void checkListen(int port) |
688 |
{ |
{ |
689 |
// XXX Should be: |
checkPermission(new SocketPermission("localhost:" |
690 |
// checkPermission(new SocketPermission("localhost:" |
+ (port == 0 ? "1024-" : "" +port), |
691 |
// + (port == 0 ? "1024-" : "" +port), |
"listen")); |
|
// "listen")); |
|
|
throw new SecurityException("Cannot listen for connections."); |
|
692 |
} |
} |
693 |
|
|
694 |
/** |
/** |
708 |
public void checkAccept(String host, int port) |
public void checkAccept(String host, int port) |
709 |
{ |
{ |
710 |
// Use the toString() hack to do the null check. |
// Use the toString() hack to do the null check. |
711 |
// XXX Should be: |
checkPermission(new SocketPermission(host.toString() + ":" + port, |
712 |
// checkPermission(new SocketPermission(host.toString() + ":" + port, |
"accept")); |
|
// "accept")); |
|
|
throw new SecurityException("Cannot accept connections."); |
|
713 |
} |
} |
714 |
|
|
715 |
/** |
/** |
726 |
*/ |
*/ |
727 |
public void checkMulticast(InetAddress addr) |
public void checkMulticast(InetAddress addr) |
728 |
{ |
{ |
729 |
// XXX Should be: |
checkPermission(new SocketPermission(addr.getHostAddress(), |
730 |
// checkPermission(new SocketPermission(addr.getHostAddress(), |
"accept,connect")); |
|
// "accept,connect")); |
|
|
throw new SecurityException("Cannot read or write multicast."); |
|
731 |
} |
} |
732 |
|
|
733 |
/** |
/** |
747 |
*/ |
*/ |
748 |
public void checkMulticast(InetAddress addr, byte ttl) |
public void checkMulticast(InetAddress addr, byte ttl) |
749 |
{ |
{ |
750 |
// XXX Should be: |
checkPermission(new SocketPermission(addr.getHostAddress(), |
751 |
// checkPermission(new SocketPermission(addr.getHostAddress(), |
"accept,connect")); |
|
// "accept,connect")); |
|
|
throw new SecurityException("Cannot read or write multicast."); |
|
752 |
} |
} |
753 |
|
|
754 |
/** |
/** |
765 |
*/ |
*/ |
766 |
public void checkPropertiesAccess() |
public void checkPropertiesAccess() |
767 |
{ |
{ |
768 |
// XXX Should be: |
checkPermission(new PropertyPermission("*", "read,write")); |
|
// checkPermission(new PropertyPermission("*", "read,write")); |
|
|
throw new SecurityException("Cannot access all system properties at once."); |
|
769 |
} |
} |
770 |
|
|
771 |
/** |
/** |
783 |
*/ |
*/ |
784 |
public void checkPropertyAccess(String key) |
public void checkPropertyAccess(String key) |
785 |
{ |
{ |
786 |
// XXX Should be: checkPermission(new PropertyPermission(key, "read")); |
checkPermission(new PropertyPermission(key, "read")); |
|
throw new SecurityException("Cannot access individual system properties."); |
|
787 |
} |
} |
788 |
|
|
789 |
/** |
/** |
804 |
*/ |
*/ |
805 |
public boolean checkTopLevelWindow(Object window) |
public boolean checkTopLevelWindow(Object window) |
806 |
{ |
{ |
807 |
// Should be: |
if (window == null) |
808 |
// if (window == null) |
throw new NullPointerException(); |
809 |
// throw new NullPointerException(); |
try |
810 |
// try |
{ |
811 |
// { |
checkPermission(new AWTPermission("showWindowWithoutWarningBanner")); |
812 |
// checkPermission(new AWTPermission("showWindowWithoutWarningBanner")); |
return true; |
813 |
// return true; |
} |
814 |
// } |
catch (SecurityException e) |
815 |
// catch (SecurityException e) |
{ |
816 |
// { |
return false; |
817 |
// return false; |
} |
|
// } |
|
|
return false; |
|
818 |
} |
} |
819 |
|
|
820 |
/** |
/** |
830 |
*/ |
*/ |
831 |
public void checkPrintJobAccess() |
public void checkPrintJobAccess() |
832 |
{ |
{ |
833 |
// XXX Should be: checkPermission(new RuntimePermission("queuePrintJob")); |
checkPermission(new RuntimePermission("queuePrintJob")); |
|
throw new SecurityException("Cannot create print jobs."); |
|
834 |
} |
} |
835 |
|
|
836 |
/** |
/** |
846 |
*/ |
*/ |
847 |
public void checkSystemClipboardAccess() |
public void checkSystemClipboardAccess() |
848 |
{ |
{ |
849 |
// XXX Should be: checkPermission(new AWTPermission("accessClipboard")); |
checkPermission(new AWTPermission("accessClipboard")); |
|
throw new SecurityException("Cannot access the system clipboard."); |
|
850 |
} |
} |
851 |
|
|
852 |
/** |
/** |
884 |
*/ |
*/ |
885 |
public void checkPackageAccess(String packageName) |
public void checkPackageAccess(String packageName) |
886 |
{ |
{ |
887 |
// XXX Implement this. |
checkPackageList(packageName, "access", "accessClassInPackage."); |
|
throw new SecurityException("Cannot access packages via the ClassLoader."); |
|
888 |
} |
} |
889 |
|
|
890 |
/** |
/** |
906 |
*/ |
*/ |
907 |
public void checkPackageDefinition(String packageName) |
public void checkPackageDefinition(String packageName) |
908 |
{ |
{ |
909 |
// XXX Implement this. |
checkPackageList(packageName, "definition", "defineClassInPackage."); |
|
throw new SecurityException("Cannot load classes into any packages via the ClassLoader."); |
|
910 |
} |
} |
911 |
|
|
912 |
/** |
/** |
924 |
*/ |
*/ |
925 |
public void checkSetFactory() |
public void checkSetFactory() |
926 |
{ |
{ |
927 |
// XXX Should be: checkPermission(new RuntimePermission("setFactory")); |
checkPermission(new RuntimePermission("setFactory")); |
|
throw new SecurityException("Cannot set the socket factory."); |
|
928 |
} |
} |
929 |
|
|
930 |
/** |
/** |
952 |
*/ |
*/ |
953 |
public void checkMemberAccess(Class c, int memberType) |
public void checkMemberAccess(Class c, int memberType) |
954 |
{ |
{ |
955 |
// XXX Implement this. |
if (c == null) |
956 |
throw new SecurityException("Cannot access members of classes."); |
throw new NullPointerException(); |
957 |
|
if (memberType == Member.PUBLIC) |
958 |
|
return; |
959 |
|
// XXX Allow access to classes created by same classloader before next |
960 |
|
// check. |
961 |
|
checkPermission(new RuntimePermission("accessDeclaredMembers")); |
962 |
} |
} |
963 |
|
|
964 |
/** |
/** |
993 |
{ |
{ |
994 |
return Thread.currentThread().getThreadGroup(); |
return Thread.currentThread().getThreadGroup(); |
995 |
} |
} |
996 |
|
|
997 |
|
/** |
998 |
|
* Helper that checks a comma-separated list of restricted packages, from |
999 |
|
* <code>Security.getProperty("package.definition")</code>, for the given |
1000 |
|
* package access permission. If packageName starts with or equals any |
1001 |
|
* restricted package, it checks |
1002 |
|
* <code>RuntimePermission(permission + packageName)</code>. |
1003 |
|
* |
1004 |
|
* @param packageName the package name to check access to |
1005 |
|
* @param restriction the list of restrictions, after "package." |
1006 |
|
* @param permission the base permission, including the '.' |
1007 |
|
* @throws SecurityException if permission is denied |
1008 |
|
* @throws NullPointerException if packageName is null |
1009 |
|
* @see #checkPackageAccess(String) |
1010 |
|
* @see #checkPackageDefinition(String) |
1011 |
|
*/ |
1012 |
|
void checkPackageList(String packageName, String restriction, |
1013 |
|
String permission) |
1014 |
|
{ |
1015 |
|
// Use the toString() hack to do the null check. |
1016 |
|
Permission p = new RuntimePermission(permission + packageName.toString()); |
1017 |
|
String list = Security.getProperty("package." + restriction); |
1018 |
|
if (list == null) |
1019 |
|
return; |
1020 |
|
while (! "".equals(packageName)) |
1021 |
|
{ |
1022 |
|
for (int index = list.indexOf(packageName); |
1023 |
|
index != -1; index = list.indexOf(packageName, index + 1)) |
1024 |
|
{ |
1025 |
|
// Exploit package visibility for speed. |
1026 |
|
if (index + packageName.count == list.count |
1027 |
|
|| list.charAt(index + packageName.count) == ',') |
1028 |
|
{ |
1029 |
|
checkPermission(p); |
1030 |
|
return; |
1031 |
|
} |
1032 |
|
} |
1033 |
|
int index = packageName.lastIndexOf('.'); |
1034 |
|
packageName = index < 0 ? "" : packageName.substring(0, index); |
1035 |
|
} |
1036 |
|
} |
1037 |
} // class SecurityManager |
} // class SecurityManager |
1038 |
|
|
1039 |
// XXX This class is unnecessary. |
// XXX This class is unnecessary. |