From 6e19854e4c43fbf8fb87c67166c6af8e4edf44ed Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Sun, 21 Oct 2012 13:34:23 +0000 Subject: [PATCH] - NPE fix on signed udpates - More work on snark updater - Clean up imports --- .../src/org/klomp/snark/UpdateHandler.java | 1 - .../src/org/klomp/snark/UpdateRunner.java | 56 ++++++++++++++++--- .../org/klomp/snark/web/I2PSnarkServlet.java | 13 +++++ .../router/update/PluginUpdateHandler.java | 10 ---- .../router/update/UnsignedUpdateChecker.java | 1 - .../router/update/UnsignedUpdateHandler.java | 6 -- .../net/i2p/router/update/UpdateHandler.java | 17 ------ .../net/i2p/router/update/UpdateRunner.java | 14 ++--- core/java/src/net/i2p/I2PAppContext.java | 2 +- .../src/net/i2p/router/RouterContext.java | 6 +- 10 files changed, 71 insertions(+), 55 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java index 0637c19a96..7bb41bc2fe 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java @@ -46,7 +46,6 @@ public class UpdateHandler implements Updater { method != UpdateMethod.TORRENT || updateSources.isEmpty()) return null; UpdateRunner update = new UpdateRunner(_context, _umgr, _smgr, updateSources, newVersion); - // set status before thread to ensure UI feedback _umgr.notifyProgress(update, "<b>" + _smgr.util().getString("Updating") + "</b>"); update.start(); return update; diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java index 53e0ec0f56..bb9906a30a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java @@ -31,10 +31,9 @@ class UpdateRunner implements UpdateTask, CompleteListener { private ByteArrayOutputStream _baos; private URI _currentURI; private Snark _snark; + private boolean _hasMetaInfo; - private static final long CONNECT_TIMEOUT = 55*1000; - private static final long INACTIVITY_TIMEOUT = 5*60*1000; - private static final long NOPROXY_INACTIVITY_TIMEOUT = 60*1000; + private static final long MAX_LENGTH = 30*1024*1024; public UpdateRunner(I2PAppContext ctx, UpdateManager umgr, SnarkManager smgr, List<URI> uris, String newVersion) { @@ -101,17 +100,43 @@ class UpdateRunner implements UpdateTask, CompleteListener { } } catch (IllegalArgumentException iae) {} } - if (_snark == null) { - _umgr.notifyTaskFailed(this, "", null); + if (_snark == null) + fatal("No valid URLs"); + } + + private void fatal(String error) { + if (_snark != null) { + if (_hasMetaInfo) { + _smgr.stopTorrent(_snark, true); + String file = _snark.getName(); + _smgr.removeTorrent(file); + // delete torrent file + File f = new File(_smgr.getDataDir(), file); + f.delete(); + // delete data + file = _snark.getBaseName(); + f = new File(_smgr.getDataDir(), file); + f.delete(); + } else { + _smgr.deleteMagnet(_snark); + } + } + _umgr.notifyTaskFailed(this, error, null); + _log.error(error); _isRunning = false; - } } //////// begin CompleteListener methods //////// all pass through to SnarkManager public void torrentComplete(Snark snark) { - + String dataFile = snark.getBaseName(); + File f = new File(_smgr.getDataDir(), dataFile); + String sudVersion = TrustedUpdate.getVersionString(f); + if (!_newVersion.equals(sudVersion)) { + fatal("version mismatch"); + } + _umgr.notifyComplete(this, _newVersion, f); _smgr.torrentComplete(snark); } @@ -121,11 +146,26 @@ class UpdateRunner implements UpdateTask, CompleteListener { } public String gotMetaInfo(Snark snark) { - + Storage storage = snark.getStorage(); + MetaInfo info = snark.getMetaInfo(); + if (info.getFiles() != null) { + fatal("more than 1 file"); + return null; + } + if (info.isPrivate()) { + fatal("private torrent"); + return null; + } + if (info.getTotalLength() > MAX_LENGTH) { + fatal("too big"); + return null; + } + _hasMetaInfo = true; return _smgr.gotMetaInfo(snark); } public void fatal(Snark snark, String error) { + fatal(error); _smgr.fatal(snark, error); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index e96eefe0b2..459652e690 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse; import net.i2p.I2PAppContext; import net.i2p.data.Base64; import net.i2p.data.DataHelper; +import net.i2p.update.*; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; @@ -42,6 +43,7 @@ import org.klomp.snark.SnarkManager; import org.klomp.snark.Storage; import org.klomp.snark.Tracker; import org.klomp.snark.TrackerClient; +import org.klomp.snark.UpdateHandler; import org.klomp.snark.dht.DHT; import org.mortbay.jetty.servlet.DefaultServlet; @@ -57,6 +59,8 @@ public class I2PSnarkServlet extends DefaultServlet { private I2PAppContext _context; private Log _log; private SnarkManager _manager; + private UpdateManager _umgr; + private UpdateHandler _uhandler; private static long _nonce; private Resource _resourceBase; private String _themePath; @@ -76,6 +80,11 @@ public class I2PSnarkServlet extends DefaultServlet { configFile = "i2psnark.config"; _manager.loadConfig(configFile); _manager.start(); + _umgr = _context.updateManager(); + if (_umgr != null) { + _uhandler = new UpdateHandler(_context, _umgr, _manager); + _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10); + } try { _resourceBase = Resource.newResource(_manager.getDataDir().getAbsolutePath()); } catch (IOException ioe) {} @@ -86,6 +95,10 @@ public class I2PSnarkServlet extends DefaultServlet { public void destroy() { if (_manager != null) _manager.stop(); + if (_umgr != null && _uhandler != null) { + //_uhandler.shutdown(); + _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT); + } super.destroy(); } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java index d142cdff84..59a2edc417 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java @@ -1,24 +1,14 @@ package net.i2p.router.update; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.List; import java.util.Properties; -import net.i2p.crypto.TrustedUpdate; import net.i2p.router.RouterContext; import net.i2p.router.web.PluginStarter; import net.i2p.update.*; -import net.i2p.util.EepGet; -import net.i2p.util.I2PAppThread; -import net.i2p.util.PartialEepGet; -import net.i2p.util.SimpleScheduler; -import net.i2p.util.SimpleTimer; -import net.i2p.util.VersionComparator; /** * Check for or download an updated version of a plugin. diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java index fe0b1acd7e..8b3bd7946d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java @@ -7,7 +7,6 @@ import java.util.List; import net.i2p.router.RouterContext; import net.i2p.router.util.RFC822Date; import net.i2p.router.web.ConfigUpdateHandler; -import net.i2p.router.web.Messages; import net.i2p.update.*; import net.i2p.util.EepHead; import net.i2p.util.I2PAppThread; diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateHandler.java index a2a94f4c15..15db5c9266 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateHandler.java @@ -6,18 +6,12 @@ import java.net.URISyntaxException; import java.util.Collections; import java.util.List; -import net.i2p.router.Router; import net.i2p.router.RouterContext; -import net.i2p.router.util.RFC822Date; import net.i2p.router.web.ConfigUpdateHandler; import net.i2p.router.web.NewsHelper; import net.i2p.update.*; import static net.i2p.update.UpdateType.*; import static net.i2p.update.UpdateMethod.*; -import net.i2p.util.EepGet; -import net.i2p.util.FileUtil; -import net.i2p.util.I2PAppThread; -import net.i2p.util.Log; /** * <p>Handles the request to update the router by firing off an diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java index 1e1d9efa1b..3af9837167 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java @@ -1,27 +1,10 @@ package net.i2p.router.update; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; import java.net.URI; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.StringTokenizer; -import net.i2p.crypto.TrustedUpdate; -import net.i2p.data.DataHelper; -import net.i2p.router.Router; import net.i2p.router.RouterContext; -import net.i2p.router.RouterVersion; -import net.i2p.router.util.RFC822Date; import net.i2p.update.*; -import net.i2p.util.EepGet; -import net.i2p.util.I2PAppThread; -import net.i2p.util.Log; -import net.i2p.util.PartialEepGet; -import net.i2p.util.VersionComparator; /** * <p>Handles the request to update the router by firing one or more diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java index 9aafb2eb9f..bf9b2d4de9 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java @@ -12,7 +12,6 @@ import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; import net.i2p.router.RouterVersion; import net.i2p.router.web.ConfigUpdateHandler; -import net.i2p.router.web.Messages; import net.i2p.update.*; import net.i2p.util.EepGet; import net.i2p.util.I2PAppThread; @@ -40,7 +39,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList protected boolean _isPartial; /** set by the listeners on completion */ protected String _newVersion; - private ByteArrayOutputStream _baos; + // 56 byte header, only used for suds + private final ByteArrayOutputStream _baos; protected URI _currentURI; private static final String SIGNED_UPDATE_FILE = "i2pupdate.sud"; @@ -56,6 +56,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList _log = ctx.logManager().getLog(getClass()); _mgr = mgr; _urls = uris; + _baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES); _updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath(); } @@ -110,14 +111,11 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList if (_urls.isEmpty()) { // not likely, don't bother translating updateStatus("<b>Update source list is empty, cannot download update</b>"); - _log.log(Log.CRIT, "Update source list is empty - cannot download update"); + _log.error("Update source list is empty - cannot download update"); _mgr.notifyTaskFailed(this, "", null); return; } - ByteArrayOutputStream baos = null; - if (shouldProxy) - baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES); for (URI uri : _urls) { _currentURI = uri; String updateURL = uri.toString(); @@ -128,10 +126,10 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList // Check the first 56 bytes for the version if (shouldProxy) { _isPartial = true; - baos.reset(); + _baos.reset(); try { // no retries - _get = new PartialEepGet(_context, proxyHost, proxyPort, baos, updateURL, TrustedUpdate.HEADER_BYTES); + _get = new PartialEepGet(_context, proxyHost, proxyPort, _baos, updateURL, TrustedUpdate.HEADER_BYTES); _get.addStatusListener(UpdateRunner.this); _get.fetch(CONNECT_TIMEOUT); } catch (Throwable t) { diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index 6b542138be..5760948b39 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -1016,7 +1016,7 @@ public class I2PAppContext { /** * The controller of router, plugin, and other updates. * @return always null in I2PAppContext, the update manager if in RouterContext and it is registered - * @since 0.9.2 + * @since 0.9.4 */ public UpdateManager updateManager() { return null; diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index 8e5c202aba..d22b69dab8 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -522,7 +522,7 @@ public class RouterContext extends I2PAppContext { /** * The controller of router, plugin, and other updates. * @return The manager if it is registered, else null - * @since 0.9.2 + * @since 0.9.4 */ @Override public UpdateManager updateManager() { @@ -532,7 +532,7 @@ public class RouterContext extends I2PAppContext { /** * Register as the update manager. * @throws IllegalStateException if one was already registered - * @since 0.9.2 + * @since 0.9.4 */ public void registerUpdateManager(UpdateManager mgr) { synchronized(_lock3) { @@ -545,7 +545,7 @@ public class RouterContext extends I2PAppContext { /** * Unregister the update manager. * @throws IllegalStateException if it was not registered - * @since 0.9.2 + * @since 0.9.4 */ public void unregisterUpdateManager(UpdateManager mgr) { synchronized(_lock3) { -- GitLab