29 * @build HashedPasswordFileTest |
29 * @build HashedPasswordFileTest |
30 * @run testng/othervm HashedPasswordFileTest |
30 * @run testng/othervm HashedPasswordFileTest |
31 * |
31 * |
32 */ |
32 */ |
33 |
33 |
34 import java.io.BufferedReader; |
34 import jdk.test.lib.Utils; |
35 import java.io.BufferedWriter; |
35 import jdk.test.lib.process.ProcessTools; |
36 import java.io.File; |
36 import org.testng.Assert; |
37 import java.io.FileNotFoundException; |
37 import org.testng.annotations.AfterClass; |
38 import java.io.FileReader; |
38 import org.testng.annotations.Test; |
39 import java.io.FileWriter; |
39 |
40 import java.io.IOException; |
40 import javax.management.MBeanServer; |
|
41 import javax.management.remote.*; |
|
42 import java.io.*; |
41 import java.lang.management.ManagementFactory; |
43 import java.lang.management.ManagementFactory; |
42 import java.net.MalformedURLException; |
|
43 import java.nio.charset.StandardCharsets; |
44 import java.nio.charset.StandardCharsets; |
44 import java.nio.file.FileSystems; |
45 import java.nio.file.FileSystems; |
45 import java.nio.file.Files; |
46 import java.nio.file.Files; |
46 import java.nio.file.attribute.PosixFilePermission; |
47 import java.nio.file.attribute.PosixFilePermission; |
47 import java.security.MessageDigest; |
48 import java.security.MessageDigest; |
48 import java.security.NoSuchAlgorithmException; |
49 import java.security.NoSuchAlgorithmException; |
49 import java.util.ArrayList; |
50 import java.util.*; |
50 import java.util.Base64; |
|
51 import java.util.HashMap; |
|
52 import java.util.HashSet; |
|
53 import java.util.List; |
51 import java.util.List; |
54 import java.util.Map; |
|
55 import java.util.Random; |
|
56 import java.util.Set; |
52 import java.util.Set; |
57 import java.util.concurrent.*; |
53 import java.util.concurrent.*; |
58 import javax.management.MBeanServer; |
|
59 import javax.management.remote.JMXConnector; |
|
60 import javax.management.remote.JMXConnectorFactory; |
|
61 import javax.management.remote.JMXConnectorServer; |
|
62 import javax.management.remote.JMXConnectorServerFactory; |
|
63 import javax.management.remote.JMXServiceURL; |
|
64 |
|
65 import org.testng.Assert; |
|
66 import org.testng.annotations.Test; |
|
67 import org.testng.annotations.AfterClass; |
|
68 |
|
69 import jdk.test.lib.Utils; |
|
70 import jdk.test.lib.process.ProcessTools; |
|
71 |
54 |
72 @Test |
55 @Test |
73 public class HashedPasswordFileTest { |
56 public class HashedPasswordFileTest { |
74 |
57 |
75 private final String[] randomWords = {"accost", "savoie", "bogart", "merest", |
58 private final String[] randomWords = {"accost", "savoie", "bogart", "merest", |
94 "SHA3-256", |
77 "SHA3-256", |
95 "SHA3-384", |
78 "SHA3-384", |
96 "SHA3-512" |
79 "SHA3-512" |
97 }; |
80 }; |
98 |
81 |
99 private final Random rnd = new Random(); |
|
100 private final Random random = Utils.getRandomInstance(); |
82 private final Random random = Utils.getRandomInstance(); |
101 |
83 |
102 private JMXConnectorServer cs; |
84 private JMXConnectorServer cs; |
103 |
85 |
104 private String randomWord() { |
86 private String randomWord() { |
105 int idx = rnd.nextInt(randomWords.length); |
87 int idx = random.nextInt(randomWords.length); |
106 return randomWords[idx]; |
88 return randomWords[idx]; |
107 } |
89 } |
108 |
90 |
109 private String[] getHash(String algorithm, String password) { |
91 private String[] getHash(String algorithm, String password) { |
110 try { |
92 try { |
144 File file = createNewPasswordFile(); |
126 File file = createNewPasswordFile(); |
145 Map<String, String> props = new HashMap<>(); |
127 Map<String, String> props = new HashMap<>(); |
146 BufferedWriter br; |
128 BufferedWriter br; |
147 try (FileWriter fw = new FileWriter(file)) { |
129 try (FileWriter fw = new FileWriter(file)) { |
148 br = new BufferedWriter(fw); |
130 br = new BufferedWriter(fw); |
149 int numentries = rnd.nextInt(5) + 3; |
131 int numentries = random.nextInt(5) + 3; |
150 for (int i = 0; i < numentries; i++) { |
132 for (int i = 0; i < numentries; i++) { |
151 String username = randomWord(); |
133 String username; |
|
134 do { |
|
135 username = randomWord(); |
|
136 } while (props.get(username) != null); |
152 String password = randomWord(); |
137 String password = randomWord(); |
153 props.put(username, password); |
138 props.put(username, password); |
154 br.write(username + " " + password + "\n"); |
139 br.write(username + " " + password + "\n"); |
155 } |
140 } |
156 br.flush(); |
141 br.flush(); |
180 File file = createNewPasswordFile(); |
165 File file = createNewPasswordFile(); |
181 Map<String, String> props = new HashMap<>(); |
166 Map<String, String> props = new HashMap<>(); |
182 BufferedWriter br; |
167 BufferedWriter br; |
183 try (FileWriter fw = new FileWriter(file)) { |
168 try (FileWriter fw = new FileWriter(file)) { |
184 br = new BufferedWriter(fw); |
169 br = new BufferedWriter(fw); |
185 int numentries = rnd.nextInt(5) + 3; |
170 int numentries = random.nextInt(5) + 3; |
186 for (int i = 0; i < numentries; i++) { |
171 for (int i = 0; i < numentries; i++) { |
187 String username = randomWord(); |
172 String username; |
|
173 do { |
|
174 username = randomWord(); |
|
175 } while (props.get(username) != null); |
188 String password = randomWord(); |
176 String password = randomWord(); |
189 String alg = hashAlgs[rnd.nextInt(hashAlgs.length)]; |
177 String alg = hashAlgs[random.nextInt(hashAlgs.length)]; |
190 String[] b64str = getHash(alg, password); |
178 String[] b64str = getHash(alg, password); |
191 br.write(username + " " + b64str[0] + " " + b64str[1] + " " + alg + "\n"); |
179 br.write(username + " " + b64str[0] + " " + b64str[1] + " " + alg + "\n"); |
192 props.put(username, password); |
180 props.put(username, password); |
193 } |
181 } |
194 br.flush(); |
182 br.flush(); |
305 public void testMultipleClients() throws Throwable { |
293 public void testMultipleClients() throws Throwable { |
306 Map<String, String> credentials = generateClearTextPasswordFile(); |
294 Map<String, String> credentials = generateClearTextPasswordFile(); |
307 JMXServiceURL serverUrl = createServerSide(true); |
295 JMXServiceURL serverUrl = createServerSide(true); |
308 Assert.assertEquals(isPasswordFileHashed(), false); |
296 Assert.assertEquals(isPasswordFileHashed(), false); |
309 // create random number of clients |
297 // create random number of clients |
310 int numClients = rnd.nextInt(20) + 10; |
298 int numClients = random.nextInt(20) + 10; |
311 List<Future> futures = new ArrayList<>(); |
299 List<Future> futures = new ArrayList<>(); |
312 ExecutorService executor = Executors.newFixedThreadPool(numClients); |
300 ExecutorService executor = Executors.newFixedThreadPool(numClients); |
313 for (int i = 0; i < numClients; i++) { |
301 for (int i = 0; i < numClients; i++) { |
314 Future future = executor.submit(new SimpleJMXClient(serverUrl, credentials)); |
302 Future future = executor.submit(new SimpleJMXClient(serverUrl, credentials)); |
315 futures.add(future); |
303 futures.add(future); |
353 while ((line = br.readLine()) != null) { |
341 while ((line = br.readLine()) != null) { |
354 if (line.trim().startsWith("#")) { |
342 if (line.trim().startsWith("#")) { |
355 sbuild.append(line).append("\n"); |
343 sbuild.append(line).append("\n"); |
356 continue; |
344 continue; |
357 } |
345 } |
358 String[] tokens = line.split("\\s+"); |
346 |
359 // Change password for random entries |
347 // Change password for random entries |
360 if ((tokens.length == 4 || tokens.length == 3) && rnd.nextBoolean()) { |
348 if (random.nextBoolean()) { |
361 String password = randomWord(); |
349 String[] tokens = line.split("\\s+"); |
362 credentials.put(tokens[0], password); |
350 if ((tokens.length == 4 || tokens.length == 3)) { |
363 sbuild.append(tokens[0]).append(" ").append(password).append("\n"); |
351 String password = randomWord(); |
|
352 credentials.put(tokens[0], password); |
|
353 sbuild.append(tokens[0]).append(" ").append(password).append("\n"); |
|
354 } |
364 } else { |
355 } else { |
365 sbuild.append(line).append("\n"); |
356 sbuild.append(line).append("\n"); |
366 } |
357 } |
367 } |
358 } |
368 |
359 |
369 // Add new entries in clear |
360 // Add new entries in clear |
370 int newentries = rnd.nextInt(2) + 3; |
361 int newentries = random.nextInt(2) + 3; |
371 for (int i = 0; i < newentries; i++) { |
362 for (int i = 0; i < newentries; i++) { |
372 String username = randomWord(); |
363 String username; |
|
364 do { |
|
365 username = randomWord(); |
|
366 } while (credentials.get(username) != null); |
373 String password = randomWord(); |
367 String password = randomWord(); |
374 credentials.put(username, password); |
368 credentials.put(username, password); |
375 sbuild.append(username).append(" ").append(password).append("\n"); |
369 sbuild.append(username).append(" ").append(password).append("\n"); |
376 } |
370 } |
377 |
371 |
378 // Add new entries as a hash |
372 // Add new entries as a hash |
379 int numentries = rnd.nextInt(2) + 3; |
373 int numentries = random.nextInt(2) + 3; |
380 for (int i = 0; i < numentries; i++) { |
374 for (int i = 0; i < numentries; i++) { |
381 String username = randomWord(); |
375 String username; |
|
376 do { |
|
377 username = randomWord(); |
|
378 } while (credentials.get(username) != null); |
382 String password = randomWord(); |
379 String password = randomWord(); |
383 String alg = hashAlgs[rnd.nextInt(hashAlgs.length)]; |
380 String alg = hashAlgs[random.nextInt(hashAlgs.length)]; |
384 String[] b64str = getHash(alg, password); |
381 String[] b64str = getHash(alg, password); |
385 credentials.put(username, password); |
382 credentials.put(username, password); |
386 sbuild.append(username).append(" ").append(b64str[0]) |
383 sbuild.append(username).append(" ").append(b64str[0]) |
387 .append(" ").append(b64str[1]).append(" ") |
384 .append(" ").append(b64str[1]).append(" ") |
388 .append(alg).append("\n"); |
385 .append(alg).append("\n"); |