1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.javax.security.auth; 19 20 import java.security.DomainCombiner; 21 import java.security.Principal; 22 import java.security.ProtectionDomain; 23 import java.util.Set; 24 25 /** 26 * Merges permissions based on code source and code signers with permissions 27 * granted to the specified {@link Subject}. 28 */ 29 public class SubjectDomainCombiner implements DomainCombiner { 30 31 // subject to be associated 32 private Subject subject; 33 34 // permission required to get a subject object 35 private static final AuthPermission _GET = new AuthPermission( 36 "getSubjectFromDomainCombiner"); //$NON-NLS-1$ 37 38 /** 39 * Creates a domain combiner for the entity provided in {@code subject}. 40 * 41 * @param subject 42 * the entity to which this domain combiner is associated. 43 */ SubjectDomainCombiner(Subject subject)44 public SubjectDomainCombiner(Subject subject) { 45 super(); 46 if (subject == null) { 47 throw new NullPointerException(); 48 } 49 this.subject = subject; 50 } 51 52 /** 53 * Returns the entity to which this domain combiner is associated. 54 * 55 * @return the entity to which this domain combiner is associated. 56 */ getSubject()57 public Subject getSubject() { 58 SecurityManager sm = System.getSecurityManager(); 59 if (sm != null) { 60 sm.checkPermission(_GET); 61 } 62 63 return subject; 64 } 65 66 /** 67 * Merges the {@code ProtectionDomain} with the {@code Principal}s 68 * associated with the subject of this {@code SubjectDomainCombiner}. 69 * 70 * @param currentDomains 71 * the {@code ProtectionDomain}s associated with the context of 72 * the current thread. The domains must be sorted according to 73 * the execution order, the most recent residing at the 74 * beginning. 75 * @param assignedDomains 76 * the {@code ProtectionDomain}s from the parent thread based on 77 * code source and signers. 78 * @return a single {@code ProtectionDomain} array computed from the two 79 * provided arrays, or {@code null}. 80 * @see ProtectionDomain 81 */ combine(ProtectionDomain[] currentDomains, ProtectionDomain[] assignedDomains)82 public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, 83 ProtectionDomain[] assignedDomains) { 84 // get array length for combining protection domains 85 int len = 0; 86 if (currentDomains != null) { 87 len += currentDomains.length; 88 } 89 if (assignedDomains != null) { 90 len += assignedDomains.length; 91 } 92 if (len == 0) { 93 return null; 94 } 95 96 ProtectionDomain[] pd = new ProtectionDomain[len]; 97 98 // for each current domain substitute set of principal with subject's 99 int cur = 0; 100 if (currentDomains != null) { 101 102 Set<Principal> s = subject.getPrincipals(); 103 Principal[] p = s.toArray(new Principal[s.size()]); 104 105 for (cur = 0; cur < currentDomains.length; cur++) { 106 if (currentDomains[cur] != null) { 107 ProtectionDomain newPD; 108 newPD = new ProtectionDomain(currentDomains[cur].getCodeSource(), 109 currentDomains[cur].getPermissions(), currentDomains[cur] 110 .getClassLoader(), p); 111 pd[cur] = newPD; 112 } 113 } 114 } 115 116 // copy assigned domains 117 if (assignedDomains != null) { 118 System.arraycopy(assignedDomains, 0, pd, cur, assignedDomains.length); 119 } 120 121 return pd; 122 } 123 } 124