< prev index next >

src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java

Print this page
rev 54745 : 8215032: Support Kerberos cross-realm referrals (RFC 6806)
Reviewed-by: weijun

*** 1,7 **** /* ! * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 31,40 **** --- 31,43 ---- package sun.security.krb5.internal; import sun.security.krb5.*; import java.io.IOException; + import java.util.Arrays; + import java.util.LinkedList; + import java.util.List; /** * This class is a utility that contains much of the TGS-Exchange * protocol. It is used by ../Credentials.java for service ticket * acquisition in both the normal and the x-realm case.
*** 59,75 **** throw new KrbException("Cross realm impersonation not supported"); } if (!ccreds.isForwardable()) { throw new KrbException("S4U2self needs a FORWARDABLE ticket"); } ! KrbTgsReq req = new KrbTgsReq( ! ccreds, ! ccreds.getClient(), ! new PAData(Krb5.PA_FOR_USER, new PAForUserEnc(client, ! ccreds.getSessionKey()).asn1Encode())); ! Credentials creds = req.sendAndGetCreds(); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2self request not honored by KDC"); } if (!creds.isForwardable()) { throw new KrbException("S4U2self ticket must be FORWARDABLE"); --- 62,76 ---- throw new KrbException("Cross realm impersonation not supported"); } if (!ccreds.isForwardable()) { throw new KrbException("S4U2self needs a FORWARDABLE ticket"); } ! Credentials creds = serviceCreds(KDCOptions.with(KDCOptions.FORWARDABLE), ! ccreds, ccreds.getClient(), ccreds.getClient(), null, ! new PAData[] {new PAData(Krb5.PA_FOR_USER, new PAForUserEnc(client, ! ccreds.getSessionKey()).asn1Encode())}); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2self request not honored by KDC"); } if (!creds.isForwardable()) { throw new KrbException("S4U2self ticket must be FORWARDABLE");
*** 87,101 **** */ public static Credentials acquireS4U2proxyCreds( String backend, Ticket second, PrincipalName client, Credentials ccreds) throws KrbException, IOException { ! KrbTgsReq req = new KrbTgsReq( ! ccreds, ! second, ! new PrincipalName(backend)); ! Credentials creds = req.sendAndGetCreds(); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2proxy request not honored by KDC"); } return creds; } --- 88,101 ---- */ public static Credentials acquireS4U2proxyCreds( String backend, Ticket second, PrincipalName client, Credentials ccreds) throws KrbException, IOException { ! Credentials creds = serviceCreds(KDCOptions.with( ! KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE), ! ccreds, ccreds.getClient(), new PrincipalName(backend), ! new Ticket[] {second}, null); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2proxy request not honored by KDC"); } return creds; }
*** 112,169 **** * @param ccreds client's initial credential */ public static Credentials acquireServiceCreds( String service, Credentials ccreds) throws KrbException, IOException { ! PrincipalName sname = new PrincipalName(service); ! String serviceRealm = sname.getRealmString(); ! String localRealm = ccreds.getClient().getRealmString(); ! ! if (localRealm.equals(serviceRealm)) { ! if (DEBUG) { ! System.out.println( ! ">>> Credentials acquireServiceCreds: same realm"); ! } return serviceCreds(sname, ccreds); } - Credentials theCreds = null; - - boolean[] okAsDelegate = new boolean[1]; - Credentials theTgt = getTGTforRealm(localRealm, serviceRealm, - ccreds, okAsDelegate); - if (theTgt != null) { - if (DEBUG) { - System.out.println(">>> Credentials acquireServiceCreds: " - + "got right tgt"); - System.out.println(">>> Credentials acquireServiceCreds: " - + "obtaining service creds for " + sname); - } - - try { - theCreds = serviceCreds(sname, theTgt); - } catch (Exception exc) { - if (DEBUG) { - System.out.println(exc); - } - theCreds = null; - } - } - - if (theCreds != null) { - if (DEBUG) { - System.out.println(">>> Credentials acquireServiceCreds: " - + "returning creds:"); - Credentials.printDebug(theCreds); - } - if (!okAsDelegate[0]) { - theCreds.resetDelegate(); - } - return theCreds; - } - throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED, - "No service creds"); - } /** * Gets a TGT to another realm * @param localRealm this realm * @param serviceRealm the other realm, cannot equals to localRealm --- 112,125 ---- * @param ccreds client's initial credential */ public static Credentials acquireServiceCreds( String service, Credentials ccreds) throws KrbException, IOException { ! PrincipalName sname = new PrincipalName(service, ! PrincipalName.KRB_NT_SRV_HST); return serviceCreds(sname, ccreds); } /** * Gets a TGT to another realm * @param localRealm this realm * @param serviceRealm the other realm, cannot equals to localRealm
*** 303,310 **** * This method does the real job to request the service credential. */ private static Credentials serviceCreds( PrincipalName service, Credentials ccreds) throws KrbException, IOException { ! return new KrbTgsReq(ccreds, service).sendAndGetCreds(); } } --- 259,395 ---- * This method does the real job to request the service credential. */ private static Credentials serviceCreds( PrincipalName service, Credentials ccreds) throws KrbException, IOException { ! return serviceCreds(new KDCOptions(), ccreds, ! ccreds.getClient(), service, null, null); ! } ! ! private static Credentials serviceCreds( ! KDCOptions options, Credentials asCreds, ! PrincipalName cname, PrincipalName sname, ! Ticket[] additionalTickets, PAData[] extraPAs) ! throws KrbException, IOException { ! if (!Config.DISABLE_REFERRALS) { ! try { ! return serviceCredsReferrals(options, asCreds, ! cname, sname, additionalTickets, extraPAs); ! } catch (KrbException e) { ! // Server may raise an error if CANONICALIZE is true. ! // Try CANONICALIZE false. ! } ! } ! return serviceCredsSingle(options, asCreds, ! cname, sname, additionalTickets, extraPAs); ! } ! ! private static Credentials serviceCredsReferrals( ! KDCOptions options, Credentials asCreds, ! PrincipalName cname, PrincipalName sname, ! Ticket[] additionalTickets, PAData[] extraPAs) ! throws KrbException, IOException { ! options = new KDCOptions(options.toBooleanArray()); ! options.set(KDCOptions.CANONICALIZE, true); ! PrincipalName cSname = (PrincipalName) sname.clone(); ! Credentials creds = null; ! boolean isReferral = false; ! List<String> referrals = new LinkedList<>(); ! while (referrals.size() <= Config.MAX_REFERRALS) { ! ReferralsCache.ReferralCacheEntry ref = ! ReferralsCache.get(sname, cSname.getRealmString()); ! String toRealm = null; ! if (ref == null) { ! creds = serviceCredsSingle(options, asCreds, ! cname, cSname, additionalTickets, extraPAs); ! PrincipalName server = creds.getServer(); ! if (!cSname.equals(server)) { ! String[] serverNameStrings = server.getNameStrings(); ! if (serverNameStrings.length == 2 && ! serverNameStrings[0].equals( ! PrincipalName.TGS_DEFAULT_SRV_NAME) && ! !cSname.getRealmAsString().equals(serverNameStrings[1])) { ! // Server Name (sname) has the following format: ! // krbtgt/TO-REALM.COM@FROM-REALM.COM ! ReferralsCache.put(sname, server.getRealmString(), ! serverNameStrings[1], creds); ! toRealm = serverNameStrings[1]; ! isReferral = true; ! asCreds = creds; ! } ! } ! } else { ! toRealm = ref.getToRealm(); ! asCreds = ref.getCreds(); ! isReferral = true; ! } ! if (isReferral) { ! if (referrals.contains(toRealm)) { ! // Referrals loop detected ! return null; ! } ! cSname = new PrincipalName(cSname.getNameString(), ! cSname.getNameType(), toRealm); ! referrals.add(toRealm); ! isReferral = false; ! continue; ! } ! break; ! } ! return creds; ! } ! ! private static Credentials serviceCredsSingle( ! KDCOptions options, Credentials asCreds, ! PrincipalName cname, PrincipalName sname, ! Ticket[] additionalTickets, PAData[] extraPAs) ! throws KrbException, IOException { ! Credentials theCreds = null; ! boolean[] okAsDelegate = new boolean[]{true}; ! String[] serverAsCredsNames = asCreds.getServer().getNameStrings(); ! if (serverAsCredsNames.length == 2 && ! serverAsCredsNames[0].equals( ! PrincipalName.TGS_DEFAULT_SRV_NAME)) { ! String tgtRealm = serverAsCredsNames[1]; ! String serviceRealm = sname.getRealmString(); ! if (!serviceRealm.equals(tgtRealm)) { ! // This is a cross-realm service request ! if (DEBUG) { ! System.out.println(">>> serviceCredsSingle:" + ! " cross-realm authentication"); ! System.out.println(">>> serviceCredsSingle:" + ! " obtaining credentials from " + tgtRealm + ! " to " + serviceRealm); ! } ! Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm, ! asCreds, okAsDelegate); ! if (newTgt == null) { ! throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED, ! "No service creds"); ! } ! if (DEBUG) { ! System.out.println(">>> Cross-realm TGT Credentials" + ! " serviceCredsSingle: "); ! Credentials.printDebug(newTgt); ! } ! asCreds = newTgt; ! cname = asCreds.getClient(); ! } else if (DEBUG) { ! System.out.println(">>> Credentials serviceCredsSingle:" + ! " same realm"); ! } ! } ! KrbTgsReq req = new KrbTgsReq(options, asCreds, ! cname, sname, additionalTickets, extraPAs); ! theCreds = req.sendAndGetCreds(); ! if (theCreds != null) { ! if (DEBUG) { ! System.out.println(">>> TGS credentials serviceCredsSingle:"); ! Credentials.printDebug(theCreds); ! } ! if (!okAsDelegate[0]) { ! theCreds.resetDelegate(); ! } ! } ! return theCreds; } }
< prev index next >