http_negotiate: Move the Negotiate state out of the negotiatedata structure

Given that this member variable is not used by the SASL based protocols
there is no need to have it here.

Closes #3882
This commit is contained in:
Steve Holme 2019-05-13 21:42:35 +01:00
parent 85bef18ca1
commit e832d1ef74
No known key found for this signature in database
GPG Key ID: 4059CB85CA7E8F19
6 changed files with 37 additions and 30 deletions

View File

@ -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
/*

View File

@ -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);
}

View File

@ -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))) {

View File

@ -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

View File

@ -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;

View File

@ -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;