mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
HTTP: don't abort connections with pending Negotiate authentication
... similarly to how NTLM works as Negotiate is in fact often NTLM with another name.
This commit is contained in:
parent
557ca620e4
commit
5dc68dd609
106
lib/http.c
106
lib/http.c
@ -347,6 +347,82 @@ static bool pickoneauth(struct auth *pick)
|
||||
return picked;
|
||||
}
|
||||
|
||||
/* whether to complete request (for authentication) in current connection */
|
||||
static bool complete_request(struct connectdata *conn,
|
||||
curl_off_t remaining_bytes)
|
||||
{
|
||||
#if defined(USE_NTLM) || defined(USE_SPNEGO)
|
||||
struct SessionHandle *data = conn->data;
|
||||
bool have_ntlm_or_negotiate = FALSE;
|
||||
bool auth_started = FALSE;
|
||||
|
||||
/* don't reset connection when we're in NTLM or Negotiate authentication;
|
||||
* those authenticate the connection - creating a new connection breaks the
|
||||
* authentication.
|
||||
*/
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
/* proxy NTLM authentication */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authproxy.picked == CURLAUTH_NTLM_WB)) {
|
||||
have_ntlm_or_negotiate = TRUE;
|
||||
auth_started = auth_started
|
||||
|| (conn->proxyntlm.state != NTLMSTATE_NONE);
|
||||
}
|
||||
|
||||
/* normal NTLM authentication */
|
||||
if((data->state.authhost.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
|
||||
have_ntlm_or_negotiate = TRUE;
|
||||
auth_started = auth_started
|
||||
|| (conn->ntlm.state != NTLMSTATE_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPNEGO)
|
||||
/* proxy Negotiate authentication */
|
||||
if(data->state.authproxy.picked == CURLAUTH_NEGOTIATE) {
|
||||
have_ntlm_or_negotiate = TRUE;
|
||||
auth_started = auth_started
|
||||
|| (data->state.proxyneg.state != GSS_AUTHNONE);
|
||||
}
|
||||
|
||||
/* normal Negotiate authentication */
|
||||
if(data->state.authhost.picked == CURLAUTH_NEGOTIATE) {
|
||||
have_ntlm_or_negotiate = TRUE;
|
||||
auth_started = auth_started
|
||||
|| (data->state.negotiate.state != GSS_AUTHNONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(have_ntlm_or_negotiate) {
|
||||
if(remaining_bytes < 2000 || auth_started) {
|
||||
/* NTLM/Negotiation has started *OR* there is just a little (<2K)
|
||||
* data left to send, keep on sending.
|
||||
*/
|
||||
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
infof(data, "NTLM/Negotiate send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
remaining_bytes);
|
||||
}
|
||||
#else
|
||||
/* unused parameters: */
|
||||
(void)conn;
|
||||
(void)remaining_bytes;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_http_perhapsrewind()
|
||||
*
|
||||
@ -420,36 +496,12 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
conn->bits.rewindaftersend = FALSE; /* default */
|
||||
|
||||
if((expectsend == -1) || (expectsend > bytessent)) {
|
||||
#if defined(USE_NTLM)
|
||||
/* There is still data left to send */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->ntlm.state != NTLMSTATE_NONE) ||
|
||||
(conn->proxyntlm.state != NTLMSTATE_NONE)) {
|
||||
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
|
||||
data left to send, keep on sending. */
|
||||
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(conn->bits.close)
|
||||
/* this is already marked to get closed */
|
||||
return CURLE_OK;
|
||||
|
||||
infof(data, "NTLM send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
if(complete_request(conn, (curl_off_t)(expectsend - bytessent)))
|
||||
return CURLE_OK;
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
@ -460,7 +512,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(bytessent)
|
||||
/* we rewind now at once since if we already sent something */
|
||||
/* we rewind now at once since we already sent something */
|
||||
return Curl_readrewind(conn);
|
||||
|
||||
return CURLE_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user