Commit af5fbb14 authored by Jay Satiro's avatar Jay Satiro
Browse files

digest_sspi: Handle 'stale=TRUE' directive in HTTP digest

- If the server has provided another challenge use it as the replacement
  input token if stale=TRUE. Otherwise previous credentials have failed
  so return CURLE_LOGIN_DENIED.

Prior to this change the stale directive was ignored and if another
challenge was received it would cause error CURLE_BAD_CONTENT_ENCODING.

Ref: https://tools.ietf.org/html/rfc2617#page-10

Bug: https://github.com/curl/curl/issues/928


Reported-by: default avatar <tarek112@users.noreply.github.com>
parent de1c1a8d
Loading
Loading
Loading
Loading
+36 −7
Original line number Diff line number Diff line
@@ -335,12 +335,43 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
{
  size_t chlglen = strlen(chlg);

  /* We had an input token before and we got another one now. This means we
     provided bad credentials in the previous request. */
  if(digest->input_token)
    return CURLE_BAD_CONTENT_ENCODING;
  /* We had an input token before so if there's another one now that means we
     provided bad credentials in the previous request or it's stale. */
  if(digest->input_token) {
    bool stale = false;
    const char *p = chlg;

    /* Check for the 'stale' directive */
    for(;;) {
      char value[DIGEST_MAX_VALUE_LENGTH];
      char content[DIGEST_MAX_CONTENT_LENGTH];

      while(*p && ISSPACE(*p))
        p++;

      if(!Curl_auth_digest_get_pair(p, value, content, &p))
        break;

      if(Curl_strcasecompare(value, "stale")
         && Curl_strcasecompare(content, "true")) {
        stale = true;
        break;
      }

  /* Simply store the challenge for use later */
      while(*p && ISSPACE(*p))
        p++;

      if(',' == *p)
        p++;
    }

    if(stale)
      Curl_auth_digest_cleanup(digest);
    else
      return CURLE_LOGIN_DENIED;
  }

  /* Store the challenge for use later */
  digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen + 1);
  if(!digest->input_token)
    return CURLE_OUT_OF_MEMORY;
@@ -552,8 +583,6 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
  if(!resp) {
    free(output_token);

    Curl_safefree(digest->http_context);

    return CURLE_OUT_OF_MEMORY;
  }