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