package net.i2p.i2ptunnel.ui;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.crypto.SigType;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile;
import net.i2p.i2ptunnel.I2PTunnelClientBase;
import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase;
import net.i2p.i2ptunnel.I2PTunnelHTTPServer;
import net.i2p.i2ptunnel.I2PTunnelIRCClient;
import net.i2p.i2ptunnel.I2PTunnelServer;
import net.i2p.i2ptunnel.SSLClientUtil;
import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.i2ptunnel.web.Messages;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
/**
* General helper functions used by all UIs.
*
* @since 0.9.19
*/
public class GeneralHelper {
public static final int RUNNING = 1;
public static final int STARTING = 2;
public static final int NOT_RUNNING = 3;
public static final int STANDBY = 4;
protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
private static final String OPT = TunnelController.PFX_OPTION;
private final I2PAppContext _context;
protected final TunnelControllerGroup _group;
public GeneralHelper(TunnelControllerGroup tcg) {
this(I2PAppContext.getGlobalContext(), tcg);
}
public GeneralHelper(I2PAppContext context, TunnelControllerGroup tcg) {
_context = context;
_group = tcg;
}
public TunnelController getController(int tunnel) {
return getController(_group, tunnel);
}
public static TunnelController getController(TunnelControllerGroup tcg, int tunnel) {
if (tunnel < 0) return null;
if (tcg == null) return null;
List<TunnelController> controllers = tcg.getControllers();
if (controllers.size() > tunnel)
return controllers.get(tunnel);
else
return null;
}
public List<String> saveTunnel(int tunnel, TunnelConfig config) {
return saveTunnel(_context, _group, tunnel, config);
}
public static List<String> saveTunnel(
I2PAppContext context, TunnelControllerGroup tcg, int tunnel, TunnelConfig config) {
List<String> msgs = updateTunnelConfig(tcg, tunnel, config);
msgs.addAll(saveConfig(context, tcg));
return msgs;
}
protected static List<String> updateTunnelConfig(TunnelControllerGroup tcg, int tunnel, TunnelConfig config) {
// Get current tunnel controller
TunnelController cur = getController(tcg, tunnel);
Properties props = config.getConfig();
List<String> msgs = new ArrayList<String>();
String type = props.getProperty(TunnelController.PROP_TYPE);
if (TunnelController.TYPE_STD_CLIENT.equals(type) || TunnelController.TYPE_IRC_CLIENT.equals(type)) {
//
// If we switch to SSL, create the keystore here, so we can store the new properties.
// Down in I2PTunnelClientBase it's very hard to save the config.
//
if (Boolean.parseBoolean(props.getProperty(OPT + I2PTunnelClientBase.PROP_USE_SSL))) {
try {
boolean created = SSLClientUtil.verifyKeyStore(props, OPT);
if (created) {
// config now contains new keystore props
msgs.add("Created new self-signed certificate for tunnel " + getTunnelName(tcg, tunnel));
}
} catch (IOException ioe) {
msgs.add("Failed to create new self-signed certificate for tunnel " +
getTunnelName(tcg, tunnel) + ", check logs: " + ioe);
}
}
}
if (cur == null) {
// creating new
cur = new TunnelController(props, "", true);
tcg.addController(cur);
if (cur.getStartOnLoad())
cur.startTunnelBackground();
} else {
cur.setConfig(props, "");
}
// Only modify other shared tunnels
// if the current tunnel is shared, and of supported type
if (Boolean.parseBoolean(cur.getSharedClient()) && TunnelController.isClient(cur.getType())) {
// all clients use the same I2CP session, and as such, use the same I2CP options
List<TunnelController> controllers = tcg.getControllers();
for (int i = 0; i < controllers.size(); i++) {
TunnelController c = controllers.get(i);
// Current tunnel modified by user, skip
if (c == cur) continue;
// Only modify this non-current tunnel
// if it belongs to a shared destination, and is of supported type
if (Boolean.parseBoolean(c.getSharedClient()) && TunnelController.isClient(c.getType())) {
Properties cOpt = c.getConfig("");
config.updateTunnelQuantities(cOpt);
cOpt.setProperty("option.inbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
cOpt.setProperty("option.outbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
c.setConfig(cOpt, "");
}
}
}
return msgs;
}
protected static List<String> saveConfig(I2PAppContext context, TunnelControllerGroup tcg) {
List<String> rv = tcg.clearAllMessages();
try {
tcg.saveConfig();
rv.add(0, _t("Configuration changes saved", context));
} catch (IOException ioe) {
Log log = context.logManager().getLog(GeneralHelper.class);
log.error("Failed to save config file", ioe);
rv.add(0, _t("Failed to save configuration", context) + ": " + ioe.toString());
}
return rv;
}
public List<String> deleteTunnel(int tunnel, String privKeyFile) {
return deleteTunnel(_context, _group, tunnel, privKeyFile);
}
/**
* Stop the tunnel, delete from config,
* rename the private key file if in the default directory
*
* @param privKeyFile The priv key file name from the tunnel edit form. Can
* be null if not known.
*/
public static List<String> deleteTunnel(
I2PAppContext context, TunnelControllerGroup tcg, int tunnel, String privKeyFile) {
List<String> msgs;
TunnelController cur = getController(tcg, tunnel);
if (cur == null) {
msgs = new ArrayList<String>();
msgs.add("Invalid tunnel number");
return msgs;
}
msgs = tcg.removeController(cur);
msgs.addAll(saveConfig(context, tcg));
// Rename private key file if it was a default name in
// the default directory, so it doesn't get reused when a new
// tunnel is created.
// Use configured file name if available, not the one from the form.
String pk = cur.getPrivKeyFile();
if (pk == null)
pk = privKeyFile;
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") &&
((!TunnelController.isClient(cur.getType())) || cur.getPersistentClientKey())) {
File pkf = new File(context.getConfigDir(), pk);
if (pkf.exists()) {
String name = cur.getName();
if (name == null) {
name = cur.getDescription();
if (name == null) {
name = cur.getType();
if (name == null)
name = Long.toString(context.clock().now());
}
}
name = name.replace(' ', '_').replace(':', '_').replace("..", "_").replace('/', '_').replace('\\', '_');
name = "i2ptunnel-deleted-" + name + '-' + context.clock().now() + "-privkeys.dat";
File backupDir = new SecureFile(context.getConfigDir(), TunnelController.KEY_BACKUP_DIR);
File to;
if (backupDir.isDirectory() || backupDir.mkdir())
to = new File(backupDir, name);
else
to = new File(context.getConfigDir(), name);
boolean success = FileUtil.rename(pkf, to);
if (success)
msgs.add("Private key file " + pkf.getAbsolutePath() +
" renamed to " + to.getAbsolutePath());
}
}
return msgs;
}
//
// Accessors
//
public String getTunnelType(int tunnel) {
TunnelController tun = getController(tunnel);
return (tun != null && tun.getType() != null) ? tun.getType() : "";
}
public String getTunnelName(int tunnel) {
return getTunnelName(_group, tunnel);
}
public static String getTunnelName(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
return tun != null ? tun.getName() : null;
}
public String getTunnelDescription(int tunnel) {
TunnelController tun = getController(tunnel);
return (tun != null && tun.getDescription() != null) ? tun.getDescription() : "";
}
public String getTargetHost(int tunnel) {
TunnelController tun = getController(tunnel);
return (tun != null && tun.getTargetHost() != null) ? tun.getTargetHost() : "127.0.0.1";
}
/**
* @param tunnel
* @return -1 if unset or invalid
*/
public int getTargetPort(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null && tun.getTargetPort() != null) {
try {
return Integer.parseInt(tun.getTargetPort());
} catch (NumberFormatException e) {
return -1;
}
} else
return -1;
}
public String getSpoofedHost(int tunnel) {
TunnelController tun = getController(tunnel);
return (tun != null && tun.getSpoofedHost() != null) ? tun.getSpoofedHost() : "";
}
/**
* @return path, non-null, non-empty
*/
public String getPrivateKeyFile(int tunnel) {
return getPrivateKeyFile(_group, tunnel);
}
/**
* @return path, non-null, non-empty
*/
public String getPrivateKeyFile(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
if (tun != null) {
String rv = tun.getPrivKeyFile();
if (rv != null)
return rv;
}
if (tunnel < 0)
tunnel = tcg == null ? 999 : tcg.getControllers().size();
String rv = "i2ptunnel" + tunnel + "-privKeys.dat";
// Don't default to a file that already exists,
// which could happen after other tunnels are deleted.
int i = 0;
while ((new File(_context.getConfigDir(), rv)).exists()) {
rv = "i2ptunnel" + tunnel + '.' + (++i) + "-privKeys.dat";
}
return rv;
}
/**
* @return path or ""
* @since 0.9.30
*/
public String getAltPrivateKeyFile(int tunnel) {
return getAltPrivateKeyFile(_group, tunnel);
}
/**
* @return path or ""
* @since 0.9.30
*/
public String getAltPrivateKeyFile(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
if (tun != null) {
File f = tun.getAlternatePrivateKeyFile();
if (f != null)
return f.getAbsolutePath();
}
return "";
}
public String getClientInterface(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null) {
if ("streamrclient".equals(tun.getType()))
return tun.getTargetHost();
else
return tun.getListenOnInterface();
} else
return "127.0.0.1";
}
public int getClientPort(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null && tun.getListenPort() != null) {
try {
return Integer.parseInt(tun.getListenPort());
} catch (NumberFormatException e) {
return -1;
}
} else
return -1;
}
public int getTunnelStatus(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun == null) return NOT_RUNNING;
if (tun.getIsRunning()) {
if (tun.isClient() && tun.getIsStandby())
return STANDBY;
else
return RUNNING;
} else if (tun.getIsStarting()) return STARTING;
else return NOT_RUNNING;
}
public String getClientDestination(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun == null) return "";
String rv;
if (TunnelController.TYPE_STD_CLIENT.equals(tun.getType()) ||
TunnelController.TYPE_IRC_CLIENT.equals(tun.getType()) ||
TunnelController.TYPE_STREAMR_CLIENT.equals(tun.getType()))
rv = tun.getTargetDestination();
else
rv = tun.getProxyList();
return rv != null ? rv : "";
}
/**
* Works even if tunnel is not running.
* @return Destination or null
*/
public Destination getDestination(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null) {
Destination rv = tun.getDestination();
if (rv != null)
return rv;
// if not running, do this the hard way
File keyFile = tun.getPrivateKeyFile();
if (keyFile != null) {
PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
try {
rv = pkf.getDestination();
if (rv != null)
return rv;
} catch (I2PException e) {
} catch (IOException e) {}
}
}
return null;
}
/**
* Works even if tunnel is not running.
* @return Destination or null
* @since 0.9.30
*/
public Destination getAltDestination(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null) {
// do this the hard way
File keyFile = tun.getAlternatePrivateKeyFile();
if (keyFile != null) {
PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
try {
Destination rv = pkf.getDestination();
if (rv != null)
return rv;
} catch (I2PException e) {
} catch (IOException e) {}
}
}
return null;
}
public boolean shouldStartAutomatically(int tunnel) {
TunnelController tun = getController(tunnel);
return tun != null ? tun.getStartOnLoad() : false;
}
public boolean isSharedClient(int tunnel) {
TunnelController tun = getController(tunnel);
return tun != null ? Boolean.parseBoolean(tun.getSharedClient()) : false;
}
public boolean shouldDelayConnect(int tunnel) {
return getProperty(tunnel, "i2p.streaming.connectDelay", 0) > 0;
}
public boolean isInteractive(int tunnel) {
return getProperty(tunnel, "i2p.streaming.maxWindowSize", 128) == 16;
}
public int getTunnelDepth(int tunnel, int defaultLength) {
return getProperty(tunnel, "inbound.length", defaultLength);
}
public int getTunnelQuantity(int tunnel, int defaultQuantity) {
return getProperty(tunnel, "inbound.quantity", defaultQuantity);
}
public int getTunnelBackupQuantity(int tunnel, int defaultBackupQuantity) {
return getProperty(tunnel, "inbound.backupQuantity", defaultBackupQuantity);
}
public int getTunnelVariance(int tunnel, int defaultVariance) {
return getProperty(tunnel, "inbound.lengthVariance", defaultVariance);
}
public boolean getReduceOnIdle(int tunnel, boolean def) {
return getBooleanProperty(tunnel, "i2cp.reduceOnIdle", def);
}
public int getReduceCount(int tunnel, int def) {
return getProperty(tunnel, "i2cp.reduceQuantity", def);
}
/**
* @param tunnel
* @param def in minutes
* @return time in minutes
*/
public int getReduceTime(int tunnel, int def) {
return getProperty(tunnel, "i2cp.reduceIdleTime", def*60*1000) / (60*1000);
}
public int getCert(int tunnel) {
return 0;
}
public int getEffort(int tunnel) {
return 23;
}
public String getSigner(int tunnel) {
return "";
}
public boolean getEncrypt(int tunnel) {
return getBooleanProperty(tunnel, "i2cp.encryptLeaseSet");
}
/**
* @param newTunnelType used if tunnel < 0
*/
public int getSigType(int tunnel, String newTunnelType) {
SigType type;
String ttype;
boolean isShared;
if (tunnel >= 0) {
Destination d = getDestination(tunnel);
if (d != null) {
type = d.getSigType();
if (type != null)
return type.getCode();
}
String stype = getProperty(tunnel, I2PClient.PROP_SIGTYPE, null);
type = stype != null ? SigType.parseSigType(stype) : null;
ttype = getTunnelType(tunnel);
isShared = isSharedClient(tunnel);
} else {
type = null;
ttype = newTunnelType;
isShared = false;
}
if (type == null) {
// same default logic as in TunnelController.setConfig()
if (!TunnelController.isClient(ttype) ||
TunnelController.TYPE_IRC_CLIENT.equals(ttype) ||
TunnelController.TYPE_SOCKS_IRC.equals(ttype) ||
TunnelController.TYPE_SOCKS.equals(ttype) ||
TunnelController.TYPE_STREAMR_CLIENT.equals(ttype) ||
TunnelController.TYPE_STD_CLIENT.equals(ttype) ||
(TunnelController.TYPE_HTTP_CLIENT.equals(ttype) && isShared))
type = TunnelController.PREFERRED_SIGTYPE;
else
type = SigType.DSA_SHA1;
}
return type.getCode();
}
/**
* Random keys
*/
public String getInboundRandomKey(int tunnel) {
return getProperty(tunnel, "inbound.randomKey", "");
}
public String getOutboundRandomKey(int tunnel) {
return getProperty(tunnel, "outbound.randomKey", "");
}
public String getLeaseSetSigningPrivateKey(int tunnel) {
return getProperty(tunnel, "i2cp.leaseSetSigningPrivateKey", "");
}
public String getLeaseSetPrivateKey(int tunnel) {
return getProperty(tunnel, "i2cp.leaseSetPrivateKey", "");
}
public boolean getDCC(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC);
}
public boolean isSSLEnabled(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelServer.PROP_USE_SSL);
}
public String getEncryptKey(int tunnel) {
return getProperty(tunnel, "i2cp.leaseSetKey", "");
}
public int getAccessMode(int tunnel) {
if (getBooleanProperty(tunnel, PROP_ENABLE_ACCESS_LIST))
return 1;
if (getBooleanProperty(tunnel, PROP_ENABLE_BLACKLIST))
return 2;
return 0;
}
public String getAccessList(int tunnel) {
return getProperty(tunnel, "i2cp.accessList", "").replace(",", "\n");
}
public String getJumpList(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPClient.PROP_JUMP_SERVERS,
I2PTunnelHTTPClient.DEFAULT_JUMP_SERVERS).replace(",", "\n");
}
public boolean getCloseOnIdle(int tunnel, boolean def) {
return getBooleanProperty(tunnel, "i2cp.closeOnIdle", def);
}
public int getCloseTime(int tunnel, int def) {
return getProperty(tunnel, "i2cp.closeIdleTime", def*60*1000) / (60*1000);
}
public boolean getNewDest(int tunnel) {
return getBooleanProperty(tunnel, "i2cp.newDestOnResume") &&
getBooleanProperty(tunnel, "i2cp.closeOnIdle") &&
!getBooleanProperty(tunnel, "persistentClientKey");
}
public boolean getPersistentClientKey(int tunnel) {
return getBooleanProperty(tunnel, "persistentClientKey");
}
public boolean getDelayOpen(int tunnel) {
return getBooleanProperty(tunnel, "i2cp.delayOpen");
}
public boolean getAllowUserAgent(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_USER_AGENT);
}
public boolean getAllowReferer(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_REFERER);
}
public boolean getAllowAccept(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_ACCEPT);
}
public boolean getAllowInternalSSL(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClient.PROP_INTERNAL_SSL);
}
public boolean getMultihome(int tunnel) {
return getBooleanProperty(tunnel, "shouldBundleReplyInfo");
}
public String getProxyAuth(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_AUTH, "false");
}
public boolean getOutproxyAuth(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH);
}
public String getOutproxyUsername(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_OUTPROXY_USER, "");
}
public String getOutproxyPassword(int tunnel) {
if (getOutproxyUsername(tunnel).length() <= 0)
return "";
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_OUTPROXY_PW, "");
}
public String getSslProxies(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES, "");
}
/**
* Default true
*/
public boolean getUseOutproxyPlugin(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClientBase.PROP_USE_OUTPROXY_PLUGIN, true);
}
/** all of these are @since 0.8.3 */
public int getLimitMinute(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_CONNS_MIN, 0);
}
public int getLimitHour(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_CONNS_HOUR, 0);
}
public int getLimitDay(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_CONNS_DAY, 0);
}
public int getTotalMinute(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_TOTAL_CONNS_MIN, 0);
}
public int getTotalHour(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_TOTAL_CONNS_HOUR, 0);
}
public int getTotalDay(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_TOTAL_CONNS_DAY, 0);
}
public int getMaxStreams(int tunnel) {
return getProperty(tunnel, TunnelConfig.PROP_MAX_STREAMS, 0);
}
/**
* POST limits
* @since 0.9.9
*/
public int getPostMax(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_POST_MAX, 0);
}
public int getPostTotalMax(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_POST_TOTAL_MAX, 0);
}
public int getPostCheckTime(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_POST_WINDOW, I2PTunnelHTTPServer.DEFAULT_POST_WINDOW) / 60;
}
public int getPostBanTime(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_POST_BAN_TIME, I2PTunnelHTTPServer.DEFAULT_POST_BAN_TIME) / 60;
}
public int getPostTotalBanTime(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_POST_TOTAL_BAN_TIME, I2PTunnelHTTPServer.DEFAULT_POST_TOTAL_BAN_TIME) / 60;
}
public boolean getRejectInproxy(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPServer.OPT_REJECT_INPROXY);
}
/** @since 0.9.25 */
public boolean getRejectReferer(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPServer.OPT_REJECT_REFERER);
}
/** @since 0.9.25 */
public boolean getRejectUserAgents(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPServer.OPT_REJECT_USER_AGENTS);
}
/** @since 0.9.25 */
public String getUserAgents(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPServer.OPT_USER_AGENTS, "");
}
public boolean getUniqueLocal(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelServer.PROP_UNIQUE_LOCAL);
}
public String getCustomOptionsString(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
if (opts == null) return "";
boolean isMD5Proxy = TunnelController.TYPE_HTTP_CLIENT.equals(tun.getType()) ||
TunnelController.TYPE_CONNECT.equals(tun.getType());
Map<String, String> sorted = new TreeMap<String, String>();
for (Map.Entry<Object, Object> e : opts.entrySet()) {
String key = (String)e.getKey();
if (TunnelConfig._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 ((!isMD5Proxy) &&
TunnelConfig._nonProxyNoShowSet.contains(key))
continue;
sorted.put(key, (String)e.getValue());
}
if (sorted.isEmpty())
return "";
StringBuilder buf = new StringBuilder(64);
boolean space = false;
for (Map.Entry<String, String> e : sorted.entrySet()) {
if (space)
buf.append(' ');
else
space = true;
buf.append(e.getKey()).append('=').append(e.getValue());
}
return DataHelper.escapeHTML(buf.toString());
} else {
return "";
}
}
//
// Internal helpers
//
private int getProperty(int tunnel, String prop, int def) {
TunnelController tun = getController(tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
if (opts != null) {
String s = opts.getProperty(prop);
if (s == null) return def;
try {
return Integer.parseInt(s);
} catch (NumberFormatException nfe) {}
}
}
return def;
}
private String getProperty(int tunnel, String prop, String def) {
TunnelController tun = getController(tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
if (opts != null) {
String rv = opts.getProperty(prop);
if (rv != null)
return DataHelper.escapeHTML(rv);
}
}
return def;
}
/** default is false */
private boolean getBooleanProperty(int tunnel, String prop) {
return getBooleanProperty(tunnel, prop, false);
}
private boolean getBooleanProperty(int tunnel, String prop, boolean def) {
TunnelController tun = getController(tunnel);
if (tun != null) {
Properties opts = tun.getClientOptionProps();
if (opts != null)
return Boolean.parseBoolean(opts.getProperty(prop));
}
return def;
}
protected static String _t(String key, I2PAppContext context) {
return Messages._t(key, context);
}
}