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/krb5/Krb5NameElement.java
38922 views
1
/*
2
* Copyright (c) 2000, 2019, 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 org.ietf.jgss.*;
29
import sun.security.jgss.spi.*;
30
import sun.security.krb5.PrincipalName;
31
import sun.security.krb5.Realm;
32
import sun.security.krb5.KrbException;
33
34
import javax.security.auth.kerberos.ServicePermission;
35
import java.io.UnsupportedEncodingException;
36
import java.net.InetAddress;
37
import java.net.UnknownHostException;
38
import java.security.Provider;
39
import java.util.Locale;
40
41
/**
42
* Implements the GSSNameSpi for the krb5 mechanism.
43
*
44
* @author Mayank Upadhyay
45
*/
46
public class Krb5NameElement
47
implements GSSNameSpi {
48
49
private PrincipalName krb5PrincipalName;
50
51
private String gssNameStr = null;
52
private Oid gssNameType = null;
53
54
// XXX Move this concept into PrincipalName's asn1Encode() sometime
55
private static String CHAR_ENCODING = "UTF-8";
56
57
private Krb5NameElement(PrincipalName principalName,
58
String gssNameStr,
59
Oid gssNameType) {
60
this.krb5PrincipalName = principalName;
61
this.gssNameStr = gssNameStr;
62
this.gssNameType = gssNameType;
63
}
64
65
/**
66
* Instantiates a new Krb5NameElement object. Internally it stores the
67
* information provided by the input parameters so that they may later
68
* be used for output when a printable representaion of this name is
69
* needed in GSS-API format rather than in Kerberos format.
70
*
71
*/
72
static Krb5NameElement getInstance(String gssNameStr, Oid gssNameType)
73
throws GSSException {
74
75
/*
76
* A null gssNameType implies that the mechanism default
77
* Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL be used.
78
*/
79
if (gssNameType == null)
80
gssNameType = Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL;
81
else
82
if (!gssNameType.equals(GSSName.NT_USER_NAME) &&
83
!gssNameType.equals(GSSName.NT_HOSTBASED_SERVICE) &&
84
!gssNameType.equals(Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL) &&
85
!gssNameType.equals(GSSName.NT_EXPORT_NAME))
86
throw new GSSException(GSSException.BAD_NAMETYPE, -1,
87
gssNameType.toString()
88
+" is an unsupported nametype");
89
90
PrincipalName principalName;
91
try {
92
93
if (gssNameType.equals(GSSName.NT_EXPORT_NAME) ||
94
gssNameType.equals(Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL)) {
95
principalName = new PrincipalName(gssNameStr,
96
PrincipalName.KRB_NT_PRINCIPAL);
97
} else {
98
99
String[] components = getComponents(gssNameStr);
100
101
/*
102
* We have forms of GSS name strings that can come in:
103
*
104
* 1. names of the form "foo" with just one
105
* component. (This might include a "@" but only in escaped
106
* form like "\@")
107
* 2. names of the form "foo@bar" with two components
108
*
109
* The nametypes that are accepted are NT_USER_NAME, and
110
* NT_HOSTBASED_SERVICE.
111
*/
112
113
if (gssNameType.equals(GSSName.NT_USER_NAME))
114
principalName = new PrincipalName(gssNameStr,
115
PrincipalName.KRB_NT_PRINCIPAL);
116
else {
117
String hostName = null;
118
String service = components[0];
119
if (components.length >= 2)
120
hostName = components[1];
121
122
String principal = getHostBasedInstance(service, hostName);
123
principalName = new PrincipalName(principal,
124
PrincipalName.KRB_NT_SRV_HST);
125
}
126
}
127
128
} catch (KrbException e) {
129
throw new GSSException(GSSException.BAD_NAME, -1, e.getMessage());
130
}
131
132
if (principalName.isRealmDeduced() && !Realm.AUTODEDUCEREALM) {
133
SecurityManager sm = System.getSecurityManager();
134
if (sm != null) {
135
try {
136
sm.checkPermission(new ServicePermission(
137
"@" + principalName.getRealmAsString(), "-"));
138
} catch (SecurityException se) {
139
// Do not chain the actual exception to hide info
140
throw new GSSException(GSSException.FAILURE);
141
}
142
}
143
}
144
return new Krb5NameElement(principalName, gssNameStr, gssNameType);
145
}
146
147
public static Krb5NameElement getInstance(PrincipalName principalName) {
148
return new Krb5NameElement(principalName,
149
principalName.getName(),
150
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
151
}
152
153
private static String[] getComponents(String gssNameStr)
154
throws GSSException {
155
156
String[] retVal;
157
158
// XXX Perhaps provide this parsing code in PrincipalName
159
160
// Look for @ as in service@host
161
// Assumes host name will not have an escaped '@'
162
int separatorPos = gssNameStr.lastIndexOf('@', gssNameStr.length());
163
164
// Not really a separator if it is escaped. Then this is just part
165
// of the principal name or service name
166
if ((separatorPos > 0) &&
167
(gssNameStr.charAt(separatorPos-1) == '\\')) {
168
// Is the `\` character escaped itself?
169
if ((separatorPos - 2 < 0) ||
170
(gssNameStr.charAt(separatorPos-2) != '\\'))
171
separatorPos = -1;
172
}
173
174
if (separatorPos > 0) {
175
String serviceName = gssNameStr.substring(0, separatorPos);
176
String hostName = gssNameStr.substring(separatorPos+1);
177
retVal = new String[] { serviceName, hostName};
178
} else {
179
retVal = new String[] {gssNameStr};
180
}
181
182
return retVal;
183
184
}
185
186
private static String getHostBasedInstance(String serviceName,
187
String hostName)
188
throws GSSException {
189
StringBuffer temp = new StringBuffer(serviceName);
190
191
try {
192
// A lack of "@" defaults to the service being on the local
193
// host as per RFC 2743
194
// XXX Move this part into JGSS framework
195
if (hostName == null)
196
hostName = InetAddress.getLocalHost().getHostName();
197
198
} catch (UnknownHostException e) {
199
// use hostname as it is
200
}
201
hostName = hostName.toLowerCase(Locale.ENGLISH);
202
203
temp = temp.append('/').append(hostName);
204
return temp.toString();
205
}
206
207
public final PrincipalName getKrb5PrincipalName() {
208
return krb5PrincipalName;
209
}
210
211
/**
212
* Equal method for the GSSNameSpi objects.
213
* If either name denotes an anonymous principal, the call should
214
* return false.
215
*
216
* @param other to be compared with
217
* @return true if they both refer to the same entity, else false
218
* @exception GSSException with major codes of BAD_NAMETYPE,
219
* BAD_NAME, FAILURE
220
*/
221
public boolean equals(GSSNameSpi other) throws GSSException {
222
223
if (other == this)
224
return true;
225
226
if (other instanceof Krb5NameElement) {
227
Krb5NameElement that = (Krb5NameElement) other;
228
return (this.krb5PrincipalName.getName().equals(
229
that.krb5PrincipalName.getName()));
230
}
231
return false;
232
}
233
234
/**
235
* Compares this <code>GSSNameSpi</code> object to another Object
236
* that might be a <code>GSSNameSpi</code>. The behaviour is exactly
237
* the same as in {@link #equals(GSSNameSpi) equals} except that
238
* no GSSException is thrown; instead, false will be returned in the
239
* situation where an error occurs.
240
*
241
* @param another the object to be compared to
242
* @return true if they both refer to the same entity, else false
243
* @see #equals(GSSNameSpi)
244
*/
245
public boolean equals(Object another) {
246
if (this == another) {
247
return true;
248
}
249
250
try {
251
if (another instanceof Krb5NameElement)
252
return equals((Krb5NameElement) another);
253
} catch (GSSException e) {
254
// ignore exception
255
}
256
return false;
257
}
258
259
/**
260
* Returns a hashcode value for this GSSNameSpi.
261
*
262
* @return a hashCode value
263
*/
264
public int hashCode() {
265
return 37 * 17 + krb5PrincipalName.getName().hashCode();
266
}
267
268
269
/**
270
* Returns the principal name in the form user@REALM or
271
* host/service@REALM but with the following constraints that are
272
* imposed by RFC 1964:
273
* <pre>
274
* (1) all occurrences of the characters `@`, `/`, and `\` within
275
* principal components or realm names shall be quoted with an
276
* immediately-preceding `\`.
277
*
278
* (2) all occurrences of the null, backspace, tab, or newline
279
* characters within principal components or realm names will be
280
* represented, respectively, with `\0`, `\b`, `\t`, or `\n`.
281
*
282
* (3) the `\` quoting character shall not be emitted within an
283
* exported name except to accommodate cases (1) and (2).
284
* </pre>
285
*/
286
public byte[] export() throws GSSException {
287
// XXX Apply the above constraints.
288
byte[] retVal = null;
289
try {
290
retVal = krb5PrincipalName.getName().getBytes(CHAR_ENCODING);
291
} catch (UnsupportedEncodingException e) {
292
// Can't happen
293
}
294
return retVal;
295
}
296
297
/**
298
* Get the mechanism type that this NameElement corresponds to.
299
*
300
* @return the Oid of the mechanism type
301
*/
302
public Oid getMechanism() {
303
return (Krb5MechFactory.GSS_KRB5_MECH_OID);
304
}
305
306
/**
307
* Returns a string representation for this name. The printed
308
* name type can be obtained by calling getStringNameType().
309
*
310
* @return string form of this name
311
* @see #getStringNameType()
312
* @overrides Object#toString
313
*/
314
public String toString() {
315
return (gssNameStr);
316
// For testing: return (super.toString());
317
}
318
319
/**
320
* Returns the name type oid.
321
*/
322
public Oid getGSSNameType() {
323
return (gssNameType);
324
}
325
326
/**
327
* Returns the oid describing the format of the printable name.
328
*
329
* @return the Oid for the format of the printed name
330
*/
331
public Oid getStringNameType() {
332
// XXX For NT_EXPORT_NAME return a different name type. Infact,
333
// don't even store NT_EXPORT_NAME in the cons.
334
return (gssNameType);
335
}
336
337
/**
338
* Indicates if this name object represents an Anonymous name.
339
*/
340
public boolean isAnonymousName() {
341
return (gssNameType.equals(GSSName.NT_ANONYMOUS));
342
}
343
344
public Provider getProvider() {
345
return Krb5MechFactory.PROVIDER;
346
}
347
348
}
349
350