1 /* 2 * Copyright (c) 2014, 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 8015081 27 * @summary javax.security.auth.Subject.toString() throws NPE 28 */ 29 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.ObjectInputStream; 33 import java.io.IOException; 34 import java.lang.Exception; 35 import java.security.Principal; 36 import java.util.Arrays; 37 import java.util.Collection; 38 import java.util.Collections; 39 import java.util.HashSet; 40 import java.util.TreeSet; 41 import java.util.LinkedList; 42 import java.util.List; 43 import java.util.Set; 44 import javax.management.remote.JMXPrincipal; 45 import javax.security.auth.Subject; 46 import javax.security.auth.x500.X500Principal; 47 import javax.security.auth.kerberos.KerberosPrincipal; 48 49 public class SubjectNullTests { 50 51 // Value templates for the constructor 52 private static Principal[] princVals = { 53 new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"), 54 new JMXPrincipal("Huckleberry Finn"), 55 new KerberosPrincipal("mtwain/author@LITERATURE.US") 56 }; 57 private static String[] pubVals = {"tsawyer", "hfinn", "mtwain"}; 58 private static String[] privVals = {"th3R!v3r", "oNth3R4ft", "5Cl3M3nz"}; 59 60 // Templates for collection-based modifiers for the Subject 61 private static Principal[] tmplAddPrincs = { 62 new X500Principal("CN=John Doe, O=Bogus Corp."), 63 new KerberosPrincipal("jdoe/admin@BOGUSCORP.COM") 64 }; 65 private static String[] tmplAddPubVals = {"jdoe", "djoe"}; 66 private static String[] tmplAddPrvVals = {"b4dpa55w0rd", "pass123"}; 67 68 /** 69 * Construct a subject, and optionally place a null in any one 70 * of the three Sets used to initialize a Subject's values 71 */ 72 private static Subject makeSubj(boolean nullPrinc, boolean nullPub, 73 boolean nullPriv) { 74 Set<Principal> setPrinc = 75 new HashSet<Principal>(Arrays.asList(princVals)); 76 Set<String> setPubCreds = new HashSet<String>(Arrays.asList(pubVals)); 77 Set<String> setPrvCreds = new HashSet<String>(Arrays.asList(privVals)); 78 79 if (nullPrinc) { 80 setPrinc.add(null); 81 } 82 83 if (nullPub) { 84 setPubCreds.add(null); 85 } 86 87 if (nullPriv) { 88 setPrvCreds.add(null); 89 } 90 91 return (new Subject(false, setPrinc, setPubCreds, setPrvCreds)); 92 } 93 94 /** 95 * Provide a simple interface for abstracting collection-on-collection 96 * functions 97 */ 98 public interface Function { 99 boolean execCollection(Set<?> subjSet, Collection<?> actorData); 100 } 101 102 public static final Function methAdd = new Function() { 103 public boolean execCollection(Set<?> subjSet, Collection<?> actorData) { 104 return subjSet.addAll((Collection)actorData); 105 } 106 }; 107 108 public static final Function methContains = new Function() { 109 public boolean execCollection(Set<?> subjSet, Collection<?> actorData) { 110 return subjSet.containsAll(actorData); 111 } 112 }; 113 114 public static final Function methRemove = new Function() { 115 public boolean execCollection(Set<?> subjSet, Collection<?> actorData) { 116 return subjSet.removeAll(actorData); 117 } 118 }; 119 120 public static final Function methRetain = new Function() { 121 public boolean execCollection(Set<?> subjSet, Collection<?> actorData) { 122 return subjSet.retainAll(actorData); 123 } 124 }; 125 126 /** 127 * Run a test using a specified Collection method upon a Subject's 128 * SecureSet fields. This method expects NullPointerExceptions 129 * to be thrown, and throws RuntimeException when the operation 130 * succeeds 131 */ 132 private static void nullTestCollection(Function meth, Set<?> subjSet, 133 Collection<?> actorData) { 134 try { 135 meth.execCollection(subjSet, actorData); 136 throw new RuntimeException("Failed to throw NullPointerException"); 137 } catch (NullPointerException npe) { 138 System.out.println("Caught expected NullPointerException [PASS]"); 139 } 140 } 141 142 /** 143 * Run a test using a specified Collection method upon a Subject's 144 * SecureSet fields. This method expects the function and arguments 145 * passed in to complete without exception. It returns false 146 * if either an exception occurs or the result of the operation is 147 * false. 148 */ 149 private static boolean validTestCollection(Function meth, Set<?> subjSet, 150 Collection<?> actorData) { 151 boolean result = false; 152 153 try { 154 result = meth.execCollection(subjSet, actorData); 155 } catch (Exception exc) { 156 System.out.println("Caught exception " + exc); 157 } 158 159 return result; 160 } 161 162 /** 163 * Deserialize an object from a file. 164 * 165 * @param type The {@code Class} that the serialized file is supposed 166 * to contain. 167 * @param fileName The name of the file to be deserialized. 168 * 169 * @return An object of the type specified in the {@code type} parameter 170 */ 171 private static <T> T deserializeFile(Class type, String fileName) 172 throws IOException, ClassNotFoundException { 173 File fileObj = new File(System.getProperty("test.src", "."), fileName); 174 FileInputStream fis = new FileInputStream(fileObj); 175 ObjectInputStream ois = new ObjectInputStream(fis); 176 177 T newObj = (T)ois.readObject(); 178 ois.close(); 179 fis.close(); 180 181 return newObj; 182 } 183 184 private static void testCTOR() { 185 System.out.println("------ constructor ------"); 186 187 try { 188 // Case 1: Create a subject with a null principal 189 // Expected result: NullPointerException 190 Subject mtSubj = makeSubj(true, false, false); 191 throw new RuntimeException( 192 "constructor [principal w/ null]: Failed to throw NPE"); 193 } catch (NullPointerException npe) { 194 System.out.println("constructor [principal w/ null]: " + 195 "NullPointerException [PASS]"); 196 } 197 198 try { 199 // Case 2: Create a subject with a null public credential element 200 // Expected result: NullPointerException 201 Subject mtSubj = makeSubj(false, true, false); 202 throw new RuntimeException( 203 "constructor [pub cred w/ null]: Failed to throw NPE"); 204 } catch (NullPointerException npe) { 205 System.out.println("constructor [pub cred w/ null]: " + 206 "NullPointerException [PASS]"); 207 } 208 209 try { 210 // Case 3: Create a subject with a null private credential element 211 // Expected result: NullPointerException 212 Subject mtSubj = makeSubj(false, false, true); 213 throw new RuntimeException( 214 "constructor [priv cred w/ null]: Failed to throw NPE"); 215 } catch (NullPointerException npe) { 216 System.out.println("constructor [priv cred w/ null]: " + 217 "NullPointerException [PASS]"); 218 } 219 220 // Case 4: Create a new subject using the principals, public 221 // and private credentials from another well-formed subject 222 // Expected result: Successful construction 223 Subject srcSubj = makeSubj(false, false, false); 224 Subject mtSubj = new Subject(false, srcSubj.getPrincipals(), 225 srcSubj.getPublicCredentials(), 226 srcSubj.getPrivateCredentials()); 227 System.out.println("Construction from another well-formed Subject's " + 228 "principals/creds [PASS]"); 229 } 230 231 private static void testDeserialize() throws Exception { 232 System.out.println("------ deserialize -----"); 233 234 Subject subj = null; 235 Set<Principal> prin = null; 236 237 // Case 1: positive deserialization test of a Subject 238 // Expected result: well-formed Subject 239 subj = deserializeFile(Subject.class, "SubjNoNull.bin"); 240 System.out.println("Positive deserialization test (Subject) passed"); 241 242 // Case 2: positive deserialization test of a SecureSet 243 // Expected result: well-formed Set 244 prin = deserializeFile(Set.class, "PrinNoNull.bin"); 245 System.out.println("Positive deserialization test (SecureSet) passed"); 246 247 System.out.println( 248 "* Testing deserialization with null-poisoned objects"); 249 // Case 3: deserialization test of a null-poisoned Subject 250 // Expected result: NullPointerException 251 try { 252 subj = deserializeFile(Subject.class, "SubjWithNull.bin"); 253 throw new RuntimeException("Failed to throw NullPointerException"); 254 } catch (NullPointerException npe) { 255 System.out.println("Caught expected NullPointerException [PASS]"); 256 } 257 258 // Case 4: deserialization test of a null-poisoned SecureSet 259 // Expected result: NullPointerException 260 try { 261 prin = deserializeFile(Set.class, "PrinWithNull.bin"); 262 throw new RuntimeException("Failed to throw NullPointerException"); 263 } catch (NullPointerException npe) { 264 System.out.println("Caught expected NullPointerException [PASS]"); 265 } 266 } 267 268 private static void testAdd() { 269 System.out.println("------ add() ------"); 270 // Create a well formed subject 271 Subject mtSubj = makeSubj(false, false, false); 272 273 try { 274 // Case 1: Attempt to add null values to principal 275 // Expected result: NullPointerException 276 mtSubj.getPrincipals().add(null); 277 throw new RuntimeException( 278 "PRINCIPAL add(null): Failed to throw NPE"); 279 } catch (NullPointerException npe) { 280 System.out.println( 281 "PRINCIPAL add(null): NullPointerException [PASS]"); 282 } 283 284 try { 285 // Case 2: Attempt to add null into the public creds 286 // Expected result: NullPointerException 287 mtSubj.getPublicCredentials().add(null); 288 throw new RuntimeException( 289 "PUB CRED add(null): Failed to throw NPE"); 290 } catch (NullPointerException npe) { 291 System.out.println( 292 "PUB CRED add(null): NullPointerException [PASS]"); 293 } 294 295 try { 296 // Case 3: Attempt to add null into the private creds 297 // Expected result: NullPointerException 298 mtSubj.getPrivateCredentials().add(null); 299 throw new RuntimeException( 300 "PRIV CRED add(null): Failed to throw NPE"); 301 } catch (NullPointerException npe) { 302 System.out.println( 303 "PRIV CRED add(null): NullPointerException [PASS]"); 304 } 305 } 306 307 private static void testRemove() { 308 System.out.println("------ remove() ------"); 309 // Create a well formed subject 310 Subject mtSubj = makeSubj(false, false, false); 311 312 try { 313 // Case 1: Attempt to remove null values from principal 314 // Expected result: NullPointerException 315 mtSubj.getPrincipals().remove(null); 316 throw new RuntimeException( 317 "PRINCIPAL remove(null): Failed to throw NPE"); 318 } catch (NullPointerException npe) { 319 System.out.println( 320 "PRINCIPAL remove(null): NullPointerException [PASS]"); 321 } 322 323 try { 324 // Case 2: Attempt to remove null from the public creds 325 // Expected result: NullPointerException 326 mtSubj.getPublicCredentials().remove(null); 327 throw new RuntimeException( 328 "PUB CRED remove(null): Failed to throw NPE"); 329 } catch (NullPointerException npe) { 330 System.out.println( 331 "PUB CRED remove(null): NullPointerException [PASS]"); 332 } 333 334 try { 335 // Case 3: Attempt to remove null from the private creds 336 // Expected result: NullPointerException 337 mtSubj.getPrivateCredentials().remove(null); 338 throw new RuntimeException( 339 "PRIV CRED remove(null): Failed to throw NPE"); 340 } catch (NullPointerException npe) { 341 System.out.println( 342 "PRIV CRED remove(null): NullPointerException [PASS]"); 343 } 344 } 345 346 private static void testContains() { 347 System.out.println("------ contains() ------"); 348 // Create a well formed subject 349 Subject mtSubj = makeSubj(false, false, false); 350 351 try { 352 // Case 1: Attempt to check for null values in principals 353 // Expected result: NullPointerException 354 mtSubj.getPrincipals().contains(null); 355 throw new RuntimeException( 356 "PRINCIPAL contains(null): Failed to throw NPE"); 357 } catch (NullPointerException npe) { 358 System.out.println( 359 "PRINCIPAL contains(null): NullPointerException [PASS]"); 360 } 361 362 try { 363 // Case 2: Attempt to check for null in public creds 364 // Expected result: NullPointerException 365 mtSubj.getPublicCredentials().contains(null); 366 throw new RuntimeException( 367 "PUB CRED contains(null): Failed to throw NPE"); 368 } catch (NullPointerException npe) { 369 System.out.println( 370 "PUB CRED contains(null): NullPointerException [PASS]"); 371 } 372 373 try { 374 // Case 3: Attempt to check for null in private creds 375 // Expected result: NullPointerException 376 mtSubj.getPrivateCredentials().contains(null); 377 throw new RuntimeException( 378 "PRIV CRED contains(null): Failed to throw NPE"); 379 } catch (NullPointerException npe) { 380 System.out.println( 381 "PRIV CRED contains(null): NullPointerException [PASS]"); 382 } 383 } 384 385 private static void testAddAll() { 386 // Create a well formed subject and additional collections 387 Subject mtSubj = makeSubj(false, false, false); 388 Set<Principal> morePrincs = new HashSet<>(Arrays.asList(tmplAddPrincs)); 389 Set<Object> morePubVals = new HashSet<>(Arrays.asList(tmplAddPubVals)); 390 Set<Object> morePrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals)); 391 392 // Run one success test for each Subject family to verify the 393 // overloaded method works as intended. 394 Set<Principal> setPrin = mtSubj.getPrincipals(); 395 Set<Object> setPubCreds = mtSubj.getPublicCredentials(); 396 Set<Object> setPrvCreds = mtSubj.getPrivateCredentials(); 397 int prinOrigSize = setPrin.size(); 398 int pubOrigSize = setPubCreds.size(); 399 int prvOrigSize = setPrvCreds.size(); 400 401 System.out.println("------ addAll() -----"); 402 403 // Add the new members, then check the resulting size of the 404 // Subject attributes to verify they've increased by the proper 405 // amounts. 406 if ((validTestCollection(methAdd, setPrin, morePrincs) != true) || 407 (setPrin.size() != prinOrigSize + morePrincs.size())) 408 { 409 throw new RuntimeException("Failed addAll() on principals"); 410 } 411 if ((validTestCollection(methAdd, setPubCreds, 412 morePubVals) != true) || 413 (setPubCreds.size() != pubOrigSize + morePubVals.size())) 414 { 415 throw new RuntimeException("Failed addAll() on public creds"); 416 } 417 if ((validTestCollection(methAdd, setPrvCreds, 418 morePrvVals) != true) || 419 (setPrvCreds.size() != prvOrigSize + morePrvVals.size())) 420 { 421 throw new RuntimeException("Failed addAll() on private creds"); 422 } 423 System.out.println("Positive addAll() test passed"); 424 425 // Now add null elements into each container, then retest 426 morePrincs.add(null); 427 morePubVals.add(null); 428 morePrvVals.add(null); 429 430 System.out.println("* Testing addAll w/ null values on Principals"); 431 nullTestCollection(methAdd, mtSubj.getPrincipals(), null); 432 nullTestCollection(methAdd, mtSubj.getPrincipals(), morePrincs); 433 434 System.out.println("* Testing addAll w/ null values on Public Creds"); 435 nullTestCollection(methAdd, mtSubj.getPublicCredentials(), null); 436 nullTestCollection(methAdd, mtSubj.getPublicCredentials(), 437 morePubVals); 438 439 System.out.println("* Testing addAll w/ null values on Private Creds"); 440 nullTestCollection(methAdd, mtSubj.getPrivateCredentials(), null); 441 nullTestCollection(methAdd, mtSubj.getPrivateCredentials(), 442 morePrvVals); 443 } 444 445 private static void testRemoveAll() { 446 // Create a well formed subject and additional collections 447 Subject mtSubj = makeSubj(false, false, false); 448 Set<Principal> remPrincs = new HashSet<>(); 449 Set<Object> remPubVals = new HashSet<>(); 450 Set<Object> remPrvVals = new HashSet<>(); 451 452 remPrincs.add(new KerberosPrincipal("mtwain/author@LITERATURE.US")); 453 remPubVals.add("mtwain"); 454 remPrvVals.add("5Cl3M3nz"); 455 456 // Run one success test for each Subject family to verify the 457 // overloaded method works as intended. 458 Set<Principal> setPrin = mtSubj.getPrincipals(); 459 Set<Object> setPubCreds = mtSubj.getPublicCredentials(); 460 Set<Object> setPrvCreds = mtSubj.getPrivateCredentials(); 461 int prinOrigSize = setPrin.size(); 462 int pubOrigSize = setPubCreds.size(); 463 int prvOrigSize = setPrvCreds.size(); 464 465 System.out.println("------ removeAll() -----"); 466 467 // Remove the specified members, then check the resulting size of the 468 // Subject attributes to verify they've decreased by the proper 469 // amounts. 470 if ((validTestCollection(methRemove, setPrin, remPrincs) != true) || 471 (setPrin.size() != prinOrigSize - remPrincs.size())) 472 { 473 throw new RuntimeException("Failed removeAll() on principals"); 474 } 475 if ((validTestCollection(methRemove, setPubCreds, 476 remPubVals) != true) || 477 (setPubCreds.size() != pubOrigSize - remPubVals.size())) 478 { 479 throw new RuntimeException("Failed removeAll() on public creds"); 480 } 481 if ((validTestCollection(methRemove, setPrvCreds, 482 remPrvVals) != true) || 483 (setPrvCreds.size() != prvOrigSize - remPrvVals.size())) 484 { 485 throw new RuntimeException("Failed removeAll() on private creds"); 486 } 487 System.out.println("Positive removeAll() test passed"); 488 489 // Now add null elements into each container, then retest 490 remPrincs.add(null); 491 remPubVals.add(null); 492 remPrvVals.add(null); 493 494 System.out.println("* Testing removeAll w/ null values on Principals"); 495 nullTestCollection(methRemove, mtSubj.getPrincipals(), null); 496 nullTestCollection(methRemove, mtSubj.getPrincipals(), remPrincs); 497 498 System.out.println( 499 "* Testing removeAll w/ null values on Public Creds"); 500 nullTestCollection(methRemove, mtSubj.getPublicCredentials(), null); 501 nullTestCollection(methRemove, mtSubj.getPublicCredentials(), 502 remPubVals); 503 504 System.out.println( 505 "* Testing removeAll w/ null values on Private Creds"); 506 nullTestCollection(methRemove, mtSubj.getPrivateCredentials(), null); 507 nullTestCollection(methRemove, mtSubj.getPrivateCredentials(), 508 remPrvVals); 509 } 510 511 private static void testContainsAll() { 512 // Create a well formed subject and additional collections 513 Subject mtSubj = makeSubj(false, false, false); 514 Set<Principal> testPrincs = new HashSet<>(Arrays.asList(princVals)); 515 Set<Object> testPubVals = new HashSet<>(Arrays.asList(pubVals)); 516 Set<Object> testPrvVals = new HashSet<>(Arrays.asList(privVals)); 517 518 System.out.println("------ containsAll() -----"); 519 520 // Run one success test for each Subject family to verify the 521 // overloaded method works as intended. 522 if ((validTestCollection(methContains, mtSubj.getPrincipals(), 523 testPrincs) == false) && 524 (validTestCollection(methContains, mtSubj.getPublicCredentials(), 525 testPubVals) == false) && 526 (validTestCollection(methContains, 527 mtSubj.getPrivateCredentials(), testPrvVals) == false)) { 528 throw new RuntimeException("Valid containsAll() check failed"); 529 } 530 System.out.println("Positive containsAll() test passed"); 531 532 // Now let's add a null into each collection and watch the fireworks. 533 testPrincs.add(null); 534 testPubVals.add(null); 535 testPrvVals.add(null); 536 537 System.out.println( 538 "* Testing containsAll w/ null values on Principals"); 539 nullTestCollection(methContains, mtSubj.getPrincipals(), null); 540 nullTestCollection(methContains, mtSubj.getPrincipals(), testPrincs); 541 542 System.out.println( 543 "* Testing containsAll w/ null values on Public Creds"); 544 nullTestCollection(methContains, mtSubj.getPublicCredentials(), 545 null); 546 nullTestCollection(methContains, mtSubj.getPublicCredentials(), 547 testPubVals); 548 549 System.out.println( 550 "* Testing containsAll w/ null values on Private Creds"); 551 nullTestCollection(methContains, mtSubj.getPrivateCredentials(), 552 null); 553 nullTestCollection(methContains, mtSubj.getPrivateCredentials(), 554 testPrvVals); 555 } 556 557 private static void testRetainAll() { 558 // Create a well formed subject and additional collections 559 Subject mtSubj = makeSubj(false, false, false); 560 Set<Principal> remPrincs = new HashSet<>(Arrays.asList(tmplAddPrincs)); 561 Set<Object> remPubVals = new HashSet<>(Arrays.asList(tmplAddPubVals)); 562 Set<Object> remPrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals)); 563 564 // Add in values that exist within the Subject 565 remPrincs.add(princVals[2]); 566 remPubVals.add(pubVals[2]); 567 remPrvVals.add(privVals[2]); 568 569 // Run one success test for each Subject family to verify the 570 // overloaded method works as intended. 571 Set<Principal> setPrin = mtSubj.getPrincipals(); 572 Set<Object> setPubCreds = mtSubj.getPublicCredentials(); 573 Set<Object> setPrvCreds = mtSubj.getPrivateCredentials(); 574 int prinOrigSize = setPrin.size(); 575 int pubOrigSize = setPubCreds.size(); 576 int prvOrigSize = setPrvCreds.size(); 577 578 System.out.println("------ retainAll() -----"); 579 580 // Retain the specified members (those that exist in the Subject) 581 // and validate the results. 582 if (validTestCollection(methRetain, setPrin, remPrincs) == false || 583 setPrin.size() != 1 || setPrin.contains(princVals[2]) == false) 584 { 585 throw new RuntimeException("Failed retainAll() on principals"); 586 } 587 588 if (validTestCollection(methRetain, setPubCreds, 589 remPubVals) == false || 590 setPubCreds.size() != 1 || 591 setPubCreds.contains(pubVals[2]) == false) 592 { 593 throw new RuntimeException("Failed retainAll() on public creds"); 594 } 595 if (validTestCollection(methRetain, setPrvCreds, 596 remPrvVals) == false || 597 setPrvCreds.size() != 1 || 598 setPrvCreds.contains(privVals[2]) == false) 599 { 600 throw new RuntimeException("Failed retainAll() on private creds"); 601 } 602 System.out.println("Positive retainAll() test passed"); 603 604 // Now add null elements into each container, then retest 605 remPrincs.add(null); 606 remPubVals.add(null); 607 remPrvVals.add(null); 608 609 System.out.println("* Testing retainAll w/ null values on Principals"); 610 nullTestCollection(methRetain, mtSubj.getPrincipals(), null); 611 nullTestCollection(methRetain, mtSubj.getPrincipals(), remPrincs); 612 613 System.out.println( 614 "* Testing retainAll w/ null values on Public Creds"); 615 nullTestCollection(methRetain, mtSubj.getPublicCredentials(), null); 616 nullTestCollection(methRetain, mtSubj.getPublicCredentials(), 617 remPubVals); 618 619 System.out.println( 620 "* Testing retainAll w/ null values on Private Creds"); 621 nullTestCollection(methRetain, mtSubj.getPrivateCredentials(), null); 622 nullTestCollection(methRetain, mtSubj.getPrivateCredentials(), 623 remPrvVals); 624 } 625 626 private static void testIsEmpty() { 627 Subject populatedSubj = makeSubj(false, false, false); 628 Subject emptySubj = new Subject(); 629 630 System.out.println("------ isEmpty() -----"); 631 632 if (populatedSubj.getPrincipals().isEmpty()) { 633 throw new RuntimeException( 634 "Populated Subject Principals incorrectly returned empty"); 635 } 636 if (emptySubj.getPrincipals().isEmpty() == false) { 637 throw new RuntimeException( 638 "Empty Subject Principals incorrectly returned non-empty"); 639 } 640 System.out.println("isEmpty() test passed"); 641 } 642 643 private static void testSecureSetEquals() { 644 System.out.println("------ SecureSet.equals() -----"); 645 646 Subject subj = makeSubj(false, false, false); 647 648 // Case 1: null comparison [expect false] 649 if (subj.getPublicCredentials().equals(null) != false) { 650 throw new RuntimeException( 651 "equals(null) incorrectly returned true"); 652 } 653 654 // Case 2: Self-comparison [expect true] 655 Set<Principal> princs = subj.getPrincipals(); 656 princs.equals(subj.getPrincipals()); 657 658 // Case 3: Comparison with non-Set type [expect false] 659 List<Principal> listPrinc = 660 new LinkedList<Principal>(Arrays.asList(princVals)); 661 if (subj.getPublicCredentials().equals(listPrinc) != false) { 662 throw new RuntimeException( 663 "equals([Non-Set]) incorrectly returned true"); 664 } 665 666 // Case 4: SecureSets of differing sizes [expect false] 667 Subject subj1princ = new Subject(); 668 Subject subj2princ = new Subject(); 669 subj1princ.getPrincipals().add( 670 new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US")); 671 subj1princ.getPrincipals().add( 672 new X500Principal("CN=John Doe, O=Bogus Corp.")); 673 subj2princ.getPrincipals().add( 674 new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US")); 675 if (subj1princ.getPrincipals().equals( 676 subj2princ.getPrincipals()) != false) { 677 throw new RuntimeException( 678 "equals([differing sizes]) incorrectly returned true"); 679 } 680 681 // Case 5: Content equality test [expect true] 682 Set<Principal> equalSet = 683 new HashSet<Principal>(Arrays.asList(princVals)); 684 if (subj.getPrincipals().equals(equalSet) != true) { 685 throw new RuntimeException( 686 "equals([equivalent set]) incorrectly returned false"); 687 } 688 689 // Case 5: Content inequality test [expect false] 690 691 // Note: to not fall into the size inequality check the two 692 // sets need to have the same number of elements. 693 Set<Principal> inequalSet = 694 new HashSet<Principal>(Arrays.asList(tmplAddPrincs)); 695 inequalSet.add(new JMXPrincipal("Samuel Clemens")); 696 697 if (subj.getPrincipals().equals(inequalSet) != false) { 698 throw new RuntimeException( 699 "equals([equivalent set]) incorrectly returned false"); 700 } 701 System.out.println("SecureSet.equals() tests passed"); 702 } 703 704 private static void testToArray() { 705 System.out.println("------ toArray() -----"); 706 707 Subject subj = makeSubj(false, false, false); 708 709 // Case 1: no-parameter toArray with equality comparison 710 // Expected result: true 711 List<Object> alSubj = Arrays.asList(subj.getPrincipals().toArray()); 712 List<Principal> alPrincs = Arrays.asList(princVals); 713 714 if (alSubj.size() != alPrincs.size() || 715 alSubj.containsAll(alPrincs) != true) { 716 throw new RuntimeException( 717 "Unexpected inequality on returned toArray()"); 718 } 719 720 // Case 2: generic-type toArray where passed array is of sufficient 721 // size. 722 // Expected result: returned Array is reference-equal to input param 723 // and content equal to data used to construct the originating Subject. 724 Principal[] pBlock = new Principal[3]; 725 Principal[] pBlockRef = subj.getPrincipals().toArray(pBlock); 726 alSubj = Arrays.asList(pBlockRef); 727 728 if (pBlockRef != pBlock) { 729 throw new RuntimeException( 730 "Unexpected reference-inequality on returned toArray(T[])"); 731 } else if (alSubj.size() != alPrincs.size() || 732 alSubj.containsAll(alPrincs) != true) { 733 throw new RuntimeException( 734 "Unexpected content-inequality on returned toArray(T[])"); 735 } 736 737 // Case 3: generic-type toArray where passed array is of 738 // insufficient size. 739 // Expected result: returned Array is not reference-equal to 740 // input param but is content equal to data used to construct the 741 // originating Subject. 742 pBlock = new Principal[1]; 743 pBlockRef = subj.getPrincipals().toArray(pBlock); 744 alSubj = Arrays.asList(pBlockRef); 745 746 if (pBlockRef == pBlock) { 747 throw new RuntimeException( 748 "Unexpected reference-equality on returned toArray(T[])"); 749 } else if (alSubj.size() != alPrincs.size() || 750 alSubj.containsAll(alPrincs) != true) { 751 throw new RuntimeException( 752 "Unexpected content-inequality on returned toArray(T[])"); 753 } 754 System.out.println("toArray() tests passed"); 755 } 756 757 public static void main(String[] args) throws Exception { 758 759 testCTOR(); 760 761 testDeserialize(); 762 763 testAdd(); 764 765 testRemove(); 766 767 testContains(); 768 769 testAddAll(); 770 771 testRemoveAll(); 772 773 testContainsAll(); 774 775 testRetainAll(); 776 777 testIsEmpty(); 778 779 testSecureSetEquals(); 780 781 testToArray(); 782 } 783 }