Skip to content

Commit

Permalink
Fix RFC 2617 ("auth-int" digest authorisation) as patched by Charles …
Browse files Browse the repository at this point in the history
…Collicutt.

Source: #26 --- thanks!
  • Loading branch information
kristaps committed Mar 22, 2018
1 parent f899451 commit c7cb369
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 35 deletions.
35 changes: 25 additions & 10 deletions auth.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2015--2017 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2015--2018 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2018 Charles Collicutt <charles@collicutt.co.uk>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -120,6 +121,7 @@ khttpdigest_validatehash(const struct kreq *req, const char *skey4)
char skey1[MD5_DIGEST_LENGTH * 2 + 1],
skey2[MD5_DIGEST_LENGTH * 2 + 1],
skey3[MD5_DIGEST_LENGTH * 2 + 1],
skeyb[MD5_DIGEST_LENGTH * 2 + 1],
count[9];
size_t i;
const struct khttpdigest *auth;
Expand All @@ -139,9 +141,8 @@ khttpdigest_validatehash(const struct kreq *req, const char *skey4)
/*
* MD5-sess hashes the nonce and client nonce as well as the
* existing hash (user/real/pass).
* Note that the existing hash is MD5_DIGEST_LENGTH * 2 as
* validated by prncpl_pentry_check().
*/

if (KHTTPALG_MD5_SESS == auth->alg) {
MD5Init(&ctx);
MD5Updatec(&ctx, skey4, strlen(skey4));
Expand All @@ -155,20 +156,34 @@ khttpdigest_validatehash(const struct kreq *req, const char *skey4)
} else
strlcpy(skey1, skey4, sizeof(skey1));

/* Now start the "auth" hash sequence. */

MD5Init(&ctx);
MD5Updatec(&ctx, kmethods[req->method],
strlen(kmethods[req->method]));
MD5Updatec(&ctx, ":", 1);
MD5Updatec(&ctx, auth->uri, strlen(auth->uri));

/*
* If we're requesting integrity authentication ("auth-int"),
* then we also bring in the hash of the message body.
*/

if (KHTTPQOP_AUTH_INT == auth->qop) {
/* This shouldn't happen... */
if (NULL == req->rawauth.digest)
return(-1);
memcpy(ha2, req->rawauth.digest, sizeof(ha2));
} else {
MD5Init(&ctx);
MD5Updatec(&ctx, kmethods[req->method],
strlen(kmethods[req->method]));

for (i = 0; i < MD5_DIGEST_LENGTH; i++)
snprintf(&skeyb[i * 2], 3, "%02x",
(unsigned char)req->rawauth.digest[i]);

MD5Updatec(&ctx, ":", 1);
MD5Updatec(&ctx, auth->uri, strlen(auth->uri));
MD5Final(ha2, &ctx);
MD5Updatec(&ctx, skeyb, MD5_DIGEST_LENGTH * 2);
}

MD5Final(ha2, &ctx);

for (i = 0; i < MD5_DIGEST_LENGTH; i++)
snprintf(&skey2[i * 2], 3, "%02x", ha2[i]);

Expand Down
34 changes: 9 additions & 25 deletions child.c
Expand Up @@ -1342,17 +1342,16 @@ kworker_child_path(struct env *env, int fd, size_t envsz)
}

/*
* Construct the "HA2" component of an HTTP digest hash.
* Construct the body hash component of an HTTP digest hash.
* See khttpdigest_validatehash(3) for where this is used.
* See RFC 2617.
* We only do this if our authorisation requires it!
*/
static void
kworker_child_bodymd5(struct env *env, int fd,
size_t envsz, const char *b, size_t bsz, int md5)
kworker_child_bodymd5(int fd, const char *b, size_t bsz, int md5)
{
MD5_CTX ctx;
unsigned char ha2[MD5_DIGEST_LENGTH];
const char *uri, *script, *method;
unsigned char hab[MD5_DIGEST_LENGTH];
size_t sz;

if ( ! md5) {
Expand All @@ -1361,30 +1360,15 @@ kworker_child_bodymd5(struct env *env, int fd,
return;
}

uri = kworker_env(env, envsz, "PATH_INFO");
script = kworker_env(env, envsz, "SCRIPT_NAME");
method = kworker_env(env, envsz, "REQUEST_METHOD");

if (NULL == uri)
uri = "";
if (NULL == script)
script = "";
if (NULL == method)
method = "";

MD5Init(&ctx);
MD5Updatec(&ctx, method, strlen(method));
MD5Updatec(&ctx, ":", 1);
MD5Updatec(&ctx, script, strlen(script));
MD5Updatec(&ctx, uri, strlen(uri));
MD5Updatec(&ctx, ":", 1);
MD5Updatec(&ctx, b, bsz);
MD5Final(ha2, &ctx);
MD5Final(hab, &ctx);

/* This is a binary write! */

sz = MD5_DIGEST_LENGTH;
fullwrite(fd, &sz, sizeof(size_t));
fullwrite(fd, ha2, sz);
fullwrite(fd, hab, sz);
}

/*
Expand Down Expand Up @@ -1413,7 +1397,7 @@ kworker_child_body(struct env *env, int fd, size_t envsz,

if (0 == len) {
/* Remember to print our MD5 value. */
kworker_child_bodymd5(env, fd, envsz, "", 0, md5);
kworker_child_bodymd5(fd, "", 0, md5);
return;
}

Expand Down Expand Up @@ -1446,7 +1430,7 @@ kworker_child_body(struct env *env, int fd, size_t envsz,

/* If requested, print our MD5 value. */

kworker_child_bodymd5(env, fd, envsz, b, bsz, md5);
kworker_child_bodymd5(fd, b, bsz, md5);

if (bsz && KREQ_DEBUG_READ_BODY & debugging) {
fprintf(stderr, "%u: ", getpid());
Expand Down

0 comments on commit c7cb369

Please sign in to comment.