39#if ! defined(BAUTH_SUPPORT) && ! defined(DAUTH_SUPPORT)
40#error This file requires Basic or Digest authentication support
72 mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= c->state);
119 (
' ' == h->
value[token_len]) || (
'\t' == h->
value[token_len]))
123 auth_value->
str = h->
value + token_len + 1;
128 auth_value->
str = h->
value + token_len;
151parse_bauth_params (
const char *str,
160 while (i < str_len && (
' ' == str[i] ||
'\t' == str[i]))
165 size_t token68_start;
171 while (i < str_len &&
' ' != str[i] &&
'\t' != str[i])
175 if ((
',' == str[i]) || (
';' == str[i]))
179 token68_len = i - token68_start;
183 while (i < str_len && (
' ' == str[i] ||
'\t' == str[i]))
217 mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= connection->state);
219 if (connection->
rq.bauth_tried)
220 return connection->
rq.bauth;
227 connection->
rq.bauth_tried =
true;
228 connection->
rq.bauth =
NULL;
239 MHD_DLOG (connection->
daemon,
240 _ (
"Not enough memory in the connection's pool to allocate " \
241 "for Basic Authorization header parsing.\n"));
247 if (parse_bauth_params (h_auth_value.str, h_auth_value.len, bauth))
248 connection->
rq.bauth = bauth;
252 MHD_DLOG (connection->
daemon,
253 _ (
"The Basic Authorization client's header has "
254 "incorrect format.\n"));
256 connection->
rq.bauth =
NULL;
259 connection->
rq.bauth_tried =
true;
260 return connection->
rq.bauth;
276get_rq_dauth_algo (
const struct MHD_RqDAuthParam *
const algo_param)
278 if (
NULL == algo_param->value.str)
281 if (algo_param->quoted)
283 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
284 algo_param->value.len, \
287 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
288 algo_param->value.len, \
291 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
292 algo_param->value.len, \
295 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
296 algo_param->value.len, \
303 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
304 algo_param->value.len, \
308 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
309 algo_param->value.len, \
318 algo_param->value.str, \
319 algo_param->value.len))
322 algo_param->value.str, \
323 algo_param->value.len))
326 algo_param->value.str, \
327 algo_param->value.len))
333 algo_param->value.str, \
334 algo_param->value.len))
337 algo_param->value.str, \
338 algo_param->value.len))
341 algo_param->value.str, \
342 algo_param->value.len))
356get_rq_dauth_qop (
const struct MHD_RqDAuthParam *
const qop_param)
358 if (
NULL == qop_param->value.str)
360 if (qop_param->quoted)
362 if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
363 qop_param->value.len, \
366 if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
367 qop_param->value.len, \
374 qop_param->value.str, \
375 qop_param->value.len))
378 qop_param->value.str, \
379 qop_param->value.len))
397parse_dauth_params (
const char *str,
398 const size_t str_len,
399 struct MHD_RqDAuth *pdauth)
420 struct MHD_RqDAuthParam userhash;
421 struct MHD_RqDAuthParam algorithm;
443 struct MHD_RqDAuthParam *params[
sizeof(tk_names) /
sizeof(tk_names[0])];
445 params[0 ] = &(pdauth->nonce);
446 params[1 ] = &(pdauth->opaque);
447 params[2 ] = &algorithm;
448 params[3 ] = &(pdauth->response);
449 params[4 ] = &(pdauth->username);
450 params[5 ] = &(pdauth->username_ext);
451 params[6 ] = &(pdauth->realm);
452 params[7 ] = &(pdauth->uri);
453 params[8 ] = &(pdauth->qop_raw);
454 params[9 ] = &(pdauth->cnonce);
455 params[10] = &(pdauth->nc);
456 params[11] = &userhash;
458 mhd_assert ((
sizeof(tk_names) /
sizeof(tk_names[0])) == \
459 (
sizeof(params) /
sizeof(params[0])));
460 memset (&userhash, 0,
sizeof(userhash));
461 memset (&algorithm, 0,
sizeof(algorithm));
465 while (i < str_len && (
' ' == str[i] ||
'\t' == str[i]))
477 for (p = 0; p < (
sizeof(tk_names) /
sizeof(tk_names[0])); ++p)
480 struct MHD_RqDAuthParam *
const param = params[p];
481 if ( (tk_name->
len <= left) &&
484 ((tk_name->
len == left) ||
485 (
'=' == str[i + tk_name->
len]) ||
486 (
' ' == str[i + tk_name->
len]) ||
487 (
'\t' == str[i + tk_name->
len]) ||
488 (
',' == str[i + tk_name->
len]) ||
489 (
';' == str[i + tk_name->
len])) )
495 if (tk_name->
len == left)
501 while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]))
503 if ((i == str_len) || (
'=' != str[i]))
507 while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]))
509 if ((str_len > i) && (
'"' == str[i]))
513 while (str_len > i &&
'"' != str[i])
527 value_len = i - value_start;
533 while (str_len > i &&
',' != str[i] &&
534 ' ' != str[i] &&
'\t' != str[i] &&
';' != str[i])
542 value_len = i - value_start;
545 while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]))
547 if ((str_len > i) && (
',' != str[i]))
552 param->value.str = str + value_start;
553 param->value.len = value_len;
554 param->quoted = quoted;
559 if (p == (
sizeof(tk_names) /
sizeof(tk_names[0])))
562 while (str_len > i &&
',' != str[i])
564 if ((0 == str[i]) || (
';' == str[i]))
569 while (str_len > i &&
'"' != str[i])
588 while (i < str_len && (
' ' == str[i] ||
'\t' == str[i]))
594 if (
NULL != userhash.value.str)
598 MHD_str_equal_caseless_quoted_s_bin_n (userhash.value.str, \
599 userhash.value.len, \
608 pdauth->userhash =
false;
610 pdauth->algo3 = get_rq_dauth_algo (&algorithm);
611 pdauth->qop = get_rq_dauth_qop (&pdauth->qop_raw);
629const struct MHD_RqDAuth *
633 struct MHD_RqDAuth *dauth;
635 mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= connection->state);
637 if (connection->
rq.dauth_tried)
638 return connection->
rq.dauth;
645 connection->
rq.dauth_tried =
true;
646 connection->
rq.dauth =
NULL;
651 (
struct MHD_RqDAuth *)
657 MHD_DLOG (connection->
daemon,
658 _ (
"Not enough memory in the connection's pool to allocate " \
659 "for Digest Authorization header parsing.\n"));
664 memset (dauth, 0,
sizeof(
struct MHD_RqDAuth));
665 if (parse_dauth_params (h_auth_value.str, h_auth_value.len, dauth))
666 connection->
rq.dauth = dauth;
670 MHD_DLOG (connection->
daemon,
671 _ (
"The Digest Authorization client's header has "
672 "incorrect format.\n"));
674 connection->
rq.dauth =
NULL;
677 connection->
rq.dauth_tried =
true;
678 return connection->
rq.dauth;
#define _MHD_AUTH_BASIC_BASE
void * MHD_connection_alloc_memory_(struct MHD_Connection *connection, size_t size)
Methods for managing connections.
#define MHD_TOKEN_AUTH_INT_
#define _MHD_SHA256_TOKEN
#define _MHD_SHA512_256_TOKEN
#define _MHD_AUTH_DIGEST_BASE
static bool find_auth_rq_header_(const struct MHD_Connection *c, enum MHD_AuthType type, struct _MHD_str_w_len *auth_value)
Declarations for HTTP authorisation general functions.
#define MHD_STATICSTR_LEN_(macro)
#define _MHD_S_STR_W_LEN(str)
MHD internal shared structures.
@ MHD_CONNECTION_HEADERS_PROCESSED
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
Header for string manipulating helpers.
#define MHD_str_equal_caseless_s_bin_n_(a, s, l)
@ MHD_DIGEST_AUTH_ALGO3_MD5_SESSION
@ MHD_DIGEST_AUTH_ALGO3_MD5
@ MHD_DIGEST_AUTH_ALGO3_SHA256
@ MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION
@ MHD_DIGEST_AUTH_ALGO3_INVALID
@ MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION
@ MHD_DIGEST_AUTH_ALGO3_SHA512_256
@ MHD_DIGEST_AUTH_QOP_AUTH
@ MHD_DIGEST_AUTH_QOP_INVALID
@ MHD_DIGEST_AUTH_QOP_NONE
@ MHD_DIGEST_AUTH_QOP_AUTH_INT
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
struct MHD_HTTP_Header * headers_received
struct _MHD_str_w_len token68