diff options
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r-- | src/microhttpd/digestauth.c | 78 |
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 |