Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java
38922 views
/*1* Copyright (c) 2000, 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 org.ietf.jgss.*;28import sun.security.jgss.GSSCaller;29import sun.security.jgss.spi.*;30import sun.security.krb5.*;31import sun.security.krb5.Config;32import javax.security.auth.kerberos.*;33import java.net.InetAddress;34import java.io.IOException;35import java.util.Date;36import java.security.AccessController;37import java.security.AccessControlContext;38import java.security.PrivilegedExceptionAction;39import java.security.PrivilegedActionException;4041/**42* Implements the krb5 initiator credential element.43*44* @author Mayank Upadhyay45* @author Ram Marti46* @since 1.447*/4849public class Krb5InitCredential50extends KerberosTicket51implements Krb5CredElement {5253private static final long serialVersionUID = 7723415700837898232L;5455private Krb5NameElement name;56private Credentials krb5Credentials;57public KerberosTicket proxyTicket;5859private Krb5InitCredential(Krb5NameElement name,60byte[] asn1Encoding,61KerberosPrincipal client,62KerberosPrincipal clientAlias,63KerberosPrincipal server,64KerberosPrincipal serverAlias,65byte[] sessionKey,66int keyType,67boolean[] flags,68Date authTime,69Date startTime,70Date endTime,71Date renewTill,72InetAddress[] clientAddresses)73throws GSSException {74super(asn1Encoding,75client,76server,77sessionKey,78keyType,79flags,80authTime,81startTime,82endTime,83renewTill,84clientAddresses);85KerberosSecrets.getJavaxSecurityAuthKerberosAccess()86.kerberosTicketSetClientAlias(this, clientAlias);87KerberosSecrets.getJavaxSecurityAuthKerberosAccess()88.kerberosTicketSetServerAlias(this, serverAlias);89this.name = name;9091try {92// Cache this for later use by the sun.security.krb5 package.93krb5Credentials = new Credentials(asn1Encoding,94client.getName(),95(clientAlias != null ?96clientAlias.getName() : null),97server.getName(),98(serverAlias != null ?99serverAlias.getName() : null),100sessionKey,101keyType,102flags,103authTime,104startTime,105endTime,106renewTill,107clientAddresses);108} catch (KrbException e) {109throw new GSSException(GSSException.NO_CRED, -1,110e.getMessage());111} catch (IOException e) {112throw new GSSException(GSSException.NO_CRED, -1,113e.getMessage());114}115116}117118private Krb5InitCredential(Krb5NameElement name,119Credentials delegatedCred,120byte[] asn1Encoding,121KerberosPrincipal client,122KerberosPrincipal clientAlias,123KerberosPrincipal server,124KerberosPrincipal serverAlias,125byte[] sessionKey,126int keyType,127boolean[] flags,128Date authTime,129Date startTime,130Date endTime,131Date renewTill,132InetAddress[] clientAddresses)133throws GSSException {134super(asn1Encoding,135client,136server,137sessionKey,138keyType,139flags,140authTime,141startTime,142endTime,143renewTill,144clientAddresses);145KerberosSecrets.getJavaxSecurityAuthKerberosAccess()146.kerberosTicketSetClientAlias(this, clientAlias);147KerberosSecrets.getJavaxSecurityAuthKerberosAccess()148.kerberosTicketSetServerAlias(this, serverAlias);149this.name = name;150// A delegated cred does not have all fields set. So do not try to151// creat new Credentials out of the delegatedCred.152this.krb5Credentials = delegatedCred;153}154155static Krb5InitCredential getInstance(GSSCaller caller, Krb5NameElement name,156int initLifetime)157throws GSSException {158159KerberosTicket tgt = getTgt(caller, name, initLifetime);160if (tgt == null)161throw new GSSException(GSSException.NO_CRED, -1,162"Failed to find any Kerberos tgt");163164if (name == null) {165String fullName = tgt.getClient().getName();166name = Krb5NameElement.getInstance(fullName,167Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);168}169170KerberosPrincipal clientAlias = KerberosSecrets171.getJavaxSecurityAuthKerberosAccess()172.kerberosTicketGetClientAlias(tgt);173KerberosPrincipal serverAlias = KerberosSecrets174.getJavaxSecurityAuthKerberosAccess()175.kerberosTicketGetServerAlias(tgt);176Krb5InitCredential result = new Krb5InitCredential(name,177tgt.getEncoded(),178tgt.getClient(),179clientAlias,180tgt.getServer(),181serverAlias,182tgt.getSessionKey().getEncoded(),183tgt.getSessionKeyType(),184tgt.getFlags(),185tgt.getAuthTime(),186tgt.getStartTime(),187tgt.getEndTime(),188tgt.getRenewTill(),189tgt.getClientAddresses());190result.proxyTicket = KerberosSecrets.getJavaxSecurityAuthKerberosAccess().191kerberosTicketGetProxy(tgt);192return result;193}194195static Krb5InitCredential getInstance(Krb5NameElement name,196Credentials delegatedCred)197throws GSSException {198199EncryptionKey sessionKey = delegatedCred.getSessionKey();200201/*202* all of the following data is optional in a KRB-CRED203* messages. This check for each field.204*/205206PrincipalName cPrinc = delegatedCred.getClient();207PrincipalName cAPrinc = delegatedCred.getClientAlias();208PrincipalName sPrinc = delegatedCred.getServer();209PrincipalName sAPrinc = delegatedCred.getServerAlias();210211KerberosPrincipal client = null;212KerberosPrincipal clientAlias = null;213KerberosPrincipal server = null;214KerberosPrincipal serverAlias = null;215216Krb5NameElement credName = null;217218if (cPrinc != null) {219String fullName = cPrinc.getName();220credName = Krb5NameElement.getInstance(fullName,221Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);222client = new KerberosPrincipal(fullName);223}224225if (cAPrinc != null) {226clientAlias = new KerberosPrincipal(cAPrinc.getName());227}228229// XXX Compare name to credName230231if (sPrinc != null) {232server =233new KerberosPrincipal(sPrinc.getName(),234KerberosPrincipal.KRB_NT_SRV_INST);235}236237if (sAPrinc != null) {238serverAlias = new KerberosPrincipal(sAPrinc.getName());239}240241return new Krb5InitCredential(credName,242delegatedCred,243delegatedCred.getEncoded(),244client,245clientAlias,246server,247serverAlias,248sessionKey.getBytes(),249sessionKey.getEType(),250delegatedCred.getFlags(),251delegatedCred.getAuthTime(),252delegatedCred.getStartTime(),253delegatedCred.getEndTime(),254delegatedCred.getRenewTill(),255delegatedCred.getClientAddresses());256}257258/**259* Returns the principal name for this credential. The name260* is in mechanism specific format.261*262* @return GSSNameSpi representing principal name of this credential263* @exception GSSException may be thrown264*/265public final GSSNameSpi getName() throws GSSException {266return name;267}268269/**270* Returns the init lifetime remaining.271*272* @return the init lifetime remaining in seconds273* @exception GSSException may be thrown274*/275public int getInitLifetime() throws GSSException {276Date d = getEndTime();277if (d == null) {278return 0;279}280281long retVal = d.getTime() - System.currentTimeMillis();282return (int)(retVal/1000);283}284285/**286* Returns the accept lifetime remaining.287*288* @return the accept lifetime remaining in seconds289* @exception GSSException may be thrown290*/291public int getAcceptLifetime() throws GSSException {292return 0;293}294295public boolean isInitiatorCredential() throws GSSException {296return true;297}298299public boolean isAcceptorCredential() throws GSSException {300return false;301}302303/**304* Returns the oid representing the underlying credential305* mechanism oid.306*307* @return the Oid for this credential mechanism308* @exception GSSException may be thrown309*/310public final Oid getMechanism() {311return Krb5MechFactory.GSS_KRB5_MECH_OID;312}313314public final java.security.Provider getProvider() {315return Krb5MechFactory.PROVIDER;316}317318319/**320* Returns a sun.security.krb5.Credentials instance so that it maybe321* used in that package for th Kerberos protocol.322*/323Credentials getKrb5Credentials() {324return krb5Credentials;325}326327/*328* XXX Call to this.refresh() should refresh the locally cached copy329* of krb5Credentials also.330*/331332/**333* Called to invalidate this credential element.334*/335public void dispose() throws GSSException {336try {337destroy();338} catch (javax.security.auth.DestroyFailedException e) {339GSSException gssException =340new GSSException(GSSException.FAILURE, -1,341"Could not destroy credentials - " + e.getMessage());342gssException.initCause(e);343}344}345346// XXX call to this.destroy() should destroy the locally cached copy347// of krb5Credentials and then call super.destroy().348349private static KerberosTicket getTgt(GSSCaller caller, Krb5NameElement name,350int initLifetime)351throws GSSException {352353final String clientPrincipal;354355/*356* Find the TGT for the realm that the client is in. If the client357* name is not available, then use the default realm.358*/359if (name != null) {360clientPrincipal = (name.getKrb5PrincipalName()).getName();361} else {362clientPrincipal = null;363}364365final AccessControlContext acc = AccessController.getContext();366367try {368final GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN)369? GSSCaller.CALLER_INITIATE370: caller;371return AccessController.doPrivileged(372new PrivilegedExceptionAction<KerberosTicket>() {373public KerberosTicket run() throws Exception {374// It's OK to use null as serverPrincipal. TGT is almost375// the first ticket for a principal and we use list.376return Krb5Util.getInitialTicket(377realCaller,378clientPrincipal, acc);379}});380} catch (PrivilegedActionException e) {381GSSException ge =382new GSSException(GSSException.NO_CRED, -1,383"Attempt to obtain new INITIATE credentials failed!" +384" (" + e.getMessage() + ")");385ge.initCause(e.getException());386throw ge;387}388}389390@Override391public GSSCredentialSpi impersonate(GSSNameSpi name) throws GSSException {392try {393Krb5NameElement kname = (Krb5NameElement)name;394Credentials newCred = Credentials.acquireS4U2selfCreds(395kname.getKrb5PrincipalName(), krb5Credentials);396return new Krb5ProxyCredential(this, kname, newCred.getTicket());397} catch (IOException | KrbException ke) {398GSSException ge =399new GSSException(GSSException.FAILURE, -1,400"Attempt to obtain S4U2self credentials failed!");401ge.initCause(ke);402throw ge;403}404}405}406407408