summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/http.c22
-rw-r--r--lib/http_negotiate.c32
-rw-r--r--lib/multi.c4
-rw-r--r--lib/urldata.h7
-rw-r--r--lib/vauth/spnego_gssapi.c1
-rw-r--r--lib/vauth/spnego_sspi.c1
6 files changed, 37 insertions, 30 deletions
diff --git a/lib/http.c b/lib/http.c
index 75d59ca90..222f7f53d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -494,8 +494,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
(data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
if(((expectsend - bytessent) < 2000) ||
- (conn->negotiate.state != GSS_AUTHNONE) ||
- (conn->proxyneg.state != GSS_AUTHNONE)) {
+ (conn->http_negotiate_state != GSS_AUTHNONE) ||
+ (conn->proxy_negotiate_state != GSS_AUTHNONE)) {
/* The NEGOTIATE-negotiation has started *OR*
there is just a little (<2K) data left to send, keep on sending. */
@@ -840,8 +840,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
struct Curl_easy *data = conn->data;
#ifdef USE_SPNEGO
- struct negotiatedata *negdata = proxy?
- &conn->proxyneg:&conn->negotiate;
+ curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
+ &conn->http_negotiate_state;
#endif
unsigned long *availp;
struct auth *authp;
@@ -888,7 +888,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE;
/* we received a GSS auth token and we dealt with it fine */
- negdata->state = GSS_AUTHRECV;
+ *negstate = GSS_AUTHRECV;
}
else
data->state.authproblem = TRUE;
@@ -3432,19 +3432,19 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
#if defined(USE_SPNEGO)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
- (conn->negotiate.state == GSS_AUTHRECV)) ||
+ (conn->http_negotiate_state == GSS_AUTHRECV)) ||
((data->req.httpcode == 407) &&
- (conn->proxyneg.state == GSS_AUTHRECV)))) {
+ (conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
- if((conn->negotiate.state == GSS_AUTHDONE) &&
+ if((conn->http_negotiate_state == GSS_AUTHDONE) &&
(data->req.httpcode != 401)) {
- conn->negotiate.state = GSS_AUTHSUCC;
+ conn->http_negotiate_state = GSS_AUTHSUCC;
}
- if((conn->proxyneg.state == GSS_AUTHDONE) &&
+ if((conn->proxy_negotiate_state == GSS_AUTHDONE) &&
(data->req.httpcode != 407)) {
- conn->proxyneg.state = GSS_AUTHSUCC;
+ conn->proxy_negotiate_state = GSS_AUTHSUCC;
}
#endif
/*
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 7930cf67b..c8f406444 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -49,6 +49,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
/* Point to the correct struct with this */
struct negotiatedata *neg_ctx;
+ curlnegotiate state;
if(proxy) {
userp = conn->http_proxy.user;
@@ -57,6 +58,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.host.name;
neg_ctx = &conn->proxyneg;
+ state = conn->proxy_negotiate_state;
}
else {
userp = conn->user;
@@ -65,6 +67,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->host.name;
neg_ctx = &conn->negotiate;
+ state = conn->http_negotiate_state;
}
/* Not set means empty */
@@ -82,11 +85,11 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
len = strlen(header);
neg_ctx->havenegdata = len != 0;
if(!len) {
- if(neg_ctx->state == GSS_AUTHSUCC) {
+ if(state == GSS_AUTHSUCC) {
infof(conn->data, "Negotiate auth restarted\n");
Curl_http_auth_cleanup_negotiate(conn);
}
- else if(neg_ctx->state != GSS_AUTHNONE) {
+ else if(state != GSS_AUTHNONE) {
/* The server rejected our authentication and hasn't supplied any more
negotiation mechanisms */
Curl_http_auth_cleanup_negotiate(conn);
@@ -104,7 +107,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
host, header, neg_ctx);
if(result)
- Curl_auth_cleanup_spnego(neg_ctx);
+ Curl_http_auth_cleanup_negotiate(conn);
return result;
}
@@ -115,6 +118,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
&conn->negotiate;
struct auth *authp = proxy ? &conn->data->state.authproxy :
&conn->data->state.authhost;
+ curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
+ &conn->http_negotiate_state;
char *base64 = NULL;
size_t len = 0;
char *userp;
@@ -122,24 +127,24 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
authp->done = FALSE;
- if(neg_ctx->state == GSS_AUTHRECV) {
+ if(*state == GSS_AUTHRECV) {
if(neg_ctx->havenegdata) {
neg_ctx->havemultiplerequests = TRUE;
}
}
- else if(neg_ctx->state == GSS_AUTHSUCC) {
+ else if(*state == GSS_AUTHSUCC) {
if(!neg_ctx->havenoauthpersist) {
neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests;
}
}
if(neg_ctx->noauthpersist ||
- (neg_ctx->state != GSS_AUTHDONE && neg_ctx->state != GSS_AUTHSUCC)) {
+ (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) {
- if(neg_ctx->noauthpersist && neg_ctx->state == GSS_AUTHSUCC) {
+ if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) {
infof(conn->data, "Curl_output_negotiate, "
"no persistent authentication: cleanup existing context");
- Curl_auth_cleanup_spnego(neg_ctx);
+ Curl_http_auth_cleanup_negotiate(conn);
}
if(!neg_ctx->context) {
result = Curl_input_negotiate(conn, proxy, "Negotiate");
@@ -176,23 +181,23 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
return CURLE_OUT_OF_MEMORY;
}
- neg_ctx->state = GSS_AUTHSENT;
+ *state = GSS_AUTHSENT;
#ifdef HAVE_GSSAPI
if(neg_ctx->status == GSS_S_COMPLETE ||
neg_ctx->status == GSS_S_CONTINUE_NEEDED) {
- neg_ctx->state = GSS_AUTHDONE;
+ *state = GSS_AUTHDONE;
}
#else
#ifdef USE_WINDOWS_SSPI
if(neg_ctx->status == SEC_E_OK ||
neg_ctx->status == SEC_I_CONTINUE_NEEDED) {
- neg_ctx->state = GSS_AUTHDONE;
+ *state = GSS_AUTHDONE;
}
#endif
#endif
}
- if(neg_ctx->state == GSS_AUTHDONE || neg_ctx->state == GSS_AUTHSUCC) {
+ if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) {
/* connection is already authenticated,
* don't send a header in future requests */
authp->done = TRUE;
@@ -205,6 +210,9 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
void Curl_http_auth_cleanup_negotiate(struct connectdata *conn)
{
+ conn->http_negotiate_state = GSS_AUTHNONE;
+ conn->proxy_negotiate_state = GSS_AUTHNONE;
+
Curl_auth_cleanup_spnego(&conn->negotiate);
Curl_auth_cleanup_spnego(&conn->proxyneg);
}
diff --git a/lib/multi.c b/lib/multi.c
index 39e521afd..d7970c7d5 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -592,8 +592,8 @@ static CURLcode multi_done(struct Curl_easy *data,
conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
#endif
#if defined(USE_SPNEGO)
- && !(conn->negotiate.state == GSS_AUTHRECV ||
- conn->proxyneg.state == GSS_AUTHRECV)
+ && !(conn->http_negotiate_state == GSS_AUTHRECV ||
+ conn->proxy_negotiate_state == GSS_AUTHRECV)
#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
diff --git a/lib/urldata.h b/lib/urldata.h
index fe54651b1..053d190fe 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -361,11 +361,9 @@ struct ntlmdata {
};
#endif
+/* Struct used for Negotiate (SPNEGO) authentication */
#ifdef USE_SPNEGO
struct negotiatedata {
- /* When doing Negotiate (SPNEGO) auth, we first need to send a token
- and then validate the received one. */
- curlnegotiate state;
#ifdef HAVE_GSSAPI
OM_uint32 status;
gss_ctx_id_t context;
@@ -985,6 +983,9 @@ struct connectdata {
#endif
#ifdef USE_SPNEGO
+ curlnegotiate http_negotiate_state;
+ curlnegotiate proxy_negotiate_state;
+
struct negotiatedata negotiate; /* state data for host Negotiate auth */
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
#endif
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index 1c324cf27..5d43e1100 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -273,7 +273,6 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
- nego->state = GSS_AUTHNONE;
nego->noauthpersist = FALSE;
nego->havenoauthpersist = FALSE;
nego->havenegdata = FALSE;
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index 2029c6b7a..4b21cc769 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -343,7 +343,6 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
nego->token_max = 0;
- nego->state = GSS_AUTHNONE;
nego->noauthpersist = FALSE;
nego->havenoauthpersist = FALSE;
nego->havenegdata = FALSE;