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