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;
|
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()
|
* Curl_http_perhapsrewind()
|
||||||
*
|
*
|
||||||
@ -420,36 +496,12 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
|||||||
conn->bits.rewindaftersend = FALSE; /* default */
|
conn->bits.rewindaftersend = FALSE; /* default */
|
||||||
|
|
||||||
if((expectsend == -1) || (expectsend > bytessent)) {
|
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)
|
if(conn->bits.close)
|
||||||
/* this is already marked to get closed */
|
/* this is already marked to get closed */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
infof(data, "NTLM send, close instead of sending %"
|
if(complete_request(conn, (curl_off_t)(expectsend - bytessent)))
|
||||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
return CURLE_OK;
|
||||||
(curl_off_t)(expectsend - bytessent));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is not NTLM or many bytes left to send: close */
|
/* This is not NTLM or many bytes left to send: close */
|
||||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||||
@ -460,7 +512,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(bytessent)
|
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 Curl_readrewind(conn);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
Loading…
Reference in New Issue
Block a user