rugged 0.21.0 → 0.21.1b0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -5
- data/ext/rugged/extconf.rb +8 -8
- data/ext/rugged/rugged.h +1 -1
- data/ext/rugged/rugged_cred.c +23 -0
- data/ext/rugged/rugged_index.c +5 -1
- data/ext/rugged/rugged_remote.c +68 -0
- data/ext/rugged/rugged_repo.c +287 -5
- data/ext/rugged/rugged_tag_collection.c +70 -2
- data/ext/rugged/rugged_tree.c +29 -10
- data/lib/rugged.rb +1 -0
- data/lib/rugged/attributes.rb +41 -0
- data/lib/rugged/diff.rb +0 -1
- data/lib/rugged/diff/line.rb +1 -3
- data/lib/rugged/patch.rb +12 -2
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +11 -0
- data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
- data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
- data/vendor/libgit2/deps/zlib/adler32.c +39 -29
- data/vendor/libgit2/deps/zlib/crc32.c +33 -50
- data/vendor/libgit2/deps/zlib/crc32.h +1 -1
- data/vendor/libgit2/deps/zlib/deflate.c +198 -65
- data/vendor/libgit2/deps/zlib/deflate.h +8 -4
- data/vendor/libgit2/deps/zlib/infback.c +640 -0
- data/vendor/libgit2/deps/zlib/inffast.c +3 -3
- data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
- data/vendor/libgit2/deps/zlib/inflate.c +84 -52
- data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
- data/vendor/libgit2/deps/zlib/trees.c +18 -36
- data/vendor/libgit2/deps/zlib/zconf.h +4 -0
- data/vendor/libgit2/deps/zlib/zlib.h +250 -95
- data/vendor/libgit2/deps/zlib/zutil.c +13 -10
- data/vendor/libgit2/deps/zlib/zutil.h +41 -62
- data/vendor/libgit2/include/git2/attr.h +16 -13
- data/vendor/libgit2/include/git2/buffer.h +16 -0
- data/vendor/libgit2/include/git2/checkout.h +12 -12
- data/vendor/libgit2/include/git2/cherrypick.h +15 -15
- data/vendor/libgit2/include/git2/clone.h +77 -69
- data/vendor/libgit2/include/git2/diff.h +7 -0
- data/vendor/libgit2/include/git2/errors.h +1 -0
- data/vendor/libgit2/include/git2/merge.h +16 -0
- data/vendor/libgit2/include/git2/oid.h +8 -4
- data/vendor/libgit2/include/git2/oidarray.h +40 -0
- data/vendor/libgit2/include/git2/remote.h +5 -24
- data/vendor/libgit2/include/git2/repository.h +4 -1
- data/vendor/libgit2/include/git2/reset.h +4 -0
- data/vendor/libgit2/include/git2/status.h +17 -14
- data/vendor/libgit2/include/git2/submodule.h +18 -0
- data/vendor/libgit2/include/git2/sys/transport.h +354 -0
- data/vendor/libgit2/include/git2/transport.h +34 -327
- data/vendor/libgit2/include/git2/types.h +16 -6
- data/vendor/libgit2/src/array.h +1 -1
- data/vendor/libgit2/src/attr_file.c +14 -1
- data/vendor/libgit2/src/blame.c +0 -1
- data/vendor/libgit2/src/buffer.c +67 -10
- data/vendor/libgit2/src/buffer.h +4 -2
- data/vendor/libgit2/src/cache.c +9 -9
- data/vendor/libgit2/src/cache.h +1 -1
- data/vendor/libgit2/src/checkout.c +118 -23
- data/vendor/libgit2/src/cherrypick.c +41 -44
- data/vendor/libgit2/src/clone.c +94 -56
- data/vendor/libgit2/src/config_file.c +4 -4
- data/vendor/libgit2/src/diff.c +21 -0
- data/vendor/libgit2/src/diff_file.c +1 -0
- data/vendor/libgit2/src/diff_print.c +11 -9
- data/vendor/libgit2/src/diff_tform.c +3 -1
- data/vendor/libgit2/src/errors.c +9 -7
- data/vendor/libgit2/src/fileops.c +5 -3
- data/vendor/libgit2/src/global.c +9 -1
- data/vendor/libgit2/src/global.h +1 -0
- data/vendor/libgit2/src/graph.c +2 -2
- data/vendor/libgit2/src/indexer.c +6 -1
- data/vendor/libgit2/src/merge.c +98 -144
- data/vendor/libgit2/src/merge.h +1 -1
- data/vendor/libgit2/src/netops.c +4 -0
- data/vendor/libgit2/src/oid.c +8 -0
- data/vendor/libgit2/src/oid.h +11 -0
- data/vendor/libgit2/src/oidarray.c +21 -0
- data/vendor/libgit2/src/oidarray.h +18 -0
- data/vendor/libgit2/src/pack.c +1 -4
- data/vendor/libgit2/src/path.c +93 -33
- data/vendor/libgit2/src/path.h +21 -0
- data/vendor/libgit2/src/pool.c +1 -1
- data/vendor/libgit2/src/posix.h +46 -28
- data/vendor/libgit2/src/refs.h +2 -2
- data/vendor/libgit2/src/refspec.c +54 -18
- data/vendor/libgit2/src/remote.c +31 -8
- data/vendor/libgit2/src/remote.h +3 -0
- data/vendor/libgit2/src/repository.c +27 -11
- data/vendor/libgit2/src/revert.c +4 -6
- data/vendor/libgit2/src/revparse.c +15 -18
- data/vendor/libgit2/src/revwalk.c +0 -3
- data/vendor/libgit2/src/signature.c +2 -2
- data/vendor/libgit2/src/stash.c +2 -1
- data/vendor/libgit2/src/status.c +11 -2
- data/vendor/libgit2/src/strnlen.h +2 -1
- data/vendor/libgit2/src/submodule.c +73 -33
- data/vendor/libgit2/src/thread-utils.h +0 -7
- data/vendor/libgit2/src/trace.h +9 -1
- data/vendor/libgit2/src/transport.c +93 -90
- data/vendor/libgit2/src/transports/auth.c +71 -0
- data/vendor/libgit2/src/transports/auth.h +63 -0
- data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
- data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
- data/vendor/libgit2/src/transports/cred.c +58 -0
- data/vendor/libgit2/src/transports/cred.h +14 -0
- data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
- data/vendor/libgit2/src/transports/git.c +1 -0
- data/vendor/libgit2/src/transports/http.c +168 -76
- data/vendor/libgit2/src/transports/smart.h +1 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +4 -2
- data/vendor/libgit2/src/transports/ssh.c +214 -38
- data/vendor/libgit2/src/transports/winhttp.c +26 -6
- data/vendor/libgit2/src/unix/posix.h +23 -9
- data/vendor/libgit2/src/unix/realpath.c +8 -7
- data/vendor/libgit2/src/util.c +2 -1
- data/vendor/libgit2/src/util.h +3 -3
- data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
- data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
- data/vendor/libgit2/src/win32/posix.h +20 -31
- data/vendor/libgit2/src/win32/posix_w32.c +33 -4
- metadata +81 -69
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
412
|
-
|
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
|
-
|
428
|
-
|
429
|
-
|
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
|
-
|
432
|
-
|
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 (
|
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
|
-
|
494
|
+
if ((error = _git_ssh_session_create(&session, s->socket)) < 0)
|
495
|
+
goto on_error;
|
443
496
|
|
444
|
-
if (
|
497
|
+
if ((error = list_auth_methods(&auth_methods, session, user)) < 0)
|
445
498
|
goto on_error;
|
446
499
|
|
447
|
-
|
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
|
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
|
-
|
495
|
-
return -1;
|
577
|
+
const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack;
|
496
578
|
|
497
|
-
return
|
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
|
-
|
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
|
-
|
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
|
-
|
768
|
+
p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service);
|
749
769
|
else
|
750
|
-
|
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
|
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;
|