libmicrohttpd

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

commit a2916400661cb7c468af5744ea284ec9157abac9
parent 5e5efd92797e01595ea69826cde808d8e13ae26e
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Thu, 25 Aug 2022 20:02:30 +0300

digestauth: keep results of algo and QOP parsing, renamed public struct member

Diffstat:
Msrc/include/microhttpd.h | 4++--
Msrc/microhttpd/Makefile.am | 2+-
Msrc/microhttpd/digestauth.c | 163+++----------------------------------------------------------------------------
Msrc/microhttpd/digestauth.h | 58+++++++++++++++++++++++++---------------------------------
Msrc/microhttpd/gen_auth.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/microhttpd/internal.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/microhttpd/mhd_str.h | 42++----------------------------------------
Asrc/microhttpd/mhd_str_types.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/microhttpd/test_auth_parse.c | 460+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/testcurl/test_digestauth2.c | 4++--
Msrc/testcurl/test_digestauth_emu_ext.c | 4++--
Mw32/common/libmicrohttpd-files.vcxproj | 1+
Mw32/common/libmicrohttpd-filters.vcxproj | 3+++
13 files changed, 631 insertions(+), 353 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -4789,7 +4789,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 0x00097525 + * @note Available since #MHD_VERSION 0x00097533 */ struct MHD_DigestAuthInfo { @@ -4799,7 +4799,7 @@ struct MHD_DigestAuthInfo * @warning Do not be confused with #MHD_DigestAuthAlgorithm, * which uses other values! */ - enum MHD_DigestAuthAlgo3 algo; + enum MHD_DigestAuthAlgo3 algo3; /** * The type of username used by client. diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am @@ -82,7 +82,7 @@ libmicrohttpd_la_SOURCES = \ mhd_mono_clock.c mhd_mono_clock.h \ mhd_limits.h \ sysfdsetsize.c sysfdsetsize.h \ - mhd_str.c mhd_str.h \ + mhd_str.c mhd_str.h mhd_str_types.h\ mhd_send.h mhd_send.c \ mhd_assert.h \ mhd_sockets.c mhd_sockets.h \ diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c @@ -134,37 +134,6 @@ #define MAX_AUTH_RESPONSE_LENGTH (MAX_DIGEST * 2) /** - * The token for MD5 algorithm. - */ -#define _MHD_MD5_TOKEN "MD5" - -/** - * The token for SHA-256 algorithm. - */ -#define _MHD_SHA256_TOKEN "SHA-256" - -/** - * The token for SHA-512/256 algorithm. - * Unsupported currently by MHD for authentication. - */ -#define _MHD_SHA512_256_TOKEN "SHA-512-256" - -/** - * The suffix token for "session" algorithms. - */ -#define _MHD_SESS_TOKEN "-sess" - -/** - * The "auth" token for QOP - */ -#define MHD_TOKEN_AUTH_ "auth" - -/** - * The "auth-int" token for QOP - */ -#define MHD_TOKEN_AUTH_INT_ "auth-int" - -/** * The required prefix of parameter with the extended notation */ #define MHD_DAUTH_EXT_PARAM_PREFIX "UTF-8'" @@ -729,89 +698,6 @@ get_rq_unames_size (const struct MHD_RqDAuth *params, /** - * Get client's Digest Authorization algorithm type. - * If no algorithm is specified by client, MD5 is assumed. - * @param params the Digest Authorization parameters - * @return the algorithm type - */ -static enum MHD_DigestAuthAlgo3 -get_rq_algo (const struct MHD_RqDAuth *params) -{ - const struct MHD_RqDAuthParam *const algo_param = - &params->algorithm; - if (NULL == algo_param->value.str) - return MHD_DIGEST_AUTH_ALGO3_MD5; /* Assume MD5 by default */ - - if (algo_param->quoted) - { - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_MD5_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_MD5; - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_SHA256_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_SHA256; - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_MD5_TOKEN _MHD_SESS_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION; - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_SHA256_TOKEN \ - _MHD_SESS_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION; - - /* Algorithms below are not supported by MHD for authentication */ - - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_SHA512_256_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_SHA512_256; - if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ - algo_param->value.len, \ - _MHD_SHA512_256_TOKEN \ - _MHD_SESS_TOKEN)) - return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION; - - /* No known algorithm has been detected */ - return MHD_DIGEST_AUTH_ALGO3_INVALID; - } - /* The algorithm value is not quoted */ - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_MD5; - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_SHA256; - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN _MHD_SESS_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION; - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN _MHD_SESS_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION; - - /* Algorithms below are not supported by MHD for authentication */ - - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_SHA512_256; - if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN _MHD_SESS_TOKEN, \ - algo_param->value.str, \ - algo_param->value.len)) - return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION; - - /* No known algorithm has been detected */ - return MHD_DIGEST_AUTH_ALGO3_INVALID; -} - - -/** * Get unquoted version of Digest Authorization parameter. * This function automatically zero-teminate the result. * @param param the parameter to extract @@ -973,45 +859,6 @@ get_rq_uname (const struct MHD_RqDAuth *params, /** - * Get QOP ('quality of protection') type. - * @param params the Digest Authorization parameters - * @return detected QOP ('quality of protection') type. - */ -static enum MHD_DigestAuthQOP -get_rq_qop (const struct MHD_RqDAuth *params) -{ - const struct MHD_RqDAuthParam *const qop_param = - &params->qop; - if (NULL == qop_param->value.str) - return MHD_DIGEST_AUTH_QOP_NONE; - if (qop_param->quoted) - { - if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \ - qop_param->value.len, \ - "auth")) - return MHD_DIGEST_AUTH_QOP_AUTH; - if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \ - qop_param->value.len, \ - "auth-int")) - return MHD_DIGEST_AUTH_QOP_AUTH_INT; - } - else - { - if (MHD_str_equal_caseless_s_bin_n_ ("auth", \ - qop_param->value.str, \ - qop_param->value.len)) - return MHD_DIGEST_AUTH_QOP_AUTH; - if (MHD_str_equal_caseless_s_bin_n_ ("auth-int", \ - qop_param->value.str, \ - qop_param->value.len)) - return MHD_DIGEST_AUTH_QOP_AUTH_INT; - } - /* No know QOP has been detected */ - return MHD_DIGEST_AUTH_QOP_INVALID; -} - - -/** * Result of request's Digest Authorization 'nc' value extraction */ enum MHD_GetRqNCResult @@ -1124,7 +971,7 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection) unif_buf_ptr = (uint8_t *) (info + 1); unif_buf_used = 0; - info->algo = get_rq_algo (params); + info->algo3 = params->algo3; if ( (MHD_DIGEST_AUTH_UNAME_TYPE_MISSING != uname_type) && (MHD_DIGEST_AUTH_UNAME_TYPE_INVALID != uname_type) ) @@ -1159,7 +1006,7 @@ MHD_digest_auth_get_request_info3 (struct MHD_Connection *connection) mhd_assert (unif_buf_size >= unif_buf_used); - info->qop = get_rq_qop (params); + info->qop = params->qop; if (NULL != params->cnonce.value.str) info->cnonce_len = params->cnonce.value.len; @@ -2110,7 +1957,7 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, /* ** Initial parameters checks and setup ** */ /* Get client's algorithm */ - c_algo = get_rq_algo (params); + c_algo = params->algo3; /* Check whether client's algorithm is allowed by function parameter */ if (((unsigned int) c_algo) != (((unsigned int) c_algo) & ((unsigned int) malgo3))) @@ -2135,7 +1982,7 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, if (! digest_setup (&da, get_base_digest_algo (c_algo))) MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); /* Check 'mqop' value */ - c_qop = get_rq_qop (params); + c_qop = params->qop; /* Check whether client's algorithm is allowed by function parameter */ if (((unsigned int) c_qop) != (((unsigned int) c_qop) & ((unsigned int) mqop))) @@ -2479,7 +2326,7 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, /* Update digest with ':' */ digest_update_with_colon (&da); /* Update digest with 'qop' value */ - unq_res = get_unquoted_param (&params->qop, tmp1, ptmp2, &tmp2_size, + unq_res = get_unquoted_param (&params->qop_raw, tmp1, ptmp2, &tmp2_size, &unquoted); if (_MHD_UNQ_OK != unq_res) return MHD_DAUTH_ERROR; diff --git a/src/microhttpd/digestauth.h b/src/microhttpd/digestauth.h @@ -50,43 +50,35 @@ #define _MHD_AUTH_DIGEST_BASE "Digest" /** - * Parameter of request's Digest Authorization header + * The token for MD5 algorithm. */ -struct MHD_RqDAuthParam -{ - /** - * The string with length, NOT zero-terminated - */ - struct _MHD_str_w_len value; - /** - * True if string must be "unquoted" before processing. - * This member is false if the string is used in DQUOTE marks, but no - * backslash-escape is used in the string. - */ - bool quoted; -}; +#define _MHD_MD5_TOKEN "MD5" /** - * Request client's Digest Authorization header parameters + * The token for SHA-256 algorithm. */ -struct MHD_RqDAuth -{ - struct MHD_RqDAuthParam nonce; - struct MHD_RqDAuthParam opaque; - struct MHD_RqDAuthParam algorithm; - struct MHD_RqDAuthParam response; - struct MHD_RqDAuthParam username; - struct MHD_RqDAuthParam username_ext; - struct MHD_RqDAuthParam realm; - struct MHD_RqDAuthParam uri; - struct MHD_RqDAuthParam qop; - struct MHD_RqDAuthParam cnonce; - struct MHD_RqDAuthParam nc; - /** - * True if 'userhash' parameter is used with value 'true'. - */ - bool userhash; -}; +#define _MHD_SHA256_TOKEN "SHA-256" + +/** + * The token for SHA-512/256 algorithm. + * Unsupported currently by MHD for authentication. + */ +#define _MHD_SHA512_256_TOKEN "SHA-512-256" + +/** + * The suffix token for "session" algorithms. + */ +#define _MHD_SESS_TOKEN "-sess" + +/** + * The "auth" token for QOP + */ +#define MHD_TOKEN_AUTH_ "auth" + +/** + * The "auth-int" token for QOP + */ +#define MHD_TOKEN_AUTH_INT_ "auth-int" #endif /* ! MHD_DIGESTAUTH_H */ diff --git a/src/microhttpd/gen_auth.c b/src/microhttpd/gen_auth.c @@ -274,6 +274,125 @@ struct dauth_token_param struct MHD_RqDAuthParam *const param; }; + +/** + * Get client's Digest Authorization algorithm type. + * If no algorithm is specified by client, MD5 is assumed. + * @param params the Digest Authorization 'algorithm' parameter + * @return the algorithm type + */ +static enum MHD_DigestAuthAlgo3 +get_rq_dauth_algo (const struct MHD_RqDAuthParam *const algo_param) +{ + if (NULL == algo_param->value.str) + return MHD_DIGEST_AUTH_ALGO3_MD5; /* Assume MD5 by default */ + + if (algo_param->quoted) + { + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_MD5_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_MD5; + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_SHA256_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_SHA256; + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_MD5_TOKEN _MHD_SESS_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION; + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_SHA256_TOKEN \ + _MHD_SESS_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION; + + /* Algorithms below are not supported by MHD for authentication */ + + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_SHA512_256_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_SHA512_256; + if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \ + algo_param->value.len, \ + _MHD_SHA512_256_TOKEN \ + _MHD_SESS_TOKEN)) + return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION; + + /* No known algorithm has been detected */ + return MHD_DIGEST_AUTH_ALGO3_INVALID; + } + /* The algorithm value is not quoted */ + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_MD5; + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_SHA256; + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN _MHD_SESS_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION; + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN _MHD_SESS_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION; + + /* Algorithms below are not supported by MHD for authentication */ + + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_SHA512_256; + if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN _MHD_SESS_TOKEN, \ + algo_param->value.str, \ + algo_param->value.len)) + return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION; + + /* No known algorithm has been detected */ + return MHD_DIGEST_AUTH_ALGO3_INVALID; +} + + +/** + * Get QOP ('quality of protection') type. + * @param qop_param the Digest Authorization 'QOP' parameter + * @return detected QOP ('quality of protection') type. + */ +static enum MHD_DigestAuthQOP +get_rq_dauth_qop (const struct MHD_RqDAuthParam *const qop_param) +{ + if (NULL == qop_param->value.str) + return MHD_DIGEST_AUTH_QOP_NONE; + if (qop_param->quoted) + { + if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \ + qop_param->value.len, \ + MHD_TOKEN_AUTH_)) + return MHD_DIGEST_AUTH_QOP_AUTH; + if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \ + qop_param->value.len, \ + MHD_TOKEN_AUTH_INT_)) + return MHD_DIGEST_AUTH_QOP_AUTH_INT; + } + else + { + if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_, \ + qop_param->value.str, \ + qop_param->value.len)) + return MHD_DIGEST_AUTH_QOP_AUTH; + if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_INT_, \ + qop_param->value.str, \ + qop_param->value.len)) + return MHD_DIGEST_AUTH_QOP_AUTH_INT; + } + /* No know QOP has been detected */ + return MHD_DIGEST_AUTH_QOP_INVALID; +} + + /** * Parse request Authorization header parameters for Digest Authentication * @param str the header string, everything after "Digest " substring @@ -306,16 +425,17 @@ parse_dauth_params (const char *str, static const struct _MHD_cstr_w_len userhash_tk = _MHD_S_STR_W_LEN ("userhash"); struct MHD_RqDAuthParam userhash; + struct MHD_RqDAuthParam algorithm; struct dauth_token_param map[] = { {&nonce_tk, &(pdauth->nonce)}, {&opaque_tk, &(pdauth->opaque)}, - {&algorithm_tk, &(pdauth->algorithm)}, + {&algorithm_tk, &algorithm}, {&response_tk, &(pdauth->response)}, {&username_tk, &(pdauth->username)}, {&username_ext_tk, &(pdauth->username_ext)}, {&realm_tk, &(pdauth->realm)}, {&uri_tk, &(pdauth->uri)}, - {&qop_tk, &(pdauth->qop)}, + {&qop_tk, &(pdauth->qop_raw)}, {&cnonce_tk, &(pdauth->cnonce)}, {&nc_tk, &(pdauth->nc)}, {&userhash_tk, &userhash} @@ -324,6 +444,7 @@ parse_dauth_params (const char *str, size_t p; memset (&userhash, 0, sizeof(userhash)); + memset (&algorithm, 0, sizeof(algorithm)); i = 0; /* Skip all whitespaces at start */ @@ -454,6 +575,7 @@ parse_dauth_params (const char *str, } /* Postprocess values */ + if (NULL != userhash.value.str) { if (userhash.quoted) @@ -470,6 +592,9 @@ parse_dauth_params (const char *str, else pdauth->userhash = false; + pdauth->algo3 = get_rq_dauth_algo (&algorithm); + pdauth->qop = get_rq_dauth_qop (&pdauth->qop_raw); + return true; } diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -62,6 +62,7 @@ #include "mhd_locks.h" #include "mhd_sockets.h" #include "mhd_itc_types.h" +#include "mhd_str_types.h" #if defined(BAUTH_SUPPORT) || defined(DAUTH_SUPPORT) #include "gen_auth.h" #endif /* BAUTH_SUPPORT || DAUTH_SUPPORT*/ @@ -2282,6 +2283,51 @@ struct MHD_Daemon }; +#ifdef DAUTH_SUPPORT + +/** + * Parameter of request's Digest Authorization header + */ +struct MHD_RqDAuthParam +{ + /** + * The string with length, NOT zero-terminated + */ + struct _MHD_str_w_len value; + /** + * True if string must be "unquoted" before processing. + * This member is false if the string is used in DQUOTE marks, but no + * backslash-escape is used in the string. + */ + bool quoted; +}; + +/** + * Request client's Digest Authorization header parameters + */ +struct MHD_RqDAuth +{ + struct MHD_RqDAuthParam nonce; + struct MHD_RqDAuthParam opaque; + struct MHD_RqDAuthParam response; + struct MHD_RqDAuthParam username; + struct MHD_RqDAuthParam username_ext; + struct MHD_RqDAuthParam realm; + struct MHD_RqDAuthParam uri; + /* The raw QOP value, used in the 'response' calculation */ + struct MHD_RqDAuthParam qop_raw; + struct MHD_RqDAuthParam cnonce; + struct MHD_RqDAuthParam nc; + + /* Decoded values are below */ + bool userhash; /* True if 'userhash' parameter has value 'true'. */ + enum MHD_DigestAuthAlgo3 algo3; + enum MHD_DigestAuthQOP qop; +}; + + +#endif /* DAUTH_SUPPORT */ + /** * Insert an element at the head of a DLL. Assumes that head, tail and * element are structs with prev and next fields. diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h @@ -38,6 +38,8 @@ #include <stdbool.h> #endif /* HAVE_STDBOOL_H */ +#include "mhd_str_types.h" + #if defined(_MSC_FULL_VER) && ! defined(_SSIZE_T_DEFINED) #define _SSIZE_T_DEFINED typedef intptr_t ssize_t; @@ -47,46 +49,6 @@ typedef intptr_t ssize_t; #include "mhd_limits.h" #endif /* MHD_FAVOR_SMALL_CODE */ -#ifndef MHD_STATICSTR_LEN_ -/** - * Determine length of static string / macro strings at compile time. - */ -#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) -#endif /* ! MHD_STATICSTR_LEN_ */ - -/** - * Constant string with length - */ -struct _MHD_cstr_w_len -{ - const char *const str; - const size_t len; -}; - -/** - * String with length - */ -struct _MHD_str_w_len -{ - const char *str; - size_t len; -}; - -/** - * Modifiable string with length - */ -struct _MHD_mstr_w_len -{ - char *str; - size_t len; -}; - -/** - * Static string initialiser for struct _MHD_str_w_len - */ -#define _MHD_S_STR_W_LEN(str) { str, MHD_STATICSTR_LEN_(str) } - - /* * Block of functions/macros that use US-ASCII charset as required by HTTP * standards. Not affected by current locale settings. diff --git a/src/microhttpd/mhd_str_types.h b/src/microhttpd/mhd_str_types.h @@ -0,0 +1,68 @@ +/* + This file is part of libmicrohttpd + Copyright (C) 2015-2022 Karlson2k (Evgeny Grin) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * @file microhttpd/mhd_str_types.h + * @brief Header for string manipulating helpers types + * @author Karlson2k (Evgeny Grin) + */ + +#ifndef MHD_STR_TYPES_H +#define MHD_STR_TYPES_H 1 + +#ifndef MHD_STATICSTR_LEN_ +/** + * Determine length of static string / macro strings at compile time. + */ +#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) +#endif /* ! MHD_STATICSTR_LEN_ */ + +/** + * Constant string with length + */ +struct _MHD_cstr_w_len +{ + const char *const str; + const size_t len; +}; + +/** + * String with length + */ +struct _MHD_str_w_len +{ + const char *str; + size_t len; +}; + +/** + * Modifiable string with length + */ +struct _MHD_mstr_w_len +{ + char *str; + size_t len; +}; + +/** + * Static string initialiser for struct _MHD_str_w_len + */ +#define _MHD_S_STR_W_LEN(str) { str, MHD_STATICSTR_LEN_(str) } + +#endif /* MHD_STR_TYPES_H */ diff --git a/src/microhttpd/test_auth_parse.c b/src/microhttpd/test_auth_parse.c @@ -956,13 +956,15 @@ cmp_dauth_param (const char *pname, const struct MHD_RqDAuthParam *param, if (0 != ret) { fprintf (stderr, "Parameter '%s' parsed incorrectly:\n", pname); - fprintf (stderr, "\tRESULT :\tvalue.str: %s", + fprintf (stderr, "\tRESULT :\tvalue.str: %.*s", + (int) (param->value.str ? param->value.len : 6), param->value.str ? param->value.str : "(NULL)"); fprintf (stderr, "\tvalue.len: %u", (unsigned) param->value.len); fprintf (stderr, "\tquoted: %s\n", (unsigned) param->quoted ? "true" : "false"); - fprintf (stderr, "\tEXPECTED:\tvalue.str: %s", + fprintf (stderr, "\tEXPECTED:\tvalue.str: %.*s", + (int) (expected_value ? expected_len : 6), expected_value ? expected_value : "(NULL)"); fprintf (stderr, "\tvalue.len: %u", (unsigned) expected_len); @@ -977,13 +979,14 @@ cmp_dauth_param (const char *pname, const struct MHD_RqDAuthParam *param, static unsigned int expect_digest_n (const char *hdr, size_t hdr_len, const char *nonce, - const char *algorithm, + enum MHD_DigestAuthAlgo3 algo3, const char *response, const char *username, const char *username_ext, const char *realm, const char *uri, - const char *qop, + const char *qop_raw, + enum MHD_DigestAuthQOP qop, const char *cnonce, const char *nc, int userhash, @@ -1003,14 +1006,31 @@ expect_digest_n (const char *hdr, size_t hdr_len, ret = 0; ret += cmp_dauth_param ("nonce", &h->nonce, nonce); - ret += cmp_dauth_param ("algorithm", &h->algorithm, algorithm); + if (h->algo3 != algo3) + { + ret += 1; + fprintf (stderr, "Parameter 'algorithm' detected incorrectly:\n"); + fprintf (stderr, "\tRESULT :\t%u\n", + (unsigned) h->algo3); + fprintf (stderr, "\tEXPECTED:\t%u\n", + (unsigned) algo3); + } ret += cmp_dauth_param ("response", &h->response, response); ret += cmp_dauth_param ("username", &h->username, username); ret += cmp_dauth_param ("username_ext", &h->username_ext, username_ext); ret += cmp_dauth_param ("realm", &h->realm, realm); ret += cmp_dauth_param ("uri", &h->uri, uri); - ret += cmp_dauth_param ("qop", &h->qop, qop); + ret += cmp_dauth_param ("qop", &h->qop_raw, qop_raw); + if (h->qop != qop) + { + ret += 1; + fprintf (stderr, "Parameter 'qop' detected incorrectly:\n"); + fprintf (stderr, "\tRESULT :\t%u\n", + (unsigned) h->qop); + fprintf (stderr, "\tEXPECTED:\t%u\n", + (unsigned) qop); + } ret += cmp_dauth_param ("cnonce", &h->cnonce, cnonce); ret += cmp_dauth_param ("nc", &h->nc, nc); if (h->userhash != ! (! userhash)) @@ -1035,102 +1055,286 @@ expect_digest_n (const char *hdr, size_t hdr_len, } -#define expect_digest(h,no,a,rs,un,ux,rm,ur,q,c,nc,uh) \ +#define expect_digest(h,no,a,rs,un,ux,rm,ur,qr,qe,c,nc,uh) \ expect_digest_n(h,MHD_STATICSTR_LEN_(h),\ - no,a,rs,un,ux,rm,ur,q,c,nc,uh,__LINE__) + no,a,rs,un,ux,rm,ur,qr,qe,c,nc,uh,__LINE__) static unsigned int check_digest (void) { unsigned int r = 0; /**< The number of errors */ - r += expect_digest ("Digest", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, 0); - r += expect_digest ("Digest nc=1", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=\"1\"", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=\"1\" ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest ,nc=\"1\" ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=\"1\", ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=\"1\" , ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=1, ", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest nc=1 , ", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest ,,,nc=1, ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest ,,,nc=1 , ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1", 0); - r += expect_digest ("Digest ,,,nc=\"1 \", ", NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, "1 ", 0); - r += expect_digest ("Digest nc=\"1 \"", NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, "1 ", 0); - r += expect_digest ("Digest nc=\"1 \" ,", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1 ", 0); - r += expect_digest ("Digest nc=\"1 \", ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1 ", 0); - r += expect_digest ("Digest nc=\"1;\", ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1;", 0); - r += expect_digest ("Digest nc=\"1\\;\", ", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, "1\\;", 0); - - r += expect_digest ("Digest userhash=false", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 0); - r += expect_digest ("Digest userhash=\"false\"", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 0); - r += expect_digest ("Digest userhash=foo", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 0); - r += expect_digest ("Digest userhash=true", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash=\"true\"", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash=\"\\t\\r\\u\\e\"", NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash=TRUE", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash=True", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash = true", NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, NULL, 1); - r += expect_digest ("Digest userhash=True2", NULL, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, 0); - r += expect_digest ("Digest userhash=\" true\"", NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, NULL, 0); + r += expect_digest ("Digest", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest nc=1", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, NULL, \ + MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=\"1\"", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=\"1\" ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest ,nc=\"1\" ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=\"1\", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=\"1\" , ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=1, ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest nc=1 , ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest ,,,nc=1, ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest ,,,nc=1 , ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0); + r += expect_digest ("Digest ,,,nc=\"1 \", ", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0); + r += expect_digest ("Digest nc=\"1 \"", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0); + r += expect_digest ("Digest nc=\"1 \" ,", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0); + r += expect_digest ("Digest nc=\"1 \", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0); + r += expect_digest ("Digest nc=\"1;\", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1;", 0); + r += expect_digest ("Digest nc=\"1\\;\", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1\\;", 0); + + r += expect_digest ("Digest userhash=false", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest userhash=\"false\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest userhash=foo", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest userhash=true", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash=\"true\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash=\"\\t\\r\\u\\e\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash=TRUE", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash=True", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash = true", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1); + r += expect_digest ("Digest userhash=True2", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest userhash=\" true\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + + r += expect_digest ("Digest algorithm=MD5", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=md5", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=Md5", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=mD5", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"MD5\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"\\M\\D\\5\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"\\m\\d\\5\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=SHA-256", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=sha-256", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=Sha-256", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"SHA-256\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"SHA\\-25\\6\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=\"shA-256\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=MD5-sess", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=MD5-SESS", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=md5-Sess", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=SHA-256-seSS", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=SHA-512-256", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA512_256, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=SHA-512-256-sess", NULL, \ + MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=MD5-2", NULL, \ + MHD_DIGEST_AUTH_ALGO3_INVALID, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=MD5-sess2", NULL, \ + MHD_DIGEST_AUTH_ALGO3_INVALID, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=SHA-256-512", NULL, \ + MHD_DIGEST_AUTH_ALGO3_INVALID, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + r += expect_digest ("Digest algorithm=", NULL, \ + MHD_DIGEST_AUTH_ALGO3_INVALID, \ + NULL, NULL, NULL, NULL, NULL, \ + NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0); + + r += expect_digest ("Digest qop=auth", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"auth\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0); + r += expect_digest ("Digest qop=Auth", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "Auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0); + r += expect_digest ("Digest qop=AUTH", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "AUTH", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"\\A\\ut\\H\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "\\A\\ut\\H", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"auth \"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auth ", MHD_DIGEST_AUTH_QOP_INVALID, NULL, NULL, 0); + r += expect_digest ("Digest qop=auth-int", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auth-int", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"auth-int\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auth-int", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"auTh-iNt\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auTh-iNt", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0); + r += expect_digest ("Digest qop=\"auTh-iNt2\"", NULL, \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ + NULL, NULL, NULL, NULL, NULL, \ + "auTh-iNt2", MHD_DIGEST_AUTH_QOP_INVALID, NULL, NULL, 0); r += expect_digest ("Digest username=\"test@example.com\", " \ - "realm=\"users@example.com\", nonce=\"32141232413abcde\", " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "realm=\"users@example.com\", " \ + "nonce=\"32141232413abcde\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", NULL, \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_MD5, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ - NULL, "users@example.com", "/example", "auth", \ + NULL, "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, \ "0a4f113b", "00000001", 0); r += expect_digest ("Digest username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", "SHA-256", \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest username=test@example.com, " \ - "realm=users@example.com, algorithm=\"SHA-256\", " \ + "realm=users@example.com, algorithm=\"SHA-256-sess\", " \ "nonce=32141232413abcde, " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=/example, qop=\"auth\", nc=\"00000001\", cnonce=0a4f113b, " \ + "uri=/example, qop=\"auth\", nc=\"00000001\", " \ + "cnonce=0a4f113b, " \ "response=6629fae49393a05397450978507c4ef1, " \ - "opaque=sadfljk32sdaf", "32141232413abcde", "SHA-256", \ + "opaque=sadfljk32sdaf", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest username = \"test@example.com\", " \ "realm\t=\t\"users@example.com\", algorithm\t= SHA-256, " \ @@ -1140,21 +1344,25 @@ check_digest (void) "cnonce\t\t\t= \"0a4f113b\", " \ "response =\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\t\t\"sadfljk32sdaf\"", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest username=\"test@example.com\"," \ - "realm=\"users@example.com\",algorithm=SHA-256," \ + "realm=\"users@example.com\",algorithm=SHA-512-256," \ "nonce=\"32141232413abcde\"," \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates," \ - "uri=\"/example\",qop=auth,nc=00000001,cnonce=\"0a4f113b\"," \ + "uri=\"/example\",qop=auth,nc=00000001," \ + "cnonce=\"0a4f113b\"," \ "response=\"6629fae49393a05397450978507c4ef1\"," \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", "SHA-256", \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA512_256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest username=\"test@example.com\"," \ "realm=\"users@example.com\",algorithm=SHA-256," \ @@ -1162,107 +1370,128 @@ check_digest (void) "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates," \ "uri=\"/example\",qop=auth,nc=00000001,cnonce=\"0a4f113b\"," \ "response=\"6629fae49393a05397450978507c4ef1\"," \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", "SHA-256", \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=zyx, username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", "SHA-256", \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ - "opaque=\"sadfljk32sdaf\"", "32141232413abcde", "SHA-256", \ + "opaque=\"sadfljk32sdaf\"", "32141232413abcde", + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\",,,,,", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx\", username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx, abc\", " \ "username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx, abc=cde\", " \ "username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \ - "SHA-256", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx, abc=cde\", " \ "username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " \ + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\", foo=\"bar1, bar2\"", \ - "32141232413abcde", "SHA-256", \ + "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx, \\\\\"abc=cde\\\\\"\", " \ "username=\"test@example.com\", " \ @@ -1272,23 +1501,28 @@ check_digest (void) "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\", foo=\"bar1, bar2\"", \ - "32141232413abcde", "SHA-256", \ + "32141232413abcde", + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); r += expect_digest ("Digest abc=\"zyx, \\\\\"abc=cde\\\\\"\", " \ "username=\"test@example.com\", " \ "realm=\"users@example.com\", algorithm=SHA-256, " \ "nonce=\"32141232413abcde\", " \ "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \ - "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \ + "uri=\"/example\", qop=auth, nc=00000001, " + "cnonce=\"0a4f113b\", " \ "response=\"6629fae49393a05397450978507c4ef1\", " \ "opaque=\"sadfljk32sdaf\", foo=\",nc=02\"", - "32141232413abcde", "SHA-256", \ + "32141232413abcde", \ + MHD_DIGEST_AUTH_ALGO3_SHA256, \ "6629fae49393a05397450978507c4ef1", "test@example.com", \ "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \ - "users@example.com", "/example", "auth", "0a4f113b", \ + "users@example.com", "/example", \ + "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \ "00000001", 0); return r; diff --git a/src/testcurl/test_digestauth2.c b/src/testcurl/test_digestauth2.c @@ -548,12 +548,12 @@ ahc_echo (void *cls, else if (NULL != dinfo->userhash_bin) mhdErrorExitDesc ("'userhash_bin' is NOT NULL"); } - if (algo3 != dinfo->algo) + if (algo3 != dinfo->algo3) { fprintf (stderr, "Unexpected 'algo'.\n" "Expected: %d\tRecieved: %d. ", (int) algo3, - (int) dinfo->algo); + (int) dinfo->algo3); mhdErrorExitDesc ("Wrong 'algo'"); } if (! test_rfc2069) diff --git a/src/testcurl/test_digestauth_emu_ext.c b/src/testcurl/test_digestauth_emu_ext.c @@ -417,12 +417,12 @@ ahc_echo (void *cls, } else if (NULL != dinfo->userhash_bin) mhdErrorExitDesc ("'userhash_bin' is NOT NULL"); - else if (MHD_DIGEST_AUTH_ALGO3_MD5 != dinfo->algo) + else if (MHD_DIGEST_AUTH_ALGO3_MD5 != dinfo->algo3) { fprintf (stderr, "Unexpected 'algo'.\n" "Expected: %d\tRecieved: %d. ", (int) MHD_DIGEST_AUTH_ALGO3_MD5, - (int) dinfo->algo); + (int) dinfo->algo3); mhdErrorExitDesc ("Wrong 'algo'"); } else if (MHD_STATICSTR_LEN_ (CNONCE_EMU) != dinfo->cnonce_len) diff --git a/w32/common/libmicrohttpd-files.vcxproj b/w32/common/libmicrohttpd-files.vcxproj @@ -52,6 +52,7 @@ <ClInclude Include="$(MhdSrc)microhttpd\tsearch.h" /> <ClInclude Include="$(MhdSrc)microhttpd\sysfdsetsize.h" /> <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h" /> + <ClInclude Include="$(MhdSrc)microhttpd\mhd_str_types.h" /> <ClInclude Include="$(MhdSrc)microhttpd\mhd_threads.h" /> <ClInclude Include="$(MhdSrc)microhttpd\mhd_locks.h" /> <ClInclude Include="$(MhdSrc)microhttpd\mhd_send.h" /> diff --git a/w32/common/libmicrohttpd-filters.vcxproj b/w32/common/libmicrohttpd-filters.vcxproj @@ -100,6 +100,9 @@ <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h"> <Filter>Internal Headers</Filter> </ClInclude> + <ClInclude Include="$(MhdSrc)microhttpd\mhd_str_types.h"> + <Filter>Internal Headers</Filter> + </ClInclude> <ClInclude Include="$(MhdSrc)microhttpd\mhd_threads.h"> <Filter>Internal Headers</Filter> </ClInclude>