2013-01-14 58 views
1

考慮下面的代碼片段是否有java.net.SocketPermission中的錯誤在JVM中6 & 7 Oracle和OpenJDK的具有相同的行爲)與CNAME反向查找打交道時

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域的挖查找揭示了以下內容:

[[email protected] ~]$ 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查找生產:

[[email protected] ~]$ 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"; 
}; 

代碼的正確執行結果。

+0

FWIW,它看起來像我有完全相同的問題摔跤:http://stackoverflow.com/questions/36123812/odd-wildcard-behavior-in-java-net-socketpermission – metadaddy

回答

-1

連接時,該操作不會被JVM執行。它構造一個包含實際主機名/ IP地址的SocketPermission,並使用'implies'來檢查.policy文件中是否有任何權限意味着該權限

+0

這不是事實正確。請參閱上面的更新。 – Ray