/* * Copyright (c) 2013, 2016, 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. */ import java.net.URLPermission; /* * @test * @bug 8010464 * @modules jdk.httpserver * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext * @run main/othervm URLTest * @summary check URLPermission with Http(s)URLConnection */ import java.net.*; import java.io.*; import java.security.*; import java.util.concurrent.*; import com.sun.net.httpserver.*; import javax.net.ssl.*; import jdk.testlibrary.SimpleSSLContext; public class URLTest { static boolean failed; public static void main (String[] args) throws Exception { createServers(); try { // Verify without a Security Manager test1(); test2(); test3(); // Set the security manager. Each test will set its own policy. Policy.setPolicy(new CustomPolicy()); System.setSecurityManager(new SecurityManager()); System.out.println("\n Security Manager has been set."); test1(); test2(); test3(); if (failed) throw new RuntimeException("Test failed"); } finally { shutdown(); } } static void test1() throws IOException { System.out.println("\n--- Test 1 ---"); boolean expectException = false; SecurityManager sm = System.getSecurityManager(); if (sm != null) { expectException = true; Policy.setPolicy(new CustomPolicy( new URLPermission("http://127.0.0.1:"+httpPort+"/foo.html", "GET:X-Foo,Z-Bar"), new URLPermission("https://127.0.0.1:"+httpsPort+"/foo.html", "POST:X-Fob,T-Bar"))); } String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; // simple positive test. Should succeed test(url1, "GET", "X-Foo"); test(url1, "GET", "Z-Bar", "X-Foo"); test(url1, "GET", "X-Foo", "Z-Bar"); test(url1, "GET", "Z-Bar"); test(url2, "POST", "X-Fob"); // reverse the methods, should fail test(url1, "POST", "X-Foo", expectException); test(url2, "GET", "X-Fob", expectException); // different URLs, should fail test(url3, "GET", "X-Foo", expectException); test(url4, "POST", "X-Fob", expectException); } static void test2() throws IOException { System.out.println("\n--- Test 2 ---"); SecurityManager sm = System.getSecurityManager(); if (sm != null) { Policy.setPolicy(new CustomPolicy( new URLPermission("http://127.0.0.1:"+httpPort+"/*", "GET:X-Foo"), new URLPermission("https://127.0.0.1:"+httpsPort+"/*", "POST:X-Fob"))); } String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; // simple positive test. Should succeed test(url1, "GET", "X-Foo"); test(url2, "POST", "X-Fob"); test(url3, "GET", "X-Foo"); test(url4, "POST", "X-Fob"); } static void test3() throws IOException { System.out.println("\n--- Test 3 ---"); boolean expectException = false; SecurityManager sm = System.getSecurityManager(); if (sm != null) { expectException = true; Policy.setPolicy(new CustomPolicy( new URLPermission("http://127.0.0.1:"+httpPort+"/a/b/-", "DELETE,GET:X-Foo,Y-Foo"), new URLPermission("https://127.0.0.1:"+httpsPort+"/a/c/-", "POST:*"))); } String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; String url2 = "https://127.0.0.1:"+httpsPort+"/a/c/d/e/foo.html"; String url3 = "http://127.0.0.1:"+httpPort+"/a/b/c"; String url4 = "https://127.0.0.1:"+httpsPort+"/a/b/c"; test(url1, "GET", "X-Foo", expectException); test(url2, "POST", "X-Zxc"); test(url3, "DELETE", "Y-Foo"); test(url4, "POST", "Y-Foo", expectException); } // Convenience methods to simplify previous explicit test scenarios. static void test(String u, String method, String header) throws IOException { test(u, method, header, null, false); } static void test(String u, String method, String header, boolean expectException) throws IOException { test(u, method, header, null, expectException); } static void test(String u, String method, String header1, String header2) throws IOException { test(u, method, header1, header2, false); } static void test(String u, String method, String header1, String header2, boolean expectException) throws IOException { URL url = new URL(u); System.out.println("url=" + u + " method=" + method + " header1=" + header1 + " header2=" + header2 + " expectException=" + expectException); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); if (urlc instanceof HttpsURLConnection) { HttpsURLConnection ssl = (HttpsURLConnection)urlc; ssl.setHostnameVerifier((host, sess) -> true); ssl.setSSLSocketFactory(ctx.getSocketFactory()); } urlc.setRequestMethod(method); if (header1 != null) urlc.addRequestProperty(header1, "foo"); if (header2 != null) urlc.addRequestProperty(header2, "bar"); try { int code = urlc.getResponseCode(); if (expectException) { failed = true; System.out.println("FAIL"); return; } if (code != 200) throw new RuntimeException("Unexpected response " + code); InputStream is = urlc.getInputStream(); is.readAllBytes(); is.close(); } catch (RuntimeException e) { if (!expectException || !(e.getCause() instanceof SecurityException)) { System.out.println ("FAIL. Unexpected: " + e.getMessage()); e.printStackTrace(); failed = true; return; } else { System.out.println("Got expected exception: " + e.getMessage()); } } System.out.println ("PASS"); } static HttpServer httpServer; static HttpsServer httpsServer; static HttpContext c, cs; static ExecutorService e, es; static SSLContext ctx; static int httpPort; static int httpsPort; static void createServers() throws Exception { InetSocketAddress any = new InetSocketAddress(0); httpServer = HttpServer.create(any, 0); httpsServer = HttpsServer.create(any, 0); OkHandler h = new OkHandler(); c = httpServer.createContext("/", h); cs = httpsServer.createContext("/", h); e = Executors.newCachedThreadPool(); es = Executors.newCachedThreadPool(); httpServer.setExecutor(e); httpsServer.setExecutor(es); ctx = new SimpleSSLContext().get(); httpsServer.setHttpsConfigurator(new HttpsConfigurator (ctx)); httpServer.start(); httpsServer.start(); httpPort = httpServer.getAddress().getPort(); httpsPort = httpsServer.getAddress().getPort(); } static void shutdown() { httpServer.stop(1); httpsServer.stop(1); e.shutdown(); es.shutdown(); } static class OkHandler implements HttpHandler { public void handle(HttpExchange x) throws IOException { x.sendResponseHeaders(200, -1); x.close(); } } static class CustomPolicy extends Policy { final PermissionCollection perms = new Permissions(); CustomPolicy(Permission... permissions) { java.util.Arrays.stream(permissions).forEach(perms::add); // needed for the HTTP(S) server perms.add(new SocketPermission("localhost:1024-", "listen,resolve,accept")); // needed by the test to reset the policy, per testX method perms.add(new SecurityPermission("setPolicy")); // needed to shutdown the ThreadPoolExecutor ( used by the servers ) perms.add(new RuntimePermission("modifyThread")); // needed by the client code forHttpsURLConnection.setSSLSocketFactory perms.add(new RuntimePermission("setFactory")); } public PermissionCollection getPermissions(ProtectionDomain domain) { return perms; } public PermissionCollection getPermissions(CodeSource codesource) { return perms; } public boolean implies(ProtectionDomain domain, Permission perm) { return perms.implies(perm); } } }