From: hno <> Date: Wed, 29 Aug 2007 04:35:29 +0000 (+0000) Subject: Bug #2057: NTLM stop work in messengers after upgrade to squid 2.6 stable 14 X-Git-Tag: SQUID_3_0_PRE7~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d3b341efba50621e1068e734ceb32c7cb9f2482;p=thirdparty%2Fsquid.git Bug #2057: NTLM stop work in messengers after upgrade to squid 2.6 stable 14 There is clients out there who only signal keep-alive during the NTLM handshake, not on the final request. For example seen on CONNECT requests. This patch makes Squid automatically fall back on Basic/Digest if NTLM or Negotiate authentication can not be performed. Detected by seeing a challenge from the helper on a non-persistent connection. --- diff --git a/src/AuthUserRequest.cc b/src/AuthUserRequest.cc index 8c30b259c1..51204796be 100644 --- a/src/AuthUserRequest.cc +++ b/src/AuthUserRequest.cc @@ -1,6 +1,6 @@ /* - * $Id: AuthUserRequest.cc,v 1.16 2007/05/09 09:07:38 wessels Exp $ + * $Id: AuthUserRequest.cc,v 1.17 2007/08/28 22:35:29 hno Exp $ * * DO NOT MODIFY NEXT 2 LINES: * arch-tag: 6803fde1-d5a2-4c29-9034-1c0c9f650eb4 @@ -586,7 +586,7 @@ AuthUserRequest::addReplyAuthHeader(HttpReply * rep, AuthUserRequest * auth_user /* this is a authenticate-needed response */ { - if ((auth_user_request != NULL) && !authenticateUserAuthenticated(auth_user_request)) + if ((auth_user_request != NULL) && authenticateDirection(auth_user_request) == 1) /* scheme specific */ auth_user_request->user()->config->fixHeader(auth_user_request, rep, type, request); else diff --git a/src/auth/negotiate/auth_negotiate.cc b/src/auth/negotiate/auth_negotiate.cc index ca79edaccd..575f225e05 100644 --- a/src/auth/negotiate/auth_negotiate.cc +++ b/src/auth/negotiate/auth_negotiate.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_negotiate.cc,v 1.25 2007/08/27 12:50:46 hno Exp $ + * $Id: auth_negotiate.cc,v 1.26 2007/08/28 22:35:29 hno Exp $ * * DEBUG: section 29 Negotiate Authenticator * AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli @@ -345,7 +345,6 @@ AuthNegotiateConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *re /* we're waiting for a response from the client. Pass it the blob */ debugs(29, 9, "AuthNegotiateConfig::fixHeader: Sending type:" << type << " header: 'Negotiate " << negotiate_request->server_blob << "'"); httpHeaderPutStrf(&rep->header, type, "Negotiate %s", negotiate_request->server_blob); - request->flags.must_keepalive = 1; safe_free(negotiate_request->server_blob); break; @@ -425,21 +424,21 @@ authenticateNegotiateHandleReply(void *data, void *lastserver, char *reply) if (strncasecmp(reply, "TT ", 3) == 0) { /* we have been given a blob to send to the client */ - if (arg) *arg++ = '\0'; - safe_free(negotiate_request->server_blob); - - negotiate_request->server_blob = xstrdup(blob); - - negotiate_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS; - - auth_user_request->denyMessage("Authentication in progress"); - - debugs(29, 4, "authenticateNegotiateHandleReply: Need to challenge the client with a server blob '" << blob << "'"); - - result = S_HELPER_RESERVE; + negotiate_request->request->flags.must_keepalive = 1; + if (negotiate_request->request->flags.proxy_keepalive) { + negotiate_request->server_blob = xstrdup(blob); + negotiate_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS; + auth_user_request->denyMessage("Authentication in progress"); + debugs(29, 4, "authenticateNegotiateHandleReply: Need to challenge the client with a server blob '" << blob << "'"); + result = S_HELPER_RESERVE; + } else { + negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; + auth_user_request->denyMessage("NTLM authentication requires a persistent connection"); + result = S_HELPER_RELEASE; + } } else if (strncasecmp(reply, "AF ", 3) == 0 && arg != NULL) { /* we're finished, release the helper */ @@ -525,6 +524,10 @@ authenticateNegotiateHandleReply(void *data, void *lastserver, char *reply) fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } + if (negotiate_request->request) { + HTTPMSGUNLOCK(negotiate_request->request); + negotiate_request->request = NULL; + } r->handler(r->data, NULL); cbdataReferenceDone(r->data); authenticateStateFree(r); @@ -680,13 +683,6 @@ AuthNegotiateUserRequest::authenticate(HttpRequest * request, ConnStateData::Poi return; } - if (!request->flags.proxy_keepalive) { - debugs(29, 2, "AuthNegotiateUserRequest::authenticate: attempt to perform authentication without a persistent connection!"); - auth_state = AUTHENTICATE_STATE_FAILED; - request->flags.must_keepalive = 1; - return; - } - if (waiting) { debugs(29, 1, "AuthNegotiateUserRequest::authenticate: waiting for helper reply!"); return; @@ -726,6 +722,8 @@ AuthNegotiateUserRequest::authenticate(HttpRequest * request, ConnStateData::Poi assert(conn->auth_user_request == NULL); conn->auth_user_request = this; AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn"); + this->request = request; + HTTPMSGLOCK(this->request); return; break; @@ -745,6 +743,10 @@ AuthNegotiateUserRequest::authenticate(HttpRequest * request, ConnStateData::Poi client_blob = xstrdup (blob); + if (this->request) + HTTPMSGUNLOCK(this->request); + this->request = request; + HTTPMSGLOCK(this->request); return; break; @@ -786,6 +788,10 @@ AuthNegotiateUserRequest::~AuthNegotiateUserRequest() helperStatefulReleaseServer(authserver); authserver = NULL; } + if (request) { + HTTPMSGUNLOCK(request); + request = NULL; + } } void diff --git a/src/auth/negotiate/auth_negotiate.h b/src/auth/negotiate/auth_negotiate.h index 035679520f..e8b2939420 100644 --- a/src/auth/negotiate/auth_negotiate.h +++ b/src/auth/negotiate/auth_negotiate.h @@ -89,6 +89,9 @@ public: /* currently waiting for helper response */ unsigned char waiting; + /* need access to the request flags to mess around on pconn failure */ + HttpRequest *request; + private: /* the user */ NegotiateUser * _theUser; diff --git a/src/auth/ntlm/auth_ntlm.cc b/src/auth/ntlm/auth_ntlm.cc index 3c368c3c99..4cbf3ab5e1 100644 --- a/src/auth/ntlm/auth_ntlm.cc +++ b/src/auth/ntlm/auth_ntlm.cc @@ -1,6 +1,6 @@ /* - * $Id: auth_ntlm.cc,v 1.75 2007/08/27 12:50:47 hno Exp $ + * $Id: auth_ntlm.cc,v 1.76 2007/08/28 22:35:29 hno Exp $ * * DEBUG: section 29 NTLM Authenticator * AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli @@ -313,7 +313,6 @@ AuthNTLMConfig::fixHeader(AuthUserRequest *auth_user_request, HttpReply *rep, ht /* we're waiting for a response from the client. Pass it the blob */ debugs(29, 9, "AuthNTLMConfig::fixHeader: Sending type:" << type << " header: 'NTLM " << ntlm_request->server_blob << "'"); httpHeaderPutStrf(&rep->header, type, "NTLM %s", ntlm_request->server_blob); - request->flags.must_keepalive = 1; safe_free(ntlm_request->server_blob); break; @@ -390,11 +389,18 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) if (strncasecmp(reply, "TT ", 3) == 0) { /* we have been given a blob to send to the client */ safe_free(ntlm_request->server_blob); - ntlm_request->server_blob = xstrdup(blob); - ntlm_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS; - auth_user_request->denyMessage("Authentication in progress"); - debugs(29, 4, "authenticateNTLMHandleReply: Need to challenge the client with a server blob '" << blob << "'"); - result = S_HELPER_RESERVE; + ntlm_request->request->flags.must_keepalive = 1; + if (ntlm_request->request->flags.proxy_keepalive) { + ntlm_request->server_blob = xstrdup(blob); + ntlm_request->auth_state = AUTHENTICATE_STATE_IN_PROGRESS; + auth_user_request->denyMessage("Authentication in progress"); + debugs(29, 4, "authenticateNTLMHandleReply: Need to challenge the client with a server blob '" << blob << "'"); + result = S_HELPER_RESERVE; + } else { + ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; + auth_user_request->denyMessage("NTLM authentication requires a persistent connection"); + result = S_HELPER_RELEASE; + } } else if (strncasecmp(reply, "AF ", 3) == 0) { /* we're finished, release the helper */ ntlm_user->username(blob); @@ -454,6 +460,10 @@ authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } + if (ntlm_request->request) { + HTTPMSGUNLOCK(ntlm_request->request); + ntlm_request->request = NULL; + } r->handler(r->data, NULL); cbdataReferenceDone(r->data); authenticateStateFree(r); @@ -609,13 +619,6 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer return; } - if (!request->flags.proxy_keepalive) { - debugs(29, 2, "AuthNTLMUserRequest::authenticate: attempt to perform authentication without a persistent connection!"); - auth_state = AUTHENTICATE_STATE_FAILED; - request->flags.must_keepalive = 1; - return; - } - if (waiting) { debugs(29, 1, "AuthNTLMUserRequest::authenticate: waiting for helper reply!"); return; @@ -656,6 +659,8 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer assert(conn->auth_user_request == NULL); conn->auth_user_request = this; AUTHUSERREQUESTLOCK(conn->auth_user_request, "conn"); + this->request = request; + HTTPMSGLOCK(this->request); return; break; @@ -675,6 +680,10 @@ AuthNTLMUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointer client_blob = xstrdup (blob); + if (this->request) + HTTPMSGUNLOCK(this->request); + this->request = request; + HTTPMSGLOCK(this->request); return; break; @@ -716,6 +725,10 @@ AuthNTLMUserRequest::~AuthNTLMUserRequest() helperStatefulReleaseServer(authserver); authserver = NULL; } + if (request) { + HTTPMSGUNLOCK(request); + request = NULL; + } } void diff --git a/src/auth/ntlm/auth_ntlm.h b/src/auth/ntlm/auth_ntlm.h index f4454f2780..227b2527f2 100644 --- a/src/auth/ntlm/auth_ntlm.h +++ b/src/auth/ntlm/auth_ntlm.h @@ -87,6 +87,9 @@ public: /* currently waiting for helper response */ unsigned char waiting; + /* need access to the request flags to mess around on pconn failure */ + HttpRequest *request; + private: /* the user */ NTLMUser * _theUser;