From b774d31c48838c2e1224fffd417d6d2d1b127666 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 23 Jul 2021 17:52:57 +0000 Subject: [PATCH] 8266689: More Constrained Delegation Reviewed-by: valeriep, rhalade, ahgross --- .../sun/security/jgss/krb5/SubjectComber.java | 158 ++++++++++-------- .../security/auth/module/Krb5LoginModule.java | 8 +- 2 files changed, 90 insertions(+), 76 deletions(-) diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/SubjectComber.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/SubjectComber.java index 1bc1bf7d629..964f1eac80a 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/SubjectComber.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/SubjectComber.java @@ -25,6 +25,7 @@ package sun.security.jgss.krb5; +import sun.security.krb5.JavaxSecurityAuthKerberosAccess; import sun.security.krb5.KerberosSecrets; import javax.security.auth.kerberos.KerberosTicket; @@ -150,83 +151,58 @@ class SubjectComber { Iterator iterator = pcs.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); - if (obj instanceof KerberosTicket) { - @SuppressWarnings("unchecked") - KerberosTicket ticket = (KerberosTicket)obj; - if (DEBUG) { - System.out.println("Found ticket for " - + ticket.getClient() - + " to go to " - + ticket.getServer() - + " expiring on " - + ticket.getEndTime()); - } - if (!ticket.isCurrent()) { - // let us remove the ticket from the Subject - // Note that both TGT and service ticket will be - // removed upon expiration - if (!subject.isReadOnly()) { - iterator.remove(); - try { - ticket.destroy(); - if (DEBUG) { - System.out.println("Removed and destroyed " - + "the expired Ticket \n" - + ticket); + if (!(obj instanceof KerberosTicket)) { + continue; + } + @SuppressWarnings("unchecked") + KerberosTicket ticket = (KerberosTicket)obj; + if (DEBUG) { + System.out.println("Found ticket for " + + ticket.getClient() + + " to go to " + + ticket.getServer() + + " expiring on " + + ticket.getEndTime()); + } + if (!ticket.isCurrent()) { + // let us remove the ticket from the Subject + // Note that both TGT and service ticket will be + // removed upon expiration + if (!subject.isReadOnly()) { + iterator.remove(); + try { + ticket.destroy(); + if (DEBUG) { + System.out.println("Removed and destroyed " + + "the expired Ticket \n" + + ticket); - } - } catch (DestroyFailedException dfe) { - if (DEBUG) { - System.out.println("Expired ticket not" + - " detroyed successfully. " + dfe); - } } - + } catch (DestroyFailedException dfe) { + if (DEBUG) { + System.out.println("Expired ticket not" + + " detroyed successfully. " + dfe); + } } - } else { - KerberosPrincipal serverAlias = KerberosSecrets - .getJavaxSecurityAuthKerberosAccess() - .kerberosTicketGetServerAlias(ticket); - if (serverPrincipal == null || - ticket.getServer().getName().equals(serverPrincipal) || - (serverAlias != null && - serverPrincipal.equals( - serverAlias.getName()))) { - KerberosPrincipal clientAlias = KerberosSecrets - .getJavaxSecurityAuthKerberosAccess() - .kerberosTicketGetClientAlias(ticket); - if (clientPrincipal == null || - clientPrincipal.equals( - ticket.getClient().getName()) || - (clientAlias != null && - clientPrincipal.equals( - clientAlias.getName()))) { - if (oneOnly) { - return ticket; - } else { - // Record names so that tickets will - // all belong to same principals - if (clientPrincipal == null) { - if (clientAlias == null) { - clientPrincipal = - ticket.getClient().getName(); - } else { - clientPrincipal = - clientAlias.getName(); - } - } - if (serverPrincipal == null) { - if (serverAlias == null) { - serverPrincipal = - ticket.getServer().getName(); - } else { - serverPrincipal = - serverAlias.getName(); - } - } - answer.add(credClass.cast(ticket)); - } + } + continue; + } + String serverMatch = findServerMatch(serverPrincipal, ticket); + if (serverMatch != null) { + String clientMatch = findClientMatch(clientPrincipal, ticket); + if (clientMatch != null) { + if (oneOnly) { + return ticket; + } else { + // Record names so that tickets will + // all belong to same principals + if (clientPrincipal == null) { + clientPrincipal = clientMatch; } + if (serverPrincipal == null) { + serverPrincipal = serverMatch; + } + answer.add(credClass.cast(ticket)); } } } @@ -236,4 +212,40 @@ class SubjectComber { return answer; } } + + private static String findServerMatch(String input, KerberosTicket ticket) { + KerberosPrincipal serverAlias = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess() + .kerberosTicketGetServerAlias(ticket); + if (input != null) { + return ((serverAlias != null && input.equals(serverAlias.getName())) || + input.equals(ticket.getServer().getName())) + ? input : null; + } else { + return serverAlias != null + ? serverAlias.getName() + : ticket.getServer().getName(); + } + } + + private static String findClientMatch(String input, KerberosTicket ticket) { + JavaxSecurityAuthKerberosAccess access = KerberosSecrets + .getJavaxSecurityAuthKerberosAccess(); + KerberosPrincipal clientAlias = access.kerberosTicketGetClientAlias(ticket); + KerberosTicket proxy = access.kerberosTicketGetProxy(ticket); + if (input != null) { + return ((clientAlias != null && input.equals(clientAlias.getName())) || + (proxy != null && input.equals(proxy.getClient().getName())) || + (proxy == null && input.equals(ticket.getClient().getName()))) + ? input : null; + } else { + if (clientAlias != null) { + return clientAlias.getName(); + } else if (proxy != null) { + return proxy.getClient().getName(); + } else { + return ticket.getClient().getName(); + } + } + } } diff --git a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java index 2e42e73fff4..91d4b41be4d 100644 --- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java +++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java @@ -663,9 +663,11 @@ public class Krb5LoginModule implements LoginModule { } if (cred != null) { - // get the principal name from the ticket cache - if (principal == null) { - principal = cred.getClient(); + // get the principal name from the ticket cache + if (principal == null) { + principal = cred.getProxy() != null + ? cred.getProxy().getClient() + : cred.getClient(); } } if (debug) {