diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/transports/cred.c | 27 | ||||
-rw-r--r-- | src/transports/winhttp.c | 28 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/transports/cred.c b/src/transports/cred.c index cc7fdab4b..05d2c8dc6 100644 --- a/src/transports/cred.c +++ b/src/transports/cred.c @@ -29,6 +29,10 @@ int git_cred_has_username(git_cred *cred) ret = !!c->username; break; } + case GIT_CREDTYPE_DEFAULT: { + ret = 0; + break; + } } return ret; @@ -115,6 +119,13 @@ static void ssh_custom_free(struct git_cred *cred) git__free(c); } +static void default_free(struct git_cred *cred) +{ + git_cred_default *c = (git_cred_default *)cred; + + git__free(c); +} + int git_cred_ssh_key_new( git_cred **cred, const char *username, @@ -191,3 +202,19 @@ int git_cred_ssh_custom_new( *cred = &c->parent; return 0; } + +int git_cred_default_new(git_cred **cred) +{ + git_cred_default *c; + + assert(cred); + + c = git__calloc(1, sizeof(git_cred_default)); + GITERR_CHECK_ALLOC(c); + + c->credtype = GIT_CREDTYPE_DEFAULT; + c->free = default_free; + + *cred = c; + return 0; +} diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index f7566458e..673cd0faf 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -52,6 +52,7 @@ static const int no_check_cert_flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | typedef enum { GIT_WINHTTP_AUTH_BASIC = 1, + GIT_WINHTTP_AUTH_NEGOTIATE = 2, } winhttp_authmechanism_t; typedef struct { @@ -138,6 +139,22 @@ on_error: return error; } +static int apply_default_credentials(HINTERNET request) +{ + /* If we are explicitly asked to deliver default credentials, turn set + * the security level to low which will guarantee they are delivered. + * The default is "medium" which applies to the intranet and sounds + * like it would correspond to Internet Explorer security zones, but + * in fact does not. + */ + DWORD data = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW; + + if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &data, sizeof(DWORD))) + return -1; + + return 0; +} + static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); @@ -317,6 +334,11 @@ static int winhttp_stream_connect(winhttp_stream *s) t->auth_mechanism == GIT_WINHTTP_AUTH_BASIC && apply_basic_credential(s->request, t->cred) < 0) goto on_error; + else if (t->cred && + t->cred->credtype == GIT_CREDTYPE_DEFAULT && + t->auth_mechanism == GIT_WINHTTP_AUTH_NEGOTIATE && + apply_default_credentials(s->request) < 0) + goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ @@ -361,6 +383,12 @@ static int parse_unauthorized_response( *auth_mechanism = GIT_WINHTTP_AUTH_BASIC; } + if ((WINHTTP_AUTH_SCHEME_NTLM & supported) || + (WINHTTP_AUTH_SCHEME_NEGOTIATE & supported)) { + *allowed_types |= GIT_CREDTYPE_DEFAULT; + *auth_mechanism = GIT_WINHTTP_AUTH_NEGOTIATE; + } + return 0; } |