libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 4baec145d4c68fbd8efd4052abca24d244bf3188
parent 13db035fc9e191e99dbaf3507e45516eb4ffeabd
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sun, 24 Jul 2022 13:51:15 +0300

Digest Auth public structs: removed redundant member

Added one more check for data validity.

Diffstat:
Msrc/include/microhttpd.h | 45+++++++++++++++++++++++++++++----------------
Msrc/microhttpd/digestauth.c | 18++++++++++--------
Msrc/testcurl/test_digestauth_emu_ext.c | 4----
3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -96,7 +96,7 @@ extern "C" * they are parsed as decimal numbers. * Example: 0x01093001 = 1.9.30-1. */ -#define MHD_VERSION 0x00097523 +#define MHD_VERSION 0x00097525 /* If generic headers don't work on your platform, include headers which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t', @@ -4664,7 +4664,7 @@ enum MHD_DigestAuthMultiQOP * * Application may modify buffers as needed until #MHD_free() is called for * pointer to this structure - * @note Available since #MHD_VERSION 0x00097519 + * @note Available since #MHD_VERSION 0x00097525 */ struct MHD_DigestAuthInfo { @@ -4676,10 +4676,12 @@ struct MHD_DigestAuthInfo * which uses other values! */ enum MHD_DigestAuthAlgo3 algo; + /** * The type of username used by client. */ enum MHD_DigestAuthUsernameType uname_type; + /** * The username string. * Valid only if username is standard, extended, or userhash. @@ -4691,46 +4693,54 @@ struct MHD_DigestAuthInfo * This can be NULL is username is missing or invalid. */ char *username; + /** * The length of the @a username. * When the @a username is NULL, this member is always zero. */ size_t username_len; + /** * The userhash decoded to binary form. * Used only if username type is userhash, always NULL otherwise. - * @warning this is a binary data, no zero termination + * When not NULL, this points to binary sequence @a username_len /2 bytes + * long. + * @warning This is binary data, no zero termination. + * @warning To avoid buffer overruns, always check the size of the data before + * use, because @ userhash_bin can point even to zero-sized + * data. */ uint8_t *userhash_bin; - /** - * The number of bytes pointed by the @a userhash_bin. - * When the @a userhash_bin is NULL, this member is always zero. - */ - size_t userhash_bin_size; + /** * The 'opaque' parameter value, as specified by client. * NULL if not specified by client. */ char *opaque; + /** * The length of the @a opaque. * When the @a opaque is NULL, this member is always zero. */ size_t opaque_len; + /** * The 'realm' parameter value, as specified by client. * NULL if not specified by client. */ char *realm; + /** * The length of the @a realm. * When the @a realm is NULL, this member is always zero. */ size_t realm_len; + /** * The 'qop' parameter value. */ enum MHD_DigestAuthQOP qop; + /** * The length of the 'cnonce' parameter value, including possible * backslash-escape characters. @@ -4740,6 +4750,7 @@ struct MHD_DigestAuthInfo * characters long. */ size_t cnonce_len; + /** * The nc parameter value. * Can be used by application to limit the number of nonce re-uses. If @ nc @@ -4773,7 +4784,7 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection); * * Application may modify buffers as needed until #MHD_free() is called for * pointer to this structure - * @note Available since #MHD_VERSION 0x00097519 + * @note Available since #MHD_VERSION 0x00097525 */ struct MHD_DigestAuthUsernameInfo { @@ -4783,6 +4794,7 @@ struct MHD_DigestAuthUsernameInfo * instead NULL is returned by #MHD_digest_auth_get_username3(). */ enum MHD_DigestAuthUsernameType uname_type; + /** * The username string. * Valid only if username is standard, extended, or userhash. @@ -4794,22 +4806,23 @@ struct MHD_DigestAuthUsernameInfo * This can be NULL is username is missing or invalid. */ char *username; + /** * The length of the @a username. * When the @a username is NULL, this member is always zero. */ size_t username_len; + /** * The userhash decoded to binary form. - * Used only if username type is userhash, always NULL if not used. - * @warning this is a binary data, no zero termination + * When not NULL, this points to binary sequence @a username_len /2 bytes + * long. + * @warning This is binary data, no zero termination. + * @warning To avoid buffer overruns, always check the size of the data before + * use, because @ userhash_bin can point even to zero-sized + * data. */ uint8_t *userhash_bin; - /** - * The number of bytes pointed by the @a userhash_bin. - * When the @a userhash_bin is NULL, this member is always zero. - */ - size_t userhash_bin_size; }; /** diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c @@ -881,20 +881,23 @@ get_rq_uname (const struct MHD_RqDAuth *params, buf_used += uname_info->username_len + 1; if (MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH == uname_type) { - uname_info->userhash_bin_size = MHD_hex_to_bin (uname_info->username, - uname_info->username_len, - buf + buf_used); - if ( (0 == uname_info->userhash_bin_size) && - (0 != uname_info->username_len) ) + size_t res; + uint8_t *const bin_data = (uint8_t *) (buf + buf_used); + res = MHD_hex_to_bin (uname_info->username, + uname_info->username_len, + bin_data); + if (res != uname_info->username_len / 2) { uname_info->userhash_bin = NULL; uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_INVALID; } else { - uname_info->userhash_bin = (uint8_t *) (buf + buf_used); + /* Avoid pointers outside allocated region when the size is zero */ + uname_info->userhash_bin = (0 != res) ? + bin_data : (uint8_t *) uname_info->username; uname_info->uname_type = MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH; - buf_used += uname_info->userhash_bin_size; + buf_used += res; } } else @@ -1093,7 +1096,6 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection) info->username = uname_strct.username; info->username_len = uname_strct.username_len; info->userhash_bin = uname_strct.userhash_bin; - info->userhash_bin_size = uname_strct.userhash_bin_size; } else info->uname_type = uname_type; diff --git a/src/testcurl/test_digestauth_emu_ext.c b/src/testcurl/test_digestauth_emu_ext.c @@ -383,8 +383,6 @@ ahc_echo (void *cls, } else if (NULL != creds->userhash_bin) mhdErrorExitDesc ("'userhash_bin' is NOT NULL"); - else if (0 != creds->userhash_bin_size) - mhdErrorExitDesc ("'userhash_bin_size' is NOT zero"); MHD_free (creds); dinfo = MHD_digest_auth_get_request_info3 (connection); @@ -419,8 +417,6 @@ ahc_echo (void *cls, } else if (NULL != dinfo->userhash_bin) mhdErrorExitDesc ("'userhash_bin' is NOT NULL"); - else if (0 != dinfo->userhash_bin_size) - mhdErrorExitDesc ("'userhash_bin_size' is NOT zero"); else if (MHD_DIGEST_AUTH_ALGO3_MD5 != dinfo->algo) { fprintf (stderr, "Unexpected 'algo'.\n"