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