]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/auth/digest/auth_digest.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / auth / digest / auth_digest.cc
index aa0845145fb0710b8a4b4f9ee72bbefcea579357..1db50bfa19e17eb039c0e760ccba3646b48cac4d 100644 (file)
  * See acl.c for access control and client_side.c for auditing */
 
 
-#include "squid.h"
+#include "squid-old.h"
 #include "rfc2617.h"
 #include "auth/digest/auth_digest.h"
+#include "auth/digest/Scheme.h"
+#include "auth/digest/User.h"
+#include "auth/digest/UserRequest.h"
 #include "auth/Gadgets.h"
+#include "auth/State.h"
+#include "base64.h"
+#include "base/StringArea.h"
 #include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
 #include "Store.h"
 #include "HttpRequest.h"
 #include "HttpReply.h"
 #include "wordlist.h"
 #include "SquidTime.h"
-/* TODO don't include this */
-#include "auth/digest/digestScheme.h"
-#include "auth/digest/digestUserRequest.h"
 
 /* Digest Scheme */
 
@@ -63,8 +66,6 @@ static hash_table *digest_nonce_cache;
 static int authdigest_initialised = 0;
 static MemAllocator *digest_nonce_pool = NULL;
 
-// CBDATA_TYPE(DigestAuthenticateStateData);
-
 enum http_digest_attr_type {
     DIGEST_USERNAME,
     DIGEST_REALM,
@@ -103,8 +104,6 @@ static digest_nonce_h *authenticateDigestNonceFindNonce(const char *nonceb64);
 static digest_nonce_h *authenticateDigestNonceNew(void);
 static void authenticateDigestNonceDelete(digest_nonce_h * nonce);
 static void authenticateDigestNonceSetup(void);
-static void authenticateDigestNonceShutdown(void);
-static void authenticateDigestNonceReconfigure(void);
 static int authDigestNonceIsStale(digest_nonce_h * nonce);
 static void authDigestNonceEncode(digest_nonce_h * nonce);
 static void authDigestNonceLink(digest_nonce_h * nonce);
@@ -112,7 +111,6 @@ static void authDigestNonceLink(digest_nonce_h * nonce);
 static int authDigestNonceLinks(digest_nonce_h * nonce);
 #endif
 static void authDigestNonceUserUnlink(digest_nonce_h * nonce);
-static void authDigestNoncePurge(digest_nonce_h * nonce);
 
 static void
 authDigestNonceEncode(digest_nonce_h * nonce)
@@ -227,11 +225,11 @@ authenticateDigestNonceSetup(void)
     if (!digest_nonce_cache) {
         digest_nonce_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string);
         assert(digest_nonce_cache);
-        eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->nonceGCInterval, 1);
+        eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->nonceGCInterval, 1);
     }
 }
 
-static void
+void
 authenticateDigestNonceShutdown(void)
 {
     /*
@@ -259,10 +257,6 @@ authenticateDigestNonceShutdown(void)
     debugs(29, 2, "authenticateDigestNonceShutdown: Nonce cache shutdown");
 }
 
-static void
-authenticateDigestNonceReconfigure(void)
-{}
-
 static void
 authenticateDigestNonceCacheCleanup(void *data)
 {
@@ -294,8 +288,8 @@ authenticateDigestNonceCacheCleanup(void *data)
 
     debugs(29, 3, "authenticateDigestNonceCacheCleanup: Finished cleaning the nonce cache.");
 
-    if (static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->active())
-        eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->nonceGCInterval, 1);
+    if (static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->active())
+        eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->nonceGCInterval, 1);
 }
 
 static void
@@ -382,12 +376,12 @@ authDigestNonceIsValid(digest_nonce_h * nonce, char nc[9])
     }
 
     /* is the nonce-count ok ? */
-    if (!static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->CheckNonceCount) {
+    if (!static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->CheckNonceCount) {
         nonce->nc++;
         return -1;              /* forced OK by configuration */
     }
 
-    if ((static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->NonceStrictness && intnc != nonce->nc + 1) ||
+    if ((static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->NonceStrictness && intnc != nonce->nc + 1) ||
             intnc < nonce->nc + 1) {
         debugs(29, 4, "authDigestNonceIsValid: Nonce count doesn't match");
         nonce->flags.valid = 0;
@@ -412,10 +406,10 @@ authDigestNonceIsStale(digest_nonce_h * nonce)
         return -1;
 
     /* has it's max duration expired? */
-    if (nonce->noncedata.creationtime + static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->noncemaxduration < current_time.tv_sec) {
+    if (nonce->noncedata.creationtime + static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->noncemaxduration < current_time.tv_sec) {
         debugs(29, 4, "authDigestNonceIsStale: Nonce is too old. " <<
                nonce->noncedata.creationtime << " " <<
-               static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->noncemaxduration << " " <<
+               static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->noncemaxduration << " " <<
                current_time.tv_sec);
 
         nonce->flags.valid = 0;
@@ -428,7 +422,7 @@ authDigestNonceIsStale(digest_nonce_h * nonce)
         return -1;
     }
 
-    if (nonce->nc > static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->noncemaxuses) {
+    if (nonce->nc > static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->noncemaxuses) {
         debugs(29, 4, "authDigestNoncelastRequest: Nonce count over user limit");
         nonce->flags.valid = 0;
         return -1;
@@ -442,7 +436,7 @@ authDigestNonceIsStale(digest_nonce_h * nonce)
  * \retval  0    the digest is not stale yet
  * \retval -1    the digest will be stale on the next request
  */
-const int
+int
 authDigestNonceLastRequest(digest_nonce_h * nonce)
 {
     if (!nonce)
@@ -453,7 +447,7 @@ authDigestNonceLastRequest(digest_nonce_h * nonce)
         return -1;
     }
 
-    if (nonce->nc >= static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->noncemaxuses - 1) {
+    if (nonce->nc >= static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->noncemaxuses - 1) {
         debugs(29, 4, "authDigestNoncelastRequest: Nonce count about to hit user limit");
         return -1;
     }
@@ -462,7 +456,7 @@ authDigestNonceLastRequest(digest_nonce_h * nonce)
     return 0;
 }
 
-static void
+void
 authDigestNoncePurge(digest_nonce_h * nonce)
 {
     if (!nonce)
@@ -480,17 +474,17 @@ authDigestNoncePurge(digest_nonce_h * nonce)
 }
 
 /* USER related functions */
-static AuthUser::Pointer
+static Auth::User::Pointer
 authDigestUserFindUsername(const char *username)
 {
     AuthUserHashPointer *usernamehash;
     debugs(29, 9, HERE << "Looking for user '" << username << "'");
 
-    if (username && (usernamehash = static_cast < auth_user_hash_pointer * >(hash_lookup(proxy_auth_username_cache, username)))) {
-        while ((usernamehash->user()->auth_type != AUTH_DIGEST) && (usernamehash->next))
+    if (username && (usernamehash = static_cast < AuthUserHashPointer * >(hash_lookup(proxy_auth_username_cache, username)))) {
+        while ((usernamehash->user()->auth_type != Auth::AUTH_DIGEST) && (usernamehash->next))
             usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
 
-        if (usernamehash->user()->auth_type == AUTH_DIGEST) {
+        if (usernamehash->user()->auth_type == Auth::AUTH_DIGEST) {
             return usernamehash->user();
         }
     }
@@ -499,7 +493,7 @@ authDigestUserFindUsername(const char *username)
 }
 
 void
-AuthDigestConfig::rotateHelpers()
+Auth::Digest::Config::rotateHelpers()
 {
     /* schedule closure of existing helpers */
     if (digestauthenticators) {
@@ -509,43 +503,10 @@ AuthDigestConfig::rotateHelpers()
     /* NP: dynamic helper restart will ensure they start up again as needed. */
 }
 
-
-/** delete the digest request structure. Does NOT delete related structures */
 void
-digestScheme::done()
+Auth::Digest::Config::dump(StoreEntry * entry, const char *name, Auth::Config * scheme)
 {
-    /** \todo this should be a Config call. */
-
-    if (digestauthenticators)
-        helperShutdown(digestauthenticators);
-
-    if (DigestFieldsInfo) {
-        httpHeaderDestroyFieldsInfo(DigestFieldsInfo, DIGEST_ENUM_END);
-        DigestFieldsInfo = NULL;
-    }
-
-    authdigest_initialised = 0;
-
-    if (!shutting_down) {
-        authenticateDigestNonceReconfigure();
-        return;
-    }
-
-    delete digestauthenticators;
-    digestauthenticators = NULL;
-
-    PurgeCredentialsCache();
-    authenticateDigestNonceShutdown();
-    debugs(29, 2, "authenticateDigestDone: Digest authentication shut down.");
-
-    /* clear the global handle to this scheme. */
-    _instance = NULL;
-}
-
-void
-AuthDigestConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme)
-{
-    wordlist *list = authenticate;
+    wordlist *list = authenticateProgram;
     debugs(29, 9, "authDigestCfgDump: Dumping configuration");
     storeAppendPrintf(entry, "%s %s", name, "digest");
 
@@ -563,15 +524,15 @@ AuthDigestConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme
 }
 
 bool
-AuthDigestConfig::active() const
+Auth::Digest::Config::active() const
 {
     return authdigest_initialised == 1;
 }
 
 bool
-AuthDigestConfig::configured() const
+Auth::Digest::Config::configured() const
 {
-    if ((authenticate != NULL) &&
+    if ((authenticateProgram != NULL) &&
             (authenticateChildren.n_max != 0) &&
             (digestAuthRealm != NULL) && (noncemaxduration > -1))
         return true;
@@ -581,16 +542,15 @@ AuthDigestConfig::configured() const
 
 /* add the [www-|Proxy-]authenticate header on a 407 or 401 reply */
 void
-AuthDigestConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpReply *rep, http_hdr_type hdrType, HttpRequest * request)
+Auth::Digest::Config::fixHeader(Auth::UserRequest::Pointer auth_user_request, HttpReply *rep, http_hdr_type hdrType, HttpRequest * request)
 {
-    if (!authenticate)
+    if (!authenticateProgram)
         return;
 
     int stale = 0;
 
     if (auth_user_request != NULL) {
-        AuthDigestUserRequest *digest_request;
-        digest_request = dynamic_cast<AuthDigestUserRequest*>(auth_user_request.getRaw());
+        Auth::Digest::UserRequest *digest_request = dynamic_cast<Auth::Digest::UserRequest*>(auth_user_request.getRaw());
         assert (digest_request != NULL);
 
         stale = !digest_request->flags.invalid_password;
@@ -599,7 +559,7 @@ AuthDigestConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpRepl
     /* on a 407 or 401 we always use a new nonce */
     digest_nonce_h *nonce = authenticateDigestNonceNew();
 
-    debugs(29, 9, "authenticateFixHeader: Sending type:" << hdrType <<
+    debugs(29, 9, HERE << "Sending type:" << hdrType <<
            " header: 'Digest realm=\"" << digestAuthRealm << "\", nonce=\"" <<
            authenticateDigestNonceNonceb64(nonce) << "\", qop=\"" << QOP_AUTH <<
            "\", stale=" << (stale ? "true" : "false"));
@@ -608,51 +568,12 @@ AuthDigestConfig::fixHeader(AuthUserRequest::Pointer auth_user_request, HttpRepl
     httpHeaderPutStrf(&rep->header, hdrType, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s", digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");
 }
 
-DigestUser::~DigestUser()
-{
-    dlink_node *link, *tmplink;
-    link = nonces.head;
-
-    while (link) {
-        tmplink = link;
-        link = link->next;
-        dlinkDelete(tmplink, &nonces);
-        authDigestNoncePurge(static_cast < digest_nonce_h * >(tmplink->data));
-        authDigestNonceUnlink(static_cast < digest_nonce_h * >(tmplink->data));
-        dlinkNodeDelete(tmplink);
-    }
-}
-
-int32_t
-DigestUser::ttl() const
-{
-    int32_t global_ttl = static_cast<int32_t>(expiretime - squid_curtime + Config.authenticateTTL);
-
-    /* find the longest lasting nonce. */
-    int32_t latest_nonce = -1;
-    dlink_node *link = nonces.head;
-    while (link) {
-        digest_nonce_h *nonce = static_cast<digest_nonce_h *>(link->data);
-        if (nonce->flags.valid && nonce->noncedata.creationtime > latest_nonce)
-            latest_nonce = nonce->noncedata.creationtime;
-
-        link = link->next;
-    }
-    if (latest_nonce == -1)
-        return min(-1, global_ttl);
-
-    int32_t nonce_ttl = latest_nonce - current_time.tv_sec + static_cast<AuthDigestConfig*>(AuthConfig::Find("digest"))->noncemaxduration;
-
-    return min(nonce_ttl, global_ttl);
-}
-
-
 /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
  * config file */
 void
-AuthDigestConfig::init(AuthConfig * scheme)
+Auth::Digest::Config::init(Auth::Config * scheme)
 {
-    if (authenticate) {
+    if (authenticateProgram) {
         DigestFieldsInfo = httpHeaderBuildFieldsInfo(DigestAttrs, DIGEST_ENUM_END);
         authenticateDigestNonceSetup();
         authdigest_initialised = 1;
@@ -660,62 +581,71 @@ AuthDigestConfig::init(AuthConfig * scheme)
         if (digestauthenticators == NULL)
             digestauthenticators = new helper("digestauthenticator");
 
-        digestauthenticators->cmdline = authenticate;
+        digestauthenticators->cmdline = authenticateProgram;
 
-        digestauthenticators->childs = authenticateChildren;
+        digestauthenticators->childs.updateLimits(authenticateChildren);
 
         digestauthenticators->ipc_type = IPC_STREAM;
 
         helperOpenServers(digestauthenticators);
-
-        CBDATA_INIT_TYPE(authenticateStateData);
     }
 }
 
 void
-AuthDigestConfig::registerWithCacheManager(void)
+Auth::Digest::Config::registerWithCacheManager(void)
 {
-    CacheManager::GetInstance()->
-    registerAction("digestauthenticator",
-                   "Digest User Authenticator Stats",
-                   authenticateDigestStats, 0, 1);
+    Mgr::RegisterAction("digestauthenticator",
+                        "Digest User Authenticator Stats",
+                        authenticateDigestStats, 0, 1);
 }
 
 /* free any allocated configuration details */
 void
-AuthDigestConfig::done()
+Auth::Digest::Config::done()
 {
-    if (authenticate)
-        wordlistDestroy(&authenticate);
+    authdigest_initialised = 0;
+
+    if (digestauthenticators)
+        helperShutdown(digestauthenticators);
+
+    if (DigestFieldsInfo) {
+        httpHeaderDestroyFieldsInfo(DigestFieldsInfo, DIGEST_ENUM_END);
+        DigestFieldsInfo = NULL;
+    }
+
+    if (!shutting_down)
+        return;
+
+    delete digestauthenticators;
+    digestauthenticators = NULL;
+
+    if (authenticateProgram)
+        wordlistDestroy(&authenticateProgram);
 
     safe_free(digestAuthRealm);
 }
 
-AuthDigestConfig::AuthDigestConfig()
-{
-    /* TODO: move into initialisation list */
-    /* 5 minutes */
-    nonceGCInterval = 5 * 60;
-    /* 30 minutes */
-    noncemaxduration = 30 * 60;
-    /* 50 requests */
-    noncemaxuses = 50;
-    /* Not strict nonce count behaviour */
-    NonceStrictness = 0;
-    /* Verify nonce count */
-    CheckNonceCount = 1;
-}
+Auth::Digest::Config::Config() :
+        digestAuthRealm(NULL),
+        nonceGCInterval(5*60),
+        noncemaxduration(30*60),
+        noncemaxuses(50),
+        NonceStrictness(0),
+        CheckNonceCount(1),
+        PostWorkaround(0),
+        utf8(0)
+{}
 
 void
-AuthDigestConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
+Auth::Digest::Config::parse(Auth::Config * scheme, int n_configured, char *param_str)
 {
     if (strcasecmp(param_str, "program") == 0) {
-        if (authenticate)
-            wordlistDestroy(&authenticate);
+        if (authenticateProgram)
+            wordlistDestroy(&authenticateProgram);
 
-        parse_wordlist(&authenticate);
+        parse_wordlist(&authenticateProgram);
 
-        requirePathnameExists("auth_param digest program", authenticate->key);
+        requirePathnameExists("auth_param digest program", authenticateProgram->key);
     } else if (strcasecmp(param_str, "children") == 0) {
         authenticateChildren.parseConfig();
     } else if (strcasecmp(param_str, "realm") == 0) {
@@ -740,9 +670,9 @@ AuthDigestConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
 }
 
 const char *
-AuthDigestConfig::type() const
+Auth::Digest::Config::type() const
 {
-    return digestScheme::GetInstance()->type();
+    return Auth::Digest::Scheme::GetInstance()->type();
 }
 
 
@@ -757,7 +687,7 @@ authenticateDigestStats(StoreEntry * sentry)
 static void
 authDigestNonceUserUnlink(digest_nonce_h * nonce)
 {
-    DigestUser *digest_user;
+    Auth::Digest::User *digest_user;
     dlink_node *link, *tmplink;
 
     if (!nonce)
@@ -792,17 +722,15 @@ authDigestNonceUserUnlink(digest_nonce_h * nonce)
 }
 
 /* authDigestUserLinkNonce: add a nonce to a given user's struct */
-
 static void
-authDigestUserLinkNonce(DigestUser * user, digest_nonce_h * nonce)
+authDigestUserLinkNonce(Auth::Digest::User * user, digest_nonce_h * nonce)
 {
     dlink_node *node;
-    DigestUser *digest_user;
 
     if (!user || !nonce)
         return;
 
-    digest_user = user;
+    Auth::Digest::User *digest_user = user;
 
     node = digest_user->nonces.head;
 
@@ -828,18 +756,18 @@ authDigestUserLinkNonce(DigestUser * user, digest_nonce_h * nonce)
 }
 
 /* setup the necessary info to log the username */
-static AuthUserRequest::Pointer
-authDigestLogUsername(char *username, AuthUserRequest::Pointer auth_user_request)
+static Auth::UserRequest::Pointer
+authDigestLogUsername(char *username, Auth::UserRequest::Pointer auth_user_request)
 {
     assert(auth_user_request != NULL);
 
     /* log the username */
     debugs(29, 9, "authDigestLogUsername: Creating new user for logging '" << username << "'");
-    AuthUser::Pointer digest_user = new DigestUser(static_cast<AuthDigestConfig*>(AuthConfig::Find("digest")));
+    Auth::User::Pointer digest_user = new Auth::Digest::User(static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest")));
     /* save the credentials */
     digest_user->username(username);
     /* set the auth_user type */
-    digest_user->auth_type = AUTH_BROKEN;
+    digest_user->auth_type = Auth::AUTH_BROKEN;
     /* link the request to the user */
     auth_user_request->user(digest_user);
     return auth_user_request;
@@ -849,8 +777,8 @@ authDigestLogUsername(char *username, AuthUserRequest::Pointer auth_user_request
  * Decode a Digest [Proxy-]Auth string, placing the results in the passed
  * Auth_user structure.
  */
-AuthUserRequest::Pointer
-AuthDigestConfig::decode(char const *proxy_auth)
+Auth::UserRequest::Pointer
+Auth::Digest::Config::decode(char const *proxy_auth)
 {
     const char *item;
     const char *p;
@@ -861,7 +789,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
 
     debugs(29, 9, "authenticateDigestDecodeAuth: beginning");
 
-    AuthDigestUserRequest *digest_request = new AuthDigestUserRequest();
+    Auth::Digest::UserRequest *digest_request = new Auth::Digest::UserRequest();
 
     /* trim DIGEST from string */
 
@@ -886,19 +814,37 @@ AuthDigestConfig::decode(char const *proxy_auth)
             vlen = 0;
         }
 
-        /* parse value. auth-param     = token "=" ( token | quoted-string ) */
+        StringArea keyName(item, nlen-1);
         String value;
+
         if (vlen > 0) {
-            if (*p == '"') {
-                if (!httpHeaderParseQuotedString(p, &value)) {
-                    debugs(29, 9, "authDigestDecodeAuth: Failed to parse attribute '" << item << "' in '" << temp << "'");
+            // see RFC 2617 section 3.2.1 and 3.2.2 for details on the BNF
+
+            if (keyName == StringArea("domain",6) || keyName == StringArea("uri",3)) {
+                // domain is Special. Not a quoted-string, must not be de-quoted. But is wrapped in '"'
+                // BUG 3077: uri= can also be sent to us in a mangled (invalid!) form like domain
+                if (*p == '"' && *(p + vlen -1) == '"') {
+                    value.limitInit(p+1, vlen-2);
+                }
+            } else if (keyName == StringArea("qop",3)) {
+                // qop is more special.
+                // On request this must not be quoted-string de-quoted. But is several values wrapped in '"'
+                // On response this is a single un-quoted token.
+                if (*p == '"' && *(p + vlen -1) == '"') {
+                    value.limitInit(p+1, vlen-2);
+                } else {
+                    value.limitInit(p, vlen);
+                }
+            } else if (*p == '"') {
+                if (!httpHeaderParseQuotedString(p, vlen, &value)) {
+                    debugs(29, 9, HERE << "Failed to parse attribute '" << item << "' in '" << temp << "'");
                     continue;
                 }
             } else {
                 value.limitInit(p, vlen);
             }
         } else {
-            debugs(29, 9, "authDigestDecodeAuth: Failed to parse attribute '" << item << "' in '" << temp << "'");
+            debugs(29, 9, HERE << "Failed to parse attribute '" << item << "' in '" << temp << "'");
             continue;
         }
 
@@ -909,61 +855,61 @@ AuthDigestConfig::decode(char const *proxy_auth)
         case DIGEST_USERNAME:
             safe_free(username);
             username = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found Username '" << username << "'");
+            debugs(29, 9, HERE << "Found Username '" << username << "'");
             break;
 
         case DIGEST_REALM:
             safe_free(digest_request->realm);
             digest_request->realm = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found realm '" << digest_request->realm << "'");
+            debugs(29, 9, HERE << "Found realm '" << digest_request->realm << "'");
             break;
 
         case DIGEST_QOP:
             safe_free(digest_request->qop);
             digest_request->qop = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found qop '" << digest_request->qop << "'");
+            debugs(29, 9, HERE << "Found qop '" << digest_request->qop << "'");
             break;
 
         case DIGEST_ALGORITHM:
             safe_free(digest_request->algorithm);
             digest_request->algorithm = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found algorithm '" << digest_request->algorithm << "'");
+            debugs(29, 9, HERE << "Found algorithm '" << digest_request->algorithm << "'");
             break;
 
         case DIGEST_URI:
             safe_free(digest_request->uri);
             digest_request->uri = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found uri '" << digest_request->uri << "'");
+            debugs(29, 9, HERE << "Found uri '" << digest_request->uri << "'");
             break;
 
         case DIGEST_NONCE:
             safe_free(digest_request->nonceb64);
             digest_request->nonceb64 = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found nonce '" << digest_request->nonceb64 << "'");
+            debugs(29, 9, HERE << "Found nonce '" << digest_request->nonceb64 << "'");
             break;
 
         case DIGEST_NC:
             if (value.size() != 8) {
-                debugs(29, 9, "authDigestDecodeAuth: Invalid nc '" << value << "' in '" << temp << "'");
+                debugs(29, 9, HERE << "Invalid nc '" << value << "' in '" << temp << "'");
             }
             xstrncpy(digest_request->nc, value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found noncecount '" << digest_request->nc << "'");
+            debugs(29, 9, HERE << "Found noncecount '" << digest_request->nc << "'");
             break;
 
         case DIGEST_CNONCE:
             safe_free(digest_request->cnonce);
             digest_request->cnonce = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found cnonce '" << digest_request->cnonce << "'");
+            debugs(29, 9, HERE << "Found cnonce '" << digest_request->cnonce << "'");
             break;
 
         case DIGEST_RESPONSE:
             safe_free(digest_request->response);
             digest_request->response = xstrndup(value.rawBuf(), value.size() + 1);
-            debugs(29, 9, "authDigestDecodeAuth: Found response '" << digest_request->response << "'");
+            debugs(29, 9, HERE << "Found response '" << digest_request->response << "'");
             break;
 
         default:
-            debugs(29, 3, "authDigestDecodeAuth: Unknown attribute '" << item << "' in '" << temp << "'");
+            debugs(29, 3, HERE << "Unknown attribute '" << item << "' in '" << temp << "'");
             break;
         }
     }
@@ -986,7 +932,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
 
     /* do we have a username ? */
     if (!username || username[0] == '\0') {
-        debugs(29, 2, "authenticateDigestDecode: Empty or not present username");
+        debugs(29, 2, HERE << "Empty or not present username");
         return authDigestLogUsername(username, digest_request);
     }
 
@@ -995,32 +941,32 @@ AuthDigestConfig::decode(char const *proxy_auth)
      * have been redone
      */
     if (strchr(username, '"')) {
-        debugs(29, 2, "authenticateDigestDecode: Unacceptable username '" << username << "'");
+        debugs(29, 2, HERE << "Unacceptable username '" << username << "'");
         return authDigestLogUsername(username, digest_request);
     }
 
     /* do we have a realm ? */
     if (!digest_request->realm || digest_request->realm[0] == '\0') {
-        debugs(29, 2, "authenticateDigestDecode: Empty or not present realm");
+        debugs(29, 2, HERE << "Empty or not present realm");
         return authDigestLogUsername(username, digest_request);
     }
 
     /* and a nonce? */
     if (!digest_request->nonceb64 || digest_request->nonceb64[0] == '\0') {
-        debugs(29, 2, "authenticateDigestDecode: Empty or not present nonce");
+        debugs(29, 2, HERE << "Empty or not present nonce");
         return authDigestLogUsername(username, digest_request);
     }
 
     /* we can't check the URI just yet. We'll check it in the
      * authenticate phase, but needs to be given */
     if (!digest_request->uri || digest_request->uri[0] == '\0') {
-        debugs(29, 2, "authenticateDigestDecode: Missing URI field");
+        debugs(29, 2, HERE << "Missing URI field");
         return authDigestLogUsername(username, digest_request);
     }
 
     /* is the response the correct length? */
     if (!digest_request->response || strlen(digest_request->response) != 32) {
-        debugs(29, 2, "authenticateDigestDecode: Response length invalid");
+        debugs(29, 2, HERE << "Response length invalid");
         return authDigestLogUsername(username, digest_request);
     }
 
@@ -1029,7 +975,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
         digest_request->algorithm = xstrndup("MD5", 4);
     else if (strcmp(digest_request->algorithm, "MD5")
              && strcmp(digest_request->algorithm, "MD5-sess")) {
-        debugs(29, 2, "authenticateDigestDecode: invalid algorithm specified!");
+        debugs(29, 2, HERE << "invalid algorithm specified!");
         return authDigestLogUsername(username, digest_request);
     }
 
@@ -1039,25 +985,25 @@ AuthDigestConfig::decode(char const *proxy_auth)
         /* check the qop is what we expected. */
         if (strcmp(digest_request->qop, QOP_AUTH) != 0) {
             /* we received a qop option we didn't send */
-            debugs(29, 2, "authenticateDigestDecode: Invalid qop option received");
+            debugs(29, 2, HERE << "Invalid qop option received");
             return authDigestLogUsername(username, digest_request);
         }
 
         /* check cnonce */
         if (!digest_request->cnonce || digest_request->cnonce[0] == '\0') {
-            debugs(29, 2, "authenticateDigestDecode: Missing cnonce field");
+            debugs(29, 2, HERE << "Missing cnonce field");
             return authDigestLogUsername(username, digest_request);
         }
 
         /* check nc */
         if (strlen(digest_request->nc) != 8 || strspn(digest_request->nc, "0123456789abcdefABCDEF") != 8) {
-            debugs(29, 2, "authenticateDigestDecode: invalid nonce count");
+            debugs(29, 2, HERE << "invalid nonce count");
             return authDigestLogUsername(username, digest_request);
         }
     } else {
         /* cnonce and nc both require qop */
         if (digest_request->cnonce || digest_request->nc) {
-            debugs(29, 2, "authenticateDigestDecode: missing qop!");
+            debugs(29, 2, HERE << "missing qop!");
             return authDigestLogUsername(username, digest_request);
         }
     }
@@ -1068,8 +1014,9 @@ AuthDigestConfig::decode(char const *proxy_auth)
     nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
     if (!nonce) {
         /* we couldn't find a matching nonce! */
-        debugs(29, 2, "authenticateDigestDecode: Unexpected or invalid nonce received");
-        digest_request->user()->credentials(AuthUser::Failed);
+        debugs(29, 2, HERE << "Unexpected or invalid nonce received");
+        if (digest_request->user() != NULL)
+            digest_request->user()->credentials(Auth::Failed);
         return authDigestLogUsername(username, digest_request);
     }
 
@@ -1078,7 +1025,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
 
     /* check that we're not being hacked / the username hasn't changed */
     if (nonce->user && strcmp(username, nonce->user->username())) {
-        debugs(29, 2, "authenticateDigestDecode: Username for the nonce does not equal the username for the request");
+        debugs(29, 2, HERE << "Username for the nonce does not equal the username for the request");
         return authDigestLogUsername(username, digest_request);
     }
 
@@ -1088,20 +1035,20 @@ AuthDigestConfig::decode(char const *proxy_auth)
     /* we don't send or parse opaques. Ok so we're flexable ... */
 
     /* find the user */
-    DigestUser *digest_user;
+    Auth::Digest::User *digest_user;
 
-    AuthUser::Pointer auth_user;
+    Auth::User::Pointer auth_user;
 
     if ((auth_user = authDigestUserFindUsername(username)) == NULL) {
         /* the user doesn't exist in the username cache yet */
-        debugs(29, 9, "authDigestDecodeAuth: Creating new digest user '" << username << "'");
-        digest_user = new DigestUser(this);
+        debugs(29, 9, HERE << "Creating new digest user '" << username << "'");
+        digest_user = new Auth::Digest::User(this);
         /* auth_user is a parent */
         auth_user = digest_user;
         /* save the username */
         digest_user->username(username);
         /* set the user type */
-        digest_user->auth_type = AUTH_DIGEST;
+        digest_user->auth_type = Auth::AUTH_DIGEST;
         /* this auth_user struct is the one to get added to the
          * username cache */
         /* store user in hash's */
@@ -1114,8 +1061,8 @@ AuthDigestConfig::decode(char const *proxy_auth)
          */
         authDigestUserLinkNonce(digest_user, nonce);
     } else {
-        debugs(29, 9, "authDigestDecodeAuth: Found user '" << username << "' in the user cache as '" << auth_user << "'");
-        digest_user = static_cast<DigestUser *>(auth_user.getRaw());
+        debugs(29, 9, HERE << "Found user '" << username << "' in the user cache as '" << auth_user << "'");
+        digest_user = static_cast<Auth::Digest::User *>(auth_user.getRaw());
         xfree(username);
     }
 
@@ -1123,7 +1070,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
     assert(digest_request != NULL);
 
     digest_request->user(digest_user);
-    debugs(29, 9, "username = '" << digest_user->username() << "'\nrealm = '" <<
+    debugs(29, 9, HERE << "username = '" << digest_user->username() << "'\nrealm = '" <<
            digest_request->realm << "'\nqop = '" << digest_request->qop <<
            "'\nalgorithm = '" << digest_request->algorithm << "'\nuri = '" <<
            digest_request->uri << "'\nnonce = '" << digest_request->nonceb64 <<
@@ -1133,6 +1080,3 @@ AuthDigestConfig::decode(char const *proxy_auth)
 
     return digest_request;
 }
-
-DigestUser::DigestUser(AuthConfig *aConfig) : AuthUser(aConfig), HA1created (0)
-{}