aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/digestauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r--src/microhttpd/digestauth.c78
1 files changed, 44 insertions, 34 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index 16541523..12fa2f3a 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -1901,7 +1901,7 @@ calc_userdigest (struct DigestAlgorithm *da,
1901 1901
1902 1902
1903/** 1903/**
1904 * Calculate userdigest, return it as binary data. 1904 * Calculate userdigest, return it as a binary data.
1905 * 1905 *
1906 * The "userdigest" is the hash of the "username:realm:password" string. 1906 * The "userdigest" is the hash of the "username:realm:password" string.
1907 * 1907 *
@@ -1918,7 +1918,7 @@ calc_userdigest (struct DigestAlgorithm *da,
1918 * @param algo3 the digest algorithm 1918 * @param algo3 the digest algorithm
1919 * @param username the username 1919 * @param username the username
1920 * @param realm the realm 1920 * @param realm the realm
1921 * @param password the password, must be zero-terminated 1921 * @param password the password
1922 * @param[out] userdigest_bin the output buffer for userdigest; 1922 * @param[out] userdigest_bin the output buffer for userdigest;
1923 * if this function succeeds, then this buffer has 1923 * if this function succeeds, then this buffer has
1924 * #MHD_digest_get_hash_size(algo3) bytes of 1924 * #MHD_digest_get_hash_size(algo3) bytes of
@@ -2003,7 +2003,7 @@ calc_userhash (struct DigestAlgorithm *da,
2003 * 2003 *
2004 * The "userhash" is the hash of the string "username:realm". 2004 * The "userhash" is the hash of the string "username:realm".
2005 * 2005 *
2006 * The "Userhash" could be used to avoid sending username in cleartext in Digest 2006 * The "userhash" could be used to avoid sending username in cleartext in Digest
2007 * Authorization client's header. 2007 * Authorization client's header.
2008 * 2008 *
2009 * Userhash is not designed to hide the username in local database or files, 2009 * Userhash is not designed to hide the username in local database or files,
@@ -2015,7 +2015,7 @@ calc_userhash (struct DigestAlgorithm *da,
2015 * when loading list of the usernames to generate the userhash for every loaded 2015 * when loading list of the usernames to generate the userhash for every loaded
2016 * username (this will cause delays at the start with the long lists). 2016 * username (this will cause delays at the start with the long lists).
2017 * 2017 *
2018 * Once "userhash" is generated it could be used to identify users for clients 2018 * Once "userhash" is generated it could be used to identify users by clients
2019 * with "userhash" support. 2019 * with "userhash" support.
2020 * Avoid repetitive usage of this function for the same username/realm 2020 * Avoid repetitive usage of this function for the same username/realm
2021 * combination as it will cause excessive CPU load; save and re-use the result 2021 * combination as it will cause excessive CPU load; save and re-use the result
@@ -2034,6 +2034,7 @@ calc_userhash (struct DigestAlgorithm *da,
2034 * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is 2034 * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
2035 * not supported (or external error has occurred, 2035 * not supported (or external error has occurred,
2036 * see #MHD_FEATURE_EXTERN_HASH) 2036 * see #MHD_FEATURE_EXTERN_HASH)
2037 * @sa #MHD_digest_auth_calc_userhash_hex()
2037 * @note Available since #MHD_VERSION 0x00097701 2038 * @note Available since #MHD_VERSION 0x00097701
2038 * @ingroup authentication 2039 * @ingroup authentication
2039 */ 2040 */
@@ -2073,11 +2074,11 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
2073 2074
2074 2075
2075/** 2076/**
2076 * Calculate "userhash", return it as hexadecimal data. 2077 * Calculate "userhash", return it as hexadecimal string.
2077 * 2078 *
2078 * The "userhash" is the hash of the string "username:realm". 2079 * The "userhash" is the hash of the string "username:realm".
2079 * 2080 *
2080 * The "Userhash" could be used to avoid sending username in cleartext in Digest 2081 * The "userhash" could be used to avoid sending username in cleartext in Digest
2081 * Authorization client's header. 2082 * Authorization client's header.
2082 * 2083 *
2083 * Userhash is not designed to hide the username in local database or files, 2084 * Userhash is not designed to hide the username in local database or files,
@@ -2089,7 +2090,7 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
2089 * when loading list of the usernames to generate the userhash for every loaded 2090 * when loading list of the usernames to generate the userhash for every loaded
2090 * username (this will cause delays at the start with the long lists). 2091 * username (this will cause delays at the start with the long lists).
2091 * 2092 *
2092 * Once "userhash" is generated it could be used to identify users for clients 2093 * Once "userhash" is generated it could be used to identify users by clients
2093 * with "userhash" support. 2094 * with "userhash" support.
2094 * Avoid repetitive usage of this function for the same username/realm 2095 * Avoid repetitive usage of this function for the same username/realm
2095 * combination as it will cause excessive CPU load; save and re-use the result 2096 * combination as it will cause excessive CPU load; save and re-use the result
@@ -2098,16 +2099,17 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
2098 * @param algo3 the algorithm for userhash calculations 2099 * @param algo3 the algorithm for userhash calculations
2099 * @param username the username 2100 * @param username the username
2100 * @param realm the realm 2101 * @param realm the realm
2101 * @param[out] userhash_hex the output buffer for userhash as hex data; 2102 * @param[out] userhash_hex the output buffer for userhash as hex string;
2102 * if this function succeeds, then this buffer has 2103 * if this function succeeds, then this buffer has
2103 * #MHD_digest_get_hash_size(algo3)*2 chars long 2104 * #MHD_digest_get_hash_size(algo3)*2 chars long
2104 * userhash string 2105 * userhash zero-terminated string
2105 * @param bin_buf_size the size of the @a userhash_bin buffer, must be 2106 * @param bin_buf_size the size of the @a userhash_bin buffer, must be
2106 * at least #MHD_digest_get_hash_size(algo3)*2+1 chars long 2107 * at least #MHD_digest_get_hash_size(algo3)*2+1 chars long
2107 * @return MHD_YES on success, 2108 * @return MHD_YES on success,
2108 * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is 2109 * MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
2109 * not supported (or external error has occurred, 2110 * not supported (or external error has occurred,
2110 * see #MHD_FEATURE_EXTERN_HASH). 2111 * see #MHD_FEATURE_EXTERN_HASH).
2112 * @sa #MHD_digest_auth_calc_userhash()
2111 * @note Available since #MHD_VERSION 0x00097701 2113 * @note Available since #MHD_VERSION 0x00097701
2112 * @ingroup authentication 2114 * @ingroup authentication
2113 */ 2115 */
@@ -3135,16 +3137,17 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
3135 * @a mqop and the client uses this mode, then server generated nonces are 3137 * @a mqop and the client uses this mode, then server generated nonces are
3136 * used as one-time nonces because nonce-count is not supported in this old RFC. 3138 * used as one-time nonces because nonce-count is not supported in this old RFC.
3137 * Communication in this mode is very inefficient, especially if the client 3139 * Communication in this mode is very inefficient, especially if the client
3138 * requests several resources one-by-one as for every request new nonce must be 3140 * requests several resources one-by-one as for every request a new nonce must
3139 * generated and client repeat all requests twice (first time to get a new 3141 * be generated and client repeats all requests twice (first time to get a new
3140 * nonce and second time to perform an authorised request). 3142 * nonce and second time to perform an authorised request).
3141 * 3143 *
3142 * @param connection the MHD connection structure 3144 * @param connection the MHD connection structure
3143 * @param realm the realm to be used for authorization of the client 3145 * @param realm the realm for authorization of the client
3144 * @param username the username needs to be authenticated, must be in clear text 3146 * @param username the username to be authenticated, must be in clear text
3145 * even if userhash is used by the client 3147 * even if userhash is used by the client
3146 * @param password the password used in the authentication 3148 * @param password the password matching the @a username (and the @a realm)
3147 * @param nonce_timeout the nonce validity duration in seconds 3149 * @param nonce_timeout the period of seconds since nonce generation, when
3150 * the nonce is recognised as valid and not stale.
3148 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc 3151 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
3149 * exceeds the specified value then MHD_DAUTH_NONCE_STALE is 3152 * exceeds the specified value then MHD_DAUTH_NONCE_STALE is
3150 * returned; 3153 * returned;
@@ -3189,13 +3192,13 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection,
3189 * @a mqop and the client uses this mode, then server generated nonces are 3192 * @a mqop and the client uses this mode, then server generated nonces are
3190 * used as one-time nonces because nonce-count is not supported in this old RFC. 3193 * used as one-time nonces because nonce-count is not supported in this old RFC.
3191 * Communication in this mode is very inefficient, especially if the client 3194 * Communication in this mode is very inefficient, especially if the client
3192 * requests several resources one-by-one as for every request new nonce must be 3195 * requests several resources one-by-one as for every request a new nonce must
3193 * generated and client repeat all requests twice (first time to get a new 3196 * be generated and client repeats all requests twice (first time to get a new
3194 * nonce and second time to perform an authorised request). 3197 * nonce and second time to perform an authorised request).
3195 * 3198 *
3196 * @param connection the MHD connection structure 3199 * @param connection the MHD connection structure
3197 * @param realm the realm to be used for authorization of the client 3200 * @param realm the realm for authorization of the client
3198 * @param username the username needs to be authenticated, must be in clear text 3201 * @param username the username to be authenticated, must be in clear text
3199 * even if userhash is used by the client 3202 * even if userhash is used by the client
3200 * @param userdigest the precalculated binary hash of the string 3203 * @param userdigest the precalculated binary hash of the string
3201 * "username:realm:password", 3204 * "username:realm:password",
@@ -3517,14 +3520,16 @@ queue_auth_required_response3_inner (struct MHD_Connection *connection,
3517 size_t p; /* The position in the buffer */ 3520 size_t p; /* The position in the buffer */
3518 char *hdr_name; 3521 char *hdr_name;
3519 3522
3520 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_AUTH_ALGO3_SESSION)) 3523 if (0 == (((unsigned int) malgo3) & MHD_DIGEST_AUTH_ALGO3_NON_SESSION))
3521 { 3524 {
3522#ifdef HAVE_MESSAGES 3525#ifdef HAVE_MESSAGES
3523 MHD_DLOG (connection->daemon, 3526 MHD_DLOG (connection->daemon,
3524 _ ("The 'session' algorithms are not supported.\n")); 3527 _ ("Only non-'session' algorithms are supported.\n"));
3525#endif /* HAVE_MESSAGES */ 3528#endif /* HAVE_MESSAGES */
3526 return MHD_NO; 3529 return MHD_NO;
3527 } 3530 }
3531 malgo3 &= (enum MHD_DigestAuthMultiQOP)
3532 (~((enum MHD_DigestAuthMultiQOP) MHD_DIGEST_AUTH_ALGO3_NON_SESSION));
3528#ifdef MHD_MD5_SUPPORT 3533#ifdef MHD_MD5_SUPPORT
3529 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5)) 3534 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5))
3530 s_algo = MHD_DIGEST_AUTH_ALGO3_MD5; 3535 s_algo = MHD_DIGEST_AUTH_ALGO3_MD5;
@@ -3555,9 +3560,10 @@ queue_auth_required_response3_inner (struct MHD_Connection *connection,
3555 return MHD_NO; 3560 return MHD_NO;
3556 } 3561 }
3557 3562
3558 if (((unsigned int) mqop) != 3563 if (MHD_DIGEST_AUTH_MULT_QOP_AUTH_INT == mqop)
3559 (((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT))
3560 MHD_PANIC (_ ("Wrong 'mqop' value, API violation")); 3564 MHD_PANIC (_ ("Wrong 'mqop' value, API violation"));
3565 mqop &= (enum MHD_DigestAuthMultiQOP)
3566 (~((enum MHD_DigestAuthMultiQOP) MHD_DIGEST_AUTH_QOP_AUTH_INT));
3561 3567
3562 if (! digest_init_one_time (da, get_base_digest_algo (s_algo))) 3568 if (! digest_init_one_time (da, get_base_digest_algo (s_algo)))
3563 MHD_PANIC (_ ("Wrong 'algo' value, API violation")); 3569 MHD_PANIC (_ ("Wrong 'algo' value, API violation"));
@@ -3904,22 +3910,26 @@ queue_auth_required_response3_inner (struct MHD_Connection *connection,
3904 * any case client may assume that URI is in the same "protection 3910 * any case client may assume that URI is in the same "protection
3905 * space" if it starts with any of values specified here; 3911 * space" if it starts with any of values specified here;
3906 * could be NULL (clients typically assume that the same 3912 * could be NULL (clients typically assume that the same
3907 * credentials could be used for any URI on the same host) 3913 * credentials could be used for any URI on the same host);
3914 * this list provides information for the client only and does
3915 * not actually restrict anything on the server side
3908 * @param response the reply to send; should contain the "access denied" 3916 * @param response the reply to send; should contain the "access denied"
3909 * body; note that this function sets the "WWW Authenticate" 3917 * body;
3910 * header and that the caller should not do this; 3918 * note: this function sets the "WWW Authenticate" header and
3919 * the caller should not set this header;
3911 * the NULL is tolerated 3920 * the NULL is tolerated
3912 * @param signal_stale set to #MHD_YES if the nonce is stale to add 'stale=true' 3921 * @param signal_stale if set to #MHD_YES then indication of stale nonce used in
3922 * the client's request is signalled by adding 'stale=true'
3913 * to the authentication header, this instructs the client 3923 * to the authentication header, this instructs the client
3914 * to retry immediately with the new nonce and the same 3924 * to retry immediately with the new nonce and the same
3915 * credentials, without asking user for the new password 3925 * credentials, without asking user for the new password
3916 * @param mqop the QOP to use 3926 * @param mqop the QOP to use
3917 * @param malgo3 digest algorithm to use, MHD selects; if several algorithms 3927 * @param malgo3 digest algorithm to use; if several algorithms are allowed
3918 * are allowed then MD5 is preferred (currently, may be changed 3928 * then MD5 is preferred (currently, may be changed in next
3919 * in next versions) 3929 * versions)
3920 * @param userhash_support if set to non-zero value (#MHD_YES) then support of 3930 * @param userhash_support if set to non-zero value (#MHD_YES) then support of
3921 * userhash is indicated, the client may provide 3931 * userhash is indicated, allowing client to provide
3922 * hash("username:realm") instead of username in 3932 * hash("username:realm") instead of the username in
3923 * clear text; 3933 * clear text;
3924 * note that clients are allowed to provide the username 3934 * note that clients are allowed to provide the username
3925 * in cleartext even if this parameter set to non-zero; 3935 * in cleartext even if this parameter set to non-zero;
@@ -3928,8 +3938,8 @@ queue_auth_required_response3_inner (struct MHD_Connection *connection,
3928 * username; see #MHD_digest_auth_calc_userhash() and 3938 * username; see #MHD_digest_auth_calc_userhash() and
3929 * #MHD_digest_auth_calc_userhash_hex() 3939 * #MHD_digest_auth_calc_userhash_hex()
3930 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is 3940 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
3931 * added, indicating for the client that UTF-8 encoding 3941 * added, indicating for the client that UTF-8 encoding for
3932 * is preferred 3942 * the username is preferred
3933 * @return #MHD_YES on success, #MHD_NO otherwise 3943 * @return #MHD_YES on success, #MHD_NO otherwise
3934 * @note Available since #MHD_VERSION 0x00097701 3944 * @note Available since #MHD_VERSION 0x00097701
3935 * @ingroup authentication 3945 * @ingroup authentication