Skip to content

Commit

Permalink
* Startup: Fix rekeying on Windows (tickets #1056, 1057)
Browse files Browse the repository at this point in the history
  • Loading branch information
zzz committed Oct 1, 2013
1 parent cbd2494 commit cba3b24
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 17 deletions.
3 changes: 3 additions & 0 deletions history.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2013-10-01 zzz
* Startup: Fix rekeying on Windows (tickets #1056, 1057)

* 2013-09-30 0.9.8 released

2013-09-26 kytv
Expand Down
2 changes: 1 addition & 1 deletion router/java/src/net/i2p/router/RouterVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 0;
public final static long BUILD = 1;

/** for example "-test" */
public final static String EXTRA = "";
Expand Down
50 changes: 36 additions & 14 deletions router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
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;
Expand All @@ -28,9 +29,8 @@

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);
Expand Down Expand Up @@ -61,11 +61,9 @@ private void loadRouterInfo() {
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;
Expand All @@ -76,7 +74,7 @@ private void loadRouterInfo() {
// 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);
Expand All @@ -88,16 +86,21 @@ private void loadRouterInfo() {
_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();
Expand All @@ -112,17 +115,31 @@ private void loadRouterInfo() {
} 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) {}
Expand All @@ -135,6 +152,11 @@ private void loadRouterInfo() {
* @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++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public void runJob() {
void rebuildRouterInfo() {
rebuildRouterInfo(true);
}

void rebuildRouterInfo(boolean alreadyRunning) {
_log.debug("Rebuilding the new router info");
RouterInfo info = null;
Expand All @@ -86,8 +87,8 @@ void rebuildRouterInfo(boolean alreadyRunning) {

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 {
Expand Down Expand Up @@ -116,6 +117,9 @@ void rebuildRouterInfo(boolean alreadyRunning) {
} 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 {
Expand Down

0 comments on commit cba3b24

Please sign in to comment.