From: Amos Jeffries Date: Sun, 8 May 2011 13:53:10 +0000 (+1200) Subject: Cleanup: sync NTLM and Negotiate UserRequest code X-Git-Tag: take07~16^2~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7afc3bf21fb00bef3e0cdc93145bcb4d2bf5a29f;p=thirdparty%2Fsquid.git Cleanup: sync NTLM and Negotiate UserRequest code Minor tweaks to reduce diff between the files. No logic changes. Renames the addHeader() to addAuthentiocationInfoHeader(), Renames the addTrailer() to addAuthentiocationInfoTrailer() and document that they add additional *-Info header to the HTTP reply. --- diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 6e1cd1c8f3..f5637e627a 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -221,11 +221,11 @@ AuthUserRequest::direction() } void -AuthUserRequest::addHeader(HttpReply * rep, int accelerated) +AuthUserRequest::addAuthenticationInfoHeader(HttpReply * rep, int accelerated) {} void -AuthUserRequest::addTrailer(HttpReply * rep, int accelerated) +AuthUserRequest::addAuthenticationInfoTrailer(HttpReply * rep, int accelerated) {} void @@ -527,13 +527,13 @@ AuthUserRequest::addReplyAuthHeader(HttpReply * rep, AuthUserRequest::Pointer au } } + /* * allow protocol specific headers to be _added_ to the existing - * response - ie digest auth + * response - currently Digest or Negotiate auth */ - if (auth_user_request != NULL) { - auth_user_request->addHeader(rep, accelerated); + auth_user_request->addAuthenticationInfoHeader(rep, accelerated); if (auth_user_request->lastReply != AUTH_AUTHENTICATED) auth_user_request->lastReply = AUTH_ACL_CANNOT_AUTHENTICATE; } @@ -545,13 +545,12 @@ authenticateFixHeader(HttpReply * rep, AuthUserRequest::Pointer auth_user_reques AuthUserRequest::addReplyAuthHeader(rep, auth_user_request, request, accelerated, internal); } - /* call the active auth module and allow it to add a trailer to the request */ void authenticateAddTrailer(HttpReply * rep, AuthUserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated) { if (auth_user_request != NULL) - auth_user_request->addTrailer(rep, accelerated); + auth_user_request->addAuthenticationInfoTrailer(rep, accelerated); } Auth::Scheme::Pointer diff --git a/src/auth/UserRequest.h b/src/auth/UserRequest.h index b585217a12..c81185c9e6 100644 --- a/src/auth/UserRequest.h +++ b/src/auth/UserRequest.h @@ -49,6 +49,12 @@ class ConnStateData; class HttpReply; class HttpRequest; +/** + * Maximum length (buffer size) for token strings. + */ +// AYJ: must match re-definition in helpers/negotiate_auth/kerberos/negotiate_kerb_auth.cc +#define MAX_AUTHTOKEN_LEN 32768 + /// \ingroup AuthAPI class AuthUserIP { @@ -128,18 +134,24 @@ public: bool valid() const; virtual void authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type) = 0; - /* template method */ + + /* template method - what needs to be done next? advertise schemes, challenge, handle error, nothing? */ virtual Auth::Direction module_direction() = 0; - virtual void addHeader(HttpReply * rep, int accel); - virtual void addTrailer(HttpReply * rep, int accel); + + /* add the [Proxy-]Authentication-Info header */ + virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); + + /* add the [Proxy-]Authentication-Info trailer */ + virtual void addAuthenticationInfoTrailer(HttpReply * rep, int accel); + virtual void onConnectionClose(ConnStateData *); /** * Called when squid is ready to put the request on hold and wait for a callback from the auth module * when the auth module has performed it's external activities. * - \param handler Handler to process the callback when its run - \param data CBDATA for handler + * \param handler Handler to process the callback when its run + * \param data CBDATA for handler */ virtual void module_start(RH *handler, void *data) = 0; diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index 245072b731..c52b76109f 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -190,9 +190,8 @@ AuthDigestUserRequest::module_direction() } } -/* add the [proxy]authorisation header */ void -AuthDigestUserRequest::addHeader(HttpReply * rep, int accel) +AuthDigestUserRequest::addAuthenticationInfoHeader(HttpReply * rep, int accel) { http_hdr_type type; @@ -218,9 +217,8 @@ AuthDigestUserRequest::addHeader(HttpReply * rep, int accel) } #if WAITING_FOR_TE -/** add the [proxy]authorisation header */ void -AuthDigestUserRequest::addTrailer(HttpReply * rep, int accel) +AuthDigestUserRequest::addAuthenticationInfoTrailer(HttpReply * rep, int accel) { int type; diff --git a/src/auth/digest/UserRequest.h b/src/auth/digest/UserRequest.h index c2416728bd..88bf96a3cc 100644 --- a/src/auth/digest/UserRequest.h +++ b/src/auth/digest/UserRequest.h @@ -24,10 +24,9 @@ public: virtual int authenticated() const; virtual void authenticate(HttpRequest * request, ConnStateData * conn, http_hdr_type type); virtual Auth::Direction module_direction(); - virtual void addHeader(HttpReply * rep, int accel); + virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); #if WAITING_FOR_TE - - virtual void addTrailer(HttpReply * rep, int accel); + virtual void addAuthenticationInfoTrailer(HttpReply * rep, int accel); #endif virtual void module_start(RH *, void *); diff --git a/src/auth/negotiate/UserRequest.cc b/src/auth/negotiate/UserRequest.cc index b50df9eaf9..68916cb4d7 100644 --- a/src/auth/negotiate/UserRequest.cc +++ b/src/auth/negotiate/UserRequest.cc @@ -8,12 +8,6 @@ #include "HttpRequest.h" #include "SquidTime.h" -/** - * Maximum length (buffer size) for token strings. - */ -// AYJ: must match re-definition in helpers/negotiate_auth/kerberos/negotiate_kerb_auth.cc -#define MAX_AUTHTOKEN_LEN 32768 - AuthNegotiateUserRequest::AuthNegotiateUserRequest() { waiting=0; @@ -29,11 +23,8 @@ AuthNegotiateUserRequest::~AuthNegotiateUserRequest() safe_free(server_blob); safe_free(client_blob); - if (authserver != NULL) { - debugs(29, 9, HERE << "releasing server '" << authserver << "'"); - helperStatefulReleaseServer(authserver); - authserver = NULL; - } + releaseAuthServer(); + if (request) { HTTPMSGUNLOCK(request); request = NULL; @@ -87,27 +78,6 @@ AuthNegotiateUserRequest::module_direction() } } -/* add the [proxy]authorisation header */ -void -AuthNegotiateUserRequest::addHeader(HttpReply * rep, int accel) -{ - http_hdr_type type; - - if (!server_blob) - return; - - /* don't add to authentication error pages */ - if ((!accel && rep->sline.status == HTTP_PROXY_AUTHENTICATION_REQUIRED) - || (accel && rep->sline.status == HTTP_UNAUTHORIZED)) - return; - - type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; - httpHeaderPutStrf(&rep->header, type, "Negotiate %s", server_blob); - - safe_free(server_blob); -} - -/** send the initial data to a stateful negotiate authenticator module */ void AuthNegotiateUserRequest::module_start(RH * handler, void *data) { @@ -119,23 +89,23 @@ AuthNegotiateUserRequest::module_start(RH * handler, void *data) assert(user() != NULL); assert(user()->auth_type == Auth::AUTH_NEGOTIATE); - debugs(29, 8, HERE << "auth state is '" << user()->credentials() << "'"); - if (static_cast(Auth::Config::Find("negotiate"))->authenticateProgram == NULL) { debugs(29, DBG_CRITICAL, "ERROR: No Negotiate authentication program configured."); handler(data, NULL); return; } + debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'"); + authenticateStateData *r = cbdataAlloc(authenticateStateData); r->handler = handler; r->data = cbdataReference(data); r->auth_user_request = this; if (user()->credentials() == Auth::Pending) { - snprintf(buf, MAX_AUTHTOKEN_LEN, "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here? + snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here? } else { - snprintf(buf, MAX_AUTHTOKEN_LEN, "KK %s\n", client_blob); + snprintf(buf, sizeof(buf), "KK %s\n", client_blob); } waiting = 1; @@ -175,7 +145,7 @@ AuthNegotiateUserRequest::onConnectionClose(ConnStateData *conn) releaseAuthServer(); /* unlock the connection based lock */ - debugs(29, 9, "AuthNegotiateUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << conn << "'."); + debugs(29, 9, HERE << "Unlocking auth_user from the connection '" << conn << "'."); conn->auth_user_request = NULL; } @@ -183,10 +153,12 @@ AuthNegotiateUserRequest::onConnectionClose(ConnStateData *conn) void AuthNegotiateUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, http_hdr_type type) { - assert (this); + assert(this); + + /* Check that we are in the client side, where we can generate + * auth challenges */ - /** Check that we are in the client side, where we can generate auth challenges */ - if (conn == NULL) { + if (conn == NULL || !cbdataReferenceValid(conn)) { user()->credentials(Auth::Failed); debugs(29, DBG_IMPORTANT, "WARNING: Negotiate Authentication attempt to perform authentication without a connection!"); return; @@ -257,8 +229,6 @@ AuthNegotiateUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * c debugs(29, 9, HERE << "auth state negotiate failed. " << proxy_auth); break; } - - return; } void @@ -287,20 +257,20 @@ AuthNegotiateUserRequest::HandleReply(void *data, void *lastserver, char *reply) AuthUserRequest::Pointer auth_user_request = r->auth_user_request; assert(auth_user_request != NULL); - AuthNegotiateUserRequest *negotiate_request = dynamic_cast(auth_user_request.getRaw()); - assert(negotiate_request != NULL); + AuthNegotiateUserRequest *lm_request = dynamic_cast(auth_user_request.getRaw()); + assert(lm_request != NULL); + assert(lm_request->waiting); - assert(negotiate_request->waiting); - negotiate_request->waiting = 0; - safe_free(negotiate_request->client_blob); + lm_request->waiting = 0; + safe_free(lm_request->client_blob); assert(auth_user_request->user() != NULL); assert(auth_user_request->user()->auth_type == Auth::AUTH_NEGOTIATE); - if (negotiate_request->authserver == NULL) - negotiate_request->authserver = static_cast(lastserver); + if (lm_request->authserver == NULL) + lm_request->authserver = static_cast(lastserver); else - assert(negotiate_request->authserver == lastserver); + assert(lm_request->authserver == lastserver); /* seperate out the useful data */ blob = strchr(reply, ' '); @@ -316,10 +286,10 @@ AuthNegotiateUserRequest::HandleReply(void *data, void *lastserver, char *reply) /* we have been given a blob to send to the client */ if (arg) *arg++ = '\0'; - safe_free(negotiate_request->server_blob); - negotiate_request->request->flags.must_keepalive = 1; - if (negotiate_request->request->flags.proxy_keepalive) { - negotiate_request->server_blob = xstrdup(blob); + safe_free(lm_request->server_blob); + lm_request->request->flags.must_keepalive = 1; + if (lm_request->request->flags.proxy_keepalive) { + lm_request->server_blob = xstrdup(blob); auth_user_request->user()->credentials(Auth::Handshake); auth_user_request->denyMessage("Authentication in progress"); debugs(29, 4, HERE << "Need to challenge the client with a server blob '" << blob << "'"); @@ -335,16 +305,16 @@ AuthNegotiateUserRequest::HandleReply(void *data, void *lastserver, char *reply) auth_user_request->user()->username(arg); auth_user_request->denyMessage("Login successful"); - safe_free(negotiate_request->server_blob); - negotiate_request->server_blob = xstrdup(blob); - negotiate_request->releaseAuthServer(); + safe_free(lm_request->server_blob); + lm_request->server_blob = xstrdup(blob); + lm_request->releaseAuthServer(); /* connection is authenticated */ debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username()); /* see if this is an existing user with a different proxy_auth * string */ AuthUserHashPointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->username())); - Auth::User::Pointer local_auth_user = negotiate_request->user(); + Auth::User::Pointer local_auth_user = lm_request->user(); while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NEGOTIATE || strcmp(usernamehash->user()->username(), auth_user_request->user()->username()) != 0)) usernamehash = static_cast(usernamehash->next); @@ -374,10 +344,10 @@ AuthNegotiateUserRequest::HandleReply(void *data, void *lastserver, char *reply) *arg++ = '\0'; auth_user_request->denyMessage(arg); - negotiate_request->user()->credentials(Auth::Failed); - safe_free(negotiate_request->server_blob); - negotiate_request->server_blob = xstrdup(blob); - negotiate_request->releaseAuthServer(); + auth_user_request->user()->credentials(Auth::Failed); + safe_free(lm_request->server_blob); + lm_request->server_blob = xstrdup(blob); + lm_request->releaseAuthServer(); debugs(29, 4, HERE << "Failed validating user via Negotiate. Error returned '" << blob << "'"); } else if (strncasecmp(reply, "BH ", 3) == 0) { /* TODO kick off a refresh process. This can occur after a YR or after @@ -387,17 +357,35 @@ AuthNegotiateUserRequest::HandleReply(void *data, void *lastserver, char *reply) * Needing YR. */ auth_user_request->denyMessage(blob); auth_user_request->user()->credentials(Auth::Failed); - safe_free(negotiate_request->server_blob); - negotiate_request->releaseAuthServer(); + safe_free(lm_request->server_blob); + lm_request->releaseAuthServer(); debugs(29, DBG_IMPORTANT, "ERROR: Negotiate Authentication validating user. Error returned '" << reply << "'"); } else { /* protocol error */ fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } - negotiate_request->request = NULL; + lm_request->request = NULL; r->handler(r->data, NULL); cbdataReferenceDone(r->data); authenticateStateFree(r); } +void +AuthNegotiateUserRequest::addAuthenticationInfoHeader(HttpReply * rep, int accel) +{ + http_hdr_type type; + + if (!server_blob) + return; + + /* don't add to authentication error pages */ + if ((!accel && rep->sline.status == HTTP_PROXY_AUTHENTICATION_REQUIRED) + || (accel && rep->sline.status == HTTP_UNAUTHORIZED)) + return; + + type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; + httpHeaderPutStrf(&rep->header, type, "Negotiate %s", server_blob); + + safe_free(server_blob); +} diff --git a/src/auth/negotiate/UserRequest.h b/src/auth/negotiate/UserRequest.h index f2d372df2f..c2fcd6c4b3 100644 --- a/src/auth/negotiate/UserRequest.h +++ b/src/auth/negotiate/UserRequest.h @@ -25,7 +25,7 @@ public: virtual void onConnectionClose(ConnStateData *); virtual void module_start(RH *, void *); - virtual void addHeader(HttpReply * rep, int accel); + virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); virtual const char * connLastHeader(); diff --git a/src/auth/ntlm/UserRequest.cc b/src/auth/ntlm/UserRequest.cc index b811357c95..960e395d7c 100644 --- a/src/auth/ntlm/UserRequest.cc +++ b/src/auth/ntlm/UserRequest.cc @@ -6,15 +6,13 @@ #include "HttpRequest.h" #include "SquidTime.h" -/* state wrapper functions */ - AuthNTLMUserRequest::AuthNTLMUserRequest() { waiting=0; client_blob=0; server_blob=0; authserver=NULL; - request = NULL; + request=NULL; } AuthNTLMUserRequest::~AuthNTLMUserRequest() @@ -37,6 +35,18 @@ AuthNTLMUserRequest::connLastHeader() return NULL; } +int +AuthNTLMUserRequest::authenticated() const +{ + if (user() != NULL && user()->credentials() == Auth::Ok) { + debugs(29, 9, HERE << "user authenticated."); + return 1; + } + + debugs(29, 9, HERE << "user not fully authenticated."); + return 0; +} + Auth::Direction AuthNTLMUserRequest::module_direction() { @@ -52,13 +62,13 @@ AuthNTLMUserRequest::module_direction() case Auth::Handshake: assert(server_blob); - return Auth::CRED_CHALLENGE; /* send to client */ + return Auth::CRED_CHALLENGE; case Auth::Ok: return Auth::CRED_VALID; case Auth::Failed: - return Auth::CRED_ERROR; // XXX really? not VALID or CHALLENGE? + return Auth::CRED_ERROR; // XXX: really? not VALID or CHALLENGE? default: debugs(29, DBG_IMPORTANT, "WARNING: NTLM Authentication in unexpected state: " << user()->credentials()); @@ -66,33 +76,31 @@ AuthNTLMUserRequest::module_direction() } } -/* send the initial data to a stateful ntlm authenticator module */ void AuthNTLMUserRequest::module_start(RH * handler, void *data) { - authenticateStateData *r = NULL; - static char buf[8192]; + static char buf[MAX_AUTHTOKEN_LEN]; assert(data); assert(handler); - debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'"); - if (static_cast(Auth::Config::Find("ntlm"))->authenticateProgram == NULL) { debugs(29, DBG_CRITICAL, "ERROR: NTLM Start: no NTLM program configured."); handler(data, NULL); return; } - r = cbdataAlloc(authenticateStateData); + debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'"); + + authenticateStateData *r = cbdataAlloc(authenticateStateData); r->handler = handler; r->data = cbdataReference(data); r->auth_user_request = this; if (user()->credentials() == Auth::Pending) { - snprintf(buf, 8192, "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here? + snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here? } else { - snprintf(buf, 8192, "KK %s\n", client_blob); + snprintf(buf, sizeof(buf), "KK %s\n", client_blob); } waiting = 1; @@ -128,33 +136,17 @@ AuthNTLMUserRequest::onConnectionClose(ConnStateData *conn) return; } - // unlock / un-reserve the helpers releaseAuthServer(); /* unlock the connection based lock */ - debugs(29, 9, "AuthNTLMUserRequest::onConnectionClose: Unlocking auth_user from the connection '" << conn << "'."); + debugs(29, 9, HERE << "Unlocking auth_user from the connection '" << conn << "'."); conn->auth_user_request = NULL; } -int -AuthNTLMUserRequest::authenticated() const -{ - if (user()->credentials() == Auth::Ok) { - debugs(29, 9, "AuthNTLMUserRequest::authenticated: user authenticated."); - return 1; - } - - debugs(29, 9, "AuthNTLMUserRequest::authenticated: user not fully authenticated."); - - return 0; -} - void AuthNTLMUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, http_hdr_type type) { - const char *proxy_auth, *blob; - assert(this); /* Check that we are in the client side, where we can generate @@ -162,25 +154,25 @@ AuthNTLMUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, if (conn == NULL || !cbdataReferenceValid(conn)) { user()->credentials(Auth::Failed); - debugs(29, 1, "AuthNTLMUserRequest::authenticate: attempt to perform authentication without a connection!"); + debugs(29, DBG_IMPORTANT, "WARNING: NTLM Authentication attempt to perform authentication without a connection!"); return; } if (waiting) { - debugs(29, 1, "AuthNTLMUserRequest::authenticate: waiting for helper reply!"); + debugs(29, DBG_IMPORTANT, "WARNING: NTLM Authentication waiting for helper reply!"); return; } if (server_blob) { - debugs(29, 2, "AuthNTLMUserRequest::authenticate: need to challenge client '" << server_blob << "'!"); + debugs(29, 2, HERE << "need to challenge client '" << server_blob << "'!"); return; } /* get header */ - proxy_auth = aRequest->header.getStr(type); + const char *proxy_auth = aRequest->header.getStr(type); /* locate second word */ - blob = proxy_auth; + const char *blob = proxy_auth; /* if proxy_auth is actually NULL, we'd better not manipulate it. */ if (blob) { @@ -198,7 +190,7 @@ AuthNTLMUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, case Auth::Unchecked: /* we've received a ntlm request. pass to a helper */ - debugs(29, 9, "AuthNTLMUserRequest::authenticate: auth state ntlm none. Received blob: '" << proxy_auth << "'"); + debugs(29, 9, HERE << "auth state ntlm none. Received blob: '" << proxy_auth << "'"); user()->credentials(Auth::Pending); safe_free(client_blob); client_blob=xstrdup(blob); @@ -209,15 +201,14 @@ AuthNTLMUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, break; case Auth::Pending: - debugs(29, 1, "AuthNTLMUserRequest::authenticate: need to ask helper"); + debugs(29, 1, HERE << "need to ask helper"); break; case Auth::Handshake: /* we should have received a blob from the client. Hand it off to * some helper */ safe_free(client_blob); - client_blob = xstrdup (blob); - + client_blob = xstrdup(blob); if (request) HTTPMSGUNLOCK(request); request = aRequest; @@ -230,7 +221,7 @@ AuthNTLMUserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, case Auth::Failed: /* we've failed somewhere in authentication */ - debugs(29, 9, "AuthNTLMUserRequest::authenticate: auth state ntlm failed. " << proxy_auth); + debugs(29, 9, HERE << "auth state ntlm failed. " << proxy_auth); break; } } @@ -243,37 +234,38 @@ AuthNTLMUserRequest::HandleReply(void *data, void *lastserver, char *reply) int valid; char *blob; - debugs(29, 8, "authenticateNTLMHandleReply: helper: '" << lastserver << "' sent us '" << (reply ? reply : "") << "'"); + debugs(29, 8, HERE << "helper: '" << lastserver << "' sent us '" << (reply ? reply : "") << "'"); valid = cbdataReferenceValid(r->data); if (!valid) { - debugs(29, 1, "authenticateNTLMHandleReply: invalid callback data. helper '" << lastserver << "'."); + debugs(29, DBG_IMPORTANT, "ERROR: NTLM Authentication invalid callback data. helper '" << lastserver << "'."); cbdataReferenceDone(r->data); authenticateStateFree(r); return; } if (!reply) { - debugs(29, 1, "authenticateNTLMHandleReply: Helper '" << lastserver << "' crashed!."); + debugs(29, DBG_IMPORTANT, "ERROR: NTLM Authentication Helper '" << lastserver << "' crashed!."); reply = (char *)"BH Internal error"; } AuthUserRequest::Pointer auth_user_request = r->auth_user_request; assert(auth_user_request != NULL); - AuthNTLMUserRequest *ntlm_request = dynamic_cast(auth_user_request.getRaw()); - assert(ntlm_request != NULL); - assert(ntlm_request->waiting); - assert(ntlm_request->user() != NULL); - assert(ntlm_request->user()->auth_type == Auth::AUTH_NTLM); + AuthNTLMUserRequest *lm_request = dynamic_cast(auth_user_request.getRaw()); + assert(lm_request != NULL); + assert(lm_request->waiting); - ntlm_request->waiting = 0; - safe_free(ntlm_request->client_blob); + lm_request->waiting = 0; + safe_free(lm_request->client_blob); - if (ntlm_request->authserver == NULL) - ntlm_request->authserver = static_cast(lastserver); + assert(auth_user_request->user() != NULL); + assert(auth_user_request->user()->auth_type == Auth::AUTH_NTLM); + + if (lm_request->authserver == NULL) + lm_request->authserver = static_cast(lastserver); else - assert(ntlm_request->authserver == lastserver); + assert(lm_request->authserver == lastserver); /* seperate out the useful data */ blob = strchr(reply, ' '); @@ -282,30 +274,31 @@ AuthNTLMUserRequest::HandleReply(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->request->flags.must_keepalive = 1; - if (ntlm_request->request->flags.proxy_keepalive) { - ntlm_request->server_blob = xstrdup(blob); - ntlm_request->user()->credentials(Auth::Handshake); + safe_free(lm_request->server_blob); + lm_request->request->flags.must_keepalive = 1; + if (lm_request->request->flags.proxy_keepalive) { + lm_request->server_blob = xstrdup(blob); + auth_user_request->user()->credentials(Auth::Handshake); auth_user_request->denyMessage("Authentication in progress"); - debugs(29, 4, "authenticateNTLMHandleReply: Need to challenge the client with a server blob '" << blob << "'"); + debugs(29, 4, HERE << "Need to challenge the client with a server blob '" << blob << "'"); } else { - ntlm_request->user()->credentials(Auth::Failed); + auth_user_request->user()->credentials(Auth::Failed); auth_user_request->denyMessage("NTLM authentication requires a persistent connection"); } } else if (strncasecmp(reply, "AF ", 3) == 0) { /* we're finished, release the helper */ auth_user_request->user()->username(blob); auth_user_request->denyMessage("Login successful"); - safe_free(ntlm_request->server_blob); + safe_free(lm_request->server_blob); + lm_request->releaseAuthServer(); - debugs(29, 4, "authenticateNTLMHandleReply: Successfully validated user via NTLM. Username '" << blob << "'"); + debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << blob << "'"); /* connection is authenticated */ - debugs(29, 4, "AuthNTLMUserRequest::authenticate: authenticated user " << auth_user_request->user()->username()); + debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username()); /* see if this is an existing user with a different proxy_auth * string */ - auth_user_hash_pointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->username())); - Auth::User::Pointer local_auth_user = ntlm_request->user(); + AuthUserHashPointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->username())); + Auth::User::Pointer local_auth_user = lm_request->user(); while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NTLM || strcmp(usernamehash->user()->username(), auth_user_request->user()->username()) != 0)) usernamehash = static_cast(usernamehash->next); @@ -315,6 +308,7 @@ AuthNTLMUserRequest::HandleReply(void *data, void *lastserver, char *reply) * Just free the temporary auth_user after merging as * much of it new state into the existing one as possible */ usernamehash->user()->absorb(local_auth_user); + /* from here on we are working with the original cached credentials. */ local_auth_user = usernamehash->user(); auth_user_request->user(local_auth_user); } else { @@ -324,15 +318,16 @@ AuthNTLMUserRequest::HandleReply(void *data, void *lastserver, char *reply) /* set these to now because this is either a new login from an * existing user or a new user */ local_auth_user->expiretime = current_time.tv_sec; - ntlm_request->releaseAuthServer(); - local_auth_user->credentials(Auth::Ok); + auth_user_request->user()->credentials(Auth::Ok); + debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << blob << "'"); + } else if (strncasecmp(reply, "NA ", 3) == 0) { /* authentication failure (wrong password, etc.) */ auth_user_request->denyMessage(blob); - ntlm_request->user()->credentials(Auth::Failed); - safe_free(ntlm_request->server_blob); - ntlm_request->releaseAuthServer(); - debugs(29, 4, "authenticateNTLMHandleReply: Failed validating user via NTLM. Error returned '" << blob << "'"); + auth_user_request->user()->credentials(Auth::Failed); + safe_free(lm_request->server_blob); + lm_request->releaseAuthServer(); + debugs(29, 4, HERE << "Failed validating user via NTLM. Error returned '" << blob << "'"); } else if (strncasecmp(reply, "BH ", 3) == 0) { /* TODO kick off a refresh process. This can occur after a YR or after * a KK. If after a YR release the helper and resubmit the request via @@ -341,17 +336,17 @@ AuthNTLMUserRequest::HandleReply(void *data, void *lastserver, char *reply) * Needing YR. */ auth_user_request->denyMessage(blob); auth_user_request->user()->credentials(Auth::Failed); - safe_free(ntlm_request->server_blob); - ntlm_request->releaseAuthServer(); - debugs(29, 1, "authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '" << reply << "'"); + safe_free(lm_request->server_blob); + lm_request->releaseAuthServer(); + debugs(29, DBG_IMPORTANT, "ERROR: NTLM Authentication validating user. Error returned '" << reply << "'"); } else { /* protocol error */ fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } - if (ntlm_request->request) { - HTTPMSGUNLOCK(ntlm_request->request); - ntlm_request->request = NULL; + if (lm_request->request) { + HTTPMSGUNLOCK(lm_request->request); + lm_request->request = NULL; } r->handler(r->data, NULL); cbdataReferenceDone(r->data);