forked from I2P_Developers/i2p.i2p
* 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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.i2p.util.SecureFile;
|
||||||
import net.i2p.util.SecureFileOutputStream;
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -280,7 +281,7 @@ public class ConfigParser {
|
|||||||
* if file cannot be written to.
|
* if file cannot be written to.
|
||||||
*/
|
*/
|
||||||
public static void write(Map map, File file) throws IOException {
|
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
|
ConfigParser
|
||||||
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
|
||||||
boolean success = tmp.renameTo(file);
|
boolean success = tmp.renameTo(file);
|
||||||
|
@ -27,6 +27,7 @@ import net.i2p.util.EepGet;
|
|||||||
import net.i2p.util.FileUtil;
|
import net.i2p.util.FileUtil;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SecureDirectory;
|
import net.i2p.util.SecureDirectory;
|
||||||
|
import net.i2p.util.SecureFile;
|
||||||
import net.i2p.util.SimpleScheduler;
|
import net.i2p.util.SimpleScheduler;
|
||||||
import net.i2p.util.SimpleTimer;
|
import net.i2p.util.SimpleTimer;
|
||||||
import net.i2p.util.Translate;
|
import net.i2p.util.Translate;
|
||||||
@ -244,7 +245,7 @@ public class I2PSnarkUtil {
|
|||||||
File out = null;
|
File out = null;
|
||||||
try {
|
try {
|
||||||
// we could use the system tmp dir but deleteOnExit() doesn't seem to work on all platforms...
|
// 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) {
|
} catch (IOException ioe) {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
if (out != null)
|
if (out != null)
|
||||||
|
@ -29,6 +29,7 @@ import java.util.List;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import net.i2p.crypto.SHA1;
|
import net.i2p.crypto.SHA1;
|
||||||
|
import net.i2p.util.SecureFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains pieces on disk. Can be used to store and retrieve pieces.
|
* 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 */
|
/** use a saved bitfield and timestamp from a config file */
|
||||||
public void check(String rootDir, long savedTime, BitField savedBitField) throws IOException
|
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;
|
boolean useSavedBitField = savedTime > 0 && savedBitField != null;
|
||||||
|
|
||||||
List files = metainfo.getFiles();
|
List files = metainfo.getFiles();
|
||||||
@ -623,7 +624,7 @@ public class Storage
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The final element (file) in the hierarchy.
|
// The final element (file) in the hierarchy.
|
||||||
f = new File(base, name);
|
f = new SecureFile(base, name);
|
||||||
if (!f.createNewFile() && !f.exists())
|
if (!f.createNewFile() && !f.exists())
|
||||||
throw new IOException("Could not create file " + f);
|
throw new IOException("Could not create file " + f);
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,11 @@ public class I2PAppContext {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static I2PAppContext getGlobalContext() {
|
public static I2PAppContext getGlobalContext() {
|
||||||
|
// skip the global lock
|
||||||
|
I2PAppContext rv = _globalAppContext;
|
||||||
|
if (rv != null)
|
||||||
|
return rv;
|
||||||
|
|
||||||
synchronized (I2PAppContext.class) {
|
synchronized (I2PAppContext.class) {
|
||||||
if (_globalAppContext == null) {
|
if (_globalAppContext == null) {
|
||||||
_globalAppContext = new I2PAppContext(false, null);
|
_globalAppContext = new I2PAppContext(false, null);
|
||||||
@ -122,6 +127,18 @@ public class I2PAppContext {
|
|||||||
return _globalAppContext;
|
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
|
* Lets root a brand new context
|
||||||
*
|
*
|
||||||
@ -257,6 +274,7 @@ public class I2PAppContext {
|
|||||||
_appDir = _routerDir;
|
_appDir = _routerDir;
|
||||||
}
|
}
|
||||||
/******
|
/******
|
||||||
|
(new Exception("Initialized by")).printStackTrace();
|
||||||
System.err.println("Base directory: " + _baseDir.getAbsolutePath());
|
System.err.println("Base directory: " + _baseDir.getAbsolutePath());
|
||||||
System.err.println("Config directory: " + _configDir.getAbsolutePath());
|
System.err.println("Config directory: " + _configDir.getAbsolutePath());
|
||||||
System.err.println("Router directory: " + _routerDir.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
|
* 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)
|
* 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
|
* @since 0.8.1
|
||||||
* @author zzz
|
* @author zzz
|
||||||
*/
|
*/
|
||||||
public class SecureDirectory extends File {
|
public class SecureDirectory extends File {
|
||||||
|
|
||||||
private static final boolean canSetPerms =
|
protected static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
|
||||||
(new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
|
|
||||||
private static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
|
|
||||||
|
|
||||||
public SecureDirectory(String pathname) {
|
public SecureDirectory(String pathname) {
|
||||||
super(pathname);
|
super(pathname);
|
||||||
@ -54,8 +53,8 @@ public class SecureDirectory extends File {
|
|||||||
* Tries to set the permissions to 700,
|
* Tries to set the permissions to 700,
|
||||||
* ignores errors
|
* ignores errors
|
||||||
*/
|
*/
|
||||||
private void setPerms() {
|
protected void setPerms() {
|
||||||
if (!canSetPerms)
|
if (!SecureFileOutputStream.canSetPerms())
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
setReadable(false, false);
|
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.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as FileOutputStream but sets the file mode so it can only
|
* 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)
|
* 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 {
|
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;
|
(new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,12 +53,22 @@ public class SecureFileOutputStream extends FileOutputStream {
|
|||||||
setPerms(file);
|
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,
|
* Tries to set the permissions to 600,
|
||||||
* ignores errors
|
* ignores errors
|
||||||
*/
|
*/
|
||||||
public static void setPerms(File f) {
|
public static void setPerms(File f) {
|
||||||
if (!canSetPerms)
|
if (!canSetPerms())
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
f.setReadable(false, false);
|
f.setReadable(false, false);
|
||||||
|
Reference in New Issue
Block a user