1 /* 2 * Copyright (c) 2017, 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 package p; 25 26 import java.security.AccessControlContext; 27 import java.security.AccessControlException; 28 import java.security.AccessController; 29 import java.security.AllPermission; 30 import java.security.CodeSource; 31 import java.security.Permission; 32 import java.security.PermissionCollection; 33 import java.security.Permissions; 34 import java.security.PrivilegedAction; 35 import java.security.ProtectionDomain; 36 import java.util.ServiceConfigurationError; 37 import java.util.ServiceLoader; 38 import java.util.ServiceLoader.Provider; 39 import static java.security.AccessController.doPrivileged; 40 41 import org.testng.annotations.DataProvider; 42 import org.testng.annotations.Test; 43 import org.testng.annotations.BeforeTest; 44 import static org.testng.Assert.*; 45 46 /** 47 * Tests ServiceLoader when running with a security manager, specifically 48 * tests to ensure that provider code is run with permissions restricted by 49 * the creater of ServiceLoader, and also testing of exceptions thrown 50 * when loading or initializing a provider. 51 */ 52 53 public class Tests { 54 55 static final Permission PERM = new RuntimePermission("eatMuffin"); 56 loadAction(Class<T> service)57 static <T> PrivilegedAction<ServiceLoader<T>> loadAction(Class<T> service) { 58 return () -> ServiceLoader.load(service); 59 } 60 withPermissions(Permission... perms)61 static AccessControlContext withPermissions(Permission... perms) { 62 Permissions p = new Permissions(); 63 for (Permission perm : perms) { 64 p.add(perm); 65 } 66 ProtectionDomain pd = new ProtectionDomain(null, p); 67 return new AccessControlContext(new ProtectionDomain[]{ pd }); 68 } 69 noPermissions()70 static AccessControlContext noPermissions() { 71 return withPermissions(/*empty*/); 72 } 73 74 @BeforeTest setSecurityManager()75 public void setSecurityManager() { 76 class Policy extends java.security.Policy { 77 private final Permissions perms; 78 public Policy(Permission... permissions) { 79 perms = new Permissions(); 80 for (Permission permission : permissions) { 81 perms.add(permission); 82 } 83 } 84 public PermissionCollection getPermissions(CodeSource cs) { 85 return perms; 86 } 87 public PermissionCollection getPermissions(ProtectionDomain pd) { 88 return perms; 89 } 90 public boolean implies(ProtectionDomain pd, Permission p) { 91 return perms.implies(p); 92 } 93 public void refresh() { } 94 } 95 Policy policy = new Policy(new AllPermission()); 96 Policy.setPolicy(policy); 97 System.setSecurityManager(new SecurityManager()); 98 } 99 100 @Test testConstructorUsingIteratorWithPermission()101 public void testConstructorUsingIteratorWithPermission() { 102 ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM)); 103 S1 obj = sl.iterator().next(); 104 } 105 106 @Test testConstructorUsingStreamWithPermission()107 public void testConstructorUsingStreamWithPermission() { 108 ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM)); 109 assertTrue(sl.stream().map(Provider::get).count() == 1); 110 } 111 112 @Test testConstructorUsingIteratorNoPermission()113 public void testConstructorUsingIteratorNoPermission() { 114 ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions()); 115 try { 116 sl.iterator().next(); 117 assertTrue(false); 118 } catch (ServiceConfigurationError e) { 119 assertTrue(e.getCause() instanceof AccessControlException); 120 } 121 } 122 123 @Test testConstructorUsingStreamNoPermission()124 public void testConstructorUsingStreamNoPermission() { 125 ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions()); 126 try { 127 sl.stream().map(Provider::get).count(); 128 assertTrue(false); 129 } catch (ServiceConfigurationError e) { 130 assertTrue(e.getCause() instanceof AccessControlException); 131 } 132 } 133 134 @Test testFactoryMethodUsingIteratorWithPermission()135 public void testFactoryMethodUsingIteratorWithPermission() { 136 ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM)); 137 S2 obj = sl.iterator().next(); 138 } 139 140 @Test testFactoryMethodUsingStreamWithPermission()141 public void testFactoryMethodUsingStreamWithPermission() { 142 ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM)); 143 assertTrue(sl.stream().map(Provider::get).count() == 1); 144 } 145 146 @Test testFactoryMethodUsingIteratorNoPermission()147 public void testFactoryMethodUsingIteratorNoPermission() { 148 ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions()); 149 try { 150 sl.iterator().next(); 151 assertTrue(false); 152 } catch (ServiceConfigurationError e) { 153 assertTrue(e.getCause() instanceof AccessControlException); 154 } 155 } 156 157 @Test testFactoryMethodUsingStreamNoPermission()158 public void testFactoryMethodUsingStreamNoPermission() { 159 ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions()); 160 try { 161 sl.stream().map(Provider::get).count(); 162 assertTrue(false); 163 } catch (ServiceConfigurationError e) { 164 assertTrue(e.getCause() instanceof AccessControlException); 165 } 166 } 167 168 @DataProvider(name = "failingServices") failingServices()169 public Object[][] failingServices() { 170 return new Object[][] { 171 { S3.class, P3.Error3.class }, 172 { S4.class, P4.Error4.class }, 173 { S5.class, P5.Error5.class }, 174 { S6.class, P6.Error6.class }, 175 }; 176 } 177 178 @Test(dataProvider = "failingServices") testFailingService(Class<?> service, Class<? extends Error> errorClass)179 public void testFailingService(Class<?> service, Class<? extends Error> errorClass) { 180 ServiceLoader<?> sl = ServiceLoader.load(service); 181 try { 182 sl.iterator().next(); 183 assertTrue(false); 184 } catch (ServiceConfigurationError e) { 185 assertTrue(e.getCause().getClass() == errorClass); 186 } 187 } 188 189 // service types and implementations 190 191 public static interface S1 { } 192 public static interface S2 { } 193 public static interface S3 { } 194 public static interface S4 { } 195 public static interface S5 { } 196 public static interface S6 { } 197 198 public static class P1 implements S1 { P1()199 public P1() { 200 AccessController.getContext().checkPermission(PERM); 201 } 202 } 203 public static class P2 implements S2 { P2()204 private P2() { 205 AccessController.getContext().checkPermission(PERM); 206 } provider()207 public static S2 provider() { 208 return new P2(); 209 } 210 } 211 212 public static class P3 implements S3 { 213 static class Error3 extends Error { } 214 static { Error3()215 if (1==1) throw new Error3(); // fail 216 } P3()217 public P3() { } 218 } 219 220 public static class P4 implements S4 { 221 static class Error4 extends Error { } 222 static { Error4()223 if (1==1) throw new Error4(); // fail 224 } provider()225 public static S4 provider() { 226 return new P4(); 227 } 228 } 229 230 public static class P5 implements S5 { 231 static class Error5 extends Error { } P5()232 public P5() { 233 throw new Error5(); // fail 234 } 235 } 236 237 public static class P6 implements S6 { 238 static class Error6 extends Error { } provider()239 public static S6 provider() { 240 throw new Error6(); // fail 241 } 242 } 243 } 244