forked from I2P_Developers/i2p.i2p
- Convert HTTP and CONNECT proxies to MD5 authentication
- Allow multiple users - Migrate passwords on first save
This commit is contained in:
@ -58,7 +58,7 @@ import net.i2p.util.PortMapper;
|
||||
*/
|
||||
public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements Runnable {
|
||||
|
||||
private static final String AUTH_REALM = "I2P SSL Proxy";
|
||||
public static final String AUTH_REALM = "I2P SSL Proxy";
|
||||
|
||||
private final static byte[] ERR_DESTINATION_UNKNOWN =
|
||||
("HTTP/1.1 503 Service Unavailable\r\n"+
|
||||
@ -277,14 +277,15 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
}
|
||||
|
||||
// Authorization
|
||||
if (!authorize(s, requestId, method, authorization)) {
|
||||
AuthResult result = authorize(s, requestId, method, authorization);
|
||||
if (result != AuthResult.AUTH_GOOD) {
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
if (authorization != null)
|
||||
_log.warn(getPrefix(requestId) + "Auth failed, sending 407 again");
|
||||
else
|
||||
_log.warn(getPrefix(requestId) + "Auth required, sending 407");
|
||||
}
|
||||
out.write(getAuthError(false).getBytes());
|
||||
out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes());
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
*/
|
||||
private final String _proxyNonce;
|
||||
|
||||
private static final String AUTH_REALM = "I2P HTTP Proxy";
|
||||
public static final String AUTH_REALM = "I2P HTTP Proxy";
|
||||
|
||||
/**
|
||||
* These are backups if the xxx.ht error page is missing.
|
||||
@ -846,7 +846,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
}
|
||||
|
||||
// Authorization
|
||||
if(!authorize(s, requestId, method, authorization)) {
|
||||
AuthResult result = authorize(s, requestId, method, authorization);
|
||||
if (result != AuthResult.AUTH_GOOD) {
|
||||
if(_log.shouldLog(Log.WARN)) {
|
||||
if(authorization != null) {
|
||||
_log.warn(getPrefix(requestId) + "Auth failed, sending 407 again");
|
||||
@ -854,7 +855,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
_log.warn(getPrefix(requestId) + "Auth required, sending 407");
|
||||
}
|
||||
}
|
||||
out.write(getAuthError(false).getBytes());
|
||||
out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes());
|
||||
writeFooter(out);
|
||||
s.close();
|
||||
return;
|
||||
|
@ -122,9 +122,16 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
/** passwords for specific outproxies may be added with outproxyUsername.fooproxy.i2p=user and outproxyPassword.fooproxy.i2p=pw */
|
||||
public static final String PROP_OUTPROXY_USER_PREFIX = PROP_OUTPROXY_USER + '.';
|
||||
public static final String PROP_OUTPROXY_PW_PREFIX = PROP_OUTPROXY_PW + '.';
|
||||
/** new style MD5 auth */
|
||||
public static final String PROP_PROXY_DIGEST_PREFIX = "proxy.auth.";
|
||||
public static final String PROP_PROXY_DIGEST_SUFFIX = ".md5";
|
||||
public static final String BASIC_AUTH = "basic";
|
||||
public static final String DIGEST_AUTH = "digest";
|
||||
|
||||
protected abstract String getRealm();
|
||||
|
||||
protected enum AuthResult {AUTH_BAD_REQ, AUTH_BAD, AUTH_STALE, AUTH_GOOD}
|
||||
|
||||
/**
|
||||
* @since 0.9.4
|
||||
*/
|
||||
@ -144,81 +151,77 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
* @param authorization may be null, the full auth line e.g. "Basic lskjlksjf"
|
||||
* @return success
|
||||
*/
|
||||
protected boolean authorize(Socket s, long requestId, String method, String authorization) {
|
||||
protected AuthResult authorize(Socket s, long requestId, String method, String authorization) {
|
||||
String authRequired = getTunnel().getClientOptions().getProperty(PROP_AUTH);
|
||||
if (authRequired == null)
|
||||
return true;
|
||||
return AuthResult.AUTH_GOOD;
|
||||
authRequired = authRequired.toLowerCase(Locale.US);
|
||||
if (authRequired.equals("false"))
|
||||
return true;
|
||||
return AuthResult.AUTH_GOOD;
|
||||
if (s instanceof InternalSocket) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix(requestId) + "Internal access, no auth required");
|
||||
return true;
|
||||
return AuthResult.AUTH_GOOD;
|
||||
}
|
||||
if (authorization == null)
|
||||
return false;
|
||||
return AuthResult.AUTH_BAD;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix(requestId) + "Auth: " + authorization);
|
||||
String authLC = authorization.toLowerCase(Locale.US);
|
||||
if (authRequired.equals("true") || authRequired.equals("basic")) {
|
||||
if (authRequired.equals("true") || authRequired.equals(BASIC_AUTH)) {
|
||||
if (!authLC.startsWith("basic "))
|
||||
return false;
|
||||
return AuthResult.AUTH_BAD;
|
||||
authorization = authorization.substring(6);
|
||||
|
||||
// hmm safeDecode(foo, true) to use standard alphabet is private in Base64
|
||||
byte[] decoded = Base64.decode(authorization.replace("/", "~").replace("+", "="));
|
||||
if (decoded != null) {
|
||||
// We send Accept-Charset: UTF-8 in the 407 so hopefully it comes back that way inside the B64 ?
|
||||
try {
|
||||
String dec = new String(decoded, "UTF-8");
|
||||
String[] parts = dec.split(":");
|
||||
String user = parts[0];
|
||||
String pw = parts[1];
|
||||
// first try pw for that user
|
||||
String configPW = getTunnel().getClientOptions().getProperty(PROP_PW_PREFIX + user);
|
||||
if (configPW == null) {
|
||||
// if not, look at default user and pw
|
||||
String configUser = getTunnel().getClientOptions().getProperty(PROP_USER);
|
||||
if (user.equals(configUser))
|
||||
configPW = getTunnel().getClientOptions().getProperty(PROP_PW);
|
||||
}
|
||||
if (configPW != null) {
|
||||
if (pw.equals(configPW)) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix(requestId) + "Good auth - user: " + user + " pw: " + pw);
|
||||
return true;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Bad auth, pw mismatch - user: " + user + " pw: " + pw + " expected: " + configPW);
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Bad auth, no stored pw for user: " + user + " pw: " + pw);
|
||||
}
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
// no ':' in response
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization, aioobe);
|
||||
// hmm safeDecode(foo, true) to use standard alphabet is private in Base64
|
||||
byte[] decoded = Base64.decode(authorization.replace("/", "~").replace("+", "="));
|
||||
if (decoded != null) {
|
||||
// We send Accept-Charset: UTF-8 in the 407 so hopefully it comes back that way inside the B64 ?
|
||||
try {
|
||||
String dec = new String(decoded, "UTF-8");
|
||||
String[] parts = dec.split(":");
|
||||
String user = parts[0];
|
||||
String pw = parts[1];
|
||||
// first try pw for that user
|
||||
String configPW = getTunnel().getClientOptions().getProperty(PROP_PW_PREFIX + user);
|
||||
if (configPW == null) {
|
||||
// if not, look at default user and pw
|
||||
String configUser = getTunnel().getClientOptions().getProperty(PROP_USER);
|
||||
if (user.equals(configUser))
|
||||
configPW = getTunnel().getClientOptions().getProperty(PROP_PW);
|
||||
}
|
||||
} else {
|
||||
if (configPW != null) {
|
||||
if (pw.equals(configPW)) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix(requestId) + "Good auth - user: " + user + " pw: " + pw);
|
||||
return AuthResult.AUTH_GOOD;
|
||||
}
|
||||
}
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
// no ':' in response
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization);
|
||||
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization, aioobe);
|
||||
return AuthResult.AUTH_BAD_REQ;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (authRequired.equals("digest")) {
|
||||
return AuthResult.AUTH_BAD;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization);
|
||||
return AuthResult.AUTH_BAD_REQ;
|
||||
}
|
||||
} else if (authRequired.equals(DIGEST_AUTH)) {
|
||||
if (!authLC.startsWith("digest "))
|
||||
return false;
|
||||
return AuthResult.AUTH_BAD;
|
||||
authorization = authorization.substring(7);
|
||||
Map<String, String> args = parseArgs(authorization);
|
||||
AuthResult rv = validateDigest(method, args);
|
||||
return rv == AuthResult.AUTH_GOOD;
|
||||
return rv;
|
||||
} else {
|
||||
_log.error("Unknown proxy authorization type configured: " + authRequired);
|
||||
return true;
|
||||
return AuthResult.AUTH_BAD_REQ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,10 +253,10 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
return check;
|
||||
}
|
||||
// get H(A1) == stored password
|
||||
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PW_PREFIX + user);
|
||||
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
|
||||
PROP_PROXY_DIGEST_SUFFIX);
|
||||
if (ha1 == null) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Bad digest auth - no stored pw for user: " + user);
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
return AuthResult.AUTH_BAD;
|
||||
}
|
||||
// get H(A2)
|
||||
@ -263,8 +266,9 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
|
||||
String hkd = PasswordManager.md5Hex(kd);
|
||||
if (!response.equals(hkd)) {
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Bad digest auth - user: " + user);
|
||||
_log.info("Bad digest auth: " + DataHelper.toString(args));
|
||||
return AuthResult.AUTH_BAD;
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
@ -288,8 +292,6 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
return Base64.encode(n);
|
||||
}
|
||||
|
||||
protected enum AuthResult {AUTH_BAD_REQ, AUTH_BAD, AUTH_STALE, AUTH_GOOD}
|
||||
|
||||
/**
|
||||
* Verify the Base 64 of 24 bytes: (now, md5 of (now, proxy nonce))
|
||||
* @since 0.9.4
|
||||
|
@ -221,19 +221,7 @@ public class EditBean extends IndexBean {
|
||||
|
||||
/** all proxy auth @since 0.8.2 */
|
||||
public boolean getProxyAuth(int tunnel) {
|
||||
return getBooleanProperty(tunnel, I2PTunnelHTTPClientBase.PROP_AUTH) &&
|
||||
getProxyUsername(tunnel).length() > 0 &&
|
||||
getProxyPassword(tunnel).length() > 0;
|
||||
}
|
||||
|
||||
public String getProxyUsername(int tunnel) {
|
||||
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_USER, "");
|
||||
}
|
||||
|
||||
public String getProxyPassword(int tunnel) {
|
||||
if (getProxyUsername(tunnel).length() <= 0)
|
||||
return "";
|
||||
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_PW, "");
|
||||
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_AUTH, "false") != "false";
|
||||
}
|
||||
|
||||
public boolean getOutproxyAuth(int tunnel) {
|
||||
@ -354,10 +342,17 @@ public class EditBean extends IndexBean {
|
||||
if (opts == null) return "";
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
int i = 0;
|
||||
boolean isMD5Proxy = "httpclient".equals(tun.getType()) ||
|
||||
"connectclient".equals(tun.getType());
|
||||
for (Iterator iter = opts.keySet().iterator(); iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
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 ((!isMD5Proxy) &&
|
||||
_nonProxyNoShowSet.contains(key))
|
||||
continue;
|
||||
String val = opts.getProperty(key);
|
||||
if (i != 0) buf.append(' ');
|
||||
buf.append(key).append('=').append(val);
|
||||
|
@ -27,6 +27,7 @@ import net.i2p.data.Certificate;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.PrivateKeyFile;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.i2ptunnel.I2PTunnelConnectClient;
|
||||
import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
|
||||
import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase;
|
||||
import net.i2p.i2ptunnel.I2PTunnelIRCClient;
|
||||
@ -36,6 +37,7 @@ import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.PasswordManager;
|
||||
|
||||
/**
|
||||
* Simple accessor for exposing tunnel info, but also an ugly form handler
|
||||
@ -83,6 +85,8 @@ public class IndexBean {
|
||||
private int _hashCashValue;
|
||||
private int _certType;
|
||||
private String _certSigner;
|
||||
private String _newProxyUser;
|
||||
private String _newProxyPW;
|
||||
|
||||
public static final int RUNNING = 1;
|
||||
public static final int STARTING = 2;
|
||||
@ -224,9 +228,9 @@ public class IndexBean {
|
||||
private String start() {
|
||||
if (_tunnel < 0) return "Invalid tunnel";
|
||||
|
||||
List controllers = _group.getControllers();
|
||||
List<TunnelController> controllers = _group.getControllers();
|
||||
if (_tunnel >= controllers.size()) return "Invalid tunnel";
|
||||
TunnelController controller = (TunnelController)controllers.get(_tunnel);
|
||||
TunnelController controller = controllers.get(_tunnel);
|
||||
controller.startTunnelBackground();
|
||||
// give the messages a chance to make it to the window
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
@ -237,9 +241,9 @@ public class IndexBean {
|
||||
private String stop() {
|
||||
if (_tunnel < 0) return "Invalid tunnel";
|
||||
|
||||
List controllers = _group.getControllers();
|
||||
List<TunnelController> controllers = _group.getControllers();
|
||||
if (_tunnel >= controllers.size()) return "Invalid tunnel";
|
||||
TunnelController controller = (TunnelController)controllers.get(_tunnel);
|
||||
TunnelController controller = controllers.get(_tunnel);
|
||||
controller.stopTunnel();
|
||||
// give the messages a chance to make it to the window
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
@ -268,10 +272,10 @@ public class IndexBean {
|
||||
// if the current tunnel is shared, and of supported type
|
||||
if (Boolean.parseBoolean(cur.getSharedClient()) && isClient(cur.getType())) {
|
||||
// all clients use the same I2CP session, and as such, use the same I2CP options
|
||||
List controllers = _group.getControllers();
|
||||
List<TunnelController> controllers = _group.getControllers();
|
||||
|
||||
for (int i = 0; i < controllers.size(); i++) {
|
||||
TunnelController c = (TunnelController)controllers.get(i);
|
||||
TunnelController c = controllers.get(i);
|
||||
|
||||
// Current tunnel modified by user, skip
|
||||
if (c == cur) continue;
|
||||
@ -804,21 +808,22 @@ public class IndexBean {
|
||||
|
||||
/** all proxy auth @since 0.8.2 */
|
||||
public void setProxyAuth(String s) {
|
||||
_booleanOptions.add(I2PTunnelHTTPClientBase.PROP_AUTH);
|
||||
if (s != null)
|
||||
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
|
||||
}
|
||||
|
||||
public void setProxyUsername(String s) {
|
||||
if (s != null)
|
||||
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_USER, s.trim());
|
||||
_newProxyUser = s.trim();
|
||||
}
|
||||
|
||||
public void setProxyPassword(String s) {
|
||||
if (s != null)
|
||||
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_PW, s.trim());
|
||||
_newProxyPW = s.trim();
|
||||
}
|
||||
|
||||
public void setOutproxyAuth(String s) {
|
||||
_booleanOptions.add(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH);
|
||||
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
|
||||
}
|
||||
|
||||
public void setOutproxyUsername(String s) {
|
||||
@ -1040,6 +1045,45 @@ public class IndexBean {
|
||||
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);
|
||||
@ -1084,15 +1128,16 @@ public class IndexBean {
|
||||
"i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen"
|
||||
};
|
||||
private static final String _booleanProxyOpts[] = {
|
||||
I2PTunnelHTTPClientBase.PROP_AUTH, I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH
|
||||
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",
|
||||
"proxyUsername", "proxyPassword", "outproxyUsername", "outproxyPassword",
|
||||
I2PTunnelHTTPClient.PROP_JUMP_SERVERS
|
||||
"outproxyUsername", "outproxyPassword",
|
||||
I2PTunnelHTTPClient.PROP_JUMP_SERVERS,
|
||||
I2PTunnelHTTPClientBase.PROP_AUTH
|
||||
};
|
||||
private static final String _otherServerOpts[] = {
|
||||
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList",
|
||||
@ -1101,7 +1146,17 @@ public class IndexBean {
|
||||
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 _noShowSet = new HashSet(64);
|
||||
protected static final Set _nonProxyNoShowSet = new HashSet(4);
|
||||
static {
|
||||
_noShowSet.addAll(Arrays.asList(_noShowOpts));
|
||||
_noShowSet.addAll(Arrays.asList(_booleanClientOpts));
|
||||
@ -1109,6 +1164,7 @@ public class IndexBean {
|
||||
_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) {
|
||||
@ -1139,6 +1195,12 @@ public class IndexBean {
|
||||
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);
|
||||
}
|
||||
@ -1190,9 +1252,9 @@ public class IndexBean {
|
||||
protected TunnelController getController(int tunnel) {
|
||||
if (tunnel < 0) return null;
|
||||
if (_group == null) return null;
|
||||
List controllers = _group.getControllers();
|
||||
List<TunnelController> controllers = _group.getControllers();
|
||||
if (controllers.size() > tunnel)
|
||||
return (TunnelController)controllers.get(tunnel);
|
||||
return controllers.get(tunnel);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user