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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/include/git2/common.h +10 -0
  4. data/vendor/libgit2/include/git2/merge.h +2 -1
  5. data/vendor/libgit2/include/git2/oid.h +4 -5
  6. data/vendor/libgit2/include/git2/submodule.h +2 -11
  7. data/vendor/libgit2/include/git2/sys/repository.h +29 -0
  8. data/vendor/libgit2/include/git2/tree.h +13 -0
  9. data/vendor/libgit2/src/apply.c +2 -2
  10. data/vendor/libgit2/src/attr_file.c +5 -5
  11. data/vendor/libgit2/src/attrcache.c +9 -7
  12. data/vendor/libgit2/src/blob.c +3 -3
  13. data/vendor/libgit2/src/branch.c +10 -10
  14. data/vendor/libgit2/src/buffer.c +4 -4
  15. data/vendor/libgit2/src/cache.c +1 -1
  16. data/vendor/libgit2/src/checkout.c +29 -25
  17. data/vendor/libgit2/src/cherrypick.c +2 -2
  18. data/vendor/libgit2/src/commit.c +2 -2
  19. data/vendor/libgit2/src/commit_list.c +2 -2
  20. data/vendor/libgit2/src/common.h +1 -1
  21. data/vendor/libgit2/src/config.c +12 -12
  22. data/vendor/libgit2/src/config_file.c +9 -9
  23. data/vendor/libgit2/src/crlf.c +1 -1
  24. data/vendor/libgit2/src/delta.c +4 -4
  25. data/vendor/libgit2/src/describe.c +11 -11
  26. data/vendor/libgit2/src/diff_driver.c +1 -1
  27. data/vendor/libgit2/src/diff_file.c +1 -1
  28. data/vendor/libgit2/src/diff_generate.c +2 -2
  29. data/vendor/libgit2/src/diff_print.c +5 -5
  30. data/vendor/libgit2/src/diff_tform.c +1 -1
  31. data/vendor/libgit2/src/diff_xdiff.c +2 -2
  32. data/vendor/libgit2/src/fetch.c +1 -1
  33. data/vendor/libgit2/src/fetchhead.c +8 -8
  34. data/vendor/libgit2/src/filebuf.c +9 -9
  35. data/vendor/libgit2/src/fileops.c +27 -27
  36. data/vendor/libgit2/src/filter.c +4 -4
  37. data/vendor/libgit2/src/hashsig.c +2 -2
  38. data/vendor/libgit2/src/ignore.c +4 -4
  39. data/vendor/libgit2/src/index.c +15 -15
  40. data/vendor/libgit2/src/indexer.c +39 -6
  41. data/vendor/libgit2/src/integer.h +6 -6
  42. data/vendor/libgit2/src/merge.c +12 -12
  43. data/vendor/libgit2/src/merge_file.c +1 -1
  44. data/vendor/libgit2/src/mwindow.c +1 -1
  45. data/vendor/libgit2/src/netops.c +4 -4
  46. data/vendor/libgit2/src/notes.c +3 -3
  47. data/vendor/libgit2/src/object.c +5 -5
  48. data/vendor/libgit2/src/odb.c +12 -12
  49. data/vendor/libgit2/src/odb_loose.c +6 -6
  50. data/vendor/libgit2/src/oid.c +5 -5
  51. data/vendor/libgit2/src/openssl_stream.c +3 -3
  52. data/vendor/libgit2/src/pack-objects.c +6 -6
  53. data/vendor/libgit2/src/pack.c +19 -10
  54. data/vendor/libgit2/src/pack.h +1 -0
  55. data/vendor/libgit2/src/patch_generate.c +5 -3
  56. data/vendor/libgit2/src/path.c +15 -15
  57. data/vendor/libgit2/src/pathspec.c +2 -2
  58. data/vendor/libgit2/src/posix.c +1 -1
  59. data/vendor/libgit2/src/push.c +6 -6
  60. data/vendor/libgit2/src/rebase.c +12 -12
  61. data/vendor/libgit2/src/refdb.c +1 -1
  62. data/vendor/libgit2/src/refdb_fs.c +12 -12
  63. data/vendor/libgit2/src/reflog.c +2 -2
  64. data/vendor/libgit2/src/refs.c +34 -17
  65. data/vendor/libgit2/src/refs.h +3 -0
  66. data/vendor/libgit2/src/remote.c +3 -3
  67. data/vendor/libgit2/src/repository.c +46 -13
  68. data/vendor/libgit2/src/repository.h +2 -1
  69. data/vendor/libgit2/src/reset.c +1 -1
  70. data/vendor/libgit2/src/revert.c +2 -2
  71. data/vendor/libgit2/src/revparse.c +5 -5
  72. data/vendor/libgit2/src/revwalk.c +3 -3
  73. data/vendor/libgit2/src/settings.c +6 -1
  74. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  75. data/vendor/libgit2/src/signature.c +1 -1
  76. data/vendor/libgit2/src/socket_stream.c +5 -5
  77. data/vendor/libgit2/src/sortedcache.c +5 -5
  78. data/vendor/libgit2/src/stash.c +6 -6
  79. data/vendor/libgit2/src/status.c +4 -4
  80. data/vendor/libgit2/src/submodule.c +159 -110
  81. data/vendor/libgit2/src/submodule.h +3 -0
  82. data/vendor/libgit2/src/sysdir.c +2 -2
  83. data/vendor/libgit2/src/tag.c +14 -14
  84. data/vendor/libgit2/src/trace.c +1 -1
  85. data/vendor/libgit2/src/transport.c +1 -1
  86. data/vendor/libgit2/src/transports/auth_negotiate.c +4 -4
  87. data/vendor/libgit2/src/transports/cred.c +1 -1
  88. data/vendor/libgit2/src/transports/git.c +3 -3
  89. data/vendor/libgit2/src/transports/http.c +6 -6
  90. data/vendor/libgit2/src/transports/local.c +2 -2
  91. data/vendor/libgit2/src/transports/smart.c +5 -5
  92. data/vendor/libgit2/src/transports/smart_pkt.c +4 -4
  93. data/vendor/libgit2/src/transports/smart_protocol.c +1 -1
  94. data/vendor/libgit2/src/transports/ssh.c +9 -9
  95. data/vendor/libgit2/src/transports/winhttp.c +155 -118
  96. data/vendor/libgit2/src/tree-cache.c +2 -2
  97. data/vendor/libgit2/src/tree.c +35 -20
  98. data/vendor/libgit2/src/unix/map.c +1 -1
  99. data/vendor/libgit2/src/util.c +3 -3
  100. data/vendor/libgit2/src/vector.c +3 -0
  101. data/vendor/libgit2/src/win32/dir.c +3 -3
  102. data/vendor/libgit2/src/win32/findfile.c +1 -1
  103. data/vendor/libgit2/src/win32/map.c +6 -6
  104. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -2
  105. data/vendor/libgit2/src/win32/w32_util.c +1 -1
  106. data/vendor/libgit2/src/win32/w32_util.h +1 -1
  107. data/vendor/libgit2/src/zstream.c +1 -1
  108. 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
- GIT_WINHTTP_AUTH_NEGOTIATE = 2,
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 auth_mechanism;
99
+ int auth_mechanisms;
99
100
  HINTERNET session;
100
101
  HINTERNET connection;
101
102
  } winhttp_subtransport;
102
103
 
103
- static int apply_basic_credential_proxy(HINTERNET request, git_cred *cred)
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
- return error;
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
- return error;
113
+ if ((error = pass_len = git__utf8_to_16_alloc(&pass, c->password)) < 0)
114
+ goto done;
114
115
 
115
- if (!WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC,
116
- user, pass, NULL)) {
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 apply_basic_credential(HINTERNET request, git_cred *cred)
134
+ static int apply_userpass_credential_proxy(HINTERNET request, git_cred *cred)
128
135
  {
129
- git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
130
- git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT;
131
- wchar_t *wide = NULL;
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
- if ((wide_len = git__utf8_to_16_alloc(&wide, git_buf_cstr(&buf))) < 0) {
142
- giterr_set(GITERR_OS, "Failed to convert string to wide form");
143
- goto on_error;
144
- }
140
+ static int apply_userpass_credential(HINTERNET request, int mechanisms, git_cred *cred)
141
+ {
142
+ DWORD native_scheme;
145
143
 
146
- if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
147
- giterr_set(GITERR_OS, "Failed to add a header to the request");
148
- goto on_error;
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
- error = 0;
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, "Failed to convert string to wide form");
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, "Failed to convert string to wide form");
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, "Failed to open request");
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, "Failed to set timeouts for WinHTTP");
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, "Failed to set proxy");
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 = apply_basic_credential_proxy(s->request, t->proxy_cred)) < 0)
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, "Failed to disable redirects");
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, "Failed to add a header to the request");
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, "Failed to convert content-type to wide characters");
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, "Failed to add a header to the request");
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, "Failed to convert accept header to wide characters");
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, "Failed to add a header to the request");
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, "Failed to convert custom header to wide characters");
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, "Failed to add a header to the request");
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->auth_mechanism == GIT_WINHTTP_AUTH_BASIC &&
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->auth_mechanism == GIT_WINHTTP_AUTH_NEGOTIATE &&
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 (apply_basic_credential(s->request, t->url_cred) < 0)
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 *auth_mechanism)
584
+ int *allowed_mechanisms)
589
585
  {
590
586
  DWORD supported, first, target;
591
587
 
592
588
  *allowed_types = 0;
593
- *auth_mechanism = 0;
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, "Failed to parse supported auth schemes");
595
+ giterr_set(GITERR_OS, "failed to parse supported auth schemes");
600
596
  return -1;
601
597
  }
602
598
 
603
- if (WINHTTP_AUTH_SCHEME_BASIC & supported) {
599
+ if (WINHTTP_AUTH_SCHEME_NTLM & supported) {
604
600
  *allowed_types |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
605
- *auth_mechanism = GIT_WINHTTP_AUTH_BASIC;
601
+ *allowed_types |= GIT_CREDTYPE_DEFAULT;
602
+ *allowed_mechanisms = GIT_WINHTTP_AUTH_NEGOTIATE;
606
603
  }
607
604
 
608
- if ((WINHTTP_AUTH_SCHEME_NTLM & supported) ||
609
- (WINHTTP_AUTH_SCHEME_NEGOTIATE & supported)) {
605
+ if (WINHTTP_AUTH_SCHEME_NEGOTIATE & supported) {
610
606
  *allowed_types |= GIT_CREDTYPE_DEFAULT;
611
- *auth_mechanism = GIT_WINHTTP_AUTH_NEGOTIATE;
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, "Failed to write chunk header");
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, "Failed to write chunk");
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, "Failed to write chunk footer");
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, "Unable to close connection");
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, "Unable to close session");
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, "Unable to convert host to wide characters");
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, "Unable to convert host to wide characters");
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, "Failed to init WinHTTP");
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, "Failed to set timeouts for WinHTTP");
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, "Failed to connect to host");
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
- if ((error = do_send_request(s, len, ignore_length)) < 0)
805
- request_failed = 1;
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, "Too many redirects or authentication replays");
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, "Failed to write final chunk");
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, "Failed to reset file pointer");
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, "Failed to read from temp file");
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, "Failed to write data");
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, "Failed to receive response");
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, "Failed to retrieve status code");
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, "Failed to read Location header");
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, "Failed to read Location header");
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, "Failed to convert Location header to UTF-8");
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->auth_mechanism) < 0)
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->auth_mechanism) < 0)
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, "Request failed with status code: %d", status_code);
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, "Failed to convert expected content-type to wide characters");
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, "Failed to retrieve response content-type");
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, "Received unexpected content-type");
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, "Failed to read data");
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, "Subtransport configured for only one write");
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, "Failed to write data");
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, "Unable to generate name for temp file");
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, "Buffer too small for name of temp file");
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, "Unable to generate name for temp file");
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, "Failed to get temp path");
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, "Failed to create temporary file");
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, "Failed to write to temporary file");
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, "Failed to add a header to the request");
1331
+ giterr_set(GITERR_OS, "failed to add a header to the request");
1295
1332
  return -1;
1296
1333
  }
1297
1334