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