From 0e5d164a8a8fd91003454dc0a63af1eed6cb6f3b Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Wed, 19 May 2004 22:00:32 +0000
Subject: [PATCH] support shutting down the router from the web console:  
 specify a "router.shutdownPassword" value in the router.config (or in the
 environment [ala -D]),   then specify that password on the shutdown form in
 the web console and hit submit.  after 30 seconds, it'll kill the router (and
 unless you're running the sim, it'll kill the JVM too, including clientApp.*
 started tunnels / etc) if we had some sort of ACL for accessing the web
 console, we could avoid the password field altogether, but we dont, so we
 cant.

---
 router/java/src/net/i2p/router/Router.java    |  5 ++++
 .../src/net/i2p/router/admin/AdminRunner.java | 27 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index a0ec518172..b7cd11d19f 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -232,6 +232,11 @@ public class Router {
         buf.append("</select>");
         buf.append("</form>");
 
+        buf.append("<form action=\"/shutdown\" method=\"GET\">");
+        buf.append("<b>Shut down the router:</b>");
+        buf.append("<input type=\"password\" name=\"password\" size=\"8\" />");
+        buf.append("<input type=\"submit\" value=\"shutdown!\" />");
+        buf.append("</form>");
         buf.append("<hr />\n");
 
         if ( (_routerInfo != null) && (_routerInfo.getIdentity() != null) )
diff --git a/router/java/src/net/i2p/router/admin/AdminRunner.java b/router/java/src/net/i2p/router/admin/AdminRunner.java
index c01b52bb3b..6a9dbc607b 100644
--- a/router/java/src/net/i2p/router/admin/AdminRunner.java
+++ b/router/java/src/net/i2p/router/admin/AdminRunner.java
@@ -15,6 +15,7 @@ import java.util.Set;
 import net.i2p.data.Hash;
 import net.i2p.router.RouterContext;
 import net.i2p.util.Log;
+import net.i2p.util.I2PThread;
 
 class AdminRunner implements Runnable {
     private Log _log;
@@ -52,6 +53,8 @@ class AdminRunner implements Runnable {
         } else if (command.indexOf("setTime") >= 0) {
             setTime(command);
             reply(out, "<html><body>Time updated</body></html>");
+        } else if (command.indexOf("/shutdown") >= 0) {
+            reply(out, shutdown(command));
         } else if (true || command.indexOf("routerConsole.html") > 0) {
             reply(out, _context.router().renderStatusHTML());
         }
@@ -135,4 +138,28 @@ class AdminRunner implements Runnable {
     private void setTime(long now) {
         _context.clock().setNow(now);
     }
+    
+    
+    private static final String SHUTDOWN_PASSWORD_PROP = "router.shutdownPassword";
+    private String shutdown(String cmd) {
+        String password = _context.router().getConfigSetting(SHUTDOWN_PASSWORD_PROP);
+        if (password == null)
+            password = _context.getProperty(SHUTDOWN_PASSWORD_PROP);
+        if (password == null) 
+            return "No shutdown password specified in the config or context - <b>REFUSING SHUTDOWN</b>." +
+                   "<a href=\"/routerConsole.html\">back</a>";
+        if (cmd.indexOf(password) > 0) {
+            I2PThread t = new I2PThread(new Runnable() {
+                public void run() { 
+                    try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
+                    _context.router().shutdown();
+                }
+            });
+            t.start();
+            return "Shutdown request accepted.  Killing the router in 30 seconds";
+        } else {
+            return "Incorrect shutdown password specified.  Please edit your router.config appropriately." +
+                   "<a href=\"/routerConsole.html\">back</a>";
+        }
+    }
 }
-- 
GitLab