* SecureFile: New class, catch places that were missed,
add i2p.insecureFiles option to disable (default false)
This commit is contained in:
@ -35,6 +35,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.util.SecureFile;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
/**
|
||||
@ -280,7 +281,7 @@ public class ConfigParser {
|
||||
* if file cannot be written to.
|
||||
*/
|
||||
public static void write(Map map, File file) throws IOException {
|
||||
File tmp = File.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
|
||||
File tmp = SecureFile.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
|
||||
ConfigParser
|
||||
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
||||
boolean success = tmp.renameTo(file);
|
||||
|
@ -27,6 +27,7 @@ import net.i2p.util.EepGet;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFile;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.util.Translate;
|
||||
@ -244,7 +245,7 @@ public class I2PSnarkUtil {
|
||||
File out = null;
|
||||
try {
|
||||
// we could use the system tmp dir but deleteOnExit() doesn't seem to work on all platforms...
|
||||
out = File.createTempFile("i2psnark", null, _tmpDir);
|
||||
out = SecureFile.createTempFile("i2psnark", null, _tmpDir);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
if (out != null)
|
||||
|
@ -29,6 +29,7 @@ import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.crypto.SHA1;
|
||||
import net.i2p.util.SecureFile;
|
||||
|
||||
/**
|
||||
* Maintains pieces on disk. Can be used to store and retrieve pieces.
|
||||
@ -462,7 +463,7 @@ public class Storage
|
||||
/** use a saved bitfield and timestamp from a config file */
|
||||
public void check(String rootDir, long savedTime, BitField savedBitField) throws IOException
|
||||
{
|
||||
File base = new File(rootDir, filterName(metainfo.getName()));
|
||||
File base = new SecureFile(rootDir, filterName(metainfo.getName()));
|
||||
boolean useSavedBitField = savedTime > 0 && savedBitField != null;
|
||||
|
||||
List files = metainfo.getFiles();
|
||||
@ -623,7 +624,7 @@ public class Storage
|
||||
else
|
||||
{
|
||||
// The final element (file) in the hierarchy.
|
||||
f = new File(base, name);
|
||||
f = new SecureFile(base, name);
|
||||
if (!f.createNewFile() && !f.exists())
|
||||
throw new IOException("Could not create file " + f);
|
||||
}
|
||||
|
@ -114,6 +114,11 @@ public class I2PAppContext {
|
||||
*
|
||||
*/
|
||||
public static I2PAppContext getGlobalContext() {
|
||||
// skip the global lock
|
||||
I2PAppContext rv = _globalAppContext;
|
||||
if (rv != null)
|
||||
return rv;
|
||||
|
||||
synchronized (I2PAppContext.class) {
|
||||
if (_globalAppContext == null) {
|
||||
_globalAppContext = new I2PAppContext(false, null);
|
||||
@ -122,6 +127,18 @@ public class I2PAppContext {
|
||||
return _globalAppContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the default context, WITHOUT creating a new one.
|
||||
* Use this in static methods used early in router initialization,
|
||||
* where creating a context messes things up.
|
||||
*
|
||||
* @return context or null
|
||||
* @since 0.8.2
|
||||
*/
|
||||
public static I2PAppContext getCurrentContext() {
|
||||
return _globalAppContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets root a brand new context
|
||||
*
|
||||
@ -257,6 +274,7 @@ public class I2PAppContext {
|
||||
_appDir = _routerDir;
|
||||
}
|
||||
/******
|
||||
(new Exception("Initialized by")).printStackTrace();
|
||||
System.err.println("Base directory: " + _baseDir.getAbsolutePath());
|
||||
System.err.println("Config directory: " + _configDir.getAbsolutePath());
|
||||
System.err.println("Router directory: " + _routerDir.getAbsolutePath());
|
||||
|
@ -5,15 +5,14 @@ import java.io.File;
|
||||
/**
|
||||
* Same as File but sets the file mode after mkdir() so it can
|
||||
* be read and written by the owner only (i.e. 700 on linux)
|
||||
* As of 0.8.2, just use SecureFile instead of this.
|
||||
*
|
||||
* @since 0.8.1
|
||||
* @author zzz
|
||||
*/
|
||||
public class SecureDirectory extends File {
|
||||
|
||||
private static final boolean canSetPerms =
|
||||
(new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
|
||||
private static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
|
||||
protected static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
|
||||
|
||||
public SecureDirectory(String pathname) {
|
||||
super(pathname);
|
||||
@ -54,8 +53,8 @@ public class SecureDirectory extends File {
|
||||
* Tries to set the permissions to 700,
|
||||
* ignores errors
|
||||
*/
|
||||
private void setPerms() {
|
||||
if (!canSetPerms)
|
||||
protected void setPerms() {
|
||||
if (!SecureFileOutputStream.canSetPerms())
|
||||
return;
|
||||
try {
|
||||
setReadable(false, false);
|
||||
|
81
core/java/src/net/i2p/util/SecureFile.java
Normal file
81
core/java/src/net/i2p/util/SecureFile.java
Normal file
@ -0,0 +1,81 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Same as SecureDirectory but sets the file mode after createNewFile()
|
||||
* and createTempFile() also. So just use this instead.
|
||||
* Probably should have just made this class in the beginning and not had two.
|
||||
*
|
||||
* @since 0.8.2
|
||||
* @author zzz
|
||||
*/
|
||||
public class SecureFile extends SecureDirectory {
|
||||
|
||||
public SecureFile(String pathname) {
|
||||
super(pathname);
|
||||
}
|
||||
|
||||
public SecureFile(String parent, String child) {
|
||||
super(parent, child);
|
||||
}
|
||||
|
||||
public SecureFile(File parent, String child) {
|
||||
super(parent, child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets file to mode 600 if the file is created
|
||||
*/
|
||||
@Override
|
||||
public boolean createNewFile() throws IOException {
|
||||
boolean rv = super.createNewFile();
|
||||
if (rv)
|
||||
setPerms();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets file to mode 600 when the file is created
|
||||
*/
|
||||
public static File createTempFile(String prefix, String suffix) throws IOException {
|
||||
File rv = File.createTempFile(prefix, suffix);
|
||||
// same thing as below but static
|
||||
SecureFileOutputStream.setPerms(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets file to mode 600 when the file is created
|
||||
*/
|
||||
public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
|
||||
File rv = File.createTempFile(prefix, suffix, directory);
|
||||
// same thing as below but static
|
||||
SecureFileOutputStream.setPerms(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to set the permissions to 600,
|
||||
* ignores errors
|
||||
*/
|
||||
@Override
|
||||
protected void setPerms() {
|
||||
if (!SecureFileOutputStream.canSetPerms())
|
||||
return;
|
||||
try {
|
||||
setReadable(false, false);
|
||||
setReadable(true, true);
|
||||
setWritable(false, false);
|
||||
setWritable(true, true);
|
||||
if (isNotWindows && isDirectory()) {
|
||||
setExecutable(false, false);
|
||||
setExecutable(true, true);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// NoSuchMethodException or NoSuchMethodError if we somehow got the
|
||||
// version detection wrong or the JVM doesn't support it
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
/**
|
||||
* Same as FileOutputStream but sets the file mode so it can only
|
||||
* be read and written by the owner only (i.e. 600 on linux)
|
||||
@ -13,7 +15,7 @@ import java.io.FileOutputStream;
|
||||
*/
|
||||
public class SecureFileOutputStream extends FileOutputStream {
|
||||
|
||||
private static final boolean canSetPerms =
|
||||
private static final boolean oneDotSix =
|
||||
(new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
|
||||
|
||||
/**
|
||||
@ -51,12 +53,22 @@ public class SecureFileOutputStream extends FileOutputStream {
|
||||
setPerms(file);
|
||||
}
|
||||
|
||||
/** @since 0.8.2 */
|
||||
static boolean canSetPerms() {
|
||||
if (!oneDotSix)
|
||||
return false;
|
||||
I2PAppContext ctx = I2PAppContext.getCurrentContext();
|
||||
if (ctx == null)
|
||||
return true;
|
||||
return !ctx.getBooleanProperty("i2p.insecureFiles");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to set the permissions to 600,
|
||||
* ignores errors
|
||||
*/
|
||||
public static void setPerms(File f) {
|
||||
if (!canSetPerms)
|
||||
if (!canSetPerms())
|
||||
return;
|
||||
try {
|
||||
f.setReadable(false, false);
|
||||
|
Reference in New Issue
Block a user