blob: 3fb48351a9c45a59aee5bb33383d760d60e4abc0 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.jgss.krb5;
27
28import org.ietf.jgss.*;
29import sun.security.jgss.GSSUtil;
30import sun.security.jgss.spi.*;
31import sun.security.krb5.*;
32import javax.security.auth.kerberos.*;
33import java.io.IOException;
34import java.security.PrivilegedActionException;
35import java.security.PrivilegedExceptionAction;
36import java.security.AccessController;
37import java.security.AccessControlContext;
38import javax.security.auth.DestroyFailedException;
39
40/**
41 * Implements the krb5 acceptor credential element.
42 *
43 * @author Mayank Upadhyay
44 * @since 1.4
45 */
46public class Krb5AcceptCredential
47 extends KerberosKey
48 implements Krb5CredElement {
49
50 private static final long serialVersionUID = 7714332137352567952L;
51
52 private Krb5NameElement name;
53
54 /**
55 * We cache an EncryptionKey representation of this key because many
56 * Krb5 operation require a key in that form. At some point we might do
57 * away with EncryptionKey altogether and use the base class
58 * KerberosKey everywhere.
59 */
60 private EncryptionKey[] krb5EncryptionKeys;
61
62 private Krb5AcceptCredential(Krb5NameElement name, KerberosKey[] keys) {
63 /*
64 * Initialize this instance with the data from the acquired
65 * KerberosKey. This class needs to be a KerberosKey too
66 * hence we can't just store a reference.
67 */
68 super(keys[0].getPrincipal(),
69 keys[0].getEncoded(),
70 keys[0].getKeyType(),
71 keys[0].getVersionNumber());
72
73 this.name = name;
74 // Cache this for later use by the sun.security.krb5 package.
75 krb5EncryptionKeys = new EncryptionKey[keys.length];
76 for (int i = 0; i < keys.length; i++) {
77 krb5EncryptionKeys[i] = new EncryptionKey(keys[i].getEncoded(),
78 keys[i].getKeyType(),
79 new Integer(keys[i].getVersionNumber()));
80 }
81 }
82
83 static Krb5AcceptCredential getInstance(final int caller, Krb5NameElement name)
84 throws GSSException {
85
86 final String serverPrinc = (name == null? null:
87 name.getKrb5PrincipalName().getName());
88 final AccessControlContext acc = AccessController.getContext();
89
90 KerberosKey[] keys;
91 try {
92 keys = AccessController.doPrivileged(
93 new PrivilegedExceptionAction<KerberosKey[]>() {
94 public KerberosKey[] run() throws Exception {
95 return Krb5Util.getKeys(
96 caller == GSSUtil.CALLER_UNKNOWN ? GSSUtil.CALLER_ACCEPT: caller,
97 serverPrinc, acc);
98 }});
99 } catch (PrivilegedActionException e) {
100 GSSException ge =
101 new GSSException(GSSException.NO_CRED, -1,
102 "Attempt to obtain new ACCEPT credentials failed!");
103 ge.initCause(e.getException());
104 throw ge;
105 }
106
107 if (keys == null || keys.length == 0)
108 throw new GSSException(GSSException.NO_CRED, -1,
109 "Failed to find any Kerberos Key");
110
111 if (name == null) {
112 String fullName = keys[0].getPrincipal().getName();
113 name = Krb5NameElement.getInstance(fullName,
114 Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
115 }
116
117 return new Krb5AcceptCredential(name, keys);
118 }
119
120 /**
121 * Returns the principal name for this credential. The name
122 * is in mechanism specific format.
123 *
124 * @return GSSNameSpi representing principal name of this credential
125 * @exception GSSException may be thrown
126 */
127 public final GSSNameSpi getName() throws GSSException {
128 return name;
129 }
130
131 /**
132 * Returns the init lifetime remaining.
133 *
134 * @return the init lifetime remaining in seconds
135 * @exception GSSException may be thrown
136 */
137 public int getInitLifetime() throws GSSException {
138 return 0;
139 }
140
141 /**
142 * Returns the accept lifetime remaining.
143 *
144 * @return the accept lifetime remaining in seconds
145 * @exception GSSException may be thrown
146 */
147 public int getAcceptLifetime() throws GSSException {
148 return GSSCredential.INDEFINITE_LIFETIME;
149 }
150
151 public boolean isInitiatorCredential() throws GSSException {
152 return false;
153 }
154
155 public boolean isAcceptorCredential() throws GSSException {
156 return true;
157 }
158
159 /**
160 * Returns the oid representing the underlying credential
161 * mechanism oid.
162 *
163 * @return the Oid for this credential mechanism
164 * @exception GSSException may be thrown
165 */
166 public final Oid getMechanism() {
167 return Krb5MechFactory.GSS_KRB5_MECH_OID;
168 }
169
170 public final java.security.Provider getProvider() {
171 return Krb5MechFactory.PROVIDER;
172 }
173
174 EncryptionKey[] getKrb5EncryptionKeys() {
175 return krb5EncryptionKeys;
176 }
177
178 /**
179 * Called to invalidate this credential element.
180 */
181 public void dispose() throws GSSException {
182 try {
183 destroy();
184 } catch (DestroyFailedException e) {
185 GSSException gssException =
186 new GSSException(GSSException.FAILURE, -1,
187 "Could not destroy credentials - " + e.getMessage());
188 gssException.initCause(e);
189 }
190 }
191
192 /**
193 * Destroys the locally cached EncryptionKey value and then calls
194 * destroy in the base class.
195 */
196 public void destroy() throws DestroyFailedException {
197 if (krb5EncryptionKeys != null) {
198 for (int i = 0; i < krb5EncryptionKeys.length; i++) {
199 krb5EncryptionKeys[i].destroy();
200 }
201 krb5EncryptionKeys = null;
202 }
203
204 super.destroy();
205 }
206}