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:
dev
2011-07-15 12:46:08 +00:00
parent fadfd0d0cf
commit a6ae4c8405
7 changed files with 347 additions and 11 deletions

View File

@ -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>

View File

@ -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" />

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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";
}
}
}

View File

@ -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();
}
}
}
}