disconnect: don't touch easy-related state on disconnects

This was done to make sure NTLM state that is bound to a connection
doesn't survive and gets used for the subsequent request - but
disconnects can also be done to for example make room in the connection
cache and thus that connection is not strictly related to the easy
handle's current operation.

The http authentication state is still kept in the easy handle since all
http auth _except_ NTLM is connection independent and thus survive over
multiple connections.

Bug: http://curl.haxx.se/mail/lib-2014-08/0148.html
Reported-by: Paras S
This commit is contained in:
Daniel Stenberg 2014-08-21 11:20:19 +02:00
parent a20da5523e
commit 898808fa8c
1 changed files with 25 additions and 27 deletions

View File

@ -2602,6 +2602,16 @@ static void conn_free(struct connectdata *conn)
free(conn); /* free all the connection oriented data */
}
/*
* Disconnects the given connection. Note the connection may not be the
* primary connection, like when freeing room in the connection cache or
* killing of a dead old connection.
*
* This function MUST NOT reset state in the SessionHandle struct if that
* isn't strictly bound to the life-time of *this* particular connection.
*
*/
CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
{
struct SessionHandle *data;
@ -2621,30 +2631,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
Curl_hostcache_prune(data); /* kill old DNS cache entries */
{
int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE);
int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE);
/* Authentication data is a mix of connection-related and sessionhandle-
related stuff. NTLM is connection-related so when we close the shop
we shall forget. */
if(has_host_ntlm) {
data->state.authhost.done = FALSE;
data->state.authhost.picked =
data->state.authhost.want;
}
if(has_proxy_ntlm) {
data->state.authproxy.done = FALSE;
data->state.authproxy.picked =
data->state.authproxy.want;
}
if(has_host_ntlm || has_proxy_ntlm)
data->state.authproblem = FALSE;
}
/* Cleanup NTLM connection-related data */
Curl_http_ntlm_cleanup(conn);
@ -2685,8 +2671,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
conn_free(conn);
Curl_speedinit(data);
return CURLE_OK;
}
@ -5617,6 +5601,21 @@ static CURLcode create_conn(struct SessionHandle *data,
*/
ConnectionStore(data, conn);
}
/* If NTLM is requested in a part of this connection, make sure we don't
assume the state is fine as this is a fresh connection and NTLM is
connection based. */
if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
data->state.authhost.done) {
infof(data, "NTLM picked AND auth done set, clear picked!\n");
data->state.authhost.picked = 0;
}
if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
data->state.authproxy.done) {
infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
data->state.authproxy.picked = 0;
}
}
/* Mark the connection as used */
@ -6031,4 +6030,3 @@ CURLcode Curl_do_more(struct connectdata *conn, int *complete)
return result;
}