forked from I2P_Developers/i2p.i2p
Keyring: Separate local and remote dests on /configkeyring
Prohibit local changes on /configkeyring Remove local keys from keyring on tunnel shutdown or encryption disable Ensure subsession encryption setting matches primary session (ticket #2108)
This commit is contained in:
@ -33,6 +33,9 @@ public class ConfigKeyringHandler extends FormHandler {
|
||||
} catch (DataFormatException dfe) {}
|
||||
if (h == null || h.getData() == null) {
|
||||
addFormError(_t("Invalid destination"));
|
||||
} else if (_context.clientManager().isLocal(h)) {
|
||||
// don't bother translating
|
||||
addFormError("Cannot add key for local destination. Enable encryption in the Hidden Services Manager.");
|
||||
} else if (sk.getData() == null) {
|
||||
addFormError(_t("Invalid key"));
|
||||
} else {
|
||||
@ -42,12 +45,16 @@ public class ConfigKeyringHandler extends FormHandler {
|
||||
}
|
||||
} else { // Delete
|
||||
if (h != null && h.getData() != null) {
|
||||
if (_context.keyRing().remove(h) != null)
|
||||
if (_context.clientManager().isLocal(h)) {
|
||||
// don't bother translating
|
||||
addFormError("Cannot remove key for local destination. Disable encryption in the Hidden Services Manager.");
|
||||
} else if (_context.keyRing().remove(h) != null) {
|
||||
addFormNotice(_t("Key for {0} removed from keyring",
|
||||
Base32.encode(h.getData()) + ".b32.i2p"));
|
||||
else
|
||||
} else {
|
||||
addFormNotice(_t("Key for {0} not found in keyring",
|
||||
Base32.encode(h.getData()) + ".b32.i2p"));
|
||||
}
|
||||
} else {
|
||||
addFormError(_t("Invalid destination"));
|
||||
}
|
||||
|
@ -30,17 +30,31 @@ public class ConfigKeyringHelper extends HelperBase {
|
||||
*/
|
||||
private void renderStatusHTML(StringWriter out) throws IOException {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
buf.append("<h3>").append(_t("Local encrypted destinations")).append("</h3>");
|
||||
render(buf, true);
|
||||
buf.append("<h3>").append(_t("Remote encrypted destinations")).append("</h3>");
|
||||
render(buf, false);
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.33 moved from PersistentKeyRing
|
||||
*/
|
||||
private void render(StringBuilder buf, boolean local) {
|
||||
buf.append("\n<table class=\"configtable\"><tr><th align=\"left\">").append(_t("Destination"))
|
||||
.append("<th align=\"left\">").append(_t("Name"))
|
||||
.append("<th align=\"left\">").append(_t("Encryption Key"))
|
||||
.append("</tr>");
|
||||
for (Map.Entry<Hash, SessionKey> e : _context.keyRing().entrySet()) {
|
||||
buf.append("\n<tr><td>");
|
||||
Hash h = e.getKey();
|
||||
if (local != _context.clientManager().isLocal(h))
|
||||
continue;
|
||||
buf.append("\n<tr><td>");
|
||||
buf.append(Base32.encode(h.getData())).append(".b32.i2p");
|
||||
buf.append("</td><td>");
|
||||
Destination dest = _context.netDb().lookupDestinationLocally(h);
|
||||
if (dest != null && _context.clientManager().isLocal(dest)) {
|
||||
if (dest != null && local) {
|
||||
TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(h);
|
||||
if (in != null && in.getDestinationNickname() != null)
|
||||
buf.append(in.getDestinationNickname());
|
||||
@ -55,7 +69,5 @@ public class ConfigKeyringHelper extends HelperBase {
|
||||
buf.append("</td>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
@ -360,6 +360,10 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
session.destroySession();
|
||||
} catch (I2PSessionException ise) {}
|
||||
}
|
||||
// do we need this here? subsession.destroySession() calls primary
|
||||
Destination d = session.getMyDestination();
|
||||
if (d != null)
|
||||
_context.keyRing().remove(d.calculateHash());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1210,6 +1214,10 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
private void closeSocket() {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix() + "Closing the socket", new Exception("closeSocket"));
|
||||
// maybe not the right place for this, but let's be sure
|
||||
Destination d = _myDestination;
|
||||
if (d != null)
|
||||
_context.keyRing().remove(d.calculateHash());
|
||||
synchronized(_stateLock) {
|
||||
changeState(State.CLOSING);
|
||||
locked_closeSocket();
|
||||
@ -1217,6 +1225,9 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
}
|
||||
synchronized (_subsessionLock) {
|
||||
for (SubSession sess : _subsessions) {
|
||||
d = sess.getMyDestination();
|
||||
if (d != null)
|
||||
_context.keyRing().remove(d.calculateHash());
|
||||
sess.changeState(State.CLOSED);
|
||||
sess.setSessionId(null);
|
||||
sess.setLeaseSet(null);
|
||||
|
@ -12,6 +12,7 @@ package net.i2p.client.impl;
|
||||
import java.io.EOFException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -21,6 +22,7 @@ import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.Lease;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.PrivateKey;
|
||||
@ -158,17 +160,27 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
|
||||
leaseSet.setEncryptionKey(li.getPublicKey());
|
||||
leaseSet.setSigningKey(li.getSigningPublicKey());
|
||||
boolean encrypt = Boolean.parseBoolean(session.getOptions().getProperty("i2cp.encryptLeaseSet"));
|
||||
String sk = session.getOptions().getProperty("i2cp.leaseSetKey");
|
||||
// SubSession options aren't updated via the gui, so use the primary options
|
||||
Properties opts;
|
||||
if (session instanceof SubSession)
|
||||
opts = ((SubSession) session).getPrimaryOptions();
|
||||
else
|
||||
opts = session.getOptions();
|
||||
boolean encrypt = Boolean.parseBoolean(opts.getProperty("i2cp.encryptLeaseSet"));
|
||||
String sk = opts.getProperty("i2cp.leaseSetKey");
|
||||
Hash h = dest.calculateHash();
|
||||
if (encrypt && sk != null) {
|
||||
SessionKey key = new SessionKey();
|
||||
try {
|
||||
key.fromBase64(sk);
|
||||
leaseSet.encrypt(key);
|
||||
_context.keyRing().put(session.getMyDestination().calculateHash(), key);
|
||||
_context.keyRing().put(h, key);
|
||||
} catch (DataFormatException dfe) {
|
||||
_log.error("Bad leaseset key: " + sk);
|
||||
_context.keyRing().remove(h);
|
||||
}
|
||||
} else {
|
||||
_context.keyRing().remove(h);
|
||||
}
|
||||
try {
|
||||
leaseSet.sign(session.getPrivateKey());
|
||||
|
@ -85,6 +85,13 @@ class SubSession extends I2PSessionMuxedImpl {
|
||||
@Override
|
||||
public void updateOptions(Properties options) {}
|
||||
|
||||
/**
|
||||
* @since 0.9.33
|
||||
*/
|
||||
public Properties getPrimaryOptions() {
|
||||
return _primary.getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the router and establish a session. This call blocks until
|
||||
* a session is granted.
|
||||
|
@ -1,3 +1,10 @@
|
||||
2018-01-14 zzz
|
||||
* Keyring (ticket #2108):
|
||||
- Separate local and remote dests on /configkeyring
|
||||
- Prohibit local changes on /configkeyring
|
||||
- Remove local keys on tunnel shutdown or encryption disable
|
||||
- Ensure subsession encryption setting matches primary session
|
||||
|
||||
2018-01-13 zzz
|
||||
* SessionKeyManager: Clean up sessions with excess tagsets
|
||||
|
||||
|
@ -38,11 +38,12 @@ public class PersistentKeyRing extends KeyRing {
|
||||
|
||||
@Override
|
||||
public SessionKey remove(Object o) {
|
||||
if (o != null && o instanceof Hash) {
|
||||
SessionKey rv = super.remove(o);
|
||||
if (rv != null && o != null && o instanceof Hash) {
|
||||
Hash h = (Hash) o;
|
||||
_ctx.router().saveConfig(PROP_PFX + h.toBase64().replace("=", "$"), null);
|
||||
}
|
||||
return super.remove(o);
|
||||
return rv;
|
||||
}
|
||||
|
||||
private void addFromProperties() {
|
||||
|
@ -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 = 20;
|
||||
public final static long BUILD = 21;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
Reference in New Issue
Block a user