@@ -36,6 +36,11 @@ static char *_remote_expectcontinue = NULL;
36
36
static char * _remote_redirect_initial = NULL ;
37
37
static char * _remote_redirect_subsequent = NULL ;
38
38
39
+ static char * _github_ssh_pubkey = NULL ;
40
+ static char * _github_ssh_privkey = NULL ;
41
+ static char * _github_ssh_passphrase = NULL ;
42
+ static char * _github_ssh_remotehostkey = NULL ;
43
+
39
44
static int _orig_proxies_need_reset = 0 ;
40
45
static char * _orig_http_proxy = NULL ;
41
46
static char * _orig_https_proxy = NULL ;
@@ -85,6 +90,11 @@ void test_online_clone__initialize(void)
85
90
_remote_redirect_initial = cl_getenv ("GITTEST_REMOTE_REDIRECT_INITIAL" );
86
91
_remote_redirect_subsequent = cl_getenv ("GITTEST_REMOTE_REDIRECT_SUBSEQUENT" );
87
92
93
+ _github_ssh_pubkey = cl_getenv ("GITTEST_GITHUB_SSH_PUBKEY" );
94
+ _github_ssh_privkey = cl_getenv ("GITTEST_GITHUB_SSH_KEY" );
95
+ _github_ssh_passphrase = cl_getenv ("GITTEST_GITHUB_SSH_PASSPHRASE" );
96
+ _github_ssh_remotehostkey = cl_getenv ("GITTEST_GITHUB_SSH_REMOTE_HOSTKEY" );
97
+
88
98
if (_remote_expectcontinue )
89
99
git_libgit2_opts (GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE , 1 );
90
100
@@ -119,6 +129,11 @@ void test_online_clone__cleanup(void)
119
129
git__free (_remote_redirect_initial );
120
130
git__free (_remote_redirect_subsequent );
121
131
132
+ git__free (_github_ssh_pubkey );
133
+ git__free (_github_ssh_privkey );
134
+ git__free (_github_ssh_passphrase );
135
+ git__free (_github_ssh_remotehostkey );
136
+
122
137
if (_orig_proxies_need_reset ) {
123
138
cl_setenv ("HTTP_PROXY" , _orig_http_proxy );
124
139
cl_setenv ("HTTPS_PROXY" , _orig_https_proxy );
@@ -554,6 +569,68 @@ static int check_ssh_auth_methods(git_credential **cred, const char *url, const
554
569
return GIT_EUSER ;
555
570
}
556
571
572
+ static int succeed_certificate_check (git_cert * cert , int valid , const char * host , void * payload )
573
+ {
574
+ GIT_UNUSED (cert );
575
+ GIT_UNUSED (valid );
576
+ GIT_UNUSED (payload );
577
+
578
+ cl_assert_equal_s ("github.com" , host );
579
+
<
EDBE
/td>580
+ return 0 ;
581
+ }
582
+
583
+ static int fail_certificate_check (git_cert * cert , int valid , const char * host , void * payload )
584
+ {
585
+ GIT_UNUSED (cert );
586
+ GIT_UNUSED (valid );
587
+ GIT_UNUSED (host );
588
+ GIT_UNUSED (payload );
589
+
590
+ return GIT_ECERTIFICATE ;
591
+ }
592
+
593
+ static int github_credentials (
594
+ git_credential * * cred ,
595
+ const char * url ,
596
+ const char * username_from_url ,
597
+ unsigned int allowed_types ,
598
+ void * data )
599
+ {
600
+ GIT_UNUSED (url );
601
+ GIT_UNUSED (username_from_url );
602
+ GIT_UNUSED (data );
603
+
604
+ if ((allowed_types & GIT_CREDENTIAL_USERNAME ) != 0 ) {
605
+ return git_credential_username_new (cred , "git" );
606
+ }
607
+
608
+ cl_assert ((allowed_types & GIT_CREDENTIAL_SSH_KEY ) != 0 );
609
+
610
+ return git_credential_ssh_key_memory_new (cred ,
611
+ "git" ,
612
+ _github_ssh_pubkey ,
613
+ _github_ssh_privkey ,
614
+ _github_ssh_passphrase );
615
+ }
616
+
617
+ void test_online_clone__ssh_github (void )
618
+ {
619
+ #if !defined(GIT_SSH ) || !defined(GIT_SSH_MEMORY_CREDENTIALS )
620
+ clar__skip ();
621
+ #endif
622
+
623
+ if (!_github_ssh_pubkey || !_github_ssh_privkey )
624
+ clar__skip ();
625
+
626
+ cl_fake_homedir (NULL );
627
+
628
+ g_options .fetch_opts .callbacks .credentials = github_credentials ;
629
+ g_options .fetch_opts .callbacks .certificate_check = succeed_certificate_check ;
630
+
631
+ cl_git_pass (git_clone (& g_repo , SSH_REPO_URL , "./foo" , & g_options ));
632
+ }
633
+
557
634
void test_online_clone__ssh_auth_methods (void )
558
635
{
559
636
int with_user ;
@@ -563,7 +640,7 @@ void test_online_clone__ssh_auth_methods(void)
563
640
#endif
564
641
g_options .fetch_opts .callbacks .credentials = check_ssh_auth_methods ;
565
642
g_options .fetch_opts .callbacks .payload = & with_user ;
566
- g_options .fetch_opts .callbacks .certificate_check = NULL ;
643
+ g_options .fetch_opts .callbacks .certificate_check = succeed_certificate_check ;
567
644
568
645
with_user = 0 ;
569
646
cl_git_fail_with (GIT_EUSER ,
@@ -574,6 +651,67 @@ void test_online_clone__ssh_auth_methods(void)
574
651
git_clone (& g_repo , "ssh://git@github.com/libgit2/TestGitRepository" , "./foo" , & g_options ));
575
652
}
576
653
654
+ /*
655
+ * Ensure that the certificate check callback is still called, and
656
+ * can accept a host key that is not in the known hosts file.
657
+ */
658
+ void test_online_clone__ssh_certcheck_accepts_unknown (void )
659
+ {
660
+ #if !defined(GIT_SSH ) || !defined(GIT_SSH_MEMORY_CREDENTIALS )
661
+ clar__skip ();
662
+ #endif
663
+
664
+ if (!_github_ssh_pubkey || !_github_ssh_privkey )
665
+ clar__skip ();
666
+
667
+ cl_fake_homedir (NULL );
668
+
669
+ g_options .fetch_opts .callbacks .credentials = github_credentials ;
670
+
671
+ /* Ensure we fail without the certificate check */
672
+ cl_git_fail_with (GIT_ECERTIFICATE ,
673
+ git_clone (& g_repo , SSH_REPO_URL , "./foo" , NULL ));
674
+
675
+ /* Set the callback to accept the certificate */
676
+ g_options .fetch_opts .callbacks .certificate_check = succeed_certificate_check ;
677
+
678
+ cl_git_pass (git_clone (& g_repo , SSH_REPO_URL , "./foo" , & g_options ));
679
+ }
680
+
681
+ /*
682
+ * Ensure that the known hosts file is read and the certificate check
683
+ * callback is still called after that.
684
+ */
685
+ void test_online_clone__ssh_certcheck_override_knownhosts (void )
686
+ {
687
+ git_str knownhostsfile = GIT_STR_INIT ;
688
+
689
+ #if !defined(GIT_SSH ) || !defined(GIT_SSH_MEMORY_CREDENTIALS )
690
+ clar__skip ();
691
+ #endif
692
+
693
+ if (!_github_ssh_pubkey || !_github_ssh_privkey || !_github_ssh_remotehostkey )
694
+ clar__skip ();
695
+
696
+ g_options .fetch_opts .callbacks .credentials = github_credentials ;
697
+
698
+ cl_fake_homedir (& knownhostsfile );
699
+ cl_git_pass (git_str_joinpath (& knownhostsfile , knownhostsfile .ptr , ".ssh" ));
700
+ cl_git_pass (p_mkdir (knownhostsfile .ptr , 0777 ));
701
+
702
+ cl_git_pass (git_str_joinpath (& knownhostsfile , knownhostsfile .ptr , "known_hosts" ));
703
+ cl_git_rewritefile (knownhostsfile .ptr , _github_ssh_remotehostkey );
704
+
705
+ /* Ensure we succeed without the certificate check */
706
+ cl_git_pass (git_clone (& g_repo , SSH_REPO_URL , "./foo" , & g_options ));
707
+
708
+ /* Set the callback to accept the certificate */
709
+ g_options .fetch_opts .callbacks .certificate_check = fail_certificate_check ;
710
+ cl_git_fail_with (GIT_ECERTIFICATE , git_clone (& g_repo , SSH_REPO_URL , "./bar" , & g_options ));
711
+
712
+ git_str_dispose (& knownhostsfile );
713
+ }
714
+
577
715
static int custom_remote_ssh_with_paths (
578
716
git_remote * * out ,
579
717
git_repository * repo ,
@@ -746,16 +884,6 @@ void test_online_clone__ssh_memory_auth(void)
746
884
cl_git_pass (git_clone (& g_repo , _remote_url , "./foo" , & g_options ));
747
885
}
748
886
749
- static int fail_certificate_check (git_cert * cert , int valid , const char * host , void * payload )
750
- {
751
- GIT_UNUSED (cert );
752
- GIT_UNUSED (valid );
753
- GIT_UNUSED (host );
754
- GIT_UNUSED (payload );
755
-
756
- return GIT_ECERTIFICATE ;
757
- }
758
-
759
887
void test_online_clone__certificate_invalid (void )
760
888
{
761
889
g_options .fetch_opts .callbacks .certificate_check = fail_certificate_check ;
@@ -769,17 +897,6 @@ void test_online_clone__certificate_invalid(void)
769
897
#endif
770
898
}
771
899
772
- static int succeed_certificate_check (git_cert * cert , int valid , const char * host , void * payload )
773
- {
774
- GIT_UNUSED (cert );
775
- GIT_UNUSED (valid );
776
- GIT_UNUSED (payload );
777
-
778
- cl_assert_equal_s ("github.com" , host );
779
-
780
- return 0 ;
781
- }
782
-
783
900
void test_online_clone__certificate_valid (void )
784
901
{
785
902
g_options .fetch_opts .callbacks .certificate_check = succeed_certificate_check ;
0 commit comments