33 #if defined(MHD_W32_MUTEX_) 34 #ifndef WIN32_LEAN_AND_MEAN 35 #define WIN32_LEAN_AND_MEAN 1 40 #define HASH_MD5_HEX_LEN (2 * MHD_MD5_DIGEST_SIZE) 42 #define TIMESTAMP_BIN_SIZE 4 43 #define TIMESTAMP_HEX_LEN (2 * TIMESTAMP_BIN_SIZE) 46 #define NONCE_STD_LEN (HASH_MD5_HEX_LEN + TIMESTAMP_HEX_LEN) 51 #define _BASE "Digest " 56 #define MAX_USERNAME_LENGTH 128 61 #define MAX_REALM_LENGTH 256 66 #define MAX_AUTH_RESPONSE_LENGTH 128 84 for (i = 0; i < len; ++i)
86 j = (bin[i] >> 4) & 0x0f;
87 hex[i * 2] = (char)((j <= 9) ? (j +
'0') : (j - 10 +
'a'));
89 hex[i * 2 + 1] = (char)((j <= 9) ? (j +
'0') : (j - 10 +
'a'));
126 (
const unsigned char *)
":",
129 (
const unsigned char *) nonce,
132 (
const unsigned char *)
":",
135 (
const unsigned char *) cnonce,
166 const char *username,
168 const char *password,
178 (
const unsigned char *) username,
181 (
const unsigned char *)
":",
184 (
const unsigned char *) realm,
187 (
const unsigned char *)
":",
190 (
const unsigned char *) password,
218 const char *noncecount,
234 (
const unsigned char *) method,
237 (
const unsigned char *)
":",
240 (
const unsigned char *) uri,
243 if (0 == strcasecmp(qop,
265 (
const unsigned char *) ha1,
268 (
const unsigned char *)
":",
271 (
const unsigned char *) nonce,
274 (
const unsigned char*)
":",
279 (
const unsigned char *) noncecount,
280 strlen (noncecount));
282 (
const unsigned char *)
":",
285 (
const unsigned char *) cnonce,
288 (
const unsigned char *)
":",
291 (
const unsigned char *) qop,
294 (
const unsigned char *)
":",
298 (
const unsigned char *) ha2hex,
338 keylen = strlen (key);
342 if (
NULL == (eq = strchr (ptr,
366 (eq == &ptr[keylen]) )
370 len = strlen (q1) + 1;
382 if (size > (
size_t) ((q2 - q1) + 1))
383 size = (q2 - q1) + 1;
427 noncelen = strlen (
nonce) + 1;
433 mod = daemon->nonce_nc_size;
441 off = (off << 8) | (*np ^ (off >> 24));
450 nn = &daemon->nnc[off];
465 if ( (nc < nn->
nc) &&
467 (
nc + 64 >= nn->
nc) &&
468 (0 == ((1LLU << (nn->
nc -
nc - 1)) & nn->
nmask)) )
471 nn->
nmask |= (1LLU << (nn->
nc -
nc - 1));
476 if ( (nc <= nn->
nc) ||
477 (0 != strcmp (nn->
nonce,
484 _(
"Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"));
489 if (64 >
nc - nn->
nc)
515 if (
NULL == (header =
520 if (0 != strncmp (header,
530 return strdup (user);
562 timestamp[0] = (
unsigned char)((nonce_time & 0xff000000) >> 0x18);
563 timestamp[1] = (
unsigned char)((nonce_time & 0x00ff0000) >> 0x10);
564 timestamp[2] = (
unsigned char)((nonce_time & 0x0000ff00) >> 0x08);
565 timestamp[3] = (
unsigned char)((nonce_time & 0x000000ff));
570 (
const unsigned char *)
":",
573 (
const unsigned char *) method,
576 (
const unsigned char *)
":",
580 (
const unsigned char *) rnd,
583 (
const unsigned char *)
":",
586 (
const unsigned char *) uri,
589 (
const unsigned char *)
":",
592 (
const unsigned char *) realm,
631 if (0 != strcmp (key,
664 unsigned int num_headers;
667 argb = strdup (args);
671 MHD_DLOG (connection->
daemon,
672 _(
"Failed to allocate memory for copy of URI arguments\n"));
693 if (0 != num_headers)
721 const char *username,
722 const char *password,
724 unsigned int nonce_timeout)
734 const char *hentity =
NULL;
748 if (0 != strncmp (header,
753 left = strlen (header);
763 (0 != strcmp (username,
766 left -= strlen (
"username") + len;
780 left -= strlen (
"realm") + len;
788 left -= strlen (
"nonce") + len;
789 if (left > 32 * 1024)
807 _(
"Authentication failed, invalid timestamp format.\n"));
817 if ( (t > nonce_time + nonce_timeout) ||
818 (nonce_time + nonce_timeout < nonce_time) )
826 daemon->digest_auth_random,
827 daemon->digest_auth_rand_size,
841 if (0 != strcmp (nonce, noncehashexp))
868 _(
"Authentication failed, invalid format.\n"));
878 _(
"Authentication failed, invalid nc format.\n"));
899 uri = malloc (left + 1);
904 _(
"Failed to allocate memory for auth header processing\n"));
950 if (0 != strncmp (uri,
952 strlen (connection->
url)))
956 _(
"Authentication failed, URI does not match.\n"));
963 const char *args = strchr (uri,
976 _(
"Authentication failed, arguments do not match.\n"));
983 return (0 == strcmp (response,
1007 const char *username,
1008 const char *password,
1009 unsigned int nonce_timeout)
1038 const char *username,
1040 unsigned int nonce_timeout)
1079 connection->
daemon->digest_auth_random,
1080 connection->
daemon->digest_auth_rand_size,
1089 #ifdef HAVE_MESSAGES 1090 MHD_DLOG (connection->
daemon,
1091 _(
"Could not register nonce (is the nonce array size zero?).\n"));
1096 hlen = MHD_snprintf_ (
NULL,
1098 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
1112 #ifdef HAVE_MESSAGES 1113 MHD_DLOG(connection->
daemon,
1114 _(
"Failed to allocate memory for auth response header\n"));
1119 if (MHD_snprintf_ (header,
1121 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
1146 #ifdef HAVE_MESSAGES 1147 MHD_DLOG (connection->
daemon,
1148 _(
"Failed to add Digest auth header\n"));
void * unescape_callback_cls
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
Header for platform missing functions.
#define MAX_AUTH_RESPONSE_LENGTH
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
static void digest_calc_response(const char ha1[HASH_MD5_HEX_LEN+1], const char *nonce, const char *noncecount, const char *cnonce, const char *qop, const char *method, const char *uri, const char *hentity, char response[HASH_MD5_HEX_LEN+1])
_MHD_EXTERN int MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
static void cvthex(const unsigned char *bin, size_t len, char *hex)
#define MHD_mutex_unlock_chk_(pmutex)
static size_t lookup_sub_value(char *dest, size_t size, const char *data, const char *key)
internal monotonic clock functions implementations
#define TIMESTAMP_BIN_SIZE
void * MHD_calloc_(size_t nelem, size_t elsize)
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
time_t MHD_monotonic_sec_counter(void)
#define MHD_INVALID_NONCE
_MHD_EXTERN int MHD_digest_auth_check(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
struct MHD_Daemon * daemon
void MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
#define MHD_MD5_DIGEST_SIZE
_MHD_EXTERN int MHD_queue_auth_fail_response(struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
internal shared structures
static int test_header(struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
char nonce[MAX_NONCE_LENGTH]
_MHD_EXTERN char * MHD_digest_auth_get_username(struct MHD_Connection *connection)
static int check_argument_match(struct MHD_Connection *connection, const char *args)
Header for string manipulating helpers.
#define MHD_STATICSTR_LEN_(macro)
UnescapeCallback unescape_callback
_MHD_EXTERN int MHD_digest_auth_check_digest(struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t digest[MD5_DIGEST_SIZE], unsigned int nonce_timeout)
_MHD_EXTERN int MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
#define MHD_HTTP_UNAUTHORIZED
void MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
static void calculate_nonce(uint32_t nonce_time, const char *method, const char *rnd, size_t rnd_size, const char *uri, const char *realm, char nonce[NONCE_STD_LEN+1])
void MD5Init(struct MD5Context *ctx)
static void digest_calc_ha1_from_digest(const char *alg, const uint8_t digest[MHD_MD5_DIGEST_SIZE], const char *nonce, const char *cnonce, char sessionkey[HASH_MD5_HEX_LEN+1])
#define MHD_mutex_lock_chk_(pmutex)
static int digest_auth_check_all(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, const uint8_t digest[MHD_MD5_DIGEST_SIZE], unsigned int nonce_timeout)
static int check_nonce_nc(struct MHD_Connection *connection, const char *nonce, uint64_t nc)
#define MAX_USERNAME_LENGTH
#define TIMESTAMP_HEX_LEN
struct MHD_HTTP_Header * headers_received
limits values definitions
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, char sessionkey[HASH_MD5_HEX_LEN+1])
size_t MHD_strx_to_uint32_n_(const char *str, size_t maxlen, uint32_t *out_val)