1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

Add support for RFC 2617 Digest Access Authentication

This commit is contained in:
Tim Ruehsen 2012-06-28 17:45:18 +02:00 committed by Giuseppe Scrivano
parent 172a117647
commit 4fe805a7ec
2 changed files with 81 additions and 22 deletions

View File

@ -1,3 +1,8 @@
2012-07-07 Tim Ruehsen <tim.ruehsen@gmx.de>
(digest_authentication_encode): Add support for RFC 2617 Digest
Access Authentication.
2012-07-07 Giuseppe Scrivano <gscrivano@gnu.org> 2012-07-07 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (http_loop): Fix log message. * http.c (http_loop): Fix log message.

View File

@ -3655,19 +3655,23 @@ digest_authentication_encode (const char *au, const char *user,
const char *passwd, const char *method, const char *passwd, const char *method,
const char *path) const char *path)
{ {
static char *realm, *opaque, *nonce; static char *realm, *opaque, *nonce, *qop;
static struct { static struct {
const char *name; const char *name;
char **variable; char **variable;
} options[] = { } options[] = {
{ "realm", &realm }, { "realm", &realm },
{ "opaque", &opaque }, { "opaque", &opaque },
{ "nonce", &nonce } { "nonce", &nonce },
{ "qop", &qop }
}; };
char cnonce[16] = "";
char *res; char *res;
size_t res_size;
param_token name, value; param_token name, value;
realm = opaque = nonce = NULL;
realm = opaque = nonce = qop = NULL;
au += 6; /* skip over `Digest' */ au += 6; /* skip over `Digest' */
while (extract_param (&au, &name, &value, ',')) while (extract_param (&au, &name, &value, ','))
@ -3683,11 +3687,19 @@ digest_authentication_encode (const char *au, const char *user,
break; break;
} }
} }
if (qop != NULL && strcmp(qop,"auth"))
{
logprintf (LOG_NOTQUIET, _("Unsupported quality of protection '%s'.\n"), qop);
user = NULL; /* force freeing mem and return */
}
if (!realm || !nonce || !user || !passwd || !path || !method) if (!realm || !nonce || !user || !passwd || !path || !method)
{ {
xfree_null (realm); xfree_null (realm);
xfree_null (opaque); xfree_null (opaque);
xfree_null (nonce); xfree_null (nonce);
xfree_null (qop);
return NULL; return NULL;
} }
@ -3716,6 +3728,30 @@ digest_authentication_encode (const char *au, const char *user,
md5_finish_ctx (&ctx, hash); md5_finish_ctx (&ctx, hash);
dump_hash (a2buf, hash); dump_hash (a2buf, hash);
if (!strcmp(qop,"auth"))
{
/* RFC 2617 Digest Access Authentication */
/* generate random hex string */
snprintf(cnonce, sizeof(cnonce), "%08x", random_number(INT_MAX));
/* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" noncecount ":" clientnonce ":" qop ": " A2BUF) */
md5_init_ctx (&ctx);
md5_process_bytes ((unsigned char *)a1buf, MD5_DIGEST_SIZE * 2, &ctx);
md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)nonce, strlen (nonce), &ctx);
md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)"00000001", 8, &ctx); /* TODO: keep track of server nonce values */
md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)cnonce, strlen(cnonce), &ctx);
md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)qop, strlen(qop), &ctx);
md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)a2buf, MD5_DIGEST_SIZE * 2, &ctx);
md5_finish_ctx (&ctx, hash);
}
else
{
/* RFC 2069 Digest Access Authentication */
/* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */ /* RESPONSE_DIGEST = H(A1BUF ":" nonce ":" A2BUF) */
md5_init_ctx (&ctx); md5_init_ctx (&ctx);
md5_process_bytes ((unsigned char *)a1buf, MD5_DIGEST_SIZE * 2, &ctx); md5_process_bytes ((unsigned char *)a1buf, MD5_DIGEST_SIZE * 2, &ctx);
@ -3724,19 +3760,37 @@ digest_authentication_encode (const char *au, const char *user,
md5_process_bytes ((unsigned char *)":", 1, &ctx); md5_process_bytes ((unsigned char *)":", 1, &ctx);
md5_process_bytes ((unsigned char *)a2buf, MD5_DIGEST_SIZE * 2, &ctx); md5_process_bytes ((unsigned char *)a2buf, MD5_DIGEST_SIZE * 2, &ctx);
md5_finish_ctx (&ctx, hash); md5_finish_ctx (&ctx, hash);
}
dump_hash (response_digest, hash); dump_hash (response_digest, hash);
res = xmalloc (strlen (user) res_size = strlen (user)
+ strlen (user) + strlen (user)
+ strlen (realm) + strlen (realm)
+ strlen (nonce) + strlen (nonce)
+ strlen (path) + strlen (path)
+ 2 * MD5_DIGEST_SIZE /*strlen (response_digest)*/ + 2 * MD5_DIGEST_SIZE /*strlen (response_digest)*/
+ (opaque ? strlen (opaque) : 0) + (opaque ? strlen (opaque) : 0)
+ 128); + (qop ? 128: 0)
sprintf (res, "Digest \ + 128;
username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
res = xmalloc (res_size);
if (!strcmp(qop,"auth"))
{
snprintf (res, res_size, "Digest "\
"username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""\
", qop=auth, nc=00000001, cnonce=\"%s\"",
user, realm, nonce, path, response_digest, cnonce);
}
else
{
snprintf (res, res_size, "Digest "\
"username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
user, realm, nonce, path, response_digest); user, realm, nonce, path, response_digest);
}
if (opaque) if (opaque)
{ {
char *p = res + strlen (res); char *p = res + strlen (res);