propagate from branch 'i2p.i2p.zzz.test2' (head 5c1b78bd78845b0c8b90fbb60412c68e7dc4f3e6)

to branch 'i2p.i2p' (head 8bdc25c8e6f40491f20b533d94eacab012adba35)
This commit is contained in:
zzz
2013-10-13 11:48:12 +00:00
135 changed files with 19078 additions and 16810 deletions

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 25;
public final static long BUILD = 1;
/** for example "-test" */
public final static String EXTRA = "";

View File

@@ -21,13 +21,12 @@ import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLContext;
import net.i2p.client.I2PClient;
import net.i2p.crypto.CertUtil;
import net.i2p.crypto.KeyStoreUtil;
import net.i2p.data.Base32;
import net.i2p.data.Base64;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import net.i2p.util.SecureDirectory;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.ShellCommand;
/**
* SSL version of ClientListenerRunner
@@ -87,31 +86,14 @@ class SSLClientListenerRunner extends ClientListenerRunner {
*/
private boolean createKeyStore(File ks) {
// make a random 48 character password (30 * 8 / 5)
byte[] rand = new byte[30];
_context.random().nextBytes(rand);
String keyPassword = Base32.encode(rand);
String keyPassword = KeyStoreUtil.randomString();
// and one for the cname
_context.random().nextBytes(rand);
String cname = Base32.encode(rand) + ".i2cp.i2p.net";
String cname = KeyStoreUtil.randomString() + ".i2cp.i2p.net";
String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
String[] args = new String[] {
keytool,
"-genkey", // -genkeypair preferred in newer keytools, but this works with more
"-storetype", KeyStore.getDefaultType(),
"-keystore", ks.getAbsolutePath(),
"-storepass", DEFAULT_KEYSTORE_PASSWORD,
"-alias", KEY_ALIAS,
"-dname", "CN=" + cname + ",OU=I2CP,O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
"-validity", "3652", // 10 years
"-keyalg", "DSA",
"-keysize", "1024",
"-keypass", keyPassword};
boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 30); // 30 secs
boolean success = KeyStoreUtil.createKeys(ks, KEY_ALIAS, cname, "I2CP", keyPassword);
if (success) {
success = ks.exists();
if (success) {
SecureFileOutputStream.setPerms(ks);
Map<String, String> changes = new HashMap();
changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
changes.put(PROP_KEY_PASSWORD, keyPassword);
@@ -123,13 +105,8 @@ class SSLClientListenerRunner extends ClientListenerRunner {
"The certificate name was generated randomly, and is not associated with your " +
"IP address, host name, router identity, or destination keys.");
} else {
_log.error("Failed to create I2CP SSL keystore using command line:");
StringBuilder buf = new StringBuilder(256);
for (int i = 0; i < args.length; i++) {
buf.append('"').append(args[i]).append("\" ");
}
_log.error(buf.toString());
_log.error("This is for the Sun/Oracle keytool, others may be incompatible.\n" +
_log.error("Failed to create I2CP SSL keystore.\n" +
"This is for the Sun/Oracle keytool, others may be incompatible.\n" +
"If you create the keystore manually, you must add " + PROP_KEYSTORE_PASSWORD + " and " + PROP_KEY_PASSWORD +
" to " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
}
@@ -143,62 +120,16 @@ class SSLClientListenerRunner extends ClientListenerRunner {
private void exportCert(File ks) {
File sdir = new SecureDirectory(_context.getConfigDir(), "certificates");
if (sdir.exists() || sdir.mkdir()) {
InputStream fis = null;
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
fis = new FileInputStream(ks);
String ksPass = _context.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
keyStore.load(fis, ksPass.toCharArray());
Certificate cert = keyStore.getCertificate(KEY_ALIAS);
if (cert != null) {
File certFile = new File(sdir, ASCII_KEYFILE);
saveCert(cert, certFile);
} else {
_log.error("Error getting SSL cert to save as ASCII");
}
} catch (GeneralSecurityException gse) {
_log.error("Error saving ASCII SSL keys", gse);
} catch (IOException ioe) {
_log.error("Error saving ASCII SSL keys", ioe);
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
String ksPass = _context.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
File out = new File(sdir, ASCII_KEYFILE);
boolean success = KeyStoreUtil.exportCert(ks, ksPass, KEY_ALIAS, out);
if (!success)
_log.error("Error getting SSL cert to save as ASCII");
} else {
_log.error("Error saving ASCII SSL keys");
}
}
private static final int LINE_LENGTH = 64;
/**
* Modified from:
* http://www.exampledepot.com/egs/java.security.cert/ExportCert.html
*
* Write a certificate to a file in base64 format.
*/
private void saveCert(Certificate cert, File file) {
OutputStream os = null;
try {
// Get the encoded form which is suitable for exporting
byte[] buf = cert.getEncoded();
os = new SecureFileOutputStream(file);
PrintWriter wr = new PrintWriter(os);
wr.println("-----BEGIN CERTIFICATE-----");
String b64 = Base64.encode(buf, true); // true = use standard alphabet
for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
}
wr.println("-----END CERTIFICATE-----");
wr.flush();
} catch (CertificateEncodingException cee) {
_log.error("Error writing X509 Certificate " + file.getAbsolutePath(), cee);
} catch (IOException ioe) {
_log.error("Error writing X509 Certificate " + file.getAbsolutePath(), ioe);
} finally {
try { if (os != null) os.close(); } catch (IOException foo) {}
}
}
/**
* Sets up the SSLContext and sets the socket factory.
* @return success

View File

@@ -67,7 +67,7 @@ class IterativeSearchJob extends FloodSearchJob {
private static final int MAX_NON_FF = 3;
/** Max number of peers to query */
private static final int TOTAL_SEARCH_LIMIT = 8;
private static final int TOTAL_SEARCH_LIMIT = 7;
/** TOTAL_SEARCH_LIMIT * SINGLE_SEARCH_TIME, plus some extra */
private static final int MAX_SEARCH_TIME = 30*1000;
/**

View File

@@ -13,6 +13,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.crypto.KeyGenerator;
import net.i2p.data.DataFormatException;
@@ -28,9 +29,8 @@ import net.i2p.util.Log;
public class LoadRouterInfoJob extends JobImpl {
private final Log _log;
private boolean _keysExist;
private boolean _infoExists;
private RouterInfo _us;
private static final AtomicBoolean _keyLengthChecked = new AtomicBoolean();
public LoadRouterInfoJob(RouterContext ctx) {
super(ctx);
@@ -61,11 +61,9 @@ public class LoadRouterInfoJob extends JobImpl {
String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
File rif = new File(getContext().getRouterDir(), routerInfoFile);
if (rif.exists())
_infoExists = true;
boolean infoExists = rif.exists();
File rkf = new File(getContext().getRouterDir(), keyFilename);
if (rkf.exists())
_keysExist = true;
boolean keysExist = rkf.exists();
InputStream fis1 = null;
InputStream fis2 = null;
@@ -76,7 +74,7 @@ public class LoadRouterInfoJob extends JobImpl {
// CRIT ...sport.udp.EstablishmentManager: Error in the establisher java.lang.NullPointerException
// at net.i2p.router.transport.udp.PacketBuilder.buildSessionConfirmedPacket(PacketBuilder.java:574)
// so pretend the RI isn't there if there is no keyfile
if (_infoExists && _keysExist) {
if (infoExists && keysExist) {
fis1 = new BufferedInputStream(new FileInputStream(rif));
info = new RouterInfo();
info.readBytes(fis1);
@@ -88,16 +86,21 @@ public class LoadRouterInfoJob extends JobImpl {
_us = info;
}
if (_keysExist) {
if (keysExist) {
fis2 = new BufferedInputStream(new FileInputStream(rkf));
PrivateKey privkey = new PrivateKey();
privkey.readBytes(fis2);
if (shouldRebuild(privkey)) {
_us = null;
// windows... close before deleting
if (fis1 != null) {
try { fis1.close(); } catch (IOException ioe) {}
fis1 = null;
}
try { fis2.close(); } catch (IOException ioe) {}
fis2 = null;
rif.delete();
rkf.delete();
_infoExists = false;
_keysExist = false;
return;
}
SigningPrivateKey signingPrivKey = new SigningPrivateKey();
@@ -112,17 +115,31 @@ public class LoadRouterInfoJob extends JobImpl {
} catch (IOException ioe) {
_log.log(Log.CRIT, "Error reading the router info from " + rif.getAbsolutePath() + " and the keys from " + rkf.getAbsolutePath(), ioe);
_us = null;
// windows... close before deleting
if (fis1 != null) {
try { fis1.close(); } catch (IOException ioe2) {}
fis1 = null;
}
if (fis2 != null) {
try { fis2.close(); } catch (IOException ioe2) {}
fis2 = null;
}
rif.delete();
rkf.delete();
_infoExists = false;
_keysExist = false;
} catch (DataFormatException dfe) {
_log.log(Log.CRIT, "Corrupt router info or keys at " + rif.getAbsolutePath() + " / " + rkf.getAbsolutePath(), dfe);
_us = null;
// windows... close before deleting
if (fis1 != null) {
try { fis1.close(); } catch (IOException ioe) {}
fis1 = null;
}
if (fis2 != null) {
try { fis2.close(); } catch (IOException ioe) {}
fis2 = null;
}
rif.delete();
rkf.delete();
_infoExists = false;
_keysExist = false;
} finally {
if (fis1 != null) try { fis1.close(); } catch (IOException ioe) {}
if (fis2 != null) try { fis2.close(); } catch (IOException ioe) {}
@@ -135,6 +152,11 @@ public class LoadRouterInfoJob extends JobImpl {
* @since 0.9.8
*/
private boolean shouldRebuild(PrivateKey privkey) {
// Prevent returning true more than once, ever.
// If we are called a second time, it's probably because we failed
// to delete router.keys for some reason.
if (!_keyLengthChecked.compareAndSet(false, true))
return false;
byte[] pkd = privkey.getData();
boolean haslong = false;
for (int i = 0; i < 8; i++) {

View File

@@ -76,6 +76,7 @@ public class RebuildRouterInfoJob extends JobImpl {
void rebuildRouterInfo() {
rebuildRouterInfo(true);
}
void rebuildRouterInfo(boolean alreadyRunning) {
_log.debug("Rebuilding the new router info");
RouterInfo info = null;
@@ -86,8 +87,8 @@ public class RebuildRouterInfoJob extends JobImpl {
if (keyFile.exists()) {
// ok, no need to rebuild a brand new identity, just update what we can
info = getContext().router().getRouterInfo();
if (info == null) {
RouterInfo oldinfo = getContext().router().getRouterInfo();
if (oldinfo == null) {
info = new RouterInfo();
FileInputStream fis = null;
try {
@@ -116,6 +117,9 @@ public class RebuildRouterInfoJob extends JobImpl {
} finally {
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
}
} else {
// Make a new RI from the old identity, or else info.setAddresses() will throw an ISE
info = new RouterInfo(oldinfo);
}
try {