jdk/test/java/io/File/CheckPermission.java
changeset 18807 7d65f90d7348
equal deleted inserted replaced
18806:c094f5a236ba 18807:7d65f90d7348
       
     1 /*
       
     2  * Copyright (c) 2013, 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 8017212
       
    26  * @summary Examine methods in File.java that access the file system do the
       
    27  *          right permission check when a security manager exists.
       
    28  * @author Dan Xu
       
    29  */
       
    30 
       
    31 import java.io.File;
       
    32 import java.io.FilenameFilter;
       
    33 import java.io.FileFilter;
       
    34 import java.io.IOException;
       
    35 import java.security.Permission;
       
    36 import java.util.ArrayList;
       
    37 import java.util.EnumMap;
       
    38 import java.util.EnumSet;
       
    39 import java.util.HashSet;
       
    40 import java.util.List;
       
    41 import java.util.Map;
       
    42 import java.util.Set;
       
    43 
       
    44 public class CheckPermission {
       
    45 
       
    46     private static final String CHECK_PERMISSION_TEST = "CheckPermissionTest";
       
    47 
       
    48     public enum FileOperation {
       
    49         READ, WRITE, DELETE, EXEC
       
    50     }
       
    51 
       
    52     static class Checks {
       
    53         private List<Permission> permissionsChecked = new ArrayList<>();
       
    54         private Set<String> propertiesChecked = new HashSet<>();
       
    55 
       
    56         private Map<FileOperation, List<String>> fileOperationChecked =
       
    57             new EnumMap<>(FileOperation.class);
       
    58 
       
    59         List<Permission> permissionsChecked() {
       
    60             return permissionsChecked;
       
    61         }
       
    62 
       
    63         Set<String> propertiesChecked() {
       
    64             return propertiesChecked;
       
    65         }
       
    66 
       
    67         List<String> fileOperationChecked(FileOperation op) {
       
    68             return fileOperationChecked.get(op);
       
    69         }
       
    70 
       
    71         void addFileOperation(FileOperation op, String file) {
       
    72             List<String> opList = fileOperationChecked.get(op);
       
    73             if (opList == null) {
       
    74                 opList = new ArrayList<>();
       
    75                 fileOperationChecked.put(op, opList);
       
    76             }
       
    77             opList.add(file);
       
    78         }
       
    79     }
       
    80 
       
    81     static ThreadLocal<Checks> myChecks = new ThreadLocal<>();
       
    82 
       
    83     static void prepare() {
       
    84         myChecks.set(new Checks());
       
    85     }
       
    86 
       
    87     static class LoggingSecurityManager extends SecurityManager {
       
    88         static void install() {
       
    89             System.setSecurityManager(new LoggingSecurityManager());
       
    90         }
       
    91 
       
    92         private void checkFileOperation(FileOperation op, String file) {
       
    93             Checks checks = myChecks.get();
       
    94             if (checks != null)
       
    95                 checks.addFileOperation(op, file);
       
    96         }
       
    97 
       
    98         @Override
       
    99         public void checkRead(String file) {
       
   100             checkFileOperation(FileOperation.READ, file);
       
   101         }
       
   102 
       
   103         @Override
       
   104         public void checkWrite(String file) {
       
   105             checkFileOperation(FileOperation.WRITE, file);
       
   106         }
       
   107 
       
   108         @Override
       
   109         public void checkDelete(String file) {
       
   110             checkFileOperation(FileOperation.DELETE, file);
       
   111         }
       
   112 
       
   113         @Override
       
   114         public void checkExec(String file) {
       
   115             checkFileOperation(FileOperation.EXEC, file);
       
   116         }
       
   117 
       
   118         @Override
       
   119         public void checkPermission(Permission perm) {
       
   120             Checks checks = myChecks.get();
       
   121             if (checks != null)
       
   122                 checks.permissionsChecked().add(perm);
       
   123         }
       
   124 
       
   125         @Override
       
   126         public void checkPropertyAccess(String key) {
       
   127             Checks checks = myChecks.get();
       
   128             if (checks != null)
       
   129                 checks.propertiesChecked().add(key);
       
   130         }
       
   131     }
       
   132 
       
   133     static void assertCheckPermission(Class<? extends Permission> type,
       
   134             String name)
       
   135     {
       
   136         for (Permission perm : myChecks.get().permissionsChecked()) {
       
   137             if (type.isInstance(perm) && perm.getName().equals(name))
       
   138                 return;
       
   139         }
       
   140         throw new RuntimeException(type.getName() + "(\"" + name
       
   141             + "\") not checked");
       
   142     }
       
   143 
       
   144     static void assertCheckPropertyAccess(String key) {
       
   145         if (!myChecks.get().propertiesChecked().contains(key))
       
   146             throw new RuntimeException("Property " + key + " not checked");
       
   147     }
       
   148 
       
   149     static void assertChecked(File file, List<String> list) {
       
   150         if (list != null && !list.isEmpty()) {
       
   151             for (String path : list) {
       
   152                 if (path.equals(file.getPath()))
       
   153                     return;
       
   154             }
       
   155         }
       
   156         throw new RuntimeException("Access not checked");
       
   157     }
       
   158 
       
   159     static void assertNotChecked(File file, List<String> list) {
       
   160         if (list != null && !list.isEmpty()) {
       
   161             for (String path : list) {
       
   162                 if (path.equals(file.getPath()))
       
   163                     throw new RuntimeException("Access checked");
       
   164             }
       
   165         }
       
   166     }
       
   167 
       
   168     static void assertCheckOperation(File file, Set<FileOperation> ops) {
       
   169         for (FileOperation op : ops)
       
   170             assertChecked(file, myChecks.get().fileOperationChecked(op));
       
   171     }
       
   172 
       
   173     static void assertNotCheckOperation(File file, Set<FileOperation> ops) {
       
   174         for (FileOperation op : ops)
       
   175             assertNotChecked(file, myChecks.get().fileOperationChecked(op));
       
   176     }
       
   177 
       
   178     static void assertOnlyCheckOperation(File file,
       
   179             EnumSet<FileOperation> ops)
       
   180     {
       
   181         assertCheckOperation(file, ops);
       
   182         assertNotCheckOperation(file, EnumSet.complementOf(ops));
       
   183     }
       
   184 
       
   185     static File testFile, another;
       
   186 
       
   187     static void setup() {
       
   188         testFile = new File(CHECK_PERMISSION_TEST + System.currentTimeMillis());
       
   189         if (testFile.exists()) {
       
   190             testFile.delete();
       
   191         }
       
   192 
       
   193         another = new File(CHECK_PERMISSION_TEST + "Another"
       
   194                            + System.currentTimeMillis());
       
   195         if (another.exists()) {
       
   196             another.delete();
       
   197         }
       
   198 
       
   199         LoggingSecurityManager.install();
       
   200     }
       
   201 
       
   202     public static void main(String[] args) throws IOException {
       
   203         setup();
       
   204 
       
   205         prepare();
       
   206         testFile.canRead();
       
   207         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   208 
       
   209         prepare();
       
   210         testFile.canWrite();
       
   211         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   212 
       
   213         prepare();
       
   214         testFile.exists();
       
   215         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   216 
       
   217         prepare();
       
   218         testFile.isDirectory();
       
   219         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   220 
       
   221         prepare();
       
   222         testFile.isFile();
       
   223         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   224 
       
   225         prepare();
       
   226         testFile.isHidden();
       
   227         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   228 
       
   229         prepare();
       
   230         testFile.lastModified();
       
   231         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   232 
       
   233         prepare();
       
   234         testFile.length();
       
   235         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   236 
       
   237         prepare();
       
   238         testFile.createNewFile();
       
   239         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   240 
       
   241         prepare();
       
   242         testFile.list();
       
   243         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   244 
       
   245         prepare();
       
   246         testFile.list(new FilenameFilter() {
       
   247             @Override
       
   248             public boolean accept(File dir, String name) {
       
   249                 return false;
       
   250             }
       
   251         });
       
   252         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   253 
       
   254         prepare();
       
   255         testFile.listFiles();
       
   256         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   257 
       
   258         prepare();
       
   259         testFile.listFiles(new FilenameFilter() {
       
   260             @Override
       
   261             public boolean accept(File dir, String name) {
       
   262                 return false;
       
   263             }
       
   264         });
       
   265         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   266 
       
   267         prepare();
       
   268         testFile.listFiles(new FileFilter() {
       
   269             @Override
       
   270             public boolean accept(File file) {
       
   271                 return false;
       
   272             }
       
   273         });
       
   274         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   275 
       
   276         prepare();
       
   277         testFile.mkdir();
       
   278         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   279 
       
   280         if (testFile.exists()) {
       
   281             prepare();
       
   282             testFile.mkdirs();
       
   283             assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   284         }
       
   285 
       
   286         if (!another.exists()) {
       
   287             prepare();
       
   288             another.mkdirs();
       
   289             assertOnlyCheckOperation(another,
       
   290                     EnumSet.of(FileOperation.READ, FileOperation.WRITE));
       
   291         }
       
   292 
       
   293         prepare();
       
   294         another.delete();
       
   295         assertOnlyCheckOperation(another, EnumSet.of(FileOperation.DELETE));
       
   296 
       
   297         prepare();
       
   298         boolean renRst = testFile.renameTo(another);
       
   299         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   300         assertOnlyCheckOperation(another, EnumSet.of(FileOperation.WRITE));
       
   301 
       
   302         if (renRst) {
       
   303             if (testFile.exists())
       
   304                 throw new RuntimeException(testFile + " is already renamed to "
       
   305                     + another);
       
   306             testFile = another;
       
   307         }
       
   308 
       
   309         prepare();
       
   310         testFile.setLastModified(0);
       
   311         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   312 
       
   313         prepare();
       
   314         testFile.setReadOnly();
       
   315         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   316 
       
   317         prepare();
       
   318         testFile.setWritable(true, true);
       
   319         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   320 
       
   321         prepare();
       
   322         testFile.setWritable(true);
       
   323         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   324 
       
   325         prepare();
       
   326         testFile.setReadable(true, true);
       
   327         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   328 
       
   329         prepare();
       
   330         testFile.setReadable(true);
       
   331         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   332 
       
   333         prepare();
       
   334         testFile.setExecutable(true, true);
       
   335         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   336 
       
   337         prepare();
       
   338         testFile.setExecutable(true);
       
   339         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.WRITE));
       
   340 
       
   341         prepare();
       
   342         testFile.canExecute();
       
   343         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.EXEC));
       
   344 
       
   345         prepare();
       
   346         testFile.getTotalSpace();
       
   347         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   348         assertCheckPermission(RuntimePermission.class,
       
   349                 "getFileSystemAttributes");
       
   350 
       
   351         prepare();
       
   352         testFile.getFreeSpace();
       
   353         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   354         assertCheckPermission(RuntimePermission.class,
       
   355                 "getFileSystemAttributes");
       
   356 
       
   357         prepare();
       
   358         testFile.getUsableSpace();
       
   359         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.READ));
       
   360         assertCheckPermission(RuntimePermission.class,
       
   361                 "getFileSystemAttributes");
       
   362 
       
   363         prepare();
       
   364         File tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null);
       
   365         assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE));
       
   366         tmpFile.delete();
       
   367         assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE));
       
   368 
       
   369         prepare();
       
   370         tmpFile = File.createTempFile(CHECK_PERMISSION_TEST, null, null);
       
   371         assertOnlyCheckOperation(tmpFile, EnumSet.of(FileOperation.WRITE));
       
   372         tmpFile.delete();
       
   373         assertCheckOperation(tmpFile, EnumSet.of(FileOperation.DELETE));
       
   374 
       
   375         prepare();
       
   376         testFile.deleteOnExit();
       
   377         assertOnlyCheckOperation(testFile, EnumSet.of(FileOperation.DELETE));
       
   378     }
       
   379 }