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