请看下面的代码片段:
(在这种情况下的OpenJDK 6b24-1.11.5-0ubuntu1〜12.10.1,由于所有的JVM 6&7 Oracle和OpenJDK的都具有相同的行为出现不相干)
SocketPermission toCheck = new SocketPermission("www.google.ca", "resolve");
SocketPermission checker = new SocketPermission("*.ca:80", "connect");
System.out.println("Result: " + checker.implies(toCheck));
checker = new SocketPermission("*.1e100.net:80", "connect");
System.out.println("Result: " + checker.implies(toCheck));
结果我得到的是:
Result: false
Result: true
这个问题似乎是在JVM做一个反向查找,以验证该地址针对解决实际域匹配。
在www.google.ca域的挖掘查找结果如下:
[rotty@rotty-desktop ~]$ dig www.google.ca ANY
; <<>> DiG 9.8.1-P1 <<>> www.google.ca ANY
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48015
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.google.ca. IN ANY
;; ANSWER SECTION:
www.google.ca. 114 IN A 74.125.226.55
www.google.ca. 114 IN A 74.125.226.56
www.google.ca. 114 IN A 74.125.226.63
www.google.ca. 74 IN AAAA 2607:f8b0:400b:801::1018
;; Query time: 27 msec
;; SERVER: 127.0.1.1#53(127.0.1.1)
;; WHEN: Mon Jan 14 17:18:50 2013
;; MSG SIZE rcvd: 107
此外,考虑在第一地址中的结果,并执行DNS查找生产:
[rotty@rotty-desktop ~]$ nslookup 74.125.226.55
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
55.226.125.74.in-addr.arpa name = yyz06s06-in-f23.1e100.net.
Authoritative answers can be found from:
这似乎清楚地表明了这一问题。 非权威反向查找返回该域定义的第一个(在这种情况下,局部性)别名。
这意味着,我需要知道,并宣布,可能解决到指定域名的根本解决任何潜在的别名。
为什么会在JVM需要这样的比赛? 就不是一个简单的验证该地址是否确实存在的“决心”的过程足以满足? 有可能是任意数量的用于地址可能反向映射。 这怎么可能曾经在工作实践中?
[更新]为了澄清,这其实表现了默认的Java策略定义相同,考虑以下附加例如:
Socket socket = new Socket("www.google.ca", 80);
socket.close();
采用以下安全策略上面:
grant {
permission java.net.SocketPermission "*.ca:80", "connect";
//permission java.net.SocketPermission "*.1e100.net:80", "connect";
};
执行程序为:
java -Djava.security.manager -Djava.security.policy=../security.policy Test
结果是:
Exception in thread "main" java.security.AccessControlException: access denied ("java.net.SocketPermission" "www.google.ca" "resolve")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
at java.security.AccessController.checkPermission(AccessController.java:560)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkConnect(SecurityManager.java:1048)
at java.net.InetAddress.getAllByName0(InetAddress.java:1203)
at java.net.InetAddress.getAllByName(InetAddress.java:1127)
at java.net.InetAddress.getAllByName(InetAddress.java:1063)
at java.net.InetAddress.getByName(InetAddress.java:1013)
at java.net.InetSocketAddress.<init>(InetSocketAddress.java:142)
at java.net.Socket.<init>(Socket.java:208)
at example.security.SocketSecurityExample.test(SocketSecurityExample.java:13)
at example.security.SocketSecurityExample.main(SocketSecurityExample.java:9)
改变策略文件:
grant {
//permission java.net.SocketPermission "*.ca:80", "connect";
permission java.net.SocketPermission "*.1e100.net:80", "connect";
};
结果在代码的正确执行。