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:
@ -121,6 +121,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
@ -167,6 +168,7 @@
|
||||
|
||||
<target name="bundle-news" unless="no.bundle">
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages-news.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles-news.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -19,6 +19,7 @@ import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.SU3File;
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.Router;
|
||||
@ -69,6 +70,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
private final Map<UpdateItem, Version> _downloaded;
|
||||
/** downloaded AND installed */
|
||||
private final Map<UpdateItem, Version> _installed;
|
||||
private final boolean _allowTorrent;
|
||||
private static final DecimalFormat _pct = new DecimalFormat("0.0%");
|
||||
|
||||
private volatile String _status;
|
||||
@ -90,6 +92,13 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
_downloaded = new ConcurrentHashMap();
|
||||
_installed = new ConcurrentHashMap();
|
||||
_status = "";
|
||||
// DEBUG slow start for snark updates
|
||||
// For 0.9.4 update, only for dev builds
|
||||
// For 0.9.5 update, only for dev builds and 1% more
|
||||
// For 0.9.6 update, only for dev builds and 3% more
|
||||
// For 0.9.8 update, only for dev builds and 30% more
|
||||
// Remove this for 100%
|
||||
_allowTorrent = RouterVersion.BUILD != 0 || _context.random().nextInt(100) < 30;
|
||||
}
|
||||
|
||||
public static ConsoleUpdateManager getInstance() {
|
||||
@ -99,6 +108,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
public void start() {
|
||||
notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context)));
|
||||
notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION);
|
||||
notifyInstalled(ROUTER_SIGNED_SU3, "", RouterVersion.VERSION);
|
||||
// hack to init from the current news file... do this before we register Updaters
|
||||
// This will not kick off any Updaters as none are yet registered
|
||||
(new NewsFetcher(_context, this, Collections.EMPTY_LIST)).checkForUpdates();
|
||||
@ -122,6 +132,15 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
register(c, ROUTER_SIGNED, HTTP, 0); // news is an update checker for the router
|
||||
Updater u = new UpdateHandler(_context, this);
|
||||
register(u, ROUTER_SIGNED, HTTP, 0);
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
register(c, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
register(u, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
// todo
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, -10);
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTP_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTP_CLEARNET, -20);
|
||||
}
|
||||
// TODO see NewsFetcher
|
||||
//register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5);
|
||||
//register(u, ROUTER_SIGNED, HTTP_CLEARNET, -10);
|
||||
@ -560,18 +579,18 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
* Call once for each type/method pair.
|
||||
*/
|
||||
public void register(Updater updater, UpdateType type, UpdateMethod method, int priority) {
|
||||
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED) && NewsHelper.dontInstall(_context)) {
|
||||
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED || type == ROUTER_SIGNED_SU3) &&
|
||||
NewsHelper.dontInstall(_context)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring registration for " + type + ", router updates disabled");
|
||||
return;
|
||||
}
|
||||
// DEBUG slow start for snark updates
|
||||
// For 0.9.4 update, only for dev builds
|
||||
// For 0.9.5 update, only for dev builds and 1% more
|
||||
// For 0.9.6 update, only for dev builds and 3% more
|
||||
// For 0.9.8 update, only for dev builds and 30% more
|
||||
// Remove this for 100%
|
||||
if (method == TORRENT && RouterVersion.BUILD == 0 && _context.random().nextInt(100) > 29) {
|
||||
if (type == ROUTER_SIGNED_SU3 && !ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring registration for " + type + ", SU3 updates disabled");
|
||||
return;
|
||||
}
|
||||
if (method == TORRENT && !_allowTorrent) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring torrent registration");
|
||||
return;
|
||||
@ -725,8 +744,10 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
// fall through
|
||||
|
||||
case ROUTER_SIGNED:
|
||||
case ROUTER_SIGNED_SU3:
|
||||
if (shouldInstall() &&
|
||||
!(isUpdateInProgress(ROUTER_SIGNED) ||
|
||||
isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||
isUpdateInProgress(ROUTER_UNSIGNED))) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Updating " + ui + " after notify");
|
||||
@ -810,6 +831,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
switch (task.getType()) {
|
||||
case NEWS:
|
||||
case ROUTER_SIGNED:
|
||||
case ROUTER_SIGNED_SU3:
|
||||
case ROUTER_UNSIGNED:
|
||||
// ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display
|
||||
break;
|
||||
@ -926,6 +948,12 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
notifyDownloaded(task.getType(), task.getID(), actualVersion);
|
||||
break;
|
||||
|
||||
case ROUTER_SIGNED_SU3:
|
||||
rv = handleSu3File(task.getURI(), actualVersion, file);
|
||||
if (rv)
|
||||
notifyDownloaded(task.getType(), task.getID(), actualVersion);
|
||||
break;
|
||||
|
||||
case ROUTER_UNSIGNED:
|
||||
rv = handleUnsignedFile(task.getURI(), actualVersion, file);
|
||||
if (rv) {
|
||||
@ -981,10 +1009,30 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
_log.info(ui + " " + ver + " downloaded");
|
||||
_downloaded.put(ui, ver);
|
||||
// one trumps the other
|
||||
if (type == ROUTER_SIGNED)
|
||||
if (type == ROUTER_SIGNED) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||
else if (type == ROUTER_UNSIGNED)
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||
// remove available from other type
|
||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED_SU3, id);
|
||||
Version old = _available.get(altui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(altui);
|
||||
// ... and declare the alt downloaded as well
|
||||
_downloaded.put(altui, ver);
|
||||
} else if (type == ROUTER_SIGNED_SU3) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||
// remove available from other type
|
||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED, id);
|
||||
Version old = _available.get(altui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(altui);
|
||||
// ... and declare the alt downloaded as well
|
||||
_downloaded.put(altui, ver);
|
||||
} else if (type == ROUTER_UNSIGNED) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||
}
|
||||
Version old = _available.get(ui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(ui);
|
||||
@ -1018,6 +1066,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
break;
|
||||
|
||||
case ROUTER_SIGNED:
|
||||
{ // avoid dup variables in next case
|
||||
String URLs = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL);
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
|
||||
List<URI> rv = new ArrayList();
|
||||
@ -1028,6 +1077,21 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
}
|
||||
Collections.shuffle(rv, _context.random());
|
||||
return rv;
|
||||
}
|
||||
|
||||
case ROUTER_SIGNED_SU3:
|
||||
{
|
||||
String URLs = ConfigUpdateHandler.SU3_UPDATE_URLS;
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
|
||||
List<URI> rv = new ArrayList();
|
||||
while (tok.hasMoreTokens()) {
|
||||
try {
|
||||
rv.add(new URI(tok.nextToken().trim()));
|
||||
} catch (URISyntaxException use) {}
|
||||
}
|
||||
Collections.shuffle(rv, _context.random());
|
||||
return rv;
|
||||
}
|
||||
|
||||
case ROUTER_UNSIGNED:
|
||||
String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
|
||||
@ -1072,14 +1136,59 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
* @return success
|
||||
*/
|
||||
private boolean handleSudFile(URI uri, String actualVersion, File f) {
|
||||
return handleRouterFile(uri, actualVersion, f, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean handleSu3File(URI uri, String actualVersion, File f) {
|
||||
return handleRouterFile(uri, actualVersion, f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sud, su2, or su3
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean handleRouterFile(URI uri, String actualVersion, File f, boolean isSU3) {
|
||||
String url = uri.toString();
|
||||
// Process the .sud/.su2 file
|
||||
updateStatus("<b>" + _("Update downloaded") + "</b>");
|
||||
TrustedUpdate up = new TrustedUpdate(_context);
|
||||
File to = new File(_context.getRouterDir(), Router.UPDATE_FILE);
|
||||
String err = up.migrateVerified(RouterVersion.VERSION, f, to);
|
||||
///////////
|
||||
// caller must delete now.. why?
|
||||
String err;
|
||||
// Process the file
|
||||
if (isSU3) {
|
||||
SU3File up = new SU3File(_context, f);
|
||||
File temp = new File(_context.getTempDir(), "su3out-" + _context.random().nextLong() + ".zip");
|
||||
try {
|
||||
if (up.verifyAndMigrate(temp)) {
|
||||
String ver = up.getVersionString();
|
||||
int type = up.getContentType();
|
||||
if (ver == null || VersionComparator.comp(RouterVersion.VERSION, ver) >= 0)
|
||||
err = "Old version " + ver;
|
||||
else if (type != SU3File.CONTENT_ROUTER)
|
||||
err = "Bad su3 content type " + type;
|
||||
else if (!FileUtil.copy(temp, to, true, false))
|
||||
err = "Failed copy to " + to;
|
||||
else
|
||||
err = null; // success
|
||||
} else {
|
||||
err = "Signature failed, signer " + DataHelper.stripHTML(up.getSignerString()) +
|
||||
' ' + up.getSigType();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_log.error("SU3 extract error", ioe);
|
||||
err = DataHelper.stripHTML(ioe.toString());
|
||||
} finally {
|
||||
temp.delete();
|
||||
}
|
||||
} else {
|
||||
TrustedUpdate up = new TrustedUpdate(_context);
|
||||
err = up.migrateVerified(RouterVersion.VERSION, f, to);
|
||||
}
|
||||
|
||||
// caller must delete.. could be an active torrent
|
||||
//f.delete();
|
||||
if (err == null) {
|
||||
String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);
|
||||
@ -1346,6 +1455,8 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if ("".equals(id))
|
||||
return "UpdateItem " + type;
|
||||
return "UpdateItem " + type + ' ' + id;
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +48,10 @@ class DummyHandler implements Checker, Updater {
|
||||
private final long _delay;
|
||||
|
||||
public DummyRunner(RouterContext ctx, ConsoleUpdateManager mgr, long maxTime) {
|
||||
super(ctx, mgr, Collections.EMPTY_LIST);
|
||||
super(ctx, mgr, UpdateType.TYPE_DUMMY, Collections.EMPTY_LIST);
|
||||
_delay = maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.TYPE_DUMMY; }
|
||||
|
||||
@Override
|
||||
public UpdateMethod getMethod() { return UpdateMethod.METHOD_DUMMY; }
|
||||
|
||||
|
@ -32,6 +32,7 @@ import net.i2p.util.EepHead;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.VersionComparator;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
|
||||
/**
|
||||
* Task to fetch updates to the news.xml, and to keep
|
||||
@ -50,7 +51,7 @@ class NewsFetcher extends UpdateRunner {
|
||||
private static final String TEMP_NEWS_FILE = "news.xml.temp";
|
||||
|
||||
public NewsFetcher(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, NEWS, uris);
|
||||
_newsFile = new File(ctx.getRouterDir(), NewsHelper.NEWS_FILE);
|
||||
_tempFile = new File(ctx.getTempDir(), "tmp-" + ctx.random().nextLong() + TEMP_NEWS_FILE);
|
||||
long lastMod = NewsHelper.lastChecked(ctx);
|
||||
@ -73,7 +74,7 @@ class NewsFetcher extends UpdateRunner {
|
||||
}
|
||||
|
||||
public void fetchNews() {
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY_NEWS, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY_NEWS);
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
|
||||
@ -88,6 +89,9 @@ class NewsFetcher extends UpdateRunner {
|
||||
EepGet get;
|
||||
if (shouldProxy)
|
||||
get = new EepGet(_context, true, proxyHost, proxyPort, 0, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
|
||||
else if ("https".equals(uri.getScheme()))
|
||||
// no constructor w/ last mod check
|
||||
get = new SSLEepGet(_context, _tempFile.getAbsolutePath(), newsURL);
|
||||
else
|
||||
get = new EepGet(_context, false, null, 0, 0, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
|
||||
get.addStatusListener(this);
|
||||
@ -113,9 +117,11 @@ class NewsFetcher extends UpdateRunner {
|
||||
private static final String MIN_JAVA_VERSION_KEY = "minjavaversion";
|
||||
private static final String SUD_KEY = "sudtorrent";
|
||||
private static final String SU2_KEY = "su2torrent";
|
||||
// following are unused
|
||||
private static final String SU3_KEY = "su3torrent";
|
||||
private static final String CLEARNET_SUD_KEY = "sudclearnet";
|
||||
private static final String CLEARNET_SU2_KEY = "su2clearnet";
|
||||
private static final String CLEARNET_HTTP_SU3_KEY = "su3clearnet";
|
||||
private static final String CLEARNET_HTTPS_SU3_KEY = "su3ssl";
|
||||
private static final String I2P_SUD_KEY = "sudi2p";
|
||||
private static final String I2P_SU2_KEY = "su2i2p";
|
||||
|
||||
@ -175,20 +181,24 @@ class NewsFetcher extends UpdateRunner {
|
||||
// and look for a second entry with clearnet URLs
|
||||
// TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET
|
||||
Map<UpdateMethod, List<URI>> sourceMap = new HashMap(4);
|
||||
// Must do su3 first
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED_SU3, "", HTTP));
|
||||
addMethod(TORRENT, args.get(SU3_KEY), sourceMap);
|
||||
addMethod(HTTP_CLEARNET, args.get(CLEARNET_HTTP_SU3_KEY), sourceMap);
|
||||
addMethod(HTTPS_CLEARNET, args.get(CLEARNET_HTTPS_SU3_KEY), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED_SU3,
|
||||
"", sourceMap, ver, "");
|
||||
sourceMap.clear();
|
||||
}
|
||||
// now do sud/su2
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP));
|
||||
String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY;
|
||||
String murl = args.get(key);
|
||||
if (murl != null) {
|
||||
List<URI> uris = tokenize(murl);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
sourceMap.put(TORRENT, uris);
|
||||
}
|
||||
}
|
||||
addMethod(TORRENT, args.get(key), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI,
|
||||
ROUTER_SIGNED, "", sourceMap,
|
||||
ver, "");
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED,
|
||||
"", sourceMap, ver, "");
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Our version is current");
|
||||
@ -292,6 +302,21 @@ class NewsFetcher extends UpdateRunner {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse URLs and add to the map
|
||||
* @param urls may be null
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private void addMethod(UpdateMethod method, String urls, Map<UpdateMethod, List<URI>> map) {
|
||||
if (urls != null) {
|
||||
List<URI> uris = tokenize(urls);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
map.put(method, uris);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** override to prevent status update */
|
||||
@Override
|
||||
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {}
|
||||
|
@ -35,16 +35,13 @@ class PluginUpdateChecker extends UpdateRunner {
|
||||
|
||||
public PluginUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||
List<URI> uris, String appName, String oldVersion ) {
|
||||
super(ctx, mgr, uris, oldVersion);
|
||||
super(ctx, mgr, UpdateType.PLUGIN, uris, oldVersion);
|
||||
if (!uris.isEmpty())
|
||||
_currentURI = uris.get(0);
|
||||
_appName = appName;
|
||||
_oldVersion = oldVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.PLUGIN; }
|
||||
|
||||
@Override
|
||||
public String getID() { return _appName; }
|
||||
|
||||
|
@ -60,7 +60,7 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
|
||||
public PluginUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris,
|
||||
String appName, String oldVersion ) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, UpdateType.PLUGIN, uris);
|
||||
if (uris.isEmpty())
|
||||
throw new IllegalArgumentException("uri cannot be empty");
|
||||
else
|
||||
@ -70,12 +70,6 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
_oldVersion = oldVersion;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UpdateType getType() {
|
||||
return UpdateType.PLUGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() { return _uri; }
|
||||
|
||||
@ -104,7 +98,7 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
} else {
|
||||
updateStatus("<b>" + _("Downloading plugin from {0}", _xpi2pURL) + "</b>");
|
||||
// use the same settings as for updater
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
try {
|
||||
|
@ -28,17 +28,10 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
||||
|
||||
public UnsignedUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||
List<URI> uris, long lastUpdateTime) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, UpdateType.ROUTER_UNSIGNED, uris);
|
||||
_ms = lastUpdateTime;
|
||||
}
|
||||
|
||||
//////// begin UpdateTask methods
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.ROUTER_UNSIGNED; }
|
||||
|
||||
//////// end UpdateTask methods
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
_isRunning = true;
|
||||
|
@ -25,16 +25,12 @@ import net.i2p.util.Log;
|
||||
class UnsignedUpdateRunner extends UpdateRunner {
|
||||
|
||||
public UnsignedUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, ROUTER_UNSIGNED, uris);
|
||||
if (!uris.isEmpty())
|
||||
_currentURI = uris.get(0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return ROUTER_UNSIGNED; }
|
||||
|
||||
|
||||
/** Get the file */
|
||||
@Override
|
||||
protected void update() {
|
||||
|
@ -4,7 +4,10 @@ import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.web.ConfigUpdateHandler;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateType.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
|
||||
/**
|
||||
* <p>Handles the request to update the router by firing one or more
|
||||
@ -38,10 +41,13 @@ class UpdateHandler implements Updater {
|
||||
*/
|
||||
public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources,
|
||||
String id, String newVersion, long maxTime) {
|
||||
if (type != UpdateType.ROUTER_SIGNED ||
|
||||
method != UpdateMethod.HTTP || updateSources.isEmpty())
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if ((type != ROUTER_SIGNED && type != ROUTER_SIGNED_SU3) ||
|
||||
(shouldProxy && method != HTTP) ||
|
||||
((!shouldProxy) && method != HTTP_CLEARNET && method != HTTPS_CLEARNET) ||
|
||||
updateSources.isEmpty())
|
||||
return null;
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, updateSources);
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, type, method, updateSources);
|
||||
// set status before thread to ensure UI feedback
|
||||
_mgr.notifyProgress(update, "<b>" + _mgr._("Updating") + "</b>");
|
||||
return update;
|
||||
|
@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
@ -13,10 +14,12 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
import net.i2p.router.web.ConfigUpdateHandler;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.PartialEepGet;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
@ -30,6 +33,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
protected final RouterContext _context;
|
||||
protected final Log _log;
|
||||
protected final ConsoleUpdateManager _mgr;
|
||||
protected final UpdateType _type;
|
||||
protected final UpdateMethod _method;
|
||||
protected final List<URI> _urls;
|
||||
protected final String _updateFile;
|
||||
protected volatile boolean _isRunning;
|
||||
@ -53,20 +58,42 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
/**
|
||||
* Uses router version for partial checks
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
this(ctx, mgr, uris, RouterVersion.VERSION);
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type, List<URI> uris) {
|
||||
this(ctx, mgr, type, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses router version for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris) {
|
||||
this(ctx, mgr, type, method, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.7
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, String currentVersion) {
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
List<URI> uris, String currentVersion) {
|
||||
this(ctx, mgr, type, HTTP, uris, currentVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method HTTP, HTTP_CLEARNET, or HTTPS_CLEARNET
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris, String currentVersion) {
|
||||
super("Update Runner");
|
||||
setDaemon(true);
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_mgr = mgr;
|
||||
_type = type;
|
||||
_method = method;
|
||||
_urls = uris;
|
||||
_baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES);
|
||||
_updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath();
|
||||
@ -82,9 +109,9 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public UpdateType getType() { return UpdateType.ROUTER_SIGNED; }
|
||||
public UpdateType getType() { return _type; }
|
||||
|
||||
public UpdateMethod getMethod() { return UpdateMethod.HTTP; }
|
||||
public UpdateMethod getMethod() { return _method; }
|
||||
|
||||
public URI getURI() { return _currentURI; }
|
||||
|
||||
@ -117,9 +144,32 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
// Alternative: In bytesTransferred(), Check the data in the output file after
|
||||
// we've received at least 56 bytes. Need a cancel() method in EepGet ?
|
||||
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
boolean shouldProxy;
|
||||
String proxyHost;
|
||||
int proxyPort;
|
||||
boolean isSSL = false;
|
||||
if (_method == HTTP) {
|
||||
shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if (shouldProxy) {
|
||||
proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
} else {
|
||||
// TODO, wrong method, fail
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
}
|
||||
} else if (_method == HTTP_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
} else if (_method == HTTPS_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
isSSL = true;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (_urls.isEmpty()) {
|
||||
// not likely, don't bother translating
|
||||
@ -132,12 +182,24 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
for (URI uri : _urls) {
|
||||
_currentURI = uri;
|
||||
String updateURL = uri.toString();
|
||||
if ((_method == HTTP && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTP_CLEARNET && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTPS_CLEARNET && !"https".equals(uri.getScheme())) ||
|
||||
uri.getHost() == null ||
|
||||
(_method != HTTP && uri.getHost().toLowerCase(Locale.US).endsWith(".i2p"))) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Bad update URI " + uri + " for method " + _method);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateStatus("<b>" + _("Updating from {0}", linkify(updateURL)) + "</b>");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Selected update URL: " + updateURL);
|
||||
|
||||
// Check the first 56 bytes for the version
|
||||
if (shouldProxy) {
|
||||
// FIXME PartialEepGet works with clearnet but not with SSL
|
||||
_newVersion = null;
|
||||
if (!isSSL) {
|
||||
_isPartial = true;
|
||||
_baos.reset();
|
||||
try {
|
||||
@ -157,6 +219,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
if (shouldProxy)
|
||||
// 40 retries!!
|
||||
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
|
||||
else if (isSSL)
|
||||
_get = new SSLEepGet(_context, _updateFile, updateURL);
|
||||
else
|
||||
_get = new EepGet(_context, 1, _updateFile, updateURL, false);
|
||||
_get.addStatusListener(UpdateRunner.this);
|
||||
@ -208,6 +272,9 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME if we didn't do a partial, we don't know
|
||||
if (_newVersion == null)
|
||||
_newVersion = "unknown";
|
||||
File tmp = new File(_updateFile);
|
||||
if (_mgr.notifyComplete(this, _newVersion, tmp))
|
||||
this.done = true;
|
||||
|
@ -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