diff options
author | Jiri Vanek <[email protected]> | 2013-02-27 17:00:48 +0100 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2013-02-27 17:00:48 +0100 |
commit | 59a94f89ce7543d5a9788040de31d20fdf642c23 (patch) | |
tree | dc7e60f2487e02cb5c04514796da3a49b160848c /netx/net/sourceforge/jnlp/util/lockingfile | |
parent | 8f33e7d61884012e3c759b563c94f97ecdac4371 (diff) |
Added backend and settings for extended applet security
Diffstat (limited to 'netx/net/sourceforge/jnlp/util/lockingfile')
3 files changed, 417 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/util/lockingfile/LockedFile.java b/netx/net/sourceforge/jnlp/util/lockingfile/LockedFile.java new file mode 100644 index 0000000..2941dd9 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/lockingfile/LockedFile.java @@ -0,0 +1,159 @@ +/* + Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea 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 for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.util.lockingfile; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.locks.ReentrantLock; + +/* + * Process & thread locked access to a file. Creates file if it does not already exist. + */ +public class LockedFile { + + // The file for access + private RandomAccessFile randomAccessFile; + private FileChannel fileChannel; + private File file; + // A file lock will protect against locks for multiple + // processes, while a thread lock is still needed within a single JVM. + private FileLock processLock = null; + private ReentrantLock threadLock = new ReentrantLock(); + private boolean readOnly; + + private LockedFile(File file) { + this.file = file; + try { + //just try to create + this.file.createNewFile(); + } catch (Exception ex) { + //intentionaly silent + } + if (!this.file.isFile() && file.getParentFile() != null && !file.getParentFile().canWrite()) { + readOnly = true; + } else { + this.readOnly = !file.canWrite(); + if (!readOnly && file.getParentFile() != null && !file.getParentFile().canWrite()) { + readOnly = true; + } + } + } + + public boolean isReadOnly() { + return readOnly; + } + // Provide shared access to LockedFile's via weak map + static private final Map<File, LockedFile> instanceCache = new WeakHashMap<File, LockedFile>(); + + /** + * Get a LockedFile for a given File. Ensures that we share the same + * instance for all threads + * + * @param file the file to lock + * @return a LockedFile instance + */ + synchronized public static LockedFile getInstance(File file) { + if (!instanceCache.containsKey(file)) { + instanceCache.put(file, new LockedFile(file)); + } + + return instanceCache.get(file); + } + + /** + * Get the file being locked. + * + * @return the file + */ + public File getFile() { + return file; + } + + /** + * Lock access to the file. Lock is reentrant. + */ + public void lock() throws IOException { + // Create if does not already exist, cannot lock non-existing file + if (!isReadOnly()) { + this.file.createNewFile(); + } + + this.threadLock.lock(); + + if (this.processLock != null) { + return; + } + + if (this.file.exists()) { + this.randomAccessFile = new RandomAccessFile(this.file, isReadOnly() ? "r" : "rws"); + this.fileChannel = randomAccessFile.getChannel(); + if (!isReadOnly()){ + this.processLock = this.fileChannel.lock(); + } + } + } + + /** + * Unlock access to the file. Lock is reentrant. + */ + public void unlock() throws IOException { + boolean releaseProcessLock = (this.threadLock.getHoldCount() == 1); + try { + if (releaseProcessLock) { + if (this.processLock != null){ + this.processLock.release(); + } + this.processLock = null; + //necessary for read only file + if (this.randomAccessFile != null){ + this.randomAccessFile.close(); + } + //necessary for not existing parent direcotry + if (this.fileChannel != null){ + this.fileChannel.close(); + } + } + } finally { + this.threadLock.unlock(); + } + } +}
\ No newline at end of file diff --git a/netx/net/sourceforge/jnlp/util/lockingfile/LockingReaderWriter.java b/netx/net/sourceforge/jnlp/util/lockingfile/LockingReaderWriter.java new file mode 100644 index 0000000..16fbaa6 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/lockingfile/LockingReaderWriter.java @@ -0,0 +1,200 @@ +/* +Copyright (C) 2013 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea 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 for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ +package net.sourceforge.jnlp.util.lockingfile; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + +/** + * Process-locked string storage backed by a file. + * Each string is stored on its own line. + * Any new-lines must be encoded somehow if they are to be stored. + */ +public abstract class LockingReaderWriter { + + private LockedFile lockedFile; + + /** + * Create locking file-backed storage. + * @param file the storage file + */ + public LockingReaderWriter(File file) { + this.lockedFile = LockedFile.getInstance(file); + } + + /** + * Get the underlying file. + * Any access to this file should use lock() & unlock(). + * + * @return the file + */ + public File getBackingFile() { + return this.lockedFile.getFile(); + } + + public boolean isReadOnly() { + return this.lockedFile.isReadOnly(); + } + + /** + * Lock the underlying storage. Lock is reentrant. + */ + public void lock() { + try { + lockedFile.lock(); + } catch (IOException e) { + throw new StorageIoException(e); + } + } + + /** + * Unlock the underlying storage. Lock is reentrant. + */ + public void unlock() { + try { + lockedFile.unlock(); + } catch (IOException e) { + throw new StorageIoException(e); + } + } + + /** + * Writes stored contents to file. Assumes lock is held. + * @throws IOException + */ + protected void writeContents() throws IOException { + if (!getBackingFile().isFile()){ + return; + } + if (isReadOnly()){ + return; + } + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(getBackingFile()), "UTF-8")); + writeContent(writer); + writer.flush(); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + protected abstract void writeContent(BufferedWriter writer) throws IOException; + + /** + * Reads contents from file. Assumes lock is held. + * @throws IOException + */ + protected void readContents() throws IOException { + if (!getBackingFile().isFile()){ + return; + } + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader( + new FileInputStream(getBackingFile()), "UTF-8")); + + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + readLine(line); + } + } finally { + if (reader != null) { + reader.close(); + } + } + } + + /** + * Reads contents from the file, first acquring a lock. + * @throws IOException + */ + protected synchronized void readContentsLocked() throws IOException { + doLocked(new Runnable() { + + @Override + public void run() { + try { + readContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }); + } + + /** + * Write contents to the file, first acquring a lock. + * @throws IOException + */ + protected synchronized void writeContentsLocked() throws IOException { + doLocked(new Runnable() { + + public void run() { + try { + writeContents(); + } catch (IOException ex) { + throw new StorageIoException(ex); + } + } + }); + + } + + protected void doLocked(Runnable r) { + lock(); + try { + r.run(); + } finally { + unlock(); + } + } + + protected abstract void readLine(String line); +} diff --git a/netx/net/sourceforge/jnlp/util/lockingfile/StorageIoException.java b/netx/net/sourceforge/jnlp/util/lockingfile/StorageIoException.java new file mode 100644 index 0000000..e0087a2 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/lockingfile/StorageIoException.java @@ -0,0 +1,58 @@ +/* Copyright (C) 2013 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea 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 for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp.util.lockingfile; + +/** + * Thrown when an exception occurs using the storage (namely IOException) + */ +public class StorageIoException extends RuntimeException { + + LockingReaderWriter outer; + + public StorageIoException(Exception e) { + super(e); + } + + public StorageIoException(String e) { + super(e); + } + + public StorageIoException(Exception e, LockingReaderWriter outer) { + super(e); + this.outer = outer; + } +} |