--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6866804 7006126
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+ static class Checks {
+ private List<Permission> permissionsChecked = new ArrayList<>();
+ private Set<String> propertiesChecked = new HashSet<>();
+ private List<String> readsChecked = new ArrayList<>();
+ private List<String> writesChecked = new ArrayList<>();
+ private List<String> deletesChecked = new ArrayList<>();
+ private List<String> execsChecked = new ArrayList<>();
+
+ List<Permission> permissionsChecked() { return permissionsChecked; }
+ Set<String> propertiesChecked() { return propertiesChecked; }
+ List<String> readsChecked() { return readsChecked; }
+ List<String> writesChecked() { return writesChecked; }
+ List<String> deletesChecked() { return deletesChecked; }
+ List<String> execsChecked() { return execsChecked; }
+ }
+
+ static ThreadLocal<Checks> myChecks =
+ new ThreadLocal<Checks>() {
+ @Override protected Checks initialValue() {
+ return null;
+ }
+ };
+
+ static void prepare() {
+ myChecks.set(new Checks());
+ }
+
+ static void assertCheckPermission(Class<? extends Permission> type,
+ String name)
+ {
+ for (Permission perm: myChecks.get().permissionsChecked()) {
+ if (type.isInstance(perm) && perm.getName().equals(name))
+ return;
+ }
+ throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked");
+ }
+
+ static void assertCheckPropertyAccess(String key) {
+ if (!myChecks.get().propertiesChecked().contains(key))
+ throw new RuntimeException("Property " + key + " not checked");
+ }
+
+ static void assertChecked(Path file, List<String> list) {
+ String s = file.toString();
+ for (String f: list) {
+ if (f.endsWith(s))
+ return;
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckRead(Path file) {
+ assertChecked(file, myChecks.get().readsChecked());
+ }
+
+ static void assertCheckWrite(Path file) {
+ assertChecked(file, myChecks.get().writesChecked());
+ }
+
+ static void assertCheckWriteToDirectory(Path dir) {
+ String s = dir.toString();
+ List<String> list = myChecks.get().writesChecked();
+ for (String f: list) {
+ if (f.startsWith(s)) {
+ return;
+ }
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckDelete(Path file) {
+ assertChecked(file, myChecks.get().deletesChecked());
+ }
+
+ static void assertCheckExec(Path file) {
+ assertChecked(file, myChecks.get().execsChecked());
+ }
+
+ static class LoggingSecurityManager extends SecurityManager {
+ static void install() {
+ System.setSecurityManager(new LoggingSecurityManager());
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.permissionsChecked().add(perm);
+ }
+
+ @Override
+ public void checkPropertyAccess(String key) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.propertiesChecked().add(key);
+ }
+
+ @Override
+ public void checkRead(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.readsChecked().add(file);
+ }
+
+ @Override
+ public void checkWrite(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.writesChecked().add(file);
+ }
+
+ @Override
+ public void checkDelete(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.deletesChecked().add(file);
+ }
+
+ @Override
+ public void checkExec(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.execsChecked().add(file);
+ }
+ }
+
+ static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ view.setTimes(null, now, now);
+ assertCheckWrite(file);
+ }
+
+ static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ PosixFileAttributes attrs = view.readAttributes();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setPermissions(attrs.permissions());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ }
+
+ public static void main(String[] args) throws IOException {
+ final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath();
+ final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+
+ Path file = createFile(testdir.resolve("file1234"));
+ try {
+ LoggingSecurityManager.install();
+
+ // -- check access --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ isReadable(file);
+ assertCheckRead(file);
+
+ prepare();
+ isWritable(file);
+ assertCheckWrite(file);
+
+ prepare();
+ isExecutable(file);
+ assertCheckExec(file);
+
+ // -- copy --
+
+ Path target = testdir.resolve("target1234");
+ prepare();
+ copy(file, target);
+ try {
+ assertCheckRead(file);
+ assertCheckWrite(target);
+ } finally {
+ delete(target);
+ }
+
+ if (TestUtil.supportsLinks(testdir)) {
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ prepare();
+ copy(link, target, LinkOption.NOFOLLOW_LINKS);
+ try {
+ assertCheckRead(link);
+ assertCheckWrite(target);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(target);
+ }
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createDirectory --
+
+ Path subdir = testdir.resolve("subdir1234");
+ prepare();
+ createDirectory(subdir);
+ try {
+ assertCheckWrite(subdir);
+ } finally {
+ delete(subdir);
+ }
+
+ // -- createFile --
+
+ Path fileToCreate = testdir.resolve("file7890");
+ prepare();
+ createFile(fileToCreate);
+ try {
+ assertCheckWrite(fileToCreate);
+ } finally {
+ delete(fileToCreate);
+ }
+
+ // -- createSymbolicLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("link1234");
+ createSymbolicLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createLink --
+
+ if (TestUtil.supportsLinks(testdir)) {
+ prepare();
+ Path link = testdir.resolve("entry234");
+ createLink(link, file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "hard");
+ } finally {
+ delete(link);
+ }
+ }
+
+ // -- createTempFile --
+
+ prepare();
+ Path tmpfile1 = createTempFile("foo", null);
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpfile1);
+ }
+ prepare();
+ Path tmpfile2 = createTempFile(testdir, "foo", ".tmp");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpfile2);
+ }
+
+ // -- createTempDirectory --
+
+ prepare();
+ Path tmpdir1 = createTempDirectory("foo");
+ try {
+ assertCheckWriteToDirectory(tmpdir);
+ } finally {
+ delete(tmpdir1);
+ }
+ prepare();
+ Path tmpdir2 = createTempDirectory(testdir, "foo");
+ try {
+ assertCheckWriteToDirectory(testdir);
+ } finally {
+ delete(tmpdir2);
+ }
+
+ // -- delete/deleteIfExists --
+
+ Path fileToDelete = testdir.resolve("file7890");
+
+ createFile(fileToDelete);
+ prepare();
+ delete(fileToDelete);
+ assertCheckDelete(fileToDelete);
+
+ createFile(fileToDelete);
+ prepare();
+ deleteIfExists(fileToDelete); // file exists
+ assertCheckDelete(fileToDelete);
+
+ prepare();
+ deleteIfExists(fileToDelete); // file does not exist
+ assertCheckDelete(fileToDelete);
+
+ // -- exists/notExists --
+
+ prepare();
+ exists(file);
+ assertCheckRead(file);
+
+ prepare();
+ notExists(file);
+ assertCheckRead(file);
+
+ // -- getFileStore --
+
+ prepare();
+ getFileStore(file);
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+ // -- isSameFile --
+
+ prepare();
+ isSameFile(file, testdir);
+ assertCheckRead(file);
+ assertCheckRead(testdir);
+
+ // -- move --
+
+ Path target2 = testdir.resolve("target1234");
+ prepare();
+ move(file, target2);
+ try {
+ assertCheckWrite(file);
+ assertCheckWrite(target2);
+ } finally {
+ // restore file
+ move(target2, file);
+ }
+
+ // -- newByteChannel --
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) {
+ assertCheckWrite(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) {
+ assertCheckRead(file);
+ assertCheckWrite(file);
+ }
+
+ prepare();
+ try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) {
+ assertCheckRead(file);
+ assertCheckDelete(file);
+ }
+ createFile(file); // restore file
+
+
+ // -- newInputStream/newOutptuStream --
+
+ prepare();
+ try (InputStream in = newInputStream(file)) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (OutputStream out = newOutputStream(file)) {
+ assertCheckWrite(file);
+ }
+
+ // -- newDirectoryStream --
+
+ prepare();
+ try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) {
+ assertCheckRead(testdir);
+
+ if (stream instanceof SecureDirectoryStream<?>) {
+ Path entry;
+ SecureDirectoryStream<Path> sds =
+ (SecureDirectoryStream<Path>)stream;
+
+ // newByteChannel
+ entry = file.getFileName();
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) {
+ assertCheckRead(file);
+ }
+ prepare();
+ try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) {
+ assertCheckWrite(file);
+ }
+
+ // deleteFile
+ entry = file.getFileName();
+ prepare();
+ sds.deleteFile(entry);
+ assertCheckDelete(file);
+ createFile(testdir.resolve(entry)); // restore file
+
+ // deleteDirectory
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ prepare();
+ sds.deleteDirectory(entry);
+ assertCheckDelete(testdir.resolve(entry));
+
+ // move
+ entry = Paths.get("tempname1234");
+ prepare();
+ sds.move(file.getFileName(), sds, entry);
+ assertCheckWrite(file);
+ assertCheckWrite(testdir.resolve(entry));
+ sds.move(entry, sds, file.getFileName()); // restore file
+
+ // newDirectoryStream
+ entry = Paths.get("subdir1234");
+ createDirectory(testdir.resolve(entry));
+ try {
+ prepare();
+ sds.newDirectoryStream(entry).close();
+ assertCheckRead(testdir.resolve(entry));
+ } finally {
+ delete(testdir.resolve(entry));
+ }
+
+ // getFileAttributeView to access attributes of directory
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(BasicFileAttributeView.class), testdir);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(PosixFileAttributeView.class), testdir);
+
+ // getFileAttributeView to access attributes of entry
+ entry = file.getFileName();
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+ } else {
+ System.out.println("SecureDirectoryStream not tested");
+ }
+ }
+
+ // -- toAbsolutePath --
+
+ prepare();
+ file.getFileName().toAbsolutePath();
+ assertCheckPropertyAccess("user.dir");
+
+ // -- toRealPath --
+
+ prepare();
+ file.toRealPath(true);
+ assertCheckRead(file);
+
+ prepare();
+ file.toRealPath(false);
+ assertCheckRead(file);
+
+ prepare();
+ Paths.get(".").toRealPath(true);
+ assertCheckPropertyAccess("user.dir");
+
+ prepare();
+ Paths.get(".").toRealPath(false);
+ assertCheckPropertyAccess("user.dir");
+
+ // -- register --
+
+ try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
+ prepare();
+ testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+ assertCheckRead(testdir);
+ }
+
+ // -- getAttribute/setAttribute/readAttributes --
+
+ prepare();
+ getAttribute(file, "size");
+ assertCheckRead(file);
+
+ prepare();
+ setAttribute(file, "lastModifiedTime",
+ FileTime.fromMillis(System.currentTimeMillis()));
+ assertCheckWrite(file);
+
+ prepare();
+ readAttributes(file, "*");
+ assertCheckRead(file);
+
+ // -- BasicFileAttributeView --
+ testBasicFileAttributeView(
+ getFileAttributeView(file, BasicFileAttributeView.class), file);
+
+ // -- PosixFileAttributeView --
+
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(file, PosixFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class))
+ {
+ testPosixFileAttributeView(view, file);
+ } else {
+ System.out.println("PosixFileAttributeView not tested");
+ }
+ }
+
+ // -- DosFileAttributeView --
+
+ {
+ DosFileAttributeView view =
+ getFileAttributeView(file, DosFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class))
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ view.setArchive(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setHidden(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setReadOnly(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setSystem(false);
+ assertCheckWrite(file);
+ } else {
+ System.out.println("DosFileAttributeView not tested");
+ }
+ }
+
+ // -- FileOwnerAttributeView --
+
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(file, FileOwnerAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class))
+ {
+ prepare();
+ UserPrincipal owner = view.getOwner();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(owner);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ } else {
+ System.out.println("FileOwnerAttributeView not tested");
+ }
+ }
+
+ // -- UserDefinedFileAttributeView --
+
+ {
+ UserDefinedFileAttributeView view =
+ getFileAttributeView(file, UserDefinedFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class))
+ {
+ prepare();
+ view.write("test", ByteBuffer.wrap(new byte[100]));
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.read("test", ByteBuffer.allocate(100));
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.size("test");
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.list();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.delete("test");
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+ } else {
+ System.out.println("UserDefinedFileAttributeView not tested");
+ }
+ }
+
+ // -- AclFileAttributeView --
+ {
+ AclFileAttributeView view =
+ getFileAttributeView(file, AclFileAttributeView.class);
+ if (view != null &&
+ getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class))
+ {
+ prepare();
+ List<AclEntry> acl = view.getAcl();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ prepare();
+ view.setAcl(acl);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ } else {
+ System.out.println("AclFileAttributeView not tested");
+ }
+ }
+
+ // -- UserPrincipalLookupService
+
+ UserPrincipalLookupService lookupService =
+ FileSystems.getDefault().getUserPrincipalLookupService();
+ UserPrincipal owner = getOwner(file);
+
+ prepare();
+ lookupService.lookupPrincipalByName(owner.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+
+ try {
+ UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group();
+ prepare();
+ lookupService.lookupPrincipalByGroupName(group.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+ } catch (UnsupportedOperationException ignore) {
+ System.out.println("lookupPrincipalByGroupName not tested");
+ }
+
+
+ } finally {
+ deleteIfExists(file);
+ }
+ }
+}