1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.security.auth; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessControlContext; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.DomainCombiner; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Permission; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Principal; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedAction; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedActionException; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PrivilegedExceptionAction; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.ProtectionDomain; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.AbstractSet; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.LinkedList; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The central class of the {@code javax.security.auth} package representing an 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authenticated user or entity (both referred to as "subject"). IT defines also 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the static methods that allow code to be run, and do modifications according 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to the subject's permissions. 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A subject has the following features: 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>A set of {@code Principal} objects specifying the identities bound to a 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Subject} that distinguish it.</li> 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Credentials (public and private) such as certificates, keys, or 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authentication proofs such as tickets</li> 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class Subject implements Serializable { 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -8308522755600156056L; 56f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 57f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final AuthPermission _AS = new AuthPermission("doAs"); 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _AS_PRIVILEGED = new AuthPermission( 60f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "doAsPrivileged"); 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _SUBJECT = new AuthPermission( 63f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "getSubject"); 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _PRINCIPALS = new AuthPermission( 66f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "modifyPrincipals"); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _PRIVATE_CREDENTIALS = new AuthPermission( 69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "modifyPrivateCredentials"); 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _PUBLIC_CREDENTIALS = new AuthPermission( 72f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "modifyPublicCredentials"); 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final AuthPermission _READ_ONLY = new AuthPermission( 75f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes "setReadOnly"); 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Set<Principal> principals; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean readOnly; 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set of private credentials 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient SecureSet<Object> privateCredentials; 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set of public credentials 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient SecureSet<Object> publicCredentials; 86f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default constructor initializing the sets of public and private 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * credentials and principals with the empty set. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Subject() { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project principals = new SecureSet<Principal>(_PRINCIPALS); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project publicCredentials = new SecureSet<Object>(_PUBLIC_CREDENTIALS); 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project privateCredentials = new SecureSet<Object>(_PRIVATE_CREDENTIALS); 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readOnly = false; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The constructor for the subject, setting its public and private 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * credentials and principals according to the arguments. 10213970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param readOnly 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code true} if this {@code Subject} is read-only, thus 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * preventing any modifications to be done. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param subjPrincipals 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the set of Principals that are attributed to this {@code 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subject}. 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param pubCredentials 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the set of public credentials that distinguish this {@code 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subject}. 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param privCredentials 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the set of private credentials that distinguish this {@code 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subject}. 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Subject(boolean readOnly, Set<? extends Principal> subjPrincipals, 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<?> pubCredentials, Set<?> privCredentials) { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11986acc043d3334651ee26c65467d78d6cefedd397Kenny Root if (subjPrincipals == null) { 12086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("subjPrincipals == null"); 12186acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (pubCredentials == null) { 12286acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("pubCredentials == null"); 12386acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (privCredentials == null) { 12486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("privCredentials == null"); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project principals = new SecureSet<Principal>(_PRINCIPALS, subjPrincipals); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project publicCredentials = new SecureSet<Object>(_PUBLIC_CREDENTIALS, pubCredentials); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project privateCredentials = new SecureSet<Object>(_PRIVATE_CREDENTIALS, privCredentials); 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.readOnly = readOnly; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Runs the code defined by {@code action} using the permissions granted to 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Subject} itself and to the code as well. 13713970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param subject 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the distinguished {@code Subject}. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param action 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the code to be run. 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Object} returned when running the {@code action}. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 14555b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson public static <T> T doAs(Subject subject, PrivilegedAction<T> action) { 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedAction(subject, action, AccessController.getContext()); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Run the code defined by {@code action} using the permissions granted to 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Subject} and to the code itself, additionally providing a more 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specific context. 15313970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param subject 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the distinguished {@code Subject}. 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param action 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the code to be run. 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param context 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specific context in which the {@code action} is invoked. 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code null} a new {@link AccessControlContext} is 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instantiated. 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Object} returned when running the {@code action}. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 16555b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson public static <T> T doAsPrivileged(Subject subject, PrivilegedAction<T> action, 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AccessControlContext context) { 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (context == null) { 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedAction(subject, action, new AccessControlContext( 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ProtectionDomain[0])); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedAction(subject, action, context); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // instantiates a new context and passes it to AccessController 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 17655b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson private static <T> T doAs_PrivilegedAction(Subject subject, PrivilegedAction<T> action, 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final AccessControlContext context) { 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AccessControlContext newContext; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final SubjectDomainCombiner combiner; 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subject == null) { 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // performance optimization 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if subject is null there is nothing to combine 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project combiner = null; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project combiner = new SubjectDomainCombiner(subject); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PrivilegedAction dccAction = new PrivilegedAction() { 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object run() { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new AccessControlContext(context, combiner); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newContext = (AccessControlContext) AccessController.doPrivileged(dccAction); 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return AccessController.doPrivileged(action, newContext); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Runs the code defined by {@code action} using the permissions granted to 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the subject and to the code itself. 20413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param subject 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the distinguished {@code Subject}. 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param action 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the code to be run. 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Object} returned when running the {@code action}. 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PrivilegedActionException 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if running the {@code action} throws an exception. 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 21455b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson public static <T> T doAs(Subject subject, PrivilegedExceptionAction<T> action) 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws PrivilegedActionException { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedExceptionAction(subject, action, AccessController.getContext()); 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Runs the code defined by {@code action} using the permissions granted to 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the subject and to the code itself, additionally providing a more 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specific context. 22313970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param subject 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the distinguished {@code Subject}. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param action 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the code to be run. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param context 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specific context in which the {@code action} is invoked. 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code null} a new {@link AccessControlContext} is 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instantiated. 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Object} returned when running the {@code action}. 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws PrivilegedActionException 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if running the {@code action} throws an exception. 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 23755b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson public static <T> T doAsPrivileged(Subject subject, 23855b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson PrivilegedExceptionAction<T> action, AccessControlContext context) 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws PrivilegedActionException { 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (context == null) { 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedExceptionAction(subject, action, 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new AccessControlContext(new ProtectionDomain[0])); 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doAs_PrivilegedExceptionAction(subject, action, context); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // instantiates a new context and passes it to AccessController 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 24955b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson private static <T> T doAs_PrivilegedExceptionAction(Subject subject, 25055b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson PrivilegedExceptionAction<T> action, final AccessControlContext context) 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws PrivilegedActionException { 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AccessControlContext newContext; 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final SubjectDomainCombiner combiner; 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (subject == null) { 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // performance optimization 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if subject is null there is nothing to combine 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project combiner = null; 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project combiner = new SubjectDomainCombiner(subject); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PrivilegedAction<AccessControlContext> dccAction = new PrivilegedAction<AccessControlContext>() { 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AccessControlContext run() { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new AccessControlContext(context, combiner); 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newContext = AccessController.doPrivileged(dccAction); 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return AccessController.doPrivileged(action, newContext); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks two Subjects for equality. More specifically if the principals, 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * public and private credentials are equal, equality for two {@code 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subjects} is implied. 27913970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Object} checked for equality with this {@code 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subject}. 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the specified {@code Subject} is equal to this 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (this == obj) { 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (obj == null || this.getClass() != obj.getClass()) { 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Subject that = (Subject) obj; 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (principals.equals(that.principals) 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && publicCredentials.equals(that.publicCredentials) 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && privateCredentials.equals(that.privateCredentials)) { 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this {@code Subject}'s {@link Principal}. 30913970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this {@code Subject}'s {@link Principal}. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Principal> getPrincipals() { 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return principals; 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31613970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this {@code Subject}'s {@link Principal} which is a subclass of 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Class} provided. 32013970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Class} as a criteria which the {@code Principal} 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned must satisfy. 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this {@code Subject}'s {@link Principal}. Modifications to the 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned set of {@code Principal}s do not affect this {@code 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Subject}'s set. 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public <T extends Principal> Set<T> getPrincipals(Class<T> c) { 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((SecureSet<Principal>) principals).get(c); 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the private credentials associated with this {@code Subject}. 33413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the private credentials associated with this {@code Subject}. 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Object> getPrivateCredentials() { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return privateCredentials; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this {@code Subject}'s private credentials which are a subclass 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the {@code Class} provided. 34413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Class} as a criteria which the private credentials 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned must satisfy. 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this {@code Subject}'s private credentials. Modifications to the 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned set of credentials do not affect this {@code Subject}'s 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * credentials. 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public <T> Set<T> getPrivateCredentials(Class<T> c) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return privateCredentials.get(c); 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the public credentials associated with this {@code Subject}. 35813970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the public credentials associated with this {@code Subject}. 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Object> getPublicCredentials() { 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return publicCredentials; 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36513970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this {@code Subject}'s public credentials which are a subclass of 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Class} provided. 36913970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Class} as a criteria which the public credentials 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned must satisfy. 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this {@code Subject}'s public credentials. Modifications to the 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned set of credentials do not affect this {@code Subject}'s 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * credentials. 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public <T> Set<T> getPublicCredentials(Class<T> c) { 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return publicCredentials.get(c); 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a hash code of this {@code Subject}. 38313970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a hash code of this {@code Subject}. 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return principals.hashCode() + privateCredentials.hashCode() 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + publicCredentials.hashCode(); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Prevents from modifications being done to the credentials and {@link 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Principal} sets. After setting it to read-only this {@code Subject} can 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not be made writable again. The destroy method on the credentials still 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * works though. 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setReadOnly() { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readOnly = true; 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this {@code Subject} is read-only or not. 40413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return whether this {@code Subject} is read-only or not. 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isReadOnly() { 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readOnly; 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a {@code String} representation of this {@code Subject}. 41313970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a {@code String} representation of this {@code Subject}. 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 4187f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom StringBuilder buf = new StringBuilder("Subject:\n"); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<?> it = principals.iterator(); 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 422f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes buf.append("\tPrincipal: "); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append(it.next()); 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append('\n'); 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it = publicCredentials.iterator(); 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 429f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes buf.append("\tPublic Credential: "); 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append(it.next()); 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append('\n'); 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = buf.length() - 1; 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project it = privateCredentials.iterator(); 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 438f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes buf.append("\tPrivate Credential: "); 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append(it.next()); 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.append('\n'); 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SecurityException e) { 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf.delete(offset, buf.length()); 444f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes buf.append("\tPrivate Credentials: no accessible information\n"); 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buf.toString(); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObject(ObjectInputStream in) throws IOException, 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.defaultReadObject(); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project publicCredentials = new SecureSet<Object>(_PUBLIC_CREDENTIALS); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project privateCredentials = new SecureSet<Object>(_PRIVATE_CREDENTIALS); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(ObjectOutputStream out) throws IOException { 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project out.defaultWriteObject(); 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code Subject} that was last associated with the {@code 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context} provided as argument. 46513970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param context 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code context} that was associated with the 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Subject}. 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Subject} that was last associated with the {@code 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context} provided as argument. 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Subject getSubject(final AccessControlContext context) { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (context == null) { 47486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("context == null"); 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PrivilegedAction<DomainCombiner> action = new PrivilegedAction<DomainCombiner>() { 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DomainCombiner run() { 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return context.getDomainCombiner(); 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DomainCombiner combiner = AccessController.doPrivileged(action); 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((combiner == null) || !(combiner instanceof SubjectDomainCombiner)) { 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((SubjectDomainCombiner) combiner).getSubject(); 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkState() { 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (readOnly) { 4912313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes throw new IllegalStateException("Set is read-only"); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final class SecureSet<SST> extends AbstractSet<SST> implements Serializable { 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compatibility issue: see comments for setType variable 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 7911754171111800359L; 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private LinkedList<SST> elements; 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Is used to define a set type for serialization. 506f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A type can be principal, priv. or pub. credential set. The spec. 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * doesn't clearly says that priv. and pub. credential sets can be 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * serialized and what classes they are. It is only possible to figure 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * out from writeObject method comments that priv. credential set is 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * serializable and it is an instance of SecureSet class. So pub. 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * credential was implemented by analogy 513f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compatibility issue: the class follows its specified serial form. 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Also according to the serialization spec. adding new field is a 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * compatible change. So is ok for principal set (because the default 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value for integer is zero). But priv. or pub. credential set it is 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not compatible because most probably other implementations resolve 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this issue in other way 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int setType; 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Defines principal set for serialization. 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int SET_Principal = 0; 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Defines private credential set for serialization. 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int SET_PrivCred = 1; 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Defines public credential set for serialization. 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int SET_PubCred = 2; 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // permission required to modify set 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient AuthPermission permission; 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected SecureSet(AuthPermission perm) { 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project permission = perm; 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project elements = new LinkedList<SST>(); 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // creates set from specified collection with specified permission 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all collection elements are verified before adding 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected SecureSet(AuthPermission perm, Collection<? extends SST> s) { 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(perm); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Subject's constructor receives a Set, we can trusts if a set is from bootclasspath, 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // and not to check whether it contains duplicates or not 547f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes boolean trust = s.getClass().getClassLoader() == null; 548f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 54955b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson for (SST o : s) { 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project verifyElement(o); 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (trust || !elements.contains(o)) { 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project elements.add(o); 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // verifies new set element 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void verifyElement(Object o) { 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o == null) { 56186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("o == null"); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (permission == _PRINCIPALS && !(Principal.class.isAssignableFrom(o.getClass()))) { 5642313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes throw new IllegalArgumentException("Element is not instance of java.security.Principal"); 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * verifies specified element, checks set state, and security permission 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to modify set before adding new element 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean add(SST o) { 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project verifyElement(o); 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!elements.contains(o)) { 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project elements.add(o); 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // returns an instance of SecureIterator 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<SST> iterator() { 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (permission == _PRIVATE_CREDENTIALS) { 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * private credential set requires iterator with additional 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * security check (PrivateCredentialPermission) 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SecureIterator(elements.iterator()) { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * checks permission to access next private credential moves 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to the next element even SecurityException was thrown 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SST next() { 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SST obj = iterator.next(); 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return obj; 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SecureIterator(elements.iterator()); 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean retainAll(Collection<?> c) { 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) { 61486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("c == null"); 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.retainAll(c); 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return elements.size(); 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return set with elements that are instances or subclasses of the 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified class 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final <E> Set<E> get(final Class<E> c) { 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) { 63186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("c == null"); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractSet<E> s = new AbstractSet<E>() { 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private LinkedList<E> elements = new LinkedList<E>(); 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean add(E o) { 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!c.isAssignableFrom(o.getClass())) { 6402313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes throw new IllegalArgumentException("Invalid type: " + o.getClass()); 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (elements.contains(o)) { 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project elements.add(o); 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<E> iterator() { 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return elements.iterator(); 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean retainAll(Collection<?> c) { 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) { 65986acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("c == null"); 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.retainAll(c); 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return elements.size(); 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME must have permissions for requested priv. credentials 67155b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson for (SST o : this) { 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c.isAssignableFrom(o.getClass())) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.add(c.cast(o)); 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return s; 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void readObject(ObjectInputStream in) throws IOException, 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ClassNotFoundException { 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.defaultReadObject(); 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (setType) { 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case SET_Principal: 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project permission = _PRINCIPALS; 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case SET_PrivCred: 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project permission = _PRIVATE_CREDENTIALS; 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case SET_PubCred: 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project permission = _PUBLIC_CREDENTIALS; 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 69755b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson for (SST element : elements) { 69855b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson verifyElement(element); 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70255b2d1c3f492f6140ad6dd18a4bec4ec2643d664Jesse Wilson @SuppressWarnings("UnusedDeclaration") 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(ObjectOutputStream out) throws IOException { 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (permission == _PRIVATE_CREDENTIALS) { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setType = SET_PrivCred; 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (permission == _PRINCIPALS) { 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setType = SET_Principal; 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setType = SET_PubCred; 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project out.defaultWriteObject(); 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Represents iterator for subject's secure set 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SecureIterator implements Iterator<SST> { 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Iterator<SST> iterator; 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected SecureIterator(Iterator<SST> iterator) { 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.iterator = iterator; 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasNext() { 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return iterator.hasNext(); 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SST next() { 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return iterator.next(); 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * checks set state, and security permission to modify set before 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removing current element 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove() { 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project iterator.remove(); 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7442313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes} 745