1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18//package test.java.tests.api.javax.security.auth; 19package tests.api.javax.security.auth; 20 21import java.net.MalformedURLException; 22import java.net.URL; 23import java.security.AllPermission; 24import java.security.CodeSource; 25import java.security.Permission; 26import java.security.PermissionCollection; 27import java.security.Permissions; 28import java.security.Principal; 29import java.security.ProtectionDomain; 30import java.util.EnumSet; 31import java.util.Enumeration; 32import java.util.HashSet; 33import java.util.Set; 34 35import dalvik.annotation.TestLevel; 36import dalvik.annotation.TestTargetClass; 37import dalvik.annotation.TestTargetNew; 38 39import junit.framework.TestCase; 40 41import javax.security.auth.AuthPermission; 42import javax.security.auth.PrivateCredentialPermission; 43import javax.security.auth.Subject; 44import javax.security.auth.SubjectDomainCombiner; 45import javax.security.auth.x500.X500Principal; 46 47 48/** 49 * Tests for <code>SubjectDomainCombiner</code> class constructors and methods. 50 * 51 */ 52@TestTargetClass(SubjectDomainCombiner.class) 53public class SubjectDomainCombinerTest extends TestCase { 54 private final static boolean DEBUG = true; 55 56 SecurityManager old; 57 58 @Override 59 protected void setUp() throws Exception { 60 old = System.getSecurityManager(); 61 super.setUp(); 62 } 63 64 @Override 65 protected void tearDown() throws Exception { 66 System.setSecurityManager(old); 67 super.tearDown(); 68 } 69 70 71 /** 72 * @tests javax.security.auth.SubjectDomainCombiner#SubjectDomainCombiner(Subject subject) 73 */ 74 @TestTargetNew( 75 level = TestLevel.COMPLETE, 76 notes = "", 77 method = "SubjectDomainCombiner", 78 args = {Subject.class} 79 ) 80 public void test_Constructor_01() { 81 Subject s = new Subject(); 82 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 83 84 try { 85 assertEquals(s, c.getSubject()); 86 } catch(SecurityException se) { 87 88 } 89 } 90 91 /** 92 * @tests javax.security.auth.SubjectDomainCombiner#getSubject() 93 */ 94 @TestTargetNew( 95 level = TestLevel.COMPLETE, 96 notes = "Verifies that Subject associated with this SubjectDomainCombiner is returned", 97 method = "getSubject", 98 args = {} 99 ) 100 public void test_getSubject_01() { 101 class TestSecurityManager extends SecurityManager { 102 @Override 103 public void checkPermission(Permission permission) { 104 if (permission instanceof AuthPermission 105 && "getSubjectFromDomainCombiner".equals(permission.getName())) { 106 return; 107 } 108 super.checkPermission(permission); 109 } 110 } 111 112 TestSecurityManager sm = new TestSecurityManager(); 113 System.setSecurityManager(sm); 114 115 Subject s = new Subject(); 116 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 117 118 assertEquals(s, c.getSubject()); 119 } 120 121 122 /** 123 * @tests javax.security.auth.SubjectDomainCombiner#getSubject() 124 */ 125 @TestTargetNew( 126 level = TestLevel.COMPLETE, 127 notes = "SecurityException to be thrown if caller doesn't have permissions to get the Subject", 128 method = "getSubject", 129 args = {} 130 ) 131 public void test_getSubject_02() { 132 class TestSecurityManager extends SecurityManager { 133 @Override 134 public void checkPermission(Permission permission) { 135 if (permission instanceof AuthPermission 136 && "getSubjectFromDomainCombiner".equals(permission.getName())) { 137 throw new SecurityException(); 138 } 139 super.checkPermission(permission); 140 } 141 } 142 143 TestSecurityManager sm = new TestSecurityManager(); 144 System.setSecurityManager(sm); 145 146 Subject s = new Subject(); 147 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 148 149 try { 150 c.getSubject(); 151 fail("SecurityException expected"); 152 } catch(SecurityException se) { 153 // expected 154 } 155 } 156 157 protected final static String locationUrl = "http://localhost"; 158 159 160 protected final static String[] currentDomainX500names = { "CN=cd_name,OU=abc,O=corp,C=CH" }; 161 protected final static String[] currentDomainPerms = { "getStackTrace", 162 "setIO" 163 }; 164 165 protected final static String[] assignedDomainX500names = { "CN=ad_name,OU=def,O=corp,C=US" }; 166 protected final static String[] assignedDomainPerms = { "accessDeclaredMembers" 167 }; 168 169 protected final static String[] SubjectX500names = { "CN=s_user,OU=abc,O=corp,C=US", 170 "CN=s_user,OU=abc,O=corp,C=RU" }; 171 protected final static String subjectPubPerm1 = "readFileDescriptor"; 172 protected final static String subjectPvtPerm1 = "writeFileDescriptor"; 173 174 /** 175 * @tests javax.security.auth.SubjectDomainCombiner#combine() 176 */ 177 @TestTargetNew( 178 level = TestLevel.COMPLETE, 179 notes = "both currentDomains and assignedDomains are not null", 180 method = "combine", 181 args = {ProtectionDomain[].class, ProtectionDomain[].class} 182 ) 183 public void test_combine_01() { 184 185 URL url; 186 try { 187 url = new URL(locationUrl); 188 } catch (MalformedURLException mue) { 189 throw new Error(mue); 190 } 191 CodeSource cs = new CodeSource(url, (java.security.cert.Certificate[])null); 192 193 class MyClassLoader extends ClassLoader { 194 public MyClassLoader() { 195 super(); 196 } 197 } 198 199 ClassLoader current_pd_cl = new MyClassLoader() ; 200 ClassLoader assigned_pd_cl = new MyClassLoader() ; 201 202 // current domains 203 ProtectionDomain[] current_pd = createProtectionDomains(cs, current_pd_cl, currentDomainX500names, currentDomainPerms); 204 205 // assigned domains 206 ProtectionDomain[] assigned_pd = createProtectionDomains(cs, assigned_pd_cl, assignedDomainX500names, assignedDomainPerms); 207 208 // subject 209 Subject s = createSubject(); 210 211 // combine 212 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 213 214 ProtectionDomain[] r_pd = c.combine(current_pd, assigned_pd); 215 if(DEBUG) { 216 System.out.println("=========== c_pd"); 217 dumpPD(current_pd); 218 System.out.println("=========== a_pd"); 219 dumpPD(assigned_pd); 220 System.out.println("=========== r_pd"); 221 dumpPD(r_pd); 222 System.out.println("==========="); 223 } 224 225 for(int i = 0; i < r_pd.length; i++) { 226 ProtectionDomain pd = r_pd[i]; 227 // check CodeSource 228 assertTrue("code source mismatch", pd.getCodeSource().equals(cs)); 229 boolean cpd = false; 230 // check ClassLoader 231 if(pd.getClassLoader().equals(current_pd_cl)) { 232 cpd = true; 233 } else if(pd.getClassLoader().equals(assigned_pd_cl)) { 234 cpd = false; 235 } else { 236 fail("class loader mismatch"); 237 } 238 239 // check principals 240 Principal[] principals = pd.getPrincipals(); 241 String[] names; 242 if(cpd == true) names = SubjectX500names; 243 else names = assignedDomainX500names; 244 245 for(int j = 0; j < principals.length; j++) { 246 if(contains(names, principals[j].getName()) == false) 247 fail("principal mismatch (" + j +") " + principals[j].getName()); 248 } 249 250 // check permissions 251 PermissionCollection perms = pd.getPermissions(); 252 253 Enumeration<Permission> p = perms.elements(); 254 while(p.hasMoreElements()) { 255 Permission pp = p.nextElement(); 256 257 String pn = pp.getName(); 258 259 if(cpd == true) { 260 if(contains(currentDomainPerms, pn) == false) 261 fail("current domains permissions mismatch " + pn); 262 } else { 263 if(contains(assignedDomainPerms, pn) == false) 264 fail("assigned domains permissions mismatch " + pn); 265 } 266 } 267 } 268 } 269 270 /** 271 * @tests javax.security.auth.SubjectDomainCombiner#combine() 272 */ 273 @TestTargetNew( 274 level = TestLevel.COMPLETE, 275 notes = "assignedDomains is null", 276 method = "combine", 277 args = {ProtectionDomain[].class, ProtectionDomain[].class} 278 ) 279 public void test_combine_02() { 280 281 URL url; 282 try { 283 url = new URL(locationUrl); 284 } catch (MalformedURLException mue) { 285 throw new Error(mue); 286 } 287 CodeSource cs = new CodeSource(url, (java.security.cert.Certificate[])null); 288 289 class MyClassLoader extends ClassLoader { 290 public MyClassLoader() { 291 super(); 292 } 293 } 294 295 ClassLoader current_pd_cl = new MyClassLoader() ; 296 ClassLoader assigned_pd_cl = new MyClassLoader() ; 297 298 // current domains 299 ProtectionDomain[] current_pd = createProtectionDomains(cs, current_pd_cl, currentDomainX500names, currentDomainPerms); 300 301 // assigned domains 302 ProtectionDomain[] assigned_pd = null; 303 304 // subject 305 Subject s = createSubject(); 306 307 // combine 308 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 309 310 ProtectionDomain[] r_pd = c.combine(current_pd, assigned_pd); 311 if(DEBUG) { 312 System.out.println("=========== c_pd"); 313 dumpPD(current_pd); 314 System.out.println("=========== a_pd"); 315 dumpPD(assigned_pd); 316 System.out.println("=========== r_pd"); 317 dumpPD(r_pd); 318 System.out.println("==========="); 319 } 320 321 for(int i = 0; i < r_pd.length; i++) { 322 ProtectionDomain pd = r_pd[i]; 323 // check CodeSource 324 assertTrue("code source mismatch", pd.getCodeSource().equals(cs)); 325 326 // check ClassLoader 327 assertTrue("class loader mismatch", pd.getClassLoader().equals(current_pd_cl)); 328 329 // check principals 330 Principal[] principals = pd.getPrincipals(); 331 332 for(int j = 0; j < principals.length; j++) { 333 if(contains(SubjectX500names, principals[j].getName()) == false) 334 fail("principal mismatch (" + j +") " + principals[j].getName()); 335 } 336 337 // check permissions 338 PermissionCollection perms = pd.getPermissions(); 339 340 Enumeration<Permission> p = perms.elements(); 341 while(p.hasMoreElements()) { 342 Permission pp = p.nextElement(); 343 344 String pn = pp.getName(); 345 346 if(contains(currentDomainPerms, pn) == false) 347 fail("current domains permissions mismatch " + pn); 348 } 349 } 350 } 351 352 /** 353 * @tests javax.security.auth.SubjectDomainCombiner#combine() 354 */ 355 @TestTargetNew( 356 level = TestLevel.COMPLETE, 357 notes = "currentDomains is null", 358 method = "combine", 359 args = {ProtectionDomain[].class, ProtectionDomain[].class} 360 ) 361 public void test_combine_03() { 362 363 URL url; 364 try { 365 url = new URL(locationUrl); 366 } catch (MalformedURLException mue) { 367 throw new Error(mue); 368 } 369 CodeSource cs = new CodeSource(url, (java.security.cert.Certificate[])null); 370 371 class MyClassLoader extends ClassLoader { 372 public MyClassLoader() { 373 super(); 374 } 375 } 376 377 ClassLoader current_pd_cl = new MyClassLoader() ; 378 ClassLoader assigned_pd_cl = new MyClassLoader() ; 379 380 // current domains 381 ProtectionDomain[] current_pd = null; 382 383 // assigned domains 384 ProtectionDomain[] assigned_pd = createProtectionDomains(cs, assigned_pd_cl, assignedDomainX500names, assignedDomainPerms); 385 386 // subject 387 Subject s = createSubject(); 388 389 // combine 390 SubjectDomainCombiner c = new SubjectDomainCombiner(s); 391 392 ProtectionDomain[] r_pd = c.combine(current_pd, assigned_pd); 393 if(DEBUG) { 394 System.out.println("=========== c_pd"); 395 dumpPD(current_pd); 396 System.out.println("=========== a_pd"); 397 dumpPD(assigned_pd); 398 System.out.println("=========== r_pd"); 399 dumpPD(r_pd); 400 System.out.println("==========="); 401 } 402 403 for(int i = 0; i < r_pd.length; i++) { 404 ProtectionDomain pd = r_pd[i]; 405 // check CodeSource 406 assertTrue("code source mismatch", pd.getCodeSource().equals(cs)); 407 // check ClassLoader 408 assertTrue("class loader mismatch", pd.getClassLoader().equals(assigned_pd_cl)); 409 410 // check principals 411 Principal[] principals = pd.getPrincipals(); 412 for(int j = 0; j < principals.length; j++) { 413 if(contains(assignedDomainX500names, principals[j].getName()) == false) 414 fail("principal mismatch (" + j +") " + principals[j].getName()); 415 } 416 417 // check permissions 418 PermissionCollection perms = pd.getPermissions(); 419 420 Enumeration<Permission> p = perms.elements(); 421 while(p.hasMoreElements()) { 422 Permission pp = p.nextElement(); 423 424 String pn = pp.getName(); 425 426 if(contains(assignedDomainPerms, pn) == false) 427 fail("assigned domains permissions mismatch " + pn); 428 } 429 } 430 } 431 432 protected ProtectionDomain[] createProtectionDomains(CodeSource cs, ClassLoader cl, String[] names, String[] perms) { 433 ProtectionDomain[] pd = new ProtectionDomain[perms.length]; 434 Principal[] principals = new Principal[names.length]; 435 for(int i = 0; i < names.length; i++) { 436 principals[i] = new X500Principal(names[i]); 437 } 438 for(int i = 0; i < perms.length; i++) { 439 RuntimePermission rp = new RuntimePermission(perms[i]); 440 PermissionCollection pc = rp.newPermissionCollection(); 441 pc.add(rp); 442 pd[i] = new ProtectionDomain(cs, pc, cl, principals); 443 } 444 return pd; 445 } 446 447 protected Subject createSubject() { 448 // principal 449 HashSet<Principal> principal_set = new HashSet<Principal>(); 450 for(int i = 0; i < SubjectX500names.length; i++) 451 principal_set.add(new X500Principal(SubjectX500names[i])); 452 453 // public permissions 454 HashSet<Permission> pub_perms_set = new HashSet<Permission>(); 455 pub_perms_set.add(new RuntimePermission(subjectPubPerm1)); 456 457 // private permissions 458 HashSet<Permission> pvt_perms_set = new HashSet<Permission>(); 459 pvt_perms_set.add(new RuntimePermission(subjectPvtPerm1)); 460 461 Subject s = new Subject(false, principal_set, pub_perms_set, pvt_perms_set); 462 return s; 463 } 464 465 boolean contains(String[] arr, String val) { 466 for(int i = 0; i < arr.length; i++) 467 if(arr[i].compareTo(val) == 0) 468 return true; 469 return false; 470 } 471 472 private void dumpPD(ProtectionDomain[] arr) { 473 if(DEBUG) { 474 if(arr == null) return; 475 for(int i = 0; i < arr.length; i++) { 476 System.out.println(arr[i].getCodeSource().getLocation().toString()); 477 dumpPerms(arr[i].getPermissions()); 478 dumpPrincipals(arr[i].getPrincipals()); 479 } 480 } 481 } 482 483 private void dumpPerms(PermissionCollection perms) { 484 if(DEBUG) { 485 Enumeration<Permission> p = perms.elements(); 486 while(p.hasMoreElements()) { 487 Permission pp = p.nextElement(); 488 System.out.println(" " + pp.getName() + " " + pp.getActions()); 489 } 490 } 491 } 492 493 private void dumpPrincipals(Principal[] p) { 494 if(DEBUG) { 495 if(p == null) return; 496 for(int i = 0; i < p.length; i++) { 497 System.out.println(" " + p[i].getName()); 498 } 499 } 500 } 501 502} 503 504