1/*
2 * Copyright (c) 2004, 2013, 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 5037004
27 * @summary Frivolous ClassCastExceptions thrown by SubjectCodeSource.implies
28 * @modules java.base/sun.security.provider
29 * @run main/othervm Comparator
30 *
31 * Note:  if you want to see the java.security.debug output,
32 *        you can not simply set the system property.
33 *        you must run this test by hand and pass -Djava.security.debug=...
34 */
35
36import java.io.*;
37import java.security.*;
38import java.util.PropertyPermission;
39import javax.security.auth.Subject;
40import javax.security.auth.x500.X500Principal;
41
42import sun.security.provider.PolicyFile;
43import com.sun.security.auth.UnixPrincipal;
44import com.sun.security.auth.NTUserPrincipal;
45import com.sun.security.auth.SolarisPrincipal;
46
47public class Comparator {
48
49    private static final PropertyPermission FOO =
50                new PropertyPermission("foo", "read");
51    private static final PropertyPermission BAR =
52                new PropertyPermission("bar", "read");
53    private static final PropertyPermission FOOBAR =
54                new PropertyPermission("foobar", "read");
55    private static final PropertyPermission HELLO =
56                new PropertyPermission("hello", "read");
57    private static final PropertyPermission WORLD =
58                new PropertyPermission("world", "read");
59
60    private static final CodeSource cs =
61                new CodeSource(null, (java.security.cert.Certificate[])null);
62
63    private static final Principal[] p1 = new Principal[] {
64                                new UnixPrincipal("1") };
65
66    private static final Principal[] p2 = new Principal[] {
67                                new X500Principal("cn=2"),
68                                new NTUserPrincipal("2") };
69
70    private static final Principal[] p3 = new Principal[] {
71                                new UnixPrincipal("1"),
72                                new X500Principal("cn=2"),
73                                new NTUserPrincipal("2") };
74
75    private static final Principal[] p4 = new Principal[] {
76                                new UnixPrincipal("1"),
77                                new NTUserPrincipal("4") };
78
79    private static final Principal[] p5 = new Principal[] {
80                                new UnixPrincipal("1"),
81                                new X500Principal("cn=2"),
82                                new NTUserPrincipal("2"),
83                                new X500Principal("cn=x500") };
84
85    private static final Principal[] p6 = new Principal[] {
86                                new UnixPrincipal("1"),
87                                new NTUserPrincipal("4"),
88                                new X500Principal("cn=x500") };
89
90    private static final Principal[] badP = new Principal[] {
91                                new SolarisPrincipal("bad") };
92
93    public static class PCompare1 implements Principal {
94
95        private String name;
96
97        public PCompare1(String name) {
98            this.name = name;
99        }
100
101        @Override
102        public String getName() {
103            return name;
104        }
105
106        @Override
107        public boolean implies (Subject subject) {
108            if (subject.getPrincipals().contains(p1[0])) {
109                return true;
110            }
111            return false;
112        }
113    }
114
115    public static class PCompare2 implements Principal {
116        private String name;
117
118        public PCompare2(String name) {
119            this.name = name;
120        }
121
122        @Override
123        public String getName() {
124            return name;
125        }
126
127        @Override
128        public boolean implies (Subject subject) {
129            if (subject.getPrincipals().contains(p2[0]) &&
130                subject.getPrincipals().contains(p2[1])) {
131                return true;
132            }
133            return false;
134        }
135    }
136
137    public static class PCompare3 implements Principal {
138        private String name;
139
140        public PCompare3(String name) {
141            this.name = name;
142        }
143
144        @Override
145        public String getName() {
146            return name;
147        }
148
149        @Override
150        public boolean implies (Subject subject) {
151            return false;
152        }
153    }
154
155    public static void main(String[] args) throws Exception {
156
157        int testnum = 1;
158
159        // in case we run standalone
160        String policyDir = System.getProperty("test.src");
161        if (policyDir == null) {
162            policyDir = ".";
163        }
164
165        // do principal-only tests
166        System.setProperty("java.security.policy",
167                        "=" +
168                        policyDir +
169                        File.separatorChar +
170                        "Comparator.Principal.Policy");
171        PolicyFile policy = new PolicyFile();
172        testnum = doPrincipalTest(policy, testnum);
173        System.out.println("============ Principal Test Passed ============");
174
175        // do comparator-only tests
176        System.setProperty("java.security.policy",
177                        "=" +
178                        policyDir +
179                        File.separatorChar +
180                        "Comparator.Comparator.Policy");
181        policy = new PolicyFile();
182        testnum = doComparatorTest(policy, testnum);
183        System.out.println("============ Comparator Test Passed ============");
184
185        // combined principal/comparator tests
186        System.setProperty("java.security.policy",
187                        "=" +
188                        policyDir +
189                        File.separatorChar +
190                        "Comparator.Combined.Policy");
191        policy = new PolicyFile();
192        testnum = doCombinedTest(policy, testnum);
193        System.out.println("============ Combined Test Passed ============");
194    }
195
196    private static int doBadTest(PolicyFile policy, int testnum) {
197
198        // this principal is not in policy - should not match any policy grants
199        ProtectionDomain pd = new ProtectionDomain(cs, null, null, badP);
200        if (policy.implies(pd, FOO)) {
201            throw new SecurityException("test." + testnum + " failed");
202        }
203        testnum++;
204
205        // this principal is not in policy - should not match any policy grants
206        if (policy.implies(pd, BAR)) {
207            throw new SecurityException("test." + testnum + " failed");
208        }
209        testnum++;
210
211        // this principal is not in policy - should not match any policy grants
212        if (policy.implies(pd, FOOBAR)) {
213            throw new SecurityException("test." + testnum + " failed");
214        }
215        testnum++;
216
217        return testnum;
218    }
219
220    private static int doPrincipalTest(PolicyFile policy, int testnum) {
221
222        // security check against one principal should pass
223        ProtectionDomain pd = new ProtectionDomain(cs, null, null, p1);
224        if (!policy.implies(pd, FOO)) {
225            throw new SecurityException("test." + testnum + " failed");
226        }
227        testnum++;
228
229        // should not match BAR grant entry in policy
230        pd = new ProtectionDomain(cs, null, null, p1);
231        if (policy.implies(pd, BAR)) {
232            throw new SecurityException("test." + testnum + " failed");
233        }
234        testnum++;
235
236        // security check against two principals should pass
237        pd = new ProtectionDomain(cs, null, null, p2);
238        if (!policy.implies(pd, BAR)) {
239            throw new SecurityException("test." + testnum + " failed");
240        }
241        testnum++;
242
243        // should not match FOOBAR grant entry in policy
244        pd = new ProtectionDomain(cs, null, null, p1);
245        if (policy.implies(pd, FOOBAR)) {
246            throw new SecurityException("test." + testnum + " failed");
247        }
248        testnum++;
249
250        // should not match FOOBAR grant entry in policy
251        pd = new ProtectionDomain(cs, null, null, p2);
252        if (policy.implies(pd, FOOBAR)) {
253            throw new SecurityException("test." + testnum + " failed");
254        }
255        testnum++;
256
257        testnum = doBadTest(policy, testnum);
258
259        return testnum;
260    }
261
262    private static int doComparatorTest(PolicyFile policy, int testnum) {
263
264        // security check against one comparator should pass
265        ProtectionDomain pd = new ProtectionDomain(cs, null, null, p1);
266        if (!policy.implies(pd, FOO)) {
267            throw new SecurityException("test." + testnum + " failed");
268        }
269        testnum++;
270
271        // should not match BAR grant entry in policy
272        pd = new ProtectionDomain(cs, null, null, p1);
273        if (policy.implies(pd, BAR)) {
274            throw new SecurityException("test." + testnum + " failed");
275        }
276        testnum++;
277
278        // security check against two comparators should pass for FOO
279        pd = new ProtectionDomain(cs, null, null, p3);
280        if (!policy.implies(pd, FOO)) {
281            throw new SecurityException("test." + testnum + " failed");
282        }
283        testnum++;
284
285        // security check against two comparators should pass for BAR
286        pd = new ProtectionDomain(cs, null, null, p3);
287        if (!policy.implies(pd, BAR)) {
288            throw new SecurityException("test." + testnum + " failed");
289        }
290        testnum++;
291
292        // security check should fail against FOOBAR
293        pd = new ProtectionDomain(cs, null, null, p3);
294        if (policy.implies(pd, FOOBAR)) {
295            throw new SecurityException("test." + testnum + " failed");
296        }
297        testnum++;
298
299        testnum = doBadTest(policy, testnum);
300
301        return testnum;
302    }
303
304    private static int doCombinedTest(PolicyFile policy, int testnum) {
305
306        // security check against principal followed by comparator should pass
307        ProtectionDomain pd = new ProtectionDomain(cs, null, null, p3);
308        if (!policy.implies(pd, FOO)) {
309            throw new SecurityException("test." + testnum + " failed");
310        }
311        testnum++;
312
313        // should not match BAR grant entry in policy
314        pd = new ProtectionDomain(cs, null, null, p3);
315        if (policy.implies(pd, BAR)) {
316            throw new SecurityException("test." + testnum + " failed");
317        }
318        testnum++;
319
320        // security check against comparator followed by principal should pass
321        pd = new ProtectionDomain(cs, null, null, p4);
322        if (!policy.implies(pd, BAR)) {
323            throw new SecurityException("test." + testnum + " failed");
324        }
325        testnum++;
326
327        // should not match FOO grant entry in policy
328        pd = new ProtectionDomain(cs, null, null, p4);
329        if (policy.implies(pd, FOO)) {
330            throw new SecurityException("test." + testnum + " failed");
331        }
332        testnum++;
333
334        // security check against principal-principal-comparator should pass
335        pd = new ProtectionDomain(cs, null, null, p5);
336        if (!policy.implies(pd, HELLO)) {
337            throw new SecurityException("test." + testnum + " failed");
338        }
339        testnum++;
340
341        // should not match WORLD grant entry in policy
342        pd = new ProtectionDomain(cs, null, null, p5);
343        if (policy.implies(pd, WORLD)) {
344            throw new SecurityException("test." + testnum + " failed");
345        }
346        testnum++;
347
348        // security check against principal-principal-comparator should pass
349        pd = new ProtectionDomain(cs, null, null, p6);
350        if (!policy.implies(pd, WORLD)) {
351            throw new SecurityException("test." + testnum + " failed");
352        }
353        testnum++;
354
355        // should not match HELLO grant entry in policy
356        pd = new ProtectionDomain(cs, null, null, p6);
357        if (policy.implies(pd, HELLO)) {
358            throw new SecurityException("test." + testnum + " failed");
359        }
360        testnum++;
361
362        testnum = doBadTest(policy, testnum);
363
364        return testnum;
365    }
366}
367