diff options
Diffstat (limited to 'src/microhttpd/gen_auth.c')
-rw-r--r-- | src/microhttpd/gen_auth.c | 129 |
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 | */ | ||
284 | static enum MHD_DigestAuthAlgo3 | ||
285 | get_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 | */ | ||
364 | static enum MHD_DigestAuthQOP | ||
365 | get_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 | ||