author | rriggs |
Fri, 07 Dec 2018 11:51:17 -0500 | |
changeset 52902 | e3398b2e1ab0 |
parent 47216 | 71c04702a3d5 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
23010
6dadb192ad81
8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents:
21278
diff
changeset
|
2 |
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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. |
|
2 | 24 |
*/ |
25 |
||
26 |
package com.sun.jndi.ldap; |
|
27 |
||
28 |
import javax.naming.NamingException; |
|
29 |
import javax.naming.directory.InvalidSearchFilterException; |
|
30 |
||
31 |
import java.io.IOException; |
|
32 |
||
33 |
/** |
|
34 |
* LDAP (RFC-1960) and LDAPv3 (RFC-2254) search filters. |
|
35 |
* |
|
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
36 |
* @author Xuelei Fan |
2 | 37 |
* @author Vincent Ryan |
38 |
* @author Jagane Sundar |
|
39 |
* @author Rosanna Lee |
|
40 |
*/ |
|
41 |
||
42 |
final class Filter { |
|
43 |
||
44 |
/** |
|
45 |
* First convert filter string into byte[]. |
|
46 |
* For LDAP v3, the conversion uses Unicode -> UTF8 |
|
47 |
* For LDAP v2, the conversion uses Unicode -> ISO 8859 (Latin-1) |
|
48 |
* |
|
49 |
* Then parse the byte[] as a filter, converting \hh to |
|
50 |
* a single byte, and encoding the resulting filter |
|
51 |
* into the supplied BER buffer |
|
52 |
*/ |
|
53 |
static void encodeFilterString(BerEncoder ber, String filterStr, |
|
54 |
boolean isLdapv3) throws IOException, NamingException { |
|
55 |
||
52902
e3398b2e1ab0
8214971: Replace use of string.equals("") with isEmpty()
rriggs
parents:
47216
diff
changeset
|
56 |
if ((filterStr == null) || (filterStr.isEmpty())) { |
2 | 57 |
throw new InvalidSearchFilterException("Empty filter"); |
58 |
} |
|
59 |
byte[] filter; |
|
60 |
int filterLen; |
|
61 |
if (isLdapv3) { |
|
62 |
filter = filterStr.getBytes("UTF8"); |
|
63 |
} else { |
|
64 |
filter = filterStr.getBytes("8859_1"); |
|
65 |
} |
|
66 |
filterLen = filter.length; |
|
67 |
if (dbg) { |
|
68 |
dbgIndent = 0; |
|
69 |
System.err.println("String filter: " + filterStr); |
|
70 |
System.err.println("size: " + filterLen); |
|
71 |
dprint("original: ", filter, 0, filterLen); |
|
72 |
} |
|
73 |
||
74 |
encodeFilter(ber, filter, 0, filterLen); |
|
75 |
} |
|
76 |
||
77 |
private static void encodeFilter(BerEncoder ber, byte[] filter, |
|
78 |
int filterStart, int filterEnd) throws IOException, NamingException { |
|
79 |
||
80 |
if (dbg) { |
|
81 |
dprint("encFilter: ", filter, filterStart, filterEnd); |
|
82 |
dbgIndent++; |
|
83 |
} |
|
84 |
||
85 |
if ((filterEnd - filterStart) <= 0) { |
|
86 |
throw new InvalidSearchFilterException("Empty filter"); |
|
87 |
} |
|
88 |
||
89 |
int nextOffset; |
|
90 |
int parens, balance; |
|
91 |
boolean escape; |
|
92 |
||
93 |
parens = 0; |
|
94 |
||
95 |
int filtOffset[] = new int[1]; |
|
96 |
||
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
97 |
for (filtOffset[0] = filterStart; filtOffset[0] < filterEnd;) { |
2 | 98 |
switch (filter[filtOffset[0]]) { |
99 |
case '(': |
|
100 |
filtOffset[0]++; |
|
101 |
parens++; |
|
102 |
switch (filter[filtOffset[0]]) { |
|
103 |
case '&': |
|
104 |
encodeComplexFilter(ber, filter, |
|
105 |
LDAP_FILTER_AND, filtOffset, filterEnd); |
|
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
106 |
// filtOffset[0] has pointed to char after right paren |
2 | 107 |
parens--; |
108 |
break; |
|
109 |
||
110 |
case '|': |
|
111 |
encodeComplexFilter(ber, filter, |
|
112 |
LDAP_FILTER_OR, filtOffset, filterEnd); |
|
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
113 |
// filtOffset[0] has pointed to char after right paren |
2 | 114 |
parens--; |
115 |
break; |
|
116 |
||
117 |
case '!': |
|
118 |
encodeComplexFilter(ber, filter, |
|
119 |
LDAP_FILTER_NOT, filtOffset, filterEnd); |
|
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
120 |
// filtOffset[0] has pointed to char after right paren |
2 | 121 |
parens--; |
122 |
break; |
|
123 |
||
124 |
default: |
|
125 |
balance = 1; |
|
126 |
escape = false; |
|
127 |
nextOffset = filtOffset[0]; |
|
128 |
while (nextOffset < filterEnd && balance > 0) { |
|
129 |
if (!escape) { |
|
130 |
if (filter[nextOffset] == '(') |
|
131 |
balance++; |
|
132 |
else if (filter[nextOffset] == ')') |
|
133 |
balance--; |
|
134 |
} |
|
135 |
if (filter[nextOffset] == '\\' && !escape) |
|
136 |
escape = true; |
|
137 |
else |
|
138 |
escape = false; |
|
139 |
if (balance > 0) |
|
140 |
nextOffset++; |
|
141 |
} |
|
142 |
if (balance != 0) |
|
143 |
throw new InvalidSearchFilterException( |
|
144 |
"Unbalanced parenthesis"); |
|
145 |
||
146 |
encodeSimpleFilter(ber, filter, filtOffset[0], nextOffset); |
|
147 |
||
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
148 |
// points to the char after right paren. |
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
149 |
filtOffset[0] = nextOffset + 1; |
2 | 150 |
|
151 |
parens--; |
|
152 |
break; |
|
153 |
||
154 |
} |
|
155 |
break; |
|
156 |
||
157 |
case ')': |
|
158 |
// |
|
159 |
// End of sequence |
|
160 |
// |
|
161 |
ber.endSeq(); |
|
162 |
filtOffset[0]++; |
|
163 |
parens--; |
|
164 |
break; |
|
165 |
||
166 |
case ' ': |
|
167 |
filtOffset[0]++; |
|
168 |
break; |
|
169 |
||
170 |
default: // assume simple type=value filter |
|
171 |
encodeSimpleFilter(ber, filter, filtOffset[0], filterEnd); |
|
172 |
filtOffset[0] = filterEnd; // force break from outer |
|
173 |
break; |
|
174 |
} |
|
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
175 |
|
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
176 |
if (parens < 0) { |
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
177 |
throw new InvalidSearchFilterException( |
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
178 |
"Unbalanced parenthesis"); |
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
179 |
} |
2 | 180 |
} |
181 |
||
3325
0e7d9c6c9994
6449574: Invalid ldap filter is accepted and processed
xuelei
parents:
2
diff
changeset
|
182 |
if (parens != 0) { |
2 | 183 |
throw new InvalidSearchFilterException("Unbalanced parenthesis"); |
184 |
} |
|
185 |
||
186 |
if (dbg) { |
|
187 |
dbgIndent--; |
|
188 |
} |
|
189 |
||
190 |
} |
|
191 |
||
192 |
/** |
|
193 |
* convert character 'c' that represents a hexadecimal digit to an integer. |
|
21278 | 194 |
* if 'c' is not a hexadecimal digit [0-9A-Fa-f], -1 is returned. |
2 | 195 |
* otherwise the converted value is returned. |
196 |
*/ |
|
197 |
private static int hexchar2int( byte c ) { |
|
198 |
if ( c >= '0' && c <= '9' ) { |
|
199 |
return( c - '0' ); |
|
200 |
} |
|
201 |
if ( c >= 'A' && c <= 'F' ) { |
|
202 |
return( c - 'A' + 10 ); |
|
203 |
} |
|
204 |
if ( c >= 'a' && c <= 'f' ) { |
|
205 |
return( c - 'a' + 10 ); |
|
206 |
} |
|
207 |
return( -1 ); |
|
208 |
} |
|
209 |
||
210 |
// called by the LdapClient.compare method |
|
211 |
static byte[] unescapeFilterValue(byte[] orig, int start, int end) |
|
212 |
throws NamingException { |
|
213 |
boolean escape = false, escStart = false; |
|
214 |
int ival; |
|
215 |
byte ch; |
|
216 |
||
217 |
if (dbg) { |
|
218 |
dprint("unescape: " , orig, start, end); |
|
219 |
} |
|
220 |
||
221 |
int len = end - start; |
|
222 |
byte tbuf[] = new byte[len]; |
|
223 |
int j = 0; |
|
224 |
for (int i = start; i < end; i++) { |
|
225 |
ch = orig[i]; |
|
226 |
if (escape) { |
|
227 |
// Try LDAP V3 escape (\xx) |
|
228 |
if ((ival = hexchar2int(ch)) < 0) { |
|
229 |
||
230 |
/** |
|
231 |
* If there is no hex char following a '\' when |
|
232 |
* parsing a LDAP v3 filter (illegal by v3 way) |
|
233 |
* we fallback to the way we unescape in v2. |
|
234 |
*/ |
|
235 |
if (escStart) { |
|
236 |
// V2: \* \( \) |
|
237 |
escape = false; |
|
238 |
tbuf[j++] = ch; |
|
239 |
} else { |
|
240 |
// escaping already started but we can't find 2nd hex |
|
241 |
throw new InvalidSearchFilterException("invalid escape sequence: " + orig); |
|
242 |
} |
|
243 |
} else { |
|
244 |
if (escStart) { |
|
245 |
tbuf[j] = (byte)(ival<<4); |
|
246 |
escStart = false; |
|
247 |
} else { |
|
248 |
tbuf[j++] |= (byte)ival; |
|
249 |
escape = false; |
|
250 |
} |
|
251 |
} |
|
252 |
} else if (ch != '\\') { |
|
253 |
tbuf[j++] = ch; |
|
254 |
escape = false; |
|
255 |
} else { |
|
256 |
escStart = escape = true; |
|
257 |
} |
|
258 |
} |
|
259 |
byte[] answer = new byte[j]; |
|
260 |
System.arraycopy(tbuf, 0, answer, 0, j); |
|
261 |
if (dbg) { |
|
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
262 |
Ber.dumpBER(System.err, "", answer, 0, j); |
2 | 263 |
} |
264 |
return answer; |
|
265 |
} |
|
266 |
||
267 |
private static int indexOf(byte[] str, char ch, int start, int end) { |
|
268 |
for (int i = start; i < end; i++) { |
|
269 |
if (str[i] == ch) |
|
270 |
return i; |
|
271 |
} |
|
272 |
return -1; |
|
273 |
} |
|
274 |
||
275 |
private static int indexOf(byte[] str, String target, int start, int end) { |
|
276 |
int where = indexOf(str, target.charAt(0), start, end); |
|
277 |
if (where >= 0) { |
|
278 |
for (int i = 1; i < target.length(); i++) { |
|
279 |
if (str[where+i] != target.charAt(i)) { |
|
280 |
return -1; |
|
281 |
} |
|
282 |
} |
|
283 |
} |
|
284 |
return where; |
|
285 |
} |
|
286 |
||
287 |
private static int findUnescaped(byte[] str, char ch, int start, int end) { |
|
288 |
while (start < end) { |
|
289 |
int where = indexOf(str, ch, start, end); |
|
290 |
||
291 |
/* |
|
292 |
* Count the immediate preceding '\' to find out if |
|
293 |
* this is an escaped '*'. This is a made-up way for |
|
294 |
* parsing an escaped '*' in v2. This is how the other leading |
|
295 |
* SDK vendors interpret v2. |
|
296 |
* For v3 we fallback to the way we parse "\*" in v2. |
|
297 |
* It's not legal in v3 to use "\*" to escape '*'; the right |
|
298 |
* way is to use "\2a" instead. |
|
299 |
*/ |
|
300 |
int backSlashPos; |
|
301 |
int backSlashCnt = 0; |
|
302 |
for (backSlashPos = where - 1; |
|
303 |
((backSlashPos >= start) && (str[backSlashPos] == '\\')); |
|
304 |
backSlashPos--, backSlashCnt++); |
|
305 |
||
306 |
// if at start of string, or not there at all, or if not escaped |
|
307 |
if (where == start || where == -1 || ((backSlashCnt % 2) == 0)) |
|
308 |
return where; |
|
309 |
||
310 |
// start search after escaped star |
|
311 |
start = where + 1; |
|
312 |
} |
|
313 |
return -1; |
|
314 |
} |
|
315 |
||
316 |
||
317 |
private static void encodeSimpleFilter(BerEncoder ber, byte[] filter, |
|
318 |
int filtStart, int filtEnd) throws IOException, NamingException { |
|
319 |
||
320 |
if (dbg) { |
|
321 |
dprint("encSimpleFilter: ", filter, filtStart, filtEnd); |
|
322 |
dbgIndent++; |
|
323 |
} |
|
324 |
||
325 |
String type, value; |
|
326 |
int valueStart, valueEnd, typeStart, typeEnd; |
|
327 |
||
328 |
int eq; |
|
329 |
if ((eq = indexOf(filter, '=', filtStart, filtEnd)) == -1) { |
|
330 |
throw new InvalidSearchFilterException("Missing 'equals'"); |
|
331 |
} |
|
332 |
||
333 |
||
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
334 |
valueStart = eq + 1; // value starts after equal sign |
2 | 335 |
valueEnd = filtEnd; |
336 |
typeStart = filtStart; // beginning of string |
|
337 |
||
338 |
int ftype; |
|
339 |
||
340 |
switch (filter[eq - 1]) { |
|
341 |
case '<': |
|
342 |
ftype = LDAP_FILTER_LE; |
|
343 |
typeEnd = eq - 1; |
|
344 |
break; |
|
345 |
case '>': |
|
346 |
ftype = LDAP_FILTER_GE; |
|
347 |
typeEnd = eq - 1; |
|
348 |
break; |
|
349 |
case '~': |
|
350 |
ftype = LDAP_FILTER_APPROX; |
|
351 |
typeEnd = eq - 1; |
|
352 |
break; |
|
353 |
case ':': |
|
354 |
ftype = LDAP_FILTER_EXT; |
|
355 |
typeEnd = eq - 1; |
|
356 |
break; |
|
357 |
default: |
|
358 |
typeEnd = eq; |
|
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
359 |
//initializing ftype to make the compiler happy |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
360 |
ftype = 0x00; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
361 |
break; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
362 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
363 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
364 |
if (dbg) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
365 |
System.err.println("type: " + typeStart + ", " + typeEnd); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
366 |
System.err.println("value: " + valueStart + ", " + valueEnd); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
367 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
368 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
369 |
// check validity of type |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
370 |
// |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
371 |
// RFC4512 defines the type as the following ABNF: |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
372 |
// attr = attributedescription |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
373 |
// attributedescription = attributetype options |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
374 |
// attributetype = oid |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
375 |
// oid = descr / numericoid |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
376 |
// descr = keystring |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
377 |
// keystring = leadkeychar *keychar |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
378 |
// leadkeychar = ALPHA |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
379 |
// keychar = ALPHA / DIGIT / HYPHEN |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
380 |
// numericoid = number 1*( DOT number ) |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
381 |
// number = DIGIT / ( LDIGIT 1*DIGIT ) |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
382 |
// options = *( SEMI option ) |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
383 |
// option = 1*keychar |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
384 |
// |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
385 |
// And RFC4515 defines the extensible type as the following ABNF: |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
386 |
// attr [dnattrs] [matchingrule] / [dnattrs] matchingrule |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
387 |
int optionsStart = -1; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
388 |
int extensibleStart = -1; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
389 |
if ((filter[typeStart] >= '0' && filter[typeStart] <= '9') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
390 |
(filter[typeStart] >= 'A' && filter[typeStart] <= 'Z') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
391 |
(filter[typeStart] >= 'a' && filter[typeStart] <= 'z')) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
392 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
393 |
boolean isNumericOid = |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
394 |
filter[typeStart] >= '0' && filter[typeStart] <= '9'; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
395 |
for (int i = typeStart + 1; i < typeEnd; i++) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
396 |
// ';' is an indicator of attribute options |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
397 |
if (filter[i] == ';') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
398 |
if (isNumericOid && filter[i - 1] == '.') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
399 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
400 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
401 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
402 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
403 |
// attribute options |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
404 |
optionsStart = i; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
405 |
break; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
406 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
407 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
408 |
// ':' is an indicator of extensible rules |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
409 |
if (filter[i] == ':' && ftype == LDAP_FILTER_EXT) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
410 |
if (isNumericOid && filter[i - 1] == '.') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
411 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
412 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
413 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
414 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
415 |
// extensible matching |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
416 |
extensibleStart = i; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
417 |
break; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
418 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
419 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
420 |
if (isNumericOid) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
421 |
// numeric object identifier |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
422 |
if ((filter[i] == '.' && filter[i - 1] == '.') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
423 |
(filter[i] != '.' && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
424 |
!(filter[i] >= '0' && filter[i] <= '9'))) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
425 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
426 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
427 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
428 |
} else { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
429 |
// descriptor |
7520
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
430 |
// The underscore ("_") character is not allowed by |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
431 |
// the LDAP specification. We allow it here to |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
432 |
// tolerate the incorrect use in practice. |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
433 |
if (filter[i] != '-' && filter[i] != '_' && |
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
434 |
!(filter[i] >= '0' && filter[i] <= '9') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
435 |
!(filter[i] >= 'A' && filter[i] <= 'Z') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
436 |
!(filter[i] >= 'a' && filter[i] <= 'z')) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
437 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
438 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
439 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
440 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
441 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
442 |
} else if (ftype == LDAP_FILTER_EXT && filter[typeStart] == ':') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
443 |
// extensible matching |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
444 |
extensibleStart = typeStart; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
445 |
} else { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
446 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
447 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
448 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
449 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
450 |
// check attribute options |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
451 |
if (optionsStart > 0) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
452 |
for (int i = optionsStart + 1; i < typeEnd; i++) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
453 |
if (filter[i] == ';') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
454 |
if (filter[i - 1] == ';') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
455 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
456 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
457 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
458 |
continue; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
459 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
460 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
461 |
// ':' is an indicator of extensible rules |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
462 |
if (filter[i] == ':' && ftype == LDAP_FILTER_EXT) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
463 |
if (filter[i - 1] == ';') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
464 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
465 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
466 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
467 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
468 |
// extensible matching |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
469 |
extensibleStart = i; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
470 |
break; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
471 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
472 |
|
7520
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
473 |
// The underscore ("_") character is not allowed by |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
474 |
// the LDAP specification. We allow it here to |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
475 |
// tolerate the incorrect use in practice. |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
476 |
if (filter[i] != '-' && filter[i] != '_' && |
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
477 |
!(filter[i] >= '0' && filter[i] <= '9') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
478 |
!(filter[i] >= 'A' && filter[i] <= 'Z') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
479 |
!(filter[i] >= 'a' && filter[i] <= 'z')) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
480 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
481 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
482 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
483 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
484 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
485 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
486 |
// check extensible matching |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
487 |
if (extensibleStart > 0) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
488 |
boolean isMatchingRule = false; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
489 |
for (int i = extensibleStart + 1; i < typeEnd; i++) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
490 |
if (filter[i] == ':') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
491 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
492 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
493 |
} else if ((filter[i] >= '0' && filter[i] <= '9') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
494 |
(filter[i] >= 'A' && filter[i] <= 'Z') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
495 |
(filter[i] >= 'a' && filter[i] <= 'z')) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
496 |
boolean isNumericOid = filter[i] >= '0' && filter[i] <= '9'; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
497 |
i++; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
498 |
for (int j = i; j < typeEnd; j++, i++) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
499 |
// allows no more than two extensible rules |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
500 |
if (filter[j] == ':') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
501 |
if (isMatchingRule) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
502 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
503 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
504 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
505 |
if (isNumericOid && filter[j - 1] == '.') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
506 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
507 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
508 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
509 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
510 |
isMatchingRule = true; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
511 |
break; |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
512 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
513 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
514 |
if (isNumericOid) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
515 |
// numeric object identifier |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
516 |
if ((filter[j] == '.' && filter[j - 1] == '.') || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
517 |
(filter[j] != '.' && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
518 |
!(filter[j] >= '0' && filter[j] <= '9'))) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
519 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
520 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
521 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
522 |
} else { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
523 |
// descriptor |
7520
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
524 |
// The underscore ("_") character is not allowed by |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
525 |
// the LDAP specification. We allow it here to |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
526 |
// tolerate the incorrect use in practice. |
05eaa49f406b
6979376: to have ldap filters tolerate underscore character in object identifier
xuelei
parents:
6127
diff
changeset
|
527 |
if (filter[j] != '-' && filter[j] != '_' && |
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
528 |
!(filter[j] >= '0' && filter[j] <= '9') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
529 |
!(filter[j] >= 'A' && filter[j] <= 'Z') && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
530 |
!(filter[j] >= 'a' && filter[j] <= 'z')) { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
531 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
532 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
533 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
534 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
535 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
536 |
} else { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
537 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
538 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
539 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
540 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
541 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
542 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
543 |
// ensure the latest byte is not isolated |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
544 |
if (filter[typeEnd - 1] == '.' || filter[typeEnd - 1] == ';' || |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
545 |
filter[typeEnd - 1] == ':') { |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
546 |
throw new InvalidSearchFilterException( |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
547 |
"invalid attribute description"); |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
548 |
} |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
549 |
|
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
550 |
if (typeEnd == eq) { // filter type is of "equal" |
2 | 551 |
if (findUnescaped(filter, '*', valueStart, valueEnd) == -1) { |
552 |
ftype = LDAP_FILTER_EQUALITY; |
|
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
553 |
} else if (filter[valueStart] == '*' && |
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
554 |
valueStart == (valueEnd - 1)) { |
2 | 555 |
ftype = LDAP_FILTER_PRESENT; |
556 |
} else { |
|
557 |
encodeSubstringFilter(ber, filter, |
|
558 |
typeStart, typeEnd, valueStart, valueEnd); |
|
559 |
return; |
|
560 |
} |
|
561 |
} |
|
562 |
||
563 |
if (ftype == LDAP_FILTER_PRESENT) { |
|
564 |
ber.encodeOctetString(filter, ftype, typeStart, typeEnd-typeStart); |
|
565 |
} else if (ftype == LDAP_FILTER_EXT) { |
|
566 |
encodeExtensibleMatch(ber, filter, |
|
567 |
typeStart, typeEnd, valueStart, valueEnd); |
|
568 |
} else { |
|
569 |
ber.beginSeq(ftype); |
|
570 |
ber.encodeOctetString(filter, Ber.ASN_OCTET_STR, |
|
4978
6bee79de5db6
6916202: More cases of invalid ldap filters accepted and processed
xuelei
parents:
3325
diff
changeset
|
571 |
typeStart, typeEnd - typeStart); |
2 | 572 |
ber.encodeOctetString( |
573 |
unescapeFilterValue(filter, valueStart, valueEnd), |
|
574 |
Ber.ASN_OCTET_STR); |
|
575 |
ber.endSeq(); |
|
576 |
} |
|
577 |
||
578 |
if (dbg) { |
|
579 |
dbgIndent--; |
|
580 |
} |
|
581 |
} |
|
582 |
||
583 |
private static void encodeSubstringFilter(BerEncoder ber, byte[] filter, |
|
584 |
int typeStart, int typeEnd, int valueStart, int valueEnd) |
|
585 |
throws IOException, NamingException { |
|
586 |
||
587 |
if (dbg) { |
|
588 |
dprint("encSubstringFilter: type ", filter, typeStart, typeEnd); |
|
589 |
dprint(", val : ", filter, valueStart, valueEnd); |
|
590 |
dbgIndent++; |
|
591 |
} |
|
592 |
||
593 |
ber.beginSeq(LDAP_FILTER_SUBSTRINGS); |
|
594 |
ber.encodeOctetString(filter, Ber.ASN_OCTET_STR, |
|
595 |
typeStart, typeEnd-typeStart); |
|
596 |
ber.beginSeq(LdapClient.LBER_SEQUENCE); |
|
597 |
int index; |
|
598 |
int previndex = valueStart; |
|
599 |
while ((index = findUnescaped(filter, '*', previndex, valueEnd)) != -1) { |
|
600 |
if (previndex == valueStart) { |
|
601 |
if (previndex < index) { |
|
602 |
if (dbg) |
|
603 |
System.err.println( |
|
604 |
"initial: " + previndex + "," + index); |
|
605 |
ber.encodeOctetString( |
|
606 |
unescapeFilterValue(filter, previndex, index), |
|
607 |
LDAP_SUBSTRING_INITIAL); |
|
608 |
} |
|
609 |
} else { |
|
610 |
if (previndex < index) { |
|
611 |
if (dbg) |
|
612 |
System.err.println("any: " + previndex + "," + index); |
|
613 |
ber.encodeOctetString( |
|
614 |
unescapeFilterValue(filter, previndex, index), |
|
615 |
LDAP_SUBSTRING_ANY); |
|
616 |
} |
|
617 |
} |
|
618 |
previndex = index + 1; |
|
619 |
} |
|
620 |
if (previndex < valueEnd) { |
|
621 |
if (dbg) |
|
622 |
System.err.println("final: " + previndex + "," + valueEnd); |
|
623 |
ber.encodeOctetString( |
|
624 |
unescapeFilterValue(filter, previndex, valueEnd), |
|
625 |
LDAP_SUBSTRING_FINAL); |
|
626 |
} |
|
627 |
ber.endSeq(); |
|
628 |
ber.endSeq(); |
|
629 |
||
630 |
if (dbg) { |
|
631 |
dbgIndent--; |
|
632 |
} |
|
633 |
} |
|
634 |
||
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
635 |
// The complex filter types look like: |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
636 |
// "&(type=val)(type=val)" |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
637 |
// "|(type=val)(type=val)" |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
638 |
// "!(type=val)" |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
639 |
// |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
640 |
// The filtOffset[0] pointing to the '&', '|', or '!'. |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
641 |
// |
2 | 642 |
private static void encodeComplexFilter(BerEncoder ber, byte[] filter, |
643 |
int filterType, int filtOffset[], int filtEnd) |
|
644 |
throws IOException, NamingException { |
|
645 |
||
646 |
if (dbg) { |
|
647 |
dprint("encComplexFilter: ", filter, filtOffset[0], filtEnd); |
|
648 |
dprint(", type: " + Integer.toString(filterType, 16)); |
|
649 |
dbgIndent++; |
|
650 |
} |
|
651 |
||
652 |
filtOffset[0]++; |
|
653 |
||
654 |
ber.beginSeq(filterType); |
|
655 |
||
656 |
int[] parens = findRightParen(filter, filtOffset, filtEnd); |
|
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
657 |
encodeFilterList(ber, filter, filterType, parens[0], parens[1]); |
2 | 658 |
|
659 |
ber.endSeq(); |
|
660 |
||
661 |
if (dbg) { |
|
662 |
dbgIndent--; |
|
663 |
} |
|
664 |
||
665 |
} |
|
666 |
||
667 |
// |
|
668 |
// filter at filtOffset[0] - 1 points to a (. Find ) that matches it |
|
669 |
// and return substring between the parens. Adjust filtOffset[0] to |
|
670 |
// point to char after right paren |
|
671 |
// |
|
672 |
private static int[] findRightParen(byte[] filter, int filtOffset[], int end) |
|
673 |
throws IOException, NamingException { |
|
674 |
||
675 |
int balance = 1; |
|
676 |
boolean escape = false; |
|
677 |
int nextOffset = filtOffset[0]; |
|
678 |
||
679 |
while (nextOffset < end && balance > 0) { |
|
680 |
if (!escape) { |
|
681 |
if (filter[nextOffset] == '(') |
|
682 |
balance++; |
|
683 |
else if (filter[nextOffset] == ')') |
|
684 |
balance--; |
|
685 |
} |
|
686 |
if (filter[nextOffset] == '\\' && !escape) |
|
687 |
escape = true; |
|
688 |
else |
|
689 |
escape = false; |
|
690 |
if (balance > 0) |
|
691 |
nextOffset++; |
|
692 |
} |
|
693 |
if (balance != 0) { |
|
694 |
throw new InvalidSearchFilterException("Unbalanced parenthesis"); |
|
695 |
} |
|
696 |
||
697 |
// String tmp = filter.substring(filtOffset[0], nextOffset); |
|
698 |
||
699 |
int[] tmp = new int[] {filtOffset[0], nextOffset}; |
|
700 |
||
701 |
filtOffset[0] = nextOffset + 1; |
|
702 |
||
703 |
return tmp; |
|
704 |
||
705 |
} |
|
706 |
||
707 |
// |
|
708 |
// Encode filter list of type "(filter1)(filter2)..." |
|
709 |
// |
|
710 |
private static void encodeFilterList(BerEncoder ber, byte[] filter, |
|
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
711 |
int filterType, int start, int end) throws IOException, NamingException { |
2 | 712 |
|
713 |
if (dbg) { |
|
714 |
dprint("encFilterList: ", filter, start, end); |
|
715 |
dbgIndent++; |
|
716 |
} |
|
717 |
||
718 |
int filtOffset[] = new int[1]; |
|
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
719 |
int listNumber = 0; |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
720 |
for (filtOffset[0] = start; filtOffset[0] < end; filtOffset[0]++) { |
2 | 721 |
if (Character.isSpaceChar((char)filter[filtOffset[0]])) |
722 |
continue; |
|
723 |
||
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
724 |
if ((filterType == LDAP_FILTER_NOT) && (listNumber > 0)) { |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
725 |
throw new InvalidSearchFilterException( |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
726 |
"Filter (!) cannot be followed by more than one filters"); |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
727 |
} |
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
728 |
|
2 | 729 |
if (filter[filtOffset[0]] == '(') { |
730 |
continue; |
|
731 |
} |
|
732 |
||
733 |
int[] parens = findRightParen(filter, filtOffset, end); |
|
734 |
||
735 |
// add enclosing parens |
|
736 |
int len = parens[1]-parens[0]; |
|
737 |
byte[] newfilter = new byte[len+2]; |
|
738 |
System.arraycopy(filter, parens[0], newfilter, 1, len); |
|
739 |
newfilter[0] = (byte)'('; |
|
740 |
newfilter[len+1] = (byte)')'; |
|
741 |
encodeFilter(ber, newfilter, 0, newfilter.length); |
|
10113
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
742 |
|
b51717fb633d
7041125: LDAP API does not catch malformed filters that contain two operands for the ! operator
coffeys
parents:
7520
diff
changeset
|
743 |
listNumber++; |
2 | 744 |
} |
745 |
||
746 |
if (dbg) { |
|
747 |
dbgIndent--; |
|
748 |
} |
|
749 |
||
750 |
} |
|
751 |
||
752 |
// |
|
753 |
// Encode extensible match |
|
754 |
// |
|
755 |
private static void encodeExtensibleMatch(BerEncoder ber, byte[] filter, |
|
756 |
int matchStart, int matchEnd, int valueStart, int valueEnd) |
|
757 |
throws IOException, NamingException { |
|
758 |
||
759 |
boolean matchDN = false; |
|
760 |
int colon; |
|
761 |
int colon2; |
|
762 |
int i; |
|
763 |
||
764 |
ber.beginSeq(LDAP_FILTER_EXT); |
|
765 |
||
766 |
// test for colon separator |
|
767 |
if ((colon = indexOf(filter, ':', matchStart, matchEnd)) >= 0) { |
|
768 |
||
769 |
// test for match DN |
|
770 |
if ((i = indexOf(filter, ":dn", colon, matchEnd)) >= 0) { |
|
771 |
matchDN = true; |
|
772 |
} |
|
773 |
||
774 |
// test for matching rule |
|
775 |
if (((colon2 = indexOf(filter, ':', colon + 1, matchEnd)) >= 0) |
|
776 |
|| (i == -1)) { |
|
777 |
||
778 |
if (i == colon) { |
|
779 |
ber.encodeOctetString(filter, LDAP_FILTER_EXT_RULE, |
|
780 |
colon2 + 1, matchEnd - (colon2 + 1)); |
|
781 |
||
782 |
} else if ((i == colon2) && (i >= 0)) { |
|
783 |
ber.encodeOctetString(filter, LDAP_FILTER_EXT_RULE, |
|
784 |
colon + 1, colon2 - (colon + 1)); |
|
785 |
||
786 |
} else { |
|
787 |
ber.encodeOctetString(filter, LDAP_FILTER_EXT_RULE, |
|
788 |
colon + 1, matchEnd - (colon + 1)); |
|
789 |
} |
|
790 |
} |
|
791 |
||
792 |
// test for attribute type |
|
793 |
if (colon > matchStart) { |
|
794 |
ber.encodeOctetString(filter, |
|
795 |
LDAP_FILTER_EXT_TYPE, matchStart, colon - matchStart); |
|
796 |
} |
|
797 |
} else { |
|
798 |
ber.encodeOctetString(filter, LDAP_FILTER_EXT_TYPE, matchStart, |
|
799 |
matchEnd - matchStart); |
|
800 |
} |
|
801 |
||
802 |
ber.encodeOctetString( |
|
803 |
unescapeFilterValue(filter, valueStart, valueEnd), |
|
804 |
LDAP_FILTER_EXT_VAL); |
|
805 |
||
806 |
/* |
|
807 |
* This element is defined in RFC-2251 with an ASN.1 DEFAULT tag. |
|
808 |
* However, for Active Directory interoperability it is transmitted |
|
809 |
* even when FALSE. |
|
810 |
*/ |
|
811 |
ber.encodeBoolean(matchDN, LDAP_FILTER_EXT_DN); |
|
812 |
||
813 |
ber.endSeq(); |
|
814 |
} |
|
815 |
||
816 |
//////////////////////////////////////////////////////////////////////////// |
|
817 |
// |
|
818 |
// some debug print code that does indenting. Useful for debugging |
|
819 |
// the filter generation code |
|
820 |
// |
|
821 |
//////////////////////////////////////////////////////////////////////////// |
|
822 |
||
6127 | 823 |
private static final boolean dbg = false; |
2 | 824 |
private static int dbgIndent = 0; |
825 |
||
826 |
private static void dprint(String msg) { |
|
827 |
dprint(msg, new byte[0], 0, 0); |
|
828 |
} |
|
829 |
||
830 |
private static void dprint(String msg, byte[] str) { |
|
831 |
dprint(msg, str, 0, str.length); |
|
832 |
} |
|
833 |
||
834 |
private static void dprint(String msg, byte[] str, int start, int end) { |
|
835 |
String dstr = " "; |
|
836 |
int i = dbgIndent; |
|
837 |
while (i-- > 0) { |
|
838 |
dstr += " "; |
|
839 |
} |
|
840 |
dstr += msg; |
|
841 |
||
842 |
System.err.print(dstr); |
|
843 |
for (int j = start; j < end; j++) { |
|
844 |
System.err.print((char)str[j]); |
|
845 |
} |
|
846 |
System.err.println(); |
|
847 |
} |
|
848 |
||
849 |
/////////////// Constants used for encoding filter ////////////// |
|
850 |
||
851 |
static final int LDAP_FILTER_AND = 0xa0; |
|
852 |
static final int LDAP_FILTER_OR = 0xa1; |
|
853 |
static final int LDAP_FILTER_NOT = 0xa2; |
|
854 |
static final int LDAP_FILTER_EQUALITY = 0xa3; |
|
855 |
static final int LDAP_FILTER_SUBSTRINGS = 0xa4; |
|
856 |
static final int LDAP_FILTER_GE = 0xa5; |
|
857 |
static final int LDAP_FILTER_LE = 0xa6; |
|
858 |
static final int LDAP_FILTER_PRESENT = 0x87; |
|
859 |
static final int LDAP_FILTER_APPROX = 0xa8; |
|
860 |
static final int LDAP_FILTER_EXT = 0xa9; // LDAPv3 |
|
861 |
||
862 |
static final int LDAP_FILTER_EXT_RULE = 0x81; // LDAPv3 |
|
863 |
static final int LDAP_FILTER_EXT_TYPE = 0x82; // LDAPv3 |
|
864 |
static final int LDAP_FILTER_EXT_VAL = 0x83; // LDAPv3 |
|
865 |
static final int LDAP_FILTER_EXT_DN = 0x84; // LDAPv3 |
|
866 |
||
867 |
static final int LDAP_SUBSTRING_INITIAL = 0x80; |
|
868 |
static final int LDAP_SUBSTRING_ANY = 0x81; |
|
869 |
static final int LDAP_SUBSTRING_FINAL = 0x82; |
|
870 |
} |