test/jdk/java/net/httpclient/security/Security.java
branchhttp-client-branch
changeset 56391 a44e40b6aa43
parent 56388 701dd37aa97a
child 56396 8e8423347c1e
equal deleted inserted replaced
56390:ba892d93b3c5 56391:a44e40b6aa43
    48  */
    48  */
    49 
    49 
    50 // Tests 1, 10, 11 and 12 executed from Driver
    50 // Tests 1, 10, 11 and 12 executed from Driver
    51 
    51 
    52 import com.sun.net.httpserver.Headers;
    52 import com.sun.net.httpserver.Headers;
    53 import com.sun.net.httpserver.HttpContext;
       
    54 import com.sun.net.httpserver.HttpExchange;
    53 import com.sun.net.httpserver.HttpExchange;
    55 import com.sun.net.httpserver.HttpHandler;
    54 import com.sun.net.httpserver.HttpHandler;
    56 import com.sun.net.httpserver.HttpServer;
    55 import com.sun.net.httpserver.HttpServer;
    57 import com.sun.net.httpserver.HttpsServer;
    56 import com.sun.net.httpserver.HttpsServer;
    58 import java.io.IOException;
    57 import java.io.IOException;
    95 /**
    94 /**
    96  * Security checks test
    95  * Security checks test
    97  */
    96  */
    98 public class Security {
    97 public class Security {
    99 
    98 
   100     static HttpServer s1 = null;
    99     static HttpServer s1;
   101     static ExecutorService executor=null;
   100     static ExecutorService executor;
   102     static int port, proxyPort;
   101     static int port, proxyPort;
   103     static HttpClient client;
   102     static HttpClient client;
   104     static String httproot, fileuri, fileroot, redirectroot;
   103     static String httproot, fileuri, fileroot, redirectroot;
   105     static List<HttpClient> clients = new LinkedList<>();
   104     static List<HttpClient> clients = new LinkedList<>();
   106     static URI uri;
   105     static URI uri;
   107 
   106 
   108     interface Test {
   107     interface ThrowingRunnable { void run() throws Throwable; }
   109         void execute() throws IOException, InterruptedException;
       
   110     }
       
   111 
   108 
   112     static class TestAndResult {
   109     static class TestAndResult {
   113         Test test;
   110         private final ThrowingRunnable runnable;
   114         boolean result;
   111         private final boolean expectSecurityException;
   115 
   112 
   116         TestAndResult (Test t, boolean result) {
   113         TestAndResult(boolean expectSecurityException, ThrowingRunnable runnable) {
   117             this.test = t;
   114             this.expectSecurityException = expectSecurityException;
   118             this.result = result;
   115             this.runnable = runnable;
   119         }
   116         }
   120     }
   117 
   121 
   118         static TestAndResult of(boolean expectSecurityException,
   122     static TestAndResult test(boolean result, Test t) {
   119                                 ThrowingRunnable runnable) {
   123         return new TestAndResult(t, result);
   120             return new TestAndResult(expectSecurityException, runnable);
   124     }
   121         }
   125 
   122 
   126     static TestAndResult[] tests;
   123         void runWithPolicy(String policy) {
       
   124             System.out.println("Using policy file: " + policy);
       
   125             try {
       
   126                 runnable.run();
       
   127                 if (expectSecurityException) {
       
   128                     System.out.println("FAILED: expected security exception");
       
   129                     throw new RuntimeException("FAILED: expected security exception\"");
       
   130                 }
       
   131                 System.out.println (policy + " succeeded as expected");
       
   132             } catch (BindException e) {
       
   133                 System.exit(10);
       
   134             } catch (SecurityException e) {
       
   135                 if (!expectSecurityException) {
       
   136                     System.out.println("Unexpected security Exception: " + e);
       
   137                     throw new RuntimeException(e);
       
   138                 }
       
   139                 System.out.println(policy + " threw exception as expected");
       
   140             } catch (Throwable t) {
       
   141                 throw new AssertionError(t);
       
   142             }
       
   143         }
       
   144     }
       
   145 
       
   146     static TestAndResult[] tests = createTests();
   127     static String testclasses;
   147     static String testclasses;
   128     static File subdir;
   148     static File subdir;
   129 
   149 
   130     /**
   150     /**
   131      * The ProxyServer class is compiled by jtreg, but we want to
   151      * The ProxyServer class is compiled by jtreg, but we want to
   174     }
   194     }
   175 
   195 
   176     static Class<?> proxyClass;
   196     static Class<?> proxyClass;
   177     static Constructor<?> proxyConstructor;
   197     static Constructor<?> proxyConstructor;
   178 
   198 
   179     static void setupTests() {
   199     static TestAndResult[] createTests() {
   180         tests = new TestAndResult[]{
   200         return new TestAndResult[] {
   181             // (0) policy does not have permission for file. Should fail
   201             // (0) policy does not have permission for file. Should fail
   182             test(false, () -> { // Policy 0
   202             TestAndResult.of(true, () -> { // Policy 0
   183                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   203                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   184                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   204                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   185                 HttpResponse<?> response = client.send(request, ofString());
   205                 HttpResponse<?> response = client.send(request, ofString());
   186             }),
   206             }),
   187             // (1) policy has permission for file URL
   207             // (1) policy has permission for file URL
   188             test(true, () -> { //Policy 1
   208             TestAndResult.of(false, () -> { //Policy 1
   189                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   209                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   190                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   210                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   191                 HttpResponse<?> response = client.send(request, ofString());
   211                 HttpResponse<?> response = client.send(request, ofString());
   192             }),
   212             }),
   193             // (2) policy has permission for all file URLs under /files
   213             // (2) policy has permission for all file URLs under /files
   194             test(true, () -> { // Policy 2
   214             TestAndResult.of(false, () -> { // Policy 2
   195                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   215                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   196                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   216                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   197                 HttpResponse<?> response = client.send(request, ofString());
   217                 HttpResponse<?> response = client.send(request, ofString());
   198             }),
   218             }),
   199             // (3) policy has permission for first URL but not redirected URL
   219             // (3) policy has permission for first URL but not redirected URL
   200             test(false, () -> { // Policy 3
   220             TestAndResult.of(true, () -> { // Policy 3
   201                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   221                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   202                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   222                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   203                 HttpResponse<?> response = client.send(request, ofString());
   223                 HttpResponse<?> response = client.send(request, ofString());
   204             }),
   224             }),
   205             // (4) policy has permission for both first URL and redirected URL
   225             // (4) policy has permission for both first URL and redirected URL
   206             test(true, () -> { // Policy 4
   226             TestAndResult.of(false, () -> { // Policy 4
   207                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   227                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   208                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   228                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   209                 HttpResponse<?> response = client.send(request, ofString());
   229                 HttpResponse<?> response = client.send(request, ofString());
   210             }),
   230             }),
   211             // (5) policy has permission for redirected but not first URL
   231             // (5) policy has permission for redirected but not first URL
   212             test(false, () -> { // Policy 5
   232             TestAndResult.of(true, () -> { // Policy 5
   213                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   233                 URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
   214                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   234                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   215                 HttpResponse<?> response = client.send(request, ofString());
   235                 HttpResponse<?> response = client.send(request, ofString());
   216             }),
   236             }),
   217             // (6) policy has permission for file URL, but not method
   237             // (6) policy has permission for file URL, but not method
   218             test(false, () -> { //Policy 6
   238             TestAndResult.of(true, () -> { //Policy 6
   219                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   239                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   220                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   240                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   221                 HttpResponse<?> response = client.send(request, ofString());
   241                 HttpResponse<?> response = client.send(request, ofString());
   222             }),
   242             }),
   223             // (7) policy has permission for file URL, method, but not header
   243             // (7) policy has permission for file URL, method, but not header
   224             test(false, () -> { //Policy 7
   244             TestAndResult.of(true, () -> { //Policy 7
   225                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   245                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   226                 HttpRequest request = HttpRequest.newBuilder(u)
   246                 HttpRequest request = HttpRequest.newBuilder(u)
   227                                                  .header("X-Foo", "bar")
   247                                                  .header("X-Foo", "bar")
   228                                                  .GET()
   248                                                  .GET()
   229                                                  .build();
   249                                                  .build();
   230                 HttpResponse<?> response = client.send(request, ofString());
   250                 HttpResponse<?> response = client.send(request, ofString());
   231             }),
   251             }),
   232             // (8) policy has permission for file URL, method and header
   252             // (8) policy has permission for file URL, method and header
   233             test(true, () -> { //Policy 8
   253             TestAndResult.of(false, () -> { //Policy 8
   234                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   254                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   235                 HttpRequest request = HttpRequest.newBuilder(u)
   255                 HttpRequest request = HttpRequest.newBuilder(u)
   236                                                  .header("X-Foo", "bar")
   256                                                  .header("X-Foo", "bar")
   237                                                  .GET()
   257                                                  .GET()
   238                                                  .build();
   258                                                  .build();
   239                 HttpResponse<?> response = client.send(request, ofString());
   259                 HttpResponse<?> response = client.send(request, ofString());
   240             }),
   260             }),
   241             // (9) policy has permission for file URL, method and header
   261             // (9) policy has permission for file URL, method and header
   242             test(true, () -> { //Policy 9
   262             TestAndResult.of(false, () -> { //Policy 9
   243                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   263                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   244                 HttpRequest request = HttpRequest.newBuilder(u)
   264                 HttpRequest request = HttpRequest.newBuilder(u)
   245                                                  .headers("X-Foo", "bar", "X-Bar", "foo")
   265                                                  .headers("X-Foo", "bar", "X-Bar", "foo")
   246                                                  .GET()
   266                                                  .GET()
   247                                                  .build();
   267                                                  .build();
   248                 HttpResponse<?> response = client.send(request, ofString());
   268                 HttpResponse<?> response = client.send(request, ofString());
   249             }),
   269             }),
   250             // (10) policy has permission for destination URL but not for proxy
   270             // (10) policy has permission for destination URL but not for proxy
   251             test(false, () -> { //Policy 10
   271             TestAndResult.of(true, () -> { //Policy 10
   252                 directProxyTest(proxyPort, true);
   272                 directProxyTest(proxyPort, true);
   253             }),
   273             }),
   254             // (11) policy has permission for both destination URL and proxy
   274             // (11) policy has permission for both destination URL and proxy
   255             test(true, () -> { //Policy 11
   275             TestAndResult.of(false, () -> { //Policy 11
   256                 directProxyTest(proxyPort, true);
   276                 directProxyTest(proxyPort, true);
   257             }),
   277             }),
   258             // (12) policy has permission for both destination URL and proxy
   278             // (12) policy has permission for both destination URL and proxy
   259             test(false, () -> { //Policy 12 ( 11 & 12 are the same )
   279             TestAndResult.of(true, () -> { //Policy 12 ( 11 & 12 are the same )
   260                 directProxyTest(proxyPort, false);
   280                 directProxyTest(proxyPort, false);
   261             }),
   281             }),
   262             // (13) async version of test 0
   282             // (13) async version of test 0
   263             test(false, () -> { // Policy 0
   283             TestAndResult.of(true, () -> { // Policy 0
   264                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   284                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   265                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   285                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   266                 try {
   286                 try {
   267                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
   287                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
   268                 } catch (ExecutionException e) {
   288                 } catch (ExecutionException e) {
   272                         throw new RuntimeException(e);
   292                         throw new RuntimeException(e);
   273                     }
   293                     }
   274                 }
   294                 }
   275             }),
   295             }),
   276             // (14) async version of test 1
   296             // (14) async version of test 1
   277             test(true, () -> { //Policy 1
   297             TestAndResult.of(false, () -> { //Policy 1
   278                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   298                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   279                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   299                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   280                 try {
   300                 try {
   281                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
   301                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
   282                 } catch (ExecutionException e) {
   302                 } catch (ExecutionException e) {
   287                     }
   307                     }
   288                 }
   308                 }
   289             }),
   309             }),
   290             // (15) check that user provided unprivileged code running on a worker
   310             // (15) check that user provided unprivileged code running on a worker
   291             //      thread does not gain ungranted privileges.
   311             //      thread does not gain ungranted privileges.
   292             test(false, () -> { //Policy 12
   312             TestAndResult.of(true, () -> { //Policy 12
   293                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   313                 URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
   294                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   314                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
   295                 HttpResponse.BodyHandler<String> sth = ofString();
   315                 HttpResponse.BodyHandler<String> sth = ofString();
   296 
   316 
   297                 CompletableFuture<HttpResponse<String>> cf =
   317                 CompletableFuture<HttpResponse<String>> cf =
   375                                          .headers("X-Foo", "bar", "X-Bar", "foo")
   395                                          .headers("X-Foo", "bar", "X-Bar", "foo")
   376                                          .build();
   396                                          .build();
   377         HttpResponse<?> response = cl.send(request, ofString());
   397         HttpResponse<?> response = cl.send(request, ofString());
   378     }
   398     }
   379 
   399 
   380     static void runtest(Test r, String policy, boolean succeeds) {
       
   381         System.out.println("Using policy file: " + policy);
       
   382         try {
       
   383             r.execute();
       
   384             if (!succeeds) {
       
   385                 System.out.println("FAILED: expected security exception");
       
   386                 throw new RuntimeException("FAILED: expected security exception\"");
       
   387             }
       
   388             System.out.println (policy + " succeeded as expected");
       
   389         } catch (BindException e) {
       
   390             System.exit(10);
       
   391         } catch (SecurityException e) {
       
   392             if (succeeds) {
       
   393                 System.out.println("FAILED");
       
   394                 throw new RuntimeException(e);
       
   395             }
       
   396             System.out.println (policy + " threw exception as expected");
       
   397         } catch (IOException | InterruptedException ee) {
       
   398             throw new RuntimeException(ee);
       
   399         }
       
   400     }
       
   401 
       
   402     public static void main(String[] args) throws Exception {
   400     public static void main(String[] args) throws Exception {
   403         try {
   401         try {
   404             initServer();
   402             initServer();
   405             setupProxy();
   403             setupProxy();
   406         } catch (BindException e) {
   404         } catch (BindException e) {
   407             System.exit(10);
   405             System.exit(10);
   408         }
   406         }
   409         fileroot = System.getProperty ("test.src")+ "/docs";
   407         fileroot = System.getProperty("test.src")+ "/docs";
   410         int testnum = Integer.parseInt(args[0]);
   408         int testnum = Integer.parseInt(args[0]);
   411         String policy = args[0];
   409         String policy = args[0];
   412 
   410 
   413         client = HttpClient.newBuilder()
   411         client = HttpClient.newBuilder()
   414                            .followRedirects(HttpClient.Redirect.ALWAYS)
   412                            .followRedirects(HttpClient.Redirect.ALWAYS)
   415                            .build();
   413                            .build();
   416 
   414 
   417         clients.add(client);
   415         clients.add(client);
   418 
   416 
   419         try {
   417         try {
   420             setupTests();
       
   421             TestAndResult tr = tests[testnum];
   418             TestAndResult tr = tests[testnum];
   422             runtest(tr.test, policy, tr.result);
   419             tr.runWithPolicy(policy);
   423         } finally {
   420         } finally {
   424             s1.stop(0);
   421             s1.stop(0);
   425             executor.shutdownNow();
   422             executor.shutdownNow();
   426         }
   423         }
   427     }
   424     }
   435         Logger logger = Logger.getLogger("com.sun.net.httpserver");
   432         Logger logger = Logger.getLogger("com.sun.net.httpserver");
   436         ConsoleHandler ch = new ConsoleHandler();
   433         ConsoleHandler ch = new ConsoleHandler();
   437         logger.setLevel(Level.ALL);
   434         logger.setLevel(Level.ALL);
   438         ch.setLevel(Level.ALL);
   435         ch.setLevel(Level.ALL);
   439         logger.addHandler(ch);
   436         logger.addHandler(ch);
   440         String root = System.getProperty ("test.src")+ "/docs";
   437         String root = System.getProperty("test.src")+ "/docs";
   441         InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
   438         InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
   442         s1 = HttpServer.create (addr, 0);
   439         s1 = HttpServer.create (addr, 0);
   443         if (s1 instanceof HttpsServer) {
   440         if (s1 instanceof HttpsServer) {
   444             throw new RuntimeException ("should not be httpsserver");
   441             throw new RuntimeException("should not be httpsserver");
   445         }
   442         }
   446         HttpHandler h = new FileServerHandler (root);
   443         s1.createContext("/files", new FileServerHandler(root));
   447         HttpContext c = s1.createContext ("/files", h);
   444         s1.createContext("/redirect", new RedirectHandler("/redirect"));
   448 
       
   449         HttpHandler h1 = new RedirectHandler ("/redirect");
       
   450         HttpContext c1 = s1.createContext ("/redirect", h1);
       
   451 
   445 
   452         executor = Executors.newCachedThreadPool();
   446         executor = Executors.newCachedThreadPool();
   453         s1.setExecutor (executor);
   447         s1.setExecutor(executor);
   454         s1.start();
   448         s1.start();
   455 
   449 
   456         if (port == 0)
   450         if (port == 0)
   457             port = s1.getAddress().getPort();
   451             port = s1.getAddress().getPort();
   458         else {
   452         else {
   483         synchronized void increment() {
   477         synchronized void increment() {
   484             count++;
   478             count++;
   485         }
   479         }
   486 
   480 
   487         @Override
   481         @Override
   488         public synchronized void handle(HttpExchange t)
   482         public synchronized void handle(HttpExchange t) throws IOException {
   489                 throws IOException {
       
   490             byte[] buf = new byte[2048];
       
   491             System.out.println("Server: " + t.getRequestURI());
   483             System.out.println("Server: " + t.getRequestURI());
   492             try (InputStream is = t.getRequestBody()) {
   484             try (InputStream is = t.getRequestBody()) {
   493                 while (is.read(buf) != -1) ;
   485                is.readAllBytes();
   494             }
   486             }
   495             increment();
   487             increment();
   496             if (count() == 1) {
   488             if (count() == 1) {
   497                 Headers map = t.getResponseHeaders();
   489                 Headers map = t.getResponseHeaders();
   498                 String redirect = "/redirect/bar.txt";
   490                 String redirect = "/redirect/bar.txt";