Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jgss/GSSUtil.java
38830 views
1
/*
2
* Copyright (c) 2000, 2017, 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;
27
28
import com.sun.security.auth.callback.TextCallbackHandler;
29
import javax.security.auth.Subject;
30
import javax.security.auth.kerberos.KerberosPrincipal;
31
import javax.security.auth.kerberos.KerberosTicket;
32
import javax.security.auth.kerberos.KerberosKey;
33
import org.ietf.jgss.*;
34
import sun.security.jgss.spi.GSSNameSpi;
35
import sun.security.jgss.spi.GSSCredentialSpi;
36
import sun.security.action.GetPropertyAction;
37
import sun.security.jgss.krb5.Krb5NameElement;
38
import sun.security.jgss.spnego.SpNegoCredElement;
39
import java.util.Set;
40
import java.util.HashSet;
41
import java.util.Vector;
42
import java.util.Iterator;
43
import java.security.AccessController;
44
import java.security.AccessControlContext;
45
import java.security.PrivilegedExceptionAction;
46
import java.security.PrivilegedActionException;
47
import javax.security.auth.callback.CallbackHandler;
48
import javax.security.auth.login.LoginContext;
49
import javax.security.auth.login.LoginException;
50
import sun.security.action.GetBooleanAction;
51
52
/**
53
* The GSSUtilImplementation that knows how to work with the internals of
54
* the GSS-API.
55
*/
56
public class GSSUtil {
57
58
public static final Oid GSS_KRB5_MECH_OID =
59
GSSUtil.createOid("1.2.840.113554.1.2.2");
60
public static final Oid GSS_KRB5_MECH_OID2 =
61
GSSUtil.createOid("1.3.5.1.5.2");
62
public static final Oid GSS_KRB5_MECH_OID_MS =
63
GSSUtil.createOid("1.2.840.48018.1.2.2");
64
65
public static final Oid GSS_SPNEGO_MECH_OID =
66
GSSUtil.createOid("1.3.6.1.5.5.2");
67
68
public static final Oid NT_GSS_KRB5_PRINCIPAL =
69
GSSUtil.createOid("1.2.840.113554.1.2.2.1");
70
71
private static final String DEFAULT_HANDLER =
72
"auth.login.defaultCallbackHandler";
73
74
static final boolean DEBUG;
75
static {
76
DEBUG = (AccessController.doPrivileged
77
(new GetBooleanAction("sun.security.jgss.debug"))).
78
booleanValue();
79
}
80
81
static void debug(String message) {
82
if (DEBUG) {
83
assert(message != null);
84
System.out.println(message);
85
}
86
}
87
88
// NOTE: this method is only for creating Oid objects with
89
// known to be valid <code>oidStr</code> given it ignores
90
// the GSSException
91
public static Oid createOid(String oidStr) {
92
try {
93
return new Oid(oidStr);
94
} catch (GSSException e) {
95
debug("Ignored invalid OID: " + oidStr);
96
return null;
97
}
98
}
99
100
public static boolean isSpNegoMech(Oid oid) {
101
return (GSS_SPNEGO_MECH_OID.equals(oid));
102
}
103
104
public static boolean isKerberosMech(Oid oid) {
105
return (GSS_KRB5_MECH_OID.equals(oid) ||
106
GSS_KRB5_MECH_OID2.equals(oid) ||
107
GSS_KRB5_MECH_OID_MS.equals(oid));
108
109
}
110
111
public static String getMechStr(Oid oid) {
112
if (isSpNegoMech(oid)) {
113
return "SPNEGO";
114
} else if (isKerberosMech(oid)) {
115
return "Kerberos V5";
116
} else {
117
return oid.toString();
118
}
119
}
120
121
/**
122
* Note: The current impl only works with Sun's impl of
123
* GSSName and GSSCredential since it depends on package
124
* private APIs.
125
*/
126
public static Subject getSubject(GSSName name,
127
GSSCredential creds) {
128
129
HashSet<Object> privCredentials = null;
130
HashSet<Object> pubCredentials = new HashSet<Object>(); // empty Set
131
132
Set<GSSCredentialSpi> gssCredentials = null;
133
134
Set<KerberosPrincipal> krb5Principals =
135
new HashSet<KerberosPrincipal>();
136
137
if (name instanceof GSSNameImpl) {
138
try {
139
GSSNameSpi ne = ((GSSNameImpl) name).getElement
140
(GSS_KRB5_MECH_OID);
141
String krbName = ne.toString();
142
if (ne instanceof Krb5NameElement) {
143
krbName =
144
((Krb5NameElement) ne).getKrb5PrincipalName().getName();
145
}
146
KerberosPrincipal krbPrinc = new KerberosPrincipal(krbName);
147
krb5Principals.add(krbPrinc);
148
} catch (GSSException ge) {
149
debug("Skipped name " + name + " due to " + ge);
150
}
151
}
152
153
if (creds instanceof GSSCredentialImpl) {
154
gssCredentials = ((GSSCredentialImpl) creds).getElements();
155
privCredentials = new HashSet<Object>(gssCredentials.size());
156
populateCredentials(privCredentials, gssCredentials);
157
} else {
158
privCredentials = new HashSet<Object>(); // empty Set
159
}
160
debug("Created Subject with the following");
161
debug("principals=" + krb5Principals);
162
debug("public creds=" + pubCredentials);
163
debug("private creds=" + privCredentials);
164
165
return new Subject(false, krb5Principals, pubCredentials,
166
privCredentials);
167
168
}
169
170
/**
171
* Populates the set credentials with elements from gssCredentials. At
172
* the same time, it converts any subclasses of KerberosTicket
173
* into KerberosTicket instances and any subclasses of KerberosKey into
174
* KerberosKey instances. (It is not desirable to expose the customer
175
* to sun.security.jgss.krb5.Krb5InitCredential which extends
176
* KerberosTicket and sun.security.jgss.krb5.Kbr5AcceptCredential which
177
* extends KerberosKey.)
178
*/
179
private static void populateCredentials(Set<Object> credentials,
180
Set<?> gssCredentials) {
181
182
Object cred;
183
184
Iterator<?> elements = gssCredentials.iterator();
185
while (elements.hasNext()) {
186
187
cred = elements.next();
188
189
// Retrieve the internal cred out of SpNegoCredElement
190
if (cred instanceof SpNegoCredElement) {
191
cred = ((SpNegoCredElement) cred).getInternalCred();
192
}
193
194
if (cred instanceof KerberosTicket) {
195
if (!cred.getClass().getName().equals
196
("javax.security.auth.kerberos.KerberosTicket")) {
197
KerberosTicket tempTkt = (KerberosTicket) cred;
198
cred = new KerberosTicket(tempTkt.getEncoded(),
199
tempTkt.getClient(),
200
tempTkt.getServer(),
201
tempTkt.getSessionKey().getEncoded(),
202
tempTkt.getSessionKeyType(),
203
tempTkt.getFlags(),
204
tempTkt.getAuthTime(),
205
tempTkt.getStartTime(),
206
tempTkt.getEndTime(),
207
tempTkt.getRenewTill(),
208
tempTkt.getClientAddresses());
209
}
210
credentials.add(cred);
211
} else if (cred instanceof KerberosKey) {
212
if (!cred.getClass().getName().equals
213
("javax.security.auth.kerberos.KerberosKey")) {
214
KerberosKey tempKey = (KerberosKey) cred;
215
cred = new KerberosKey(tempKey.getPrincipal(),
216
tempKey.getEncoded(),
217
tempKey.getKeyType(),
218
tempKey.getVersionNumber());
219
}
220
credentials.add(cred);
221
} else {
222
// Ignore non-KerberosTicket and non-KerberosKey elements
223
debug("Skipped cred element: " + cred);
224
}
225
}
226
}
227
228
/**
229
* Authenticate using the login module from the specified
230
* configuration entry.
231
*
232
* @param caller the caller of JAAS Login
233
* @param mech the mech to be used
234
* @return the authenticated subject
235
*/
236
public static Subject login(GSSCaller caller, Oid mech) throws LoginException {
237
238
CallbackHandler cb = null;
239
if (caller instanceof HttpCaller) {
240
cb = new sun.net.www.protocol.http.spnego.NegotiateCallbackHandler(
241
((HttpCaller)caller).info());
242
} else {
243
String defaultHandler =
244
java.security.Security.getProperty(DEFAULT_HANDLER);
245
// get the default callback handler
246
if ((defaultHandler != null) && (defaultHandler.length() != 0)) {
247
cb = null;
248
} else {
249
cb = new TextCallbackHandler();
250
}
251
}
252
253
// New instance of LoginConfigImpl must be created for each login,
254
// since the entry name is not passed as the first argument, but
255
// generated with caller and mech inside LoginConfigImpl
256
LoginContext lc = new LoginContext("", null, cb,
257
new LoginConfigImpl(caller, mech));
258
lc.login();
259
return lc.getSubject();
260
}
261
262
/**
263
* Determines if the application doesn't mind if the mechanism obtains
264
* the required credentials from outside of the current Subject. Our
265
* Kerberos v5 mechanism would do a JAAS login on behalf of the
266
* application if this were the case.
267
*
268
* The application indicates this by explicitly setting the system
269
* property javax.security.auth.useSubjectCredsOnly to false.
270
*/
271
public static boolean useSubjectCredsOnly(GSSCaller caller) {
272
273
String propValue = GetPropertyAction.privilegedGetProperty(
274
"javax.security.auth.useSubjectCredsOnly");
275
276
// Invalid values should be ignored and the default assumed.
277
if (caller instanceof HttpCaller) {
278
// Default for HTTP/SPNEGO is false.
279
return "true".equalsIgnoreCase(propValue);
280
} else {
281
// Default for JGSS is true.
282
return !("false".equalsIgnoreCase(propValue));
283
}
284
}
285
286
/**
287
* Determines the SPNEGO interoperability mode with Microsoft;
288
* by default it is set to true.
289
*
290
* To disable it, the application indicates this by explicitly setting
291
* the system property sun.security.spnego.interop to false.
292
*/
293
public static boolean useMSInterop() {
294
/*
295
* Don't use GetBooleanAction because the default value in the JRE
296
* (when this is unset) has to treated as true.
297
*/
298
String propValue = AccessController.doPrivileged(
299
new GetPropertyAction("sun.security.spnego.msinterop",
300
"true"));
301
/*
302
* This property has to be explicitly set to "false". Invalid
303
* values should be ignored and the default "true" assumed.
304
*/
305
return (!propValue.equalsIgnoreCase("false"));
306
}
307
308
/**
309
* Searches the private credentials of current Subject with the
310
* specified criteria and returns the matching GSSCredentialSpi
311
* object out of Sun's impl of GSSCredential. Returns null if
312
* no Subject present or a Vector which contains 0 or more
313
* matching GSSCredentialSpi objects.
314
*/
315
public static <T extends GSSCredentialSpi> Vector<T>
316
searchSubject(final GSSNameSpi name,
317
final Oid mech,
318
final boolean initiate,
319
final Class<? extends T> credCls) {
320
debug("Search Subject for " + getMechStr(mech) +
321
(initiate? " INIT" : " ACCEPT") + " cred (" +
322
(name == null? "<<DEF>>" : name.toString()) + ", " +
323
credCls.getName() + ")");
324
final AccessControlContext acc = AccessController.getContext();
325
try {
326
Vector<T> creds =
327
AccessController.doPrivileged
328
(new PrivilegedExceptionAction<Vector<T>>() {
329
public Vector<T> run() throws Exception {
330
Subject accSubj = Subject.getSubject(acc);
331
Vector<T> result = null;
332
if (accSubj != null) {
333
result = new Vector<T>();
334
Iterator<GSSCredentialImpl> iterator =
335
accSubj.getPrivateCredentials
336
(GSSCredentialImpl.class).iterator();
337
while (iterator.hasNext()) {
338
GSSCredentialImpl cred = iterator.next();
339
debug("...Found cred" + cred);
340
try {
341
GSSCredentialSpi ce =
342
cred.getElement(mech, initiate);
343
debug("......Found element: " + ce);
344
if (ce.getClass().equals(credCls) &&
345
(name == null ||
346
name.equals((Object) ce.getName()))) {
347
result.add(credCls.cast(ce));
348
} else {
349
debug("......Discard element");
350
}
351
} catch (GSSException ge) {
352
debug("...Discard cred (" + ge + ")");
353
}
354
}
355
} else debug("No Subject");
356
return result;
357
}
358
});
359
return creds;
360
} catch (PrivilegedActionException pae) {
361
debug("Unexpected exception when searching Subject:");
362
if (DEBUG) pae.printStackTrace();
363
return null;
364
}
365
}
366
}
367
368