Skip to content
Permalink
Browse files

http_negotiate: Move the Negotiate state out of the negotiatedata str…

…ucture

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

Closes #3882
  • Loading branch information...
captain-caveman2k committed May 13, 2019
1 parent 85bef18 commit e832d1ef74f260146cdab59cbac1d6969836663a
Showing with 37 additions and 30 deletions.
  1. +11 −11 lib/http.c
  2. +20 −12 lib/http_negotiate.c
  3. +2 −2 lib/multi.c
  4. +4 −3 lib/urldata.h
  5. +0 −1 lib/vauth/spnego_gssapi.c
  6. +0 −1 lib/vauth/spnego_sspi.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
/*
@@ -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,31 +118,33 @@ 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;
CURLcode result;

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

0 comments on commit e832d1e

Please sign in to comment.
You can’t perform that action at this time.