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