]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #2057: NTLM stop work in messengers after upgrade to squid 2.6 stable 14
authorhno <>
Wed, 29 Aug 2007 04:35:29 +0000 (04:35 +0000)
committerhno <>
Wed, 29 Aug 2007 04:35:29 +0000 (04:35 +0000)
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.

src/AuthUserRequest.cc
src/auth/negotiate/auth_negotiate.cc
src/auth/negotiate/auth_negotiate.h
src/auth/ntlm/auth_ntlm.cc
src/auth/ntlm/auth_ntlm.h

index 8c30b259c1869b2abe7befa740c6b4939902485e..51204796be35aa9553cb479bd758403842765936 100644 (file)
@@ -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
index ca79edaccdd796efb64fb976f04bdc01c97a686b..575f225e052fcbe2bdcf2526cb63a7fb6abd8185 100644 (file)
@@ -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
index 035679520f9646554bb3a28113868c640526e9ee..e8b293942027a2267356db754d109a3648851a7d 100644 (file)
@@ -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;
index 3c368c3c99aa74a5825c4d267a994e13656303dd..4cbf3ab5e1fcdc4a7eb2ce63d1983169eda4cab0 100644 (file)
@@ -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
index f4454f2780821ce7058273d1cf6506fed3b411ab..227b2527f2754fcf2bf1e4f0bf29f61137eb4b9a 100644 (file)
@@ -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;