mirror of
https://github.com/curl/curl.git
synced 2026-06-18 13:05:37 +03:00
url: connection credentials origin
When tying credentials to a connection (NTLM, Negotiate) also link the origin the credentials are for. This prevents a connection reuse with the same credentials, but intended for another origin. The mis-reuse could happen for a forwarding proxy and NTLM (although, in the mind of the person writing this, it is an insane setup). Closes #22040
This commit is contained in:
parent
c2b050e4e4
commit
bd10924b47
4 changed files with 28 additions and 14 deletions
|
|
@ -42,6 +42,7 @@ static void http_auth_nego_reset(struct connectdata *conn,
|
|||
conn->proxy_negotiate_state = GSS_AUTHNONE;
|
||||
else {
|
||||
conn->http_negotiate_state = GSS_AUTHNONE;
|
||||
Curl_peer_unlink(&conn->creds_origin);
|
||||
Curl_creds_unlink(&conn->creds);
|
||||
}
|
||||
if(neg_ctx)
|
||||
|
|
@ -132,13 +133,19 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
if(result)
|
||||
http_auth_nego_reset(conn, neg_ctx, proxy);
|
||||
|
||||
if(!proxy) {
|
||||
if(!result && !proxy) {
|
||||
/* Start it up. From this time onwards, the connection is tied
|
||||
* tp the credentials used. */
|
||||
if(conn->creds_origin &&
|
||||
!Curl_peer_equal(conn->creds_origin, data->state.origin)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
if(conn->creds && !Curl_creds_same(creds, conn->creds)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
Curl_peer_link(&conn->creds_origin, data->state.origin);
|
||||
Curl_creds_link(&conn->creds, creds);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data,
|
|||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(data, "NTLM handshake rejected");
|
||||
Curl_auth_ntlm_remove(conn, proxy);
|
||||
Curl_peer_unlink(&conn->creds_origin);
|
||||
Curl_creds_unlink(&conn->creds);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
|
@ -184,10 +186,16 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
if(!proxy) {
|
||||
/* Start it up. From this time onwards, the connection is tied
|
||||
* tp the credentials used. */
|
||||
if(conn->creds_origin &&
|
||||
!Curl_peer_equal(conn->creds_origin, data->state.origin)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
if(conn->creds && !Curl_creds_same(creds, conn->creds)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
Curl_peer_link(&conn->creds_origin, data->state.origin);
|
||||
Curl_creds_link(&conn->creds, creds);
|
||||
}
|
||||
result = Curl_auth_create_ntlm_type1_message(data, creds, "HTTP",
|
||||
|
|
|
|||
24
lib/url.c
24
lib/url.c
|
|
@ -515,6 +515,7 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn)
|
|||
Curl_creds_unlink(&conn->socks_proxy.creds);
|
||||
#endif
|
||||
Curl_creds_unlink(&conn->creds);
|
||||
Curl_peer_unlink(&conn->creds_origin);
|
||||
curlx_safefree(conn->options);
|
||||
curlx_safefree(conn->localdev);
|
||||
Curl_ssl_conn_config_cleanup(conn);
|
||||
|
|
@ -1011,18 +1012,11 @@ static bool url_match_auth_ntlm(struct connectdata *conn,
|
|||
possible. (Especially we must not reuse the same connection if
|
||||
partway through a handshake!) */
|
||||
if(m->want_ntlm_http) {
|
||||
if(!Curl_creds_same(m->data->state.creds, conn->creds)) {
|
||||
/* we prefer a credential match, but this is at least a connection
|
||||
that can be reused and "upgraded" to NTLM if it does
|
||||
not have any auth ongoing. */
|
||||
#ifdef USE_SPNEGO
|
||||
if((conn->http_ntlm_state == NTLMSTATE_NONE) &&
|
||||
(conn->http_negotiate_state == GSS_AUTHNONE)) {
|
||||
#else
|
||||
if(conn->http_ntlm_state == NTLMSTATE_NONE) {
|
||||
#endif
|
||||
m->found = conn;
|
||||
}
|
||||
if(conn->creds &&
|
||||
(!Curl_creds_same(conn->creds, m->data->state.creds) ||
|
||||
!Curl_peer_equal(conn->creds_origin, m->data->state.origin))) {
|
||||
/* connection credentials in play and not the same or not for the
|
||||
* same origin. */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1079,7 +1073,9 @@ static bool url_match_auth_nego(struct connectdata *conn,
|
|||
already authenticating with the right credentials. If not, keep looking
|
||||
so that we can reuse Negotiate connections if possible. */
|
||||
if(m->want_nego_http) {
|
||||
if(!Curl_creds_same(m->needle->creds, conn->creds))
|
||||
if(conn->creds &&
|
||||
(!Curl_creds_same(conn->creds, m->data->state.creds) ||
|
||||
!Curl_peer_equal(conn->creds_origin, m->data->state.origin)))
|
||||
return FALSE;
|
||||
}
|
||||
else if(conn->http_negotiate_state != GSS_AUTHNONE) {
|
||||
|
|
@ -1816,6 +1812,7 @@ static CURLcode url_set_conn_login(struct Curl_easy *data,
|
|||
{
|
||||
/* If our protocol needs a password and we have none, use the defaults */
|
||||
if((conn->scheme->flags & PROTOPT_NEEDSPWD) && !conn->creds) {
|
||||
Curl_peer_link(&conn->creds_origin, data->state.origin);
|
||||
if(data->state.creds)
|
||||
Curl_creds_link(&conn->creds, data->state.creds);
|
||||
else
|
||||
|
|
@ -1825,6 +1822,7 @@ static CURLcode url_set_conn_login(struct Curl_easy *data,
|
|||
else if(!(conn->scheme->flags & PROTOPT_CREDSPERREQUEST)) {
|
||||
/* for protocols that do not handle credentials per request,
|
||||
* the connection credentials are set by the initial transfer. */
|
||||
Curl_peer_link(&conn->creds_origin, data->state.origin);
|
||||
Curl_creds_link(&conn->creds, data->state.creds);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -301,6 +301,7 @@ struct connectdata {
|
|||
struct proxy_info http_proxy;
|
||||
#endif
|
||||
struct Curl_creds *creds; /* When connection itself is tied to credentials */
|
||||
struct Curl_peer *creds_origin; /* origin tied credentials are for */
|
||||
char *options; /* options string, allocated */
|
||||
struct curltime created; /* creation time */
|
||||
struct curltime lastused; /* when returned to the connection pool as idle */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue