6957564: Disclosure of DNS server IP address
authorweijun
Thu, 17 Jun 2010 12:59:14 +0800
changeset 6859 0b0cdd787307
parent 6858 8d04722ed7d2
child 6860 5b1c9a7c3b80
6957564: Disclosure of DNS server IP address Reviewed-by: xuelei, chegar
jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java
--- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java	Tue Jun 15 08:12:51 2010 -0700
+++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java	Thu Jun 17 12:59:14 2010 +0800
@@ -54,6 +54,7 @@
 public class DnsContextFactory implements InitialContextFactory {
 
     private static final String DEFAULT_URL = "dns:";
+    private static final int DEFAULT_PORT = 53;
 
 
     public Context getInitialContext(Hashtable<?,?> env) throws NamingException {
@@ -89,7 +90,9 @@
      * Public for use by product test suite.
      */
     public static boolean platformServersAvailable() {
-        return !ResolverConfiguration.open().nameservers().isEmpty();
+        return !filterNameServers(
+                    ResolverConfiguration.open().nameservers(), true
+                ).isEmpty();
     }
 
     private static Context urlToContext(String url, Hashtable env)
@@ -142,8 +145,8 @@
                 // No server or port given, so look to underlying platform.
                 // ResolverConfiguration does some limited caching, so the
                 // following is reasonably efficient even if called rapid-fire.
-                List platformServers =
-                    ResolverConfiguration.open().nameservers();
+                List platformServers = filterNameServers(
+                    ResolverConfiguration.open().nameservers(), false);
                 if (!platformServers.isEmpty()) {
                     servers.addAll(platformServers);
                     continue;  // on to next URL (if any, which is unlikely)
@@ -214,4 +217,44 @@
         String url = (String) env.get(Context.PROVIDER_URL);
         return ((url != null) ? url : DEFAULT_URL);
     }
+
+    /**
+     * Removes any DNS server that's not permitted to access
+     * @param input the input server[:port] list, must not be null
+     * @param oneIsEnough return output once there exists one ok
+     * @return the filtered list, all non-permitted input removed
+     */
+    private static List filterNameServers(List input, boolean oneIsEnough) {
+        SecurityManager security = System.getSecurityManager();
+        if (security == null || input == null || input.isEmpty()) {
+            return input;
+        } else {
+            List output = new ArrayList();
+            for (Object o: input) {
+                if (o instanceof String) {
+                    String platformServer = (String)o;
+                    int colon = platformServer.indexOf(':',
+                            platformServer.indexOf(']') + 1);
+
+                    int p = (colon < 0)
+                        ? DEFAULT_PORT
+                        : Integer.parseInt(
+                            platformServer.substring(colon + 1));
+                    String s = (colon < 0)
+                        ? platformServer
+                        : platformServer.substring(0, colon);
+                    try {
+                        security.checkConnect(s, p);
+                        output.add(platformServer);
+                        if (oneIsEnough) {
+                            return output;
+                        }
+                    } catch (SecurityException se) {
+                        continue;
+                    }
+                }
+            }
+            return output;
+        }
+    }
 }