1 /* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.jgss.krb5; 27 28 import java.io.IOException; 29 import org.ietf.jgss.*; 30 import sun.security.jgss.GSSCaller; 31 import sun.security.jgss.spi.*; 32 import sun.security.krb5.*; 33 import java.security.PrivilegedActionException; 34 import java.security.PrivilegedExceptionAction; 35 import java.security.AccessController; 36 import java.security.AccessControlContext; 37 import javax.security.auth.DestroyFailedException; 38 39 /** 40 * Implements the krb5 acceptor credential element. 41 * 42 * @author Mayank Upadhyay 43 * @since 1.4 44 */ 45 public class Krb5AcceptCredential 46 implements Krb5CredElement { 47 48 private final Krb5NameElement name; 49 private final ServiceCreds screds; 50 Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds)51 private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) { 52 /* 53 * Initialize this instance with the data from the acquired 54 * KerberosKey. This class needs to be a KerberosKey too 55 * hence we can't just store a reference. 56 */ 57 58 this.name = name; 59 this.screds = creds; 60 } 61 getInstance(final GSSCaller caller, Krb5NameElement name)62 static Krb5AcceptCredential getInstance(final GSSCaller caller, Krb5NameElement name) 63 throws GSSException { 64 65 final String serverPrinc = (name == null? null: 66 name.getKrb5PrincipalName().getName()); 67 final AccessControlContext acc = AccessController.getContext(); 68 69 ServiceCreds creds = null; 70 try { 71 creds = AccessController.doPrivileged( 72 new PrivilegedExceptionAction<ServiceCreds>() { 73 public ServiceCreds run() throws Exception { 74 return Krb5Util.getServiceCreds( 75 caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller, 76 serverPrinc, acc); 77 }}); 78 } catch (PrivilegedActionException e) { 79 GSSException ge = 80 new GSSException(GSSException.NO_CRED, -1, 81 "Attempt to obtain new ACCEPT credentials failed!"); 82 ge.initCause(e.getException()); 83 throw ge; 84 } 85 86 if (creds == null) 87 throw new GSSException(GSSException.NO_CRED, -1, 88 "Failed to find any Kerberos credentials"); 89 90 if (name == null) { 91 String fullName = creds.getName(); 92 if (fullName != null) { 93 name = Krb5NameElement.getInstance(fullName, 94 Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL); 95 } 96 } 97 98 return new Krb5AcceptCredential(name, creds); 99 } 100 101 /** 102 * Returns the principal name for this credential. The name 103 * is in mechanism specific format. 104 * 105 * @return GSSNameSpi representing principal name of this credential 106 * @exception GSSException may be thrown 107 */ getName()108 public final GSSNameSpi getName() throws GSSException { 109 return name; 110 } 111 112 /** 113 * Returns the init lifetime remaining. 114 * 115 * @return the init lifetime remaining in seconds 116 * @exception GSSException may be thrown 117 */ getInitLifetime()118 public int getInitLifetime() throws GSSException { 119 return 0; 120 } 121 122 /** 123 * Returns the accept lifetime remaining. 124 * 125 * @return the accept lifetime remaining in seconds 126 * @exception GSSException may be thrown 127 */ getAcceptLifetime()128 public int getAcceptLifetime() throws GSSException { 129 return GSSCredential.INDEFINITE_LIFETIME; 130 } 131 isInitiatorCredential()132 public boolean isInitiatorCredential() throws GSSException { 133 return false; 134 } 135 isAcceptorCredential()136 public boolean isAcceptorCredential() throws GSSException { 137 return true; 138 } 139 140 /** 141 * Returns the oid representing the underlying credential 142 * mechanism oid. 143 * 144 * @return the Oid for this credential mechanism 145 * @exception GSSException may be thrown 146 */ getMechanism()147 public final Oid getMechanism() { 148 return Krb5MechFactory.GSS_KRB5_MECH_OID; 149 } 150 getProvider()151 public final java.security.Provider getProvider() { 152 return Krb5MechFactory.PROVIDER; 153 } 154 getKrb5EncryptionKeys(PrincipalName princ)155 public EncryptionKey[] getKrb5EncryptionKeys(PrincipalName princ) { 156 return screds.getEKeys(princ); 157 } 158 159 /** 160 * Called to invalidate this credential element. 161 */ dispose()162 public void dispose() throws GSSException { 163 try { 164 destroy(); 165 } catch (DestroyFailedException e) { 166 GSSException gssException = 167 new GSSException(GSSException.FAILURE, -1, 168 "Could not destroy credentials - " + e.getMessage()); 169 gssException.initCause(e); 170 } 171 } 172 173 /** 174 * Destroys the locally cached EncryptionKey value and then calls 175 * destroy in the base class. 176 */ destroy()177 public void destroy() throws DestroyFailedException { 178 screds.destroy(); 179 } 180 181 /** 182 * Impersonation is only available on the initiator side. The 183 * service must starts as an initiator to get an initial TGT to complete 184 * the S4U2self protocol. 185 */ 186 @Override impersonate(GSSNameSpi name)187 public GSSCredentialSpi impersonate(GSSNameSpi name) throws GSSException { 188 Credentials cred = screds.getInitCred(); 189 if (cred != null) { 190 return Krb5InitCredential.getInstance(this.name, cred) 191 .impersonate(name); 192 } else { 193 throw new GSSException(GSSException.FAILURE, -1, 194 "Only an initiate credentials can impersonate"); 195 } 196 } 197 } 198