Unverified Commit e832d1ef authored by Steve Holme's avatar Steve Holme
Browse files

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
parent 85bef18c
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -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
      /*
+20 −12
Original line number Diff line number Diff line
@@ -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);
}
+2 −2
Original line number Diff line number Diff line
@@ -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))) {
+4 −3
Original line number Diff line number Diff line
@@ -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
+0 −1
Original line number Diff line number Diff line
@@ -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;
Loading