1 7 8 package javax.security.auth; 9 10 import java.util.*; 11 import java.io.*; 12 import java.lang.reflect.*; 13 import java.text.MessageFormat ; 14 import java.security.AccessController ; 15 import java.security.AccessControlContext ; 16 import java.security.DomainCombiner ; 17 import java.security.Permission ; 18 import java.security.PermissionCollection ; 19 import java.security.Principal ; 20 import java.security.PrivilegedAction ; 21 import java.security.PrivilegedExceptionAction ; 22 import java.security.PrivilegedActionException ; 23 import java.security.ProtectionDomain ; 24 import sun.security.util.ResourcesMgr; 25 import sun.security.util.SecurityConstants; 26 27 84 public final class Subject implements java.io.Serializable { 85 86 private static final long serialVersionUID = -8308522755600156056L; 87 88 98 Set principals; 99 100 104 transient Set pubCredentials; 105 transient Set privCredentials; 106 107 112 private volatile boolean readOnly = false; 113 114 private static final int PRINCIPAL_SET = 1; 115 private static final int PUB_CREDENTIAL_SET = 2; 116 private static final int PRIV_CREDENTIAL_SET = 3; 117 118 135 public Subject() { 136 137 this.principals = Collections.synchronizedSet 138 (new SecureSet(this, PRINCIPAL_SET)); 139 this.pubCredentials = Collections.synchronizedSet 140 (new SecureSet(this, PUB_CREDENTIAL_SET)); 141 this.privCredentials = Collections.synchronizedSet 142 (new SecureSet(this, PRIV_CREDENTIAL_SET)); 143 } 144 145 180 public Subject(boolean readOnly, Set<? extends Principal > principals, 181 Set<?> pubCredentials, Set<?> privCredentials) 182 { 183 184 if (principals == null || 185 pubCredentials == null || 186 privCredentials == null) 187 throw new NullPointerException 188 (ResourcesMgr.getString("invalid null input(s)")); 189 190 this.principals = Collections.synchronizedSet(new SecureSet 191 (this, PRINCIPAL_SET, principals)); 192 this.pubCredentials = Collections.synchronizedSet(new SecureSet 193 (this, PUB_CREDENTIAL_SET, pubCredentials)); 194 this.privCredentials = Collections.synchronizedSet(new SecureSet 195 (this, PRIV_CREDENTIAL_SET, privCredentials)); 196 this.readOnly = readOnly; 197 } 198 199 219 public void setReadOnly() { 220 java.lang.SecurityManager sm = System.getSecurityManager(); 221 if (sm != null) { 222 sm.checkPermission(new AuthPermission ("setReadOnly")); 223 } 224 225 this.readOnly = true; 226 } 227 228 235 public boolean isReadOnly() { 236 return this.readOnly; 237 } 238 239 264 public static Subject getSubject(final AccessControlContext acc) { 265 266 java.lang.SecurityManager sm = System.getSecurityManager(); 267 if (sm != null) { 268 sm.checkPermission(new AuthPermission ("getSubject")); 269 } 270 271 if (acc == null) { 272 throw new NullPointerException (ResourcesMgr.getString 273 ("invalid null AccessControlContext provided")); 274 } 275 276 return (Subject )AccessController.doPrivileged 278 (new java.security.PrivilegedAction () { 279 public Object run() { 280 DomainCombiner dc = acc.getDomainCombiner(); 281 if (!(dc instanceof SubjectDomainCombiner )) 282 return null; 283 SubjectDomainCombiner sdc = (SubjectDomainCombiner )dc; 284 return sdc.getSubject(); 285 } 286 }); 287 } 288 289 321 public static Object doAs(final Subject subject, 322 final java.security.PrivilegedAction action) { 323 324 java.lang.SecurityManager sm = System.getSecurityManager(); 325 if (sm != null) { 326 sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); 327 } 328 if (action == null) 329 throw new NullPointerException 330 (ResourcesMgr.getString("invalid null action provided")); 331 332 final AccessControlContext currentAcc = AccessController.getContext(); 335 336 return java.security.AccessController.doPrivileged 338 (action, 339 createContext(subject, currentAcc)); 340 } 341 342 379 public static Object doAs(final Subject subject, 380 final java.security.PrivilegedExceptionAction action) 381 throws java.security.PrivilegedActionException { 382 383 java.lang.SecurityManager sm = System.getSecurityManager(); 384 if (sm != null) { 385 sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); 386 } 387 388 if (action == null) 389 throw new NullPointerException 390 (ResourcesMgr.getString("invalid null action provided")); 391 392 final AccessControlContext currentAcc = AccessController.getContext(); 394 395 return java.security.AccessController.doPrivileged 397 (action, 398 createContext(subject, currentAcc)); 399 } 400 401 433 public static Object doAsPrivileged(final Subject subject, 434 final java.security.PrivilegedAction action, 435 final java.security.AccessControlContext acc) { 436 437 java.lang.SecurityManager sm = System.getSecurityManager(); 438 if (sm != null) { 439 sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); 440 } 441 442 if (action == null) 443 throw new NullPointerException 444 (ResourcesMgr.getString("invalid null action provided")); 445 446 final AccessControlContext callerAcc = 449 (acc == null ? 450 new AccessControlContext (new ProtectionDomain [0]) : 451 acc); 452 453 return java.security.AccessController.doPrivileged 455 (action, 456 createContext(subject, callerAcc)); 457 } 458 459 496 public static Object doAsPrivileged(final Subject subject, 497 final java.security.PrivilegedExceptionAction action, 498 final java.security.AccessControlContext acc) 499 throws java.security.PrivilegedActionException { 500 501 java.lang.SecurityManager sm = System.getSecurityManager(); 502 if (sm != null) { 503 sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); 504 } 505 506 if (action == null) 507 throw new NullPointerException 508 (ResourcesMgr.getString("invalid null action provided")); 509 510 final AccessControlContext callerAcc = 512 (acc == null ? 513 new AccessControlContext (new ProtectionDomain [0]) : 514 acc); 515 516 return java.security.AccessController.doPrivileged 518 (action, 519 createContext(subject, callerAcc)); 520 } 521 522 private static AccessControlContext createContext(final Subject subject, 523 final AccessControlContext acc) { 524 525 526 return (AccessControlContext ) 527 java.security.AccessController.doPrivileged 528 (new java.security.PrivilegedAction () { 529 public Object run() { 530 if (subject == null) 531 return new AccessControlContext (acc, null); 532 else 533 return new AccessControlContext 534 (acc, 535 new SubjectDomainCombiner (subject)); 536 } 537 }); 538 } 539 540 555 public Set<Principal > getPrincipals() { 556 557 return principals; 560 } 561 562 584 public <T extends Principal > Set<T> getPrincipals(Class <T> c) { 585 586 if (c == null) 587 throw new NullPointerException 588 (ResourcesMgr.getString("invalid null Class provided")); 589 590 return new ClassSet(PRINCIPAL_SET, c); 593 } 594 595 609 public Set<Object > getPublicCredentials() { 610 611 return pubCredentials; 614 } 615 616 641 public Set<Object > getPrivateCredentials() { 642 643 651 return privCredentials; 654 } 655 656 678 public <T> Set<T> getPublicCredentials(Class <T> c) { 679 680 if (c == null) 681 throw new NullPointerException 682 (ResourcesMgr.getString("invalid null Class provided")); 683 684 return new ClassSet<T>(PUB_CREDENTIAL_SET, c); 687 } 688 689 715 public <T> Set<T> getPrivateCredentials(Class <T> c) { 716 717 725 if (c == null) 726 throw new NullPointerException 727 (ResourcesMgr.getString("invalid null Class provided")); 728 729 return new ClassSet<T>(PRIV_CREDENTIAL_SET, c); 732 } 733 734 755 public boolean equals(Object o) { 756 757 if (o == null) 758 return false; 759 760 if (this == o) 761 return true; 762 763 if (o instanceof Subject ) { 764 765 final Subject that = (Subject )o; 766 767 Set thatPrincipals; 769 synchronized(that.principals) { 770 thatPrincipals = new HashSet(that.principals); 772 } 773 if (!principals.equals(thatPrincipals)) { 774 return false; 775 } 776 777 Set thatPubCredentials; 778 synchronized(that.pubCredentials) { 779 thatPubCredentials = new HashSet(that.pubCredentials); 781 } 782 if (!pubCredentials.equals(thatPubCredentials)) { 783 return false; 784 } 785 786 Set thatPrivCredentials; 787 synchronized(that.privCredentials) { 788 thatPrivCredentials = new HashSet(that.privCredentials); 790 } 791 if (!privCredentials.equals(thatPrivCredentials)) { 792 return false; 793 } 794 return true; 795 } 796 return false; 797 } 798 799 806 public String toString() { 807 return toString(true); 808 } 809 810 815 String toString(boolean includePrivateCredentials) { 816 817 String s = new String (ResourcesMgr.getString("Subject:\n")); 818 String suffix = new String (); 819 820 synchronized(principals) { 821 Iterator pI = principals.iterator(); 822 while (pI.hasNext()) { 823 Principal p = (Principal )pI.next(); 824 suffix = suffix + ResourcesMgr.getString("\tPrincipal: ") + 825 p.toString() + ResourcesMgr.getString("\n"); 826 } 827 } 828 829 synchronized(pubCredentials) { 830 Iterator pI = pubCredentials.iterator(); 831 while (pI.hasNext()) { 832 Object o = pI.next(); 833 suffix = suffix + 834 ResourcesMgr.getString("\tPublic Credential: ") + 835 o.toString() + ResourcesMgr.getString("\n"); 836 } 837 } 838 839 if (includePrivateCredentials) { 840 synchronized(privCredentials) { 841 Iterator pI = privCredentials.iterator(); 842 while (pI.hasNext()) { 843 try { 844 Object o = pI.next(); 845 suffix += ResourcesMgr.getString 846 ("\tPrivate Credential: ") + 847 o.toString() + 848 ResourcesMgr.getString("\n"); 849 } catch (SecurityException se) { 850 suffix += ResourcesMgr.getString 851 ("\tPrivate Credential inaccessible\n"); 852 break; 853 } 854 } 855 } 856 } 857 return s + suffix; 858 } 859 860 870 public int hashCode() { 871 872 882 883 int hashCode = 0; 884 885 synchronized(principals) { 886 Iterator pIterator = principals.iterator(); 887 while (pIterator.hasNext()) { 888 Principal p = (Principal )pIterator.next(); 889 hashCode ^= p.hashCode(); 890 } 891 } 892 893 synchronized(pubCredentials) { 894 Iterator pubCIterator = pubCredentials.iterator(); 895 while (pubCIterator.hasNext()) { 896 hashCode ^= getCredHashCode(pubCIterator.next()); 897 } 898 } 899 return hashCode; 900 } 901 902 905 private int getCredHashCode(Object o) { 906 try { 907 return o.hashCode(); 908 } catch (IllegalStateException ise) { 909 return o.getClass().toString().hashCode(); 910 } 911 } 912 913 916 private void writeObject(java.io.ObjectOutputStream oos) 917 throws java.io.IOException { 918 synchronized(principals) { 919 oos.defaultWriteObject(); 920 } 921 } 922 923 926 private void readObject(java.io.ObjectInputStream s) 927 throws java.io.IOException , ClassNotFoundException { 928 929 s.defaultReadObject(); 930 931 this.pubCredentials = Collections.synchronizedSet 934 (new SecureSet(this, PUB_CREDENTIAL_SET)); 935 this.privCredentials = Collections.synchronizedSet 936 (new SecureSet(this, PRIV_CREDENTIAL_SET)); 937 } 938 939 944 private static class SecureSet 945 extends AbstractSet 946 implements java.io.Serializable { 947 948 private static final long serialVersionUID = 7911754171111800359L; 949 950 954 private static final ObjectStreamField[] serialPersistentFields = { 955 new ObjectStreamField("this$0", Subject .class), 956 new ObjectStreamField("elements", LinkedList.class), 957 new ObjectStreamField("which", int.class) 958 }; 959 960 Subject subject; 961 LinkedList elements; 962 963 973 private int which; 974 975 SecureSet(Subject subject, int which) { 976 this.subject = subject; 977 this.which = which; 978 this.elements = new LinkedList(); 979 } 980 981 SecureSet(Subject subject, int which, Set set) { 982 this.subject = subject; 983 this.which = which; 984 this.elements = new LinkedList(set); 985 } 986 987 public int size() { 988 return elements.size(); 989 } 990 991 public Iterator iterator() { 992 final LinkedList list = elements; 993 return new Iterator() { 994 ListIterator i = list.listIterator(0); 995 996 public boolean hasNext() {return i.hasNext();} 997 998 public Object next() { 999 if (which != Subject.PRIV_CREDENTIAL_SET) { 1000 return i.next(); 1001 } 1002 1003 SecurityManager sm = System.getSecurityManager(); 1004 if (sm != null) { 1005 try { 1006 sm.checkPermission(new PrivateCredentialPermission 1007 (list.get(i.nextIndex()).getClass().getName(), 1008 subject.getPrincipals())); 1009 } catch (SecurityException se) { 1010 i.next(); 1011 throw (se); 1012 } 1013 } 1014 return i.next(); 1015 } 1016 1017 public void remove() { 1018 1019 if (subject.isReadOnly()) { 1020 throw new IllegalStateException (ResourcesMgr.getString 1021 ("Subject is read-only")); 1022 } 1023 1024 java.lang.SecurityManager sm = System.getSecurityManager(); 1025 if (sm != null) { 1026 switch (which) { 1027 case Subject.PRINCIPAL_SET: 1028 sm.checkPermission(new AuthPermission 1029 ("modifyPrincipals")); 1030 break; 1031 case Subject.PUB_CREDENTIAL_SET: 1032 sm.checkPermission(new AuthPermission 1033 ("modifyPublicCredentials")); 1034 break; 1035 default: 1036 sm.checkPermission(new AuthPermission 1037 ("modifyPrivateCredentials")); 1038 break; 1039 } 1040 } 1041 i.remove(); 1042 } 1043 }; 1044 } 1045 1046 public boolean add(Object o) { 1047 1048 if (subject.isReadOnly()) { 1049 throw new IllegalStateException 1050 (ResourcesMgr.getString("Subject is read-only")); 1051 } 1052 1053 java.lang.SecurityManager sm = System.getSecurityManager(); 1054 if (sm != null) { 1055 switch (which) { 1056 case Subject.PRINCIPAL_SET: 1057 sm.checkPermission 1058 (new AuthPermission ("modifyPrincipals")); 1059 break; 1060 case Subject.PUB_CREDENTIAL_SET: 1061 sm.checkPermission 1062 (new AuthPermission ("modifyPublicCredentials")); 1063 break; 1064 default: 1065 sm.checkPermission 1066 (new AuthPermission ("modifyPrivateCredentials")); 1067 break; 1068 } 1069 } 1070 1071 switch (which) { 1072 case Subject.PRINCIPAL_SET: 1073 if (!(o instanceof Principal )) { 1074 throw new SecurityException (ResourcesMgr.getString 1075 ("attempting to add an object which is not an " + 1076 "instance of java.security.Principal to a " + 1077 "Subject's Principal Set")); 1078 } 1079 break; 1080 default: 1081 break; 1083 } 1084 1085 if (!elements.contains(o)) 1087 return elements.add(o); 1088 else 1089 return false; 1090 } 1091 1092 public boolean remove(Object o) { 1093 1094 final Iterator e = iterator(); 1095 while (e.hasNext()) { 1096 Object next; 1097 if (which != Subject.PRIV_CREDENTIAL_SET) { 1098 next = e.next(); 1099 } else { 1100 next = (Object )java.security.AccessController.doPrivileged 1101 (new java.security.PrivilegedAction () { 1102 public Object run() { 1103 return e.next(); 1104 } 1105 }); 1106 } 1107 1108 if (next == null) { 1109 if (o == null) { 1110 e.remove(); 1111 return true; 1112 } 1113 } else if (next.equals(o)) { 1114 e.remove(); 1115 return true; 1116 } 1117 } 1118 return false; 1119 } 1120 1121 public boolean contains(Object o) { 1122 final Iterator e = iterator(); 1123 while (e.hasNext()) { 1124 Object next; 1125 if (which != Subject.PRIV_CREDENTIAL_SET) { 1126 next = e.next(); 1127 } else { 1128 1129 1135 SecurityManager sm = System.getSecurityManager(); 1136 if (sm != null) { 1137 sm.checkPermission(new PrivateCredentialPermission 1138 (o.getClass().getName(), 1139 subject.getPrincipals())); 1140 } 1141 next = (Object )java.security.AccessController.doPrivileged 1142 (new java.security.PrivilegedAction () { 1143 public Object run() { 1144 return e.next(); 1145 } 1146 }); 1147 } 1148 1149 if (next == null) { 1150 if (o == null) { 1151 return true; 1152 } 1153 } else if (next.equals(o)) { 1154 return true; 1155 } 1156 } 1157 return false; 1158 } 1159 1160 public boolean removeAll(Collection c) { 1161 1162 boolean modified = false; 1163 final Iterator e = iterator(); 1164 while (e.hasNext()) { 1165 Object next; 1166 if (which != Subject.PRIV_CREDENTIAL_SET) { 1167 next = e.next(); 1168 } else { 1169 next = (Object )java.security.AccessController.doPrivileged 1170 (new java.security.PrivilegedAction () { 1171 public Object run() { 1172 return e.next(); 1173 } 1174 }); 1175 } 1176 1177 Iterator ce = c.iterator(); 1178 while (ce.hasNext()) { 1179 Object o = ce.next(); 1180 if (next == null) { 1181 if (o == null) { 1182 e.remove(); 1183 modified = true; 1184 break; 1185 } 1186 } else if (next.equals(o)) { 1187 e.remove(); 1188 modified = true; 1189 break; 1190 } 1191 } 1192 } 1193 return modified; 1194 } 1195 1196 public boolean retainAll(Collection c) { 1197 1198 boolean modified = false; 1199 boolean retain = false; 1200 final Iterator e = iterator(); 1201 while (e.hasNext()) { 1202 retain = false; 1203 Object next; 1204 if (which != Subject.PRIV_CREDENTIAL_SET) { 1205 next = e.next(); 1206 } else { 1207 next = (Object )java.security.AccessController.doPrivileged 1208 (new java.security.PrivilegedAction () { 1209 public Object run() { 1210 return e.next(); 1211 } 1212 }); 1213 } 1214 1215 Iterator ce = c.iterator(); 1216 while (ce.hasNext()) { 1217 Object o = ce.next(); 1218 if (next == null) { 1219 if (o == null) { 1220 retain = true; 1221 break; 1222 } 1223 } else if (next.equals(o)) { 1224 retain = true; 1225 break; 1226 } 1227 } 1228 1229 if (!retain) { 1230 e.remove(); 1231 retain = false; 1232 modified = true; 1233 } 1234 } 1235 return modified; 1236 } 1237 1238 public void clear() { 1239 final Iterator e = iterator(); 1240 while (e.hasNext()) { 1241 Object next; 1242 if (which != Subject.PRIV_CREDENTIAL_SET) { 1243 next = e.next(); 1244 } else { 1245 next = (Object )java.security.AccessController.doPrivileged 1246 (new java.security.PrivilegedAction () { 1247 public Object run() { 1248 return e.next(); 1249 } 1250 }); 1251 } 1252 e.remove(); 1253 } 1254 } 1255 1256 1267 private synchronized void writeObject(java.io.ObjectOutputStream oos) 1268 throws java.io.IOException { 1269 1270 if (which == Subject.PRIV_CREDENTIAL_SET) { 1271 Iterator i = iterator(); 1273 while (i.hasNext()) { 1274 i.next(); 1275 } 1276 } 1277 ObjectOutputStream.PutField fields = oos.putFields(); 1278 fields.put("this$0", subject); 1279 fields.put("elements", elements); 1280 fields.put("which", which); 1281 oos.writeFields(); 1282 } 1283 1284 private void readObject(ObjectInputStream ois) 1285 throws IOException, ClassNotFoundException 1286 { 1287 ObjectInputStream.GetField fields = ois.readFields(); 1288 subject = (Subject ) fields.get("this$0", null); 1289 elements = (LinkedList) fields.get("elements", null); 1290 which = fields.get("which", 0); 1291 } 1292 } 1293 1294 1298 private class ClassSet<T> extends AbstractSet<T> { 1299 1300 private int which; 1301 private Class c; 1302 private Set<T> set; 1303 1304 ClassSet(int which, Class c) { 1305 this.which = which; 1306 this.c = c; 1307 set = new HashSet(); 1308 1309 switch (which) { 1310 case Subject.PRINCIPAL_SET: 1311 synchronized(principals) { populateSet(); } 1312 break; 1313 case Subject.PUB_CREDENTIAL_SET: 1314 synchronized(pubCredentials) { populateSet(); } 1315 break; 1316 default: 1317 synchronized(privCredentials) { populateSet(); } 1318 break; 1319 } 1320 } 1321 1322 private void populateSet() { 1323 final Iterator iterator; 1324 switch(which) { 1325 case Subject.PRINCIPAL_SET: 1326 iterator = Subject.this.principals.iterator(); 1327 break; 1328 case Subject.PUB_CREDENTIAL_SET: 1329 iterator = Subject.this.pubCredentials.iterator(); 1330 break; 1331 default: 1332 iterator = Subject.this.privCredentials.iterator(); 1333 break; 1334 } 1335 1336 1339 while (iterator.hasNext()) { 1340 Object next; 1341 if (which == Subject.PRIV_CREDENTIAL_SET) { 1342 next = (Object )java.security.AccessController.doPrivileged 1343 (new java.security.PrivilegedAction () { 1344 public Object run() { 1345 return iterator.next(); 1346 } 1347 }); 1348 } else { 1349 next = iterator.next(); 1350 } 1351 if (c.isAssignableFrom(next.getClass())) { 1352 if (which != Subject.PRIV_CREDENTIAL_SET) { 1353 set.add((T)next); 1354 } else { 1355 SecurityManager sm = System.getSecurityManager(); 1357 if (sm != null) { 1358 sm.checkPermission(new PrivateCredentialPermission 1359 (next.getClass().getName(), 1360 Subject.this.getPrincipals())); 1361 } 1362 set.add((T)next); 1363 } 1364 } 1365 } 1366 } 1367 1368 public int size() { 1369 return set.size(); 1370 } 1371 1372 public Iterator<T> iterator() { 1373 return set.iterator(); 1374 } 1375 1376 public boolean add(T o) { 1377 1378 if (!o.getClass().isAssignableFrom(c)) { 1379 MessageFormat form = new MessageFormat (ResourcesMgr.getString 1380 ("attempting to add an object which is not an " + 1381 "instance of class")); 1382 Object [] source = {c.toString()}; 1383 throw new SecurityException (form.format(source)); 1384 } 1385 1386 return set.add(o); 1387 } 1388 } 1389} 1390 | Popular Tags |