diff options
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r-- | src/microhttpd/digestauth.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c index e8983d62..a3399a65 100644 --- a/src/microhttpd/digestauth.c +++ b/src/microhttpd/digestauth.c | |||
@@ -1963,7 +1963,13 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, | |||
1963 | return MHD_DAUTH_WRONG_HEADER; /* Parameters cannot be used together */ | 1963 | return MHD_DAUTH_WRONG_HEADER; /* Parameters cannot be used together */ |
1964 | else if ((NULL != params->username_ext.value.str) && | 1964 | else if ((NULL != params->username_ext.value.str) && |
1965 | (MHD_DAUTH_EXT_PARAM_MIN_LEN > params->username_ext.value.len)) | 1965 | (MHD_DAUTH_EXT_PARAM_MIN_LEN > params->username_ext.value.len)) |
1966 | return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */ | 1966 | return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */ |
1967 | else if (params->userhash && (NULL == params->username.value.str)) | ||
1968 | return MHD_DAUTH_WRONG_HEADER; /* Userhash cannot be used with extended notation */ | ||
1969 | else if (params->userhash && (digest_size * 2 > params->username.value.len)) | ||
1970 | return MHD_DAUTH_WRONG_HEADER; /* Too few chars for correct userhash */ | ||
1971 | else if (params->userhash && (digest_size * 4 < params->username.value.len)) | ||
1972 | return MHD_DAUTH_WRONG_HEADER; /* Too many chars for correct userhash */ | ||
1967 | 1973 | ||
1968 | if (NULL == params->realm.value.str) | 1974 | if (NULL == params->realm.value.str) |
1969 | return MHD_DAUTH_WRONG_HEADER; | 1975 | return MHD_DAUTH_WRONG_HEADER; |
@@ -2039,32 +2045,48 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, | |||
2039 | 2045 | ||
2040 | /* Check 'username' */ | 2046 | /* Check 'username' */ |
2041 | username_len = strlen (username); | 2047 | username_len = strlen (username); |
2042 | if (NULL != params->username.value.str) | 2048 | if (! params->userhash) |
2043 | { /* Username in standard notation */ | 2049 | { |
2044 | if (! is_param_equal (¶ms->username, username, username_len)) | 2050 | if (NULL != params->username.value.str) |
2045 | return MHD_DAUTH_WRONG_USERNAME; | 2051 | { /* Username in standard notation */ |
2052 | if (! is_param_equal (¶ms->username, username, username_len)) | ||
2053 | return MHD_DAUTH_WRONG_USERNAME; | ||
2054 | } | ||
2055 | else | ||
2056 | { /* Username in extended notation */ | ||
2057 | char *r_uname; | ||
2058 | size_t buf_size = params->username_ext.value.len; | ||
2059 | ssize_t res; | ||
2060 | |||
2061 | mhd_assert (NULL != params->username_ext.value.str); | ||
2062 | mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */ | ||
2063 | buf_size += 1; /* For zero-termination */ | ||
2064 | buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN; | ||
2065 | r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size); | ||
2066 | if (NULL == r_uname) | ||
2067 | return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ? | ||
2068 | MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR; | ||
2069 | res = get_rq_extended_uname_copy_z (params->username_ext.value.str, | ||
2070 | params->username_ext.value.len, | ||
2071 | r_uname, buf_size); | ||
2072 | if (0 > res) | ||
2073 | return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */ | ||
2074 | if ((username_len != (size_t) res) || | ||
2075 | (0 != memcmp (username, r_uname, username_len))) | ||
2076 | return MHD_DAUTH_WRONG_USERNAME; | ||
2077 | } | ||
2046 | } | 2078 | } |
2047 | else | 2079 | else |
2048 | { /* Username in extended notation */ | 2080 | { /* Userhash */ |
2049 | char *r_uname; | 2081 | mhd_assert (NULL != params->username.value.str); |
2050 | size_t buf_size = params->username_ext.value.len; | 2082 | digest_init (da); |
2051 | ssize_t res; | 2083 | digest_update (da, username, username_len); |
2052 | 2084 | digest_update_with_colon (da); | |
2053 | mhd_assert (NULL != params->username_ext.value.str); | 2085 | digest_update (da, realm, realm_len); |
2054 | mhd_assert (MHD_DAUTH_EXT_PARAM_MIN_LEN <= buf_size); /* It was checked already */ | 2086 | digest_calc_hash (da, hash1_bin); |
2055 | buf_size += 1; /* For zero-termination */ | 2087 | mhd_assert (sizeof (tmp1) >= (2 * digest_size + 1)); |
2056 | buf_size -= MHD_DAUTH_EXT_PARAM_MIN_LEN; | 2088 | MHD_bin_to_hex (hash1_bin, digest_size, tmp1); |
2057 | r_uname = get_buffer_for_size (tmp1, ptmp2, &tmp2_size, buf_size); | 2089 | if (! is_param_equal_caseless (¶ms->username, tmp1, 2 * digest_size)) |
2058 | if (NULL == r_uname) | ||
2059 | return (_MHD_AUTH_DIGEST_MAX_PARAM_SIZE < buf_size) ? | ||
2060 | MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR; | ||
2061 | res = get_rq_extended_uname_copy_z (params->username_ext.value.str, | ||
2062 | params->username_ext.value.len, | ||
2063 | r_uname, buf_size); | ||
2064 | if (0 > res) | ||
2065 | return MHD_DAUTH_WRONG_HEADER; /* Broken extended notation */ | ||
2066 | if ((username_len != (size_t) res) || | ||
2067 | (0 != memcmp (username, r_uname, username_len))) | ||
2068 | return MHD_DAUTH_WRONG_USERNAME; | 2090 | return MHD_DAUTH_WRONG_USERNAME; |
2069 | } | 2091 | } |
2070 | /* 'username' valid */ | 2092 | /* 'username' valid */ |