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