aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/gen_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/gen_auth.c')
-rw-r--r--src/microhttpd/gen_auth.c129
1 files changed, 127 insertions, 2 deletions
diff --git a/src/microhttpd/gen_auth.c b/src/microhttpd/gen_auth.c
index 5c383f1a..c86d35ba 100644
--- a/src/microhttpd/gen_auth.c
+++ b/src/microhttpd/gen_auth.c
@@ -274,6 +274,125 @@ struct dauth_token_param
274 struct MHD_RqDAuthParam *const param; 274 struct MHD_RqDAuthParam *const param;
275}; 275};
276 276
277
278/**
279 * Get client's Digest Authorization algorithm type.
280 * If no algorithm is specified by client, MD5 is assumed.
281 * @param params the Digest Authorization 'algorithm' parameter
282 * @return the algorithm type
283 */
284static enum MHD_DigestAuthAlgo3
285get_rq_dauth_algo (const struct MHD_RqDAuthParam *const algo_param)
286{
287 if (NULL == algo_param->value.str)
288 return MHD_DIGEST_AUTH_ALGO3_MD5; /* Assume MD5 by default */
289
290 if (algo_param->quoted)
291 {
292 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
293 algo_param->value.len, \
294 _MHD_MD5_TOKEN))
295 return MHD_DIGEST_AUTH_ALGO3_MD5;
296 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
297 algo_param->value.len, \
298 _MHD_SHA256_TOKEN))
299 return MHD_DIGEST_AUTH_ALGO3_SHA256;
300 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
301 algo_param->value.len, \
302 _MHD_MD5_TOKEN _MHD_SESS_TOKEN))
303 return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION;
304 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
305 algo_param->value.len, \
306 _MHD_SHA256_TOKEN \
307 _MHD_SESS_TOKEN))
308 return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION;
309
310 /* Algorithms below are not supported by MHD for authentication */
311
312 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
313 algo_param->value.len, \
314 _MHD_SHA512_256_TOKEN))
315 return MHD_DIGEST_AUTH_ALGO3_SHA512_256;
316 if (MHD_str_equal_caseless_quoted_s_bin_n (algo_param->value.str, \
317 algo_param->value.len, \
318 _MHD_SHA512_256_TOKEN \
319 _MHD_SESS_TOKEN))
320 return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION;
321
322 /* No known algorithm has been detected */
323 return MHD_DIGEST_AUTH_ALGO3_INVALID;
324 }
325 /* The algorithm value is not quoted */
326 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN, \
327 algo_param->value.str, \
328 algo_param->value.len))
329 return MHD_DIGEST_AUTH_ALGO3_MD5;
330 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN, \
331 algo_param->value.str, \
332 algo_param->value.len))
333 return MHD_DIGEST_AUTH_ALGO3_SHA256;
334 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_MD5_TOKEN _MHD_SESS_TOKEN, \
335 algo_param->value.str, \
336 algo_param->value.len))
337 return MHD_DIGEST_AUTH_ALGO3_MD5_SESSION;
338 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA256_TOKEN _MHD_SESS_TOKEN, \
339 algo_param->value.str, \
340 algo_param->value.len))
341 return MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION;
342
343 /* Algorithms below are not supported by MHD for authentication */
344
345 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN, \
346 algo_param->value.str, \
347 algo_param->value.len))
348 return MHD_DIGEST_AUTH_ALGO3_SHA512_256;
349 if (MHD_str_equal_caseless_s_bin_n_ (_MHD_SHA512_256_TOKEN _MHD_SESS_TOKEN, \
350 algo_param->value.str, \
351 algo_param->value.len))
352 return MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION;
353
354 /* No known algorithm has been detected */
355 return MHD_DIGEST_AUTH_ALGO3_INVALID;
356}
357
358
359/**
360 * Get QOP ('quality of protection') type.
361 * @param qop_param the Digest Authorization 'QOP' parameter
362 * @return detected QOP ('quality of protection') type.
363 */
364static enum MHD_DigestAuthQOP
365get_rq_dauth_qop (const struct MHD_RqDAuthParam *const qop_param)
366{
367 if (NULL == qop_param->value.str)
368 return MHD_DIGEST_AUTH_QOP_NONE;
369 if (qop_param->quoted)
370 {
371 if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
372 qop_param->value.len, \
373 MHD_TOKEN_AUTH_))
374 return MHD_DIGEST_AUTH_QOP_AUTH;
375 if (MHD_str_equal_caseless_quoted_s_bin_n (qop_param->value.str, \
376 qop_param->value.len, \
377 MHD_TOKEN_AUTH_INT_))
378 return MHD_DIGEST_AUTH_QOP_AUTH_INT;
379 }
380 else
381 {
382 if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_, \
383 qop_param->value.str, \
384 qop_param->value.len))
385 return MHD_DIGEST_AUTH_QOP_AUTH;
386 if (MHD_str_equal_caseless_s_bin_n_ (MHD_TOKEN_AUTH_INT_, \
387 qop_param->value.str, \
388 qop_param->value.len))
389 return MHD_DIGEST_AUTH_QOP_AUTH_INT;
390 }
391 /* No know QOP has been detected */
392 return MHD_DIGEST_AUTH_QOP_INVALID;
393}
394
395
277/** 396/**
278 * Parse request Authorization header parameters for Digest Authentication 397 * Parse request Authorization header parameters for Digest Authentication
279 * @param str the header string, everything after "Digest " substring 398 * @param str the header string, everything after "Digest " substring
@@ -306,16 +425,17 @@ parse_dauth_params (const char *str,
306 static const struct _MHD_cstr_w_len userhash_tk = 425 static const struct _MHD_cstr_w_len userhash_tk =
307 _MHD_S_STR_W_LEN ("userhash"); 426 _MHD_S_STR_W_LEN ("userhash");
308 struct MHD_RqDAuthParam userhash; 427 struct MHD_RqDAuthParam userhash;
428 struct MHD_RqDAuthParam algorithm;
309 struct dauth_token_param map[] = { 429 struct dauth_token_param map[] = {
310 {&nonce_tk, &(pdauth->nonce)}, 430 {&nonce_tk, &(pdauth->nonce)},
311 {&opaque_tk, &(pdauth->opaque)}, 431 {&opaque_tk, &(pdauth->opaque)},
312 {&algorithm_tk, &(pdauth->algorithm)}, 432 {&algorithm_tk, &algorithm},
313 {&response_tk, &(pdauth->response)}, 433 {&response_tk, &(pdauth->response)},
314 {&username_tk, &(pdauth->username)}, 434 {&username_tk, &(pdauth->username)},
315 {&username_ext_tk, &(pdauth->username_ext)}, 435 {&username_ext_tk, &(pdauth->username_ext)},
316 {&realm_tk, &(pdauth->realm)}, 436 {&realm_tk, &(pdauth->realm)},
317 {&uri_tk, &(pdauth->uri)}, 437 {&uri_tk, &(pdauth->uri)},
318 {&qop_tk, &(pdauth->qop)}, 438 {&qop_tk, &(pdauth->qop_raw)},
319 {&cnonce_tk, &(pdauth->cnonce)}, 439 {&cnonce_tk, &(pdauth->cnonce)},
320 {&nc_tk, &(pdauth->nc)}, 440 {&nc_tk, &(pdauth->nc)},
321 {&userhash_tk, &userhash} 441 {&userhash_tk, &userhash}
@@ -324,6 +444,7 @@ parse_dauth_params (const char *str,
324 size_t p; 444 size_t p;
325 445
326 memset (&userhash, 0, sizeof(userhash)); 446 memset (&userhash, 0, sizeof(userhash));
447 memset (&algorithm, 0, sizeof(algorithm));
327 i = 0; 448 i = 0;
328 449
329 /* Skip all whitespaces at start */ 450 /* Skip all whitespaces at start */
@@ -454,6 +575,7 @@ parse_dauth_params (const char *str,
454 } 575 }
455 576
456 /* Postprocess values */ 577 /* Postprocess values */
578
457 if (NULL != userhash.value.str) 579 if (NULL != userhash.value.str)
458 { 580 {
459 if (userhash.quoted) 581 if (userhash.quoted)
@@ -470,6 +592,9 @@ parse_dauth_params (const char *str,
470 else 592 else
471 pdauth->userhash = false; 593 pdauth->userhash = false;
472 594
595 pdauth->algo3 = get_rq_dauth_algo (&algorithm);
596 pdauth->qop = get_rq_dauth_qop (&pdauth->qop_raw);
597
473 return true; 598 return true;
474} 599}
475 600