]>
Commit | Line | Data |
---|---|---|
65415ea2 BS |
1 | #include "clar_libgit2.h" |
2 | ||
3 | #include "git2/clone.h" | |
520dcc1c | 4 | #include "git2/cred_helpers.h" |
6f748f38 | 5 | #include "remote.h" |
22a2d3d5 | 6 | #include "futils.h" |
114f5a6c | 7 | #include "refs.h" |
65415ea2 | 8 | |
44f36f6e BS |
9 | #define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository" |
10 | #define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository" | |
e579e0f7 MB |
11 | #define BB_REPO_URL "https://libgit2-test@bitbucket.org/libgit2-test/testgitrepository.git" |
12 | #define BB_REPO_URL_WITH_PASS "https://libgit2-test:YT77Ppm2nq8w4TYjGS8U@bitbucket.org/libgit2-test/testgitrepository.git" | |
13 | #define BB_REPO_URL_WITH_WRONG_PASS "https://libgit2-test:wrong@bitbucket.org/libgit2-test/testgitrepository.git" | |
22a2d3d5 | 14 | #define GOOGLESOURCE_REPO_URL "https://chromium.googlesource.com/external/github.com/sergi/go-diff" |
65415ea2 | 15 | |
22618906 CMN |
16 | #define SSH_REPO_URL "ssh://github.com/libgit2/TestGitRepository" |
17 | ||
65415ea2 | 18 | static git_repository *g_repo; |
18b2d560 | 19 | static git_clone_options g_options; |
65415ea2 | 20 | |
e069c621 ET |
21 | static char *_remote_url = NULL; |
22 | static char *_remote_user = NULL; | |
23 | static char *_remote_pass = NULL; | |
ac3d33df | 24 | static char *_remote_sslnoverify = NULL; |
e069c621 ET |
25 | static char *_remote_ssh_pubkey = NULL; |
26 | static char *_remote_ssh_privkey = NULL; | |
27 | static char *_remote_ssh_passphrase = NULL; | |
28 | static char *_remote_ssh_fingerprint = NULL; | |
ac3d33df JK |
29 | static char *_remote_proxy_scheme = NULL; |
30 | static char *_remote_proxy_host = NULL; | |
07bd3e57 CMN |
31 | static char *_remote_proxy_user = NULL; |
32 | static char *_remote_proxy_pass = NULL; | |
ac3d33df | 33 | static char *_remote_proxy_selfsigned = NULL; |
22a2d3d5 | 34 | static char *_remote_expectcontinue = NULL; |
e579e0f7 MB |
35 | static char *_remote_redirect_initial = NULL; |
36 | static char *_remote_redirect_subsequent = NULL; | |
e069c621 | 37 | |
ac3d33df JK |
38 | static int _orig_proxies_need_reset = 0; |
39 | static char *_orig_http_proxy = NULL; | |
40 | static char *_orig_https_proxy = NULL; | |
c25aa7cd | 41 | static char *_orig_no_proxy = NULL; |
ac3d33df JK |
42 | |
43 | static int ssl_cert(git_cert *cert, int valid, const char *host, void *payload) | |
44 | { | |
45 | GIT_UNUSED(cert); | |
46 | GIT_UNUSED(host); | |
47 | GIT_UNUSED(payload); | |
48 | ||
49 | if (_remote_sslnoverify != NULL) | |
50 | valid = 1; | |
51 | ||
52 | return valid ? 0 : GIT_ECERTIFICATE; | |
53 | } | |
e069c621 | 54 | |
6443eaf2 | 55 | void test_online_clone__initialize(void) |
65415ea2 | 56 | { |
6affd71f | 57 | git_checkout_options dummy_opts = GIT_CHECKOUT_OPTIONS_INIT; |
8f0104ec | 58 | git_fetch_options dummy_fetch = GIT_FETCH_OPTIONS_INIT; |
730df6d0 | 59 | |
65415ea2 | 60 | g_repo = NULL; |
18b2d560 BS |
61 | |
62 | memset(&g_options, 0, sizeof(git_clone_options)); | |
63 | g_options.version = GIT_CLONE_OPTIONS_VERSION; | |
730df6d0 BS |
64 | g_options.checkout_opts = dummy_opts; |
65 | g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; | |
8f0104ec | 66 | g_options.fetch_opts = dummy_fetch; |
ac3d33df | 67 | g_options.fetch_opts.callbacks.certificate_check = ssl_cert; |
e069c621 ET |
68 | |
69 | _remote_url = cl_getenv("GITTEST_REMOTE_URL"); | |
70 | _remote_user = cl_getenv("GITTEST_REMOTE_USER"); | |
71 | _remote_pass = cl_getenv("GITTEST_REMOTE_PASS"); | |
ac3d33df | 72 | _remote_sslnoverify = cl_getenv("GITTEST_REMOTE_SSL_NOVERIFY"); |
e069c621 ET |
73 | _remote_ssh_pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY"); |
74 | _remote_ssh_privkey = cl_getenv("GITTEST_REMOTE_SSH_KEY"); | |
75 | _remote_ssh_passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE"); | |
76 | _remote_ssh_fingerprint = cl_getenv("GITTEST_REMOTE_SSH_FINGERPRINT"); | |
ac3d33df JK |
77 | _remote_proxy_scheme = cl_getenv("GITTEST_REMOTE_PROXY_SCHEME"); |
78 | _remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST"); | |
07bd3e57 CMN |
79 | _remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER"); |
80 | _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS"); | |
ac3d33df | 81 | _remote_proxy_selfsigned = cl_getenv("GITTEST_REMOTE_PROXY_SELFSIGNED"); |
22a2d3d5 | 82 | _remote_expectcontinue = cl_getenv("GITTEST_REMOTE_EXPECTCONTINUE"); |
e579e0f7 MB |
83 | _remote_redirect_initial = cl_getenv("GITTEST_REMOTE_REDIRECT_INITIAL"); |
84 | _remote_redirect_subsequent = cl_getenv("GITTEST_REMOTE_REDIRECT_SUBSEQUENT"); | |
22a2d3d5 UG |
85 | |
86 | if (_remote_expectcontinue) | |
87 | git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 1); | |
ac3d33df JK |
88 | |
89 | _orig_proxies_need_reset = 0; | |
65415ea2 BS |
90 | } |
91 | ||
6443eaf2 | 92 | void test_online_clone__cleanup(void) |
65415ea2 | 93 | { |
9094d30b | 94 | if (g_repo) { |
65415ea2 | 95 | git_repository_free(g_repo); |
9094d30b SC |
96 | g_repo = NULL; |
97 | } | |
7761ce21 | 98 | cl_fixture_cleanup("./foo"); |
e579e0f7 MB |
99 | cl_fixture_cleanup("./initial"); |
100 | cl_fixture_cleanup("./subsequent"); | |
e069c621 ET |
101 | |
102 | git__free(_remote_url); | |
103 | git__free(_remote_user); | |
104 | git__free(_remote_pass); | |
ac3d33df | 105 | git__free(_remote_sslnoverify); |
e069c621 ET |
106 | git__free(_remote_ssh_pubkey); |
107 | git__free(_remote_ssh_privkey); | |
108 | git__free(_remote_ssh_passphrase); | |
109 | git__free(_remote_ssh_fingerprint); | |
ac3d33df JK |
110 | git__free(_remote_proxy_scheme); |
111 | git__free(_remote_proxy_host); | |
07bd3e57 CMN |
112 | git__free(_remote_proxy_user); |
113 | git__free(_remote_proxy_pass); | |
ac3d33df | 114 | git__free(_remote_proxy_selfsigned); |
22a2d3d5 | 115 | git__free(_remote_expectcontinue); |
e579e0f7 MB |
116 | git__free(_remote_redirect_initial); |
117 | git__free(_remote_redirect_subsequent); | |
ac3d33df JK |
118 | |
119 | if (_orig_proxies_need_reset) { | |
120 | cl_setenv("HTTP_PROXY", _orig_http_proxy); | |
121 | cl_setenv("HTTPS_PROXY", _orig_https_proxy); | |
c25aa7cd | 122 | cl_setenv("NO_PROXY", _orig_no_proxy); |
ac3d33df JK |
123 | |
124 | git__free(_orig_http_proxy); | |
125 | git__free(_orig_https_proxy); | |
c25aa7cd | 126 | git__free(_orig_no_proxy); |
ac3d33df | 127 | } |
c25aa7cd PP |
128 | |
129 | git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, NULL); | |
65415ea2 BS |
130 | } |
131 | ||
6443eaf2 | 132 | void test_online_clone__network_full(void) |
65415ea2 BS |
133 | { |
134 | git_remote *origin; | |
135 | ||
b412d563 | 136 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); |
65415ea2 | 137 | cl_assert(!git_repository_is_bare(g_repo)); |
209425ce | 138 | cl_git_pass(git_remote_lookup(&origin, g_repo, "origin")); |
add5efe7 | 139 | |
6f748f38 JM |
140 | cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, origin->download_tags); |
141 | ||
add5efe7 | 142 | git_remote_free(origin); |
65415ea2 BS |
143 | } |
144 | ||
6443eaf2 | 145 | void test_online_clone__network_bare(void) |
65415ea2 BS |
146 | { |
147 | git_remote *origin; | |
148 | ||
18b2d560 | 149 | g_options.bare = true; |
65415ea2 | 150 | |
b412d563 | 151 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); |
65415ea2 | 152 | cl_assert(git_repository_is_bare(g_repo)); |
209425ce | 153 | cl_git_pass(git_remote_lookup(&origin, g_repo, "origin")); |
add5efe7 | 154 | |
155 | git_remote_free(origin); | |
65415ea2 BS |
156 | } |
157 | ||
6443eaf2 | 158 | void test_online_clone__empty_repository(void) |
65415ea2 BS |
159 | { |
160 | git_reference *head; | |
161 | ||
b412d563 | 162 | cl_git_pass(git_clone(&g_repo, LIVE_EMPTYREPO_URL, "./foo", &g_options)); |
65415ea2 BS |
163 | |
164 | cl_assert_equal_i(true, git_repository_is_empty(g_repo)); | |
605da51a | 165 | cl_assert_equal_i(true, git_repository_head_unborn(g_repo)); |
65415ea2 BS |
166 | |
167 | cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE)); | |
ac3d33df | 168 | cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); |
2508cc66 | 169 | cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); |
65415ea2 BS |
170 | |
171 | git_reference_free(head); | |
172 | } | |
4d968f13 | 173 | |
9c05c17b | 174 | static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload) |
183d8bdd | 175 | { |
183d8bdd | 176 | bool *was_called = (bool*)payload; |
1fc375e6 | 177 | GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot); |
183d8bdd BS |
178 | (*was_called) = true; |
179 | } | |
180 | ||
22a2d3d5 | 181 | static int fetch_progress(const git_indexer_progress *stats, void *payload) |
aa1e8674 | 182 | { |
aa1e8674 | 183 | bool *was_called = (bool*)payload; |
1fc375e6 | 184 | GIT_UNUSED(stats); |
aa1e8674 | 185 | (*was_called) = true; |
fe95ac1b | 186 | return 0; |
aa1e8674 BS |
187 | } |
188 | ||
6443eaf2 | 189 | void test_online_clone__can_checkout_a_cloned_repo(void) |
4d968f13 | 190 | { |
e579e0f7 | 191 | git_str path = GIT_STR_INIT; |
22a2d3d5 | 192 | git_reference *head, *remote_head; |
aa1e8674 BS |
193 | bool checkout_progress_cb_was_called = false, |
194 | fetch_progress_cb_was_called = false; | |
4d968f13 | 195 | |
6c9e86ad | 196 | g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; |
730df6d0 BS |
197 | g_options.checkout_opts.progress_cb = &checkout_progress; |
198 | g_options.checkout_opts.progress_payload = &checkout_progress_cb_was_called; | |
8f0104ec CMN |
199 | g_options.fetch_opts.callbacks.transfer_progress = &fetch_progress; |
200 | g_options.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; | |
4d968f13 | 201 | |
b412d563 | 202 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); |
4d968f13 | 203 | |
e579e0f7 MB |
204 | cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); |
205 | cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&path))); | |
c4f68b32 | 206 | |
207 | cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); | |
ac3d33df | 208 | cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); |
2508cc66 | 209 | cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); |
add5efe7 | 210 | |
22a2d3d5 UG |
211 | cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); |
212 | cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); | |
213 | cl_assert_equal_s("refs/remotes/origin/master", git_reference_symbolic_target(remote_head)); | |
214 | ||
aa1e8674 BS |
215 | cl_assert_equal_i(true, checkout_progress_cb_was_called); |
216 | cl_assert_equal_i(true, fetch_progress_cb_was_called); | |
183d8bdd | 217 | |
22a2d3d5 | 218 | git_reference_free(remote_head); |
add5efe7 | 219 | git_reference_free(head); |
e579e0f7 | 220 | git_str_dispose(&path); |
4d968f13 | 221 | } |
621b50e4 | 222 | |
6812afaf CMN |
223 | static int remote_mirror_cb(git_remote **out, git_repository *repo, |
224 | const char *name, const char *url, void *payload) | |
d19870d9 | 225 | { |
6812afaf | 226 | int error; |
d19870d9 | 227 | git_remote *remote; |
d19870d9 | 228 | |
8f0104ec | 229 | GIT_UNUSED(payload); |
d19870d9 | 230 | |
77254990 | 231 | if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0) |
6812afaf | 232 | return error; |
d19870d9 | 233 | |
6812afaf CMN |
234 | *out = remote; |
235 | return 0; | |
d19870d9 CMN |
236 | } |
237 | ||
b2067248 CMN |
238 | void test_online_clone__clone_mirror(void) |
239 | { | |
6812afaf | 240 | git_clone_options opts = GIT_CLONE_OPTIONS_INIT; |
b2067248 | 241 | git_reference *head; |
b2067248 CMN |
242 | |
243 | bool fetch_progress_cb_was_called = false; | |
244 | ||
8f0104ec CMN |
245 | opts.fetch_opts.callbacks.transfer_progress = &fetch_progress; |
246 | opts.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; | |
b2067248 | 247 | |
6812afaf CMN |
248 | opts.bare = true; |
249 | opts.remote_cb = remote_mirror_cb; | |
b2067248 | 250 | |
6812afaf | 251 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo.git", &opts)); |
b2067248 CMN |
252 | |
253 | cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); | |
ac3d33df | 254 | cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); |
b2067248 CMN |
255 | cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); |
256 | ||
257 | cl_assert_equal_i(true, fetch_progress_cb_was_called); | |
258 | ||
b2067248 | 259 | git_reference_free(head); |
6d1b0438 PK |
260 | git_repository_free(g_repo); |
261 | g_repo = NULL; | |
262 | ||
b2067248 CMN |
263 | cl_fixture_cleanup("./foo.git"); |
264 | } | |
265 | ||
621b50e4 BS |
266 | static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload) |
267 | { | |
268 | int *callcount = (int*)payload; | |
269 | GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b); | |
270 | *callcount = *callcount + 1; | |
271 | return 0; | |
272 | } | |
273 | ||
ffb02b16 | 274 | void test_online_clone__custom_remote_callbacks(void) |
621b50e4 | 275 | { |
621b50e4 BS |
276 | int callcount = 0; |
277 | ||
8f0104ec CMN |
278 | g_options.fetch_opts.callbacks.update_tips = update_tips; |
279 | g_options.fetch_opts.callbacks.payload = &callcount; | |
621b50e4 BS |
280 | |
281 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
282 | cl_assert(callcount > 0); | |
283 | } | |
284 | ||
3245896b MB |
285 | void test_online_clone__custom_headers(void) |
286 | { | |
287 | char *empty_header = ""; | |
288 | char *unnamed_header = "this is a header about nothing"; | |
289 | char *newlines = "X-Custom: almost OK\n"; | |
290 | char *conflict = "Accept: defined-by-git"; | |
291 | char *ok = "X-Custom: this should be ok"; | |
292 | ||
293 | g_options.fetch_opts.custom_headers.count = 1; | |
294 | ||
295 | g_options.fetch_opts.custom_headers.strings = &empty_header; | |
296 | cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
297 | ||
298 | g_options.fetch_opts.custom_headers.strings = &unnamed_header; | |
299 | cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
300 | ||
301 | g_options.fetch_opts.custom_headers.strings = &newlines; | |
302 | cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
303 | ||
304 | g_options.fetch_opts.custom_headers.strings = &conflict; | |
305 | cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
306 | ||
307 | /* Finally, we got it right! */ | |
308 | g_options.fetch_opts.custom_headers.strings = &ok; | |
309 | cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
310 | } | |
311 | ||
80fc7d6b | 312 | static int cred_failure_cb( |
22a2d3d5 | 313 | git_credential **cred, |
80fc7d6b ET |
314 | const char *url, |
315 | const char *username_from_url, | |
316 | unsigned int allowed_types, | |
317 | void *data) | |
318 | { | |
8f2a3d62 RB |
319 | GIT_UNUSED(cred); GIT_UNUSED(url); GIT_UNUSED(username_from_url); |
320 | GIT_UNUSED(allowed_types); GIT_UNUSED(data); | |
fe45922d | 321 | return -172; |
80fc7d6b ET |
322 | } |
323 | ||
fe45922d | 324 | void test_online_clone__cred_callback_failure_return_code_is_tunnelled(void) |
80fc7d6b | 325 | { |
6c7cee42 RD |
326 | git__free(_remote_url); |
327 | git__free(_remote_user); | |
328 | ||
eae0bfdc PP |
329 | _remote_url = git__strdup("https://github.com/libgit2/non-existent"); |
330 | _remote_user = git__strdup("libgit2test"); | |
5dae3ffe | 331 | |
8f0104ec | 332 | g_options.fetch_opts.callbacks.credentials = cred_failure_cb; |
80fc7d6b | 333 | |
e069c621 | 334 | cl_git_fail_with(-172, git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
80fc7d6b ET |
335 | } |
336 | ||
22a2d3d5 | 337 | static int cred_count_calls_cb(git_credential **cred, const char *url, const char *user, |
d7f962f4 CMN |
338 | unsigned int allowed_types, void *data) |
339 | { | |
340 | size_t *counter = (size_t *) data; | |
341 | ||
342 | GIT_UNUSED(url); GIT_UNUSED(user); GIT_UNUSED(allowed_types); | |
343 | ||
22a2d3d5 UG |
344 | if (allowed_types == GIT_CREDENTIAL_USERNAME) |
345 | return git_credential_username_new(cred, "foo"); | |
ccb85c8f | 346 | |
d7f962f4 CMN |
347 | (*counter)++; |
348 | ||
349 | if (*counter == 3) | |
350 | return GIT_EUSER; | |
351 | ||
22a2d3d5 | 352 | return git_credential_userpass_plaintext_new(cred, "foo", "bar"); |
d7f962f4 CMN |
353 | } |
354 | ||
355 | void test_online_clone__cred_callback_called_again_on_auth_failure(void) | |
356 | { | |
d7f962f4 CMN |
357 | size_t counter = 0; |
358 | ||
6c7cee42 RD |
359 | git__free(_remote_url); |
360 | git__free(_remote_user); | |
361 | ||
22a2d3d5 | 362 | _remote_url = git__strdup("https://gitlab.com/libgit2/non-existent"); |
eae0bfdc | 363 | _remote_user = git__strdup("libgit2test"); |
d7f962f4 | 364 | |
8f0104ec CMN |
365 | g_options.fetch_opts.callbacks.credentials = cred_count_calls_cb; |
366 | g_options.fetch_opts.callbacks.payload = &counter; | |
d7f962f4 | 367 | |
e069c621 | 368 | cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
d7f962f4 CMN |
369 | cl_assert_equal_i(3, counter); |
370 | } | |
371 | ||
e579e0f7 | 372 | static int cred_default( |
22a2d3d5 | 373 | git_credential **cred, |
adcdeb36 ET |
374 | const char *url, |
375 | const char *user_from_url, | |
376 | unsigned int allowed_types, | |
377 | void *payload) | |
378 | { | |
379 | GIT_UNUSED(url); | |
380 | GIT_UNUSED(user_from_url); | |
381 | GIT_UNUSED(payload); | |
382 | ||
22a2d3d5 | 383 | if (!(allowed_types & GIT_CREDENTIAL_DEFAULT)) |
adcdeb36 ET |
384 | return 0; |
385 | ||
22a2d3d5 | 386 | return git_credential_default_new(cred); |
adcdeb36 ET |
387 | } |
388 | ||
ffb02b16 | 389 | void test_online_clone__credentials(void) |
621b50e4 | 390 | { |
adcdeb36 ET |
391 | /* Remote URL environment variable must be set. |
392 | * User and password are optional. | |
393 | */ | |
22a2d3d5 | 394 | git_credential_userpass_payload user_pass = { |
e069c621 ET |
395 | _remote_user, |
396 | _remote_pass | |
621b50e4 BS |
397 | }; |
398 | ||
e069c621 ET |
399 | if (!_remote_url) |
400 | clar__skip(); | |
621b50e4 | 401 | |
e069c621 | 402 | if (cl_is_env_set("GITTEST_REMOTE_DEFAULT")) { |
8f0104ec | 403 | g_options.fetch_opts.callbacks.credentials = cred_default; |
adcdeb36 | 404 | } else { |
22a2d3d5 | 405 | g_options.fetch_opts.callbacks.credentials = git_credential_userpass; |
8f0104ec | 406 | g_options.fetch_opts.callbacks.payload = &user_pass; |
adcdeb36 | 407 | } |
621b50e4 | 408 | |
e069c621 | 409 | cl_git_pass(git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
5f10853e BS |
410 | git_repository_free(g_repo); g_repo = NULL; |
411 | cl_fixture_cleanup("./foo"); | |
412 | } | |
413 | ||
22a2d3d5 UG |
414 | void test_online_clone__credentials_via_custom_headers(void) |
415 | { | |
e579e0f7 MB |
416 | const char *creds = "libgit2-test:YT77Ppm2nq8w4TYjGS8U"; |
417 | git_str auth = GIT_STR_INIT; | |
22a2d3d5 | 418 | |
e579e0f7 MB |
419 | cl_git_pass(git_str_puts(&auth, "Authorization: Basic ")); |
420 | cl_git_pass(git_str_encode_base64(&auth, creds, strlen(creds))); | |
22a2d3d5 UG |
421 | g_options.fetch_opts.custom_headers.count = 1; |
422 | g_options.fetch_opts.custom_headers.strings = &auth.ptr; | |
423 | ||
e579e0f7 | 424 | cl_git_pass(git_clone(&g_repo, "https://bitbucket.org/libgit2-test/testgitrepository.git", "./foo", &g_options)); |
22a2d3d5 | 425 | |
e579e0f7 | 426 | git_str_dispose(&auth); |
22a2d3d5 UG |
427 | } |
428 | ||
5f10853e BS |
429 | void test_online_clone__bitbucket_style(void) |
430 | { | |
22a2d3d5 | 431 | git_credential_userpass_payload user_pass = { |
e579e0f7 | 432 | "libgit2-test", "YT77Ppm2nq8w4TYjGS8U" |
5f10853e BS |
433 | }; |
434 | ||
22a2d3d5 | 435 | g_options.fetch_opts.callbacks.credentials = git_credential_userpass; |
8f0104ec | 436 | g_options.fetch_opts.callbacks.payload = &user_pass; |
5f10853e BS |
437 | |
438 | cl_git_pass(git_clone(&g_repo, BB_REPO_URL, "./foo", &g_options)); | |
439 | git_repository_free(g_repo); g_repo = NULL; | |
440 | cl_fixture_cleanup("./foo"); | |
eae0bfdc PP |
441 | } |
442 | ||
443 | void test_online_clone__bitbucket_uses_creds_in_url(void) | |
444 | { | |
22a2d3d5 | 445 | git_credential_userpass_payload user_pass = { |
e579e0f7 | 446 | "libgit2-test", "wrong" |
eae0bfdc PP |
447 | }; |
448 | ||
22a2d3d5 | 449 | g_options.fetch_opts.callbacks.credentials = git_credential_userpass; |
eae0bfdc | 450 | g_options.fetch_opts.callbacks.payload = &user_pass; |
cf7038a6 | 451 | |
eae0bfdc PP |
452 | /* |
453 | * Correct user and pass are in the URL; the (incorrect) creds in | |
22a2d3d5 | 454 | * the `git_credential_userpass_payload` should be ignored. |
eae0bfdc | 455 | */ |
cf7038a6 BS |
456 | cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_PASS, "./foo", &g_options)); |
457 | git_repository_free(g_repo); g_repo = NULL; | |
458 | cl_fixture_cleanup("./foo"); | |
eae0bfdc | 459 | } |
54ffc1f7 | 460 | |
eae0bfdc PP |
461 | void test_online_clone__bitbucket_falls_back_to_specified_creds(void) |
462 | { | |
22a2d3d5 | 463 | git_credential_userpass_payload user_pass = { |
e579e0f7 | 464 | "libgit2-test", "libgit2" |
eae0bfdc PP |
465 | }; |
466 | ||
22a2d3d5 | 467 | g_options.fetch_opts.callbacks.credentials = git_credential_userpass; |
eae0bfdc PP |
468 | g_options.fetch_opts.callbacks.payload = &user_pass; |
469 | ||
470 | /* | |
471 | * TODO: as of March 2018, bitbucket sporadically fails with | |
472 | * 403s instead of replying with a 401 - but only sometimes. | |
473 | */ | |
474 | cl_skip(); | |
475 | ||
476 | /* | |
477 | * Incorrect user and pass are in the URL; the (correct) creds in | |
22a2d3d5 | 478 | * the `git_credential_userpass_payload` should be used as a fallback. |
eae0bfdc | 479 | */ |
54ffc1f7 BS |
480 | cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_WRONG_PASS, "./foo", &g_options)); |
481 | git_repository_free(g_repo); g_repo = NULL; | |
482 | cl_fixture_cleanup("./foo"); | |
621b50e4 | 483 | } |
fe95ac1b | 484 | |
22a2d3d5 UG |
485 | void test_online_clone__googlesource(void) |
486 | { | |
487 | cl_git_pass(git_clone(&g_repo, GOOGLESOURCE_REPO_URL, "./foo", &g_options)); | |
488 | git_repository_free(g_repo); g_repo = NULL; | |
489 | cl_fixture_cleanup("./foo"); | |
490 | } | |
491 | ||
492 | static int cancel_at_half(const git_indexer_progress *stats, void *payload) | |
fe95ac1b BS |
493 | { |
494 | GIT_UNUSED(payload); | |
495 | ||
496 | if (stats->received_objects > (stats->total_objects/2)) | |
25e0b157 | 497 | return 4321; |
fe95ac1b BS |
498 | return 0; |
499 | } | |
500 | ||
501 | void test_online_clone__can_cancel(void) | |
502 | { | |
8f0104ec | 503 | g_options.fetch_opts.callbacks.transfer_progress = cancel_at_half; |
d31402a3 | 504 | |
22a2d3d5 UG |
505 | cl_git_fail_with(4321, |
506 | git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); | |
fe95ac1b | 507 | } |
d31402a3 | 508 | |
22a2d3d5 | 509 | static int cred_cb(git_credential **cred, const char *url, const char *user_from_url, |
d4256ed5 CMN |
510 | unsigned int allowed_types, void *payload) |
511 | { | |
d4256ed5 CMN |
512 | GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload); |
513 | ||
22a2d3d5 UG |
514 | if (allowed_types & GIT_CREDENTIAL_USERNAME) |
515 | return git_credential_username_new(cred, _remote_user); | |
c13b6844 | 516 | |
22a2d3d5 UG |
517 | if (allowed_types & GIT_CREDENTIAL_SSH_KEY) |
518 | return git_credential_ssh_key_new(cred, | |
e069c621 ET |
519 | _remote_user, _remote_ssh_pubkey, |
520 | _remote_ssh_privkey, _remote_ssh_passphrase); | |
d4256ed5 | 521 | |
ac3d33df | 522 | git_error_set(GIT_ERROR_NET, "unexpected cred type"); |
d4256ed5 CMN |
523 | return -1; |
524 | } | |
d31402a3 | 525 | |
22a2d3d5 | 526 | static int check_ssh_auth_methods(git_credential **cred, const char *url, const char *username_from_url, |
22618906 CMN |
527 | unsigned int allowed_types, void *data) |
528 | { | |
e26b08d3 | 529 | int *with_user = (int *) data; |
22618906 | 530 | GIT_UNUSED(cred); GIT_UNUSED(url); GIT_UNUSED(username_from_url); GIT_UNUSED(data); |
d31402a3 | 531 | |
e26b08d3 | 532 | if (!*with_user) |
22a2d3d5 | 533 | cl_assert_equal_i(GIT_CREDENTIAL_USERNAME, allowed_types); |
e26b08d3 | 534 | else |
22a2d3d5 | 535 | cl_assert(!(allowed_types & GIT_CREDENTIAL_USERNAME)); |
d31402a3 | 536 | |
22618906 CMN |
537 | return GIT_EUSER; |
538 | } | |
d31402a3 | 539 | |
22618906 CMN |
540 | void test_online_clone__ssh_auth_methods(void) |
541 | { | |
e26b08d3 CMN |
542 | int with_user; |
543 | ||
fe3b6789 L |
544 | #ifndef GIT_SSH |
545 | clar__skip(); | |
546 | #endif | |
8f0104ec CMN |
547 | g_options.fetch_opts.callbacks.credentials = check_ssh_auth_methods; |
548 | g_options.fetch_opts.callbacks.payload = &with_user; | |
ac3d33df | 549 | g_options.fetch_opts.callbacks.certificate_check = NULL; |
d31402a3 | 550 | |
e26b08d3 | 551 | with_user = 0; |
22618906 CMN |
552 | cl_git_fail_with(GIT_EUSER, |
553 | git_clone(&g_repo, SSH_REPO_URL, "./foo", &g_options)); | |
e26b08d3 CMN |
554 | |
555 | with_user = 1; | |
556 | cl_git_fail_with(GIT_EUSER, | |
557 | git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
558 | } | |
559 | ||
d4256ed5 CMN |
560 | static int custom_remote_ssh_with_paths( |
561 | git_remote **out, | |
562 | git_repository *repo, | |
563 | const char *name, | |
564 | const char *url, | |
565 | void *payload) | |
566 | { | |
567 | int error; | |
d4256ed5 | 568 | |
058b753c | 569 | GIT_UNUSED(payload); |
d4256ed5 | 570 | |
058b753c | 571 | if ((error = git_remote_create(out, repo, name, url)) < 0) |
d4256ed5 | 572 | return error; |
d31402a3 | 573 | |
d4256ed5 CMN |
574 | return 0; |
575 | } | |
576 | ||
577 | void test_online_clone__ssh_with_paths(void) | |
578 | { | |
579 | char *bad_paths[] = { | |
580 | "/bin/yes", | |
581 | "/bin/false", | |
582 | }; | |
583 | char *good_paths[] = { | |
584 | "/usr/bin/git-upload-pack", | |
585 | "/usr/bin/git-receive-pack", | |
586 | }; | |
587 | git_strarray arr = { | |
588 | bad_paths, | |
589 | 2, | |
590 | }; | |
591 | ||
fe3b6789 L |
592 | #ifndef GIT_SSH |
593 | clar__skip(); | |
594 | #endif | |
e069c621 | 595 | if (!_remote_url || !_remote_user || strncmp(_remote_url, "ssh://", 5) != 0) |
d4256ed5 CMN |
596 | clar__skip(); |
597 | ||
598 | g_options.remote_cb = custom_remote_ssh_with_paths; | |
058b753c | 599 | g_options.fetch_opts.callbacks.transport = git_transport_ssh_with_paths; |
352ee171 | 600 | g_options.fetch_opts.callbacks.credentials = cred_cb; |
058b753c | 601 | g_options.fetch_opts.callbacks.payload = &arr; |
ac3d33df | 602 | g_options.fetch_opts.callbacks.certificate_check = NULL; |
d31402a3 | 603 | |
e069c621 | 604 | cl_git_fail(git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
d31402a3 | 605 | |
d4256ed5 | 606 | arr.strings = good_paths; |
e069c621 | 607 | cl_git_pass(git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
d4256ed5 | 608 | } |
d31402a3 | 609 | |
22a2d3d5 | 610 | static int cred_foo_bar(git_credential **cred, const char *url, const char *username_from_url, |
e26b08d3 CMN |
611 | unsigned int allowed_types, void *data) |
612 | ||
613 | { | |
614 | GIT_UNUSED(url); GIT_UNUSED(username_from_url); GIT_UNUSED(allowed_types); GIT_UNUSED(data); | |
615 | ||
22a2d3d5 | 616 | return git_credential_userpass_plaintext_new(cred, "foo", "bar"); |
e26b08d3 CMN |
617 | } |
618 | ||
619 | void test_online_clone__ssh_cannot_change_username(void) | |
620 | { | |
fe3b6789 L |
621 | #ifndef GIT_SSH |
622 | clar__skip(); | |
623 | #endif | |
8f0104ec | 624 | g_options.fetch_opts.callbacks.credentials = cred_foo_bar; |
e26b08d3 CMN |
625 | |
626 | cl_git_fail(git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
22618906 | 627 | } |
f0c53d21 | 628 | |
e579e0f7 | 629 | static int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload) |
bf8756d6 CMN |
630 | { |
631 | git_cert_hostkey *key; | |
632 | git_oid expected = {{0}}, actual = {{0}}; | |
bf8756d6 | 633 | |
bf8756d6 CMN |
634 | GIT_UNUSED(valid); |
635 | GIT_UNUSED(payload); | |
636 | ||
e069c621 | 637 | cl_assert(_remote_ssh_fingerprint); |
bf8756d6 | 638 | |
e069c621 | 639 | cl_git_pass(git_oid_fromstrp(&expected, _remote_ssh_fingerprint)); |
0782fc43 | 640 | cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type); |
0782fc43 | 641 | key = (git_cert_hostkey *) cert; |
bf8756d6 | 642 | |
1e0aa105 CMN |
643 | /* |
644 | * We need to figure out how long our input was to check for | |
645 | * the type. Here we abuse the fact that both hashes fit into | |
646 | * our git_oid type. | |
647 | */ | |
e069c621 | 648 | if (strlen(_remote_ssh_fingerprint) == 32 && key->type & GIT_CERT_SSH_MD5) { |
1e0aa105 | 649 | memcpy(&actual.id, key->hash_md5, 16); |
e069c621 | 650 | } else if (strlen(_remote_ssh_fingerprint) == 40 && key->type & GIT_CERT_SSH_SHA1) { |
1e0aa105 CMN |
651 | memcpy(&actual, key->hash_sha1, 20); |
652 | } else { | |
653 | cl_fail("Cannot find a usable SSH hash"); | |
654 | } | |
286369a8 | 655 | |
1e0aa105 | 656 | cl_assert(!memcmp(&expected, &actual, 20)); |
bf8756d6 | 657 | |
db3d169c SS |
658 | cl_assert_equal_s("localhost", host); |
659 | ||
bf8756d6 CMN |
660 | return GIT_EUSER; |
661 | } | |
662 | ||
663 | void test_online_clone__ssh_cert(void) | |
664 | { | |
8f0104ec | 665 | g_options.fetch_opts.callbacks.certificate_check = ssh_certificate_check; |
bf8756d6 | 666 | |
e069c621 | 667 | if (!_remote_ssh_fingerprint) |
52e09724 CMN |
668 | cl_skip(); |
669 | ||
eae0bfdc | 670 | cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
bf8756d6 CMN |
671 | } |
672 | ||
8085adf8 MG |
673 | static char *read_key_file(const char *path) |
674 | { | |
675 | FILE *f; | |
676 | char *buf; | |
677 | long key_length; | |
678 | ||
679 | if (!path || !*path) | |
680 | return NULL; | |
681 | ||
682 | cl_assert((f = fopen(path, "r")) != NULL); | |
683 | cl_assert(fseek(f, 0, SEEK_END) != -1); | |
684 | cl_assert((key_length = ftell(f)) != -1); | |
685 | cl_assert(fseek(f, 0, SEEK_SET) != -1); | |
686 | cl_assert((buf = malloc(key_length)) != NULL); | |
687 | cl_assert(fread(buf, key_length, 1, f) == 1); | |
688 | fclose(f); | |
689 | ||
690 | return buf; | |
691 | } | |
692 | ||
22a2d3d5 | 693 | static int ssh_memory_cred_cb(git_credential **cred, const char *url, const char *user_from_url, |
8085adf8 MG |
694 | unsigned int allowed_types, void *payload) |
695 | { | |
8085adf8 MG |
696 | GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload); |
697 | ||
22a2d3d5 UG |
698 | if (allowed_types & GIT_CREDENTIAL_USERNAME) |
699 | return git_credential_username_new(cred, _remote_user); | |
8085adf8 | 700 | |
22a2d3d5 | 701 | if (allowed_types & GIT_CREDENTIAL_SSH_KEY) |
8085adf8 | 702 | { |
e069c621 ET |
703 | char *pubkey = read_key_file(_remote_ssh_pubkey); |
704 | char *privkey = read_key_file(_remote_ssh_privkey); | |
8085adf8 | 705 | |
22a2d3d5 | 706 | int ret = git_credential_ssh_key_memory_new(cred, _remote_user, pubkey, privkey, _remote_ssh_passphrase); |
8085adf8 MG |
707 | |
708 | if (privkey) | |
709 | free(privkey); | |
710 | if (pubkey) | |
711 | free(pubkey); | |
712 | return ret; | |
713 | } | |
714 | ||
ac3d33df | 715 | git_error_set(GIT_ERROR_NET, "unexpected cred type"); |
8085adf8 MG |
716 | return -1; |
717 | } | |
718 | ||
719 | void test_online_clone__ssh_memory_auth(void) | |
720 | { | |
8085adf8 MG |
721 | #ifndef GIT_SSH_MEMORY_CREDENTIALS |
722 | clar__skip(); | |
723 | #endif | |
e069c621 | 724 | if (!_remote_url || !_remote_user || !_remote_ssh_privkey || strncmp(_remote_url, "ssh://", 5) != 0) |
8085adf8 MG |
725 | clar__skip(); |
726 | ||
727 | g_options.fetch_opts.callbacks.credentials = ssh_memory_cred_cb; | |
728 | ||
e069c621 | 729 | cl_git_pass(git_clone(&g_repo, _remote_url, "./foo", &g_options)); |
8085adf8 MG |
730 | } |
731 | ||
e6e834a1 | 732 | static int fail_certificate_check(git_cert *cert, int valid, const char *host, void *payload) |
85acc562 | 733 | { |
0782fc43 | 734 | GIT_UNUSED(cert); |
17491f6e | 735 | GIT_UNUSED(valid); |
e6e834a1 | 736 | GIT_UNUSED(host); |
85acc562 CMN |
737 | GIT_UNUSED(payload); |
738 | ||
23ca0ad5 | 739 | return GIT_ECERTIFICATE; |
85acc562 CMN |
740 | } |
741 | ||
742 | void test_online_clone__certificate_invalid(void) | |
743 | { | |
8f0104ec | 744 | g_options.fetch_opts.callbacks.certificate_check = fail_certificate_check; |
85acc562 | 745 | |
08545d36 | 746 | cl_git_fail_with(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options), |
17491f6e | 747 | GIT_ECERTIFICATE); |
2f5864c5 | 748 | |
08545d36 | 749 | #ifdef GIT_SSH |
2f5864c5 CMN |
750 | cl_git_fail_with(git_clone(&g_repo, "ssh://github.com/libgit2/TestGitRepository", "./foo", &g_options), |
751 | GIT_ECERTIFICATE); | |
08545d36 | 752 | #endif |
85acc562 CMN |
753 | } |
754 | ||
e6e834a1 | 755 | static int succeed_certificate_check(git_cert *cert, int valid, const char *host, void *payload) |
85acc562 | 756 | { |
0782fc43 | 757 | GIT_UNUSED(cert); |
17491f6e | 758 | GIT_UNUSED(valid); |
85acc562 CMN |
759 | GIT_UNUSED(payload); |
760 | ||
db3d169c SS |
761 | cl_assert_equal_s("github.com", host); |
762 | ||
23ca0ad5 | 763 | return 0; |
85acc562 CMN |
764 | } |
765 | ||
766 | void test_online_clone__certificate_valid(void) | |
767 | { | |
8f0104ec | 768 | g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; |
85acc562 | 769 | |
08545d36 | 770 | cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options)); |
85acc562 | 771 | } |
29e7ae5d CMN |
772 | |
773 | void test_online_clone__start_with_http(void) | |
774 | { | |
8f0104ec | 775 | g_options.fetch_opts.callbacks.certificate_check = succeed_certificate_check; |
29e7ae5d CMN |
776 | |
777 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
778 | } | |
07bd3e57 CMN |
779 | |
780 | static int called_proxy_creds; | |
22a2d3d5 | 781 | static int proxy_cred_cb(git_credential **out, const char *url, const char *username, unsigned int allowed, void *payload) |
07bd3e57 | 782 | { |
0bd77401 | 783 | GIT_UNUSED(url); |
07bd3e57 | 784 | GIT_UNUSED(username); |
0bd77401 ET |
785 | GIT_UNUSED(allowed); |
786 | GIT_UNUSED(payload); | |
07bd3e57 CMN |
787 | |
788 | called_proxy_creds = 1; | |
22a2d3d5 | 789 | return git_credential_userpass_plaintext_new(out, _remote_proxy_user, _remote_proxy_pass); |
07bd3e57 CMN |
790 | } |
791 | ||
ac3d33df JK |
792 | static int proxy_cert_cb(git_cert *cert, int valid, const char *host, void *payload) |
793 | { | |
794 | char *colon; | |
795 | size_t host_len; | |
796 | ||
797 | GIT_UNUSED(cert); | |
798 | GIT_UNUSED(valid); | |
799 | GIT_UNUSED(payload); | |
800 | ||
801 | cl_assert(_remote_proxy_host); | |
802 | ||
803 | if ((colon = strchr(_remote_proxy_host, ':')) != NULL) | |
804 | host_len = (colon - _remote_proxy_host); | |
805 | else | |
806 | host_len = strlen(_remote_proxy_host); | |
807 | ||
808 | if (_remote_proxy_selfsigned != NULL && | |
809 | strlen(host) == host_len && | |
810 | strncmp(_remote_proxy_host, host, host_len) == 0) | |
811 | valid = 1; | |
812 | ||
813 | return valid ? 0 : GIT_ECERTIFICATE; | |
814 | } | |
815 | ||
07bd3e57 CMN |
816 | void test_online_clone__proxy_credentials_request(void) |
817 | { | |
e579e0f7 | 818 | git_str url = GIT_STR_INIT; |
eae0bfdc | 819 | |
ac3d33df | 820 | if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) |
07bd3e57 CMN |
821 | cl_skip(); |
822 | ||
e579e0f7 | 823 | cl_git_pass(git_str_printf(&url, "%s://%s/", |
ac3d33df JK |
824 | _remote_proxy_scheme ? _remote_proxy_scheme : "http", |
825 | _remote_proxy_host)); | |
eae0bfdc | 826 | |
0d72f67f | 827 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; |
eae0bfdc | 828 | g_options.fetch_opts.proxy_opts.url = url.ptr; |
ac3d33df JK |
829 | g_options.fetch_opts.proxy_opts.credentials = proxy_cred_cb; |
830 | g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; | |
07bd3e57 CMN |
831 | called_proxy_creds = 0; |
832 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
833 | cl_assert(called_proxy_creds); | |
eae0bfdc | 834 | |
e579e0f7 | 835 | git_str_dispose(&url); |
07bd3e57 CMN |
836 | } |
837 | ||
838 | void test_online_clone__proxy_credentials_in_url(void) | |
839 | { | |
e579e0f7 | 840 | git_str url = GIT_STR_INIT; |
eae0bfdc | 841 | |
ac3d33df | 842 | if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) |
07bd3e57 CMN |
843 | cl_skip(); |
844 | ||
e579e0f7 | 845 | cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", |
ac3d33df JK |
846 | _remote_proxy_scheme ? _remote_proxy_scheme : "http", |
847 | _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); | |
eae0bfdc | 848 | |
0d72f67f | 849 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; |
eae0bfdc | 850 | g_options.fetch_opts.proxy_opts.url = url.ptr; |
ac3d33df | 851 | g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; |
07bd3e57 CMN |
852 | called_proxy_creds = 0; |
853 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
854 | cl_assert(called_proxy_creds == 0); | |
eae0bfdc | 855 | |
e579e0f7 | 856 | git_str_dispose(&url); |
ac3d33df JK |
857 | } |
858 | ||
859 | void test_online_clone__proxy_credentials_in_environment(void) | |
860 | { | |
e579e0f7 | 861 | git_str url = GIT_STR_INIT; |
ac3d33df JK |
862 | |
863 | if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) | |
864 | cl_skip(); | |
865 | ||
866 | _orig_http_proxy = cl_getenv("HTTP_PROXY"); | |
867 | _orig_https_proxy = cl_getenv("HTTPS_PROXY"); | |
c25aa7cd | 868 | _orig_no_proxy = cl_getenv("NO_PROXY"); |
ac3d33df JK |
869 | _orig_proxies_need_reset = 1; |
870 | ||
871 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; | |
872 | g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; | |
873 | ||
e579e0f7 | 874 | cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", |
ac3d33df JK |
875 | _remote_proxy_scheme ? _remote_proxy_scheme : "http", |
876 | _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); | |
877 | ||
878 | cl_setenv("HTTP_PROXY", url.ptr); | |
879 | cl_setenv("HTTPS_PROXY", url.ptr); | |
c25aa7cd | 880 | cl_setenv("NO_PROXY", NULL); |
ac3d33df JK |
881 | |
882 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
883 | ||
e579e0f7 | 884 | git_str_dispose(&url); |
ac3d33df JK |
885 | } |
886 | ||
c25aa7cd PP |
887 | void test_online_clone__proxy_credentials_in_url_https(void) |
888 | { | |
e579e0f7 | 889 | git_str url = GIT_STR_INIT; |
c25aa7cd PP |
890 | |
891 | if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) | |
892 | cl_skip(); | |
893 | ||
e579e0f7 | 894 | cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", |
c25aa7cd PP |
895 | _remote_proxy_scheme ? _remote_proxy_scheme : "http", |
896 | _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); | |
897 | ||
898 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; | |
899 | g_options.fetch_opts.proxy_opts.url = url.ptr; | |
900 | g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; | |
901 | g_options.fetch_opts.callbacks.certificate_check = ssl_cert; | |
902 | called_proxy_creds = 0; | |
903 | cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
904 | cl_assert(called_proxy_creds == 0); | |
905 | ||
e579e0f7 | 906 | git_str_dispose(&url); |
c25aa7cd PP |
907 | } |
908 | ||
ac3d33df JK |
909 | void test_online_clone__proxy_auto_not_detected(void) |
910 | { | |
911 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; | |
912 | ||
913 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
07bd3e57 | 914 | } |
22a2d3d5 UG |
915 | |
916 | void test_online_clone__proxy_cred_callback_after_failed_url_creds(void) | |
917 | { | |
e579e0f7 | 918 | git_str url = GIT_STR_INIT; |
22a2d3d5 UG |
919 | |
920 | if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) | |
921 | cl_skip(); | |
922 | ||
e579e0f7 | 923 | cl_git_pass(git_str_printf(&url, "%s://invalid_user_name:INVALID_pass_WORD@%s/", |
22a2d3d5 UG |
924 | _remote_proxy_scheme ? _remote_proxy_scheme : "http", |
925 | _remote_proxy_host)); | |
926 | ||
927 | g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; | |
928 | g_options.fetch_opts.proxy_opts.url = url.ptr; | |
929 | g_options.fetch_opts.proxy_opts.credentials = proxy_cred_cb; | |
930 | g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; | |
931 | called_proxy_creds = 0; | |
932 | cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); | |
933 | cl_assert(called_proxy_creds); | |
934 | ||
e579e0f7 | 935 | git_str_dispose(&url); |
22a2d3d5 UG |
936 | } |
937 | ||
938 | void test_online_clone__azurerepos(void) | |
939 | { | |
940 | cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/test", "./foo", &g_options)); | |
e579e0f7 | 941 | cl_assert(git_fs_path_exists("./foo/master.txt")); |
22a2d3d5 UG |
942 | } |
943 | ||
944 | void test_online_clone__path_whitespace(void) | |
945 | { | |
946 | cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name", "./foo", &g_options)); | |
e579e0f7 MB |
947 | cl_assert(git_fs_path_exists("./foo/master.txt")); |
948 | } | |
949 | ||
950 | void test_online_clone__redirect_default_succeeds_for_initial(void) | |
951 | { | |
952 | git_clone_options options = GIT_CLONE_OPTIONS_INIT; | |
953 | ||
954 | if (!_remote_redirect_initial || !_remote_redirect_subsequent) | |
955 | cl_skip(); | |
956 | ||
957 | cl_git_pass(git_clone(&g_repo, _remote_redirect_initial, "./initial", &options)); | |
958 | } | |
959 | ||
960 | void test_online_clone__redirect_default_fails_for_subsequent(void) | |
961 | { | |
962 | git_clone_options options = GIT_CLONE_OPTIONS_INIT; | |
963 | ||
964 | if (!_remote_redirect_initial || !_remote_redirect_subsequent) | |
965 | cl_skip(); | |
966 | ||
967 | cl_git_fail(git_clone(&g_repo, _remote_redirect_subsequent, "./fail", &options)); | |
968 | } | |
969 | ||
970 | void test_online_clone__redirect_none(void) | |
971 | { | |
972 | git_clone_options options = GIT_CLONE_OPTIONS_INIT; | |
973 | ||
974 | if (!_remote_redirect_initial) | |
975 | cl_skip(); | |
976 | ||
977 | options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_NONE; | |
978 | ||
979 | cl_git_fail(git_clone(&g_repo, _remote_redirect_initial, "./fail", &options)); | |
980 | } | |
981 | ||
982 | void test_online_clone__redirect_initial_succeeds_for_initial(void) | |
983 | { | |
984 | git_clone_options options = GIT_CLONE_OPTIONS_INIT; | |
985 | ||
986 | if (!_remote_redirect_initial || !_remote_redirect_subsequent) | |
987 | cl_skip(); | |
988 | ||
989 | options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_INITIAL; | |
990 | ||
991 | cl_git_pass(git_clone(&g_repo, _remote_redirect_initial, "./initial", &options)); | |
992 | } | |
993 | ||
994 | void test_online_clone__redirect_initial_fails_for_subsequent(void) | |
995 | { | |
996 | git_clone_options options = GIT_CLONE_OPTIONS_INIT; | |
997 | ||
998 | if (!_remote_redirect_initial || !_remote_redirect_subsequent) | |
999 | cl_skip(); | |
1000 | ||
1001 | options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_INITIAL; | |
1002 | ||
1003 | cl_git_fail(git_clone(&g_repo, _remote_redirect_subsequent, "./fail", &options)); | |
22a2d3d5 | 1004 | } |