* SecureFile: New class, catch places that were missed,

add i2p.insecureFiles option to disable (default false)
This commit is contained in:
zzz
2010-11-19 00:40:33 +00:00
parent 50d9080e26
commit e940f51599
7 changed files with 124 additions and 11 deletions

View File

@ -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);

View 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)

View File

@ -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);
}

View File

@ -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());

View File

@ -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);

View 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
}
}
}

View File

@ -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);