transports: add an `is_complete` function for auth Some authentication mechanisms (like HTTP Basic and Digest) have a one-step mechanism to create credentials, but there are more complex mechanisms like NTLM and Negotiate that require challenge/response after negotiation, requiring several round-trips. Add an `is_complete` function to know when they have round-tripped enough to be a single authentication and should now either have succeeded or failed to authenticate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
diff --git a/src/transports/auth.c b/src/transports/auth.c
index ea6cb65..849a6ce 100644
--- a/src/transports/auth.c
+++ b/src/transports/auth.c
@@ -52,6 +52,7 @@ static git_http_auth_context basic_context = {
GIT_CREDTYPE_USERPASS_PLAINTEXT,
NULL,
basic_next_token,
+ NULL,
NULL
};
diff --git a/src/transports/auth.h b/src/transports/auth.h
index 7b64770..9ead558 100644
--- a/src/transports/auth.h
+++ b/src/transports/auth.h
@@ -33,6 +33,9 @@ struct git_http_auth_context {
/** Gets the next authentication token from the context */
int (*next_token)(git_buf *out, git_http_auth_context *ctx, const char *header_name, git_cred *cred);
+ /** Examines if all tokens have been presented. */
+ int (*is_complete)(git_http_auth_context *ctx);
+
/** Frees the authentication context */
void (*free)(git_http_auth_context *ctx);
};
diff --git a/src/transports/auth_negotiate.c b/src/transports/auth_negotiate.c
index 03d3336..d5c3d16 100644
--- a/src/transports/auth_negotiate.c
+++ b/src/transports/auth_negotiate.c
@@ -170,6 +170,15 @@ done:
return error;
}
+static int negotiate_is_complete(git_http_auth_context *c)
+{
+ http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c;
+
+ assert(ctx);
+
+ return (ctx->complete == 1);
+}
+
static void negotiate_context_free(git_http_auth_context *c)
{
http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c;
@@ -266,6 +275,7 @@ int git_http_auth_negotiate(
ctx->parent.credtypes = GIT_CREDTYPE_DEFAULT;
ctx->parent.set_challenge = negotiate_set_challenge;
ctx->parent.next_token = negotiate_next_token;
+ ctx->parent.is_complete = negotiate_is_complete;
ctx->parent.free = negotiate_context_free;
*out = (git_http_auth_context *)ctx;