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);
#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;
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;
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