1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.junit.ssh;
11
12 import static java.nio.charset.StandardCharsets.UTF_8;
13 import static org.junit.Assert.assertArrayEquals;
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertFalse;
16 import static org.junit.Assert.assertNotNull;
17 import static org.junit.Assert.assertTrue;
18 import static org.junit.Assume.assumeTrue;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.nio.file.Files;
23 import java.util.List;
24 import java.util.Locale;
25
26 import org.eclipse.jgit.api.errors.TransportException;
27 import org.eclipse.jgit.transport.CredentialItem;
28 import org.junit.Test;
29 import org.junit.experimental.theories.DataPoints;
30 import org.junit.experimental.theories.Theory;
31
32
33
34
35
36
37 public abstract class SshTestBase extends SshTestHarness {
38
39 @DataPoints
40 public static String[] KEY_RESOURCES = {
41 "id_dsa",
42 "id_rsa_1024",
43 "id_rsa_2048",
44 "id_rsa_3072",
45 "id_rsa_4096",
46 "id_ecdsa_256",
47 "id_ecdsa_384",
48 "id_ecdsa_521",
49 "id_ed25519",
50
51 "id_dsa_testpass",
52 "id_rsa_1024_testpass",
53 "id_rsa_2048_testpass",
54 "id_rsa_3072_testpass",
55 "id_rsa_4096_testpass",
56 "id_ecdsa_256_testpass",
57 "id_ecdsa_384_testpass",
58 "id_ecdsa_521_testpass",
59 "id_ed25519_testpass",
60 "id_ed25519_expensive_testpass" };
61
62 protected File defaultCloneDir;
63
64 @Override
65 public void setUp() throws Exception {
66 super.setUp();
67 defaultCloneDir = new File(getTemporaryDirectory(), "cloned");
68 }
69
70 @Test(expected = TransportException.class)
71 public void testSshWithoutConfig() throws Exception {
72 cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
73 + "/doesntmatter", defaultCloneDir, null);
74 }
75
76 @Test
77 public void testSshWithGlobalIdentity() throws Exception {
78 cloneWith(
79 "ssh://" + TEST_USER + "@localhost:" + testPort
80 + "/doesntmatter",
81 defaultCloneDir, null,
82 "IdentityFile " + privateKey1.getAbsolutePath());
83 }
84
85 @Test
86 public void testSshWithDefaultIdentity() throws Exception {
87 File idRsa = new File(privateKey1.getParentFile(), "id_rsa");
88 Files.copy(privateKey1.toPath(), idRsa.toPath());
89
90 cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
91 + "/doesntmatter", defaultCloneDir, null);
92 }
93
94 @Test
95 public void testSshWithConfig() throws Exception {
96 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
97 "Host localhost",
98 "HostName localhost",
99 "Port " + testPort,
100 "User " + TEST_USER,
101 "IdentityFile " + privateKey1.getAbsolutePath());
102 }
103
104 @Test
105 public void testSshWithConfigEncryptedUnusedKey() throws Exception {
106
107 File encryptedKey = new File(sshDir, "id_dsa");
108 copyTestResource("id_dsa_testpass", encryptedKey);
109 TestCredentialsProvider provider = new TestCredentialsProvider(
110 "testpass");
111 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
112 "Host localhost",
113 "HostName localhost",
114 "Port " + testPort,
115 "User " + TEST_USER,
116 "IdentityFile " + privateKey1.getAbsolutePath());
117 assertEquals("CredentialsProvider should not have been called", 0,
118 provider.getLog().size());
119 }
120
121 @Test
122 public void testSshWithConfigEncryptedUnusedKeyInConfigLast()
123 throws Exception {
124
125 File encryptedKey = new File(sshDir, "id_dsa_test_key");
126 copyTestResource("id_dsa_testpass", encryptedKey);
127 TestCredentialsProvider provider = new TestCredentialsProvider(
128 "testpass");
129 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
130 "Host localhost",
131 "HostName localhost",
132 "Port " + testPort,
133 "User " + TEST_USER,
134 "IdentityFile " + privateKey1.getAbsolutePath(),
135 "IdentityFile " + encryptedKey.getAbsolutePath());
136
137
138 assertEquals("CredentialsProvider should not have been called", 0,
139 provider.getLog().size());
140 }
141
142 private boolean isJsch() {
143 return getSessionFactory().getType().equals("jsch");
144 }
145
146 @Test
147 public void testSshWithConfigEncryptedUnusedKeyInConfigFirst()
148 throws Exception {
149
150
151
152
153
154 if (isJsch()) {
155 return;
156 }
157
158 File encryptedKey = new File(sshDir, "id_dsa_test_key");
159 copyTestResource("id_dsa_testpass", encryptedKey);
160 TestCredentialsProvider provider = new TestCredentialsProvider(
161 "testpass");
162 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
163 "Host localhost",
164 "HostName localhost",
165 "Port " + testPort,
166 "User " + TEST_USER,
167 "IdentityFile " + encryptedKey.getAbsolutePath(),
168 "IdentityFile " + privateKey1.getAbsolutePath());
169 assertEquals("CredentialsProvider should have been called once", 1,
170 provider.getLog().size());
171 }
172
173 @Test
174 public void testSshEncryptedUsedKeyCached() throws Exception {
175
176
177 File encryptedKey = new File(sshDir, "id_dsa_test_key");
178 copyTestResource("id_dsa_testpass", encryptedKey);
179 File encryptedPublicKey = new File(sshDir, "id_dsa_test_key.pub");
180 copyTestResource("id_dsa_testpass.pub", encryptedPublicKey);
181 server.setTestUserPublicKey(encryptedPublicKey.toPath());
182 TestCredentialsProvider provider = new TestCredentialsProvider(
183 "testpass");
184 pushTo(provider,
185 cloneWith("ssh://localhost/doesntmatter", //
186 defaultCloneDir, provider,
187 "Host localhost",
188 "HostName localhost",
189 "Port " + testPort,
190 "User " + TEST_USER,
191 "IdentityFile " + encryptedKey.getAbsolutePath()));
192 assertEquals("CredentialsProvider should have been called once", 1,
193 provider.getLog().size());
194 }
195
196 @Test(expected = TransportException.class)
197 public void testSshEncryptedUsedKeyWrongPassword() throws Exception {
198 File encryptedKey = new File(sshDir, "id_dsa_test_key");
199 copyTestResource("id_dsa_testpass", encryptedKey);
200 File encryptedPublicKey = new File(sshDir, "id_dsa_test_key.pub");
201 copyTestResource("id_dsa_testpass.pub", encryptedPublicKey);
202 server.setTestUserPublicKey(encryptedPublicKey.toPath());
203 TestCredentialsProvider provider = new TestCredentialsProvider(
204 "wrongpass");
205 cloneWith("ssh://localhost/doesntmatter", //
206 defaultCloneDir, provider,
207 "Host localhost",
208 "HostName localhost",
209 "Port " + testPort,
210 "User " + TEST_USER,
211 "NumberOfPasswordPrompts 1",
212 "IdentityFile " + encryptedKey.getAbsolutePath());
213 }
214
215 @Test
216 public void testSshEncryptedUsedKeySeveralPassword() throws Exception {
217 File encryptedKey = new File(sshDir, "id_dsa_test_key");
218 copyTestResource("id_dsa_testpass", encryptedKey);
219 File encryptedPublicKey = new File(sshDir, "id_dsa_test_key.pub");
220 copyTestResource("id_dsa_testpass.pub", encryptedPublicKey);
221 server.setTestUserPublicKey(encryptedPublicKey.toPath());
222 TestCredentialsProvider provider = new TestCredentialsProvider(
223 "wrongpass", "wrongpass2", "testpass");
224 cloneWith("ssh://localhost/doesntmatter", //
225 defaultCloneDir, provider,
226 "Host localhost",
227 "HostName localhost",
228 "Port " + testPort,
229 "User " + TEST_USER,
230 "IdentityFile " + encryptedKey.getAbsolutePath());
231 assertEquals("CredentialsProvider should have been called 3 times", 3,
232 provider.getLog().size());
233 }
234
235 @Test(expected = TransportException.class)
236 public void testSshWithoutKnownHosts() throws Exception {
237 assertTrue("Could not delete known_hosts", knownHosts.delete());
238 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
239 "Host localhost",
240 "HostName localhost",
241 "Port " + testPort,
242 "User " + TEST_USER,
243 "IdentityFile " + privateKey1.getAbsolutePath());
244 }
245
246 @Test
247 public void testSshWithoutKnownHostsWithProviderAsk()
248 throws Exception {
249 File copiedHosts = new File(knownHosts.getParentFile(),
250 "copiedKnownHosts");
251 assertTrue("Failed to rename known_hosts",
252 knownHosts.renameTo(copiedHosts));
253
254
255 TestCredentialsProvider provider = new TestCredentialsProvider();
256 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
257 "Host localhost",
258 "HostName localhost",
259 "Port " + testPort,
260 "User " + TEST_USER,
261 "IdentityFile " + privateKey1.getAbsolutePath());
262 List<LogEntry> messages = provider.getLog();
263 assertFalse("Expected user interaction", messages.isEmpty());
264 if (isJsch()) {
265
266 assertEquals("Expected to be asked about the key", 1,
267 messages.size());
268 return;
269 }
270 assertEquals(
271 "Expected to be asked about the key, and the file creation",
272 2, messages.size());
273 assertTrue("~/.ssh/known_hosts should exist now", knownHosts.exists());
274
275
276
277 File clonedAgain = new File(getTemporaryDirectory(), "cloned2");
278 cloneWith("ssh://localhost/doesntmatter", clonedAgain, null, //
279 "Host localhost",
280 "HostName localhost",
281 "Port " + testPort,
282 "User " + TEST_USER,
283 "IdentityFile " + privateKey1.getAbsolutePath());
284 }
285
286 @Test
287 public void testSshWithoutKnownHostsWithProviderAcceptNew()
288 throws Exception {
289 File copiedHosts = new File(knownHosts.getParentFile(),
290 "copiedKnownHosts");
291 assertTrue("Failed to rename known_hosts",
292 knownHosts.renameTo(copiedHosts));
293 TestCredentialsProvider provider = new TestCredentialsProvider();
294 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
295 "Host localhost",
296 "HostName localhost",
297 "Port " + testPort,
298 "User " + TEST_USER,
299 "StrictHostKeyChecking accept-new",
300 "IdentityFile " + privateKey1.getAbsolutePath());
301 if (isJsch()) {
302
303 assertTrue("CredentialsProvider not called",
304 provider.getLog().isEmpty());
305 return;
306 }
307 assertEquals("Expected to be asked about the file creation", 1,
308 provider.getLog().size());
309 assertTrue("~/.ssh/known_hosts should exist now", knownHosts.exists());
310
311
312
313 File clonedAgain = new File(getTemporaryDirectory(), "cloned2");
314 cloneWith("ssh://localhost/doesntmatter", clonedAgain, null, //
315 "Host localhost",
316 "HostName localhost",
317 "Port " + testPort,
318 "User " + TEST_USER,
319 "IdentityFile " + privateKey1.getAbsolutePath());
320 }
321
322 @Test(expected = TransportException.class)
323 public void testSshWithoutKnownHostsDeny() throws Exception {
324 File copiedHosts = new File(knownHosts.getParentFile(),
325 "copiedKnownHosts");
326 assertTrue("Failed to rename known_hosts",
327 knownHosts.renameTo(copiedHosts));
328 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
329 "Host localhost",
330 "HostName localhost",
331 "Port " + testPort,
332 "User " + TEST_USER,
333 "StrictHostKeyChecking yes",
334 "IdentityFile " + privateKey1.getAbsolutePath());
335 }
336
337 @Test(expected = TransportException.class)
338 public void testSshModifiedHostKeyDeny()
339 throws Exception {
340 File copiedHosts = new File(knownHosts.getParentFile(),
341 "copiedKnownHosts");
342 assertTrue("Failed to rename known_hosts",
343 knownHosts.renameTo(copiedHosts));
344
345 createKnownHostsFile(knownHosts, "localhost", testPort, publicKey1);
346 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
347 "Host localhost",
348 "HostName localhost",
349 "Port " + testPort,
350 "User " + TEST_USER,
351 "StrictHostKeyChecking yes",
352 "IdentityFile " + privateKey1.getAbsolutePath());
353 }
354
355 @Test(expected = TransportException.class)
356 public void testSshModifiedHostKeyWithProviderDeny() throws Exception {
357 File copiedHosts = new File(knownHosts.getParentFile(),
358 "copiedKnownHosts");
359 assertTrue("Failed to rename known_hosts",
360 knownHosts.renameTo(copiedHosts));
361
362 createKnownHostsFile(knownHosts, "localhost", testPort, publicKey1);
363 TestCredentialsProvider provider = new TestCredentialsProvider();
364 try {
365 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
366 "Host localhost",
367 "HostName localhost",
368 "Port " + testPort,
369 "User " + TEST_USER,
370 "StrictHostKeyChecking yes",
371 "IdentityFile " + privateKey1.getAbsolutePath());
372 } catch (Exception e) {
373 assertEquals("Expected to be told about the modified key", 1,
374 provider.getLog().size());
375 assertTrue("Only messages expected", provider.getLog().stream()
376 .flatMap(l -> l.getItems().stream()).allMatch(
377 c -> c instanceof CredentialItem.InformationalMessage));
378 throw e;
379 }
380 }
381
382 private void checkKnownHostsModifiedHostKey(File backup, File newFile,
383 String wrongKey) throws IOException {
384 List<String> oldLines = Files.readAllLines(backup.toPath(), UTF_8);
385
386 String oldKeyPart = null;
387 for (String oldLine : oldLines) {
388 if (oldLine.contains("[localhost]:")) {
389 String[] parts = oldLine.split("\\s+");
390 if (parts.length > 2) {
391 oldKeyPart = parts[parts.length - 2] + ' '
392 + parts[parts.length - 1];
393 break;
394 }
395 }
396 }
397 assertNotNull("Old key not found", oldKeyPart);
398 List<String> newLines = Files.readAllLines(newFile.toPath(), UTF_8);
399 assertFalse("Old host key still found in known_hosts file" + newFile,
400 hasHostKey("localhost", testPort, wrongKey, newLines));
401 assertTrue("New host key not found in known_hosts file" + newFile,
402 hasHostKey("localhost", testPort, oldKeyPart, newLines));
403
404 }
405
406 @Test
407 public void testSshModifiedHostKeyAllow() throws Exception {
408 assertTrue("Failed to delete known_hosts", knownHosts.delete());
409 createKnownHostsFile(knownHosts, "localhost", testPort, publicKey1);
410 File backup = new File(getTemporaryDirectory(), "backupKnownHosts");
411 Files.copy(knownHosts.toPath(), backup.toPath());
412 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
413 "Host localhost",
414 "HostName localhost",
415 "Port " + testPort,
416 "User " + TEST_USER,
417 "StrictHostKeyChecking no",
418 "IdentityFile " + privateKey1.getAbsolutePath());
419
420 String[] oldLines = Files
421 .readAllLines(backup.toPath(), UTF_8)
422 .toArray(new String[0]);
423 String[] newLines = Files
424 .readAllLines(knownHosts.toPath(), UTF_8)
425 .toArray(new String[0]);
426 assertArrayEquals("Known hosts file should not be modified", oldLines,
427 newLines);
428 }
429
430 @Test
431 public void testSshModifiedHostKeyAsk() throws Exception {
432 File copiedHosts = new File(knownHosts.getParentFile(),
433 "copiedKnownHosts");
434 assertTrue("Failed to rename known_hosts",
435 knownHosts.renameTo(copiedHosts));
436 String wrongKeyPart = createKnownHostsFile(knownHosts, "localhost",
437 testPort, publicKey1);
438 TestCredentialsProvider provider = new TestCredentialsProvider();
439 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
440 "Host localhost",
441 "HostName localhost",
442 "Port " + testPort,
443 "User " + TEST_USER,
444 "IdentityFile " + privateKey1.getAbsolutePath());
445 checkKnownHostsModifiedHostKey(copiedHosts, knownHosts, wrongKeyPart);
446 assertEquals("Expected to be asked about the modified key", 1,
447 provider.getLog().size());
448 }
449
450 @Test
451 public void testSshCloneWithConfigAndPush() throws Exception {
452 pushTo(cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
453 "Host localhost",
454 "HostName localhost",
455 "Port " + testPort,
456 "User " + TEST_USER,
457 "IdentityFile " + privateKey1.getAbsolutePath()));
458 }
459
460 @Test
461 public void testSftpWithConfig() throws Exception {
462 cloneWith("sftp://localhost/.git", defaultCloneDir, null, //
463 "Host localhost",
464 "HostName localhost",
465 "Port " + testPort,
466 "User " + TEST_USER,
467 "IdentityFile " + privateKey1.getAbsolutePath());
468 }
469
470 @Test
471 public void testSftpCloneWithConfigAndPush() throws Exception {
472 pushTo(cloneWith("sftp://localhost/.git", defaultCloneDir, null, //
473 "Host localhost",
474 "HostName localhost",
475 "Port " + testPort,
476 "User " + TEST_USER,
477 "IdentityFile " + privateKey1.getAbsolutePath()));
478 }
479
480 @Test(expected = TransportException.class)
481 public void testSshWithConfigWrongKey() throws Exception {
482 cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, null, //
483 "Host localhost",
484 "HostName localhost",
485 "Port " + testPort,
486 "User " + TEST_USER,
487 "IdentityFile " + privateKey2.getAbsolutePath());
488 }
489
490 @Test
491 public void testSshWithWrongUserNameInConfig() throws Exception {
492
493 cloneWith(
494 "ssh://" + TEST_USER + "@localhost:" + testPort
495 + "/doesntmatter",
496 defaultCloneDir, null,
497 "Host localhost",
498 "HostName localhost",
499 "User sombody_else",
500 "IdentityFile " + privateKey1.getAbsolutePath());
501 }
502
503 @Test
504 public void testSshWithWrongPortInConfig() throws Exception {
505
506 cloneWith(
507 "ssh://" + TEST_USER + "@localhost:" + testPort
508 + "/doesntmatter",
509 defaultCloneDir, null,
510 "Host localhost",
511 "HostName localhost",
512 "Port 22",
513 "User " + TEST_USER,
514 "IdentityFile " + privateKey1.getAbsolutePath());
515 }
516
517 @Test
518 public void testSshWithAliasInConfig() throws Exception {
519
520 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
521 "Host git",
522 "HostName localhost",
523 "Port " + testPort,
524 "User " + TEST_USER,
525 "IdentityFile " + privateKey1.getAbsolutePath(), "",
526 "Host localhost",
527 "HostName localhost",
528 "Port 22",
529 "User someone_else",
530 "IdentityFile " + privateKey2.getAbsolutePath());
531 }
532
533 @Test
534 public void testSshWithUnknownCiphersInConfig() throws Exception {
535
536 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
537 "Host git",
538 "HostName localhost",
539 "Port " + testPort,
540 "User " + TEST_USER,
541 "IdentityFile " + privateKey1.getAbsolutePath(),
542 "Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr");
543 }
544
545 @Test
546 public void testSshWithUnknownHostKeyAlgorithmsInConfig()
547 throws Exception {
548
549 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
550 "Host git",
551 "HostName localhost",
552 "Port " + testPort,
553 "User " + TEST_USER,
554 "IdentityFile " + privateKey1.getAbsolutePath(),
555 "HostKeyAlgorithms foobar,ssh-rsa,ssh-dss");
556 }
557
558 @Test
559 public void testSshWithUnknownKexAlgorithmsInConfig()
560 throws Exception {
561
562 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
563 "Host git",
564 "HostName localhost",
565 "Port " + testPort,
566 "User " + TEST_USER,
567 "IdentityFile " + privateKey1.getAbsolutePath(),
568 "KexAlgorithms foobar,diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521");
569 }
570
571 @Test
572 public void testSshWithMinimalHostKeyAlgorithmsInConfig()
573 throws Exception {
574
575 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
576 "Host git",
577 "HostName localhost",
578 "Port " + testPort,
579 "User " + TEST_USER,
580 "IdentityFile " + privateKey1.getAbsolutePath(),
581 "HostKeyAlgorithms ssh-rsa,ssh-dss");
582 }
583
584 @Test
585 public void testSshWithUnknownAuthInConfig() throws Exception {
586 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
587 "Host git",
588 "HostName localhost",
589 "Port " + testPort,
590 "User " + TEST_USER,
591 "IdentityFile " + privateKey1.getAbsolutePath(),
592 "PreferredAuthentications gssapi-with-mic,hostbased,publickey,keyboard-interactive,password");
593 }
594
595 @Test(expected = TransportException.class)
596 public void testSshWithNoMatchingAuthInConfig() throws Exception {
597
598 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
599 "Host git",
600 "HostName localhost",
601 "Port " + testPort,
602 "User " + TEST_USER,
603 "IdentityFile " + privateKey1.getAbsolutePath(),
604 "PreferredAuthentications password");
605 }
606
607 @Test
608 public void testRsaHostKeySecond() throws Exception {
609
610
611
612 File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
613 copyTestResource("id_ecdsa_256", newHostKey);
614 server.addHostKey(newHostKey.toPath(), true);
615 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
616 "Host git",
617 "HostName localhost",
618 "Port " + testPort,
619 "User " + TEST_USER,
620 "IdentityFile " + privateKey1.getAbsolutePath());
621 }
622
623 @Test
624 public void testEcDsaHostKey() throws Exception {
625
626
627
628 File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
629 copyTestResource("id_ecdsa_256", newHostKey);
630 server.addHostKey(newHostKey.toPath(), false);
631 File newHostKeyPub = new File(getTemporaryDirectory(),
632 "newhostkey.pub");
633 copyTestResource("id_ecdsa_256.pub", newHostKeyPub);
634 createKnownHostsFile(knownHosts, "localhost", testPort, newHostKeyPub);
635 cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
636 "Host git",
637 "HostName localhost",
638 "Port " + testPort,
639 "User " + TEST_USER,
640 "IdentityFile " + privateKey1.getAbsolutePath());
641 }
642
643 @Test
644 public void testPasswordAuth() throws Exception {
645 server.enablePasswordAuthentication();
646 TestCredentialsProvider provider = new TestCredentialsProvider(
647 TEST_USER.toUpperCase(Locale.ROOT));
648 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
649 "Host git",
650 "HostName localhost",
651 "Port " + testPort,
652 "User " + TEST_USER,
653 "PreferredAuthentications password");
654 }
655
656 @Test
657 public void testPasswordAuthSeveralTimes() throws Exception {
658 server.enablePasswordAuthentication();
659 TestCredentialsProvider provider = new TestCredentialsProvider(
660 "wrongpass", "wrongpass", TEST_USER.toUpperCase(Locale.ROOT));
661 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
662 "Host git",
663 "HostName localhost",
664 "Port " + testPort,
665 "User " + TEST_USER,
666 "PreferredAuthentications password");
667 }
668
669 @Test(expected = TransportException.class)
670 public void testPasswordAuthWrongPassword() throws Exception {
671 server.enablePasswordAuthentication();
672 TestCredentialsProvider provider = new TestCredentialsProvider(
673 "wrongpass");
674 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
675 "Host git",
676 "HostName localhost",
677 "Port " + testPort,
678 "User " + TEST_USER,
679 "PreferredAuthentications password");
680 }
681
682 @Test(expected = TransportException.class)
683 public void testPasswordAuthNoPassword() throws Exception {
684 server.enablePasswordAuthentication();
685 TestCredentialsProvider provider = new TestCredentialsProvider();
686 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
687 "Host git",
688 "HostName localhost",
689 "Port " + testPort,
690 "User " + TEST_USER,
691 "PreferredAuthentications password");
692 }
693
694 @Test(expected = TransportException.class)
695 public void testPasswordAuthCorrectPasswordTooLate() throws Exception {
696 server.enablePasswordAuthentication();
697 TestCredentialsProvider provider = new TestCredentialsProvider(
698 "wrongpass", "wrongpass", "wrongpass",
699 TEST_USER.toUpperCase(Locale.ROOT));
700 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
701 "Host git",
702 "HostName localhost",
703 "Port " + testPort,
704 "User " + TEST_USER,
705 "PreferredAuthentications password");
706 }
707
708 @Test
709 public void testKeyboardInteractiveAuth() throws Exception {
710 server.enableKeyboardInteractiveAuthentication();
711 TestCredentialsProvider provider = new TestCredentialsProvider(
712 TEST_USER.toUpperCase(Locale.ROOT));
713 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
714 "Host git",
715 "HostName localhost",
716 "Port " + testPort,
717 "User " + TEST_USER,
718 "PreferredAuthentications keyboard-interactive");
719 }
720
721 @Test
722 public void testKeyboardInteractiveAuthSeveralTimes() throws Exception {
723 server.enableKeyboardInteractiveAuthentication();
724 TestCredentialsProvider provider = new TestCredentialsProvider(
725 "wrongpass", "wrongpass", TEST_USER.toUpperCase(Locale.ROOT));
726 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
727 "Host git",
728 "HostName localhost",
729 "Port " + testPort,
730 "User " + TEST_USER,
731 "PreferredAuthentications keyboard-interactive");
732 }
733
734 @Test(expected = TransportException.class)
735 public void testKeyboardInteractiveAuthWrongPassword() throws Exception {
736 server.enableKeyboardInteractiveAuthentication();
737 TestCredentialsProvider provider = new TestCredentialsProvider(
738 "wrongpass");
739 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
740 "Host git",
741 "HostName localhost",
742 "Port " + testPort,
743 "User " + TEST_USER,
744 "PreferredAuthentications keyboard-interactive");
745 }
746
747 @Test(expected = TransportException.class)
748 public void testKeyboardInteractiveAuthNoPassword() throws Exception {
749 server.enableKeyboardInteractiveAuthentication();
750 TestCredentialsProvider provider = new TestCredentialsProvider();
751 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
752 "Host git",
753 "HostName localhost",
754 "Port " + testPort,
755 "User " + TEST_USER,
756 "PreferredAuthentications keyboard-interactive");
757 }
758
759 @Test(expected = TransportException.class)
760 public void testKeyboardInteractiveAuthCorrectPasswordTooLate()
761 throws Exception {
762 server.enableKeyboardInteractiveAuthentication();
763 TestCredentialsProvider provider = new TestCredentialsProvider(
764 "wrongpass", "wrongpass", "wrongpass",
765 TEST_USER.toUpperCase(Locale.ROOT));
766 cloneWith("ssh://git/doesntmatter", defaultCloneDir, provider, //
767 "Host git",
768 "HostName localhost",
769 "Port " + testPort,
770 "User " + TEST_USER,
771 "PreferredAuthentications keyboard-interactive");
772 }
773
774 @Theory
775 public void testSshKeys(String keyName) throws Exception {
776
777
778 assumeTrue(!(isJsch() && (keyName.contains("ed25519")
779 || keyName.startsWith("id_ecdsa_384")
780 || keyName.startsWith("id_ecdsa_521"))));
781 File cloned = new File(getTemporaryDirectory(), "cloned");
782 String keyFileName = keyName + "_key";
783 File privateKey = new File(sshDir, keyFileName);
784 copyTestResource(keyName, privateKey);
785 File publicKey = new File(sshDir, keyFileName + ".pub");
786 copyTestResource(keyName + ".pub", publicKey);
787 server.setTestUserPublicKey(publicKey.toPath());
788 TestCredentialsProvider provider = new TestCredentialsProvider(
789 "testpass");
790 pushTo(provider,
791 cloneWith("ssh://localhost/doesntmatter", //
792 cloned, provider,
793 "Host localhost",
794 "HostName localhost",
795 "Port " + testPort,
796 "User " + TEST_USER,
797 "IdentityFile " + privateKey.getAbsolutePath()));
798 int expectedCalls = keyName.endsWith("testpass") ? 1 : 0;
799 assertEquals("Unexpected calls to CredentialsProvider", expectedCalls,
800 provider.getLog().size());
801
802
803 cloned = new File(getTemporaryDirectory(), "cloned2");
804 pushTo(null,
805 cloneWith("ssh://localhost/doesntmatter", //
806 cloned, null,
807 "Host localhost",
808 "HostName localhost",
809 "Port " + testPort,
810 "User " + TEST_USER,
811 "IdentityFile " + privateKey.getAbsolutePath()));
812 }
813 }