1 /* 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.net.URLPermission; 25 /* 26 * @test 27 * @bug 8010464 28 * @modules jdk.httpserver 29 * @library /lib/testlibrary/ 30 * @build jdk.testlibrary.SimpleSSLContext 31 * @run main/othervm URLTest 32 * @summary check URLPermission with Http(s)URLConnection 33 */ 34 35 import java.net.*; 36 import java.io.*; 37 import java.security.*; 38 import java.util.concurrent.*; 39 import com.sun.net.httpserver.*; 40 import javax.net.ssl.*; 41 import jdk.testlibrary.SimpleSSLContext; 42 43 public class URLTest { 44 45 static boolean failed; 46 47 public static void main (String[] args) throws Exception { 48 createServers(); 49 50 try { 51 // Verify without a Security Manager 52 test1(); 53 test2(); 54 test3(); 55 56 // Set the security manager. Each test will set its own policy. 57 Policy.setPolicy(new CustomPolicy()); 58 System.setSecurityManager(new SecurityManager()); 59 System.out.println("\n Security Manager has been set."); 60 61 test1(); 62 test2(); 63 test3(); 64 65 if (failed) 66 throw new RuntimeException("Test failed"); 67 } finally { 68 shutdown(); 69 } 70 } 71 72 static void test1() throws IOException { 73 System.out.println("\n--- Test 1 ---"); 74 75 boolean expectException = false; 76 SecurityManager sm = System.getSecurityManager(); 77 if (sm != null) { 78 expectException = true; 79 Policy.setPolicy(new CustomPolicy( 80 new URLPermission("http://127.0.0.1:"+httpPort+"/foo.html", "GET:X-Foo,Z-Bar"), 81 new URLPermission("https://127.0.0.1:"+httpsPort+"/foo.html", "POST:X-Fob,T-Bar"))); 82 } 83 84 String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; 85 String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; 86 String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; 87 String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; 88 89 // simple positive test. Should succeed 90 test(url1, "GET", "X-Foo"); 91 test(url1, "GET", "Z-Bar", "X-Foo"); 92 test(url1, "GET", "X-Foo", "Z-Bar"); 93 test(url1, "GET", "Z-Bar"); 94 test(url2, "POST", "X-Fob"); 95 96 // reverse the methods, should fail 97 test(url1, "POST", "X-Foo", expectException); 98 test(url2, "GET", "X-Fob", expectException); 99 100 // different URLs, should fail 101 test(url3, "GET", "X-Foo", expectException); 102 test(url4, "POST", "X-Fob", expectException); 103 } 104 105 static void test2() throws IOException { 106 System.out.println("\n--- Test 2 ---"); 107 108 SecurityManager sm = System.getSecurityManager(); 109 if (sm != null) { 110 Policy.setPolicy(new CustomPolicy( 111 new URLPermission("http://127.0.0.1:"+httpPort+"/*", "GET:X-Foo"), 112 new URLPermission("https://127.0.0.1:"+httpsPort+"/*", "POST:X-Fob"))); 113 } 114 115 String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; 116 String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; 117 String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; 118 String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; 119 120 // simple positive test. Should succeed 121 test(url1, "GET", "X-Foo"); 122 test(url2, "POST", "X-Fob"); 123 test(url3, "GET", "X-Foo"); 124 test(url4, "POST", "X-Fob"); 125 } 126 127 static void test3() throws IOException { 128 System.out.println("\n--- Test 3 ---"); 129 130 boolean expectException = false; 131 SecurityManager sm = System.getSecurityManager(); 132 if (sm != null) { 133 expectException = true; 134 Policy.setPolicy(new CustomPolicy( 135 new URLPermission("http://127.0.0.1:"+httpPort+"/a/b/-", "DELETE,GET:X-Foo,Y-Foo"), 136 new URLPermission("https://127.0.0.1:"+httpsPort+"/a/c/-", "POST:*"))); 137 } 138 139 String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; 140 String url2 = "https://127.0.0.1:"+httpsPort+"/a/c/d/e/foo.html"; 141 String url3 = "http://127.0.0.1:"+httpPort+"/a/b/c"; 142 String url4 = "https://127.0.0.1:"+httpsPort+"/a/b/c"; 143 144 test(url1, "GET", "X-Foo", expectException); 145 test(url2, "POST", "X-Zxc"); 146 test(url3, "DELETE", "Y-Foo"); 147 test(url4, "POST", "Y-Foo", expectException); 148 } 149 150 // Convenience methods to simplify previous explicit test scenarios. 151 static void test(String u, String method, String header) throws IOException { 152 test(u, method, header, null, false); 153 } 154 155 static void test(String u, String method, String header, boolean expectException) 156 throws IOException 157 { 158 test(u, method, header, null, expectException); 159 } 160 161 static void test(String u, String method, String header1, String header2) 162 throws IOException 163 { 164 test(u, method, header1, header2, false); 165 } 166 167 static void test(String u, 168 String method, 169 String header1, 170 String header2, 171 boolean expectException) 172 throws IOException 173 { 174 URL url = new URL(u); 175 System.out.println("url=" + u + " method=" + method + 176 " header1=" + header1 + " header2=" + header2 + 177 " expectException=" + expectException); 178 HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); 179 if (urlc instanceof HttpsURLConnection) { 180 HttpsURLConnection ssl = (HttpsURLConnection)urlc; 181 ssl.setHostnameVerifier((host, sess) -> true); 182 ssl.setSSLSocketFactory(ctx.getSocketFactory()); 183 } 184 urlc.setRequestMethod(method); 185 if (header1 != null) 186 urlc.addRequestProperty(header1, "foo"); 187 if (header2 != null) 188 urlc.addRequestProperty(header2, "bar"); 189 190 try { 191 int code = urlc.getResponseCode(); 192 if (expectException) { 193 failed = true; 194 System.out.println("FAIL"); 195 return; 196 } 197 if (code != 200) 198 throw new RuntimeException("Unexpected response " + code); 199 200 InputStream is = urlc.getInputStream(); 201 is.readAllBytes(); 202 is.close(); 203 } catch (RuntimeException e) { 204 if (!expectException || !(e.getCause() instanceof SecurityException)) { 205 System.out.println ("FAIL. Unexpected: " + e.getMessage()); 206 e.printStackTrace(); 207 failed = true; 208 return; 209 } else { 210 System.out.println("Got expected exception: " + e.getMessage()); 211 } 212 } 213 System.out.println ("PASS"); 214 } 215 216 static HttpServer httpServer; 217 static HttpsServer httpsServer; 218 static HttpContext c, cs; 219 static ExecutorService e, es; 220 static SSLContext ctx; 221 static int httpPort; 222 static int httpsPort; 223 224 static void createServers() throws Exception { 225 InetSocketAddress any = new InetSocketAddress(0); 226 httpServer = HttpServer.create(any, 0); 227 httpsServer = HttpsServer.create(any, 0); 228 229 OkHandler h = new OkHandler(); 230 231 c = httpServer.createContext("/", h); 232 cs = httpsServer.createContext("/", h); 233 e = Executors.newCachedThreadPool(); 234 es = Executors.newCachedThreadPool(); 235 httpServer.setExecutor(e); 236 httpsServer.setExecutor(es); 237 238 ctx = new SimpleSSLContext().get(); 239 httpsServer.setHttpsConfigurator(new HttpsConfigurator (ctx)); 240 241 httpServer.start(); 242 httpsServer.start(); 243 244 httpPort = httpServer.getAddress().getPort(); 245 httpsPort = httpsServer.getAddress().getPort(); 246 } 247 248 static void shutdown() { 249 httpServer.stop(1); 250 httpsServer.stop(1); 251 e.shutdown(); 252 es.shutdown(); 253 } 254 255 static class OkHandler implements HttpHandler { 256 public void handle(HttpExchange x) throws IOException { 257 x.sendResponseHeaders(200, -1); 258 x.close(); 259 } 260 } 261 262 static class CustomPolicy extends Policy { 263 final PermissionCollection perms = new Permissions(); 264 CustomPolicy(Permission... permissions) { 265 java.util.Arrays.stream(permissions).forEach(perms::add); 266 267 // needed for the HTTP(S) server 268 perms.add(new SocketPermission("localhost:1024-", "listen,resolve,accept")); 269 // needed by the test to reset the policy, per testX method 270 perms.add(new SecurityPermission("setPolicy")); 271 // needed to shutdown the ThreadPoolExecutor ( used by the servers ) 272 perms.add(new RuntimePermission("modifyThread")); 273 // needed by the client code forHttpsURLConnection.setSSLSocketFactory 274 perms.add(new RuntimePermission("setFactory")); 275 } 276 277 public PermissionCollection getPermissions(ProtectionDomain domain) { 278 return perms; 279 } 280 281 public PermissionCollection getPermissions(CodeSource codesource) { 282 return perms; 283 } 284 285 public boolean implies(ProtectionDomain domain, Permission perm) { 286 return perms.implies(perm); 287 } 288 } 289 }