digest_auth_check(): added support for userhash

This commit is contained in:
Evgeny Grin (Karlson2k)
2022-07-25 16:20:48 +03:00
parent c024f7c8ad
commit 7e5206cc03
+47 -25
View File
@@ -1963,7 +1963,13 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
return MHD_DAUTH_WRONG_HEADER; /* Parameters cannot be used together */
else if ((NULL != params->username_ext.value.str) &&
(MHD_DAUTH_EXT_PARAM_MIN_LEN > params->username_ext.value.len))
return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
else if (params->userhash && (NULL == params->username.value.str))
return MHD_DAUTH_WRONG_HEADER; /* Userhash cannot be used with extended notation */
else if (params->userhash && (digest_size * 2 > params->username.value.len))
return MHD_DAUTH_WRONG_HEADER; /* Too few chars for correct userhash */
else if (params->userhash && (digest_size * 4 < params->username.value.len))
return MHD_DAUTH_WRONG_HEADER; /* Too many chars for correct userhash */
if (NULL == params->realm.value.str)
return MHD_DAUTH_WRONG_HEADER;
@@ -2039,32 +2045,48 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
/* Check 'username' */
username_len = strlen (username);
if (NULL != params->username.value.str)
{ /* Username in standard notation */
if (! is_param_equal (&params->username, username, username_len))
return MHD_DAUTH_WRONG_USERNAME;
if (! params->userhash)
{
if (NULL != params->username.value.str)
{ /* Username in standard notation */
if (! is_param_equal (&params->username, username, username_len))
return MHD_DAUTH_WRONG_USERNAME;
}
else
{ /* Username in extended notation */
char *r_uname;
size_t buf_size = params->username_ext.value.len;
ssize_t res;
mhd_assert (NULL != params->username_ext.value.str);
mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */
buf_size += 1; /* For zero-termination */
buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN;
r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size);
if (NULL == r_uname)
return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ?
MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
res = get_rq_extended_uname_copy_z (params->username_ext.value.str,
params->username_ext.value.len,
r_uname, buf_size);
if (0 > res)
return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
if ((username_len != (size_t) res) ||
(0 != memcmp (username, r_uname, username_len)))
return MHD_DAUTH_WRONG_USERNAME;
}
}
else
{ /* Username in extended notation */
char *r_uname;
size_t buf_size = params->username_ext.value.len;
ssize_t res;
mhd_assert (NULL != params->username_ext.value.str);
mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */
buf_size += 1; /* For zero-termination */
buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN;
r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size);
if (NULL == r_uname)
return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ?
MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
res = get_rq_extended_uname_copy_z (params->username_ext.value.str,
params->username_ext.value.len,
r_uname, buf_size);
if (0 > res)
return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */
if ((username_len != (size_t) res) ||
(0 != memcmp (username, r_uname, username_len)))
{ /* Userhash */
mhd_assert (NULL != params->username.value.str);
digest_init (da);
digest_update (da, username, username_len);
digest_update_with_colon (da);
digest_update (da, realm, realm_len);
digest_calc_hash (da, hash1_bin);
mhd_assert (sizeof (tmp1) >= (2 * digest_size + 1));
MHD_bin_to_hex (hash1_bin, digest_size, tmp1);
if (! is_param_equal_caseless (&params->username, tmp1, 2 * digest_size))
return MHD_DAUTH_WRONG_USERNAME;
}
/* 'username' valid */