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