|
1 /* |
|
2 * Copyright 2010 Sun Microsystems, Inc. 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. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 * have any questions. |
|
22 */ |
|
23 |
|
24 /** |
|
25 * @test |
|
26 * @bug 6916202 |
|
27 * @summary More cases of invalid ldap filters accepted and processed |
|
28 * @run main/othervm InvalidLdapFilters valid (cn=Babs) |
|
29 * @run main/othervm InvalidLdapFilters valid (&(cn=Bob)) |
|
30 * @run main/othervm InvalidLdapFilters valid (&(objectClass=*)(uid=*)) |
|
31 * @run main/othervm InvalidLdapFilters valid (|(cn=Bob)) |
|
32 * @run main/othervm InvalidLdapFilters valid (|(objectClass=*)(uid=*)) |
|
33 * @run main/othervm InvalidLdapFilters valid (!(cn=Tim)) |
|
34 * @run main/othervm InvalidLdapFilters valid (!(!(cn=Tim))) |
|
35 * @run main/othervm InvalidLdapFilters valid (!(&(objectClass=*)(uid=*))) |
|
36 * @run main/othervm InvalidLdapFilters valid (!(|(objectClass=*)(uid=*))) |
|
37 * @run main/othervm InvalidLdapFilters valid (o=univ*of*mich*) |
|
38 * @run main/othervm InvalidLdapFilters valid (seeAlso=) |
|
39 * @run main/othervm InvalidLdapFilters valid (cn:caseExactMatch:=Flintstone) |
|
40 * @run main/othervm InvalidLdapFilters valid (cn:=Betty) |
|
41 * @run main/othervm InvalidLdapFilters valid (sn:dn:2.4.6.8.10:=Barney) |
|
42 * @run main/othervm InvalidLdapFilters valid (o:dn:=Ace) |
|
43 * @run main/othervm InvalidLdapFilters valid (:1.2.3:=Wilma) |
|
44 * @run main/othervm InvalidLdapFilters valid (:DN:2.4.6.8.10:=Dino) |
|
45 * @run main/othervm InvalidLdapFilters valid (1.2.3=abc) |
|
46 * @run main/othervm InvalidLdapFilters valid (cn;lang-de;lang-en=abc) |
|
47 * @run main/othervm InvalidLdapFilters valid (owner=abc) |
|
48 * @run main/othervm InvalidLdapFilters valid (sn;lang-en:dn:2.4.6.8.10:=Barney) |
|
49 * @run main/othervm InvalidLdapFilters valid |
|
50 (&(objectClass=Person)(|(sn=Jensen)(cn=Bab*))) |
|
51 * @run main/othervm InvalidLdapFilters invalid "(&(cn=Robert Dean)))" |
|
52 * @run main/othervm InvalidLdapFilters invalid (&|(cn=Bob)) |
|
53 * @run main/othervm InvalidLdapFilters invalid (&&(cn=Bob)) |
|
54 * @run main/othervm InvalidLdapFilters invalid (|&(cn=Bob)) |
|
55 * @run main/othervm InvalidLdapFilters invalid (||(cn=Bob)) |
|
56 * @run main/othervm InvalidLdapFilters invalid (:1.2.:=Wilma) |
|
57 * @run main/othervm InvalidLdapFilters invalid (::DN:2.4.6.8.10:=Dino) |
|
58 * @run main/othervm InvalidLdapFilters invalid (:DN::2.4.6.8.10:=Dino) |
|
59 * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6.8.10::=Dino) |
|
60 * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6..8.10:=Dino) |
|
61 * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6.8.:=Dino) |
|
62 * @run main/othervm InvalidLdapFilters invalid (1.2.;::=abc) |
|
63 * @run main/othervm InvalidLdapFilters invalid (1.2.3;::=abc) |
|
64 * @run main/othervm InvalidLdapFilters invalid (1.2.3;x;=abc) |
|
65 * @run main/othervm InvalidLdapFilters invalid (1.2.3:x::=abc) |
|
66 * @run main/othervm InvalidLdapFilters invalid (1.2.3:x=abc) |
|
67 * @run main/othervm InvalidLdapFilters invalid (sn;:dn:2.4.6.8.10:=Barney) |
|
68 * @run main/othervm InvalidLdapFilters invalid "\"((objectClass=*)&(uid=*))\"" |
|
69 * @run main/othervm InvalidLdapFilters invalid "&(objectClass=*)(uid=*)" |
|
70 * @run main/othervm InvalidLdapFilters invalid "(:DN:2.4.6.8.10:cn:=Dino)" |
|
71 * @run main/othervm InvalidLdapFilters invalid "(:DN:2.4.6.8.10:cn=Dino)" |
|
72 * @run main/othervm InvalidLdapFilters invalid |
|
73 "((objectCategory=person)(cn=u)(!(cn=u2*)))" |
|
74 * @run main/othervm InvalidLdapFilters invalid |
|
75 "((&(objectClass=user)(cn=andy*)(cn=steve*)(cn=bob*)))" |
|
76 * |
|
77 * @author Xuelei Fan |
|
78 */ |
|
79 |
|
80 import java.io.*; |
|
81 import javax.naming.*; |
|
82 import javax.naming.directory.*; |
|
83 import java.util.Properties; |
|
84 import java.util.Hashtable; |
|
85 |
|
86 import java.net.Socket; |
|
87 import java.net.ServerSocket; |
|
88 |
|
89 public class InvalidLdapFilters { |
|
90 // Should we run the client or server in a separate thread? |
|
91 // |
|
92 // Both sides can throw exceptions, but do you have a preference |
|
93 // as to which side should be the main thread. |
|
94 static boolean separateServerThread = true; |
|
95 |
|
96 // use any free port by default |
|
97 volatile int serverPort = 0; |
|
98 |
|
99 // Is the server ready to serve? |
|
100 volatile static boolean serverReady = false; |
|
101 |
|
102 // Define the server side of the test. |
|
103 // |
|
104 // If the server prematurely exits, serverReady will be set to true |
|
105 // to avoid infinite hangs. |
|
106 void doServerSide() throws Exception { |
|
107 ServerSocket serverSock = new ServerSocket(serverPort); |
|
108 |
|
109 // signal client, it's ready to accecpt connection |
|
110 serverPort = serverSock.getLocalPort(); |
|
111 serverReady = true; |
|
112 |
|
113 // accept a connection |
|
114 Socket socket = serverSock.accept(); |
|
115 System.out.println("Server: Connection accepted"); |
|
116 |
|
117 InputStream is = socket.getInputStream(); |
|
118 OutputStream os = socket.getOutputStream(); |
|
119 |
|
120 // read the bindRequest |
|
121 while (is.read() != -1) { |
|
122 // ignore |
|
123 is.skip(is.available()); |
|
124 break; |
|
125 } |
|
126 |
|
127 byte[] bindResponse = {0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A, |
|
128 0x01, 0x00, 0x04, 0x00, 0x04, 0x00}; |
|
129 // write bindResponse |
|
130 os.write(bindResponse); |
|
131 os.flush(); |
|
132 |
|
133 // ignore any more request. |
|
134 while (is.read() != -1) { |
|
135 // ignore |
|
136 is.skip(is.available()); |
|
137 } |
|
138 |
|
139 is.close(); |
|
140 os.close(); |
|
141 socket.close(); |
|
142 serverSock.close(); |
|
143 } |
|
144 |
|
145 // Define the client side of the test. |
|
146 // |
|
147 // If the server prematurely exits, serverReady will be set to true |
|
148 // to avoid infinite hangs. |
|
149 void doClientSide() throws Exception { |
|
150 // Wait for server to get started. |
|
151 while (!serverReady) { |
|
152 Thread.sleep(50); |
|
153 } |
|
154 |
|
155 // set up the environment for creating the initial context |
|
156 Hashtable<Object, Object> env = new Hashtable<Object, Object>(); |
|
157 env.put(Context.INITIAL_CONTEXT_FACTORY, |
|
158 "com.sun.jndi.ldap.LdapCtxFactory"); |
|
159 env.put(Context.PROVIDER_URL, "ldap://localhost:" + serverPort); |
|
160 env.put("com.sun.jndi.ldap.read.timeout", "1000"); |
|
161 |
|
162 // env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
|
163 // env.put(Context.SECURITY_PRINCIPAL,"cn=root"); |
|
164 // env.put(Context.SECURITY_CREDENTIALS,"root"); |
|
165 |
|
166 // create initial context |
|
167 DirContext context = new InitialDirContext(env); |
|
168 |
|
169 // searching |
|
170 SearchControls scs = new SearchControls(); |
|
171 scs.setSearchScope(SearchControls.SUBTREE_SCOPE); |
|
172 |
|
173 try { |
|
174 NamingEnumeration answer = |
|
175 context.search("o=sun,c=us", searchFilter, scs); |
|
176 } catch (InvalidSearchFilterException isfe) { |
|
177 if (filterIsValid) { |
|
178 // unexpected filter exception. |
|
179 throw new Exception("Unexpected ISFE", isfe); |
|
180 } else { |
|
181 // ignore, it is the expected filter exception. |
|
182 System.out.println("Expected exception: " + isfe.getMessage()); |
|
183 } |
|
184 } catch (NamingException ne) { |
|
185 // maybe a read timeout exception, as the server does not response. |
|
186 if (filterIsValid) { |
|
187 System.out.println("Expected exception: " + ne.getMessage()); |
|
188 } else { |
|
189 throw new Exception("Not an InvalidSearchFilterException", ne); |
|
190 } |
|
191 } |
|
192 |
|
193 context.close(); |
|
194 } |
|
195 |
|
196 private static boolean filterIsValid; |
|
197 private static String searchFilter; |
|
198 |
|
199 private static void parseArguments(String[] args) { |
|
200 System.out.println("arguments length: " + args.length); |
|
201 if (args[0].equals("valid")) { |
|
202 filterIsValid = true; |
|
203 } |
|
204 |
|
205 searchFilter = args[1]; |
|
206 } |
|
207 |
|
208 /* |
|
209 * ============================================================ |
|
210 * The remainder is just support stuff |
|
211 */ |
|
212 |
|
213 // client and server thread |
|
214 Thread clientThread = null; |
|
215 Thread serverThread = null; |
|
216 |
|
217 // client and server exceptions |
|
218 volatile Exception serverException = null; |
|
219 volatile Exception clientException = null; |
|
220 |
|
221 void startServer(boolean newThread) throws Exception { |
|
222 if (newThread) { |
|
223 serverThread = new Thread() { |
|
224 public void run() { |
|
225 try { |
|
226 doServerSide(); |
|
227 } catch (Exception e) { |
|
228 /* |
|
229 * Our server thread just died. |
|
230 * |
|
231 * Release the client, if not active already... |
|
232 */ |
|
233 System.err.println("Server died..."); |
|
234 System.err.println(e); |
|
235 serverReady = true; |
|
236 serverException = e; |
|
237 } |
|
238 } |
|
239 }; |
|
240 serverThread.start(); |
|
241 } else { |
|
242 doServerSide(); |
|
243 } |
|
244 } |
|
245 |
|
246 void startClient(boolean newThread) throws Exception { |
|
247 if (newThread) { |
|
248 clientThread = new Thread() { |
|
249 public void run() { |
|
250 try { |
|
251 doClientSide(); |
|
252 } catch (Exception e) { |
|
253 /* |
|
254 * Our client thread just died. |
|
255 */ |
|
256 System.err.println("Client died..."); |
|
257 clientException = e; |
|
258 } |
|
259 } |
|
260 }; |
|
261 clientThread.start(); |
|
262 } else { |
|
263 doClientSide(); |
|
264 } |
|
265 } |
|
266 |
|
267 // Primary constructor, used to drive remainder of the test. |
|
268 InvalidLdapFilters() throws Exception { |
|
269 if (separateServerThread) { |
|
270 startServer(true); |
|
271 startClient(false); |
|
272 } else { |
|
273 startClient(true); |
|
274 startServer(false); |
|
275 } |
|
276 |
|
277 /* |
|
278 * Wait for other side to close down. |
|
279 */ |
|
280 if (separateServerThread) { |
|
281 serverThread.join(); |
|
282 } else { |
|
283 clientThread.join(); |
|
284 } |
|
285 |
|
286 /* |
|
287 * When we get here, the test is pretty much over. |
|
288 * |
|
289 * If the main thread excepted, that propagates back |
|
290 * immediately. If the other thread threw an exception, we |
|
291 * should report back. |
|
292 */ |
|
293 if (serverException != null) { |
|
294 System.out.print("Server Exception:"); |
|
295 throw serverException; |
|
296 } |
|
297 if (clientException != null) { |
|
298 System.out.print("Client Exception:"); |
|
299 throw clientException; |
|
300 } |
|
301 } |
|
302 |
|
303 public static void main(String[] args) throws Exception { |
|
304 // parse the customized arguments |
|
305 parseArguments(args); |
|
306 |
|
307 // start the test |
|
308 new InvalidLdapFilters(); |
|
309 } |
|
310 |
|
311 } |