forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.jetty8' (head 0a03ce60906c508b08cc84b3044954844a6ee157)
to branch 'i2p.i2p' (head d99392e09883a92b99a316b4deed0586dcf4ea5b)
This commit is contained in:
@@ -53,6 +53,9 @@ import java.util.StringTokenizer;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import gnu.getopt.Getopt;
|
||||
import gnu.getopt.LongOpt;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
@@ -107,18 +110,46 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
|
||||
private final Set<ConnectionEventListener> listeners = new CopyOnWriteArraySet<ConnectionEventListener>();
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new I2PTunnel(args);
|
||||
private static final int NOGUI = 99999;
|
||||
private static final LongOpt[] longopts = new LongOpt[] {
|
||||
new LongOpt("cli", LongOpt.NO_ARGUMENT, null, 'c'),
|
||||
new LongOpt("die", LongOpt.NO_ARGUMENT, null, 'd'),
|
||||
new LongOpt("gui", LongOpt.NO_ARGUMENT, null, 'g'),
|
||||
new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
|
||||
new LongOpt("nocli", LongOpt.NO_ARGUMENT, null, 'w'),
|
||||
new LongOpt("nogui", LongOpt.NO_ARGUMENT, null, NOGUI),
|
||||
new LongOpt("wait", LongOpt.NO_ARGUMENT, null, 'w')
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
new I2PTunnel(args);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
System.err.println(iae.toString());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard constructor for embedded, uses args "-nocli -die" to return immediately
|
||||
*/
|
||||
public I2PTunnel() {
|
||||
this(nocli_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* See usage() for options
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public I2PTunnel(String[] args) {
|
||||
this(args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* See usage() for options
|
||||
* @param lsnr may be null
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public I2PTunnel(String[] args, ConnectionEventListener lsnr) {
|
||||
super();
|
||||
_context = I2PAppContext.getGlobalContext(); // new I2PAppContext();
|
||||
@@ -134,37 +165,95 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
boolean checkRunByE = true;
|
||||
boolean cli = true;
|
||||
boolean dontDie = true;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("-die")) {
|
||||
boolean error = false;
|
||||
List<String> eargs = null;
|
||||
Getopt g = new Getopt("i2ptunnel", args, "d::n:c::w::e:h::", longopts);
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
switch (c) {
|
||||
case 'd': // -d, -die, --die
|
||||
dontDie = false;
|
||||
gui = false;
|
||||
cli = false;
|
||||
checkRunByE = false;
|
||||
} else if (args[i].equals("-nogui")) {
|
||||
break;
|
||||
|
||||
case 'n': // -noc, -nog, -nocli, -nogui
|
||||
String a = g.getOptarg();
|
||||
if (a.startsWith("oc")) {
|
||||
gui = false;
|
||||
cli = false;
|
||||
checkRunByE = false;
|
||||
break;
|
||||
} else if (a.startsWith("og")) {
|
||||
// fall thru
|
||||
} else {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
// fall thru for -nogui only
|
||||
|
||||
case NOGUI: // --nogui
|
||||
gui = false;
|
||||
_log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
|
||||
+ "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
|
||||
} else if (args[i].equals("-cli")) {
|
||||
|
||||
case 'c': // -c, -cli, --cli
|
||||
gui = false;
|
||||
cli = true;
|
||||
checkRunByE = false;
|
||||
} else if (args[i].equals("-nocli") || args[i].equals("-wait")) {
|
||||
break;
|
||||
|
||||
case 'w': // -w, -wait, --nocli
|
||||
gui = false;
|
||||
cli = false;
|
||||
checkRunByE = false;
|
||||
} else if (args[i].equals("-e")) {
|
||||
runCommand(args[i + 1], this);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (eargs == null)
|
||||
eargs = new ArrayList<String>(4);
|
||||
eargs.add(g.getOptarg());
|
||||
if (checkRunByE) {
|
||||
checkRunByE = false;
|
||||
cli = false;
|
||||
}
|
||||
} else if (new File(args[i]).exists()) {
|
||||
runCommand("run " + args[i], this);
|
||||
} else {
|
||||
System.out.println("Unknown parameter " + args[i]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
case ':':
|
||||
default:
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
int remaining = args.length - g.getOptind();
|
||||
|
||||
if (error || remaining > 1) {
|
||||
System.err.println(usage());
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (eargs != null) {
|
||||
for (String arg : eargs) {
|
||||
runCommand(arg, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining == 1) {
|
||||
String f = args[g.getOptind()];
|
||||
File file = new File(f);
|
||||
// This is probably just a problem with the options, so
|
||||
// throw from here
|
||||
if (!file.exists()) {
|
||||
System.err.println(usage());
|
||||
throw new IllegalArgumentException("Command file does not exist: " + f);
|
||||
}
|
||||
runCommand("run " + f, this);
|
||||
}
|
||||
|
||||
if (gui) {
|
||||
new I2PTunnelGUI(this);
|
||||
} else if (cli) {
|
||||
@@ -185,6 +274,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else if (eargs == null && remaining == 0 && dontDie) {
|
||||
System.err.println(usage());
|
||||
throw new IllegalArgumentException("Waiting for nothing! Specify gui, cli, command, command file, or die");
|
||||
}
|
||||
|
||||
while (dontDie) {
|
||||
@@ -197,6 +289,23 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
}
|
||||
|
||||
/** with newlines except for last line */
|
||||
private static String usage() {
|
||||
// not sure this all makes sense, just documenting what's above
|
||||
return
|
||||
"Usage: i2ptunnel [options] [commandFile]\n" +
|
||||
" Default is to run the GUI.\n" +
|
||||
" commandFile: run all commands in this file\n" +
|
||||
" Options:\n" +
|
||||
" -c, -cli, --cli : run the command line interface\n" +
|
||||
" -d, -die, --die : exit immediately, do not wait for commands to finish\n" +
|
||||
" -e 'command [args]' : run the command\n" +
|
||||
" -h, --help : display this help\n" +
|
||||
" -nocli, --nocli : do not run the command line interface or GUI\n" +
|
||||
" -nogui, --nogui : do not run the GUI\n" +
|
||||
" -w, -wait, --wait : do not run the command line interface or GUI";
|
||||
}
|
||||
|
||||
/** @return A copy, non-null */
|
||||
List<I2PSession> getSessions() {
|
||||
return new ArrayList<I2PSession>(_sessions);
|
||||
@@ -312,30 +421,30 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* @param l logger to receive events and output
|
||||
*/
|
||||
private static void runHelp(Logging l) {
|
||||
l.log("Command list:");
|
||||
l.log("Command list:\n" +
|
||||
// alphabetical please...
|
||||
l.log(" auth <username> <password>");
|
||||
l.log(" client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]");
|
||||
l.log(" clientoptions [-acx] [key=value ]*");
|
||||
l.log(" close [forced] <jobnumber>|all");
|
||||
l.log(" config [-s] <i2phost> <i2pport>");
|
||||
l.log(" connectclient <port> [<sharedClient>] [<proxy>]");
|
||||
l.log(" genkeys <privkeyfile> [<pubkeyfile>]");
|
||||
l.log(" gentextkeys");
|
||||
l.log(" httpbidirserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>");
|
||||
l.log(" httpclient <port> [<sharedClient>] [<proxy>]");
|
||||
l.log(" httpserver <host> <port> <spoofedhost> <privkeyfile>");
|
||||
l.log(" ircclient <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]");
|
||||
l.log(" list");
|
||||
l.log(" listen_on <ip>");
|
||||
l.log(" lookup <name>");
|
||||
l.log(" owndest yes|no");
|
||||
l.log(" ping <args>");
|
||||
l.log(" quit");
|
||||
l.log(" read_timeout <msecs>");
|
||||
l.log(" run <commandfile>");
|
||||
l.log(" server <host> <port> <privkeyfile>");
|
||||
l.log(" textserver <host> <port> <privkey>");
|
||||
" auth <username> <password>\n" +
|
||||
" client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
|
||||
" clientoptions [-acx] [key=value ]*\n" +
|
||||
" close [forced] <jobnumber>|all\n" +
|
||||
" config [-s] <i2phost> <i2pport>\n" +
|
||||
" connectclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" genkeys <privkeyfile> [<pubkeyfile>]\n" +
|
||||
" gentextkeys\n" +
|
||||
" httpbidirserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>\n" +
|
||||
" httpclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" httpserver <host> <port> <spoofedhost> <privkeyfile>\n" +
|
||||
" ircclient <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
|
||||
" list\n" +
|
||||
" listen_on <ip>\n" +
|
||||
" lookup <name>\n" +
|
||||
" owndest yes|no\n" +
|
||||
" ping <args>\n" +
|
||||
" quit\n" +
|
||||
" read_timeout <msecs>\n" +
|
||||
" run <commandfile>\n" +
|
||||
" server <host> <port> <privkeyfile>\n" +
|
||||
" textserver <host> <port> <privkey>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,12 +487,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
_clientOptions.setProperty(key, val);
|
||||
}
|
||||
} else {
|
||||
l.log("Usage:");
|
||||
l.log(" clientoptions [key=value ]* // sets current options");
|
||||
l.log(" clientoptions -a [key=value ]* // adds to current options");
|
||||
l.log(" clientoptions -c // clears current options");
|
||||
l.log(" clientoptions -x [key ]* // removes listed options");
|
||||
l.log("Current options:");
|
||||
l.log("Usage:\n" +
|
||||
" clientoptions [key=value ]* // sets current options\n" +
|
||||
" clientoptions -a [key=value ]* // adds to current options\n" +
|
||||
" clientoptions -c // clears current options\n" +
|
||||
" clientoptions -x [key ]* // removes listed options\n" +
|
||||
"Current options:\n");
|
||||
Properties p = new OrderedProperties();
|
||||
p.putAll(_clientOptions);
|
||||
for (Map.Entry<Object, Object> e : p.entrySet()) {
|
||||
@@ -466,8 +575,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
|
||||
return;
|
||||
} else {
|
||||
l.log("server <host> <port> <privkeyfile>");
|
||||
l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
l.log("server <host> <port> <privkeyfile>\n" +
|
||||
" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
notifyEvent("serverTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -517,8 +626,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
|
||||
return;
|
||||
} else {
|
||||
l.log("server <host> <port> <privkeyfile>");
|
||||
l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
l.log("server <host> <port> <privkeyfile>\n" +
|
||||
" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
notifyEvent("serverTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -578,8 +687,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
|
||||
return;
|
||||
} else {
|
||||
l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>");
|
||||
l.log(" creates an HTTP server that sends all incoming data\n"
|
||||
l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>\n" +
|
||||
" creates an HTTP server that sends all incoming data\n"
|
||||
+ " of its destination to host:port., filtering the HTTP\n"
|
||||
+ " headers so it looks like the request is to the spoofed host.");
|
||||
notifyEvent("serverTaskId", Integer.valueOf(-1));
|
||||
@@ -654,8 +763,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
|
||||
return;
|
||||
} else {
|
||||
l.log("httpserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>");
|
||||
l.log(" creates a bidirectional HTTP server that sends all incoming data\n"
|
||||
l.log("httpserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>\n" +
|
||||
" creates a bidirectional HTTP server that sends all incoming data\n"
|
||||
+ " of its destination to host:port., filtering the HTTP\n"
|
||||
+ " headers so it looks like the request is to the spoofed host,"
|
||||
+ " and listens to host:proxyport to proxy HTTP requests.");
|
||||
@@ -707,8 +816,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
addtask(serv);
|
||||
notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
|
||||
} else {
|
||||
l.log("textserver <host> <port> <privkey>");
|
||||
l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
l.log("textserver <host> <port> <privkey>\n" +
|
||||
" creates a server that sends all incoming data\n" + " of its destination to host:port.");
|
||||
notifyEvent("textserverTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -765,8 +874,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]");
|
||||
l.log(" creates a client that forwards port to the pubkey.\n"
|
||||
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]\n" +
|
||||
" creates a client that forwards port to the pubkey.\n"
|
||||
+ " use 0 as port to get a free port assigned. If you specify\n"
|
||||
+ " a comma delimited list of pubkeys, it will rotate among them\n"
|
||||
+ " randomlyl. sharedClient indicates if this client shares \n"
|
||||
@@ -841,11 +950,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("httpclient <port> [<sharedClient>] [<proxy>]");
|
||||
l.log(" creates a client that distributes HTTP requests.");
|
||||
l.log(" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
|
||||
l.log(" <proxy> (optional) indicates a proxy server to be used");
|
||||
l.log(" when trying to access an address out of the .i2p domain");
|
||||
l.log("httpclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" creates a client that distributes HTTP requests.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
|
||||
" <proxy> (optional) indicates a proxy server to be used\n" +
|
||||
" when trying to access an address out of the .i2p domain");
|
||||
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -908,11 +1017,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("connectclient <port> [<sharedClient>] [<proxy>]");
|
||||
l.log(" creates a client that for SSL/HTTPS requests.");
|
||||
l.log(" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
|
||||
l.log(" <proxy> (optional) indicates a proxy server to be used");
|
||||
l.log(" when trying to access an address out of the .i2p domain");
|
||||
l.log("connectclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" creates a client that for SSL/HTTPS requests.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
|
||||
" <proxy> (optional) indicates a proxy server to be used\n" +
|
||||
" when trying to access an address out of the .i2p domain\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -975,9 +1084,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]");
|
||||
l.log(" creates a client that filter IRC protocol.");
|
||||
l.log(" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
|
||||
l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]\n" +
|
||||
" creates a client that filter IRC protocol.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n");
|
||||
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1028,8 +1137,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("sockstunnel <port>");
|
||||
l.log(" creates a tunnel that distributes SOCKS requests.");
|
||||
l.log("sockstunnel <port>\n" +
|
||||
" creates a tunnel that distributes SOCKS requests.");
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1075,8 +1184,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]");
|
||||
l.log(" creates a tunnel for SOCKS IRC.");
|
||||
l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]\n" +
|
||||
" creates a tunnel for SOCKS IRC.");
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1125,8 +1234,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
throw iae;
|
||||
}
|
||||
} else {
|
||||
l.log("streamrclient <host> <port> <destination>");
|
||||
l.log(" creates a tunnel that receives streaming data.");
|
||||
l.log("streamrclient <host> <port> <destination>\n" +
|
||||
" creates a tunnel that receives streaming data.");
|
||||
notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1166,8 +1275,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
addtask(task);
|
||||
notifyEvent("streamrtunnelTaskId", Integer.valueOf(task.getId()));
|
||||
} else {
|
||||
l.log("streamrserver <port> <privkeyfile>");
|
||||
l.log(" creates a tunnel that sends streaming data.");
|
||||
l.log("streamrserver <port> <privkeyfile>\n" +
|
||||
" creates a tunnel that sends streaming data.");
|
||||
notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1195,12 +1304,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
port = args[i];
|
||||
notifyEvent("configResult", "ok");
|
||||
} else {
|
||||
l.log("Usage:");
|
||||
l.log(" config [-s] <i2phost> <i2pport>");
|
||||
l.log(" sets the connection to the i2p router.");
|
||||
l.log("Current setting:");
|
||||
boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL"));
|
||||
l.log(" " + host + ' ' + port + (ssl ? " SSL" : ""));
|
||||
l.log("Usage:\n" +
|
||||
" config [-s] <i2phost> <i2pport>\n" +
|
||||
" sets the connection to the i2p router.\n" +
|
||||
"Current setting:\n" +
|
||||
" " + host + ' ' + port + (ssl ? " SSL" : ""));
|
||||
notifyEvent("configResult", "error");
|
||||
}
|
||||
}
|
||||
@@ -1210,16 +1319,16 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
*
|
||||
* @param args {username, password}
|
||||
* @param l logger to receive events and output
|
||||
* @since 0.9.10
|
||||
* @since 0.9.11
|
||||
*/
|
||||
private void runAuth(String args[], Logging l) {
|
||||
if (args.length == 2) {
|
||||
_clientOptions.setProperty("i2cp.username", args[0]);
|
||||
_clientOptions.setProperty("i2cp.password", args[1]);
|
||||
} else {
|
||||
l.log("Usage:");
|
||||
l.log(" auth <username> <password>");
|
||||
l.log(" Sets the i2cp credentials");
|
||||
l.log("Usage:\n" +
|
||||
" auth <username> <password>\n" +
|
||||
" Sets the i2cp credentials");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,8 +1346,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
ownDest = args[0].equalsIgnoreCase("yes");
|
||||
notifyEvent("owndestResult", "ok");
|
||||
} else {
|
||||
l.log("owndest yes|no");
|
||||
l.log(" Specifies whether to use its own destination \n" + " for each outgoing tunnel");
|
||||
l.log("owndest yes|no\n" +
|
||||
" Specifies whether to use its own destination \n" + " for each outgoing tunnel");
|
||||
notifyEvent("owndestResult", "error");
|
||||
}
|
||||
}
|
||||
@@ -1256,8 +1365,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
listenHost = args[0];
|
||||
notifyEvent("listen_onResult", "ok");
|
||||
} else {
|
||||
l.log("listen_on <ip>");
|
||||
l.log(" sets the interface to listen for the I2PClient.");
|
||||
l.log("listen_on <ip>\n" +
|
||||
" sets the interface to listen for the I2PClient.");
|
||||
notifyEvent("listen_onResult", "error");
|
||||
}
|
||||
}
|
||||
@@ -1279,15 +1388,16 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
notifyEvent("read_timeoutResult", "ok");
|
||||
} else {
|
||||
l.log("read_timeout <msecs>");
|
||||
l.log(" sets the read timeout (in milliseconds) for I2P connections\n"
|
||||
l.log("read_timeout <msecs>\n" +
|
||||
" sets the read timeout (in milliseconds) for I2P connections\n"
|
||||
+" Negative values will make the connections wait forever");
|
||||
notifyEvent("read_timeoutResult", "error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new keypair
|
||||
* Generate a new keypair.
|
||||
* Does NOT support non-default sig types.
|
||||
* Deprecated - only used by CLI
|
||||
*
|
||||
* Sets the event "genkeysResult" = "ok" or "error" after the generation is complete
|
||||
@@ -1307,8 +1417,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
return;
|
||||
}
|
||||
} else if (args.length != 1) {
|
||||
l.log("genkeys <privkeyfile> [<pubkeyfile>]");
|
||||
l.log(" creates a new keypair and prints the public key.\n"
|
||||
l.log("genkeys <privkeyfile> [<pubkeyfile>]\n" +
|
||||
" creates a new keypair and prints the public key.\n"
|
||||
+ " if pubkeyfile is given, saves the public key there." + "\n"
|
||||
+ " if the privkeyfile already exists, just print/save" + "the pubkey.");
|
||||
//notifyEvent("genkeysResult", "error");
|
||||
@@ -1330,7 +1440,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new keypair
|
||||
* Generate a new keypair.
|
||||
* Does NOT support non-default sig types.
|
||||
* Deprecated - only used by CLI
|
||||
*
|
||||
* Sets the event "privateKey" = base64 of the privateKey stream and
|
||||
@@ -1339,7 +1450,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* @param l logger to receive events and output
|
||||
*/
|
||||
private static void runGenTextKeys(Logging l) {
|
||||
ByteArrayOutputStream privkey = new ByteArrayOutputStream(512);
|
||||
ByteArrayOutputStream privkey = new ByteArrayOutputStream(1024);
|
||||
ByteArrayOutputStream pubkey = new ByteArrayOutputStream(512);
|
||||
makeKey(privkey, pubkey, l);
|
||||
l.log("Private key: " + Base64.encode(privkey.toByteArray()));
|
||||
@@ -1394,8 +1505,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
*/
|
||||
public void runClose(String args[], Logging l) {
|
||||
if (args.length == 0 || args.length > 2) {
|
||||
l.log("close [forced] <jobnumber>|all");
|
||||
l.log(" stop running tasks. either only one or all.\n"
|
||||
l.log("close [forced] <jobnumber>|all\n" +
|
||||
" stop running tasks. either only one or all.\n"
|
||||
+ " use 'forced' to also stop tasks with active connections.\n"
|
||||
+ " use the 'list' command to show the job numbers");
|
||||
notifyEvent("closeResult", "error");
|
||||
@@ -1456,8 +1567,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
notifyEvent("runResult", "error");
|
||||
}
|
||||
} else {
|
||||
l.log("run <commandfile>");
|
||||
l.log(" loads commandfile and runs each line in it. \n"
|
||||
l.log("run <commandfile>\n" +
|
||||
" loads commandfile and runs each line in it. \n"
|
||||
+ " You can also give the filename on the commandline.");
|
||||
notifyEvent("runResult", "error");
|
||||
}
|
||||
@@ -1474,8 +1585,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
*/
|
||||
private void runLookup(String args[], Logging l) {
|
||||
if (args.length != 1) {
|
||||
l.log("lookup <name>");
|
||||
l.log(" try to resolve the name into a destination key");
|
||||
l.log("lookup <name>\n" +
|
||||
" try to resolve the name into a destination key");
|
||||
notifyEvent("lookupResult", "invalidUsage");
|
||||
} else {
|
||||
try {
|
||||
@@ -1513,15 +1624,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
addtask(task);
|
||||
notifyEvent("pingTaskId", Integer.valueOf(task.getId()));
|
||||
} else {
|
||||
l.log("ping <opts> <b64dest|host>");
|
||||
l.log("ping <opts> -h (pings all hosts in hosts.txt)");
|
||||
l.log("ping <opts> -l <destlistfile> (pings a list of hosts in a file)");
|
||||
l.log(" Options:\n" +
|
||||
" -c (require 5 consecutive pings to report success)\n" +
|
||||
" -m maxSimultaneousPings (default 10)\n" +
|
||||
" -n numberOfPings (default 3)\n" +
|
||||
" -t timeout (ms, default 30000)\n");
|
||||
l.log(" Tests communication with peers.\n");
|
||||
l.log(I2Ping.usage());
|
||||
notifyEvent("pingTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1593,10 +1696,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
|
||||
/**
|
||||
* Create a new destination, storing the destination and its private keys where
|
||||
* instructed
|
||||
* instructed.
|
||||
* Does NOT support non-default sig types.
|
||||
* Deprecated - only used by CLI
|
||||
*
|
||||
* @param writeTo location to store the private keys
|
||||
* @param writeTo location to store the destination and private keys
|
||||
* @param pubDest location to store the destination
|
||||
* @param l logger to send messages to
|
||||
*/
|
||||
@@ -1605,8 +1709,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
l.log("Generating new keys...");
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
Destination d = client.createDestination(writeTo);
|
||||
l.log("Secret key saved.");
|
||||
l.log("Public key: " + d.toBase64());
|
||||
l.log("Secret key saved.\n" +
|
||||
"Public key: " + d.toBase64());
|
||||
writeTo.flush();
|
||||
writeTo.close();
|
||||
writePubKey(d, pubDest, l);
|
||||
@@ -1673,7 +1777,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* @param i2cpPort may be null
|
||||
* @param user may be null
|
||||
* @param pw may be null
|
||||
* @since 0.9.10
|
||||
* @since 0.9.11
|
||||
*/
|
||||
private static Destination destFromName(String name, String i2cpHost,
|
||||
String i2cpPort, boolean isSSL,
|
||||
|
@@ -55,7 +55,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
private int localPort;
|
||||
|
||||
/**
|
||||
* Protected for I2Ping since 0.9.10. Not for use outside package.
|
||||
* Protected for I2Ping since 0.9.11. Not for use outside package.
|
||||
*/
|
||||
protected boolean listenerReady;
|
||||
|
||||
@@ -586,7 +586,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-final since 0.9.10.
|
||||
* Non-final since 0.9.11.
|
||||
* Any overrides must set listenerReady = true.
|
||||
*/
|
||||
public void run() {
|
||||
|
@@ -24,6 +24,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.InternalSocket;
|
||||
import net.i2p.util.Log;
|
||||
@@ -409,60 +410,8 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
* @since 0.9.4
|
||||
*/
|
||||
private static Map<String, String> parseArgs(String args) {
|
||||
Map<String, String> rv = new HashMap<String, String>(8);
|
||||
char data[] = args.toCharArray();
|
||||
StringBuilder buf = new StringBuilder(32);
|
||||
boolean isQuoted = false;
|
||||
String key = null;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
switch (data[i]) {
|
||||
case '\"':
|
||||
if (isQuoted) {
|
||||
// keys never quoted
|
||||
if (key != null) {
|
||||
rv.put(key, buf.toString().trim());
|
||||
key = null;
|
||||
}
|
||||
buf.setLength(0);
|
||||
}
|
||||
isQuoted = !isQuoted;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case ',':
|
||||
// whitespace - if we're in a quoted section, keep this as part of the quote,
|
||||
// otherwise use it as a delim
|
||||
if (isQuoted) {
|
||||
buf.append(data[i]);
|
||||
} else {
|
||||
if (key != null) {
|
||||
rv.put(key, buf.toString().trim());
|
||||
key = null;
|
||||
}
|
||||
buf.setLength(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (isQuoted) {
|
||||
buf.append(data[i]);
|
||||
} else {
|
||||
key = buf.toString().trim().toLowerCase(Locale.US);
|
||||
buf.setLength(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
buf.append(data[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key != null)
|
||||
rv.put(key, buf.toString().trim());
|
||||
return rv;
|
||||
// moved to EepGet, since it needs this too
|
||||
return EepGet.parseAuthArgs(args);
|
||||
}
|
||||
|
||||
//////// Error page stuff
|
||||
|
@@ -18,6 +18,7 @@ import javax.net.ssl.SSLException;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
@@ -137,6 +138,8 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr
|
||||
protected InputStream getSocketIn() throws IOException { return s.getInputStream(); }
|
||||
protected OutputStream getSocketOut() throws IOException { return s.getOutputStream(); }
|
||||
|
||||
private static final byte[] POST = { 'P', 'O', 'S', 'T', ' ' };
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -159,8 +162,12 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr
|
||||
// So we now get a fast return from flush(), and can do it here to save 250 ms.
|
||||
// To make sure we are under the initial window size and don't hang waiting for accept,
|
||||
// only flush if it fits in one message.
|
||||
if (initialI2PData.length <= 1730) // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE
|
||||
i2pout.flush();
|
||||
if (initialI2PData.length <= 1730) { // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE
|
||||
// Don't flush if POST, so we can get POST data into the initial packet
|
||||
if (initialI2PData.length < 5 ||
|
||||
!DataHelper.eq(POST, 0, initialI2PData, 0, 5))
|
||||
i2pout.flush();
|
||||
}
|
||||
//}
|
||||
}
|
||||
if (initialSocketData != null) {
|
||||
|
@@ -11,6 +11,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import gnu.getopt.Getopt;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSession;
|
||||
@@ -86,48 +88,76 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
int count = PING_COUNT;
|
||||
boolean countPing = false;
|
||||
boolean reportTimes = true;
|
||||
while (true) {
|
||||
if (cmd.startsWith("-t ")) { // timeout
|
||||
cmd = cmd.substring(3);
|
||||
int pos = cmd.indexOf(" ");
|
||||
if (pos == -1) {
|
||||
l.log("Syntax error");
|
||||
return;
|
||||
} else {
|
||||
timeout = Long.parseLong(cmd.substring(0, pos));
|
||||
String hostListFile = null;
|
||||
int localPort = 0;
|
||||
int remotePort = 0;
|
||||
boolean error = false;
|
||||
String[] argv = cmd.split(" ");
|
||||
Getopt g = new Getopt("ping", argv, "t:m:n:chl:f:p:");
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
switch (c) {
|
||||
case 't': // timeout
|
||||
timeout = Long.parseLong(g.getOptarg());
|
||||
// convenience, convert msec to sec
|
||||
if (timeout < 100)
|
||||
timeout *= 1000;
|
||||
cmd = cmd.substring(pos + 1);
|
||||
}
|
||||
} else if (cmd.startsWith("-m ")) { // max simultaneous pings
|
||||
cmd = cmd.substring(3);
|
||||
int pos = cmd.indexOf(" ");
|
||||
if (pos == -1) {
|
||||
l.log("Syntax error");
|
||||
return;
|
||||
} else {
|
||||
MAX_SIMUL_PINGS = Integer.parseInt(cmd.substring(0, pos));
|
||||
cmd = cmd.substring(pos + 1);
|
||||
}
|
||||
} else if (cmd.startsWith("-n ")) { // number of pings
|
||||
cmd = cmd.substring(3);
|
||||
int pos = cmd.indexOf(" ");
|
||||
if (pos == -1) {
|
||||
l.log("Syntax error");
|
||||
return;
|
||||
} else {
|
||||
count = Integer.parseInt(cmd.substring(0, pos));
|
||||
cmd = cmd.substring(pos + 1);
|
||||
}
|
||||
} else if (cmd.startsWith("-c ")) { // "count" ping
|
||||
break;
|
||||
|
||||
case 'm': // max simultaneous pings
|
||||
MAX_SIMUL_PINGS = Integer.parseInt(g.getOptarg());
|
||||
break;
|
||||
|
||||
case 'n': // number of pings
|
||||
count = Integer.parseInt(g.getOptarg());
|
||||
break;
|
||||
|
||||
case 'c': // "count" ping
|
||||
countPing = true;
|
||||
count = CPING_COUNT;
|
||||
cmd = cmd.substring(3);
|
||||
} else if (cmd.equals("-h")) { // ping all hosts
|
||||
cmd = "-l hosts.txt";
|
||||
} else if (cmd.startsWith("-l ")) { // ping a list of hosts
|
||||
BufferedReader br = new BufferedReader(new FileReader(cmd.substring(3)));
|
||||
break;
|
||||
|
||||
case 'h': // ping all hosts
|
||||
if (hostListFile != null)
|
||||
error = true;
|
||||
else
|
||||
hostListFile = "hosts.txt";
|
||||
break;
|
||||
|
||||
case 'l': // ping a list of hosts
|
||||
if (hostListFile != null)
|
||||
error = true;
|
||||
else
|
||||
hostListFile = g.getOptarg();
|
||||
break;
|
||||
|
||||
case 'f': // local port
|
||||
localPort = Integer.parseInt(g.getOptarg());
|
||||
break;
|
||||
|
||||
case 'p': // remote port
|
||||
remotePort = Integer.parseInt(g.getOptarg());
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case ':':
|
||||
default:
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
int remaining = argv.length - g.getOptind();
|
||||
|
||||
if (error ||
|
||||
remaining > 1 ||
|
||||
(remaining <= 0 && hostListFile == null) ||
|
||||
(remaining > 0 && hostListFile != null)) {
|
||||
System.out.println(usage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (hostListFile != null) {
|
||||
BufferedReader br = new BufferedReader(new FileReader(hostListFile));
|
||||
String line;
|
||||
List<PingHandler> pingHandlers = new ArrayList<PingHandler>();
|
||||
int i = 0;
|
||||
@@ -138,7 +168,8 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
if (line.indexOf("=") != -1) { // maybe file is hosts.txt?
|
||||
line = line.substring(0, line.indexOf("="));
|
||||
}
|
||||
PingHandler ph = new PingHandler(line, count, timeout, countPing, reportTimes);
|
||||
PingHandler ph = new PingHandler(line, count, localPort, remotePort,
|
||||
timeout, countPing, reportTimes);
|
||||
ph.start();
|
||||
pingHandlers.add(ph);
|
||||
if (++i > 1)
|
||||
@@ -148,13 +179,31 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
for (Thread t : pingHandlers)
|
||||
t.join();
|
||||
return;
|
||||
} else {
|
||||
Thread t = new PingHandler(cmd, count, timeout, countPing, reportTimes);
|
||||
t.start();
|
||||
t.join();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String host = argv[g.getOptind()];
|
||||
Thread t = new PingHandler(host, count, localPort, remotePort,
|
||||
timeout, countPing, reportTimes);
|
||||
t.start();
|
||||
t.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* With newlines except for last line
|
||||
* @since 0.9.12
|
||||
*/
|
||||
public static String usage() {
|
||||
return
|
||||
"ping <opts> <b64dest|host>\n" +
|
||||
"ping <opts> -h (pings all hosts in hosts.txt)\n" +
|
||||
"ping <opts> -l <destlistfile> (pings a list of hosts in a file)\n" +
|
||||
"Options:\n" +
|
||||
" -c (require 5 consecutive pings to report success)\n" +
|
||||
" -m maxSimultaneousPings (default 10)\n" +
|
||||
" -n numberOfPings (default 3)\n" +
|
||||
" -t timeout (ms, default 30000)\n" +
|
||||
" -f fromPort\n" +
|
||||
" -p toPort";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +219,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean ping(Destination dest, long timeout) throws I2PException {
|
||||
private boolean ping(Destination dest, int fromPort, int toPort, long timeout) throws I2PException {
|
||||
try {
|
||||
synchronized (simulLock) {
|
||||
while (simulPings >= MAX_SIMUL_PINGS) {
|
||||
@@ -183,7 +232,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
}
|
||||
lastPingTime = System.currentTimeMillis();
|
||||
}
|
||||
boolean sent = sockMgr.ping(dest, timeout);
|
||||
boolean sent = sockMgr.ping(dest, fromPort, toPort, timeout);
|
||||
synchronized (simulLock) {
|
||||
simulPings--;
|
||||
simulLock.notifyAll();
|
||||
@@ -197,7 +246,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
|
||||
/**
|
||||
* Does nothing.
|
||||
* @since 0.9.10
|
||||
* @since 0.9.11
|
||||
*/
|
||||
protected void clientConnectionRun(Socket s) {}
|
||||
|
||||
@@ -207,15 +256,20 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
private final long timeout;
|
||||
private final boolean countPing;
|
||||
private final boolean reportTimes;
|
||||
private final int localPort;
|
||||
private final int remotePort;
|
||||
|
||||
/**
|
||||
* As of 0.9.10, does NOT start itself.
|
||||
* As of 0.9.11, does NOT start itself.
|
||||
* Caller must call start()
|
||||
* @param dest b64 or b32 or host name
|
||||
*/
|
||||
public PingHandler(String dest, int count, long timeout, boolean countPings, boolean report) {
|
||||
public PingHandler(String dest, int count, int fromPort, int toPort,
|
||||
long timeout, boolean countPings, boolean report) {
|
||||
this.destination = dest;
|
||||
cnt = count;
|
||||
localPort = fromPort;
|
||||
remotePort = toPort;
|
||||
this.timeout = timeout;
|
||||
countPing = countPings;
|
||||
reportTimes = report;
|
||||
@@ -235,8 +289,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
long totalTime = 0;
|
||||
StringBuilder pingResults = new StringBuilder(2 * cnt + destination.length() + 3);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
boolean sent;
|
||||
sent = ping(dest, timeout);
|
||||
boolean sent = ping(dest, localPort, remotePort, timeout);
|
||||
if (countPing) {
|
||||
if (!sent) {
|
||||
pingResults.append(i).append(" ");
|
||||
@@ -276,7 +329,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
|
||||
/**
|
||||
* @param name b64 or b32 or host name
|
||||
* @since 0.9.10
|
||||
* @since 0.9.11
|
||||
*/
|
||||
private Destination lookup(String name) {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
|
@@ -7,11 +7,13 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel;
|
||||
@@ -49,8 +51,8 @@ public class TunnelController implements Logging {
|
||||
* the prefix should be used (and, in turn, that prefix should be stripped off
|
||||
* before being interpreted by this controller)
|
||||
*
|
||||
* @param config original key=value mapping
|
||||
* @param prefix beginning of key values that are relevent to this tunnel
|
||||
* @param config original key=value mapping non-null
|
||||
* @param prefix beginning of key values that are relevant to this tunnel
|
||||
*/
|
||||
public TunnelController(Properties config, String prefix) {
|
||||
this(config, prefix, true);
|
||||
@@ -58,6 +60,8 @@ public class TunnelController implements Logging {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param config original key=value mapping non-null
|
||||
* @param prefix beginning of key values that are relevant to this tunnel
|
||||
* @param createKey for servers, whether we want to create a brand new destination
|
||||
* with private keys at the location specified or not (does not
|
||||
* overwrite existing ones)
|
||||
@@ -99,7 +103,16 @@ public class TunnelController implements Logging {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new SecureFileOutputStream(keyFile);
|
||||
Destination dest = client.createDestination(fos);
|
||||
SigType stype = I2PClient.DEFAULT_SIGTYPE;
|
||||
String st = _config.getProperty("option." + I2PClient.PROP_SIGTYPE);
|
||||
if (st != null) {
|
||||
SigType type = SigType.parseSigType(st);
|
||||
if (type != null)
|
||||
stype = type;
|
||||
else
|
||||
log("Unsupported sig type " + st);
|
||||
}
|
||||
Destination dest = client.createDestination(fos, stype);
|
||||
String destStr = dest.toBase64();
|
||||
log("Private key created and saved in " + keyFile.getAbsolutePath());
|
||||
log("You should backup this file in a secure place.");
|
||||
|
@@ -12,6 +12,7 @@ import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.i2ptunnel.I2PTunnel;
|
||||
import net.i2p.i2ptunnel.I2PTunnelTask;
|
||||
@@ -78,8 +79,17 @@ import net.i2p.util.EventDispatcher;
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
byte[] key;
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(512);
|
||||
client.createDestination(out);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||
SigType stype = I2PClient.DEFAULT_SIGTYPE;
|
||||
String st = tunnel.getClientOptions().getProperty(I2PClient.PROP_SIGTYPE);
|
||||
if (st != null) {
|
||||
SigType type = SigType.parseSigType(st);
|
||||
if (type != null)
|
||||
stype = type;
|
||||
else
|
||||
l.log("Unsupported sig type " + st);
|
||||
}
|
||||
client.createDestination(out, stype);
|
||||
key = out.toByteArray();
|
||||
} catch(Exception exc) {
|
||||
throw new RuntimeException("failed to create i2p-destination", exc);
|
||||
|
@@ -14,6 +14,7 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.PrivateKeyFile;
|
||||
@@ -177,6 +178,11 @@ public class EditBean extends IndexBean {
|
||||
return getBooleanProperty(tunnel, "i2cp.encryptLeaseSet");
|
||||
}
|
||||
|
||||
/** @since 0.9.12 */
|
||||
public int getSigType(int tunnel) {
|
||||
return getProperty(tunnel, I2PClient.PROP_SIGTYPE, 0);
|
||||
}
|
||||
|
||||
/** @since 0.8.9 */
|
||||
public boolean getDCC(int tunnel) {
|
||||
return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC);
|
||||
@@ -358,6 +364,11 @@ public class EditBean extends IndexBean {
|
||||
return Addresses.getAllAddresses();
|
||||
}
|
||||
|
||||
/** @since 0.9.12 */
|
||||
public boolean isAdvanced() {
|
||||
return _context.getBooleanProperty("routerconsole.advanced");
|
||||
}
|
||||
|
||||
public String getI2CPHost(int tunnel) {
|
||||
if (_context.isRouterContext())
|
||||
return _("internal");
|
||||
|
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.Outproxy;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Certificate;
|
||||
import net.i2p.data.Destination;
|
||||
@@ -983,6 +984,7 @@ public class IndexBean {
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCert(String val) {
|
||||
if (val != null) {
|
||||
try {
|
||||
@@ -990,10 +992,24 @@ public class IndexBean {
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSigner(String val) {
|
||||
_certSigner = val;
|
||||
}
|
||||
|
||||
/** @since 0.9.12 */
|
||||
public void setSigType(String val) {
|
||||
if (val != null) {
|
||||
_otherOptions.put(I2PClient.PROP_SIGTYPE, val);
|
||||
if (val.equals("0"))
|
||||
_certType = 0;
|
||||
else
|
||||
_certType = 5;
|
||||
}
|
||||
// TODO: Call modifyDestination??
|
||||
// Otherwise this only works on a new tunnel...
|
||||
}
|
||||
|
||||
/** Modify or create a destination */
|
||||
private String modifyDestination() {
|
||||
if (_privKeyFile == null || _privKeyFile.trim().length() <= 0)
|
||||
@@ -1234,13 +1250,14 @@ public class IndexBean {
|
||||
"outproxyUsername", "outproxyPassword",
|
||||
I2PTunnelHTTPClient.PROP_JUMP_SERVERS,
|
||||
I2PTunnelHTTPClientBase.PROP_AUTH,
|
||||
I2PClient.PROP_SIGTYPE,
|
||||
I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES
|
||||
};
|
||||
private static final String _otherServerOpts[] = {
|
||||
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList",
|
||||
PROP_MAX_CONNS_MIN, PROP_MAX_CONNS_HOUR, PROP_MAX_CONNS_DAY,
|
||||
PROP_MAX_TOTAL_CONNS_MIN, PROP_MAX_TOTAL_CONNS_HOUR, PROP_MAX_TOTAL_CONNS_DAY,
|
||||
PROP_MAX_STREAMS
|
||||
PROP_MAX_STREAMS, I2PClient.PROP_SIGTYPE
|
||||
};
|
||||
private static final String _httpServerOpts[] = {
|
||||
I2PTunnelHTTPServer.OPT_POST_WINDOW,
|
||||
|
Reference in New Issue
Block a user