forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test2' (head 5c1b78bd78845b0c8b90fbb60412c68e7dc4f3e6)
to branch 'i2p.i2p' (head 8bdc25c8e6f40491f20b533d94eacab012adba35)
This commit is contained in:
@@ -14,8 +14,6 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
private static final String HOPS = ngettext("1 hop", "{0} hops");
|
||||
private static final String TUNNELS = ngettext("1 tunnel", "{0} tunnels");
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
public String getForm() {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
// HTML: <input> cannot be inside a <table>
|
||||
@@ -69,7 +67,7 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
|
||||
private void renderForm(StringBuilder buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
||||
|
||||
boolean advanced = _context.getBooleanProperty(PROP_ADVANCED);
|
||||
boolean advanced = isAdvanced();
|
||||
|
||||
buf.append("<tr><th colspan=\"3\"><a name=\"").append(prefix).append("\">");
|
||||
buf.append(name).append("</a></th></tr>\n");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -22,6 +23,7 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
private String _proxyHost;
|
||||
private String _proxyPort;
|
||||
private boolean _updateThroughProxy;
|
||||
private boolean _newsThroughProxy;
|
||||
private String _trustedKeys;
|
||||
private boolean _updateUnsigned;
|
||||
private String _zipURL;
|
||||
@@ -36,7 +38,11 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public static final String PROP_UPDATE_POLICY = "router.updatePolicy";
|
||||
public static final String DEFAULT_UPDATE_POLICY = "download";
|
||||
public static final String PROP_SHOULD_PROXY = "router.updateThroughProxy";
|
||||
public static final String DEFAULT_SHOULD_PROXY = Boolean.TRUE.toString();
|
||||
public static final boolean DEFAULT_SHOULD_PROXY = true;
|
||||
/** @since 0.9.9 */
|
||||
public static final String PROP_SHOULD_PROXY_NEWS = "router.fetchNewsThroughProxy";
|
||||
/** @since 0.9.9 */
|
||||
public static final boolean DEFAULT_SHOULD_PROXY_NEWS = true;
|
||||
public static final String PROP_PROXY_HOST = "router.updateProxyHost";
|
||||
public static final String DEFAULT_PROXY_HOST = "127.0.0.1";
|
||||
public static final String PROP_PROXY_PORT = "router.updateProxyPort";
|
||||
@@ -50,6 +56,7 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public static final String PROP_ZIP_URL = "router.updateUnsignedURL";
|
||||
|
||||
public static final String PROP_UPDATE_URL = "router.updateURL";
|
||||
|
||||
/**
|
||||
* Changed as of release 0.8 to support both .sud and .su2
|
||||
* Some JVMs (IcedTea) don't have pack200
|
||||
@@ -75,6 +82,10 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
"http://update.killyourtv.i2p/i2pupdate.sud\r\n" +
|
||||
"http://update.postman.i2p/i2pupdate.sud" ;
|
||||
|
||||
/**
|
||||
* These are only for .sud and .su2.
|
||||
* Do NOT use this for .su3
|
||||
*/
|
||||
public static final String DEFAULT_UPDATE_URL;
|
||||
static {
|
||||
if (FileUtil.isPack200Supported())
|
||||
@@ -83,6 +94,34 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
DEFAULT_UPDATE_URL = NO_PACK200_URLS;
|
||||
}
|
||||
|
||||
private static final String SU3_CERT_DIR = "certificates/router";
|
||||
|
||||
/**
|
||||
* Only enabled if we have pack200 and trusted public key certificates installed
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static final boolean USE_SU3_UPDATE;
|
||||
static {
|
||||
String[] files = (new File(I2PAppContext.getGlobalContext().getBaseDir(), SU3_CERT_DIR)).list();
|
||||
USE_SU3_UPDATE = FileUtil.isPack200Supported() && files != null && files.length > 0;
|
||||
}
|
||||
|
||||
private static final String DEFAULT_SU3_UPDATE_URLS =
|
||||
"http://echelon.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://inr.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://meeh.i2p/i2pupdate/i2pupdate.su3\r\n" +
|
||||
"http://stats.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://www.i2p2.i2p/_static/i2pupdate.su3\r\n" +
|
||||
"http://update.dg.i2p/files/i2pupdate.su3\r\n" +
|
||||
"http://update.killyourtv.i2p/i2pupdate.su3\r\n" +
|
||||
"http://update.postman.i2p/i2pupdate.su3" ;
|
||||
|
||||
/**
|
||||
* Empty string if disabled. Cannot be overridden by config.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static final String SU3_UPDATE_URLS = USE_SU3_UPDATE ? DEFAULT_SU3_UPDATE_URLS : "";
|
||||
|
||||
public static final String PROP_TRUSTED_KEYS = "router.trustedUpdateKeys";
|
||||
|
||||
/**
|
||||
@@ -130,6 +169,8 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
Map<String, String> changes = new HashMap();
|
||||
|
||||
if ( (_newsURL != null) && (_newsURL.length() > 0) ) {
|
||||
if (_newsURL.startsWith("https"))
|
||||
_newsThroughProxy = false;
|
||||
String oldURL = ConfigUpdateHelper.getNewsURL(_context);
|
||||
if ( (oldURL == null) || (!_newsURL.equals(oldURL)) ) {
|
||||
changes.put(PROP_NEWS_URL, _newsURL);
|
||||
@@ -155,8 +196,9 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
}
|
||||
}
|
||||
|
||||
changes.put(PROP_SHOULD_PROXY, "" + _updateThroughProxy);
|
||||
changes.put(PROP_UPDATE_UNSIGNED, "" + _updateUnsigned);
|
||||
changes.put(PROP_SHOULD_PROXY, Boolean.toString(_updateThroughProxy));
|
||||
changes.put(PROP_SHOULD_PROXY_NEWS, Boolean.toString(_newsThroughProxy));
|
||||
changes.put(PROP_UPDATE_UNSIGNED, Boolean.toString(_updateUnsigned));
|
||||
|
||||
String oldFreqStr = _context.getProperty(PROP_REFRESH_FREQUENCY, DEFAULT_REFRESH_FREQUENCY);
|
||||
long oldFreq = DEFAULT_REFRESH_FREQ;
|
||||
@@ -218,4 +260,6 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public void setProxyPort(String port) { _proxyPort = port; }
|
||||
public void setUpdateUnsigned(String foo) { _updateUnsigned = true; }
|
||||
public void setZipURL(String url) { _zipURL = url; }
|
||||
/** @since 0.9.9 */
|
||||
public void setNewsThroughProxy(String foo) { _newsThroughProxy = true; }
|
||||
}
|
||||
|
||||
@@ -73,13 +73,20 @@ public class ConfigUpdateHelper extends HelperBase {
|
||||
}
|
||||
|
||||
public String getUpdateThroughProxy() {
|
||||
String proxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if (Boolean.parseBoolean(proxy))
|
||||
if (_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" checked=\"checked\" >";
|
||||
else
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" >";
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public String getNewsThroughProxy() {
|
||||
if (_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY_NEWS, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY_NEWS))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"newsThroughProxy\" checked=\"checked\" >";
|
||||
else
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"newsThroughProxy\" >";
|
||||
}
|
||||
|
||||
public String getUpdateUnsigned() {
|
||||
if (_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" checked=\"checked\" >";
|
||||
|
||||
@@ -11,6 +11,8 @@ public abstract class HelperBase {
|
||||
protected RouterContext _context;
|
||||
protected Writer _out;
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@@ -25,6 +27,11 @@ public abstract class HelperBase {
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public boolean isAdvanced() {
|
||||
return _context.getBooleanProperty(PROP_ADVANCED);
|
||||
}
|
||||
|
||||
/** might be useful in the jsp's */
|
||||
//public RouterContext getContext() { return _context; }
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public class NewsHelper extends ContentHelper {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return false;
|
||||
return mgr.isUpdateInProgress(ROUTER_SIGNED) ||
|
||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||
mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||
mgr.isUpdateInProgress(TYPE_DUMMY);
|
||||
}
|
||||
@@ -60,7 +61,8 @@ public class NewsHelper extends ContentHelper {
|
||||
public static boolean isUpdateAvailable() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return false;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED) != null;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED) != null ||
|
||||
mgr.getUpdateAvailable(ROUTER_SIGNED_SU3) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,6 +73,9 @@ public class NewsHelper extends ContentHelper {
|
||||
public static String updateVersion() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return null;
|
||||
String rv = mgr.getUpdateAvailable(ROUTER_SIGNED_SU3);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED);
|
||||
}
|
||||
|
||||
@@ -93,6 +98,9 @@ public class NewsHelper extends ContentHelper {
|
||||
public static String updateVersionDownloaded() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return null;
|
||||
String rv = mgr.getUpdateDownloaded(ROUTER_SIGNED_SU3);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return mgr.getUpdateDownloaded(ROUTER_SIGNED);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.Signature;
|
||||
|
||||
/**
|
||||
* Sign a statement about this router.
|
||||
* @since 0.9.8
|
||||
*/
|
||||
public class ProofHelper extends HelperBase {
|
||||
|
||||
public String getProof() {
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
RouterInfo us = _context.router().getRouterInfo();
|
||||
buf.append("Hash: ").append(us.getIdentity().calculateHash().toBase64()).append('\n');
|
||||
//buf.append("Ident: ").append(us.getIdentity().toBase64()).append('\n');
|
||||
for (RouterAddress addr : us.getAddresses()) {
|
||||
buf.append(addr.getTransportStyle()).append(": ").append(addr.getHost()).append('\n');
|
||||
}
|
||||
buf.append("Caps: ").append(us.getCapabilities()).append('\n');
|
||||
buf.append("Date: ").append(new Date()); // no trailing newline
|
||||
String msg = buf.toString();
|
||||
byte[] data = DataHelper.getUTF8(msg);
|
||||
Signature sig = _context.dsa().sign(data, _context.keyManager().getSigningPrivateKey());
|
||||
buf.setLength(0);
|
||||
buf.append("---BEGIN I2P SIGNED MESSAGE---\n");
|
||||
buf.append(msg);
|
||||
buf.append("\n---BEGIN I2P SIGNATURE---\n");
|
||||
buf.append(sig.toBase64());
|
||||
buf.append("\n---END I2P SIGNATURE---");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.ClientAppState;
|
||||
import static net.i2p.app.ClientAppState.*;
|
||||
import net.i2p.apps.systray.SysTray;
|
||||
import net.i2p.crypto.KeyStoreUtil;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.jetty.I2PLogger;
|
||||
@@ -38,8 +39,6 @@ import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.PortMapper;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.ShellCommand;
|
||||
import net.i2p.util.SystemVersion;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
@@ -677,12 +676,6 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
System.err.println("Console SSL error, must set " + PROP_KEY_PASSWORD + " in " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
|
||||
return rv;
|
||||
}
|
||||
File dir = ks.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
File sdir = new SecureDirectory(dir.getAbsolutePath());
|
||||
if (!sdir.mkdir())
|
||||
return false;
|
||||
}
|
||||
return createKeyStore(ks);
|
||||
}
|
||||
|
||||
@@ -697,31 +690,13 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
*/
|
||||
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) + ".console.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", "console",
|
||||
"-dname", "CN=" + cname + ",OU=Console,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
|
||||
String cname = KeyStoreUtil.randomString() + ".console.i2p.net";
|
||||
boolean success = KeyStoreUtil.createKeys(ks, "console", cname, "Console", keyPassword);
|
||||
if (success) {
|
||||
success = ks.exists();
|
||||
if (success) {
|
||||
SecureFileOutputStream.setPerms(ks);
|
||||
try {
|
||||
Map<String, String> changes = new HashMap();
|
||||
changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
|
||||
@@ -735,13 +710,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
"The certificate name was generated randomly, and is not associated with your " +
|
||||
"IP address, host name, router identity, or destination keys.");
|
||||
} else {
|
||||
System.err.println("Failed to create console SSL keystore using command line:");
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
buf.append('"').append(args[i]).append("\" ");
|
||||
}
|
||||
System.err.println(buf.toString());
|
||||
System.err.println("This is for the Sun/Oracle keytool, others may be incompatible.\n" +
|
||||
System.err.println("Failed to create console 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());
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TunnelRenderer {
|
||||
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
|
||||
Map<Hash, TunnelPool> clientOutboundPools = _context.tunnelManager().getOutboundClientPools();
|
||||
destinations = new ArrayList(clientInboundPools.keySet());
|
||||
boolean debug = _context.getBooleanProperty(ConfigTunnelsHelper.PROP_ADVANCED);
|
||||
boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
|
||||
for (int i = 0; i < destinations.size(); i++) {
|
||||
Hash client = destinations.get(i);
|
||||
boolean isLocal = _context.clientManager().isLocal(client);
|
||||
|
||||
@@ -66,6 +66,8 @@ public class UpdateHandler {
|
||||
_nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
|
||||
if (_action.contains("Unsigned")) {
|
||||
update(ROUTER_UNSIGNED);
|
||||
} else if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
update(ROUTER_SIGNED_SU3);
|
||||
} else {
|
||||
update(ROUTER_SIGNED);
|
||||
}
|
||||
@@ -76,7 +78,8 @@ public class UpdateHandler {
|
||||
ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
|
||||
if (mgr == null)
|
||||
return;
|
||||
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED)) {
|
||||
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3)) {
|
||||
_log.error("Update already running");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user