36#if defined(MHD_W32_MUTEX_)
37#ifndef WIN32_LEAN_AND_MEAN
38#define WIN32_LEAN_AND_MEAN 1
46#define TIMESTAMP_BIN_SIZE 4
53#define NONCE_STD_LEN(digest_size) \
54 ((digest_size) * 2 + TIMESTAMP_BIN_SIZE * 2)
61#define MAX_DIGEST SHA256_DIGEST_SIZE
66#ifndef HAVE_C_VARARRAYS
72#define VLA_ARRAY_LEN_DIGEST(n) (MAX_DIGEST)
80#define VLA_ARRAY_LEN_DIGEST(n) (n)
86#define VLA_CHECK_LEN_DIGEST(n) do { if ((n) > MAX_DIGEST) mhd_panic ( \
87 mhd_panic_cls, __FILE__, __LINE__, \
88 "VLA too big.\n"); } while (0)
94#define _BASE "Digest "
99#define MAX_USERNAME_LENGTH 128
104#define MAX_REALM_LENGTH 256
109#define MAX_AUTH_RESPONSE_LENGTH 256
117struct DigestAlgorithm
122 unsigned int digest_size;
186 for (
i = 0;
i < len; ++
i)
188 j = (
bin[
i] >> 4) & 0x0f;
189 hex[
i * 2] = (
char) ((
j <= 9) ? (
j +
'0') : (
j - 10 +
'a'));
191 hex[
i * 2 + 1] = (
char) ((
j <= 9) ? (
j +
'0') : (
j - 10 +
'a'));
214 struct DigestAlgorithm *
da,
219 const unsigned int digest_size =
da->digest_size;
233 (
const unsigned char *)
":",
236 (
const unsigned char *) nonce,
239 (
const unsigned char *)
":",
242 (
const unsigned char *)
cnonce,
280 struct DigestAlgorithm *
da)
290 (
const unsigned char *)
":",
293 (
const unsigned char *)
realm,
296 (
const unsigned char *)
":",
336 struct DigestAlgorithm *
da)
338 const unsigned int digest_size =
da->digest_size;
346 (
const unsigned char *) method,
349 (
const unsigned char *)
":",
352 (
const unsigned char *)
uri,
377 (
const unsigned char *)
ha1,
380 (
const unsigned char *)
":",
383 (
const unsigned char *) nonce,
386 (
const unsigned char*)
":",
394 (
const unsigned char *)
":",
397 (
const unsigned char *)
cnonce,
400 (
const unsigned char *)
":",
403 (
const unsigned char *)
qop,
406 (
const unsigned char *)
":",
410 (
const unsigned char *)
da->sessionkey,
494 if (size > (
size_t) ((
q2 -
q1) + 1))
495 size = (
q2 -
q1) + 1;
545 mod = daemon->nonce_nc_size;
562 nn = &daemon->nnc[
off];
563#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
574#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
583 (
nc + 64 >=
nn->nc) &&
584 (0 == ((1LL
U << (
nn->nc -
nc - 1)) &
nn->nmask)) )
587 nn->nmask |= (1LL
U << (
nn->nc -
nc - 1));
588#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
599#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
605 "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"));
610 if (64 >
nc -
nn->nc)
611 nn->nmask <<= (
nc -
nn->nc);
615#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
681 struct DigestAlgorithm *
da,
685 const unsigned int digest_size =
da->digest_size;
698 (
const unsigned char *)
":",
701 (
const unsigned char *) method,
704 (
const unsigned char *)
":",
708 (
const unsigned char *)
rnd,
711 (
const unsigned char *)
":",
714 (
const unsigned char *)
uri,
717 (
const unsigned char *)
":",
720 (
const unsigned char *)
realm,
729 nonce + digest_size * 2);
807 _ (
"Failed to allocate memory for copy of URI arguments.\n"));
858 struct DigestAlgorithm *
da,
870 const unsigned int digest_size =
da->digest_size;
933 if (
left > 32 * 1024)
951 _ (
"Authentication failed, invalid timestamp format.\n"));
970 daemon->digest_auth_random,
971 daemon->digest_auth_rand_size,
1013 _ (
"Authentication failed, invalid format.\n"));
1023 _ (
"Authentication failed, invalid nc format.\n"));
1049 _ (
"Failed to allocate memory for auth header processing.\n"));
1084 digest_size * 2 + 1);
1109 _ (
"Authentication failed, URI does not match.\n"));
1128 _ (
"Authentication failed, arguments do not match.\n"));
1135 return (0 ==
strcmp (response,
1184#define SETUP_DA(algo,da) \
1186 struct MD5Context md5; \
1187 struct sha256_ctx sha256; \
1190 char md5[MD5_DIGEST_SIZE * 2 + 1]; \
1191 char sha256[SHA256_DIGEST_SIZE * 2 + 1]; \
1193 struct DigestAlgorithm da; \
1197 case MHD_DIGEST_ALG_MD5: \
1198 da.digest_size = MD5_DIGEST_SIZE; \
1199 da.ctx = &ctx.md5; \
1201 da.sessionkey = skey.md5; \
1202 da.init = &MHD_MD5Init; \
1203 da.update = &MHD_MD5Update; \
1204 da.digest = &MHD_MD5Final; \
1206 case MHD_DIGEST_ALG_AUTO: \
1208 case MHD_DIGEST_ALG_SHA256: \
1209 da.digest_size = SHA256_DIGEST_SIZE; \
1210 da.ctx = &ctx.sha256; \
1211 da.alg = "SHA-256"; \
1212 da.sessionkey = skey.sha256; \
1213 da.init = &MHD_SHA256_init; \
1214 da.update = &MHD_SHA256_update; \
1215 da.digest = &MHD_SHA256_finish; \
1218 da.digest_size = 0; \
1219 mhd_assert (false); \
1289 if (
da.digest_size != digest_size)
1369 connection->
daemon->digest_auth_random,
1370 connection->
daemon->digest_auth_rand_size,
1383 "Could not register nonce (is the nonce array size zero?).\n"));
1390 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s",
1408 _ (
"Failed to allocate memory for auth response header.\n"));
1415 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s",
1450 _ (
"Failed to add Digest auth header.\n"));
struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
#define VLA_CHECK_LEN_DIGEST(n)
#define SETUP_DA(algo, da)
static void digest_calc_response(const char *ha1, const char *nonce, const char *noncecount, const char *cnonce, const char *qop, const char *method, const char *uri, const char *hentity, struct DigestAlgorithm *da)
#define NONCE_STD_LEN(digest_size)
static enum MHD_Result check_argument_match(struct MHD_Connection *connection, const char *args)
#define MAX_AUTH_RESPONSE_LENGTH
#define TIMESTAMP_BIN_SIZE
static void digest_calc_ha1_from_user(const char *alg, const char *username, const char *realm, const char *password, const char *nonce, const char *cnonce, struct DigestAlgorithm *da)
static size_t lookup_sub_value(char *dest, size_t size, const char *data, const char *key)
static enum MHD_Result check_nonce_nc(struct MHD_Connection *connection, const char *nonce, uint64_t nc)
#define MAX_USERNAME_LENGTH
static void calculate_nonce(uint32_t nonce_time, const char *method, const char *rnd, size_t rnd_size, const char *uri, const char *realm, struct DigestAlgorithm *da, char *nonce)
static enum MHD_Result test_header(struct MHD_Connection *connection, const char *key, size_t key_size, const char *value, size_t value_size, enum MHD_ValueKind kind)
#define VLA_ARRAY_LEN_DIGEST(n)
static void digest_calc_ha1_from_digest(const char *alg, struct DigestAlgorithm *da, const uint8_t *digest, const char *nonce, const char *cnonce)
static void cvthex(const unsigned char *bin, size_t len, char *hex)
_MHD_EXTERN char * MHD_digest_auth_get_username(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_digest_auth_check2(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN enum MHD_Result MHD_queue_auth_fail_response2(struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN int MHD_digest_auth_check_digest2(struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t *digest, size_t digest_size, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN enum MHD_Result MHD_queue_auth_fail_response(struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
static int digest_auth_check_all(struct MHD_Connection *connection, struct DigestAlgorithm *da, const char *realm, const char *username, const char *password, const uint8_t *digest, unsigned int nonce_timeout)
_MHD_EXTERN int MHD_digest_auth_check_digest(struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t digest[MHD_MD5_DIGEST_SIZE], unsigned int nonce_timeout)
_MHD_EXTERN int MHD_digest_auth_check(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
#define MHD_INVALID_NONCE
#define MHD_HTTP_UNAUTHORIZED
_MHD_EXTERN enum MHD_Result MHD_lookup_connection_value_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char **value_ptr, size_t *value_size_ptr)
_MHD_EXTERN enum MHD_Result MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
time_t MHD_monotonic_sec_counter(void)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)
#define MHD_STATICSTR_LEN_(macro)
MHD internal shared structures.
Header for platform missing functions.
limits values definitions
internal monotonic clock functions implementations
Header for string manipulating helpers.
#define MHD_MD5_DIGEST_SIZE
Calculation of SHA-256 digest.
struct MHD_HTTP_Header * headers_received
struct MHD_Daemon * daemon
void * unescape_callback_cls
UnescapeCallback unescape_callback
char nonce[MAX_NONCE_LENGTH]