1 /* 2 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 6866804 7006126 26 * @summary Unit test for java.nio.file.Files 27 * @library .. 28 * @build CheckPermissions 29 * @run main/othervm CheckPermissions 30 */ 31 32 import java.nio.ByteBuffer; 33 import java.nio.file.*; 34 import static java.nio.file.Files.*; 35 import static java.nio.file.StandardOpenOption.*; 36 import java.nio.file.attribute.*; 37 import java.nio.channels.SeekableByteChannel; 38 import java.security.Permission; 39 import java.io.*; 40 import java.util.*; 41 42 /** 43 * Checks each method that accesses the file system does the right permission 44 * check when there is a security manager set. 45 */ 46 47 public class CheckPermissions { 48 49 static class Checks { 50 private List<Permission> permissionsChecked = new ArrayList<>(); 51 private Set<String> propertiesChecked = new HashSet<>(); 52 private List<String> readsChecked = new ArrayList<>(); 53 private List<String> writesChecked = new ArrayList<>(); 54 private List<String> deletesChecked = new ArrayList<>(); 55 private List<String> execsChecked = new ArrayList<>(); 56 57 List<Permission> permissionsChecked() { return permissionsChecked; } 58 Set<String> propertiesChecked() { return propertiesChecked; } 59 List<String> readsChecked() { return readsChecked; } 60 List<String> writesChecked() { return writesChecked; } 61 List<String> deletesChecked() { return deletesChecked; } 62 List<String> execsChecked() { return execsChecked; } 63 } 64 65 static ThreadLocal<Checks> myChecks = 66 new ThreadLocal<Checks>() { 67 @Override protected Checks initialValue() { 68 return null; 69 } 70 }; 71 72 static void prepare() { 73 myChecks.set(new Checks()); 74 } 75 76 static void assertCheckPermission(Class<? extends Permission> type, 77 String name) 78 { 79 for (Permission perm: myChecks.get().permissionsChecked()) { 80 if (type.isInstance(perm) && perm.getName().equals(name)) 81 return; 82 } 83 throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked"); 84 } 85 86 static void assertCheckPropertyAccess(String key) { 87 if (!myChecks.get().propertiesChecked().contains(key)) 88 throw new RuntimeException("Property " + key + " not checked"); 89 } 90 91 static void assertChecked(Path file, List<String> list) { 92 String s = file.toString(); 93 for (String f: list) { 94 if (f.endsWith(s)) 95 return; 96 } 97 throw new RuntimeException("Access not checked"); 98 } 99 100 static void assertCheckRead(Path file) { 101 assertChecked(file, myChecks.get().readsChecked()); 102 } 103 104 static void assertCheckWrite(Path file) { 105 assertChecked(file, myChecks.get().writesChecked()); 106 } 107 108 static void assertCheckWriteToDirectory(Path dir) { 109 String s = dir.toString(); 110 List<String> list = myChecks.get().writesChecked(); 111 for (String f: list) { 112 if (f.startsWith(s)) { 113 return; 114 } 115 } 116 throw new RuntimeException("Access not checked"); 117 } 118 119 static void assertCheckDelete(Path file) { 120 assertChecked(file, myChecks.get().deletesChecked()); 121 } 122 123 static void assertCheckExec(Path file) { 124 assertChecked(file, myChecks.get().execsChecked()); 125 } 126 127 static class LoggingSecurityManager extends SecurityManager { 128 static void install() { 129 System.setSecurityManager(new LoggingSecurityManager()); 130 } 131 132 @Override 133 public void checkPermission(Permission perm) { 134 Checks checks = myChecks.get(); 135 if (checks != null) 136 checks.permissionsChecked().add(perm); 137 } 138 139 @Override 140 public void checkPropertyAccess(String key) { 141 Checks checks = myChecks.get(); 142 if (checks != null) 143 checks.propertiesChecked().add(key); 144 } 145 146 @Override 147 public void checkRead(String file) { 148 Checks checks = myChecks.get(); 149 if (checks != null) 150 checks.readsChecked().add(file); 151 } 152 153 @Override 154 public void checkWrite(String file) { 155 Checks checks = myChecks.get(); 156 if (checks != null) 157 checks.writesChecked().add(file); 158 } 159 160 @Override 161 public void checkDelete(String file) { 162 Checks checks = myChecks.get(); 163 if (checks != null) 164 checks.deletesChecked().add(file); 165 } 166 167 @Override 168 public void checkExec(String file) { 169 Checks checks = myChecks.get(); 170 if (checks != null) 171 checks.execsChecked().add(file); 172 } 173 } 174 175 static void testBasicFileAttributeView(BasicFileAttributeView view, Path file) 176 throws IOException 177 { 178 prepare(); 179 view.readAttributes(); 180 assertCheckRead(file); 181 182 prepare(); 183 FileTime now = FileTime.fromMillis(System.currentTimeMillis()); 184 view.setTimes(null, now, now); 185 assertCheckWrite(file); 186 } 187 188 static void testPosixFileAttributeView(PosixFileAttributeView view, Path file) 189 throws IOException 190 { 191 prepare(); 192 PosixFileAttributes attrs = view.readAttributes(); 193 assertCheckRead(file); 194 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 195 196 prepare(); 197 view.setPermissions(attrs.permissions()); 198 assertCheckWrite(file); 199 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 200 201 prepare(); 202 view.setOwner(attrs.owner()); 203 assertCheckWrite(file); 204 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 205 206 prepare(); 207 view.setOwner(attrs.owner()); 208 assertCheckWrite(file); 209 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 210 } 211 212 public static void main(String[] args) throws IOException { 213 final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath(); 214 final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir")); 215 216 Path file = createFile(testdir.resolve("file1234")); 217 try { 218 LoggingSecurityManager.install(); 219 220 // -- check access -- 221 222 prepare(); 223 exists(file); 224 assertCheckRead(file); 225 226 prepare(); 227 isReadable(file); 228 assertCheckRead(file); 229 230 prepare(); 231 isWritable(file); 232 assertCheckWrite(file); 233 234 prepare(); 235 isExecutable(file); 236 assertCheckExec(file); 237 238 // -- copy -- 239 240 Path target = testdir.resolve("target1234"); 241 prepare(); 242 copy(file, target); 243 try { 244 assertCheckRead(file); 245 assertCheckWrite(target); 246 } finally { 247 delete(target); 248 } 249 250 if (TestUtil.supportsLinks(testdir)) { 251 Path link = testdir.resolve("link1234"); 252 createSymbolicLink(link, file); 253 try { 254 prepare(); 255 copy(link, target, LinkOption.NOFOLLOW_LINKS); 256 try { 257 assertCheckRead(link); 258 assertCheckWrite(target); 259 assertCheckPermission(LinkPermission.class, "symbolic"); 260 } finally { 261 delete(target); 262 } 263 } finally { 264 delete(link); 265 } 266 } 267 268 // -- createDirectory -- 269 270 Path subdir = testdir.resolve("subdir1234"); 271 prepare(); 272 createDirectory(subdir); 273 try { 274 assertCheckWrite(subdir); 275 } finally { 276 delete(subdir); 277 } 278 279 // -- createFile -- 280 281 Path fileToCreate = testdir.resolve("file7890"); 282 prepare(); 283 createFile(fileToCreate); 284 try { 285 assertCheckWrite(fileToCreate); 286 } finally { 287 delete(fileToCreate); 288 } 289 290 // -- createSymbolicLink -- 291 292 if (TestUtil.supportsLinks(testdir)) { 293 prepare(); 294 Path link = testdir.resolve("link1234"); 295 createSymbolicLink(link, file); 296 try { 297 assertCheckWrite(link); 298 assertCheckPermission(LinkPermission.class, "symbolic"); 299 } finally { 300 delete(link); 301 } 302 } 303 304 // -- createLink -- 305 306 if (TestUtil.supportsLinks(testdir)) { 307 prepare(); 308 Path link = testdir.resolve("entry234"); 309 createLink(link, file); 310 try { 311 assertCheckWrite(link); 312 assertCheckPermission(LinkPermission.class, "hard"); 313 } finally { 314 delete(link); 315 } 316 } 317 318 // -- createTempFile -- 319 320 prepare(); 321 Path tmpfile1 = createTempFile("foo", null); 322 try { 323 assertCheckWriteToDirectory(tmpdir); 324 } finally { 325 delete(tmpfile1); 326 } 327 prepare(); 328 Path tmpfile2 = createTempFile(testdir, "foo", ".tmp"); 329 try { 330 assertCheckWriteToDirectory(testdir); 331 } finally { 332 delete(tmpfile2); 333 } 334 335 // -- createTempDirectory -- 336 337 prepare(); 338 Path tmpdir1 = createTempDirectory("foo"); 339 try { 340 assertCheckWriteToDirectory(tmpdir); 341 } finally { 342 delete(tmpdir1); 343 } 344 prepare(); 345 Path tmpdir2 = createTempDirectory(testdir, "foo"); 346 try { 347 assertCheckWriteToDirectory(testdir); 348 } finally { 349 delete(tmpdir2); 350 } 351 352 // -- delete/deleteIfExists -- 353 354 Path fileToDelete = testdir.resolve("file7890"); 355 356 createFile(fileToDelete); 357 prepare(); 358 delete(fileToDelete); 359 assertCheckDelete(fileToDelete); 360 361 createFile(fileToDelete); 362 prepare(); 363 deleteIfExists(fileToDelete); // file exists 364 assertCheckDelete(fileToDelete); 365 366 prepare(); 367 deleteIfExists(fileToDelete); // file does not exist 368 assertCheckDelete(fileToDelete); 369 370 // -- exists/notExists -- 371 372 prepare(); 373 exists(file); 374 assertCheckRead(file); 375 376 prepare(); 377 notExists(file); 378 assertCheckRead(file); 379 380 // -- getFileStore -- 381 382 prepare(); 383 getFileStore(file); 384 assertCheckRead(file); 385 assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes"); 386 387 // -- isSameFile -- 388 389 prepare(); 390 isSameFile(file, testdir); 391 assertCheckRead(file); 392 assertCheckRead(testdir); 393 394 // -- move -- 395 396 Path target2 = testdir.resolve("target1234"); 397 prepare(); 398 move(file, target2); 399 try { 400 assertCheckWrite(file); 401 assertCheckWrite(target2); 402 } finally { 403 // restore file 404 move(target2, file); 405 } 406 407 // -- newByteChannel -- 408 409 prepare(); 410 try (SeekableByteChannel sbc = newByteChannel(file)) { 411 assertCheckRead(file); 412 } 413 prepare(); 414 try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) { 415 assertCheckWrite(file); 416 } 417 prepare(); 418 try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) { 419 assertCheckRead(file); 420 assertCheckWrite(file); 421 } 422 423 prepare(); 424 try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) { 425 assertCheckRead(file); 426 assertCheckDelete(file); 427 } 428 createFile(file); // restore file 429 430 431 // -- newInputStream/newOutptuStream -- 432 433 prepare(); 434 try (InputStream in = newInputStream(file)) { 435 assertCheckRead(file); 436 } 437 prepare(); 438 try (OutputStream out = newOutputStream(file)) { 439 assertCheckWrite(file); 440 } 441 442 // -- newDirectoryStream -- 443 444 prepare(); 445 try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) { 446 assertCheckRead(testdir); 447 448 if (stream instanceof SecureDirectoryStream<?>) { 449 Path entry; 450 SecureDirectoryStream<Path> sds = 451 (SecureDirectoryStream<Path>)stream; 452 453 // newByteChannel 454 entry = file.getFileName(); 455 prepare(); 456 try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) { 457 assertCheckRead(file); 458 } 459 prepare(); 460 try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) { 461 assertCheckWrite(file); 462 } 463 464 // deleteFile 465 entry = file.getFileName(); 466 prepare(); 467 sds.deleteFile(entry); 468 assertCheckDelete(file); 469 createFile(testdir.resolve(entry)); // restore file 470 471 // deleteDirectory 472 entry = Paths.get("subdir1234"); 473 createDirectory(testdir.resolve(entry)); 474 prepare(); 475 sds.deleteDirectory(entry); 476 assertCheckDelete(testdir.resolve(entry)); 477 478 // move 479 entry = Paths.get("tempname1234"); 480 prepare(); 481 sds.move(file.getFileName(), sds, entry); 482 assertCheckWrite(file); 483 assertCheckWrite(testdir.resolve(entry)); 484 sds.move(entry, sds, file.getFileName()); // restore file 485 486 // newDirectoryStream 487 entry = Paths.get("subdir1234"); 488 createDirectory(testdir.resolve(entry)); 489 try { 490 prepare(); 491 sds.newDirectoryStream(entry).close(); 492 assertCheckRead(testdir.resolve(entry)); 493 } finally { 494 delete(testdir.resolve(entry)); 495 } 496 497 // getFileAttributeView to access attributes of directory 498 testBasicFileAttributeView(sds 499 .getFileAttributeView(BasicFileAttributeView.class), testdir); 500 testPosixFileAttributeView(sds 501 .getFileAttributeView(PosixFileAttributeView.class), testdir); 502 503 // getFileAttributeView to access attributes of entry 504 entry = file.getFileName(); 505 testBasicFileAttributeView(sds 506 .getFileAttributeView(entry, BasicFileAttributeView.class), file); 507 testPosixFileAttributeView(sds 508 .getFileAttributeView(entry, PosixFileAttributeView.class), file); 509 510 } else { 511 System.out.println("SecureDirectoryStream not tested"); 512 } 513 } 514 515 // -- toAbsolutePath -- 516 517 prepare(); 518 file.getFileName().toAbsolutePath(); 519 assertCheckPropertyAccess("user.dir"); 520 521 // -- toRealPath -- 522 523 prepare(); 524 file.toRealPath(true); 525 assertCheckRead(file); 526 527 prepare(); 528 file.toRealPath(false); 529 assertCheckRead(file); 530 531 prepare(); 532 Paths.get(".").toRealPath(true); 533 assertCheckPropertyAccess("user.dir"); 534 535 prepare(); 536 Paths.get(".").toRealPath(false); 537 assertCheckPropertyAccess("user.dir"); 538 539 // -- register -- 540 541 try (WatchService watcher = FileSystems.getDefault().newWatchService()) { 542 prepare(); 543 testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE); 544 assertCheckRead(testdir); 545 } 546 547 // -- getAttribute/setAttribute/readAttributes -- 548 549 prepare(); 550 getAttribute(file, "size"); 551 assertCheckRead(file); 552 553 prepare(); 554 setAttribute(file, "lastModifiedTime", 555 FileTime.fromMillis(System.currentTimeMillis())); 556 assertCheckWrite(file); 557 558 prepare(); 559 readAttributes(file, "*"); 560 assertCheckRead(file); 561 562 // -- BasicFileAttributeView -- 563 testBasicFileAttributeView( 564 getFileAttributeView(file, BasicFileAttributeView.class), file); 565 566 // -- PosixFileAttributeView -- 567 568 { 569 PosixFileAttributeView view = 570 getFileAttributeView(file, PosixFileAttributeView.class); 571 if (view != null && 572 getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class)) 573 { 574 testPosixFileAttributeView(view, file); 575 } else { 576 System.out.println("PosixFileAttributeView not tested"); 577 } 578 } 579 580 // -- DosFileAttributeView -- 581 582 { 583 DosFileAttributeView view = 584 getFileAttributeView(file, DosFileAttributeView.class); 585 if (view != null && 586 getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class)) 587 { 588 prepare(); 589 view.readAttributes(); 590 assertCheckRead(file); 591 592 prepare(); 593 view.setArchive(false); 594 assertCheckWrite(file); 595 596 prepare(); 597 view.setHidden(false); 598 assertCheckWrite(file); 599 600 prepare(); 601 view.setReadOnly(false); 602 assertCheckWrite(file); 603 604 prepare(); 605 view.setSystem(false); 606 assertCheckWrite(file); 607 } else { 608 System.out.println("DosFileAttributeView not tested"); 609 } 610 } 611 612 // -- FileOwnerAttributeView -- 613 614 { 615 FileOwnerAttributeView view = 616 getFileAttributeView(file, FileOwnerAttributeView.class); 617 if (view != null && 618 getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class)) 619 { 620 prepare(); 621 UserPrincipal owner = view.getOwner(); 622 assertCheckRead(file); 623 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 624 625 prepare(); 626 view.setOwner(owner); 627 assertCheckWrite(file); 628 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 629 630 } else { 631 System.out.println("FileOwnerAttributeView not tested"); 632 } 633 } 634 635 // -- UserDefinedFileAttributeView -- 636 637 { 638 UserDefinedFileAttributeView view = 639 getFileAttributeView(file, UserDefinedFileAttributeView.class); 640 if (view != null && 641 getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class)) 642 { 643 prepare(); 644 view.write("test", ByteBuffer.wrap(new byte[100])); 645 assertCheckWrite(file); 646 assertCheckPermission(RuntimePermission.class, 647 "accessUserDefinedAttributes"); 648 649 prepare(); 650 view.read("test", ByteBuffer.allocate(100)); 651 assertCheckRead(file); 652 assertCheckPermission(RuntimePermission.class, 653 "accessUserDefinedAttributes"); 654 655 prepare(); 656 view.size("test"); 657 assertCheckRead(file); 658 assertCheckPermission(RuntimePermission.class, 659 "accessUserDefinedAttributes"); 660 661 prepare(); 662 view.list(); 663 assertCheckRead(file); 664 assertCheckPermission(RuntimePermission.class, 665 "accessUserDefinedAttributes"); 666 667 prepare(); 668 view.delete("test"); 669 assertCheckWrite(file); 670 assertCheckPermission(RuntimePermission.class, 671 "accessUserDefinedAttributes"); 672 } else { 673 System.out.println("UserDefinedFileAttributeView not tested"); 674 } 675 } 676 677 // -- AclFileAttributeView -- 678 { 679 AclFileAttributeView view = 680 getFileAttributeView(file, AclFileAttributeView.class); 681 if (view != null && 682 getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class)) 683 { 684 prepare(); 685 List<AclEntry> acl = view.getAcl(); 686 assertCheckRead(file); 687 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 688 prepare(); 689 view.setAcl(acl); 690 assertCheckWrite(file); 691 assertCheckPermission(RuntimePermission.class, "accessUserInformation"); 692 } else { 693 System.out.println("AclFileAttributeView not tested"); 694 } 695 } 696 697 // -- UserPrincipalLookupService 698 699 UserPrincipalLookupService lookupService = 700 FileSystems.getDefault().getUserPrincipalLookupService(); 701 UserPrincipal owner = getOwner(file); 702 703 prepare(); 704 lookupService.lookupPrincipalByName(owner.getName()); 705 assertCheckPermission(RuntimePermission.class, 706 "lookupUserInformation"); 707 708 try { 709 UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group(); 710 prepare(); 711 lookupService.lookupPrincipalByGroupName(group.getName()); 712 assertCheckPermission(RuntimePermission.class, 713 "lookupUserInformation"); 714 } catch (UnsupportedOperationException ignore) { 715 System.out.println("lookupPrincipalByGroupName not tested"); 716 } 717 718 719 } finally { 720 deleteIfExists(file); 721 } 722 } 723 }