提交 4ecd6748 编写于 作者: M michaelm

6569621: Problem with java/classes_net

Reviewed-by: chegar
上级 d3f3c958
...@@ -1013,6 +1013,12 @@ class InetAddress implements java.io.Serializable { ...@@ -1013,6 +1013,12 @@ class InetAddress implements java.io.Serializable {
return InetAddress.getAllByName(host)[0]; return InetAddress.getAllByName(host)[0];
} }
// called from deployment cache manager
public static InetAddress getByName(String host, InetAddress reqAddr)
throws UnknownHostException {
return InetAddress.getAllByName(host, reqAddr)[0];
}
/** /**
* Given the name of a host, returns an array of its IP addresses, * Given the name of a host, returns an array of its IP addresses,
* based on the configured name service on the system. * based on the configured name service on the system.
...@@ -1054,6 +1060,11 @@ class InetAddress implements java.io.Serializable { ...@@ -1054,6 +1060,11 @@ class InetAddress implements java.io.Serializable {
*/ */
public static InetAddress[] getAllByName(String host) public static InetAddress[] getAllByName(String host)
throws UnknownHostException { throws UnknownHostException {
return getAllByName(host, null);
}
private static InetAddress[] getAllByName(String host, InetAddress reqAddr)
throws UnknownHostException {
if (host == null || host.length() == 0) { if (host == null || host.length() == 0) {
InetAddress[] ret = new InetAddress[1]; InetAddress[] ret = new InetAddress[1];
...@@ -1113,7 +1124,7 @@ class InetAddress implements java.io.Serializable { ...@@ -1113,7 +1124,7 @@ class InetAddress implements java.io.Serializable {
// We were expecting an IPv6 Litteral, but got something else // We were expecting an IPv6 Litteral, but got something else
throw new UnknownHostException("["+host+"]"); throw new UnknownHostException("["+host+"]");
} }
return getAllByName0(host); return getAllByName0(host, reqAddr, true);
} }
/** /**
...@@ -1174,6 +1185,12 @@ class InetAddress implements java.io.Serializable { ...@@ -1174,6 +1185,12 @@ class InetAddress implements java.io.Serializable {
*/ */
static InetAddress[] getAllByName0 (String host, boolean check) static InetAddress[] getAllByName0 (String host, boolean check)
throws UnknownHostException { throws UnknownHostException {
return getAllByName0 (host, null, check);
}
private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
throws UnknownHostException {
/* If it gets here it is presumed to be a hostname */ /* If it gets here it is presumed to be a hostname */
/* Cache.get can return: null, unknownAddress, or InetAddress[] */ /* Cache.get can return: null, unknownAddress, or InetAddress[] */
...@@ -1191,7 +1208,7 @@ class InetAddress implements java.io.Serializable { ...@@ -1191,7 +1208,7 @@ class InetAddress implements java.io.Serializable {
/* If no entry in cache, then do the host lookup */ /* If no entry in cache, then do the host lookup */
if (addresses == null) { if (addresses == null) {
addresses = getAddressesFromNameService(host); addresses = getAddressesFromNameService(host, reqAddr);
} }
if (addresses == unknown_array) if (addresses == unknown_array)
...@@ -1200,7 +1217,7 @@ class InetAddress implements java.io.Serializable { ...@@ -1200,7 +1217,7 @@ class InetAddress implements java.io.Serializable {
return addresses.clone(); return addresses.clone();
} }
private static InetAddress[] getAddressesFromNameService(String host) private static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
throws UnknownHostException throws UnknownHostException
{ {
InetAddress[] addresses = null; InetAddress[] addresses = null;
...@@ -1256,10 +1273,32 @@ class InetAddress implements java.io.Serializable { ...@@ -1256,10 +1273,32 @@ class InetAddress implements java.io.Serializable {
} }
} }
// Cache the addresses. // More to do?
if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
// Find it?
int i = 1;
for (; i < addresses.length; i++) {
if (addresses[i].equals(reqAddr)) {
break;
}
}
// Rotate
if (i < addresses.length) {
InetAddress tmp, tmp2 = reqAddr;
for (int j = 0; j < i; j++) {
tmp = addresses[j];
addresses[j] = tmp2;
tmp2 = tmp;
}
addresses[i] = tmp2;
}
}
// Cache the address.
cacheAddresses(host, addresses, success); cacheAddresses(host, addresses, success);
if (!success && ex != null) if (!success && ex != null)
throw ex; throw ex;
} finally { } finally {
// Delete host from the lookupTable and notify // Delete host from the lookupTable and notify
// all threads waiting on the lookupTable monitor. // all threads waiting on the lookupTable monitor.
...@@ -1393,7 +1432,7 @@ class InetAddress implements java.io.Serializable { ...@@ -1393,7 +1432,7 @@ class InetAddress implements java.io.Serializable {
InetAddress[] localAddrs; InetAddress[] localAddrs;
try { try {
localAddrs = localAddrs =
InetAddress.getAddressesFromNameService(local); InetAddress.getAddressesFromNameService(local, null);
} catch (UnknownHostException uhe) { } catch (UnknownHostException uhe) {
// Rethrow with a more informative error message. // Rethrow with a more informative error message.
UnknownHostException uhe2 = UnknownHostException uhe2 =
......
...@@ -127,11 +127,12 @@ class Socket implements java.io.Closeable { ...@@ -127,11 +127,12 @@ class Socket implements java.io.Closeable {
} }
if (security != null) { if (security != null) {
if (epoint.isUnresolved()) if (epoint.isUnresolved())
security.checkConnect(epoint.getHostName(), epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort());
epoint.getPort()); if (epoint.isUnresolved())
security.checkConnect(epoint.getHostName(), epoint.getPort());
else else
security.checkConnect(epoint.getAddress().getHostAddress(), security.checkConnect(epoint.getAddress().getHostAddress(),
epoint.getPort()); epoint.getPort());
} }
impl = new SocksSocketImpl(p); impl = new SocksSocketImpl(p);
impl.setSocket(this); impl.setSocket(this);
......
...@@ -41,6 +41,7 @@ import java.io.ObjectInputStream; ...@@ -41,6 +41,7 @@ import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import sun.net.util.IPAddressUtil; import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.security.util.Debug;
/** /**
...@@ -211,13 +212,32 @@ implements java.io.Serializable ...@@ -211,13 +212,32 @@ implements java.io.Serializable
// port range on host // port range on host
private transient int[] portrange; private transient int[] portrange;
// true if the trustProxy system property is set private transient boolean defaultDeny = false;
private static boolean trustProxy;
// true if this SocketPermission represents a hostname
// that failed our reverse mapping heuristic test
private transient boolean untrusted;
private transient boolean trusted;
// true if the sun.net.trustNameService system property is set
private static boolean trustNameService;
private static Debug debug = null;
private static boolean debugInit = false;
static { static {
Boolean tmp = java.security.AccessController.doPrivileged( Boolean tmp = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("trustProxy")); new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
trustProxy = tmp.booleanValue(); trustNameService = tmp.booleanValue();
}
private static synchronized Debug getDebug()
{
if (!debugInit) {
debug = Debug.getInstance("access");
debugInit = true;
}
return debug;
} }
/** /**
...@@ -263,6 +283,10 @@ implements java.io.Serializable ...@@ -263,6 +283,10 @@ implements java.io.Serializable
init(getName(), mask); init(getName(), mask);
} }
private void setDeny() {
defaultDeny = true;
}
private static String getHost(String host) private static String getHost(String host)
{ {
if (host.equals("")) { if (host.equals("")) {
...@@ -560,6 +584,38 @@ implements java.io.Serializable ...@@ -560,6 +584,38 @@ implements java.io.Serializable
return mask; return mask;
} }
private boolean isUntrusted()
throws UnknownHostException
{
if (trusted) return false;
if (invalid || untrusted) return true;
try {
if (!trustNameService && (defaultDeny ||
sun.net.www.URLConnection.isProxiedHost(hostname))) {
if (this.cname == null) {
this.getCanonName();
}
if (!match(cname, hostname) &&
(defaultDeny || !cname.equals(addresses[0].getHostAddress()))) {
// Last chance
if (!authorized(hostname, addresses[0].getAddress())) {
untrusted = true;
Debug debug = getDebug();
if (debug != null && Debug.isOn("failure")) {
debug.println("socket access restriction: proxied host " + "(" + addresses[0] + ")" + " does not match " + cname + " from reverse lookup");
}
return true;
}
}
trusted = true;
}
} catch (UnknownHostException uhe) {
invalid = true;
throw uhe;
}
return false;
}
/** /**
* attempt to get the fully qualified domain name * attempt to get the fully qualified domain name
* *
...@@ -567,7 +623,7 @@ implements java.io.Serializable ...@@ -567,7 +623,7 @@ implements java.io.Serializable
void getCanonName() void getCanonName()
throws UnknownHostException throws UnknownHostException
{ {
if (cname != null || invalid) return; if (cname != null || invalid || untrusted) return;
// attempt to get the canonical name // attempt to get the canonical name
...@@ -593,6 +649,141 @@ implements java.io.Serializable ...@@ -593,6 +649,141 @@ implements java.io.Serializable
} }
} }
private String cdomain, hdomain;
private boolean match(String cname, String hname) {
String a = cname.toLowerCase();
String b = hname.toLowerCase();
if (a.startsWith(b) &&
((a.length() == b.length()) || (a.charAt(b.length()) == '.')))
return true;
if (cdomain == null) {
cdomain = guessRegisteredDomain(a);
}
if (hdomain == null) {
hdomain = guessRegisteredDomain(b);
}
return cdomain.length() != 0 && hdomain.length() != 0
&& cdomain.equals(hdomain);
}
/* Apart from special cases, this checks for 2 letter TLD
* (usually ccTLD) and then for a specific set of common labels
* indicating likely 2nd level public suffixes. If both conditions
* true then return right most three labels. Otherwise, return
* 2 rightmost labels.
*
* www.sun.com. -> sun.com
* www.sun.co.uk -> sun.co.uk
* www.sun.com.au -> sun.com.au
*/
private String guessRegisteredDomain(String cname) {
int dot;
dot = cname.lastIndexOf('.');
if (dot == -1)
return cname;
if (dot == 0)
return "";
if (dot == cname.length() - 1) {
cname = cname.substring(0, cname.length() -1);
dot = cname.lastIndexOf('.');
}
if (dot < 1)
return "";
int second = cname.lastIndexOf('.', dot - 1);
if (second == -1)
return cname;
if (((cname.length() - dot) <= 3) && ((dot - second) <= 4) && second > 0) {
if (dot - second == 4) {
String s = cname.substring(second + 1, dot);
if (!(s.equals("com") || s.equals("org") || s.equals("edu"))) {
return cname.substring(second + 1);
}
}
int third = cname.lastIndexOf('.', second - 1);
if (third == -1)
return cname.substring(second + 1);
else
return cname.substring(third + 1);
}
return cname.substring(second + 1);
}
private boolean authorized(String cname, byte[] addr) {
if (addr.length == 4)
return authorizedIPv4(cname, addr);
else if (addr.length == 16)
return authorizedIPv6(cname, addr);
else
return false;
}
private boolean authorizedIPv4(String cname, byte[] addr) {
String authHost = "";
InetAddress auth;
try {
authHost = "auth." +
(addr[3] & 0xff) + "." + (addr[2] & 0xff) + "." +
(addr[1] & 0xff) + "." + (addr[0] & 0xff) +
".in-addr.arpa";
// Following check seems unnecessary
// auth = InetAddress.getAllByName0(authHost, false)[0];
authHost = hostname + '.' + authHost;
auth = InetAddress.getAllByName0(authHost, false)[0];
if (auth.equals(InetAddress.getByAddress(addr))) {
return true;
}
Debug debug = getDebug();
if (debug != null && Debug.isOn("failure")) {
debug.println("socket access restriction: IP address of " + auth + " != " + InetAddress.getByAddress(addr));
}
} catch (UnknownHostException uhe) {
Debug debug = getDebug();
if (debug != null && Debug.isOn("failure")) {
debug.println("socket access restriction: forward lookup failed for " + authHost);
}
}
return false;
}
private boolean authorizedIPv6(String cname, byte[] addr) {
String authHost = "";
InetAddress auth;
try {
StringBuffer sb = new StringBuffer(39);
for (int i = 15; i >= 0; i--) {
sb.append(Integer.toHexString(((addr[i]) & 0x0f)));
sb.append('.');
sb.append(Integer.toHexString(((addr[i] >> 4) & 0x0f)));
sb.append('.');
}
authHost = "auth." + sb.toString() + "IP6.ARPA";
//auth = InetAddress.getAllByName0(authHost, false)[0];
authHost = hostname + '.' + authHost;
auth = InetAddress.getAllByName0(authHost, false)[0];
if (auth.equals(InetAddress.getByAddress(addr)))
return true;
Debug debug = getDebug();
if (debug != null && Debug.isOn("failure")) {
debug.println("socket access restriction: IP address of " + auth + " != " + InetAddress.getByAddress(addr));
}
} catch (UnknownHostException uhe) {
Debug debug = getDebug();
if (debug != null && Debug.isOn("failure")) {
debug.println("socket access restriction: forward lookup failed for " + authHost);
}
}
return false;
}
/** /**
* get IP addresses. Sets invalid to true if we can't get them. * get IP addresses. Sets invalid to true if we can't get them.
* *
...@@ -720,12 +911,7 @@ implements java.io.Serializable ...@@ -720,12 +911,7 @@ implements java.io.Serializable
// return if either one of these NetPerm objects are invalid... // return if either one of these NetPerm objects are invalid...
if (this.invalid || that.invalid) { if (this.invalid || that.invalid) {
return (trustProxy ? inProxyWeTrust(that) : false); return compareHostnames(that);
}
if (this.getName().equalsIgnoreCase(that.getName())) {
return true;
} }
try { try {
...@@ -778,28 +964,29 @@ implements java.io.Serializable ...@@ -778,28 +964,29 @@ implements java.io.Serializable
that.getIP(); that.getIP();
} }
for (j = 0; j < this.addresses.length; j++) { if (!(that.init_with_ip && this.isUntrusted())) {
for (i=0; i < that.addresses.length; i++) { for (j = 0; j < this.addresses.length; j++) {
if (this.addresses[j].equals(that.addresses[i])) for (i=0; i < that.addresses.length; i++) {
return true; if (this.addresses[j].equals(that.addresses[i]))
return true;
}
} }
}
// XXX: if all else fails, compare hostnames? // XXX: if all else fails, compare hostnames?
// Do we really want this? // Do we really want this?
if (this.cname == null) { if (this.cname == null) {
this.getCanonName(); this.getCanonName();
} }
if (that.cname == null) { if (that.cname == null) {
that.getCanonName(); that.getCanonName();
} }
return (this.cname.equalsIgnoreCase(that.cname)); return (this.cname.equalsIgnoreCase(that.cname));
}
} catch (UnknownHostException uhe) { } catch (UnknownHostException uhe) {
if (trustProxy) return compareHostnames(that);
return inProxyWeTrust(that);
} }
// make sure the first thing that is done here is to return // make sure the first thing that is done here is to return
...@@ -808,19 +995,23 @@ implements java.io.Serializable ...@@ -808,19 +995,23 @@ implements java.io.Serializable
return false; return false;
} }
private boolean inProxyWeTrust(SocketPermission that) { private boolean compareHostnames(SocketPermission that) {
// if we trust the proxy, we see if the original names/IPs passed // we see if the original names/IPs passed in were equal.
// in were equal.
String thisHost = hostname; String thisHost = hostname;
String thatHost = that.hostname; String thatHost = that.hostname;
if (thisHost == null) if (thisHost == null) {
return false; return false;
else } else if (this.wildcard) {
final int cnameLength = this.cname.length();
return thatHost.regionMatches(true,
(thatHost.length() - cnameLength), this.cname, 0, cnameLength);
} else {
return thisHost.equalsIgnoreCase(thatHost); return thisHost.equalsIgnoreCase(thatHost);
}
} }
/** /**
* Checks two SocketPermission objects for equality. * Checks two SocketPermission objects for equality.
* <P> * <P>
......
...@@ -238,4 +238,14 @@ abstract public class URLConnection extends java.net.URLConnection { ...@@ -238,4 +238,14 @@ abstract public class URLConnection extends java.net.URLConnection {
public void close() { public void close() {
url = null; url = null;
} }
private static HashMap<String,Void> proxiedHosts = new HashMap<>();
public synchronized static void setProxiedHost(String host) {
proxiedHosts.put(host.toLowerCase(), null);
}
public synchronized static boolean isProxiedHost(String host) {
return proxiedHosts.containsKey(host.toLowerCase());
}
} }
...@@ -301,7 +301,11 @@ public class HttpClient extends NetworkClient { ...@@ -301,7 +301,11 @@ public class HttpClient extends NetworkClient {
} else { } else {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
security.checkConnect(url.getHost(), url.getPort()); if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) {
security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort());
} else {
security.checkConnect(url.getHost(), url.getPort());
}
} }
ret.url = url; ret.url = url;
} }
...@@ -457,11 +461,11 @@ public class HttpClient extends NetworkClient { ...@@ -457,11 +461,11 @@ public class HttpClient extends NetworkClient {
protected synchronized void openServer() throws IOException { protected synchronized void openServer() throws IOException {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkConnect(host, port);
}
if (keepingAlive) { // already opened if (keepingAlive) { // already opened
if (security != null) {
security.checkConnect(host, port);
}
return; return;
} }
...@@ -469,11 +473,19 @@ public class HttpClient extends NetworkClient { ...@@ -469,11 +473,19 @@ public class HttpClient extends NetworkClient {
url.getProtocol().equals("https") ) { url.getProtocol().equals("https") ) {
if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) { if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) {
sun.net.www.URLConnection.setProxiedHost(host);
if (security != null) {
security.checkConnect(host,port);
}
privilegedOpenServer((InetSocketAddress) proxy.address()); privilegedOpenServer((InetSocketAddress) proxy.address());
usingProxy = true; usingProxy = true;
return; return;
} else { } else {
// make direct connection // make direct connection
if (security != null) {
// redundant?
security.checkConnect(host, port);
}
openServer(host, port); openServer(host, port);
usingProxy = false; usingProxy = false;
return; return;
...@@ -484,11 +496,19 @@ public class HttpClient extends NetworkClient { ...@@ -484,11 +496,19 @@ public class HttpClient extends NetworkClient {
* ftp url. * ftp url.
*/ */
if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) { if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) {
sun.net.www.URLConnection.setProxiedHost(host);
if (security != null) {
security.checkConnect(host,port);
}
privilegedOpenServer((InetSocketAddress) proxy.address()); privilegedOpenServer((InetSocketAddress) proxy.address());
usingProxy = true; usingProxy = true;
return; return;
} else { } else {
// make direct connection // make direct connection
if (security != null) {
// redundant?
security.checkConnect(host, port);
}
super.openServer(host, port); super.openServer(host, port);
usingProxy = false; usingProxy = false;
return; return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册