forked from I2P_Developers/i2p.i2p
Console: Move /configkeyring HTML to console,
don't truncate hashes, tag for translation, display as b32, trim form data, better form errors, fix removing entries, parameterize form messages (ticket #2108)
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
package net.i2p.router.web.helpers;
|
package net.i2p.router.web.helpers;
|
||||||
|
|
||||||
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.SessionKey;
|
import net.i2p.data.SessionKey;
|
||||||
@ -30,18 +31,23 @@ public class ConfigKeyringHandler extends FormHandler {
|
|||||||
try {
|
try {
|
||||||
sk.fromBase64(_key);
|
sk.fromBase64(_key);
|
||||||
} catch (DataFormatException dfe) {}
|
} catch (DataFormatException dfe) {}
|
||||||
if (h != null && h.getData() != null && sk.getData() != null) {
|
if (h == null || h.getData() == null) {
|
||||||
_context.keyRing().put(h, sk);
|
addFormError(_t("Invalid destination"));
|
||||||
addFormNotice(_t("Key for") + " " + h.toBase64() + " " + _t("added to keyring"));
|
} else if (sk.getData() == null) {
|
||||||
|
addFormError(_t("Invalid key"));
|
||||||
} else {
|
} else {
|
||||||
addFormError(_t("Invalid destination or key"));
|
_context.keyRing().put(h, sk);
|
||||||
|
addFormNotice(_t("Key for {0} added to keyring",
|
||||||
|
Base32.encode(h.getData()) + ".b32.i2p"));
|
||||||
}
|
}
|
||||||
} else { // Delete
|
} else { // Delete
|
||||||
if (h != null && h.getData() != null) {
|
if (h != null && h.getData() != null) {
|
||||||
if (_context.keyRing().remove(h) != null)
|
if (_context.keyRing().remove(h) != null)
|
||||||
addFormNotice(_t("Key for") + " " + h.toBase64() + " " + _t("removed from keyring"));
|
addFormNotice(_t("Key for {0} removed from keyring",
|
||||||
|
Base32.encode(h.getData()) + ".b32.i2p"));
|
||||||
else
|
else
|
||||||
addFormNotice(_t("Key for") + " " + h.toBase64() + " " + _t("not found in keyring"));
|
addFormNotice(_t("Key for {0} not found in keyring",
|
||||||
|
Base32.encode(h.getData()) + ".b32.i2p"));
|
||||||
} else {
|
} else {
|
||||||
addFormError(_t("Invalid destination"));
|
addFormError(_t("Invalid destination"));
|
||||||
}
|
}
|
||||||
@ -51,6 +57,6 @@ public class ConfigKeyringHandler extends FormHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPeer(String peer) { _peer = peer; }
|
public void setPeer(String peer) { if (peer != null) _peer = peer.trim(); }
|
||||||
public void setKey(String peer) { _key = peer; }
|
public void setKey(String key) { if (key != null) _key = key.trim(); }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,13 @@ package net.i2p.router.web.helpers;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.i2p.data.Base32;
|
||||||
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.data.Hash;
|
||||||
|
import net.i2p.data.SessionKey;
|
||||||
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import net.i2p.router.web.HelperBase;
|
import net.i2p.router.web.HelperBase;
|
||||||
|
|
||||||
|
|
||||||
@ -12,10 +18,44 @@ public class ConfigKeyringHelper extends HelperBase {
|
|||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
StringWriter sw = new StringWriter(4*1024);
|
StringWriter sw = new StringWriter(4*1024);
|
||||||
try {
|
try {
|
||||||
_context.keyRing().renderStatusHTML(sw);
|
renderStatusHTML(sw);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
}
|
||||||
return sw.toString();
|
return sw.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.9.33 moved from PersistentKeyRing
|
||||||
|
*/
|
||||||
|
private void renderStatusHTML(StringWriter out) throws IOException {
|
||||||
|
StringBuilder buf = new StringBuilder(1024);
|
||||||
|
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();
|
||||||
|
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)) {
|
||||||
|
TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(h);
|
||||||
|
if (in != null && in.getDestinationNickname() != null)
|
||||||
|
buf.append(in.getDestinationNickname());
|
||||||
|
} else {
|
||||||
|
String host = _context.namingService().reverseLookup(h);
|
||||||
|
if (host != null)
|
||||||
|
buf.append(host);
|
||||||
|
}
|
||||||
|
buf.append("</td><td>");
|
||||||
|
SessionKey sk = e.getValue();
|
||||||
|
buf.append(sk.toBase64());
|
||||||
|
buf.append("</td>\n");
|
||||||
|
}
|
||||||
|
buf.append("</table>\n");
|
||||||
|
out.write(buf.toString());
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<%=intl._t("Keys for local destinations must be entered on the")%> <a href="i2ptunnel/"><%=intl._t("I2PTunnel page")%></a>.
|
<%=intl._t("Keys for local destinations must be entered on the")%> <a href="i2ptunnel/"><%=intl._t("I2PTunnel page")%></a>.
|
||||||
</td>
|
</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td align="right"><b><%=intl._t("Dest. name, hash, or full key")%>:</b></td>
|
<td align="right"><b><%=intl._t("Full destination, name, base 32, or hash")%>:</b></td>
|
||||||
<td><textarea name="peer" cols="44" rows="1" style="height: 3em;" wrap="off" spellcheck="false"></textarea></td>
|
<td><textarea name="peer" cols="44" rows="1" style="height: 3em;" wrap="off" spellcheck="false"></textarea></td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td align="right"><b><%=intl._t("Encryption Key")%>:</b></td>
|
<td align="right"><b><%=intl._t("Encryption Key")%>:</b></td>
|
||||||
|
@ -16,5 +16,9 @@ public class KeyRing extends ConcurrentHashMap<Hash, SessionKey> {
|
|||||||
super(0);
|
super(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated unused since 0.9.33; code moved to routerconsole
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public void renderStatusHTML(Writer out) throws IOException {}
|
public void renderStatusHTML(Writer out) throws IOException {}
|
||||||
}
|
}
|
||||||
|
11
history.txt
11
history.txt
@ -1,8 +1,19 @@
|
|||||||
|
2017-12-01 zzz
|
||||||
|
* Build: Split net.i2p.router.web into two packages
|
||||||
|
* Console: Move /configkeyring HTML to console, fix deletion,
|
||||||
|
don't truncate hashes, better form errors, tag for translation (ticket #2108)
|
||||||
|
* Streaming: Double the RTO on congestion (ticket #1939)
|
||||||
|
|
||||||
|
2017-11-27 zzz
|
||||||
|
* Debian: Exclude gradle, IntelliJ, Docker, .tx, gcj files from source tarballs
|
||||||
|
|
||||||
2017-11-27 str4d
|
2017-11-27 str4d
|
||||||
* Build: Add Gradle build scripts for compiling the codebase and generating
|
* Build: Add Gradle build scripts for compiling the codebase and generating
|
||||||
IDE project files.
|
IDE project files.
|
||||||
|
|
||||||
2017-11-26 zzz
|
2017-11-26 zzz
|
||||||
|
* Build: Add xenial build option
|
||||||
|
* Console: Safer processing of changes on /configadvanced
|
||||||
* Context: Hopefully fix rare NPE on Android (ticket #2092)
|
* Context: Hopefully fix rare NPE on Android (ticket #2092)
|
||||||
|
|
||||||
2017-11-25 zzz
|
2017-11-25 zzz
|
||||||
|
@ -4,7 +4,6 @@ import java.io.IOException;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.LeaseSet;
|
import net.i2p.data.LeaseSet;
|
||||||
import net.i2p.data.SessionKey;
|
import net.i2p.data.SessionKey;
|
||||||
@ -37,9 +36,13 @@ public class PersistentKeyRing extends KeyRing {
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionKey remove(Hash h) {
|
@Override
|
||||||
_ctx.router().saveConfig(PROP_PFX + h.toBase64().replace("=", "$"), null);
|
public SessionKey remove(Object o) {
|
||||||
return super.remove(h);
|
if (o != null && o instanceof Hash) {
|
||||||
|
Hash h = (Hash) o;
|
||||||
|
_ctx.router().saveConfig(PROP_PFX + h.toBase64().replace("=", "$"), null);
|
||||||
|
}
|
||||||
|
return super.remove(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFromProperties() {
|
private void addFromProperties() {
|
||||||
@ -60,38 +63,4 @@ public class PersistentKeyRing extends KeyRing {
|
|||||||
} catch (DataFormatException dfe) { continue; }
|
} catch (DataFormatException dfe) { continue; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderStatusHTML(Writer out) throws IOException {
|
|
||||||
StringBuilder buf = new StringBuilder(1024);
|
|
||||||
buf.append("\n<table class=\"configtable\"><tr><th align=\"left\">Destination Hash<th align=\"left\">Name or Dest.<th align=\"left\">Encryption Key</tr>");
|
|
||||||
for (Entry<Hash, SessionKey> e : entrySet()) {
|
|
||||||
buf.append("\n<tr><td>");
|
|
||||||
Hash h = e.getKey();
|
|
||||||
buf.append(h.toBase64().substring(0, 6)).append("…");
|
|
||||||
buf.append("<td>");
|
|
||||||
Destination dest = _ctx.netDb().lookupDestinationLocally(h);
|
|
||||||
if (dest != null) {
|
|
||||||
if (_ctx.clientManager().isLocal(dest)) {
|
|
||||||
TunnelPoolSettings in = _ctx.tunnelManager().getInboundSettings(h);
|
|
||||||
if (in != null && in.getDestinationNickname() != null)
|
|
||||||
buf.append(in.getDestinationNickname());
|
|
||||||
else
|
|
||||||
buf.append(dest.toBase64().substring(0, 6)).append("…");
|
|
||||||
} else {
|
|
||||||
String host = _ctx.namingService().reverseLookup(dest);
|
|
||||||
if (host != null)
|
|
||||||
buf.append(host);
|
|
||||||
else
|
|
||||||
buf.append(dest.toBase64().substring(0, 6)).append("…");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf.append("<td>");
|
|
||||||
SessionKey sk = e.getValue();
|
|
||||||
buf.append(sk.toBase64());
|
|
||||||
}
|
|
||||||
buf.append("\n</table>\n");
|
|
||||||
out.write(buf.toString());
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 9;
|
public final static long BUILD = 10;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user