--------------------- PatchSet 11591 Date: 2007/08/28 22:39:10 Author: hno Branch: HEAD Tag: (none) Log: MFC: 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. Members: src/auth/negotiate/auth_negotiate.c:1.11->1.12 src/auth/negotiate/auth_negotiate.h:1.2->1.3 src/auth/ntlm/auth_ntlm.c:1.41->1.42 src/auth/ntlm/auth_ntlm.h:1.11->1.12 Index: squid/src/auth/negotiate/auth_negotiate.c =================================================================== RCS file: /cvsroot/squid/squid/src/auth/negotiate/auth_negotiate.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- squid/src/auth/negotiate/auth_negotiate.c 27 Aug 2007 12:51:43 -0000 1.11 +++ squid/src/auth/negotiate/auth_negotiate.c 28 Aug 2007 22:39:10 -0000 1.12 @@ -1,6 +1,6 @@ /* - * $Id: auth_negotiate.c,v 1.11 2007/08/27 12:51:43 hno Exp $ + * $Id: auth_negotiate.c,v 1.12 2007/08/28 22:39:10 hno Exp $ * * DEBUG: section 29 Negotiate Authenticator * AUTHOR: Robert Collins @@ -334,7 +334,6 @@ debug(29, 9) ("authenticateNegotiateFixErrorHeader: Sending type:%d header: 'Negotiate %s'\n", type, negotiate_request->server_blob); httpHeaderPutStrf(&rep->header, type, "Negotiate %s", negotiate_request->server_blob); safe_free(negotiate_request->server_blob); - request->flags.must_keepalive = 1; break; case AUTHENTICATE_STATE_DONE: /* Special case when authentication finished, but not allowed by ACL */ @@ -383,6 +382,10 @@ debug(29, 9) ("authenticateNegotiateRequestFree: releasing server '%p'\n", negotiate_request->authserver); authenticateNegotiateReleaseServer(negotiate_request); } + if (negotiate_request->request) { + requestUnlink(negotiate_request->request); + negotiate_request->request = NULL; + } memPoolFree(negotiate_request_pool, negotiate_request); } @@ -478,11 +481,18 @@ if (arg) *arg++ = '\0'; safe_free(negotiate_request->server_blob); - negotiate_request->server_blob = xstrdup(blob); - negotiate_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE; - safe_free(auth_user_request->message); - auth_user_request->message = xstrdup("Authentication in progress"); - debug(29, 4) ("authenticateNegotiateHandleReply: Need to challenge the client with a server blob '%s'\n", blob); + 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_NEGOTIATE; + safe_free(auth_user_request->message); + auth_user_request->message = xstrdup("Authentication in progress"); + debug(29, 4) ("authenticateNegotiateHandleReply: Need to challenge the client with a server blob '%s'\n", blob); + } else { + negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; + safe_free(auth_user_request->message); + auth_user_request->message = xstrdup("NTLM authentication requires a persistent connection"); + } } else if (strncasecmp(reply, "AF ", 3) == 0 && arg != NULL) { auth_user_hash_pointer *usernamehash; /* we're finished, release the helper */ @@ -544,6 +554,8 @@ } else { fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } + requestUnlink(negotiate_request->request); + negotiate_request->request = NULL; r->handler(r->data, NULL); cbdataUnlock(r->data); authenticateStateFree(r); @@ -702,12 +714,6 @@ debug(29, 1) ("authenticateNegotiateAuthenticateUser: attempt to perform authentication without a connection!\n"); return; } - if (!request->flags.proxy_keepalive) { - debug(29, 2) ("authenticateNegotiateAuthenticateUser: attempt to perform authentication without a persistent connection!\n"); - negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; - request->flags.must_keepalive = 1; - return; - } if (negotiate_request->waiting) { debug(29, 1) ("authenticateNegotiateAuthenticateUser: waiting for helper reply!\n"); return; @@ -739,6 +745,7 @@ /* and lock for the connection duration */ debug(29, 9) ("authenticateNegotiateAuthenticateUser: Locking auth_user from the connection.\n"); authenticateAuthUserRequestLock(auth_user_request); + negotiate_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_INITIAL: @@ -754,6 +761,9 @@ * details. */ safe_free(negotiate_request->client_blob); negotiate_request->client_blob = xstrdup(blob); + if (negotiate_request->request) + requestUnlink(negotiate_request->request); + negotiate_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_DONE: Index: squid/src/auth/negotiate/auth_negotiate.h =================================================================== RCS file: /cvsroot/squid/squid/src/auth/negotiate/auth_negotiate.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- squid/src/auth/negotiate/auth_negotiate.h 27 Feb 2007 22:39:50 -0000 1.2 +++ squid/src/auth/negotiate/auth_negotiate.h 28 Aug 2007 22:39:10 -0000 1.3 @@ -41,6 +41,8 @@ char *server_blob; /* our current blob to pass to the server */ char *client_blob; + /* the HTTP request */ + request_t *request; }; /* configuration runtime data */ Index: squid/src/auth/ntlm/auth_ntlm.c =================================================================== RCS file: /cvsroot/squid/squid/src/auth/ntlm/auth_ntlm.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -r1.41 -r1.42 --- squid/src/auth/ntlm/auth_ntlm.c 27 Aug 2007 12:51:44 -0000 1.41 +++ squid/src/auth/ntlm/auth_ntlm.c 28 Aug 2007 22:39:10 -0000 1.42 @@ -1,6 +1,6 @@ /* - * $Id: auth_ntlm.c,v 1.41 2007/08/27 12:51:44 hno Exp $ + * $Id: auth_ntlm.c,v 1.42 2007/08/28 22:39:10 hno Exp $ * * DEBUG: section 29 NTLM Authenticator * AUTHOR: Robert Collins @@ -332,7 +332,6 @@ debug(29, 9) ("authenticateNTLMFixErrorHeader: Sending type:%d header: 'NTLM %s'\n", type, ntlm_request->server_blob); httpHeaderPutStrf(&rep->header, type, "NTLM %s", ntlm_request->server_blob); safe_free(ntlm_request->server_blob); - request->flags.must_keepalive = 1; break; case AUTHENTICATE_STATE_DONE: /* Special case when authentication finished, but not allowed by ACL */ @@ -356,6 +355,10 @@ debug(29, 9) ("authenticateNTLMRequestFree: releasing server '%p'\n", ntlm_request->authserver); authenticateNTLMReleaseServer(ntlm_request); } + if (ntlm_request->request) { + requestUnlink(ntlm_request->request); + ntlm_request->request = NULL; + } memPoolFree(ntlm_request_pool, ntlm_request); } @@ -445,11 +448,18 @@ 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_NEGOTIATE; - safe_free(auth_user_request->message); - auth_user_request->message = xstrdup("Authentication in progress"); - debug(29, 4) ("authenticateNTLMHandleReply: Need to challenge the client with a server blob '%s'\n", blob); + 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_NEGOTIATE; + safe_free(auth_user_request->message); + auth_user_request->message = xstrdup("Authentication in progress"); + debug(29, 4) ("authenticateNTLMHandleReply: Need to challenge the client with a server blob '%s'\n", blob); + } else { + ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; + safe_free(auth_user_request->message); + auth_user_request->message = xstrdup("NTLM authentication requires a persistent connection"); + } } else if (strncasecmp(reply, "AF ", 3) == 0) { auth_user_hash_pointer *usernamehash; /* we're finished, release the helper */ @@ -503,6 +513,8 @@ } else { fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } + requestUnlink(ntlm_request->request); + ntlm_request->request = NULL; r->handler(r->data, NULL); cbdataUnlock(r->data); authenticateStateFree(r); @@ -661,12 +673,6 @@ debug(29, 1) ("authenticateNTLMAuthenticateUser: attempt to perform authentication without a connection!\n"); return; } - if (!request->flags.proxy_keepalive) { - debug(29, 2) ("authenticateNTLMAuthenticateUser: attempt to perform authentication without a persistent connection!\n"); - ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; - request->flags.must_keepalive = 1; - return; - } if (ntlm_request->waiting) { debug(29, 1) ("authenticateNTLMAuthenticateUser: waiting for helper reply!\n"); return; @@ -698,6 +704,7 @@ /* and lock for the connection duration */ debug(29, 9) ("authenticateNTLMAuthenticateUser: Locking auth_user from the connection.\n"); authenticateAuthUserRequestLock(auth_user_request); + ntlm_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_INITIAL: @@ -713,6 +720,9 @@ * details. */ safe_free(ntlm_request->client_blob); ntlm_request->client_blob = xstrdup(blob); + if (ntlm_request->request) + requestUnlink(ntlm_request->request); + ntlm_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_DONE: Index: squid/src/auth/ntlm/auth_ntlm.h =================================================================== RCS file: /cvsroot/squid/squid/src/auth/ntlm/auth_ntlm.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- squid/src/auth/ntlm/auth_ntlm.h 27 Feb 2007 22:39:50 -0000 1.11 +++ squid/src/auth/ntlm/auth_ntlm.h 28 Aug 2007 22:39:10 -0000 1.12 @@ -41,6 +41,8 @@ char *server_blob; /* our current blob to pass to the server */ char *client_blob; + /* the HTTP request */ + request_t *request; }; /* configuration runtime data */