url: fix reuse of connections using HTTP Negotiate
No binary (build failed)
—
(log yok)
| @@ -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 | |