Path: blob/master/test/jdk/java/net/httpclient/FilePublisher/SecureZipFSProvider.java
41153 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.io.InputStream;25import java.net.URI;26import java.nio.channels.FileChannel;27import java.nio.channels.SeekableByteChannel;28import java.nio.file.AccessMode;29import java.nio.file.CopyOption;30import java.nio.file.DirectoryStream;31import java.nio.file.FileStore;32import java.nio.file.FileSystem;33import java.nio.file.LinkOption;34import java.nio.file.OpenOption;35import java.nio.file.Path;36import java.nio.file.PathMatcher;37import java.nio.file.ProviderMismatchException;38import java.nio.file.WatchEvent;39import java.nio.file.WatchKey;40import java.nio.file.WatchService;41import java.nio.file.attribute.BasicFileAttributes;42import java.nio.file.attribute.FileAttribute;43import java.nio.file.attribute.FileAttributeView;44import java.nio.file.attribute.UserPrincipalLookupService;45import java.nio.file.spi.FileSystemProvider;46import java.util.Iterator;47import java.util.Map;48import java.util.Set;49import java.util.concurrent.ConcurrentHashMap;5051public class SecureZipFSProvider extends FileSystemProvider {52private final ConcurrentHashMap<FileSystem, SecureZipFS> map =53new ConcurrentHashMap<>();54private final FileSystemProvider defaultProvider;5556public SecureZipFSProvider(FileSystemProvider provider) {57defaultProvider = provider;58}5960@Override61public String getScheme() {62return "jar";63}6465public FileSystem newFileSystem(FileSystem fs) {66return map.computeIfAbsent(fs, (sfs) ->67new SecureZipFS(this, fs));68}6970@Override71public FileSystem newFileSystem(URI uri, Map<String, ?> env)72throws IOException {73FileSystem fs = defaultProvider.newFileSystem(uri, env);74return map.computeIfAbsent(fs, (sfs) ->75new SecureZipFS(this, fs)76);77}7879@Override80public FileSystem getFileSystem(URI uri) {81return map.get(defaultProvider.getFileSystem(uri));82}8384@Override85public Path getPath(URI uri) {86Path p = defaultProvider.getPath(uri);87return map.get(defaultProvider.getFileSystem(uri)).wrap(p);88}8990@Override91public InputStream newInputStream(Path path, OpenOption... options)92throws IOException {93Path p = toTestPath(path).unwrap();9495// Added permission checks before opening the file96SecurityManager sm = System.getSecurityManager();97if (sm != null) {98sm.checkPermission(new RuntimePermission("customPermission"));99sm.checkRead(p.toString());100}101return defaultProvider.newInputStream(p, options);102}103104@Override105public SeekableByteChannel newByteChannel(Path path,106Set<? extends OpenOption> options,107FileAttribute<?>... attrs)108throws IOException {109Path p = toTestPath(path).unwrap();110return defaultProvider.newByteChannel(p, options, attrs);111}112113@Override114public FileChannel newFileChannel(Path path,115Set<? extends OpenOption> options,116FileAttribute<?>... attrs)117throws IOException {118Path p = toTestPath(path).unwrap();119return defaultProvider.newFileChannel(p, options, attrs);120}121122123@Override124public DirectoryStream<Path> newDirectoryStream(Path dir,125DirectoryStream.Filter<? super Path> filter) {126throw new RuntimeException("not implemented");127}128129@Override130public void createDirectory(Path dir, FileAttribute<?>... attrs)131throws IOException {132Path p = toTestPath(dir).unwrap();133defaultProvider.createDirectory(p, attrs);134}135136@Override137public void delete(Path path) throws IOException {138Path p = toTestPath(path).unwrap();139defaultProvider.delete(p);140}141142@Override143public void copy(Path source, Path target, CopyOption... options)144throws IOException {145Path sp = toTestPath(source).unwrap();146Path tp = toTestPath(target).unwrap();147defaultProvider.copy(sp, tp, options);148}149150@Override151public void move(Path source, Path target, CopyOption... options)152throws IOException {153Path sp = toTestPath(source).unwrap();154Path tp = toTestPath(target).unwrap();155defaultProvider.move(sp, tp, options);156}157158@Override159public boolean isSameFile(Path path, Path path2)160throws IOException {161Path p = toTestPath(path).unwrap();162Path p2 = toTestPath(path2).unwrap();163return defaultProvider.isSameFile(p, p2);164}165166@Override167public boolean isHidden(Path path) throws IOException {168Path p = toTestPath(path).unwrap();169return defaultProvider.isHidden(p);170}171172@Override173public FileStore getFileStore(Path path) throws IOException {174Path p = toTestPath(path).unwrap();175return defaultProvider.getFileStore(p);176}177178@Override179public void checkAccess(Path path, AccessMode... modes) throws IOException {180Path p = toTestPath(path).unwrap();181defaultProvider.checkAccess(p, modes);182}183184@Override185public <V extends FileAttributeView> V getFileAttributeView(Path path,186Class<V> type,187LinkOption... options) {188Path p = toTestPath(path).unwrap();189return defaultProvider.getFileAttributeView(p, type, options);190}191192@Override193public <A extends BasicFileAttributes> A readAttributes(Path path,194Class<A> type,195LinkOption... options)196throws IOException {197Path p = toTestPath(path).unwrap();198return defaultProvider.readAttributes(p, type, options);199}200201@Override202public Map<String, Object> readAttributes(Path path,203String attributes,204LinkOption... options)205throws IOException {206Path p = toTestPath(path).unwrap();207return defaultProvider.readAttributes(p, attributes, options);208}209210@Override211public void setAttribute(Path path, String attribute,212Object value, LinkOption... options)213throws IOException {214Path p = toTestPath(path).unwrap();215defaultProvider.setAttribute(p, attribute, options);216}217218// Checks that the given file is a TestPath219static TestPath toTestPath(Path obj) {220if (obj == null)221throw new NullPointerException();222if (!(obj instanceof TestPath))223throw new ProviderMismatchException();224return (TestPath) obj;225}226227static class SecureZipFS extends FileSystem {228private final SecureZipFSProvider provider;229private final FileSystem delegate;230231public SecureZipFS(SecureZipFSProvider provider, FileSystem delegate) {232this.provider = provider;233this.delegate = delegate;234}235236Path wrap(Path path) {237return (path != null) ? new TestPath(this, path) : null;238}239240Path unwrap(Path wrapper) {241if (wrapper == null)242throw new NullPointerException();243if (!(wrapper instanceof TestPath))244throw new ProviderMismatchException();245return ((TestPath) wrapper).unwrap();246}247248@Override249public FileSystemProvider provider() {250return provider;251}252253@Override254public void close() throws IOException {255delegate.close();256}257258@Override259public boolean isOpen() {260return delegate.isOpen();261}262263@Override264public boolean isReadOnly() {265return delegate.isReadOnly();266}267268@Override269public String getSeparator() {270return delegate.getSeparator();271}272273@Override274public Iterable<Path> getRootDirectories() {275return delegate.getRootDirectories();276}277278@Override279public Iterable<FileStore> getFileStores() {280return delegate.getFileStores();281}282283@Override284public Set<String> supportedFileAttributeViews() {285return delegate.supportedFileAttributeViews();286}287288@Override289public Path getPath(String first, String... more) {290return wrap(delegate.getPath(first, more));291}292293@Override294public PathMatcher getPathMatcher(String syntaxAndPattern) {295return delegate.getPathMatcher(syntaxAndPattern);296}297298@Override299public UserPrincipalLookupService getUserPrincipalLookupService() {300return delegate.getUserPrincipalLookupService();301}302303@Override304public WatchService newWatchService() throws IOException {305return delegate.newWatchService();306}307}308309static class TestPath implements Path {310private final SecureZipFS fs;311private final Path delegate;312313TestPath(SecureZipFS fs, Path delegate) {314this.fs = fs;315this.delegate = delegate;316}317318Path unwrap() {319return delegate;320}321322@Override323public SecureZipFS getFileSystem() {324return fs;325}326327@Override328public boolean isAbsolute() {329return delegate.isAbsolute();330}331332@Override333public Path getRoot() {334return fs.wrap(delegate.getRoot());335}336337@Override338public Path getFileName() {339return fs.wrap(delegate.getFileName());340}341342@Override343public Path getParent() {344return fs.wrap(delegate.getParent());345}346347@Override348public int getNameCount() {349return delegate.getNameCount();350}351352@Override353public Path getName(int index) {354return fs.wrap(delegate.getName(index));355}356357@Override358public Path subpath(int beginIndex, int endIndex) {359return fs.wrap(delegate.subpath(beginIndex, endIndex));360}361362@Override363public boolean startsWith(Path other) {364return delegate.startsWith(other);365}366367@Override368public boolean endsWith(Path other) {369return delegate.endsWith(other);370}371372@Override373public Path normalize() {374return fs.wrap(delegate.normalize());375}376377@Override378public Path resolve(Path other) {379return fs.wrap(delegate.resolve(fs.wrap(other)));380}381382@Override383public Path relativize(Path other) {384return fs.wrap(delegate.relativize(fs.wrap(other)));385}386387@Override388public URI toUri() {389String ssp = delegate.toUri().getSchemeSpecificPart();390return URI.create(fs.provider().getScheme() + ":" + ssp);391}392393@Override394public Path toAbsolutePath() {395return fs.wrap(delegate.toAbsolutePath());396}397398@Override399public Path toRealPath(LinkOption... options) throws IOException {400return fs.wrap(delegate.toRealPath(options));401}402403@Override404public WatchKey register(WatchService watcher,405WatchEvent.Kind<?>[] events,406WatchEvent.Modifier... modifiers)407throws IOException {408return delegate.register(watcher, events, modifiers);409}410411@Override412public Iterator<Path> iterator() {413final Iterator<Path> itr = delegate.iterator();414return new Iterator<>() {415@Override416public boolean hasNext() {417return itr.hasNext();418}419420@Override421public Path next() {422return fs.wrap(itr.next());423}424425@Override426public void remove() {427itr.remove();428}429};430}431432@Override433public int compareTo(Path other) {434return delegate.compareTo(fs.unwrap(other));435}436437@Override438public int hashCode() {439return delegate.hashCode();440}441442@Override443public boolean equals(Object other) {444return other instanceof TestPath && delegate.equals(fs.unwrap((TestPath) other));445}446447@Override448public String toString() {449return delegate.toString();450}451}452}453454455