8025734: Use literal IP address where possible in SocketPermission generated by HttpURLPermission
authormichaelm
Wed, 23 Oct 2013 11:00:12 +0100
changeset 21344 13091b742137
parent 21343 2a4c97049dc6
child 21345 822b73ad4cc0
8025734: Use literal IP address where possible in SocketPermission generated by HttpURLPermission Reviewed-by: chegar
jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
jdk/test/java/net/URLPermission/nstest/LookupTest.java
jdk/test/java/net/URLPermission/nstest/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
jdk/test/java/net/URLPermission/nstest/SimpleNameService.java
jdk/test/java/net/URLPermission/nstest/SimpleNameServiceDescriptor.java
jdk/test/java/net/URLPermission/nstest/policy
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Oct 23 10:50:34 2013 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Oct 23 11:00:12 2013 +0100
@@ -903,6 +903,18 @@
 
     private String getHostAndPort(URL url) {
         String host = url.getHost();
+        final String hostarg = host;
+        try {
+            // lookup hostname and use IP address if available
+            host = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<String>() {
+                    public String run() throws IOException {
+                            InetAddress addr = InetAddress.getByName(hostarg);
+                            return addr.getHostAddress();
+                    }
+                }
+            );
+        } catch (PrivilegedActionException e) {}
         int port = url.getPort();
         if (port == -1) {
             String scheme = url.getProtocol();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java	Wed Oct 23 11:00:12 2013 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @compile -XDignore.symbol.file=true SimpleNameService.java
+ *                                     SimpleNameServiceDescriptor.java
+ * @run main/othervm/timeout=200 -Dsun.net.spi.nameservice.provider.1=simple,sun LookupTest
+ */
+
+/**
+ * This is a simple smoke test of the HttpURLPermission mechanism, which
+ * checks for either IOException (due to unknown host) or SecurityException
+ * due to lack of permission to connect
+ */
+
+import java.net.*;
+import java.io.*;
+
+public class LookupTest {
+
+    static void test(
+        String url, boolean throwsSecException, boolean throwsIOException)
+    {
+        try {
+            URL u = new URL(url);
+            System.err.println ("Connecting to " + u);
+            URLConnection urlc = u.openConnection();
+            InputStream is = urlc.getInputStream();
+        } catch (SecurityException e) {
+            if (!throwsSecException) {
+                throw new RuntimeException ("(1) was not expecting " + e);
+            }
+            return;
+        } catch (IOException ioe) {
+            if (!throwsIOException) {
+                throw new RuntimeException ("(2) was not expecting " + ioe);
+            }
+            return;
+        }
+        if (throwsSecException || throwsIOException) {
+            System.err.printf ("was expecting a %s\n", throwsSecException ?
+                "security exception" : "IOException");
+            throw new RuntimeException("was expecting an exception");
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+        SimpleNameService.put("allowedAndFound.com", "127.0.0.1");
+        SimpleNameService.put("notAllowedButFound.com", "99.99.99.99");
+        // name "notAllowedAndNotFound.com" is not in map
+        // name "allowedButNotfound.com" is not in map
+        startServer();
+
+        String policyFileName = "file://" + System.getProperty("test.src", ".") + "/policy";
+        System.err.println ("policy = " + policyFileName);
+
+        System.setProperty("java.security.policy", policyFileName);
+
+        System.setSecurityManager(new SecurityManager());
+
+        test("http://allowedAndFound.com:50100/foo", false, false);
+
+        test("http://notAllowedButFound.com:50100/foo", true, false);
+
+        test("http://allowedButNotfound.com:50100/foo", false, true);
+
+        test("http://notAllowedAndNotFound.com:50100/foo", true, false);
+    }
+
+    static Thread server;
+    static ServerSocket serverSocket;
+
+    static class Server extends Thread {
+        public void run() {
+            byte[] buf = new byte[1000];
+            try {
+                while (true) {
+                    Socket s = serverSocket.accept();
+                    InputStream i = s.getInputStream();
+                    i.read(buf);
+                    OutputStream o = s.getOutputStream();
+                    String rsp = "HTTP/1.1 200 Ok\r\n" +
+                        "Connection: close\r\nContent-length: 0\r\n\r\n";
+                    o.write(rsp.getBytes());
+                    o.close();
+                }
+            } catch (IOException e) {
+                return;
+            }
+            }
+    }
+
+    static void startServer() {
+        try {
+            serverSocket = new ServerSocket(50100);
+            server = new Server();
+            server.start();
+        } catch (Exception e) {
+            throw new RuntimeException ("Test failed to initialize");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor	Wed Oct 23 11:00:12 2013 +0100
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+SimpleNameServiceDescriptor    # name service provider descriptor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/SimpleNameService.java	Wed Oct 23 11:00:12 2013 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * A simple name service based on an in-memory HashMap.
+ */
+import java.net.UnknownHostException;
+import java.net.InetAddress;
+import sun.net.spi.nameservice.*;
+import java.util.*;
+
+public final class SimpleNameService implements NameService {
+
+    private static LinkedHashMap hosts = new LinkedHashMap();
+
+    private static String addrToString(byte addr[]) {
+        return Byte.toString(addr[0]) + "." +
+               Byte.toString(addr[1]) + "." +
+               Byte.toString(addr[2]) + "." +
+               Byte.toString(addr[3]);
+    }
+
+    // ------------
+
+    public static void put(String host, String addr) {
+        hosts.put(host, addr);
+    }
+
+    public static void put(String host, byte addr[]) {
+        hosts.put(host, addrToString(addr));
+    }
+
+    public static void remove(String host) {
+        hosts.remove(host);
+    }
+
+    public static int entries () {
+        return hosts.size();
+    }
+
+    public static int lookupCalls() {
+        return lookupCalls;
+    }
+
+    static int lookupCalls = 0;
+
+    // ------------
+
+    public SimpleNameService() throws Exception {
+    }
+
+    public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
+
+        lookupCalls ++;
+
+        String value = (String)hosts.get(host);
+        if (value == null) {
+            throw new UnknownHostException(host);
+        }
+        StringTokenizer st = new StringTokenizer(value, ".");
+        byte addr[] = new byte[4];
+        for (int i=0; i<4; i++) {
+            addr[i] = (byte)Integer.parseInt(st.nextToken());
+        }
+        InetAddress[] res = new InetAddress[1];
+        res[0] = InetAddress.getByAddress(host, addr);
+        return res;
+    }
+
+    public String getHostByAddr(byte[] addr) throws UnknownHostException {
+        String addrString = addrToString(addr);
+        Iterator i = hosts.keySet().iterator();
+        while (i.hasNext()) {
+            String host = (String)i.next();
+            String value = (String)hosts.get(host);
+            if (value.equals(addrString)) {
+                return host;
+            }
+        }
+        throw new UnknownHostException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/SimpleNameServiceDescriptor.java	Wed Oct 23 11:00:12 2013 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Descriptor for the simple name service
+ */
+import sun.net.spi.nameservice.*;
+
+public final class SimpleNameServiceDescriptor implements NameServiceDescriptor {
+    /**
+     * Create a new instance of the corresponding name service.
+     */
+    public NameService createNameService() throws Exception {
+        return new SimpleNameService();
+    }
+
+    /**
+     * Returns this service provider's name
+     *
+     */
+    public String getProviderName() {
+        return "sun";
+    }
+
+    /**
+     * Returns this name service type
+     * "dns" "nis" etc
+     */
+    public String getType() {
+        return "simple";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLPermission/nstest/policy	Wed Oct 23 11:00:12 2013 +0100
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+
+grant {
+    permission java.net.URLPermission "http://allowedAndFound.com:50100/-", "*:*";
+    permission java.net.URLPermission "http://allowedButNotfound.com:50100/-", "*:*";
+
+    // needed for HttpServer
+    permission "java.net.SocketPermission" "localhost:1024-", "resolve,accept";
+};
+
+// Normal permissions that aren't granted when run under jtreg
+
+grant codeBase "file:${{java.ext.dirs}}/*" {
+        permission java.security.AllPermission;
+};
+
+grant codeBase "file:${{java.home}}/jre/lib/rt.jar" {
+        permission java.security.AllPermission;
+};
+