#include "auth/Gadgets.h"
#include "auth/State.h"
#include "base/LookupTable.h"
-#include "base64.h"
#include "cache_cf.h"
#include "event.h"
#include "helper.h"
#include "HttpHeaderTools.h"
#include "HttpReply.h"
#include "HttpRequest.h"
+#include "md5.h"
#include "mgr/Registration.h"
#include "rfc2617.h"
#include "sbuf/SBuf.h"
*/
static void authenticateDigestNonceCacheCleanup(void *data);
-static digest_nonce_h *authenticateDigestNonceFindNonce(const char *nonceb64);
+static digest_nonce_h *authenticateDigestNonceFindNonce(const char *noncehex);
static void authenticateDigestNonceDelete(digest_nonce_h * nonce);
static void authenticateDigestNonceSetup(void);
static void authDigestNonceEncode(digest_nonce_h * nonce);
if (nonce->key)
xfree(nonce->key);
- nonce->key = xcalloc(base64_encode_len(sizeof(digest_nonce_data)), 1);
- struct base64_encode_ctx ctx;
- base64_encode_init(&ctx);
- size_t blen = base64_encode_update(&ctx, reinterpret_cast<char*>(nonce->key), sizeof(digest_nonce_data), reinterpret_cast<const uint8_t*>(&(nonce->noncedata)));
- blen += base64_encode_final(&ctx, reinterpret_cast<char*>(nonce->key)+blen);
+ SquidMD5_CTX Md5Ctx;
+ HASH H;
+ SquidMD5Init(&Md5Ctx);
+ SquidMD5Update(&Md5Ctx, reinterpret_cast<const uint8_t *>(&nonce->noncedata), sizeof(nonce->noncedata));
+ SquidMD5Final(reinterpret_cast<uint8_t *>(H), &Md5Ctx);
+
+ nonce->key = xcalloc(sizeof(HASHHEX), 1);
+ CvtHex(H, static_cast<char *>(nonce->key));
}
digest_nonce_h *
*
* Now for my reasoning:
* We will not accept a unrecognised nonce->we have all recognisable
- * nonces stored. If we send out unique base64 encodings we guarantee
+ * nonces stored. If we send out unique encodings we guarantee
* that a given nonce applies to only one user (barring attacks or
* really bad timing with expiry and creation). Using a random
* component in the nonce allows us to loop to find a unique nonce.
* We use H(nonce_data) so the nonce is meaningless to the reciever.
- * So our nonce looks like base64(H(timestamp,pointertohash,randomdata))
+ * So our nonce looks like hex(H(timestamp,pointertohash,randomdata))
* And even if our randomness is not very random we don't really care
* - the timestamp and memory pointer also guarantee local uniqueness
* in the input to the hash function.
authenticateDigestNonceCacheCleanup(void *)
{
/*
- * We walk the hash by nonceb64 as that is the unique key we
+ * We walk the hash by noncehex as that is the unique key we
* use. For big hash tables we could consider stepping through
* the cache, 100/200 entries at a time. Lets see how it flies
* first.
}
const char *
-authenticateDigestNonceNonceb64(const digest_nonce_h * nonce)
+authenticateDigestNonceNonceHex(const digest_nonce_h * nonce)
{
if (!nonce)
return NULL;
}
static digest_nonce_h *
-authenticateDigestNonceFindNonce(const char *nonceb64)
+authenticateDigestNonceFindNonce(const char *noncehex)
{
digest_nonce_h *nonce = NULL;
- if (nonceb64 == NULL)
+ if (noncehex == NULL)
return NULL;
- debugs(29, 9, "looking for nonceb64 '" << nonceb64 << "' in the nonce cache.");
+ debugs(29, 9, "looking for noncehex '" << noncehex << "' in the nonce cache.");
- nonce = static_cast < digest_nonce_h * >(hash_lookup(digest_nonce_cache, nonceb64));
+ nonce = static_cast < digest_nonce_h * >(hash_lookup(digest_nonce_cache, noncehex));
- if ((nonce == NULL) || (strcmp(authenticateDigestNonceNonceb64(nonce), nonceb64)))
+ if ((nonce == NULL) || (strcmp(authenticateDigestNonceNonceHex(nonce), noncehex)))
return NULL;
debugs(29, 9, "Found nonce '" << nonce << "'");
debugs(29, 9, "Sending type:" << hdrType <<
" header: 'Digest realm=\"" << realm << "\", nonce=\"" <<
- authenticateDigestNonceNonceb64(nonce) << "\", qop=\"" << QOP_AUTH <<
+ authenticateDigestNonceNonceHex(nonce) << "\", qop=\"" << QOP_AUTH <<
"\", stale=" << (stale ? "true" : "false"));
/* in the future, for WWW auth we may want to support the domain entry */
httpHeaderPutStrf(&rep->header, hdrType, "Digest realm=\"" SQUIDSBUFPH "\", nonce=\"%s\", qop=\"%s\", stale=%s",
- SQUIDSBUFPRINT(realm), authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false");
+ SQUIDSBUFPRINT(realm), authenticateDigestNonceNonceHex(nonce), QOP_AUTH, stale ? "true" : "false");
}
/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
break;
case DIGEST_NONCE:
- safe_free(digest_request->nonceb64);
+ safe_free(digest_request->noncehex);
if (value.size() != 0)
- digest_request->nonceb64 = xstrndup(value.rawBuf(), value.size() + 1);
- debugs(29, 9, "Found nonce '" << digest_request->nonceb64 << "'");
+ digest_request->noncehex = xstrndup(value.rawBuf(), value.size() + 1);
+ debugs(29, 9, "Found nonce '" << digest_request->noncehex << "'");
break;
case DIGEST_NC:
}
/* and a nonce? */
- if (!digest_request->nonceb64 || digest_request->nonceb64[0] == '\0') {
+ if (!digest_request->noncehex || digest_request->noncehex[0] == '\0') {
debugs(29, 2, "Empty or not present nonce");
rv = authDigestLogUsername(username, digest_request, aRequestRealm);
safe_free(username);
/** below nonce state dependent **/
/* now the nonce */
- nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64);
+ nonce = authenticateDigestNonceFindNonce(digest_request->noncehex);
/* check that we're not being hacked / the username hasn't changed */
if (nonce && nonce->user && strcmp(username, nonce->user->username())) {
debugs(29, 2, "Username for the nonce does not equal the username for the request");
debugs(29, 9, "username = '" << digest_user->username() << "'\nrealm = '" <<
digest_request->realm << "'\nqop = '" << digest_request->qop <<
"'\nalgorithm = '" << digest_request->algorithm << "'\nuri = '" <<
- digest_request->uri << "'\nnonce = '" << digest_request->nonceb64 <<
+ digest_request->uri << "'\nnonce = '" << digest_request->noncehex <<
"'\nnc = '" << digest_request->nc << "'\ncnonce = '" <<
digest_request->cnonce << "'\nresponse = '" <<
digest_request->response << "'\ndigestnonce = '" << nonce << "'");
#include "SquidTime.h"
Auth::Digest::UserRequest::UserRequest() :
- nonceb64(NULL),
+ noncehex(NULL),
cnonce(NULL),
realm(NULL),
pszPass(NULL),
{
assert(LockCount()==0);
- safe_free(nonceb64);
+ safe_free(noncehex);
safe_free(cnonce);
safe_free(realm);
safe_free(pszPass);
}
DigestCalcHA1(digest_request->algorithm, NULL, NULL, NULL,
- authenticateDigestNonceNonceb64(digest_request->nonce),
+ authenticateDigestNonceNonceHex(digest_request->nonce),
digest_request->cnonce,
digest_user->HA1, SESSIONKEY);
SBuf sTmp = request->method.image();
- DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceb64(digest_request->nonce),
+ DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceHex(digest_request->nonce),
digest_request->nc, digest_request->cnonce, digest_request->qop,
sTmp.c_str(), digest_request->uri, HA2, Response);
* used.
*/
sTmp = HttpRequestMethod(Http::METHOD_GET).image();
- DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceb64(digest_request->nonce),
+ DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceHex(digest_request->nonce),
digest_request->nc, digest_request->cnonce, digest_request->qop,
sTmp.c_str(), digest_request->uri, HA2, Response);
/* check Auth::Pending to avoid loop */
if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc) && user()->credentials() != Auth::Pending) {
- debugs(29, 3, auth_user->username() << "' validated OK but nonce stale: " << digest_request->nonceb64);
+ debugs(29, 3, auth_user->username() << "' validated OK but nonce stale: " << digest_request->noncehex);
/* Pending prevent banner and makes a ldap control */
auth_user->credentials(Auth::Pending);
nonce->flags.valid = false;
nextnonce = authenticateDigestNonceNew();
authDigestUserLinkNonce(digest_user, nextnonce);
}
- debugs(29, 9, "Sending type:" << type << " header: 'nextnonce=\"" << authenticateDigestNonceNonceb64(nextnonce) << "\"");
- httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(nextnonce));
+ debugs(29, 9, "Sending type:" << type << " header: 'nextnonce=\"" << authenticateDigestNonceNonceHex(nextnonce) << "\"");
+ httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceHex(nextnonce));
}
}
nonce = authenticateDigestNonceNew();
authDigestUserLinkNonce(digest_user, nonce);
}
- debugs(29, 9, "Sending type:" << type << " header: 'nextnonce=\"" << authenticateDigestNonceNonceb64(nonce) << "\"");
- httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(nonce));
+ debugs(29, 9, "Sending type:" << type << " header: 'nextnonce=\"" << authenticateDigestNonceNonceHex(nonce) << "\"");
+ httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceHex(nonce));
}
}
#endif