rugged 0.21.0 → 0.21.1b0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -5
  3. data/ext/rugged/extconf.rb +8 -8
  4. data/ext/rugged/rugged.h +1 -1
  5. data/ext/rugged/rugged_cred.c +23 -0
  6. data/ext/rugged/rugged_index.c +5 -1
  7. data/ext/rugged/rugged_remote.c +68 -0
  8. data/ext/rugged/rugged_repo.c +287 -5
  9. data/ext/rugged/rugged_tag_collection.c +70 -2
  10. data/ext/rugged/rugged_tree.c +29 -10
  11. data/lib/rugged.rb +1 -0
  12. data/lib/rugged/attributes.rb +41 -0
  13. data/lib/rugged/diff.rb +0 -1
  14. data/lib/rugged/diff/line.rb +1 -3
  15. data/lib/rugged/patch.rb +12 -2
  16. data/lib/rugged/version.rb +1 -1
  17. data/vendor/libgit2/CMakeLists.txt +11 -0
  18. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  19. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  20. data/vendor/libgit2/deps/zlib/adler32.c +39 -29
  21. data/vendor/libgit2/deps/zlib/crc32.c +33 -50
  22. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  23. data/vendor/libgit2/deps/zlib/deflate.c +198 -65
  24. data/vendor/libgit2/deps/zlib/deflate.h +8 -4
  25. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  26. data/vendor/libgit2/deps/zlib/inffast.c +3 -3
  27. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  28. data/vendor/libgit2/deps/zlib/inflate.c +84 -52
  29. data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
  30. data/vendor/libgit2/deps/zlib/trees.c +18 -36
  31. data/vendor/libgit2/deps/zlib/zconf.h +4 -0
  32. data/vendor/libgit2/deps/zlib/zlib.h +250 -95
  33. data/vendor/libgit2/deps/zlib/zutil.c +13 -10
  34. data/vendor/libgit2/deps/zlib/zutil.h +41 -62
  35. data/vendor/libgit2/include/git2/attr.h +16 -13
  36. data/vendor/libgit2/include/git2/buffer.h +16 -0
  37. data/vendor/libgit2/include/git2/checkout.h +12 -12
  38. data/vendor/libgit2/include/git2/cherrypick.h +15 -15
  39. data/vendor/libgit2/include/git2/clone.h +77 -69
  40. data/vendor/libgit2/include/git2/diff.h +7 -0
  41. data/vendor/libgit2/include/git2/errors.h +1 -0
  42. data/vendor/libgit2/include/git2/merge.h +16 -0
  43. data/vendor/libgit2/include/git2/oid.h +8 -4
  44. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  45. data/vendor/libgit2/include/git2/remote.h +5 -24
  46. data/vendor/libgit2/include/git2/repository.h +4 -1
  47. data/vendor/libgit2/include/git2/reset.h +4 -0
  48. data/vendor/libgit2/include/git2/status.h +17 -14
  49. data/vendor/libgit2/include/git2/submodule.h +18 -0
  50. data/vendor/libgit2/include/git2/sys/transport.h +354 -0
  51. data/vendor/libgit2/include/git2/transport.h +34 -327
  52. data/vendor/libgit2/include/git2/types.h +16 -6
  53. data/vendor/libgit2/src/array.h +1 -1
  54. data/vendor/libgit2/src/attr_file.c +14 -1
  55. data/vendor/libgit2/src/blame.c +0 -1
  56. data/vendor/libgit2/src/buffer.c +67 -10
  57. data/vendor/libgit2/src/buffer.h +4 -2
  58. data/vendor/libgit2/src/cache.c +9 -9
  59. data/vendor/libgit2/src/cache.h +1 -1
  60. data/vendor/libgit2/src/checkout.c +118 -23
  61. data/vendor/libgit2/src/cherrypick.c +41 -44
  62. data/vendor/libgit2/src/clone.c +94 -56
  63. data/vendor/libgit2/src/config_file.c +4 -4
  64. data/vendor/libgit2/src/diff.c +21 -0
  65. data/vendor/libgit2/src/diff_file.c +1 -0
  66. data/vendor/libgit2/src/diff_print.c +11 -9
  67. data/vendor/libgit2/src/diff_tform.c +3 -1
  68. data/vendor/libgit2/src/errors.c +9 -7
  69. data/vendor/libgit2/src/fileops.c +5 -3
  70. data/vendor/libgit2/src/global.c +9 -1
  71. data/vendor/libgit2/src/global.h +1 -0
  72. data/vendor/libgit2/src/graph.c +2 -2
  73. data/vendor/libgit2/src/indexer.c +6 -1
  74. data/vendor/libgit2/src/merge.c +98 -144
  75. data/vendor/libgit2/src/merge.h +1 -1
  76. data/vendor/libgit2/src/netops.c +4 -0
  77. data/vendor/libgit2/src/oid.c +8 -0
  78. data/vendor/libgit2/src/oid.h +11 -0
  79. data/vendor/libgit2/src/oidarray.c +21 -0
  80. data/vendor/libgit2/src/oidarray.h +18 -0
  81. data/vendor/libgit2/src/pack.c +1 -4
  82. data/vendor/libgit2/src/path.c +93 -33
  83. data/vendor/libgit2/src/path.h +21 -0
  84. data/vendor/libgit2/src/pool.c +1 -1
  85. data/vendor/libgit2/src/posix.h +46 -28
  86. data/vendor/libgit2/src/refs.h +2 -2
  87. data/vendor/libgit2/src/refspec.c +54 -18
  88. data/vendor/libgit2/src/remote.c +31 -8
  89. data/vendor/libgit2/src/remote.h +3 -0
  90. data/vendor/libgit2/src/repository.c +27 -11
  91. data/vendor/libgit2/src/revert.c +4 -6
  92. data/vendor/libgit2/src/revparse.c +15 -18
  93. data/vendor/libgit2/src/revwalk.c +0 -3
  94. data/vendor/libgit2/src/signature.c +2 -2
  95. data/vendor/libgit2/src/stash.c +2 -1
  96. data/vendor/libgit2/src/status.c +11 -2
  97. data/vendor/libgit2/src/strnlen.h +2 -1
  98. data/vendor/libgit2/src/submodule.c +73 -33
  99. data/vendor/libgit2/src/thread-utils.h +0 -7
  100. data/vendor/libgit2/src/trace.h +9 -1
  101. data/vendor/libgit2/src/transport.c +93 -90
  102. data/vendor/libgit2/src/transports/auth.c +71 -0
  103. data/vendor/libgit2/src/transports/auth.h +63 -0
  104. data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
  105. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  106. data/vendor/libgit2/src/transports/cred.c +58 -0
  107. data/vendor/libgit2/src/transports/cred.h +14 -0
  108. data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
  109. data/vendor/libgit2/src/transports/git.c +1 -0
  110. data/vendor/libgit2/src/transports/http.c +168 -76
  111. data/vendor/libgit2/src/transports/smart.h +1 -0
  112. data/vendor/libgit2/src/transports/smart_protocol.c +4 -2
  113. data/vendor/libgit2/src/transports/ssh.c +214 -38
  114. data/vendor/libgit2/src/transports/winhttp.c +26 -6
  115. data/vendor/libgit2/src/unix/posix.h +23 -9
  116. data/vendor/libgit2/src/unix/realpath.c +8 -7
  117. data/vendor/libgit2/src/util.c +2 -1
  118. data/vendor/libgit2/src/util.h +3 -3
  119. data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
  120. data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
  121. data/vendor/libgit2/src/win32/posix.h +20 -31
  122. data/vendor/libgit2/src/win32/posix_w32.c +33 -4
  123. metadata +81 -69
@@ -9,6 +9,7 @@
9
9
  #include "netops.h"
10
10
  #include "buffer.h"
11
11
  #include "push.h"
12
+ #include "git2/sys/transport.h"
12
13
 
13
14
  #define GIT_SIDE_BAND_DATA 1
14
15
  #define GIT_SIDE_BAND_PROGRESS 2
@@ -314,7 +314,7 @@ static int wait_while_ack(gitno_buffer *buf)
314
314
  break;
315
315
 
316
316
  if (pkt->type == GIT_PKT_ACK &&
317
- (pkt->status != GIT_ACK_CONTINUE ||
317
+ (pkt->status != GIT_ACK_CONTINUE &&
318
318
  pkt->status != GIT_ACK_COMMON)) {
319
319
  git__free(pkt);
320
320
  return 0;
@@ -592,7 +592,9 @@ int git_smart__download_pack(
592
592
  }
593
593
  } else if (pkt->type == GIT_PKT_DATA) {
594
594
  git_pkt_data *p = (git_pkt_data *) pkt;
595
- error = writepack->append(writepack, p->data, p->len, stats);
595
+
596
+ if (p->len)
597
+ error = writepack->append(writepack, p->data, p->len, stats);
596
598
  } else if (pkt->type == GIT_PKT_FLUSH) {
597
599
  /* A flush indicates the end of the packfile */
598
600
  git__free(pkt);
@@ -5,15 +5,18 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
+ #ifdef GIT_SSH
9
+ #include <libssh2.h>
10
+ #endif
11
+
8
12
  #include "git2.h"
9
13
  #include "buffer.h"
10
14
  #include "netops.h"
11
15
  #include "smart.h"
16
+ #include "cred.h"
12
17
 
13
18
  #ifdef GIT_SSH
14
19
 
15
- #include <libssh2.h>
16
-
17
20
  #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
18
21
 
19
22
  static const char prefix_ssh[] = "ssh://";
@@ -35,8 +38,12 @@ typedef struct {
35
38
  transport_smart *owner;
36
39
  ssh_stream *current_stream;
37
40
  git_cred *cred;
41
+ char *cmd_uploadpack;
42
+ char *cmd_receivepack;
38
43
  } ssh_subtransport;
39
44
 
45
+ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username);
46
+
40
47
  static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
41
48
  {
42
49
  char *ssherr;
@@ -132,11 +139,22 @@ static int ssh_stream_write(
132
139
  size_t len)
133
140
  {
134
141
  ssh_stream *s = (ssh_stream *)stream;
142
+ size_t off = 0;
143
+ ssize_t ret = 0;
135
144
 
136
145
  if (!s->sent_command && send_command(s) < 0)
137
146
  return -1;
138
147
 
139
- if (libssh2_channel_write(s->channel, buffer, len) < LIBSSH2_ERROR_NONE) {
148
+ do {
149
+ ret = libssh2_channel_write(s->channel, buffer + off, len - off);
150
+ if (ret < 0)
151
+ break;
152
+
153
+ off += ret;
154
+
155
+ } while (off < len);
156
+
157
+ if (ret < 0) {
140
158
  ssh_error(s->session, "SSH could not write data");
141
159
  return -1;
142
160
  }
@@ -274,6 +292,10 @@ static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
274
292
  }
275
293
 
276
294
  shutdown:
295
+
296
+ if (rc != LIBSSH2_ERROR_NONE)
297
+ ssh_error(session, "error authenticating");
298
+
277
299
  libssh2_agent_disconnect(agent);
278
300
  libssh2_agent_free(agent);
279
301
 
@@ -287,6 +309,7 @@ static int _git_ssh_authenticate_session(
287
309
  int rc;
288
310
 
289
311
  do {
312
+ giterr_clear();
290
313
  switch (cred->credtype) {
291
314
  case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
292
315
  git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
@@ -339,11 +362,52 @@ static int _git_ssh_authenticate_session(
339
362
  }
340
363
  } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
341
364
 
365
+ if (rc == LIBSSH2_ERROR_PASSWORD_EXPIRED || rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED)
366
+ return GIT_EAUTH;
367
+
342
368
  if (rc != LIBSSH2_ERROR_NONE) {
343
- ssh_error(session, "Failed to authenticate SSH session");
369
+ if (!giterr_last())
370
+ ssh_error(session, "Failed to authenticate SSH session");
371
+ return -1;
372
+ }
373
+
374
+ return 0;
375
+ }
376
+
377
+ static int request_creds(git_cred **out, ssh_subtransport *t, const char *user, int auth_methods)
378
+ {
379
+ int error, no_callback = 0;
380
+ git_cred *cred = NULL;
381
+
382
+ if (!t->owner->cred_acquire_cb) {
383
+ no_callback = 1;
384
+ } else {
385
+ error = t->owner->cred_acquire_cb(&cred, t->owner->url, user, auth_methods,
386
+ t->owner->cred_acquire_payload);
387
+
388
+ if (error == GIT_PASSTHROUGH)
389
+ no_callback = 1;
390
+ else if (error < 0)
391
+ return error;
392
+ else if (!cred) {
393
+ giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials");
394
+ return -1;
395
+ }
396
+ }
397
+
398
+ if (no_callback) {
399
+ giterr_set(GITERR_SSH, "authentication required but no callback set");
400
+ return -1;
401
+ }
402
+
403
+ if (!(cred->credtype & auth_methods)) {
404
+ cred->free(cred);
405
+ giterr_set(GITERR_SSH, "callback returned unsupported credentials type");
344
406
  return -1;
345
407
  }
346
408
 
409
+ *out = cred;
410
+
347
411
  return 0;
348
412
  }
349
413
 
@@ -387,8 +451,9 @@ static int _git_ssh_setup_conn(
387
451
  {
388
452
  char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
389
453
  const char *default_port="22";
390
- int no_callback = 0;
454
+ int auth_methods, error = 0;
391
455
  ssh_stream *s;
456
+ git_cred *cred = NULL;
392
457
  LIBSSH2_SESSION* session=NULL;
393
458
  LIBSSH2_CHANNEL* channel=NULL;
394
459
 
@@ -399,56 +464,68 @@ static int _git_ssh_setup_conn(
399
464
  s = (ssh_stream *)*stream;
400
465
 
401
466
  if (!git__prefixcmp(url, prefix_ssh)) {
402
- if (gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port) < 0)
467
+ if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
403
468
  goto on_error;
404
469
  } else {
405
- if (git_ssh_extract_url_parts(&host, &user, url) < 0)
470
+ if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
406
471
  goto on_error;
407
472
  port = git__strdup(default_port);
408
473
  GITERR_CHECK_ALLOC(port);
409
474
  }
410
475
 
411
- if (gitno_connect(&s->socket, host, port, 0) < 0)
412
- goto on_error;
413
-
414
- if (user && pass) {
415
- if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0)
476
+ /* we need the username to ask for auth methods */
477
+ if (!user) {
478
+ if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0)
416
479
  goto on_error;
417
- } else if (!t->owner->cred_acquire_cb) {
418
- no_callback = 1;
419
- } else {
420
- int error;
421
- error = t->owner->cred_acquire_cb(&t->cred, t->owner->url, user,
422
- GIT_CREDTYPE_USERPASS_PLAINTEXT |
423
- GIT_CREDTYPE_SSH_KEY | GIT_CREDTYPE_SSH_CUSTOM |
424
- GIT_CREDTYPE_SSH_INTERACTIVE,
425
- t->owner->cred_acquire_payload);
426
480
 
427
- if (error == GIT_PASSTHROUGH)
428
- no_callback = 1;
429
- else if (error < 0)
481
+ user = git__strdup(((git_cred_username *) cred)->username);
482
+ cred->free(cred);
483
+ cred = NULL;
484
+ if (!user)
430
485
  goto on_error;
431
- else if (!t->cred) {
432
- giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials");
486
+ } else if (user && pass) {
487
+ if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0)
433
488
  goto on_error;
434
- }
435
489
  }
436
490
 
437
- if (no_callback) {
438
- giterr_set(GITERR_SSH, "authentication required but no callback set");
491
+ if ((error = gitno_connect(&s->socket, host, port, 0)) < 0)
439
492
  goto on_error;
440
- }
441
493
 
442
- assert(t->cred);
494
+ if ((error = _git_ssh_session_create(&session, s->socket)) < 0)
495
+ goto on_error;
443
496
 
444
- if (_git_ssh_session_create(&session, s->socket) < 0)
497
+ if ((error = list_auth_methods(&auth_methods, session, user)) < 0)
445
498
  goto on_error;
446
499
 
447
- if (_git_ssh_authenticate_session(session, t->cred) < 0)
500
+ error = GIT_EAUTH;
501
+ /* if we already have something to try */
502
+ if (cred && auth_methods & cred->credtype)
503
+ error = _git_ssh_authenticate_session(session, cred);
504
+
505
+ while (error == GIT_EAUTH) {
506
+ if (cred) {
507
+ cred->free(cred);
508
+ cred = NULL;
509
+ }
510
+
511
+ if ((error = request_creds(&cred, t, user, auth_methods)) < 0)
512
+ goto on_error;
513
+
514
+ if (strcmp(user, git_cred__username(cred))) {
515
+ giterr_set(GITERR_SSH, "username does not match previous request");
516
+ error = -1;
517
+ goto on_error;
518
+ }
519
+
520
+ error = _git_ssh_authenticate_session(session, cred);
521
+ }
522
+
523
+ if (error < 0)
448
524
  goto on_error;
449
525
 
450
526
  channel = libssh2_channel_open_session(session);
451
527
  if (!channel) {
528
+ error = -1;
452
529
  ssh_error(session, "Failed to open SSH channel");
453
530
  goto on_error;
454
531
  }
@@ -459,6 +536,9 @@ static int _git_ssh_setup_conn(
459
536
  s->channel = channel;
460
537
 
461
538
  t->current_stream = s;
539
+ if (cred)
540
+ cred->free(cred);
541
+
462
542
  git__free(host);
463
543
  git__free(port);
464
544
  git__free(path);
@@ -475,6 +555,9 @@ on_error:
475
555
  if (*stream)
476
556
  ssh_stream_free(*stream);
477
557
 
558
+ if (cred)
559
+ cred->free(cred);
560
+
478
561
  git__free(host);
479
562
  git__free(port);
480
563
  git__free(user);
@@ -483,7 +566,7 @@ on_error:
483
566
  if (session)
484
567
  libssh2_session_free(session);
485
568
 
486
- return -1;
569
+ return error;
487
570
  }
488
571
 
489
572
  static int ssh_uploadpack_ls(
@@ -491,10 +574,9 @@ static int ssh_uploadpack_ls(
491
574
  const char *url,
492
575
  git_smart_subtransport_stream **stream)
493
576
  {
494
- if (_git_ssh_setup_conn(t, url, cmd_uploadpack, stream) < 0)
495
- return -1;
577
+ const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack;
496
578
 
497
- return 0;
579
+ return _git_ssh_setup_conn(t, url, cmd, stream);
498
580
  }
499
581
 
500
582
  static int ssh_uploadpack(
@@ -518,7 +600,9 @@ static int ssh_receivepack_ls(
518
600
  const char *url,
519
601
  git_smart_subtransport_stream **stream)
520
602
  {
521
- if (_git_ssh_setup_conn(t, url, cmd_receivepack, stream) < 0)
603
+ const char *cmd = t->cmd_receivepack ? t->cmd_receivepack : cmd_receivepack;
604
+
605
+ if (_git_ssh_setup_conn(t, url, cmd, stream) < 0)
522
606
  return -1;
523
607
 
524
608
  return 0;
@@ -583,8 +667,57 @@ static void _ssh_free(git_smart_subtransport *subtransport)
583
667
 
584
668
  assert(!t->current_stream);
585
669
 
670
+ git__free(t->cmd_uploadpack);
671
+ git__free(t->cmd_receivepack);
586
672
  git__free(t);
587
673
  }
674
+
675
+ #define SSH_AUTH_PUBLICKEY "publickey"
676
+ #define SSH_AUTH_PASSWORD "password"
677
+ #define SSH_AUTH_KEYBOARD_INTERACTIVE "keyboard-interactive"
678
+
679
+ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username)
680
+ {
681
+ const char *list, *ptr;
682
+
683
+ *out = 0;
684
+
685
+ list = libssh2_userauth_list(session, username, strlen(username));
686
+
687
+ /* either error, or the remote accepts NONE auth, which is bizarre, let's punt */
688
+ if (list == NULL && !libssh2_userauth_authenticated(session))
689
+ return -1;
690
+
691
+ ptr = list;
692
+ while (ptr) {
693
+ if (*ptr == ',')
694
+ ptr++;
695
+
696
+ if (!git__prefixcmp(ptr, SSH_AUTH_PUBLICKEY)) {
697
+ *out |= GIT_CREDTYPE_SSH_KEY;
698
+ *out |= GIT_CREDTYPE_SSH_CUSTOM;
699
+ ptr += strlen(SSH_AUTH_PUBLICKEY);
700
+ continue;
701
+ }
702
+
703
+ if (!git__prefixcmp(ptr, SSH_AUTH_PASSWORD)) {
704
+ *out |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
705
+ ptr += strlen(SSH_AUTH_PASSWORD);
706
+ continue;
707
+ }
708
+
709
+ if (!git__prefixcmp(ptr, SSH_AUTH_KEYBOARD_INTERACTIVE)) {
710
+ *out |= GIT_CREDTYPE_SSH_INTERACTIVE;
711
+ ptr += strlen(SSH_AUTH_KEYBOARD_INTERACTIVE);
712
+ continue;
713
+ }
714
+
715
+ /* Skipt it if we don't know it */
716
+ ptr = strchr(ptr, ',');
717
+ }
718
+
719
+ return 0;
720
+ }
588
721
  #endif
589
722
 
590
723
  int git_smart_subtransport_ssh(
@@ -615,3 +748,46 @@ int git_smart_subtransport_ssh(
615
748
  return -1;
616
749
  #endif
617
750
  }
751
+
752
+ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload)
753
+ {
754
+ #ifdef GIT_SSH
755
+ git_strarray *paths = (git_strarray *) payload;
756
+ git_transport *transport;
757
+ transport_smart *smart;
758
+ ssh_subtransport *t;
759
+ int error;
760
+ git_smart_subtransport_definition ssh_definition = {
761
+ git_smart_subtransport_ssh,
762
+ 0, /* no RPC */
763
+ };
764
+
765
+ if (paths->count != 2) {
766
+ giterr_set(GITERR_SSH, "invalid ssh paths, must be two strings");
767
+ return GIT_EINVALIDSPEC;
768
+ }
769
+
770
+ if ((error = git_transport_smart(&transport, owner, &ssh_definition)) < 0)
771
+ return error;
772
+
773
+ smart = (transport_smart *) transport;
774
+ t = (ssh_subtransport *) smart->wrapped;
775
+
776
+ t->cmd_uploadpack = git__strdup(paths->strings[0]);
777
+ GITERR_CHECK_ALLOC(t->cmd_uploadpack);
778
+ t->cmd_receivepack = git__strdup(paths->strings[1]);
779
+ GITERR_CHECK_ALLOC(t->cmd_receivepack);
780
+
781
+ *out = transport;
782
+ return 0;
783
+ #else
784
+ GIT_UNUSED(owner);
785
+ GIT_UNUSED(payload);
786
+
787
+ assert(out);
788
+ *out = NULL;
789
+
790
+ giterr_set(GITERR_INVALID, "Cannot create SSH transport. Library was built without SSH support");
791
+ return -1;
792
+ #endif
793
+ }
@@ -35,6 +35,11 @@
35
35
  #define WINHTTP_OPTION_PEERDIST_EXTENSION_STATE 109
36
36
  #define CACHED_POST_BODY_BUF_SIZE 4096
37
37
  #define UUID_LENGTH_CCH 32
38
+ #define TIMEOUT_INFINITE -1
39
+ #define DEFAULT_CONNECT_TIMEOUT 60000
40
+ #ifndef WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH
41
+ #define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
42
+ #endif
38
43
 
39
44
  static const char *prefix_http = "http://";
40
45
  static const char *prefix_https = "https://";
@@ -97,7 +102,7 @@ static int apply_basic_credential(HINTERNET request, git_cred *cred)
97
102
 
98
103
  if (git_buf_oom(&raw) ||
99
104
  git_buf_puts(&buf, "Authorization: Basic ") < 0 ||
100
- git_buf_put_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
105
+ git_buf_encode_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
101
106
  goto on_error;
102
107
 
103
108
  if ((wide_len = git__utf8_to_16_alloc(&wide, git_buf_cstr(&buf))) < 0) {
@@ -208,6 +213,8 @@ static int winhttp_stream_connect(winhttp_stream *s)
208
213
  BOOL peerdist = FALSE;
209
214
  int error = -1;
210
215
  unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
216
+ int default_timeout = TIMEOUT_INFINITE;
217
+ int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
211
218
 
212
219
  /* Prepare URL */
213
220
  git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url);
@@ -236,6 +243,11 @@ static int winhttp_stream_connect(winhttp_stream *s)
236
243
  goto on_error;
237
244
  }
238
245
 
246
+ if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
247
+ giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP");
248
+ goto on_error;
249
+ }
250
+
239
251
  /* Set proxy if necessary */
240
252
  if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0)
241
253
  goto on_error;
@@ -463,6 +475,8 @@ static int winhttp_connect(
463
475
  int32_t port;
464
476
  const char *default_port = "80";
465
477
  int error = -1;
478
+ int default_timeout = TIMEOUT_INFINITE;
479
+ int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
466
480
 
467
481
  /* Prepare port */
468
482
  if (git__strtol32(&port, t->connection_data.port, NULL, 10) < 0)
@@ -487,6 +501,12 @@ static int winhttp_connect(
487
501
  goto on_error;
488
502
  }
489
503
 
504
+ if (!WinHttpSetTimeouts(t->session, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
505
+ giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP");
506
+ goto on_error;
507
+ }
508
+
509
+
490
510
  /* Establish connection */
491
511
  t->connection = WinHttpConnect(
492
512
  t->session,
@@ -745,9 +765,9 @@ replay:
745
765
 
746
766
  /* Verify that we got the correct content-type back */
747
767
  if (post_verb == s->verb)
748
- snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
768
+ p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
749
769
  else
750
- snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
770
+ p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
751
771
 
752
772
  if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
753
773
  giterr_set(GITERR_OS, "Failed to convert expected content-type to wide characters");
@@ -1112,9 +1132,9 @@ static int winhttp_action(
1112
1132
  int ret = -1;
1113
1133
 
1114
1134
  if (!t->connection)
1115
- if (gitno_connection_data_from_url(&t->connection_data, url, NULL) < 0 ||
1116
- winhttp_connect(t, url) < 0)
1117
- return -1;
1135
+ if ((ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0 ||
1136
+ (ret = winhttp_connect(t, url)) < 0)
1137
+ return ret;
1118
1138
 
1119
1139
  if (winhttp_stream_alloc(t, &s) < 0)
1120
1140
  return -1;