http_ntlm_wb: Handle auth for only a single request

Currently when the server responds with 401 on NTLM authenticated
connection (re-used) we consider it to have failed.  However this is
legitimate and may happen when for example IIS is set configured to
'authPersistSingleRequest' or when the request goes thru a proxy (with
'via' header).

Implemented by imploying an additional state once a connection is
re-used to indicate that if we receive 401 we need to restart
authentication.

Missed in fe6049f0.
This commit is contained in:
Steve Holme 2019-05-18 17:30:16 +01:00
Родитель 2697d63363
Коммит 7ca7f82ba7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4059CB85CA7E8F19
1 изменённых файлов: 11 добавлений и 3 удалений

Просмотреть файл

@ -356,7 +356,11 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
*state = NTLMSTATE_TYPE2; /* We got a type-2 message */ *state = NTLMSTATE_TYPE2; /* We got a type-2 message */
} }
else { else {
if(*state == NTLMSTATE_TYPE3) { if(*state == NTLMSTATE_LAST) {
infof(conn->data, "NTLM auth restarted\n");
Curl_http_auth_cleanup_ntlm_wb(conn);
}
else if(*state == NTLMSTATE_TYPE3) {
infof(conn->data, "NTLM handshake rejected\n"); infof(conn->data, "NTLM handshake rejected\n");
Curl_http_auth_cleanup_ntlm_wb(conn); Curl_http_auth_cleanup_ntlm_wb(conn);
*state = NTLMSTATE_NONE; *state = NTLMSTATE_NONE;
@ -445,6 +449,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
conn->response_header = NULL; conn->response_header = NULL;
break; break;
case NTLMSTATE_TYPE2: case NTLMSTATE_TYPE2:
input = aprintf("TT %s\n", conn->challenge_header); input = aprintf("TT %s\n", conn->challenge_header);
if(!input) if(!input)
@ -466,11 +471,14 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
if(!*allocuserpwd) if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
break; break;
case NTLMSTATE_TYPE3: case NTLMSTATE_TYPE3:
/* connection is already authenticated, /* connection is already authenticated,
* don't send a header in future requests */ * don't send a header in future requests */
free(*allocuserpwd); *state = NTLMSTATE_LAST;
*allocuserpwd = NULL; /* FALLTHROUGH */
case NTLMSTATE_LAST:
Curl_safefree(*allocuserpwd);
authp->done = TRUE; authp->done = TRUE;
break; break;
} }