rugged 0.25.1.1 → 0.26.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/include/git2/common.h +10 -0
- data/vendor/libgit2/include/git2/merge.h +2 -1
- data/vendor/libgit2/include/git2/oid.h +4 -5
- data/vendor/libgit2/include/git2/submodule.h +2 -11
- data/vendor/libgit2/include/git2/sys/repository.h +29 -0
- data/vendor/libgit2/include/git2/tree.h +13 -0
- data/vendor/libgit2/src/apply.c +2 -2
- data/vendor/libgit2/src/attr_file.c +5 -5
- data/vendor/libgit2/src/attrcache.c +9 -7
- data/vendor/libgit2/src/blob.c +3 -3
- data/vendor/libgit2/src/branch.c +10 -10
- data/vendor/libgit2/src/buffer.c +4 -4
- data/vendor/libgit2/src/cache.c +1 -1
- data/vendor/libgit2/src/checkout.c +29 -25
- data/vendor/libgit2/src/cherrypick.c +2 -2
- data/vendor/libgit2/src/commit.c +2 -2
- data/vendor/libgit2/src/commit_list.c +2 -2
- data/vendor/libgit2/src/common.h +1 -1
- data/vendor/libgit2/src/config.c +12 -12
- data/vendor/libgit2/src/config_file.c +9 -9
- data/vendor/libgit2/src/crlf.c +1 -1
- data/vendor/libgit2/src/delta.c +4 -4
- data/vendor/libgit2/src/describe.c +11 -11
- data/vendor/libgit2/src/diff_driver.c +1 -1
- data/vendor/libgit2/src/diff_file.c +1 -1
- data/vendor/libgit2/src/diff_generate.c +2 -2
- data/vendor/libgit2/src/diff_print.c +5 -5
- data/vendor/libgit2/src/diff_tform.c +1 -1
- data/vendor/libgit2/src/diff_xdiff.c +2 -2
- data/vendor/libgit2/src/fetch.c +1 -1
- data/vendor/libgit2/src/fetchhead.c +8 -8
- data/vendor/libgit2/src/filebuf.c +9 -9
- data/vendor/libgit2/src/fileops.c +27 -27
- data/vendor/libgit2/src/filter.c +4 -4
- data/vendor/libgit2/src/hashsig.c +2 -2
- data/vendor/libgit2/src/ignore.c +4 -4
- data/vendor/libgit2/src/index.c +15 -15
- data/vendor/libgit2/src/indexer.c +39 -6
- data/vendor/libgit2/src/integer.h +6 -6
- data/vendor/libgit2/src/merge.c +12 -12
- data/vendor/libgit2/src/merge_file.c +1 -1
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/netops.c +4 -4
- data/vendor/libgit2/src/notes.c +3 -3
- data/vendor/libgit2/src/object.c +5 -5
- data/vendor/libgit2/src/odb.c +12 -12
- data/vendor/libgit2/src/odb_loose.c +6 -6
- data/vendor/libgit2/src/oid.c +5 -5
- data/vendor/libgit2/src/openssl_stream.c +3 -3
- data/vendor/libgit2/src/pack-objects.c +6 -6
- data/vendor/libgit2/src/pack.c +19 -10
- data/vendor/libgit2/src/pack.h +1 -0
- data/vendor/libgit2/src/patch_generate.c +5 -3
- data/vendor/libgit2/src/path.c +15 -15
- data/vendor/libgit2/src/pathspec.c +2 -2
- data/vendor/libgit2/src/posix.c +1 -1
- data/vendor/libgit2/src/push.c +6 -6
- data/vendor/libgit2/src/rebase.c +12 -12
- data/vendor/libgit2/src/refdb.c +1 -1
- data/vendor/libgit2/src/refdb_fs.c +12 -12
- data/vendor/libgit2/src/reflog.c +2 -2
- data/vendor/libgit2/src/refs.c +34 -17
- data/vendor/libgit2/src/refs.h +3 -0
- data/vendor/libgit2/src/remote.c +3 -3
- data/vendor/libgit2/src/repository.c +46 -13
- data/vendor/libgit2/src/repository.h +2 -1
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/revert.c +2 -2
- data/vendor/libgit2/src/revparse.c +5 -5
- data/vendor/libgit2/src/revwalk.c +3 -3
- data/vendor/libgit2/src/settings.c +6 -1
- data/vendor/libgit2/src/sha1_lookup.c +1 -1
- data/vendor/libgit2/src/signature.c +1 -1
- data/vendor/libgit2/src/socket_stream.c +5 -5
- data/vendor/libgit2/src/sortedcache.c +5 -5
- data/vendor/libgit2/src/stash.c +6 -6
- data/vendor/libgit2/src/status.c +4 -4
- data/vendor/libgit2/src/submodule.c +159 -110
- data/vendor/libgit2/src/submodule.h +3 -0
- data/vendor/libgit2/src/sysdir.c +2 -2
- data/vendor/libgit2/src/tag.c +14 -14
- data/vendor/libgit2/src/trace.c +1 -1
- data/vendor/libgit2/src/transport.c +1 -1
- data/vendor/libgit2/src/transports/auth_negotiate.c +4 -4
- data/vendor/libgit2/src/transports/cred.c +1 -1
- data/vendor/libgit2/src/transports/git.c +3 -3
- data/vendor/libgit2/src/transports/http.c +6 -6
- data/vendor/libgit2/src/transports/local.c +2 -2
- data/vendor/libgit2/src/transports/smart.c +5 -5
- data/vendor/libgit2/src/transports/smart_pkt.c +4 -4
- data/vendor/libgit2/src/transports/smart_protocol.c +1 -1
- data/vendor/libgit2/src/transports/ssh.c +9 -9
- data/vendor/libgit2/src/transports/winhttp.c +155 -118
- data/vendor/libgit2/src/tree-cache.c +2 -2
- data/vendor/libgit2/src/tree.c +35 -20
- data/vendor/libgit2/src/unix/map.c +1 -1
- data/vendor/libgit2/src/util.c +3 -3
- data/vendor/libgit2/src/vector.c +3 -0
- data/vendor/libgit2/src/win32/dir.c +3 -3
- data/vendor/libgit2/src/win32/findfile.c +1 -1
- data/vendor/libgit2/src/win32/map.c +6 -6
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -2
- data/vendor/libgit2/src/win32/w32_util.c +1 -1
- data/vendor/libgit2/src/win32/w32_util.h +1 -1
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +4 -4
@@ -68,7 +68,8 @@ static const IID IID_IInternetSecurityManager_mingw =
|
|
68
68
|
|
69
69
|
typedef enum {
|
70
70
|
GIT_WINHTTP_AUTH_BASIC = 1,
|
71
|
-
|
71
|
+
GIT_WINHTTP_AUTH_NTLM = 2,
|
72
|
+
GIT_WINHTTP_AUTH_NEGOTIATE = 4,
|
72
73
|
} winhttp_authmechanism_t;
|
73
74
|
|
74
75
|
typedef struct {
|
@@ -95,79 +96,66 @@ typedef struct {
|
|
95
96
|
git_cred *cred;
|
96
97
|
git_cred *url_cred;
|
97
98
|
git_cred *proxy_cred;
|
98
|
-
int
|
99
|
+
int auth_mechanisms;
|
99
100
|
HINTERNET session;
|
100
101
|
HINTERNET connection;
|
101
102
|
} winhttp_subtransport;
|
102
103
|
|
103
|
-
static int
|
104
|
+
static int _apply_userpass_credential(HINTERNET request, DWORD target, DWORD scheme, git_cred *cred)
|
104
105
|
{
|
105
106
|
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
|
106
107
|
wchar_t *user, *pass;
|
107
|
-
int error;
|
108
|
+
int user_len = 0, pass_len = 0, error = 0;
|
108
109
|
|
109
|
-
if ((error = git__utf8_to_16_alloc(&user, c->username)) < 0)
|
110
|
-
|
110
|
+
if ((error = user_len = git__utf8_to_16_alloc(&user, c->username)) < 0)
|
111
|
+
goto done;
|
111
112
|
|
112
|
-
if ((error = git__utf8_to_16_alloc(&pass, c->password)) < 0)
|
113
|
-
|
113
|
+
if ((error = pass_len = git__utf8_to_16_alloc(&pass, c->password)) < 0)
|
114
|
+
goto done;
|
114
115
|
|
115
|
-
if (!WinHttpSetCredentials(request,
|
116
|
-
|
117
|
-
giterr_set(GITERR_OS, "failed to set proxy auth");
|
116
|
+
if (!WinHttpSetCredentials(request, target, scheme, user, pass, NULL)) {
|
117
|
+
giterr_set(GITERR_OS, "failed to set credentials");
|
118
118
|
error = -1;
|
119
119
|
}
|
120
120
|
|
121
|
+
done:
|
122
|
+
if (user_len > 0)
|
123
|
+
git__memzero(user, user_len * sizeof(wchar_t));
|
124
|
+
|
125
|
+
if (pass_len > 0)
|
126
|
+
git__memzero(pass, pass_len * sizeof(wchar_t));
|
127
|
+
|
121
128
|
git__free(user);
|
122
129
|
git__free(pass);
|
123
130
|
|
124
131
|
return error;
|
125
132
|
}
|
126
133
|
|
127
|
-
static int
|
134
|
+
static int apply_userpass_credential_proxy(HINTERNET request, git_cred *cred)
|
128
135
|
{
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
int error = -1, wide_len;
|
133
|
-
|
134
|
-
git_buf_printf(&raw, "%s:%s", c->username, c->password);
|
135
|
-
|
136
|
-
if (git_buf_oom(&raw) ||
|
137
|
-
git_buf_puts(&buf, "Authorization: Basic ") < 0 ||
|
138
|
-
git_buf_encode_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
|
139
|
-
goto on_error;
|
136
|
+
return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_PROXY,
|
137
|
+
WINHTTP_AUTH_SCHEME_BASIC, cred);
|
138
|
+
}
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
140
|
+
static int apply_userpass_credential(HINTERNET request, int mechanisms, git_cred *cred)
|
141
|
+
{
|
142
|
+
DWORD native_scheme;
|
145
143
|
|
146
|
-
if (
|
147
|
-
|
148
|
-
|
144
|
+
if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) ||
|
145
|
+
(mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE)) {
|
146
|
+
native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
|
147
|
+
} else if (mechanisms & GIT_WINHTTP_AUTH_BASIC) {
|
148
|
+
native_scheme = WINHTTP_AUTH_SCHEME_BASIC;
|
149
|
+
} else {
|
150
|
+
giterr_set(GITERR_NET, "invalid authentication scheme");
|
151
|
+
return -1;
|
149
152
|
}
|
150
153
|
|
151
|
-
|
152
|
-
|
153
|
-
on_error:
|
154
|
-
/* We were dealing with plaintext passwords, so clean up after ourselves a bit. */
|
155
|
-
if (wide)
|
156
|
-
memset(wide, 0x0, wide_len * sizeof(wchar_t));
|
157
|
-
|
158
|
-
if (buf.size)
|
159
|
-
memset(buf.ptr, 0x0, buf.size);
|
160
|
-
|
161
|
-
if (raw.size)
|
162
|
-
memset(raw.ptr, 0x0, raw.size);
|
163
|
-
|
164
|
-
git__free(wide);
|
165
|
-
git_buf_free(&buf);
|
166
|
-
git_buf_free(&raw);
|
167
|
-
return error;
|
154
|
+
return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_SERVER,
|
155
|
+
native_scheme, cred);
|
168
156
|
}
|
169
157
|
|
170
|
-
static int apply_default_credentials(HINTERNET request)
|
158
|
+
static int apply_default_credentials(HINTERNET request, int mechanisms)
|
171
159
|
{
|
172
160
|
/* Either the caller explicitly requested that default credentials be passed,
|
173
161
|
* or our fallback credential callback was invoked and checked that the target
|
@@ -177,6 +165,12 @@ static int apply_default_credentials(HINTERNET request)
|
|
177
165
|
* to Internet Explorer security zones, but in fact does not. */
|
178
166
|
DWORD data = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
|
179
167
|
|
168
|
+
if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) == 0 &&
|
169
|
+
(mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) == 0) {
|
170
|
+
giterr_set(GITERR_NET, "invalid authentication scheme");
|
171
|
+
return -1;
|
172
|
+
}
|
173
|
+
|
180
174
|
if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &data, sizeof(DWORD)))
|
181
175
|
return -1;
|
182
176
|
|
@@ -202,7 +196,7 @@ static int fallback_cred_acquire_cb(
|
|
202
196
|
|
203
197
|
/* Convert URL to wide characters */
|
204
198
|
if (git__utf8_to_16_alloc(&wide_url, url) < 0) {
|
205
|
-
giterr_set(GITERR_OS, "
|
199
|
+
giterr_set(GITERR_OS, "failed to convert string to wide form");
|
206
200
|
return -1;
|
207
201
|
}
|
208
202
|
|
@@ -248,8 +242,12 @@ static int certificate_check(winhttp_stream *s, int valid)
|
|
248
242
|
git_cert_x509 cert;
|
249
243
|
|
250
244
|
/* If there is no override, we should fail if WinHTTP doesn't think it's fine */
|
251
|
-
if (t->owner->certificate_check_cb == NULL && !valid)
|
245
|
+
if (t->owner->certificate_check_cb == NULL && !valid) {
|
246
|
+
if (!giterr_last())
|
247
|
+
giterr_set(GITERR_NET, "unknown certificate check failure");
|
248
|
+
|
252
249
|
return GIT_ECERTIFICATE;
|
250
|
+
}
|
253
251
|
|
254
252
|
if (t->owner->certificate_check_cb == NULL || !t->connection_data.use_ssl)
|
255
253
|
return 0;
|
@@ -351,7 +349,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
351
349
|
|
352
350
|
/* Convert URL to wide characters */
|
353
351
|
if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) {
|
354
|
-
giterr_set(GITERR_OS, "
|
352
|
+
giterr_set(GITERR_OS, "failed to convert string to wide form");
|
355
353
|
goto on_error;
|
356
354
|
}
|
357
355
|
|
@@ -366,12 +364,12 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
366
364
|
t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0);
|
367
365
|
|
368
366
|
if (!s->request) {
|
369
|
-
giterr_set(GITERR_OS, "
|
367
|
+
giterr_set(GITERR_OS, "failed to open request");
|
370
368
|
goto on_error;
|
371
369
|
}
|
372
370
|
|
373
371
|
if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
|
374
|
-
giterr_set(GITERR_OS, "
|
372
|
+
giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP");
|
375
373
|
goto on_error;
|
376
374
|
}
|
377
375
|
|
@@ -444,7 +442,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
444
442
|
WINHTTP_OPTION_PROXY,
|
445
443
|
&proxy_info,
|
446
444
|
sizeof(WINHTTP_PROXY_INFO))) {
|
447
|
-
giterr_set(GITERR_OS, "
|
445
|
+
giterr_set(GITERR_OS, "failed to set proxy");
|
448
446
|
git__free(proxy_wide);
|
449
447
|
goto on_error;
|
450
448
|
}
|
@@ -453,7 +451,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
453
451
|
|
454
452
|
if (t->proxy_cred) {
|
455
453
|
if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) {
|
456
|
-
if ((error =
|
454
|
+
if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred)) < 0)
|
457
455
|
goto on_error;
|
458
456
|
}
|
459
457
|
}
|
@@ -467,7 +465,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
467
465
|
WINHTTP_OPTION_DISABLE_FEATURE,
|
468
466
|
&disable_redirects,
|
469
467
|
sizeof(disable_redirects))) {
|
470
|
-
giterr_set(GITERR_OS, "
|
468
|
+
giterr_set(GITERR_OS, "failed to disable redirects");
|
471
469
|
goto on_error;
|
472
470
|
}
|
473
471
|
|
@@ -481,7 +479,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
481
479
|
|
482
480
|
/* Send Pragma: no-cache header */
|
483
481
|
if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
|
484
|
-
giterr_set(GITERR_OS, "
|
482
|
+
giterr_set(GITERR_OS, "failed to add a header to the request");
|
485
483
|
goto on_error;
|
486
484
|
}
|
487
485
|
|
@@ -494,13 +492,13 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
494
492
|
goto on_error;
|
495
493
|
|
496
494
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
497
|
-
giterr_set(GITERR_OS, "
|
495
|
+
giterr_set(GITERR_OS, "failed to convert content-type to wide characters");
|
498
496
|
goto on_error;
|
499
497
|
}
|
500
498
|
|
501
499
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
502
500
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
503
|
-
giterr_set(GITERR_OS, "
|
501
|
+
giterr_set(GITERR_OS, "failed to add a header to the request");
|
504
502
|
goto on_error;
|
505
503
|
}
|
506
504
|
|
@@ -511,13 +509,13 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
511
509
|
goto on_error;
|
512
510
|
|
513
511
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
514
|
-
giterr_set(GITERR_OS, "
|
512
|
+
giterr_set(GITERR_OS, "failed to convert accept header to wide characters");
|
515
513
|
goto on_error;
|
516
514
|
}
|
517
515
|
|
518
516
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
519
517
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
520
|
-
giterr_set(GITERR_OS, "
|
518
|
+
giterr_set(GITERR_OS, "failed to add a header to the request");
|
521
519
|
goto on_error;
|
522
520
|
}
|
523
521
|
}
|
@@ -527,13 +525,13 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
527
525
|
git_buf_clear(&buf);
|
528
526
|
git_buf_puts(&buf, t->owner->custom_headers.strings[i]);
|
529
527
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
530
|
-
giterr_set(GITERR_OS, "
|
528
|
+
giterr_set(GITERR_OS, "failed to convert custom header to wide characters");
|
531
529
|
goto on_error;
|
532
530
|
}
|
533
531
|
|
534
532
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
535
533
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
536
|
-
giterr_set(GITERR_OS, "
|
534
|
+
giterr_set(GITERR_OS, "failed to add a header to the request");
|
537
535
|
goto on_error;
|
538
536
|
}
|
539
537
|
}
|
@@ -550,13 +548,11 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
550
548
|
/* If we have a credential on the subtransport, apply it to the request */
|
551
549
|
if (t->cred &&
|
552
550
|
t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
|
553
|
-
t->
|
554
|
-
apply_basic_credential(s->request, t->cred) < 0)
|
551
|
+
apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0)
|
555
552
|
goto on_error;
|
556
553
|
else if (t->cred &&
|
557
554
|
t->cred->credtype == GIT_CREDTYPE_DEFAULT &&
|
558
|
-
t->
|
559
|
-
apply_default_credentials(s->request) < 0)
|
555
|
+
apply_default_credentials(s->request, t->auth_mechanisms) < 0)
|
560
556
|
goto on_error;
|
561
557
|
|
562
558
|
/* If no other credentials have been applied and the URL has username and
|
@@ -565,7 +561,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
565
561
|
if (!t->url_cred &&
|
566
562
|
git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0)
|
567
563
|
goto on_error;
|
568
|
-
if (
|
564
|
+
if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0)
|
569
565
|
goto on_error;
|
570
566
|
}
|
571
567
|
|
@@ -585,30 +581,35 @@ on_error:
|
|
585
581
|
static int parse_unauthorized_response(
|
586
582
|
HINTERNET request,
|
587
583
|
int *allowed_types,
|
588
|
-
int *
|
584
|
+
int *allowed_mechanisms)
|
589
585
|
{
|
590
586
|
DWORD supported, first, target;
|
591
587
|
|
592
588
|
*allowed_types = 0;
|
593
|
-
*
|
589
|
+
*allowed_mechanisms = 0;
|
594
590
|
|
595
591
|
/* WinHttpQueryHeaders() must be called before WinHttpQueryAuthSchemes().
|
596
592
|
* We can assume this was already done, since we know we are unauthorized.
|
597
593
|
*/
|
598
594
|
if (!WinHttpQueryAuthSchemes(request, &supported, &first, &target)) {
|
599
|
-
giterr_set(GITERR_OS, "
|
595
|
+
giterr_set(GITERR_OS, "failed to parse supported auth schemes");
|
600
596
|
return -1;
|
601
597
|
}
|
602
598
|
|
603
|
-
if (
|
599
|
+
if (WINHTTP_AUTH_SCHEME_NTLM & supported) {
|
604
600
|
*allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
|
605
|
-
*
|
601
|
+
*allowed_types |= GIT_CREDTYPE_DEFAULT;
|
602
|
+
*allowed_mechanisms = GIT_WINHTTP_AUTH_NEGOTIATE;
|
606
603
|
}
|
607
604
|
|
608
|
-
if (
|
609
|
-
(WINHTTP_AUTH_SCHEME_NEGOTIATE & supported)) {
|
605
|
+
if (WINHTTP_AUTH_SCHEME_NEGOTIATE & supported) {
|
610
606
|
*allowed_types |= GIT_CREDTYPE_DEFAULT;
|
611
|
-
*
|
607
|
+
*allowed_mechanisms = GIT_WINHTTP_AUTH_NEGOTIATE;
|
608
|
+
}
|
609
|
+
|
610
|
+
if (WINHTTP_AUTH_SCHEME_BASIC & supported) {
|
611
|
+
*allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
|
612
|
+
*allowed_mechanisms |= GIT_WINHTTP_AUTH_BASIC;
|
612
613
|
}
|
613
614
|
|
614
615
|
return 0;
|
@@ -629,7 +630,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
629
630
|
git_buf_cstr(&buf), (DWORD)git_buf_len(&buf),
|
630
631
|
&bytes_written)) {
|
631
632
|
git_buf_free(&buf);
|
632
|
-
giterr_set(GITERR_OS, "
|
633
|
+
giterr_set(GITERR_OS, "failed to write chunk header");
|
633
634
|
return -1;
|
634
635
|
}
|
635
636
|
|
@@ -639,7 +640,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
639
640
|
if (!WinHttpWriteData(request,
|
640
641
|
buffer, (DWORD)len,
|
641
642
|
&bytes_written)) {
|
642
|
-
giterr_set(GITERR_OS, "
|
643
|
+
giterr_set(GITERR_OS, "failed to write chunk");
|
643
644
|
return -1;
|
644
645
|
}
|
645
646
|
|
@@ -647,7 +648,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
647
648
|
if (!WinHttpWriteData(request,
|
648
649
|
"\r\n", 2,
|
649
650
|
&bytes_written)) {
|
650
|
-
giterr_set(GITERR_OS, "
|
651
|
+
giterr_set(GITERR_OS, "failed to write chunk footer");
|
651
652
|
return -1;
|
652
653
|
}
|
653
654
|
|
@@ -660,7 +661,7 @@ static int winhttp_close_connection(winhttp_subtransport *t)
|
|
660
661
|
|
661
662
|
if (t->connection) {
|
662
663
|
if (!WinHttpCloseHandle(t->connection)) {
|
663
|
-
giterr_set(GITERR_OS, "
|
664
|
+
giterr_set(GITERR_OS, "unable to close connection");
|
664
665
|
ret = -1;
|
665
666
|
}
|
666
667
|
|
@@ -669,7 +670,7 @@ static int winhttp_close_connection(winhttp_subtransport *t)
|
|
669
670
|
|
670
671
|
if (t->session) {
|
671
672
|
if (!WinHttpCloseHandle(t->session)) {
|
672
|
-
giterr_set(GITERR_OS, "
|
673
|
+
giterr_set(GITERR_OS, "unable to close session");
|
673
674
|
ret = -1;
|
674
675
|
}
|
675
676
|
|
@@ -694,6 +695,38 @@ static int user_agent(git_buf *ua)
|
|
694
695
|
return git_buf_putc(ua, ')');
|
695
696
|
}
|
696
697
|
|
698
|
+
static void CALLBACK winhttp_status(
|
699
|
+
HINTERNET connection,
|
700
|
+
DWORD_PTR ctx,
|
701
|
+
DWORD code,
|
702
|
+
LPVOID info,
|
703
|
+
DWORD info_len)
|
704
|
+
{
|
705
|
+
DWORD status;
|
706
|
+
|
707
|
+
if (code != WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
|
708
|
+
return;
|
709
|
+
|
710
|
+
status = *((DWORD *)info);
|
711
|
+
|
712
|
+
if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID))
|
713
|
+
giterr_set(GITERR_NET, "SSL certificate issued for different common name");
|
714
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID))
|
715
|
+
giterr_set(GITERR_NET, "SSL certificate has expired");
|
716
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA))
|
717
|
+
giterr_set(GITERR_NET, "SSL certificate signed by unknown CA");
|
718
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT))
|
719
|
+
giterr_set(GITERR_NET, "SSL certificate is invalid");
|
720
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED))
|
721
|
+
giterr_set(GITERR_NET, "certificate revocation check failed");
|
722
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED))
|
723
|
+
giterr_set(GITERR_NET, "SSL certificate was revoked");
|
724
|
+
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR))
|
725
|
+
giterr_set(GITERR_NET, "security libraries could not be loaded");
|
726
|
+
else
|
727
|
+
giterr_set(GITERR_NET, "unknown security error %d", status);
|
728
|
+
}
|
729
|
+
|
697
730
|
static int winhttp_connect(
|
698
731
|
winhttp_subtransport *t)
|
699
732
|
{
|
@@ -714,7 +747,7 @@ static int winhttp_connect(
|
|
714
747
|
|
715
748
|
/* Prepare host */
|
716
749
|
if (git__utf8_to_16_alloc(&wide_host, t->connection_data.host) < 0) {
|
717
|
-
giterr_set(GITERR_OS, "
|
750
|
+
giterr_set(GITERR_OS, "unable to convert host to wide characters");
|
718
751
|
return -1;
|
719
752
|
}
|
720
753
|
|
@@ -724,7 +757,7 @@ static int winhttp_connect(
|
|
724
757
|
}
|
725
758
|
|
726
759
|
if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) {
|
727
|
-
giterr_set(GITERR_OS, "
|
760
|
+
giterr_set(GITERR_OS, "unable to convert host to wide characters");
|
728
761
|
git__free(wide_host);
|
729
762
|
git_buf_free(&ua);
|
730
763
|
return -1;
|
@@ -741,12 +774,12 @@ static int winhttp_connect(
|
|
741
774
|
0);
|
742
775
|
|
743
776
|
if (!t->session) {
|
744
|
-
giterr_set(GITERR_OS, "
|
777
|
+
giterr_set(GITERR_OS, "failed to init WinHTTP");
|
745
778
|
goto on_error;
|
746
779
|
}
|
747
780
|
|
748
781
|
if (!WinHttpSetTimeouts(t->session, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
|
749
|
-
giterr_set(GITERR_OS, "
|
782
|
+
giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP");
|
750
783
|
goto on_error;
|
751
784
|
}
|
752
785
|
|
@@ -759,7 +792,12 @@ static int winhttp_connect(
|
|
759
792
|
0);
|
760
793
|
|
761
794
|
if (!t->connection) {
|
762
|
-
giterr_set(GITERR_OS, "
|
795
|
+
giterr_set(GITERR_OS, "failed to connect to host");
|
796
|
+
goto on_error;
|
797
|
+
}
|
798
|
+
|
799
|
+
if (WinHttpSetStatusCallback(t->connection, winhttp_status, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, 0) == WINHTTP_INVALID_STATUS_CALLBACK) {
|
800
|
+
giterr_set(GITERR_OS, "failed to set status callback");
|
763
801
|
goto on_error;
|
764
802
|
}
|
765
803
|
|
@@ -801,16 +839,15 @@ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
801
839
|
int request_failed = 0, cert_valid = 1, error = 0;
|
802
840
|
DWORD ignore_flags;
|
803
841
|
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
if (request_failed) {
|
842
|
+
giterr_clear();
|
843
|
+
if ((error = do_send_request(s, len, ignore_length)) < 0) {
|
808
844
|
if (GetLastError() != ERROR_WINHTTP_SECURE_FAILURE) {
|
809
845
|
giterr_set(GITERR_OS, "failed to send request");
|
810
846
|
return -1;
|
811
|
-
} else {
|
812
|
-
cert_valid = 0;
|
813
847
|
}
|
848
|
+
|
849
|
+
request_failed = 1;
|
850
|
+
cert_valid = 0;
|
814
851
|
}
|
815
852
|
|
816
853
|
giterr_clear();
|
@@ -853,7 +890,7 @@ static int winhttp_stream_read(
|
|
853
890
|
replay:
|
854
891
|
/* Enforce a reasonable cap on the number of replays */
|
855
892
|
if (++replay_count >= 7) {
|
856
|
-
giterr_set(GITERR_NET, "
|
893
|
+
giterr_set(GITERR_NET, "too many redirects or authentication replays");
|
857
894
|
return -1;
|
858
895
|
}
|
859
896
|
|
@@ -888,7 +925,7 @@ replay:
|
|
888
925
|
if (!WinHttpWriteData(s->request,
|
889
926
|
"0\r\n\r\n", 5,
|
890
927
|
&bytes_written)) {
|
891
|
-
giterr_set(GITERR_OS, "
|
928
|
+
giterr_set(GITERR_OS, "failed to write final chunk");
|
892
929
|
return -1;
|
893
930
|
}
|
894
931
|
}
|
@@ -899,7 +936,7 @@ replay:
|
|
899
936
|
if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body,
|
900
937
|
0, 0, FILE_BEGIN) &&
|
901
938
|
NO_ERROR != GetLastError()) {
|
902
|
-
giterr_set(GITERR_OS, "
|
939
|
+
giterr_set(GITERR_OS, "failed to reset file pointer");
|
903
940
|
return -1;
|
904
941
|
}
|
905
942
|
|
@@ -913,14 +950,14 @@ replay:
|
|
913
950
|
&bytes_read, NULL) ||
|
914
951
|
!bytes_read) {
|
915
952
|
git__free(buffer);
|
916
|
-
giterr_set(GITERR_OS, "
|
953
|
+
giterr_set(GITERR_OS, "failed to read from temp file");
|
917
954
|
return -1;
|
918
955
|
}
|
919
956
|
|
920
957
|
if (!WinHttpWriteData(s->request, buffer,
|
921
958
|
bytes_read, &bytes_written)) {
|
922
959
|
git__free(buffer);
|
923
|
-
giterr_set(GITERR_OS, "
|
960
|
+
giterr_set(GITERR_OS, "failed to write data");
|
924
961
|
return -1;
|
925
962
|
}
|
926
963
|
|
@@ -936,7 +973,7 @@ replay:
|
|
936
973
|
}
|
937
974
|
|
938
975
|
if (!WinHttpReceiveResponse(s->request, 0)) {
|
939
|
-
giterr_set(GITERR_OS, "
|
976
|
+
giterr_set(GITERR_OS, "failed to receive response");
|
940
977
|
return -1;
|
941
978
|
}
|
942
979
|
|
@@ -948,7 +985,7 @@ replay:
|
|
948
985
|
WINHTTP_HEADER_NAME_BY_INDEX,
|
949
986
|
&status_code, &status_code_length,
|
950
987
|
WINHTTP_NO_HEADER_INDEX)) {
|
951
|
-
giterr_set(GITERR_OS, "
|
988
|
+
giterr_set(GITERR_OS, "failed to retrieve status code");
|
952
989
|
return -1;
|
953
990
|
}
|
954
991
|
|
@@ -978,7 +1015,7 @@ replay:
|
|
978
1015
|
&location_length,
|
979
1016
|
WINHTTP_NO_HEADER_INDEX) ||
|
980
1017
|
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
981
|
-
giterr_set(GITERR_OS, "
|
1018
|
+
giterr_set(GITERR_OS, "failed to read Location header");
|
982
1019
|
return -1;
|
983
1020
|
}
|
984
1021
|
|
@@ -991,14 +1028,14 @@ replay:
|
|
991
1028
|
location,
|
992
1029
|
&location_length,
|
993
1030
|
WINHTTP_NO_HEADER_INDEX)) {
|
994
|
-
giterr_set(GITERR_OS, "
|
1031
|
+
giterr_set(GITERR_OS, "failed to read Location header");
|
995
1032
|
git__free(location);
|
996
1033
|
return -1;
|
997
1034
|
}
|
998
1035
|
|
999
1036
|
/* Convert the Location header to UTF-8 */
|
1000
1037
|
if (git__utf16_to_8_alloc(&location8, location) < 0) {
|
1001
|
-
giterr_set(GITERR_OS, "
|
1038
|
+
giterr_set(GITERR_OS, "failed to convert Location header to UTF-8");
|
1002
1039
|
git__free(location);
|
1003
1040
|
return -1;
|
1004
1041
|
}
|
@@ -1029,7 +1066,7 @@ replay:
|
|
1029
1066
|
if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
|
1030
1067
|
int allowed_types;
|
1031
1068
|
|
1032
|
-
if (parse_unauthorized_response(s->request, &allowed_types, &t->
|
1069
|
+
if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanisms) < 0)
|
1033
1070
|
return -1;
|
1034
1071
|
|
1035
1072
|
/* TODO: extract the username from the url, no payload? */
|
@@ -1049,7 +1086,7 @@ replay:
|
|
1049
1086
|
if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) {
|
1050
1087
|
int allowed_types;
|
1051
1088
|
|
1052
|
-
if (parse_unauthorized_response(s->request, &allowed_types, &t->
|
1089
|
+
if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanisms) < 0)
|
1053
1090
|
return -1;
|
1054
1091
|
|
1055
1092
|
if (allowed_types) {
|
@@ -1090,7 +1127,7 @@ replay:
|
|
1090
1127
|
}
|
1091
1128
|
|
1092
1129
|
if (HTTP_STATUS_OK != status_code) {
|
1093
|
-
giterr_set(GITERR_NET, "
|
1130
|
+
giterr_set(GITERR_NET, "request failed with status code: %d", status_code);
|
1094
1131
|
return -1;
|
1095
1132
|
}
|
1096
1133
|
|
@@ -1101,7 +1138,7 @@ replay:
|
|
1101
1138
|
p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
|
1102
1139
|
|
1103
1140
|
if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
|
1104
|
-
giterr_set(GITERR_OS, "
|
1141
|
+
giterr_set(GITERR_OS, "failed to convert expected content-type to wide characters");
|
1105
1142
|
return -1;
|
1106
1143
|
}
|
1107
1144
|
|
@@ -1112,12 +1149,12 @@ replay:
|
|
1112
1149
|
WINHTTP_HEADER_NAME_BY_INDEX,
|
1113
1150
|
&content_type, &content_type_length,
|
1114
1151
|
WINHTTP_NO_HEADER_INDEX)) {
|
1115
|
-
giterr_set(GITERR_OS, "
|
1152
|
+
giterr_set(GITERR_OS, "failed to retrieve response content-type");
|
1116
1153
|
return -1;
|
1117
1154
|
}
|
1118
1155
|
|
1119
1156
|
if (wcscmp(expected_content_type, content_type)) {
|
1120
|
-
giterr_set(GITERR_NET, "
|
1157
|
+
giterr_set(GITERR_NET, "received unexpected content-type");
|
1121
1158
|
return -1;
|
1122
1159
|
}
|
1123
1160
|
|
@@ -1129,7 +1166,7 @@ replay:
|
|
1129
1166
|
(DWORD)buf_size,
|
1130
1167
|
&dw_bytes_read))
|
1131
1168
|
{
|
1132
|
-
giterr_set(GITERR_OS, "
|
1169
|
+
giterr_set(GITERR_OS, "failed to read data");
|
1133
1170
|
return -1;
|
1134
1171
|
}
|
1135
1172
|
|
@@ -1152,7 +1189,7 @@ static int winhttp_stream_write_single(
|
|
1152
1189
|
|
1153
1190
|
/* This implementation of write permits only a single call. */
|
1154
1191
|
if (s->sent_request) {
|
1155
|
-
giterr_set(GITERR_NET, "
|
1192
|
+
giterr_set(GITERR_NET, "subtransport configured for only one write");
|
1156
1193
|
return -1;
|
1157
1194
|
}
|
1158
1195
|
|
@@ -1165,7 +1202,7 @@ static int winhttp_stream_write_single(
|
|
1165
1202
|
(LPCVOID)buffer,
|
1166
1203
|
(DWORD)len,
|
1167
1204
|
&bytes_written)) {
|
1168
|
-
giterr_set(GITERR_OS, "
|
1205
|
+
giterr_set(GITERR_OS, "failed to write data");
|
1169
1206
|
return -1;
|
1170
1207
|
}
|
1171
1208
|
|
@@ -1183,12 +1220,12 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
1183
1220
|
if (RPC_S_OK != status &&
|
1184
1221
|
RPC_S_UUID_LOCAL_ONLY != status &&
|
1185
1222
|
RPC_S_UUID_NO_ADDRESS != status) {
|
1186
|
-
giterr_set(GITERR_NET, "
|
1223
|
+
giterr_set(GITERR_NET, "unable to generate name for temp file");
|
1187
1224
|
return -1;
|
1188
1225
|
}
|
1189
1226
|
|
1190
1227
|
if (buffer_len_cch < UUID_LENGTH_CCH + 1) {
|
1191
|
-
giterr_set(GITERR_NET, "
|
1228
|
+
giterr_set(GITERR_NET, "buffer too small for name of temp file");
|
1192
1229
|
return -1;
|
1193
1230
|
}
|
1194
1231
|
|
@@ -1203,7 +1240,7 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
1203
1240
|
uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]);
|
1204
1241
|
|
1205
1242
|
if (result < UUID_LENGTH_CCH) {
|
1206
|
-
giterr_set(GITERR_OS, "
|
1243
|
+
giterr_set(GITERR_OS, "unable to generate name for temp file");
|
1207
1244
|
return -1;
|
1208
1245
|
}
|
1209
1246
|
|
@@ -1215,7 +1252,7 @@ static int get_temp_file(LPWSTR buffer, DWORD buffer_len_cch)
|
|
1215
1252
|
size_t len;
|
1216
1253
|
|
1217
1254
|
if (!GetTempPathW(buffer_len_cch, buffer)) {
|
1218
|
-
giterr_set(GITERR_OS, "
|
1255
|
+
giterr_set(GITERR_OS, "failed to get temp path");
|
1219
1256
|
return -1;
|
1220
1257
|
}
|
1221
1258
|
|
@@ -1258,13 +1295,13 @@ static int winhttp_stream_write_buffered(
|
|
1258
1295
|
|
1259
1296
|
if (INVALID_HANDLE_VALUE == s->post_body) {
|
1260
1297
|
s->post_body = NULL;
|
1261
|
-
giterr_set(GITERR_OS, "
|
1298
|
+
giterr_set(GITERR_OS, "failed to create temporary file");
|
1262
1299
|
return -1;
|
1263
1300
|
}
|
1264
1301
|
}
|
1265
1302
|
|
1266
1303
|
if (!WriteFile(s->post_body, buffer, (DWORD)len, &bytes_written, NULL)) {
|
1267
|
-
giterr_set(GITERR_OS, "
|
1304
|
+
giterr_set(GITERR_OS, "failed to write to temporary file");
|
1268
1305
|
return -1;
|
1269
1306
|
}
|
1270
1307
|
|
@@ -1291,7 +1328,7 @@ static int winhttp_stream_write_chunked(
|
|
1291
1328
|
if (!WinHttpAddRequestHeaders(s->request,
|
1292
1329
|
transfer_encoding, (ULONG) -1L,
|
1293
1330
|
WINHTTP_ADDREQ_FLAG_ADD)) {
|
1294
|
-
giterr_set(GITERR_OS, "
|
1331
|
+
giterr_set(GITERR_OS, "failed to add a header to the request");
|
1295
1332
|
return -1;
|
1296
1333
|
}
|
1297
1334
|
|