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