Use TunnelConfig now in i2ptunnel.jar

This commit is contained in:
str4d
2015-03-10 20:52:59 +00:00
parent a0419c9eb7
commit 97d1367180
4 changed files with 148 additions and 682 deletions

View File

@ -1,19 +1,20 @@
package net.i2p.android.i2ptunnel;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.widget.Toast;
import net.i2p.android.i2ptunnel.util.TunnelConfig;
import net.i2p.android.i2ptunnel.util.TunnelUtil;
import net.i2p.android.router.R;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile;
import net.i2p.i2ptunnel.TunnelConfig;
import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import java.util.List;
public class TunnelEntry {
public static final int RUNNING = 1;
public static final int STARTING = 2;

View File

@ -18,10 +18,11 @@ import android.widget.ListView;
import android.widget.Toast;
import net.i2p.android.help.HelpActivity;
import net.i2p.android.i2ptunnel.util.TunnelConfig;
import net.i2p.android.i2ptunnel.util.TunnelUtil;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.android.router.R;
import net.i2p.i2ptunnel.TunnelConfig;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.router.RouterContext;
@ -231,7 +232,7 @@ public class TunnelListFragment extends ListFragment implements
if (requestCode == TUNNEL_WIZARD_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
Bundle tunnelData = data.getExtras().getBundle(TUNNEL_WIZARD_DATA);
TunnelConfig cfg = TunnelConfig.createFromWizard(getActivity(), mGroup, tunnelData);
TunnelConfig cfg = TunnelUtil.createConfigFromWizard(getActivity(), mGroup, tunnelData);
TunnelEntry tunnel = TunnelEntry.createNewTunnel(getActivity(), mGroup, cfg);
mAdapter.add(tunnel);
}

View File

@ -1,668 +0,0 @@
package net.i2p.android.i2ptunnel.util;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import net.i2p.I2PAppContext;
import net.i2p.android.router.R;
import net.i2p.android.wizard.model.Page;
import net.i2p.i2ptunnel.I2PTunnelConnectClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase;
import net.i2p.i2ptunnel.I2PTunnelIRCClient;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.PasswordManager;
public class TunnelConfig {
protected final I2PAppContext _context;
private String _type;
private String _name;
private String _description;
private String _i2cpHost;
private String _i2cpPort;
private String _tunnelDepth;
private String _tunnelQuantity;
private String _tunnelVariance;
private String _tunnelBackupQuantity;
private boolean _connectDelay;
private String _customOptions;
private String _proxyList;
private String _port;
private String _reachableBy;
private String _targetDestination;
private String _targetHost;
private String _targetPort;
private String _spoofedHost;
private String _privKeyFile;
private String _profile;
private boolean _startOnLoad;
private boolean _sharedClient;
private final Set<String> _booleanOptions;
private final Map<String, String> _otherOptions;
private String _newProxyUser;
private String _newProxyPW;
static final String CLIENT_NICKNAME = "shared clients";
public static TunnelConfig createFromWizard(
Context ctx, TunnelControllerGroup tcg, Bundle data) {
// Get the Bundle keys
Resources res = ctx.getResources();
String kClientServer = res.getString(R.string.i2ptunnel_wizard_k_client_server);
String kType = res.getString(R.string.i2ptunnel_wizard_k_type);
String kName = res.getString(R.string.i2ptunnel_wizard_k_name);
String kDesc = res.getString(R.string.i2ptunnel_wizard_k_desc);
String kDest = res.getString(R.string.i2ptunnel_wizard_k_dest);
String kOutproxies = res.getString(R.string.i2ptunnel_wizard_k_outproxies);
String kTargetHost = res.getString(R.string.i2ptunnel_wizard_k_target_host);
String kTargetPort = res.getString(R.string.i2ptunnel_wizard_k_target_port);
String kReachableOn = res.getString(R.string.i2ptunnel_wizard_k_reachable_on);
String kBindingPort = res.getString(R.string.i2ptunnel_wizard_k_binding_port);
String kAutoStart = res.getString(R.string.i2ptunnel_wizard_k_auto_start);
// Create the TunnelConfig
TunnelConfig cfg = new TunnelConfig();
// Get/set the tunnel wizard settings
String clientServer = data.getBundle(kClientServer).getString(Page.SIMPLE_DATA_KEY);
String typeName = data.getBundle(clientServer + ":" + kType).getString(Page.SIMPLE_DATA_KEY);
String type = TunnelUtil.getTypeFromName(typeName, ctx);
cfg.setType(type);
String name = data.getBundle(kName).getString(Page.SIMPLE_DATA_KEY);
cfg.setName(name);
String desc = data.getBundle(kDesc).getString(Page.SIMPLE_DATA_KEY);
cfg.setDescription(desc);
String dest = null;
Bundle pageData = data.getBundle(kDest);
if (pageData != null) dest = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setTargetDestination(dest);
String outproxies = null;
pageData = data.getBundle(kOutproxies);
if (pageData != null) outproxies = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setProxyList(outproxies);
String targetHost = null;
pageData = data.getBundle(kTargetHost);
if (pageData != null) targetHost = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setTargetHost(targetHost);
String targetPort = null;
pageData = data.getBundle(kTargetPort);
if (pageData != null) targetPort = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setTargetPort(targetPort);
String reachableOn = null;
pageData = data.getBundle(kReachableOn);
if (pageData != null) reachableOn = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setReachableBy(reachableOn);
String bindingPort = null;
pageData = data.getBundle(kBindingPort);
if (pageData != null) bindingPort = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setPort(bindingPort);
boolean autoStart = data.getBundle(kAutoStart).getBoolean(Page.SIMPLE_DATA_KEY);
cfg.setStartOnLoad(autoStart);
// Set sensible defaults for a new tunnel
cfg.setTunnelDepth("3");
cfg.setTunnelVariance("0");
cfg.setTunnelQuantity("2");
cfg.setTunnelBackupQuantity("0");
cfg.setClientHost("internal");
cfg.setClientport("internal");
cfg.setCustomOptions("");
if (!"streamrclient".equals(type)) {
cfg.setProfile("bulk");
cfg.setReduceCount("1");
cfg.setReduceTime("20");
}
if (TunnelUtil.isClient(type)) { /* Client-only defaults */
if (!"streamrclient".equals(type)) {
cfg.setNewDest("0");
cfg.setCloseTime("30");
}
if ("httpclient".equals(type) ||
"connectclient".equals(type) ||
"sockstunnel".equals(type) |
"socksirctunnel".equals(type)) {
cfg.setProxyUsername("");
cfg.setProxyPassword("");
cfg.setOutproxyUsername("");
cfg.setOutproxyPassword("");
}
if ("httpclient".equals(type))
cfg.setJumpList("http://i2host.i2p/cgi-bin/i2hostjump?\nhttp://stats.i2p/cgi-bin/jump.cgi?a=");
} else { /* Server-only defaults */
cfg.setPrivKeyFile(TunnelUtil.getPrivateKeyFile(tcg, -1));
cfg.setEncrypt("");
cfg.setEncryptKey("");
cfg.setAccessMode("0");
cfg.setAccessList("");
cfg.setLimitMinute("0");
cfg.setLimitHour("0");
cfg.setLimitDay("0");
cfg.setTotalMinute("0");
cfg.setTotalHour("0");
cfg.setTotalDay("0");
cfg.setMaxStreams("0");
}
return cfg;
}
public TunnelConfig() {
_context = I2PAppContext.getGlobalContext();
_booleanOptions = new ConcurrentHashSet<String>(4);
_otherOptions = new ConcurrentHashMap<String,String>(4);
}
/**
* What type of tunnel (httpclient, ircclient, client, or server). This is
* required when adding a new tunnel.
*
*/
public void setType(String type) {
_type = (type != null ? type.trim() : null);
}
String getType() { return _type; }
/** Short name of the tunnel */
public void setName(String name) {
_name = (name != null ? name.trim() : null);
}
/** one line description */
public void setDescription(String description) {
_description = (description != null ? description.trim() : null);
}
/** I2CP host the router is on, ignored when in router context */
public void setClientHost(String host) {
_i2cpHost = (host != null ? host.trim() : null);
}
/** I2CP port the router is on, ignored when in router context */
public void setClientport(String port) {
_i2cpPort = (port != null ? port.trim() : null);
}
/** how many hops to use for inbound tunnels */
public void setTunnelDepth(String tunnelDepth) {
_tunnelDepth = (tunnelDepth != null ? tunnelDepth.trim() : null);
}
/** how many parallel inbound tunnels to use */
public void setTunnelQuantity(String tunnelQuantity) {
_tunnelQuantity = (tunnelQuantity != null ? tunnelQuantity.trim() : null);
}
/** how much randomisation to apply to the depth of tunnels */
public void setTunnelVariance(String tunnelVariance) {
_tunnelVariance = (tunnelVariance != null ? tunnelVariance.trim() : null);
}
/** how many tunnels to hold in reserve to guard against failures */
public void setTunnelBackupQuantity(String tunnelBackupQuantity) {
_tunnelBackupQuantity = (tunnelBackupQuantity != null ? tunnelBackupQuantity.trim() : null);
}
/** what I2P session overrides should be used */
public void setCustomOptions(String customOptions) {
_customOptions = (customOptions != null ? customOptions.trim() : null);
}
/** what HTTP outproxies should be used (httpclient specific) */
public void setProxyList(String proxyList) {
_proxyList = (proxyList != null ? proxyList.trim() : null);
}
/** what port should this client/httpclient/ircclient listen on */
public void setPort(String port) {
_port = (port != null ? port.trim() : null);
}
/**
* what interface should this client/httpclient/ircclient listen on
*/
public void setReachableBy(String reachableBy) {
_reachableBy = (reachableBy != null ? reachableBy.trim() : null);
}
/** What peer does this client tunnel point at */
public void setTargetDestination(String dest) {
_targetDestination = (dest != null ? dest.trim() : null);
}
/** What host does this server tunnel point at */
public void setTargetHost(String host) {
_targetHost = (host != null ? host.trim() : null);
}
/** What port does this server tunnel point at */
public void setTargetPort(String port) {
_targetPort = (port != null ? port.trim() : null);
}
/** What host does this http server tunnel spoof */
public void setSpoofedHost(String host) {
_spoofedHost = (host != null ? host.trim() : null);
}
/** What filename is this server tunnel's private keys stored in */
public void setPrivKeyFile(String file) {
_privKeyFile = (file != null ? file.trim() : null);
}
/**
* If called with true, we want this tunnel to start whenever it is
* loaded (aka right now and whenever the router is started up)
*/
public void setStartOnLoad(boolean val) {
_startOnLoad = val;
}
public void setShared(boolean val) {
_sharedClient=val;
}
public void setConnectDelay(String moo) {
_connectDelay = true;
}
public void setProfile(String profile) {
_profile = profile;
}
public void setReduce(String moo) {
_booleanOptions.add("i2cp.reduceOnIdle");
}
public void setClose(String moo) {
_booleanOptions.add("i2cp.closeOnIdle");
}
public void setEncrypt(String moo) {
_booleanOptions.add("i2cp.encryptLeaseSet");
}
/** @since 0.8.9 */
public void setDCC(String moo) {
_booleanOptions.add(I2PTunnelIRCClient.PROP_DCC);
}
protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
public void setAccessMode(String val) {
if ("1".equals(val))
_booleanOptions.add(PROP_ENABLE_ACCESS_LIST);
else if ("2".equals(val))
_booleanOptions.add(PROP_ENABLE_BLACKLIST);
}
public void setDelayOpen(String moo) {
_booleanOptions.add("i2cp.delayOpen");
}
public void setNewDest(String val) {
if ("1".equals(val))
_booleanOptions.add("i2cp.newDestOnResume");
else if ("2".equals(val))
_booleanOptions.add("persistentClientKey");
}
public void setReduceTime(String val) {
if (val != null) {
try {
_otherOptions.put("i2cp.reduceIdleTime", "" + (Integer.parseInt(val.trim()) * 60*1000));
} catch (NumberFormatException nfe) {}
}
}
public void setReduceCount(String val) {
if (val != null)
_otherOptions.put("i2cp.reduceQuantity", val.trim());
}
public void setEncryptKey(String val) {
if (val != null)
_otherOptions.put("i2cp.leaseSetKey", val.trim());
}
public void setAccessList(String val) {
if (val != null)
_otherOptions.put("i2cp.accessList", val.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
}
public void setJumpList(String val) {
if (val != null)
_otherOptions.put(I2PTunnelHTTPClient.PROP_JUMP_SERVERS, val.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
}
public void setCloseTime(String val) {
if (val != null) {
try {
_otherOptions.put("i2cp.closeIdleTime", "" + (Integer.parseInt(val.trim()) * 60*1000));
} catch (NumberFormatException nfe) {}
}
}
/** all proxy auth @since 0.8.2 */
public void setProxyAuth(String s) {
if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
}
public void setProxyUsername(String s) {
if (s != null)
_newProxyUser = s.trim();
}
public void setProxyPassword(String s) {
if (s != null)
_newProxyPW = s.trim();
}
public void setOutproxyAuth(String s) {
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
}
public void setOutproxyUsername(String s) {
if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_USER, s.trim());
}
public void setOutproxyPassword(String s) {
if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_PW, s.trim());
}
/** all of these are @since 0.8.3 */
protected static final String PROP_MAX_CONNS_MIN = "i2p.streaming.maxConnsPerMinute";
protected static final String PROP_MAX_CONNS_HOUR = "i2p.streaming.maxConnsPerHour";
protected static final String PROP_MAX_CONNS_DAY = "i2p.streaming.maxConnsPerDay";
protected static final String PROP_MAX_TOTAL_CONNS_MIN = "i2p.streaming.maxTotalConnsPerMinute";
protected static final String PROP_MAX_TOTAL_CONNS_HOUR = "i2p.streaming.maxTotalConnsPerHour";
protected static final String PROP_MAX_TOTAL_CONNS_DAY = "i2p.streaming.maxTotalConnsPerDay";
protected static final String PROP_MAX_STREAMS = "i2p.streaming.maxConcurrentStreams";
public void setLimitMinute(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_CONNS_MIN, s.trim());
}
public void setLimitHour(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_CONNS_HOUR, s.trim());
}
public void setLimitDay(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_CONNS_DAY, s.trim());
}
public void setTotalMinute(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_TOTAL_CONNS_MIN, s.trim());
}
public void setTotalHour(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_TOTAL_CONNS_HOUR, s.trim());
}
public void setTotalDay(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_TOTAL_CONNS_DAY, s.trim());
}
public void setMaxStreams(String s) {
if (s != null)
_otherOptions.put(PROP_MAX_STREAMS, s.trim());
}
/**
* Based on all provided data, create a set of configuration parameters
* suitable for use in a TunnelController. This will replace (not add to)
* any existing parameters, so this should return a comprehensive mapping.
*
*/
public Properties getConfig() {
Properties config = new Properties();
updateConfigGeneric(config);
if ((TunnelUtil.isClient(_type) && !"streamrclient".equals(_type)) || "streamrserver".equals(_type)) {
// streamrserver uses interface
if (_reachableBy != null)
config.setProperty("interface", _reachableBy);
else
config.setProperty("interface", "");
} else {
// streamrclient uses targetHost
if (_targetHost != null)
config.setProperty("targetHost", _targetHost);
}
if (TunnelUtil.isClient(_type)) {
// generic client stuff
if (_port != null)
config.setProperty("listenPort", _port);
config.setProperty("sharedClient", _sharedClient + "");
for (String p : _booleanClientOpts)
config.setProperty("option." + p, "" + _booleanOptions.contains(p));
for (String p : _otherClientOpts)
if (_otherOptions.containsKey(p))
config.setProperty("option." + p, _otherOptions.get(p));
} else {
// generic server stuff
if (_targetPort != null)
config.setProperty("targetPort", _targetPort);
for (String p : _booleanServerOpts)
config.setProperty("option." + p, "" + _booleanOptions.contains(p));
for (String p : _otherServerOpts)
if (_otherOptions.containsKey(p))
config.setProperty("option." + p, _otherOptions.get(p));
}
// generic proxy stuff
if ("httpclient".equals(_type) || "connectclient".equals(_type) ||
"sockstunnel".equals(_type) ||"socksirctunnel".equals(_type)) {
for (String p : _booleanProxyOpts)
config.setProperty("option." + p, "" + _booleanOptions.contains(p));
if (_proxyList != null)
config.setProperty("proxyList", _proxyList);
}
// Proxy auth including migration to MD5
if ("httpclient".equals(_type) || "connectclient".equals(_type)) {
// Migrate even if auth is disabled
// go get the old from custom options that updateConfigGeneric() put in there
String puser = "option." + I2PTunnelHTTPClientBase.PROP_USER;
String user = config.getProperty(puser);
String ppw = "option." + I2PTunnelHTTPClientBase.PROP_PW;
String pw = config.getProperty(ppw);
if (user != null && pw != null && user.length() > 0 && pw.length() > 0) {
String pmd5 = "option." + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX +
user + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
if (config.getProperty(pmd5) == null) {
// not in there, migrate
String realm = _type.equals("httpclient") ? I2PTunnelHTTPClient.AUTH_REALM
: I2PTunnelConnectClient.AUTH_REALM;
String hex = PasswordManager.md5Hex(realm, user, pw);
if (hex != null) {
config.setProperty(pmd5, hex);
config.remove(puser);
config.remove(ppw);
}
}
}
// New user/password
String auth = _otherOptions.get(I2PTunnelHTTPClientBase.PROP_AUTH);
if (auth != null && !auth.equals("false")) {
if (_newProxyUser != null && _newProxyPW != null &&
_newProxyUser.length() > 0 && _newProxyPW.length() > 0) {
String pmd5 = "option." + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX +
_newProxyUser + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
String realm = _type.equals("httpclient") ? I2PTunnelHTTPClient.AUTH_REALM
: I2PTunnelConnectClient.AUTH_REALM;
String hex = PasswordManager.md5Hex(realm, _newProxyUser, _newProxyPW);
if (hex != null)
config.setProperty(pmd5, hex);
}
}
}
if ("ircclient".equals(_type) || "client".equals(_type) || "streamrclient".equals(_type)) {
if (_targetDestination != null)
config.setProperty("targetDestination", _targetDestination);
} else if ("httpserver".equals(_type) || "httpbidirserver".equals(_type)) {
if (_spoofedHost != null)
config.setProperty("spoofedHost", _spoofedHost);
}
if ("httpbidirserver".equals(_type)) {
if (_port != null)
config.setProperty("listenPort", _port);
if (_reachableBy != null)
config.setProperty("interface", _reachableBy);
else if (_targetHost != null)
config.setProperty("interface", _targetHost);
else
config.setProperty("interface", "");
}
if ("ircclient".equals(_type)) {
boolean dcc = _booleanOptions.contains(I2PTunnelIRCClient.PROP_DCC);
config.setProperty("option." + I2PTunnelIRCClient.PROP_DCC,
"" + dcc);
// add some sane server options since they aren't in the GUI (yet)
if (dcc) {
config.setProperty("option." + PROP_MAX_CONNS_MIN, "3");
config.setProperty("option." + PROP_MAX_CONNS_HOUR, "10");
config.setProperty("option." + PROP_MAX_TOTAL_CONNS_MIN, "5");
config.setProperty("option." + PROP_MAX_TOTAL_CONNS_HOUR, "25");
}
}
return config;
}
private static final String _noShowOpts[] = {
"inbound.length", "outbound.length", "inbound.lengthVariance", "outbound.lengthVariance",
"inbound.backupQuantity", "outbound.backupQuantity", "inbound.quantity", "outbound.quantity",
"inbound.nickname", "outbound.nickname", "i2p.streaming.connectDelay", "i2p.streaming.maxWindowSize",
I2PTunnelIRCClient.PROP_DCC
};
private static final String _booleanClientOpts[] = {
"i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen"
};
private static final String _booleanProxyOpts[] = {
I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH
};
private static final String _booleanServerOpts[] = {
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST
};
private static final String _otherClientOpts[] = {
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime",
"outproxyUsername", "outproxyPassword",
I2PTunnelHTTPClient.PROP_JUMP_SERVERS,
I2PTunnelHTTPClientBase.PROP_AUTH
};
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
};
/**
* do NOT add these to noShoOpts, we must leave them in for HTTPClient and ConnectCLient
* so they will get migrated to MD5
* TODO migrate socks to MD5
*/
private static final String _otherProxyOpts[] = {
"proxyUsername", "proxyPassword"
};
protected static final Set<String> _noShowSet = new HashSet<String>(64);
protected static final Set<String> _nonProxyNoShowSet = new HashSet<String>(4);
static {
_noShowSet.addAll(Arrays.asList(_noShowOpts));
_noShowSet.addAll(Arrays.asList(_booleanClientOpts));
_noShowSet.addAll(Arrays.asList(_booleanProxyOpts));
_noShowSet.addAll(Arrays.asList(_booleanServerOpts));
_noShowSet.addAll(Arrays.asList(_otherClientOpts));
_noShowSet.addAll(Arrays.asList(_otherServerOpts));
_nonProxyNoShowSet.addAll(Arrays.asList(_otherProxyOpts));
}
private void updateConfigGeneric(Properties config) {
config.setProperty("type", _type);
if (_name != null)
config.setProperty("name", _name);
if (_description != null)
config.setProperty("description", _description);
if (!_context.isRouterContext()) {
if (_i2cpHost != null)
config.setProperty("i2cpHost", _i2cpHost);
if ( (_i2cpPort != null) && (_i2cpPort.trim().length() > 0) ) {
config.setProperty("i2cpPort", _i2cpPort);
} else {
config.setProperty("i2cpPort", "7654");
}
}
if (_privKeyFile != null)
config.setProperty("privKeyFile", _privKeyFile);
if (_customOptions != null) {
StringTokenizer tok = new StringTokenizer(_customOptions);
while (tok.hasMoreTokens()) {
String pair = tok.nextToken();
int eq = pair.indexOf('=');
if ( (eq <= 0) || (eq >= pair.length()) )
continue;
String key = pair.substring(0, eq);
if (_noShowSet.contains(key))
continue;
// leave in for HTTP and Connect so it can get migrated to MD5
// hide for SOCKS until migrated to MD5
if ((!"httpclient".equals(_type)) &&
(! "connectclient".equals(_type)) &&
_nonProxyNoShowSet.contains(key))
continue;
String val = pair.substring(eq+1);
config.setProperty("option." + key, val);
}
}
config.setProperty("startOnLoad", _startOnLoad + "");
if (_tunnelQuantity != null) {
config.setProperty("option.inbound.quantity", _tunnelQuantity);
config.setProperty("option.outbound.quantity", _tunnelQuantity);
}
if (_tunnelDepth != null) {
config.setProperty("option.inbound.length", _tunnelDepth);
config.setProperty("option.outbound.length", _tunnelDepth);
}
if (_tunnelVariance != null) {
config.setProperty("option.inbound.lengthVariance", _tunnelVariance);
config.setProperty("option.outbound.lengthVariance", _tunnelVariance);
}
if (_tunnelBackupQuantity != null) {
config.setProperty("option.inbound.backupQuantity", _tunnelBackupQuantity);
config.setProperty("option.outbound.backupQuantity", _tunnelBackupQuantity);
}
if (_connectDelay)
config.setProperty("option.i2p.streaming.connectDelay", "1000");
else
config.setProperty("option.i2p.streaming.connectDelay", "0");
if (TunnelUtil.isClient(_type) && _sharedClient) {
config.setProperty("option.inbound.nickname", CLIENT_NICKNAME);
config.setProperty("option.outbound.nickname", CLIENT_NICKNAME);
} else if (_name != null) {
config.setProperty("option.inbound.nickname", _name);
config.setProperty("option.outbound.nickname", _name);
}
if ("interactive".equals(_profile))
// This was 1 which doesn't make much sense
// The real way to make it interactive is to make the streaming lib
// MessageInputStream flush faster but there's no option for that yet,
// Setting it to 16 instead of the default but not sure what good that is either.
config.setProperty("option.i2p.streaming.maxWindowSize", "16");
else
config.remove("option.i2p.streaming.maxWindowSize");
}
}

View File

@ -2,10 +2,15 @@ package net.i2p.android.i2ptunnel.util;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import net.i2p.I2PAppContext;
import net.i2p.android.router.R;
import net.i2p.android.router.util.Util;
import net.i2p.android.wizard.model.Page;
import net.i2p.i2ptunnel.I2PTunnelHTTPServer;
import net.i2p.i2ptunnel.I2PTunnelServer;
import net.i2p.i2ptunnel.TunnelConfig;
import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.util.FileUtil;
@ -82,8 +87,8 @@ public abstract class TunnelUtil {
cOpt.setProperty("option.inbound.backupQuantity", config.getProperty("option.inbound.backupQuantity"));
if (config.getProperty("option.outbound.backupQuantity") != null)
cOpt.setProperty("option.outbound.backupQuantity", config.getProperty("option.outbound.backupQuantity"));
cOpt.setProperty("option.inbound.nickname", TunnelConfig.CLIENT_NICKNAME);
cOpt.setProperty("option.outbound.nickname", TunnelConfig.CLIENT_NICKNAME);
cOpt.setProperty("option.inbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
cOpt.setProperty("option.outbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
c.setConfig(cOpt, "");
}
@ -223,13 +228,7 @@ public abstract class TunnelUtil {
}
public static boolean isClient(String type) {
return ( ("client".equals(type)) ||
("httpclient".equals(type)) ||
("sockstunnel".equals(type)) ||
("socksirctunnel".equals(type)) ||
("connectclient".equals(type)) ||
("streamrclient".equals(type)) ||
("ircclient".equals(type)));
return TunnelController.isClient(type);
}
public static String getPrivateKeyFile(TunnelControllerGroup tcg, int tunnel) {
@ -240,4 +239,137 @@ public abstract class TunnelUtil {
tunnel = tcg == null ? 999 : tcg.getControllers().size();
return "i2ptunnel" + tunnel + "-privKeys.dat";
}
/** @since 0.9.9 */
public boolean isSSLEnabled(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
return Boolean.parseBoolean(opts.getProperty(I2PTunnelServer.PROP_USE_SSL));
}
return false;
}
/** @since 0.9.12 */
public boolean isRejectInproxy(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
return Boolean.parseBoolean(opts.getProperty(I2PTunnelHTTPServer.OPT_REJECT_INPROXY));
}
return false;
}
public static TunnelConfig createConfigFromWizard(
Context ctx, TunnelControllerGroup tcg, Bundle data) {
// Get the Bundle keys
Resources res = ctx.getResources();
String kClientServer = res.getString(R.string.i2ptunnel_wizard_k_client_server);
String kType = res.getString(R.string.i2ptunnel_wizard_k_type);
String kName = res.getString(R.string.i2ptunnel_wizard_k_name);
String kDesc = res.getString(R.string.i2ptunnel_wizard_k_desc);
String kDest = res.getString(R.string.i2ptunnel_wizard_k_dest);
String kOutproxies = res.getString(R.string.i2ptunnel_wizard_k_outproxies);
String kTargetHost = res.getString(R.string.i2ptunnel_wizard_k_target_host);
String kTargetPort = res.getString(R.string.i2ptunnel_wizard_k_target_port);
String kReachableOn = res.getString(R.string.i2ptunnel_wizard_k_reachable_on);
String kBindingPort = res.getString(R.string.i2ptunnel_wizard_k_binding_port);
String kAutoStart = res.getString(R.string.i2ptunnel_wizard_k_auto_start);
// Create the TunnelConfig
TunnelConfig cfg = new TunnelConfig();
// Get/set the tunnel wizard settings
String clientServer = data.getBundle(kClientServer).getString(Page.SIMPLE_DATA_KEY);
String typeName = data.getBundle(clientServer + ":" + kType).getString(Page.SIMPLE_DATA_KEY);
String type = getTypeFromName(typeName, ctx);
cfg.setType(type);
String name = data.getBundle(kName).getString(Page.SIMPLE_DATA_KEY);
cfg.setName(name);
String desc = data.getBundle(kDesc).getString(Page.SIMPLE_DATA_KEY);
cfg.setDescription(desc);
String dest = null;
Bundle pageData = data.getBundle(kDest);
if (pageData != null) dest = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setTargetDestination(dest);
String outproxies = null;
pageData = data.getBundle(kOutproxies);
if (pageData != null) outproxies = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setProxyList(outproxies);
String targetHost = null;
pageData = data.getBundle(kTargetHost);
if (pageData != null) targetHost = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setTargetHost(targetHost);
int targetPort = -1;
pageData = data.getBundle(kTargetPort);
if (pageData != null) targetPort = pageData.getInt(Page.SIMPLE_DATA_KEY);
cfg.setTargetPort(targetPort);
String reachableOn = null;
pageData = data.getBundle(kReachableOn);
if (pageData != null) reachableOn = pageData.getString(Page.SIMPLE_DATA_KEY);
cfg.setReachableBy(reachableOn);
int bindingPort = -1;
pageData = data.getBundle(kBindingPort);
if (pageData != null) bindingPort = pageData.getInt(Page.SIMPLE_DATA_KEY);
cfg.setPort(bindingPort);
boolean autoStart = data.getBundle(kAutoStart).getBoolean(Page.SIMPLE_DATA_KEY);
cfg.setStartOnLoad(autoStart);
// Set sensible defaults for a new tunnel
cfg.setTunnelDepth(3);
cfg.setTunnelVariance(0);
cfg.setTunnelQuantity(2);
cfg.setTunnelBackupQuantity(0);
cfg.setClientHost("internal");
cfg.setClientPort("internal");
cfg.setCustomOptions("");
if (!"streamrclient".equals(type)) {
cfg.setProfile("bulk");
cfg.setReduceCount(1);
cfg.setReduceTime(20);
}
if (TunnelUtil.isClient(type)) { /* Client-only defaults */
if (!"streamrclient".equals(type)) {
cfg.setNewDest("0");
cfg.setCloseTime(30);
}
if ("httpclient".equals(type) ||
"connectclient".equals(type) ||
"sockstunnel".equals(type) |
"socksirctunnel".equals(type)) {
cfg.setProxyUsername("");
cfg.setProxyPassword("");
cfg.setOutproxyUsername("");
cfg.setOutproxyPassword("");
}
if ("httpclient".equals(type))
cfg.setJumpList("http://i2host.i2p/cgi-bin/i2hostjump?\nhttp://stats.i2p/cgi-bin/jump.cgi?a=");
} else { /* Server-only defaults */
cfg.setPrivKeyFile(TunnelUtil.getPrivateKeyFile(tcg, -1));
cfg.setEncrypt();
cfg.setEncryptKey("");
cfg.setAccessMode("0");
cfg.setAccessList("");
cfg.setLimitMinute(0);
cfg.setLimitHour(0);
cfg.setLimitDay(0);
cfg.setTotalMinute(0);
cfg.setTotalHour(0);
cfg.setTotalDay(0);
cfg.setMaxStreams(0);
}
return cfg;
}
}