Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java
67772 views
1
/*
2
* Copyright (c) 1999, 2022, 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 com.sun.jndi.ldap;
27
28
import javax.naming.*;
29
import java.net.MalformedURLException;
30
import java.io.UnsupportedEncodingException;
31
import java.net.URI;
32
import java.security.AccessController;
33
import java.security.PrivilegedAction;
34
import java.util.Locale;
35
import java.util.StringTokenizer;
36
import com.sun.jndi.toolkit.url.Uri;
37
import com.sun.jndi.toolkit.url.UrlUtil;
38
39
/*
40
* Extract components of an LDAP URL.
41
*
42
* The format of an LDAP URL is defined in RFC 2255 as follows:
43
*
44
* ldapurl = scheme "://" [hostport] ["/"
45
* [dn ["?" [attributes] ["?" [scope]
46
* ["?" [filter] ["?" extensions]]]]]]
47
* scheme = "ldap"
48
* attributes = attrdesc *("," attrdesc)
49
* scope = "base" / "one" / "sub"
50
* dn = distinguishedName from Section 3 of [1]
51
* hostport = hostport from Section 5 of RFC 1738 [5]
52
* attrdesc = AttributeDescription from Section 4.1.5 of [2]
53
* filter = filter from Section 4 of [4]
54
* extensions = extension *("," extension)
55
* extension = ["!"] extype ["=" exvalue]
56
* extype = token / xtoken
57
* exvalue = LDAPString from section 4.1.2 of [2]
58
* token = oid from section 4.1 of [3]
59
* xtoken = ("X-" / "x-") token
60
*
61
* For example,
62
*
63
* ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US
64
* ldap://host.com:6666/o=IMC,c=US??sub?(cn=Babs%20Jensen)
65
*
66
* This class also supports ldaps URLs.
67
*/
68
69
public final class LdapURL extends Uri {
70
71
private static final String PARSE_MODE_PROP = "com.sun.jndi.ldapURLParsing";
72
private static final ParseMode DEFAULT_PARSE_MODE = ParseMode.COMPAT;
73
74
public static final ParseMode PARSE_MODE;
75
static {
76
PrivilegedAction<String> action = () ->
77
System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
78
ParseMode parseMode = DEFAULT_PARSE_MODE;
79
try {
80
@SuppressWarnings("removal")
81
String mode = AccessController.doPrivileged(action);
82
parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT));
83
} catch (Throwable t) {
84
parseMode = DEFAULT_PARSE_MODE;
85
} finally {
86
PARSE_MODE = parseMode;
87
}
88
}
89
90
private boolean useSsl = false;
91
private String DN = null;
92
private String attributes = null;
93
private String scope = null;
94
private String filter = null;
95
private String extensions = null;
96
97
/**
98
* Creates an LdapURL object from an LDAP URL string.
99
*/
100
public LdapURL(String url) throws NamingException {
101
102
super();
103
104
try {
105
init(url); // scheme, host, port, path, query
106
useSsl = scheme.equalsIgnoreCase("ldaps");
107
108
if (! (scheme.equalsIgnoreCase("ldap") || useSsl)) {
109
throw newInvalidURISchemeException(url);
110
}
111
112
parsePathAndQuery(); // DN, attributes, scope, filter, extensions
113
114
} catch (MalformedURLException e) {
115
NamingException ne = new NamingException("Cannot parse url: " + url);
116
ne.setRootCause(e);
117
throw ne;
118
} catch (UnsupportedEncodingException e) {
119
NamingException ne = new NamingException("Cannot parse url: " + url);
120
ne.setRootCause(e);
121
throw ne;
122
}
123
}
124
125
@Override
126
protected MalformedURLException newInvalidURISchemeException(String uri) {
127
return new MalformedURLException("Not an LDAP URL: " + uri);
128
}
129
130
@Override
131
protected boolean isSchemeOnly(String uri) {
132
return isLdapSchemeOnly(uri);
133
}
134
135
@Override
136
protected ParseMode parseMode() {
137
return PARSE_MODE;
138
}
139
140
/**
141
* Returns true if the URL is an LDAPS URL.
142
*/
143
public boolean useSsl() {
144
return useSsl;
145
}
146
147
/**
148
* Returns the LDAP URL's distinguished name.
149
*/
150
public String getDN() {
151
return DN;
152
}
153
154
/**
155
* Returns the LDAP URL's attributes.
156
*/
157
public String getAttributes() {
158
return attributes;
159
}
160
161
/**
162
* Returns the LDAP URL's scope.
163
*/
164
public String getScope() {
165
return scope;
166
}
167
168
/**
169
* Returns the LDAP URL's filter.
170
*/
171
public String getFilter() {
172
return filter;
173
}
174
175
/**
176
* Returns the LDAP URL's extensions.
177
*/
178
public String getExtensions() {
179
return extensions;
180
}
181
182
/**
183
* Given a space-separated list of LDAP URLs, returns an array of strings.
184
*/
185
public static String[] fromList(String urlList) throws NamingException {
186
187
String[] urls = new String[(urlList.length() + 1) / 2];
188
int i = 0; // next available index in urls
189
StringTokenizer st = new StringTokenizer(urlList, " ");
190
191
while (st.hasMoreTokens()) {
192
// we don't accept scheme-only URLs here
193
urls[i++] = validateURI(st.nextToken());
194
}
195
String[] trimmed = new String[i];
196
System.arraycopy(urls, 0, trimmed, 0, i);
197
return trimmed;
198
}
199
200
public static boolean isLdapSchemeOnly(String uri) {
201
return "ldap:".equals(uri) || "ldaps:".equals(uri);
202
}
203
204
public static String validateURI(String uri) {
205
// no validation in legacy mode parsing
206
if (PARSE_MODE == ParseMode.LEGACY) {
207
return uri;
208
}
209
210
// special case of scheme-only URIs
211
if (isLdapSchemeOnly(uri)) {
212
return uri;
213
}
214
215
// use java.net.URI to validate the uri syntax
216
return URI.create(uri).toString();
217
}
218
219
/**
220
* Determines whether an LDAP URL has query components.
221
*/
222
public static boolean hasQueryComponents(String url) {
223
return (url.lastIndexOf('?') != -1);
224
}
225
226
/*
227
* Assembles an LDAP or LDAPS URL string from its components.
228
* If "host" is an IPv6 literal, it may optionally include delimiting
229
* brackets.
230
*/
231
static String toUrlString(String host, int port, String dn, boolean useSsl)
232
{
233
234
try {
235
String h = (host != null) ? host : "";
236
if ((h.indexOf(':') != -1) && (h.charAt(0) != '[')) {
237
h = "[" + h + "]"; // IPv6 literal
238
}
239
String p = (port != -1) ? (":" + port) : "";
240
String d = (dn != null) ? ("/" + UrlUtil.encode(dn, "UTF8")) : "";
241
242
String uri = useSsl ? "ldaps://" + h + p + d : "ldap://" + h + p + d;
243
return validateURI(uri);
244
} catch (UnsupportedEncodingException e) {
245
// UTF8 should always be supported
246
throw new IllegalStateException("UTF-8 encoding unavailable");
247
}
248
}
249
250
/*
251
* Parses the path and query components of an URL and sets this
252
* object's fields accordingly.
253
*/
254
private void parsePathAndQuery() throws MalformedURLException,
255
UnsupportedEncodingException {
256
257
// path begins with a '/' or is empty
258
259
if (path.isEmpty()) {
260
return;
261
}
262
263
DN = path.startsWith("/") ? path.substring(1) : path;
264
if (DN.length() > 0) {
265
DN = UrlUtil.decode(DN, "UTF8");
266
}
267
268
// query begins with a '?' or is null
269
270
if (query == null || query.length() < 2) {
271
return;
272
}
273
274
int currentIndex = 1;
275
int nextQmark;
276
int endIndex;
277
278
// attributes:
279
nextQmark = query.indexOf('?', currentIndex);
280
endIndex = nextQmark == -1 ? query.length() : nextQmark;
281
if (endIndex - currentIndex > 0) {
282
attributes = query.substring(currentIndex, endIndex);
283
}
284
currentIndex = endIndex + 1;
285
if (currentIndex >= query.length()) {
286
return;
287
}
288
289
// scope:
290
nextQmark = query.indexOf('?', currentIndex);
291
endIndex = nextQmark == -1 ? query.length() : nextQmark;
292
if (endIndex - currentIndex > 0) {
293
scope = query.substring(currentIndex, endIndex);
294
}
295
currentIndex = endIndex + 1;
296
if (currentIndex >= query.length()) {
297
return;
298
}
299
300
// filter:
301
nextQmark = query.indexOf('?', currentIndex);
302
endIndex = nextQmark == -1 ? query.length() : nextQmark;
303
if (endIndex - currentIndex > 0) {
304
filter = query.substring(currentIndex, endIndex);
305
filter = UrlUtil.decode(filter, "UTF8");
306
}
307
currentIndex = endIndex + 1;
308
if (currentIndex >= query.length()) {
309
return;
310
}
311
312
// extensions:
313
if (query.length() - currentIndex > 0) {
314
extensions = query.substring(currentIndex);
315
extensions = UrlUtil.decode(extensions, "UTF8");
316
}
317
}
318
319
/*
320
public static void main(String[] args) throws Exception {
321
322
LdapURL url = new LdapURL(args[0]);
323
324
System.out.println("Example LDAP URL: " + url.toString());
325
System.out.println(" scheme: " + url.getScheme());
326
System.out.println(" host: " + url.getHost());
327
System.out.println(" port: " + url.getPort());
328
System.out.println(" DN: " + url.getDN());
329
System.out.println(" attrs: " + url.getAttributes());
330
System.out.println(" scope: " + url.getScope());
331
System.out.println(" filter: " + url.getFilter());
332
System.out.println(" extens: " + url.getExtensions());
333
System.out.println("");
334
}
335
*/
336
}
337
338