diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java index aa73fb1c81..e2583e2c77 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java @@ -21,12 +21,12 @@ public class ConfigKeyringHandler extends FormHandler { private String _peer; private String _key; private String _secret; + private String[] _revokes; private int _mode; @Override protected void processForm() { - boolean adding = _action.equals(_t("Add key")); - if (adding || _action.equals(_t("Delete key"))) { + if (_action.equals(_t("Add key"))) { if (_peer == null) { addFormError(_t("You must enter a destination")); return; @@ -36,7 +36,7 @@ public class ConfigKeyringHandler extends FormHandler { // don't wait for several seconds for b33 lookup h = ConvertToHash.getHash(_peer); } - if (adding) { + byte[] b = null; if (_mode == 1 || _mode == 4 || _mode == 5) { if (_key == null) { @@ -166,18 +166,37 @@ public class ConfigKeyringHandler extends FormHandler { addFormError(_t("Invalid destination") + ": " + iae.getMessage()); } } - } else { // Delete - if (h != null && h.getData() != 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", h.toBase32())); - } else { - addFormNotice(_t("Key for {0} not found in keyring", h.toBase32())); + + } else if (_action.equals(_t("Delete key")) && _revokes != null) { + // these should all be b32s or b33s + for (String p : _revokes) { + boolean removed = false; + if (p.length() == 60) { + // don't wait for several seconds for b33 lookup + Hash h = ConvertToHash.getHash(p); + if (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) { + removed = true; + } } + } else if (p.length() > 60) { + try { + BlindData bd = Blinding.decode(_context, p); + if (bd != null) { + SigningPublicKey spk = bd.getUnblindedPubKey(); + removed = _context.netDb().removeBlindData(spk); + } + } catch (IllegalArgumentException iae) {} } else { - addFormError(_t("Invalid destination")); + addFormError(_t("Invalid destination") + ": " + p); + } + if (removed) { + addFormNotice(_t("Key for {0} removed from keyring", p)); + } else { + addFormError(_t("Key for {0} not found in keyring", p)); } } } else { @@ -203,4 +222,7 @@ public class ConfigKeyringHandler extends FormHandler { _mode = Integer.parseInt(m); } catch (NumberFormatException nfe) {} } + + /** @since 0.9.41 */ + public void setRevokeClient(String[] revokes) { _revokes = revokes; } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java index 127df7f9d9..260cf0d632 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java @@ -45,7 +45,10 @@ public class ConfigKeyringHelper extends HelperBase { * @param local true for local (Enc. LS1 only), false for remote (all types) */ private void render(StringBuilder buf, boolean local) { - buf.append("\n
").append(_t("Destination")) + buf.append("\n"); + if (!local) + buf.append("
").append(_t("Delete")); + buf.append("").append(_t("Destination")) .append("").append(_t("Name")); if (!local) buf.append("").append(_t("Type")); @@ -59,7 +62,10 @@ public class ConfigKeyringHelper extends HelperBase { if (local != _context.clientManager().isLocal(h)) continue; buf.append("\n
"); - buf.append(h.toBase32()); + String b32 = h.toBase32(); + if (!local) + buf.append(""); + buf.append(b32); buf.append(""); Destination dest = _context.netDb().lookupDestinationLocally(h); if (dest != null && local) { @@ -86,7 +92,10 @@ public class ConfigKeyringHelper extends HelperBase { // TODO sort by hostname for (BlindData bd : bdata) { buf.append("\n
"); - buf.append(bd.toBase32()); + String b32 = bd.toBase32(); + if (!local) + buf.append(""); + buf.append(b32); buf.append(""); Hash h = bd.getDestHash(); if (h != null) { diff --git a/apps/routerconsole/jsp/configkeyring.jsp b/apps/routerconsole/jsp/configkeyring.jsp index 07e8dcf0f1..3b4ba97204 100644 --- a/apps/routerconsole/jsp/configkeyring.jsp +++ b/apps/routerconsole/jsp/configkeyring.jsp @@ -21,9 +21,13 @@

<%=intl._t("The router keyring is used to decrypt encrypted leaseSets.")%> <%=intl._t("The keyring may contain keys for local or remote encrypted destinations.")%>

-
+ +
+ " > + " > +

<%=intl._t("Manual Keyring Addition")%>

@@ -48,7 +52,7 @@ <%=intl._t("Blinded")%> - @@ -66,6 +70,5 @@
" > -" > " >
diff --git a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java index 7bd754cc04..d2402de825 100644 --- a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java @@ -187,4 +187,13 @@ public abstract class NetworkDatabaseFacade implements Service { public List getBlindData() { return null; } + + /** + * For console ConfigKeyringHelper + * @return true if removed + * @since 0.9.41 + */ + public boolean removeBlindData(SigningPublicKey spk) { + return false; + } } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/BlindCache.java b/router/java/src/net/i2p/router/networkdb/kademlia/BlindCache.java index 8be87f86d3..9a10b1a010 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/BlindCache.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/BlindCache.java @@ -249,6 +249,28 @@ class BlindCache { return rv; } + /** + * For console ConfigKeyringHelper. + * Persists immediately if removed. + * + * @param spk the unblinded public key + * @return true if removed + * @since 0.9.41 + */ + public boolean removeBlindData(SigningPublicKey spk) { + boolean rv = false; + BlindData bd = _cache.remove(spk); + if (bd != null) { + rv = true; + _reverseCache.remove(bd.getBlindedPubKey()); + Hash h = bd.getDestHash(); + if (h != null) + _hashCache.remove(h); + store(); + } + return rv; + } + /** * Load from file. * Format: diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index 4062815bfd..e48e4c98fd 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -501,6 +501,16 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad public List getBlindData() { return _blindCache.getData(); } + + /** + * For console ConfigKeyringHelper + * @param spk the unblinded public key + * @return true if removed + * @since 0.9.41 + */ + public boolean removeBlindData(SigningPublicKey spk) { + return _blindCache.removeBlindData(spk); + } /** * @return RouterInfo, LeaseSet, or null, validated