mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
url: fix reuse of connections using HTTP Negotiate
Assume Negotiate means connection-based Reported-by: Zhicheng Chen Closes #20534
This commit is contained in:
parent
2d8284e4e8
commit
34fa034d9a
87
lib/url.c
87
lib/url.c
@ -764,6 +764,8 @@ struct url_conn_match {
|
||||
BIT(may_multiplex);
|
||||
BIT(want_ntlm_http);
|
||||
BIT(want_proxy_ntlm_http);
|
||||
BIT(want_nego_http);
|
||||
BIT(want_proxy_nego_http);
|
||||
|
||||
BIT(wait_pipe);
|
||||
BIT(force_reuse);
|
||||
@ -1185,6 +1187,63 @@ static bool url_match_auth_ntlm(struct connectdata *conn,
|
||||
#define url_match_auth_ntlm(c, m) ((void)c, (void)m, TRUE)
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
static bool url_match_auth_nego(struct connectdata *conn,
|
||||
struct url_conn_match *m)
|
||||
{
|
||||
/* If we are looking for an HTTP+Negotiate connection, check if this is
|
||||
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_timestrcmp(m->needle->user, conn->user) ||
|
||||
Curl_timestrcmp(m->needle->passwd, conn->passwd))
|
||||
return FALSE;
|
||||
}
|
||||
else if(conn->http_negotiate_state != GSS_AUTHNONE) {
|
||||
/* Connection is using Negotiate auth but we do not want Negotiate */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* Same for Proxy Negotiate authentication */
|
||||
if(m->want_proxy_nego_http) {
|
||||
/* Both conn->http_proxy.user and conn->http_proxy.passwd can be
|
||||
* NULL */
|
||||
if(!conn->http_proxy.user || !conn->http_proxy.passwd)
|
||||
return FALSE;
|
||||
|
||||
if(Curl_timestrcmp(m->needle->http_proxy.user,
|
||||
conn->http_proxy.user) ||
|
||||
Curl_timestrcmp(m->needle->http_proxy.passwd,
|
||||
conn->http_proxy.passwd))
|
||||
return FALSE;
|
||||
}
|
||||
else if(conn->proxy_negotiate_state != GSS_AUTHNONE) {
|
||||
/* Proxy connection is using Negotiate auth but we do not want Negotiate */
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
if(m->want_ntlm_http || m->want_proxy_ntlm_http) {
|
||||
/* Credentials are already checked, we may use this connection. We MUST
|
||||
* use a connection where it has already been fully negotiated. If it has
|
||||
* not, we keep on looking for a better one. */
|
||||
m->found = conn;
|
||||
if((m->want_nego_http &&
|
||||
(conn->http_negotiate_state != GSS_AUTHNONE)) ||
|
||||
(m->want_proxy_nego_http &&
|
||||
(conn->proxy_negotiate_state != GSS_AUTHNONE))) {
|
||||
/* We must use this connection, no other */
|
||||
m->force_reuse = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE; /* get another */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#define url_match_auth_nego(c, m) ((void)c, (void)m, TRUE)
|
||||
#endif
|
||||
|
||||
static bool url_match_conn(struct connectdata *conn, void *userdata)
|
||||
{
|
||||
struct url_conn_match *m = userdata;
|
||||
@ -1228,6 +1287,11 @@ static bool url_match_conn(struct connectdata *conn, void *userdata)
|
||||
else if(m->force_reuse)
|
||||
return TRUE;
|
||||
|
||||
if(!url_match_auth_nego(conn, m))
|
||||
return FALSE;
|
||||
else if(m->force_reuse)
|
||||
return TRUE;
|
||||
|
||||
if(!url_match_multiplex_limits(conn, m))
|
||||
return FALSE;
|
||||
|
||||
@ -1290,13 +1354,26 @@ static bool url_attach_existing(struct Curl_easy *data,
|
||||
match.may_multiplex = xfer_may_multiplex(data, needle);
|
||||
|
||||
#ifdef USE_NTLM
|
||||
match.want_ntlm_http = ((data->state.authhost.want & CURLAUTH_NTLM) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP));
|
||||
match.want_ntlm_http =
|
||||
(data->state.authhost.want & CURLAUTH_NTLM) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
match.want_proxy_ntlm_http =
|
||||
(needle->bits.proxy_user_passwd &&
|
||||
(data->state.authproxy.want & CURLAUTH_NTLM) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP));
|
||||
needle->bits.proxy_user_passwd &&
|
||||
(data->state.authproxy.want & CURLAUTH_NTLM) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
|
||||
match.want_nego_http =
|
||||
(data->state.authhost.want & CURLAUTH_NEGOTIATE) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
match.want_proxy_nego_http =
|
||||
needle->bits.proxy_user_passwd &&
|
||||
(data->state.authproxy.want & CURLAUTH_NEGOTIATE) &&
|
||||
(needle->scheme->protocol & PROTO_FAMILY_HTTP);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user