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