Switched to I2Ps implementation of Base64.
Added support for the RouterInfo API call. Added support for the RouterRunner API call.
This commit is contained in:
@ -7,5 +7,6 @@
|
||||
<classpathentry kind="lib" path="/home/hottuna/Apps/i2p/lib/javax.servlet.jar"/>
|
||||
<classpathentry kind="lib" path="/home/hottuna/Apps/i2p/lib/commons-logging.jar"/>
|
||||
<classpathentry kind="lib" path="/home/hottuna/Apps/i2p/lib/router.jar"/>
|
||||
<classpathentry kind="lib" path="/home/hottuna/Apps/i2p/lib/wrapper.jar"/>
|
||||
<classpathentry kind="output" path="build/obj"/>
|
||||
</classpath>
|
||||
|
@ -3,12 +3,14 @@
|
||||
<property name="i2pbase" value="../../i2p.i2p"/>
|
||||
<property name="i2plib" value="${i2pbase}/build"/>
|
||||
<property name="jettylib" value="${i2pbase}/apps/jetty/jettylib"/>
|
||||
<property name="wrapperlib" value="${i2pbase}/installer/lib/wrapper/all"/>
|
||||
|
||||
<path id="cp">
|
||||
<pathelement path="${java.class.path}" />
|
||||
<pathelement location="${i2plib}/i2p.jar" />
|
||||
<pathelement location="${i2plib}/router.jar" />
|
||||
<pathelement location="${i2plib}/i2ptunnel.jar" />
|
||||
<pathelement location="${i2plib}/org.mortbay.jetty.jar" />
|
||||
<pathelement location="${jettylib}/ant.jar"/>
|
||||
<pathelement location="${jettylib}/org.mortbay.jetty.jar"/>
|
||||
<pathelement location="${jettylib}/jasper-compiler.jar" />
|
||||
@ -17,7 +19,7 @@
|
||||
<pathelement location="${jettylib}/commons-logging.jar" />
|
||||
<pathelement location="${jettylib}/commons-el.jar" />
|
||||
<pathelement location="${jettylib}/javax.servlet.jar" />
|
||||
<pathelement location="${i2plib}/org.mortbay.jetty.jar" />
|
||||
<pathelement location="${wrapperlib}/wrapper.jar" />
|
||||
</path>
|
||||
|
||||
<target name="all" depends="clean, build" />
|
||||
|
@ -26,6 +26,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.i2pcontrol.router.RouterManager;
|
||||
import net.i2p.i2pcontrol.security.KeyStoreInitializer;
|
||||
import net.i2p.i2pcontrol.security.SecurityManager;
|
||||
import net.i2p.i2pcontrol.servlets.JSONRPC2Servlet;
|
||||
import net.i2p.i2pcontrol.servlets.configuration.ConfigurationManager;
|
||||
import net.i2p.i2pcontrol.util.IsJar;
|
||||
import net.i2p.util.Log;
|
||||
@ -78,6 +79,7 @@ public class I2PControlController{
|
||||
_conf.getConf("i2pcontrol.listen.port", 5555);
|
||||
I2PAppContext.getGlobalContext().logManager().setDefaultLimit(Log.STR_DEBUG);
|
||||
}
|
||||
I2PAppContext.getGlobalContext().logManager().getLog(JSONRPC2Servlet.class).setMinimumPriority(Log.DEBUG); // Delete me
|
||||
|
||||
_server = new Server();
|
||||
try {
|
||||
@ -86,7 +88,7 @@ public class I2PControlController{
|
||||
ssl.setCipherSuites(SecurityManager.getSupprtedSSLCipherSuites());
|
||||
ssl.setInetAddrPort(new InetAddrPort(
|
||||
_conf.getConf("i2pcontrol.listen.address", "127.0.0.1"),
|
||||
_conf.getConf("i2pcontrol.listen.port", 7560)));
|
||||
_conf.getConf("i2pcontrol.listen.port", 7650)));
|
||||
ssl.setWantClientAuth(false); // Don't care about client authentication.
|
||||
ssl.setPassword(SecurityManager.getKeyStorePassword());
|
||||
ssl.setKeyPassword(SecurityManager.getKeyStorePassword());
|
||||
@ -115,6 +117,7 @@ public class I2PControlController{
|
||||
|
||||
|
||||
private static void stop() {
|
||||
_conf.writeConfFile();
|
||||
try {
|
||||
if (_server != null)
|
||||
_server.stop();
|
||||
@ -122,6 +125,5 @@ public class I2PControlController{
|
||||
} catch (InterruptedException e) {
|
||||
_log.error("Stopping server" + e);
|
||||
}
|
||||
_conf.writeConfFile();
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,9 @@ import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.SHA256Generator;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.i2pcontrol.security.jbcrypt.BCrypt;
|
||||
import net.i2p.i2pcontrol.servlets.configuration.ConfigurationManager;
|
||||
import net.i2p.util.Log;
|
||||
@ -110,9 +107,8 @@ public class SecurityManager {
|
||||
* @return base64 encode of X509Certificate
|
||||
*/
|
||||
private static String getBase64FromCert(X509Certificate cert){
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
try {
|
||||
return encoder.encodeBuffer(cert.getEncoded());
|
||||
return Base64.encode(cert.getEncoded());
|
||||
} catch (CertificateEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -139,8 +135,7 @@ public class SecurityManager {
|
||||
SHA256Generator hashGen = new SHA256Generator(I2PAppContext.getGlobalContext());
|
||||
byte[] bytes = string.getBytes();
|
||||
bytes = hashGen.calculateHash(bytes).toByteArray();
|
||||
BASE64Encoder encoder = new BASE64Encoder();
|
||||
return encoder.encodeBuffer(bytes).trim();
|
||||
return Base64.encode(bytes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,6 +34,8 @@ import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.AuthenticateHandler;
|
||||
import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.EchoHandler;
|
||||
import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.GetRateHandler;
|
||||
import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.NetworkSettingHandler;
|
||||
import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.RouterInfoHandler;
|
||||
import net.i2p.i2pcontrol.servlets.jsonrpc2handlers.RouterRunnerHandler;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
@ -61,6 +63,8 @@ public class JSONRPC2Servlet extends HttpServlet{
|
||||
disp.register(new GetRateHandler());
|
||||
disp.register(new AuthenticateHandler());
|
||||
disp.register(new NetworkSettingHandler());
|
||||
disp.register(new RouterInfoHandler());
|
||||
disp.register(new RouterRunnerHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,163 @@
|
||||
package net.i2p.i2pcontrol.servlets.jsonrpc2handlers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.i2pcontrol.I2PControlController;
|
||||
import net.i2p.i2pcontrol.router.RouterManager;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.router.transport.CommSystemFacadeImpl;
|
||||
import net.i2p.router.transport.FIFOBandwidthRefiller;
|
||||
import net.i2p.router.transport.TransportManager;
|
||||
import net.i2p.router.transport.ntcp.NTCPAddress;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
|
||||
import com.thetransactioncompany.jsonrpc2.server.MessageContext;
|
||||
import com.thetransactioncompany.jsonrpc2.server.RequestHandler;
|
||||
|
||||
/*
|
||||
* Copyright 2011 hottuna (dev@robertfoss.se)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
public class RouterInfoHandler implements RequestHandler {
|
||||
private static RouterContext _context;
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(RouterInfoHandler.class);
|
||||
|
||||
static {
|
||||
try {
|
||||
_context = RouterManager.getRouterContext();
|
||||
} catch (Exception e) {
|
||||
_log.error("Unable to initialize RouterContext.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[] { "RouterInfo" };
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
if (req.getMethod().equals("RouterInfo")) {
|
||||
return process(req);
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND,
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
private JSONRPC2Response process(JSONRPC2Request req) {
|
||||
JSONRPC2Error err = JSONRPC2Helper.validateParams(null, req);
|
||||
if (err != null)
|
||||
return new JSONRPC2Response(err, req.getID());
|
||||
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(new JSONRPC2Error(
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
|
||||
if (inParams.containsKey("i2p.router.version")) {
|
||||
outParams.put("i2p.router.version", RouterVersion.FULL_VERSION);
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.uptime")) {
|
||||
Router router = _context.router();
|
||||
if (router == null) {
|
||||
outParams.put("i2p.router.uptime", "[not up]");
|
||||
} else {
|
||||
outParams.put("i2p.router.uptime", DataHelper.formatDuration2(router.getUptime()));
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.status")) {
|
||||
outParams.put("i2p.router.status", _context.throttle().getTunnelStatus());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.status")) {
|
||||
outParams.put("i2p.router.net.status", getNetworkStatus());
|
||||
}
|
||||
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
|
||||
// Ripped out of SummaryHelper.java
|
||||
private String getNetworkStatus() {
|
||||
if (_context.router().getUptime() > 60 * 1000
|
||||
&& (!_context.router().gracefulShutdownInProgress())
|
||||
&& !_context.clientManager().isAlive())
|
||||
return ("ERR-Client Manager I2CP Error - check logs");
|
||||
long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
|
||||
// Display the actual skew, not the offset
|
||||
if (Math.abs(skew) > 60 * 1000)
|
||||
return "ERR-Clock Skew of " + Math.abs(skew);
|
||||
if (_context.router().isHidden())
|
||||
return ("Hidden");
|
||||
|
||||
int status = _context.commSystem().getReachabilityStatus();
|
||||
switch (status) {
|
||||
case CommSystemFacade.STATUS_OK:
|
||||
RouterAddress ra = _context.router().getRouterInfo().getTargetAddress("NTCP");
|
||||
if (ra == null || (new NTCPAddress(ra)).isPubliclyRoutable())
|
||||
return "OK";
|
||||
return "ERR-Private TCP Address";
|
||||
case CommSystemFacade.STATUS_DIFFERENT:
|
||||
return "ERR-SymmetricNAT";
|
||||
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
|
||||
if (_context.router().getRouterInfo().getTargetAddress("NTCP") != null)
|
||||
return "WARN-Firewalled with Inbound TCP Enabled";
|
||||
if (((FloodfillNetworkDatabaseFacade) _context.netDb())
|
||||
.floodfillEnabled())
|
||||
return "WARN-Firewalled and Floodfill";
|
||||
if (_context.router().getRouterInfo().getCapabilities()
|
||||
.indexOf('O') >= 0)
|
||||
return "WARN-Firewalled and Fast";
|
||||
return "Firewalled";
|
||||
case CommSystemFacade.STATUS_HOSED:
|
||||
return "ERR-UDP Port In Use";
|
||||
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
|
||||
default:
|
||||
ra = _context.router().getRouterInfo().getTargetAddress("SSU");
|
||||
if (ra == null && _context.router().getUptime() > 5 * 60 * 1000) {
|
||||
if (_context.commSystem().countActivePeers() <= 0)
|
||||
return "ERR-No Active Peers, Check Network Connection and Firewall";
|
||||
else if (_context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_HOSTNAME) == null || _context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_PORT) == null)
|
||||
return "ERR-UDP Disabled and Inbound TCP host/port not set";
|
||||
else
|
||||
return "WARN-Firewalled with UDP Disabled";
|
||||
}
|
||||
return "Testing";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package net.i2p.i2pcontrol.servlets.jsonrpc2handlers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.tanukisoftware.wrapper.WrapperManager;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.i2pcontrol.I2PControlController;
|
||||
import net.i2p.i2pcontrol.router.RouterManager;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.router.transport.CommSystemFacadeImpl;
|
||||
import net.i2p.router.transport.FIFOBandwidthRefiller;
|
||||
import net.i2p.router.transport.TransportManager;
|
||||
import net.i2p.router.transport.ntcp.NTCPAddress;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
|
||||
import com.thetransactioncompany.jsonrpc2.server.MessageContext;
|
||||
import com.thetransactioncompany.jsonrpc2.server.RequestHandler;
|
||||
|
||||
/*
|
||||
* Copyright 2011 hottuna (dev@robertfoss.se)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
public class RouterRunnerHandler implements RequestHandler {
|
||||
private static RouterContext _context;
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(RouterRunnerHandler.class);
|
||||
|
||||
private final static int SHUTDOWN_WAIT = 1500;
|
||||
|
||||
static {
|
||||
try {
|
||||
_context = RouterManager.getRouterContext();
|
||||
} catch (Exception e) {
|
||||
_log.error("Unable to initialize RouterContext.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[] { "RouterRunner" };
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
if (req.getMethod().equals("RouterRunner")) {
|
||||
return process(req);
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND,
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
private JSONRPC2Response process(JSONRPC2Request req) {
|
||||
JSONRPC2Error err = JSONRPC2Helper.validateParams(null, req);
|
||||
if (err != null)
|
||||
return new JSONRPC2Response(err, req.getID());
|
||||
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(new JSONRPC2Error(
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
|
||||
if (inParams.containsKey("Shutdown")) {
|
||||
outParams.put("Shutdown", null);
|
||||
(new Thread(){
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD));
|
||||
_context.router().shutdown(Router.EXIT_HARD); }
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("Restart")) {
|
||||
outParams.put("Restart", null);
|
||||
(new Thread(){
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD_RESTART));
|
||||
_context.router().shutdown(Router.EXIT_HARD_RESTART);
|
||||
}
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("ShutdownGraceful")) {
|
||||
outParams.put("ShutdownGraceful", null);
|
||||
(new Thread(){
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL));
|
||||
_context.router().shutdownGracefully();
|
||||
}
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("RestartGraceful")) {
|
||||
outParams.put("RestartGraceful", null);
|
||||
(new Thread(){
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART); }
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
// If no option was elected, return empty message.
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
public static class UpdateWrapperManagerTask implements Runnable {
|
||||
private int _exitCode;
|
||||
public UpdateWrapperManagerTask(int exitCode) {
|
||||
_exitCode = exitCode;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
WrapperManager.signalStopped(_exitCode);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user