Path: blob/master/src/java.security.jgss/share/classes/sun/security/jgss/krb5/SubjectComber.java
41161 views
/*1* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.jgss.krb5;2627import sun.security.krb5.KerberosSecrets;2829import javax.security.auth.kerberos.KerberosTicket;30import javax.security.auth.kerberos.KerberosKey;31import javax.security.auth.Subject;32import javax.security.auth.DestroyFailedException;33import java.util.Iterator;34import java.util.ArrayList;35import java.util.List;36import java.util.Set;37import javax.security.auth.kerberos.KerberosPrincipal;38import javax.security.auth.kerberos.KeyTab;3940/**41* This utility looks through the current Subject and retrieves private42* credentials for the desired client/server principals.43*44* @author Ram Marti45* @since 1.4.246*/4748class SubjectComber {4950private static final boolean DEBUG = Krb5Util.DEBUG;5152/**53* Default constructor54*/55private SubjectComber() { // Cannot create one of these56}5758static <T> T find(Subject subject, String serverPrincipal,59String clientPrincipal, Class<T> credClass) {6061// findAux returns T if oneOnly.62return credClass.cast(findAux(subject, serverPrincipal,63clientPrincipal, credClass, true));64}6566@SuppressWarnings("unchecked") // findAux returns List<T> if !oneOnly.67static <T> List<T> findMany(Subject subject, String serverPrincipal,68String clientPrincipal, Class<T> credClass) {6970return (List<T>)findAux(subject, serverPrincipal, clientPrincipal,71credClass, false);72}7374/**75* Find private credentials for the specified client/server principals76* in the subject. Returns null if the subject is null.77*78* @return the private credentials79*/80// Returns T if oneOnly and List<T> if !oneOnly.81private static <T> Object findAux(Subject subject, String serverPrincipal,82String clientPrincipal, Class<T> credClass, boolean oneOnly) {8384if (subject == null) {85return null;86} else {87List<T> answer = (oneOnly ? null : new ArrayList<T>());8889if (credClass == KeyTab.class) {90Iterator<KeyTab> iterator =91subject.getPrivateCredentials(KeyTab.class).iterator();92while (iterator.hasNext()) {93KeyTab t = iterator.next();94if (serverPrincipal != null && t.isBound()) {95KerberosPrincipal name = t.getPrincipal();96if (name != null) {97if (!serverPrincipal.equals(name.getName())) {98continue;99}100} else {101// legacy bound keytab. although we don't know who102// the bound principal is, it must be in allPrincs103boolean found = false;104for (KerberosPrincipal princ:105subject.getPrincipals(KerberosPrincipal.class)) {106if (princ.getName().equals(serverPrincipal)) {107found = true;108break;109}110}111if (!found) continue;112}113}114// Check passed, we can add now115if (DEBUG) {116System.out.println("Found " + credClass.getSimpleName()117+ " " + t);118}119if (oneOnly) {120return t;121} else {122answer.add(credClass.cast(t));123}124}125} else if (credClass == KerberosKey.class) {126// We are looking for credentials for the serverPrincipal127Iterator<KerberosKey> iterator =128subject.getPrivateCredentials(KerberosKey.class).iterator();129while (iterator.hasNext()) {130KerberosKey t = iterator.next();131String name = t.getPrincipal().getName();132if (serverPrincipal == null || serverPrincipal.equals(name)) {133if (DEBUG) {134System.out.println("Found " +135credClass.getSimpleName() + " for " + name);136}137if (oneOnly) {138return t;139} else {140answer.add(credClass.cast(t));141}142}143}144} else if (credClass == KerberosTicket.class) {145// we are looking for a KerberosTicket credentials146// for client-service principal pair147Set<Object> pcs = subject.getPrivateCredentials();148synchronized (pcs) {149Iterator<Object> iterator = pcs.iterator();150while (iterator.hasNext()) {151Object obj = iterator.next();152if (obj instanceof KerberosTicket) {153@SuppressWarnings("unchecked")154KerberosTicket ticket = (KerberosTicket)obj;155if (DEBUG) {156System.out.println("Found ticket for "157+ ticket.getClient()158+ " to go to "159+ ticket.getServer()160+ " expiring on "161+ ticket.getEndTime());162}163if (!ticket.isCurrent()) {164// let us remove the ticket from the Subject165// Note that both TGT and service ticket will be166// removed upon expiration167if (!subject.isReadOnly()) {168iterator.remove();169try {170ticket.destroy();171if (DEBUG) {172System.out.println("Removed and destroyed "173+ "the expired Ticket \n"174+ ticket);175176}177} catch (DestroyFailedException dfe) {178if (DEBUG) {179System.out.println("Expired ticket not" +180" detroyed successfully. " + dfe);181}182}183184}185} else {186KerberosPrincipal serverAlias = KerberosSecrets187.getJavaxSecurityAuthKerberosAccess()188.kerberosTicketGetServerAlias(ticket);189if (serverPrincipal == null ||190ticket.getServer().getName().equals(serverPrincipal) ||191(serverAlias != null &&192serverPrincipal.equals(193serverAlias.getName()))) {194KerberosPrincipal clientAlias = KerberosSecrets195.getJavaxSecurityAuthKerberosAccess()196.kerberosTicketGetClientAlias(ticket);197if (clientPrincipal == null ||198clientPrincipal.equals(199ticket.getClient().getName()) ||200(clientAlias != null &&201clientPrincipal.equals(202clientAlias.getName()))) {203if (oneOnly) {204return ticket;205} else {206// Record names so that tickets will207// all belong to same principals208if (clientPrincipal == null) {209if (clientAlias == null) {210clientPrincipal =211ticket.getClient().getName();212} else {213clientPrincipal =214clientAlias.getName();215}216}217if (serverPrincipal == null) {218if (serverAlias == null) {219serverPrincipal =220ticket.getServer().getName();221} else {222serverPrincipal =223serverAlias.getName();224}225}226answer.add(credClass.cast(ticket));227}228}229}230}231}232}233}234}235return answer;236}237}238}239240241