Skip to content

Commit a2e6e0e

Browse files
committed
transport: allow cred/cert callbacks to return GIT_PASSTHROUGH
Allow credential and certificate checking callbacks to return GIT_PASSTHROUGH, indicating that they do not want to act. Introduce this to support in both the http and ssh callbacks. Additionally, enable the same mechanism for certificate validation. This is most useful to disambiguate any meaning in the publicly exposed credential and certificate functions (`git_transport_smart_credentials` and `git_transport_smart_certificate_check`) but it may be more generally useful for callers to be able to defer back to libgit2.
1 parent 8ee1009 commit a2e6e0e

File tree

5 files changed

+17
-6
lines changed

5 files changed

+17
-6
lines changed

include/git2/errors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ typedef enum {
5252
GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */
5353
GIT_EMERGECONFLICT = -24, /**< A merge conflict exists and cannot continue */
5454

55-
GIT_PASSTHROUGH = -30, /**< Internal only */
55+
GIT_PASSTHROUGH = -30, /**< A user-configured callback refused to act */
5656
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
5757
GIT_RETRY = -32, /**< Internal only */
5858
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */

include/git2/types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ typedef struct {
330330
* this certificate is valid
331331
* @param host Hostname of the host libgit2 connected to
332332
* @param payload Payload provided by the caller
333+
* @return 0 to proceed with the connection, < 0 to fail the connection
334+
* or > 0 to indicate that the callback refused to act and that
335+
* the existing validity determination should be honored
333336
*/
334337
typedef int (*git_transport_certificate_check_cb)(git_cert *cert, int valid, const char *host, void *payload);
335338

src/transports/http.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ static int on_headers_complete(http_parser *parser)
367367
allowed_auth_types,
368368
t->owner->cred_acquire_payload);
369369

370+
/* treat GIT_PASSTHROUGH as if callback isn't set */
370371
if (error == GIT_PASSTHROUGH) {
371372
no_callback = 1;
372373
} else if (error < 0) {
@@ -635,6 +636,9 @@ static int http_connect(http_subtransport *t)
635636
giterr_clear();
636637
error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload);
637638

639+
if (error == GIT_PASSTHROUGH)
640+
error = is_valid ? 0 : GIT_ECERTIFICATE;
641+
638642
if (error < 0) {
639643
if (!giterr_last())
640644
giterr_set(GITERR_NET, "user cancelled certificate check");

src/transports/ssh.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,11 @@ static int request_creds(git_cred **out, ssh_subtransport *t, const char *user,
447447
error = t->owner->cred_acquire_cb(&cred, t->owner->url, user, auth_methods,
448448
t->owner->cred_acquire_payload);
449449

450-
if (error == GIT_PASSTHROUGH)
450+
if (error == GIT_PASSTHROUGH) {
451451
no_callback = 1;
452-
else if (error < 0)
452+
} else if (error < 0) {
453453
return error;
454-
else if (!cred) {
454+
} else if (!cred) {
455455
giterr_set(GITERR_SSH, "callback failed to initialize SSH credentials");
456456
return -1;
457457
}
@@ -584,7 +584,8 @@ static int _git_ssh_setup_conn(
584584
cert_ptr = &cert;
585585

586586
error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, host, t->owner->message_cb_payload);
587-
if (error < 0) {
587+
588+
if (error < 0 && error != GIT_PASSTHROUGH) {
588589
if (!giterr_last())
589590
giterr_set(GITERR_NET, "user cancelled hostkey check");
590591

src/transports/winhttp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ static int fallback_cred_acquire_cb(
228228
}
229229

230230
hCoInitResult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
231-
231+
232232
if (SUCCEEDED(hCoInitResult) || hCoInitResult == RPC_E_CHANGED_MODE) {
233233
IInternetSecurityManager* pISM;
234234

@@ -295,6 +295,9 @@ static int certificate_check(winhttp_stream *s, int valid)
295295
error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->connection_data.host, t->owner->message_cb_payload);
296296
CertFreeCertificateContext(cert_ctx);
297297

298+
if (error == GIT_PASSTHROUGH)
299+
error = valid ? 0 : GIT_ECERTIFICATE;
300+
298301
if (error < 0 && !giterr_last())
299302
giterr_set(GITERR_NET, "user cancelled certificate check");
300303

0 commit comments

Comments
 (0)