test/jdk/java/net/SocketPermission/SocketPermissionTest.java
changeset 47216 71c04702a3d5
parent 45467 99c87a16a8e4
child 54822 f542a3a135bd
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2014, 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 /*
       
    25  * @test
       
    26  * @bug 8047031
       
    27  * @summary SocketPermission tests for legacy socket types
       
    28  * @library /test/lib
       
    29  * @build jdk.test.lib.NetworkConfiguration
       
    30  *        jdk.test.lib.Platform
       
    31  * @run testng/othervm SocketPermissionTest
       
    32  */
       
    33 
       
    34 import java.io.IOException;
       
    35 import java.net.DatagramPacket;
       
    36 import java.net.DatagramSocket;
       
    37 import java.net.InetAddress;
       
    38 import java.net.MulticastSocket;
       
    39 import java.net.NetworkInterface;
       
    40 import java.net.ServerSocket;
       
    41 import java.net.Socket;
       
    42 import java.net.SocketPermission;
       
    43 import java.security.AccessControlContext;
       
    44 import java.security.AccessController;
       
    45 import java.security.CodeSource;
       
    46 import java.security.Permission;
       
    47 import java.security.PermissionCollection;
       
    48 import java.security.Permissions;
       
    49 import java.security.Policy;
       
    50 import java.security.PrivilegedExceptionAction;
       
    51 import java.security.ProtectionDomain;
       
    52 import java.util.Optional;
       
    53 
       
    54 import org.testng.annotations.BeforeMethod;
       
    55 import org.testng.annotations.Test;
       
    56 
       
    57 import static org.testng.Assert.*;
       
    58 
       
    59 import static jdk.test.lib.NetworkConfiguration.probe;
       
    60 import static java.nio.charset.StandardCharsets.UTF_8;
       
    61 
       
    62 public class SocketPermissionTest {
       
    63 
       
    64     @BeforeMethod
       
    65     public void setupSecurityManager() throws Exception {
       
    66         // All permissions, a specific ACC will be used to when testing
       
    67         // with a reduced permission set.
       
    68         Policy.setPolicy(new Policy() {
       
    69              final PermissionCollection perms = new Permissions();
       
    70              { perms.add(new java.security.AllPermission()); }
       
    71              public PermissionCollection getPermissions(ProtectionDomain domain) {
       
    72                  return perms;
       
    73              }
       
    74              public PermissionCollection getPermissions(CodeSource codesource) {
       
    75                  return perms;
       
    76              }
       
    77              public boolean implies(ProtectionDomain domain, Permission perm) {
       
    78                  return perms.implies(perm);
       
    79              }
       
    80         } );
       
    81         System.setSecurityManager(new SecurityManager());
       
    82     }
       
    83 
       
    84     static final AccessControlContext RESTRICTED_ACC = getAccessControlContext();
       
    85 
       
    86     @Test
       
    87     public void connectSocketTest() throws Exception {
       
    88         try (ServerSocket ss = new ServerSocket(0)) {
       
    89             int port = ss.getLocalPort();
       
    90 
       
    91             String addr = "localhost:" + port;
       
    92             AccessControlContext acc = getAccessControlContext(
       
    93                     new SocketPermission(addr, "listen,connect,resolve"));
       
    94 
       
    95             // Positive
       
    96             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
    97                 try (Socket client = new Socket(InetAddress.getLocalHost(), port)) {
       
    98                 }
       
    99                 return null;
       
   100             }, acc);
       
   101 
       
   102             //Negative
       
   103             try {
       
   104                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   105                     Socket client = new Socket(InetAddress.getLocalHost(), port);
       
   106                     fail("Expected SecurityException");
       
   107                     return null;
       
   108                 }, RESTRICTED_ACC);
       
   109             } catch (SecurityException expected) { }
       
   110         }
       
   111     }
       
   112 
       
   113     @Test
       
   114     public void connectDatagramSocketTest() throws Exception {
       
   115         byte[] msg = "Hello".getBytes(UTF_8);
       
   116         InetAddress lh = InetAddress.getLocalHost();
       
   117 
       
   118         try (DatagramSocket ds = new DatagramSocket(0)) {
       
   119             int port = ds.getLocalPort();
       
   120 
       
   121             String addr = lh.getHostAddress() + ":" + port;
       
   122             AccessControlContext acc = getAccessControlContext(
       
   123                     new SocketPermission(addr, "connect,resolve"));
       
   124 
       
   125             // Positive
       
   126             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   127                 DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
       
   128                 ds.send(dp);
       
   129                 return null;
       
   130             }, acc);
       
   131 
       
   132             // Negative
       
   133             try {
       
   134                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   135                     DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
       
   136                     ds.send(dp);
       
   137                     fail("Expected SecurityException");
       
   138                     return null;
       
   139                 }, RESTRICTED_ACC);
       
   140             } catch (SecurityException expected) { }
       
   141         }
       
   142     }
       
   143 
       
   144     @Test
       
   145     public void acceptServerSocketTest() throws Exception {
       
   146         try (ServerSocket ss = new ServerSocket(0)) {
       
   147             int port = ss.getLocalPort();
       
   148 
       
   149             String addr = "localhost:" + port;
       
   150             AccessControlContext acc = getAccessControlContext(
       
   151                     new SocketPermission(addr, "listen,connect,resolve"),
       
   152                     new SocketPermission("localhost:1024-", "accept"));
       
   153 
       
   154             // Positive
       
   155             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   156                 InetAddress me = InetAddress.getLocalHost();
       
   157                 try (Socket client = new Socket(me, port)) {
       
   158                     ss.accept();
       
   159                 }
       
   160                 return null;
       
   161             }, acc);
       
   162 
       
   163             // Negative
       
   164             try {
       
   165                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   166                     InetAddress me = InetAddress.getLocalHost();
       
   167                     try (Socket client = new Socket(me, port)) {
       
   168                         ss.accept();
       
   169                     }
       
   170                     fail("Expected SecurityException");
       
   171                     return null;
       
   172                 }, RESTRICTED_ACC);
       
   173             } catch (SecurityException expected) { }
       
   174         }
       
   175     }
       
   176 
       
   177     @Test
       
   178     public void sendDatagramPacketTest() throws Exception {
       
   179         byte[] msg = "Hello".getBytes(UTF_8);
       
   180         InetAddress group = InetAddress.getByName("229.227.226.221");
       
   181 
       
   182         try (DatagramSocket ds = new DatagramSocket(0)) {
       
   183             int port = ds.getLocalPort();
       
   184 
       
   185             String addr = "localhost:" + port;
       
   186             //test for SocketPermission "229.227.226.221", "connect,accept"
       
   187             AccessControlContext acc = getAccessControlContext(
       
   188                     new SocketPermission(addr, "listen,resolve"),
       
   189                     new SocketPermission("229.227.226.221", "connect,accept"));
       
   190 
       
   191             // Positive
       
   192             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   193                 DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
       
   194                 ds.send(hi);
       
   195                 return null;
       
   196             }, acc);
       
   197 
       
   198             // Negative
       
   199             try {
       
   200                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   201                     DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
       
   202                     ds.send(hi);
       
   203                     fail("Expected SecurityException");
       
   204                     return null;
       
   205                 }, RESTRICTED_ACC);
       
   206             } catch (SecurityException expected) { }
       
   207         }
       
   208     }
       
   209 
       
   210     @Test
       
   211     public void joinGroupMulticastTest() throws Exception {
       
   212         InetAddress group = InetAddress.getByName("229.227.226.221");
       
   213         try (MulticastSocket s = new MulticastSocket(0)) {
       
   214             int port = s.getLocalPort();
       
   215 
       
   216             String addr = "localhost:" + port;
       
   217             AccessControlContext acc = getAccessControlContext(
       
   218                     new SocketPermission(addr, "listen,resolve"),
       
   219                     new SocketPermission("229.227.226.221", "connect,accept"));
       
   220 
       
   221             // Positive ( requires a functional network interface )
       
   222             Optional<NetworkInterface> onif = probe().ip4MulticastInterfaces().findFirst();
       
   223             if (!onif.isPresent()) {
       
   224                 s.setNetworkInterface(onif.get());
       
   225 
       
   226                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   227                     s.joinGroup(group);
       
   228                     s.leaveGroup(group);
       
   229                     return null;
       
   230                 }, acc);
       
   231             }
       
   232 
       
   233             // Negative
       
   234             try {
       
   235                 AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   236                     s.joinGroup(group);
       
   237                     s.leaveGroup(group);
       
   238                     fail("Expected SecurityException");
       
   239                     return null;
       
   240                 }, RESTRICTED_ACC);
       
   241             } catch (SecurityException expected) { }
       
   242         }
       
   243 
       
   244     }
       
   245 
       
   246     @Test
       
   247     public void listenDatagramSocketTest() throws Exception {
       
   248         // the hardcoded port number doesn't really matter since we expect the
       
   249         // security permission to be checked before the underlying operation.
       
   250         int port = 8899;
       
   251         String addr = "localhost:" + port;
       
   252         AccessControlContext acc = getAccessControlContext(
       
   253                 new SocketPermission(addr, "listen"));
       
   254 
       
   255         // Positive
       
   256         AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   257             try (DatagramSocket ds = new DatagramSocket(port)) { }
       
   258             catch (IOException intermittentlyExpected) { /* ignore */ }
       
   259             return null;
       
   260         }, acc);
       
   261 
       
   262         // Negative
       
   263         try {
       
   264             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   265                 try (DatagramSocket ds = new DatagramSocket(port)) { }
       
   266                 catch (IOException intermittentlyExpected) { /* ignore */ }
       
   267                 fail("Expected SecurityException");
       
   268                 return null;
       
   269             }, RESTRICTED_ACC);
       
   270         } catch (SecurityException expected) { }
       
   271     }
       
   272 
       
   273     @Test
       
   274     public void listenMulticastSocketTest() throws Exception {
       
   275         // the hardcoded port number doesn't really matter since we expect the
       
   276         // security permission to be checked before the underlying operation.
       
   277         int port = 8899;
       
   278         String addr = "localhost:" + port;
       
   279         AccessControlContext acc = getAccessControlContext(
       
   280                 new SocketPermission(addr, "listen"));
       
   281 
       
   282         // Positive
       
   283         AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   284             try (MulticastSocket ms = new MulticastSocket(port)) { }
       
   285             catch (IOException intermittentlyExpected) { /* ignore */ }
       
   286             return null;
       
   287         }, acc);
       
   288 
       
   289         // Negative
       
   290         try {
       
   291             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   292                 try (MulticastSocket ms = new MulticastSocket(port)) { }
       
   293                 catch (IOException intermittentlyExpected) { /* ignore */ }
       
   294                 fail("Expected SecurityException");
       
   295                 return null;
       
   296             }, RESTRICTED_ACC);
       
   297         } catch (SecurityException expected) { }
       
   298     }
       
   299 
       
   300     @Test
       
   301     public void listenServerSocketTest() throws Exception {
       
   302         // the hardcoded port number doesn't really matter since we expect the
       
   303         // security permission to be checked before the underlying operation.
       
   304         int port = 8899;
       
   305         String addr = "localhost:" + port;
       
   306         AccessControlContext acc = getAccessControlContext(
       
   307                 new SocketPermission(addr, "listen"));
       
   308 
       
   309         // Positive
       
   310         AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   311             try (ServerSocket ss = new ServerSocket(port)) { }
       
   312             catch (IOException intermittentlyExpected) { /* ignore */ }
       
   313             return null;
       
   314         }, acc);
       
   315 
       
   316         // Negative
       
   317         try {
       
   318             AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
       
   319                 try (ServerSocket ss = new ServerSocket(port)) { }
       
   320                 catch (IOException intermittentlyExpected) { /* ignore */ }
       
   321                 fail("Expected SecurityException");
       
   322                 return null;
       
   323             }, RESTRICTED_ACC);
       
   324         } catch (SecurityException expected) { }
       
   325 
       
   326     }
       
   327 
       
   328     private static AccessControlContext getAccessControlContext(Permission... ps) {
       
   329         Permissions perms = new Permissions();
       
   330         for (Permission p : ps) {
       
   331             perms.add(p);
       
   332         }
       
   333         /*
       
   334          *Create an AccessControlContext that consist a single protection domain
       
   335          * with only the permissions calculated above
       
   336          */
       
   337         ProtectionDomain pd = new ProtectionDomain(null, perms);
       
   338         return new AccessControlContext(new ProtectionDomain[]{pd});
       
   339     }
       
   340 
       
   341     // Standalone entry point for running with, possibly older, JDKs.
       
   342     public static void main(String[] args) throws Throwable {
       
   343         SocketPermissionTest test = new SocketPermissionTest();
       
   344         test.setupSecurityManager();
       
   345         for (java.lang.reflect.Method m : SocketPermissionTest.class.getDeclaredMethods()) {
       
   346             if (m.getAnnotation(Test.class) != null) {
       
   347                 System.out.println("Invoking " + m.getName());
       
   348                 m.invoke(test);
       
   349             }
       
   350         }
       
   351     }
       
   352 }