diff options
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r-- | src/microhttpd/digestauth.c | 333 |
1 files changed, 288 insertions, 45 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c index a6792930..1155e6ff 100644 --- a/src/microhttpd/digestauth.c +++ b/src/microhttpd/digestauth.c | |||
@@ -33,8 +33,15 @@ | |||
33 | #include "mhd_limits.h" | 33 | #include "mhd_limits.h" |
34 | #include "internal.h" | 34 | #include "internal.h" |
35 | #include "response.h" | 35 | #include "response.h" |
36 | #include "md5.h" | 36 | #ifdef MHD_MD5_SUPPORT |
37 | #include "sha256.h" | 37 | # include "md5.h" |
38 | #endif /* MHD_MD5_SUPPORT */ | ||
39 | #ifdef MHD_SHA256_SUPPORT | ||
40 | # include "sha256.h" | ||
41 | #endif /* MHD_SHA256_SUPPORT */ | ||
42 | #ifdef MHD_SHA512_256_SUPPORT | ||
43 | # include "sha512_256.h" | ||
44 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
38 | #include "mhd_locks.h" | 45 | #include "mhd_locks.h" |
39 | #include "mhd_mono_clock.h" | 46 | #include "mhd_mono_clock.h" |
40 | #include "mhd_str.h" | 47 | #include "mhd_str.h" |
@@ -86,6 +93,18 @@ | |||
86 | ((digest_size) * 2 + TIMESTAMP_CHARS_LEN) | 93 | ((digest_size) * 2 + TIMESTAMP_CHARS_LEN) |
87 | 94 | ||
88 | 95 | ||
96 | #ifdef MHD_SHA512_256_SUPPORT | ||
97 | /** | ||
98 | * Maximum size of any digest hash supported by MHD. | ||
99 | * (SHA-512/256 > MD5). | ||
100 | */ | ||
101 | #define MAX_DIGEST SHA512_256_DIGEST_SIZE | ||
102 | |||
103 | /** | ||
104 | * The common size of SHA-256 digest and SHA-512/256 digest | ||
105 | */ | ||
106 | #define SHA256_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE | ||
107 | #elif defined(MHD_SHA256_SUPPORT) | ||
89 | /** | 108 | /** |
90 | * Maximum size of any digest hash supported by MHD. | 109 | * Maximum size of any digest hash supported by MHD. |
91 | * (SHA-256 > MD5). | 110 | * (SHA-256 > MD5). |
@@ -93,6 +112,20 @@ | |||
93 | #define MAX_DIGEST SHA256_DIGEST_SIZE | 112 | #define MAX_DIGEST SHA256_DIGEST_SIZE |
94 | 113 | ||
95 | /** | 114 | /** |
115 | * The common size of SHA-256 digest and SHA-512/256 digest | ||
116 | */ | ||
117 | #define SHA256_SHA512_256_DIGEST_SIZE SHA256_DIGEST_SIZE | ||
118 | #elif defined(MHD_MD5_SUPPORT) | ||
119 | /** | ||
120 | * Maximum size of any digest hash supported by MHD. | ||
121 | */ | ||
122 | #define MAX_DIGEST MD5_DIGEST_SIZE | ||
123 | #else /* ! MHD_MD5_SUPPORT */ | ||
124 | #error At least one hashing algorithm must be enabled | ||
125 | #endif /* ! MHD_MD5_SUPPORT */ | ||
126 | |||
127 | |||
128 | /** | ||
96 | * Macro to avoid using VLAs if the compiler does not support them. | 129 | * Macro to avoid using VLAs if the compiler does not support them. |
97 | */ | 130 | */ |
98 | #ifndef HAVE_C_VARARRAYS | 131 | #ifndef HAVE_C_VARARRAYS |
@@ -193,26 +226,54 @@ get_base_digest_algo (enum MHD_DigestAuthAlgo3 algo3) | |||
193 | * Internal inline version. | 226 | * Internal inline version. |
194 | * @param algo3 the algorithm to check | 227 | * @param algo3 the algorithm to check |
195 | * @return the size of the digest or zero if the input value is not | 228 | * @return the size of the digest or zero if the input value is not |
196 | * recognised/valid | 229 | * supported/valid |
197 | */ | 230 | */ |
198 | _MHD_static_inline size_t | 231 | _MHD_static_inline size_t |
199 | digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3) | 232 | digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3) |
200 | { | 233 | { |
234 | #ifdef MHD_MD5_SUPPORT | ||
201 | mhd_assert (MHD_MD5_DIGEST_SIZE == MD5_DIGEST_SIZE); | 235 | mhd_assert (MHD_MD5_DIGEST_SIZE == MD5_DIGEST_SIZE); |
236 | #endif /* MHD_MD5_SUPPORT */ | ||
237 | #ifdef MHD_SHA256_SUPPORT | ||
202 | mhd_assert (MHD_SHA256_DIGEST_SIZE == SHA256_DIGEST_SIZE); | 238 | mhd_assert (MHD_SHA256_DIGEST_SIZE == SHA256_DIGEST_SIZE); |
203 | /* Both MD5 and SHA-256 must not be specified at the same time */ | 239 | #endif /* MHD_SHA256_SUPPORT */ |
204 | mhd_assert ( (0 == (((unsigned int) algo3) \ | 240 | #ifdef MHD_SHA512_256_SUPPORT |
205 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5))) || \ | 241 | mhd_assert (MHD_SHA512_256_DIGEST_SIZE == SHA512_256_DIGEST_SIZE); |
206 | (0 == (((unsigned int) algo3) \ | 242 | #ifdef MHD_SHA256_SUPPORT |
207 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256))) ); | 243 | mhd_assert (SHA256_DIGEST_SIZE == SHA512_256_DIGEST_SIZE); |
244 | #endif /* MHD_SHA256_SUPPORT */ | ||
245 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
246 | /* Only one algorithm must be specified */ | ||
247 | mhd_assert (1 == \ | ||
248 | (((0 != (algo3 & MHD_DIGEST_BASE_ALGO_MD5)) ? 1 : 0) \ | ||
249 | + ((0 != (algo3 & MHD_DIGEST_BASE_ALGO_SHA256)) ? 1 : 0) \ | ||
250 | + ((0 != (algo3 & MHD_DIGEST_BASE_ALGO_SHA512_256)) ? 1 : 0))); | ||
251 | #ifdef MHD_MD5_SUPPORT | ||
208 | if (0 != (((unsigned int) algo3) | 252 | if (0 != (((unsigned int) algo3) |
209 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5))) | 253 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5))) |
210 | return MHD_MD5_DIGEST_SIZE; | 254 | return MHD_MD5_DIGEST_SIZE; |
211 | else if (0 != (((unsigned int) algo3) | 255 | else |
212 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256))) | 256 | #endif /* MHD_MD5_SUPPORT */ |
257 | #if defined(MHD_SHA256_SUPPORT) && defined(MHD_SHA512_256_SUPPORT) | ||
258 | if (0 != (((unsigned int) algo3) | ||
259 | & ( ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256) | ||
260 | | ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA512_256)))) | ||
261 | return MHD_SHA256_DIGEST_SIZE; /* The same as SHA512_256_DIGEST_SIZE */ | ||
262 | else | ||
263 | #elif defined(MHD_SHA256_SUPPORT) | ||
264 | if (0 != (((unsigned int) algo3) | ||
265 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256))) | ||
213 | return MHD_SHA256_DIGEST_SIZE; | 266 | return MHD_SHA256_DIGEST_SIZE; |
267 | else | ||
268 | #elif defined(MHD_SHA512_256_SUPPORT) | ||
269 | if (0 != (((unsigned int) algo3) | ||
270 | & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA512_256))) | ||
271 | return MHD_SHA512_256_DIGEST_SIZE; | ||
272 | else | ||
273 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
274 | (void) 0; /* Unsupported algorithm */ | ||
214 | 275 | ||
215 | return 0; /* Wrong input */ | 276 | return 0; /* Wrong input or unsupported algorithm */ |
216 | } | 277 | } |
217 | 278 | ||
218 | 279 | ||
@@ -223,8 +284,8 @@ digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3) | |||
223 | * and other parameters which size depends on used hash algorithm. | 284 | * and other parameters which size depends on used hash algorithm. |
224 | * @param algo3 the algorithm to check | 285 | * @param algo3 the algorithm to check |
225 | * @return the size of the digest (either #MHD_MD5_DIGEST_SIZE or | 286 | * @return the size of the digest (either #MHD_MD5_DIGEST_SIZE or |
226 | * #MHD_SHA256_DIGEST_SIZE) or zero if the input value is not | 287 | * #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE) |
227 | * recognised/valid | 288 | * or zero if the input value is not supported or not valid |
228 | * @sa #MHD_digest_auth_calc_userdigest() | 289 | * @sa #MHD_digest_auth_calc_userdigest() |
229 | * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex() | 290 | * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex() |
230 | * @note Available since #MHD_VERSION 0x00097526 | 291 | * @note Available since #MHD_VERSION 0x00097526 |
@@ -242,8 +303,15 @@ MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3) | |||
242 | */ | 303 | */ |
243 | union DigestCtx | 304 | union DigestCtx |
244 | { | 305 | { |
306 | #ifdef MHD_MD5_SUPPORT | ||
245 | struct MD5Context md5_ctx; | 307 | struct MD5Context md5_ctx; |
308 | #endif /* MHD_MD5_SUPPORT */ | ||
309 | #ifdef MHD_SHA256_SUPPORT | ||
246 | struct Sha256Ctx sha256_ctx; | 310 | struct Sha256Ctx sha256_ctx; |
311 | #endif /* MHD_SHA256_SUPPORT */ | ||
312 | #ifdef MHD_SHA512_256_SUPPORT | ||
313 | struct Sha512_256Ctx sha512_256_ctx; | ||
314 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
247 | }; | 315 | }; |
248 | 316 | ||
249 | /** | 317 | /** |
@@ -282,10 +350,18 @@ _MHD_static_inline unsigned int | |||
282 | digest_get_size (struct DigestAlgorithm *da) | 350 | digest_get_size (struct DigestAlgorithm *da) |
283 | { | 351 | { |
284 | mhd_assert (da->setup); | 352 | mhd_assert (da->setup); |
353 | #ifdef MHD_MD5_SUPPORT | ||
285 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) | 354 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) |
286 | return MD5_DIGEST_SIZE; | 355 | return MD5_DIGEST_SIZE; |
356 | #endif /* MHD_MD5_SUPPORT */ | ||
357 | #ifdef MHD_SHA256_SUPPORT | ||
287 | if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | 358 | if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) |
288 | return SHA256_DIGEST_SIZE; | 359 | return SHA256_DIGEST_SIZE; |
360 | #endif /* MHD_SHA256_SUPPORT */ | ||
361 | #ifdef MHD_SHA512_256_SUPPORT | ||
362 | if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo) | ||
363 | return SHA512_256_DIGEST_SIZE; | ||
364 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
289 | mhd_assert (0); /* May not happen */ | 365 | mhd_assert (0); /* May not happen */ |
290 | return 0; | 366 | return 0; |
291 | } | 367 | } |
@@ -307,8 +383,17 @@ digest_setup (struct DigestAlgorithm *da, | |||
307 | da->inited = false; | 383 | da->inited = false; |
308 | da->digest_calculated = false; | 384 | da->digest_calculated = false; |
309 | #endif /* _DEBUG */ | 385 | #endif /* _DEBUG */ |
310 | if ((MHD_DIGEST_BASE_ALGO_MD5 == algo) || | 386 | if (false |
311 | (MHD_DIGEST_BASE_ALGO_SHA256 == algo)) | 387 | #ifdef MHD_MD5_SUPPORT |
388 | || (MHD_DIGEST_BASE_ALGO_MD5 == algo) | ||
389 | #endif /* MHD_MD5_SUPPORT */ | ||
390 | #ifdef MHD_SHA256_SUPPORT | ||
391 | || (MHD_DIGEST_BASE_ALGO_SHA256 == algo) | ||
392 | #endif /* MHD_SHA256_SUPPORT */ | ||
393 | #ifdef MHD_SHA512_256_SUPPORT | ||
394 | || (MHD_DIGEST_BASE_ALGO_SHA512_256 == algo) | ||
395 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
396 | ) | ||
312 | { | 397 | { |
313 | da->algo = algo; | 398 | da->algo = algo; |
314 | #ifdef _DEBUG | 399 | #ifdef _DEBUG |
@@ -316,8 +401,7 @@ digest_setup (struct DigestAlgorithm *da, | |||
316 | #endif /* _DEBUG */ | 401 | #endif /* _DEBUG */ |
317 | return true; | 402 | return true; |
318 | } | 403 | } |
319 | mhd_assert (0); /* Bad parameter */ | 404 | return false; /* Bad or unsupported algorithm */ |
320 | return false; | ||
321 | } | 405 | } |
322 | 406 | ||
323 | 407 | ||
@@ -332,6 +416,7 @@ digest_init (struct DigestAlgorithm *da) | |||
332 | #ifdef _DEBUG | 416 | #ifdef _DEBUG |
333 | da->digest_calculated = false; | 417 | da->digest_calculated = false; |
334 | #endif | 418 | #endif |
419 | #ifdef MHD_MD5_SUPPORT | ||
335 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) | 420 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) |
336 | { | 421 | { |
337 | MHD_MD5Init (&da->ctx.md5_ctx); | 422 | MHD_MD5Init (&da->ctx.md5_ctx); |
@@ -339,7 +424,10 @@ digest_init (struct DigestAlgorithm *da) | |||
339 | da->inited = true; | 424 | da->inited = true; |
340 | #endif | 425 | #endif |
341 | } | 426 | } |
342 | else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | 427 | else |
428 | #endif /* MHD_MD5_SUPPORT */ | ||
429 | #ifdef MHD_SHA256_SUPPORT | ||
430 | if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | ||
343 | { | 431 | { |
344 | MHD_SHA256_init (&da->ctx.sha256_ctx); | 432 | MHD_SHA256_init (&da->ctx.sha256_ctx); |
345 | #ifdef _DEBUG | 433 | #ifdef _DEBUG |
@@ -347,6 +435,17 @@ digest_init (struct DigestAlgorithm *da) | |||
347 | #endif | 435 | #endif |
348 | } | 436 | } |
349 | else | 437 | else |
438 | #endif /* MHD_SHA256_SUPPORT */ | ||
439 | #ifdef MHD_SHA512_256_SUPPORT | ||
440 | if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo) | ||
441 | { | ||
442 | MHD_SHA512_256_init (&da->ctx.sha512_256_ctx); | ||
443 | #ifdef _DEBUG | ||
444 | da->inited = true; | ||
445 | #endif | ||
446 | } | ||
447 | else | ||
448 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
350 | { | 449 | { |
351 | #ifdef _DEBUG | 450 | #ifdef _DEBUG |
352 | da->inited = false; | 451 | da->inited = false; |
@@ -369,12 +468,23 @@ digest_update (struct DigestAlgorithm *da, | |||
369 | { | 468 | { |
370 | mhd_assert (da->inited); | 469 | mhd_assert (da->inited); |
371 | mhd_assert (! da->digest_calculated); | 470 | mhd_assert (! da->digest_calculated); |
471 | #ifdef MHD_MD5_SUPPORT | ||
372 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) | 472 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) |
373 | MHD_MD5Update (&da->ctx.md5_ctx, (const uint8_t *) data, length); | 473 | MHD_MD5Update (&da->ctx.md5_ctx, (const uint8_t *) data, length); |
374 | else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | 474 | else |
475 | #endif /* MHD_MD5_SUPPORT */ | ||
476 | #ifdef MHD_SHA256_SUPPORT | ||
477 | if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | ||
375 | MHD_SHA256_update (&da->ctx.sha256_ctx, (const uint8_t *) data, length); | 478 | MHD_SHA256_update (&da->ctx.sha256_ctx, (const uint8_t *) data, length); |
376 | else | 479 | else |
377 | mhd_assert (0); /* May not happen */ | 480 | #endif /* MHD_SHA256_SUPPORT */ |
481 | #ifdef MHD_SHA512_256_SUPPORT | ||
482 | if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo) | ||
483 | MHD_SHA512_256_update (&da->ctx.sha512_256_ctx, | ||
484 | (const uint8_t *) data, length); | ||
485 | else | ||
486 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
487 | mhd_assert (0); /* May not happen */ | ||
378 | } | 488 | } |
379 | 489 | ||
380 | 490 | ||
@@ -416,12 +526,22 @@ digest_calc_hash (struct DigestAlgorithm *da, uint8_t *digest) | |||
416 | { | 526 | { |
417 | mhd_assert (da->inited); | 527 | mhd_assert (da->inited); |
418 | mhd_assert (! da->digest_calculated); | 528 | mhd_assert (! da->digest_calculated); |
529 | #ifdef MHD_MD5_SUPPORT | ||
419 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) | 530 | if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) |
420 | MHD_MD5Final (&da->ctx.md5_ctx, digest); | 531 | MHD_MD5Final (&da->ctx.md5_ctx, digest); |
421 | else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | 532 | else |
533 | #endif /* MHD_MD5_SUPPORT */ | ||
534 | #ifdef MHD_SHA256_SUPPORT | ||
535 | if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) | ||
422 | MHD_SHA256_finish (&da->ctx.sha256_ctx, digest); | 536 | MHD_SHA256_finish (&da->ctx.sha256_ctx, digest); |
423 | else | 537 | else |
424 | mhd_assert (0); /* May not happen */ | 538 | #endif /* MHD_SHA256_SUPPORT */ |
539 | #ifdef MHD_SHA512_256_SUPPORT | ||
540 | if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo) | ||
541 | MHD_SHA512_256_finish (&da->ctx.sha512_256_ctx, digest); | ||
542 | else | ||
543 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
544 | mhd_assert (0); /* May not happen */ | ||
425 | #ifdef _DEBUG | 545 | #ifdef _DEBUG |
426 | da->digest_calculated = true; | 546 | da->digest_calculated = true; |
427 | #endif | 547 | #endif |
@@ -444,8 +564,14 @@ get_nonce_timestamp (const char *const nonce, | |||
444 | if (0 == noncelen) | 564 | if (0 == noncelen) |
445 | noncelen = strlen (nonce); | 565 | noncelen = strlen (nonce); |
446 | 566 | ||
447 | if ( (NONCE_STD_LEN (SHA256_DIGEST_SIZE) != noncelen) && | 567 | if (true |
448 | (NONCE_STD_LEN (MD5_DIGEST_SIZE) != noncelen) ) | 568 | #ifdef MHD_MD5_SUPPORT |
569 | && (NONCE_STD_LEN (MD5_DIGEST_SIZE) != noncelen) | ||
570 | #endif /* MHD_MD5_SUPPORT */ | ||
571 | #if defined(MHD_SHA256_SUPPORT) || defined(MHD_SHA512_256_SUPPORT) | ||
572 | && (NONCE_STD_LEN (SHA256_SHA512_256_DIGEST_SIZE) != noncelen) | ||
573 | #endif /* MHD_SHA256_SUPPORT */ | ||
574 | ) | ||
449 | return false; | 575 | return false; |
450 | 576 | ||
451 | if (TIMESTAMP_CHARS_LEN != | 577 | if (TIMESTAMP_CHARS_LEN != |
@@ -2213,19 +2339,43 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, | |||
2213 | #endif /* HAVE_MESSAGES */ | 2339 | #endif /* HAVE_MESSAGES */ |
2214 | return MHD_DAUTH_WRONG_ALGO; | 2340 | return MHD_DAUTH_WRONG_ALGO; |
2215 | } | 2341 | } |
2342 | #ifndef MHD_MD5_SUPPORT | ||
2343 | if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5)) | ||
2344 | { | ||
2345 | #ifdef HAVE_MESSAGES | ||
2346 | MHD_DLOG (connection->daemon, | ||
2347 | _ ("The MD5 algorithm is not supported by this MHD build.\n")); | ||
2348 | #endif /* HAVE_MESSAGES */ | ||
2349 | return MHD_DAUTH_WRONG_ALGO; | ||
2350 | } | ||
2351 | #endif /* ! MHD_MD5_SUPPORT */ | ||
2352 | #ifndef MHD_SHA256_SUPPORT | ||
2353 | if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA256)) | ||
2354 | { | ||
2355 | #ifdef HAVE_MESSAGES | ||
2356 | MHD_DLOG (connection->daemon, | ||
2357 | _ ("The SHA-256 algorithm is not supported by " | ||
2358 | "this MHD build.\n")); | ||
2359 | #endif /* HAVE_MESSAGES */ | ||
2360 | return MHD_DAUTH_WRONG_ALGO; | ||
2361 | } | ||
2362 | #endif /* ! MHD_SHA256_SUPPORT */ | ||
2363 | #ifndef MHD_SHA512_256_SUPPORT | ||
2216 | if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA512_256)) | 2364 | if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA512_256)) |
2217 | { | 2365 | { |
2218 | #ifdef HAVE_MESSAGES | 2366 | #ifdef HAVE_MESSAGES |
2219 | MHD_DLOG (connection->daemon, | 2367 | MHD_DLOG (connection->daemon, |
2220 | _ ("The SHA-512/256 algorithm is not supported.\n")); | 2368 | _ ("The SHA-512/256 algorithm is not supported by " |
2369 | "this MHD build.\n")); | ||
2221 | #endif /* HAVE_MESSAGES */ | 2370 | #endif /* HAVE_MESSAGES */ |
2222 | return MHD_DAUTH_WRONG_ALGO; | 2371 | return MHD_DAUTH_WRONG_ALGO; |
2223 | } | 2372 | } |
2373 | #endif /* ! MHD_SHA512_256_SUPPORT */ | ||
2224 | if (! digest_setup (&da, get_base_digest_algo (c_algo))) | 2374 | if (! digest_setup (&da, get_base_digest_algo (c_algo))) |
2225 | MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); | 2375 | MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); |
2226 | /* Check 'mqop' value */ | 2376 | /* Check 'mqop' value */ |
2227 | c_qop = params->qop; | 2377 | c_qop = params->qop; |
2228 | /* Check whether client's algorithm is allowed by function parameter */ | 2378 | /* Check whether client's QOP is allowed by function parameter */ |
2229 | if (((unsigned int) c_qop) != | 2379 | if (((unsigned int) c_qop) != |
2230 | (((unsigned int) c_qop) & ((unsigned int) mqop))) | 2380 | (((unsigned int) c_qop) & ((unsigned int) mqop))) |
2231 | return MHD_DAUTH_WRONG_QOP; | 2381 | return MHD_DAUTH_WRONG_QOP; |
@@ -2241,8 +2391,8 @@ digest_auth_check_all_inner (struct MHD_Connection *connection, | |||
2241 | if ((MHD_DIGEST_AUTH_QOP_NONE == c_qop) && | 2391 | if ((MHD_DIGEST_AUTH_QOP_NONE == c_qop) && |
2242 | (0 == (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5))) | 2392 | (0 == (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5))) |
2243 | MHD_DLOG (connection->daemon, | 2393 | MHD_DLOG (connection->daemon, |
2244 | _ ("RFC2069 with SHA-256 algorithm is non-standard " \ | 2394 | _ ("RFC2069 with SHA-256 or SHA-512/256 algorithm is " \ |
2245 | "extension.\n")); | 2395 | "non-standard extension.\n")); |
2246 | #endif /* HAVE_MESSAGES */ | 2396 | #endif /* HAVE_MESSAGES */ |
2247 | 2397 | ||
2248 | digest_size = digest_get_size (&da); | 2398 | digest_size = digest_get_size (&da); |
@@ -2776,7 +2926,8 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection, | |||
2776 | * see #MHD_digest_auth_calc_userdigest() | 2926 | * see #MHD_digest_auth_calc_userdigest() |
2777 | * @param userdigest_size the size of the @a userdigest in bytes, must match the | 2927 | * @param userdigest_size the size of the @a userdigest in bytes, must match the |
2778 | * hashing algorithm (see #MHD_MD5_DIGEST_SIZE, | 2928 | * hashing algorithm (see #MHD_MD5_DIGEST_SIZE, |
2779 | * #MHD_SHA256_DIGEST_SIZE, #MHD_digest_get_hash_size()) | 2929 | * #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE, |
2930 | * #MHD_digest_get_hash_size()) | ||
2780 | * @param nonce_timeout the period of seconds since nonce generation, when | 2931 | * @param nonce_timeout the period of seconds since nonce generation, when |
2781 | * the nonce is recognised as valid and not stale. | 2932 | * the nonce is recognised as valid and not stale. |
2782 | * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc | 2933 | * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc |
@@ -2786,9 +2937,9 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection, | |||
2786 | * @param mqop the QOP to use | 2937 | * @param mqop the QOP to use |
2787 | * @param malgo3 digest algorithms allowed to use, fail if algorithm used | 2938 | * @param malgo3 digest algorithms allowed to use, fail if algorithm used |
2788 | * by the client is not allowed by this parameter; | 2939 | * by the client is not allowed by this parameter; |
2789 | * both MD5-based and SHA-256-based algorithms cannot be used at | 2940 | * more than one base algorithms (MD5, SHA-256, SHA-512/256) |
2790 | * the same time for this function as @a userdigest_size must | 2941 | * cannot be used at the same time for this function |
2791 | * match specified algorithm | 2942 | * as @a userdigest must match specified algorithm |
2792 | * @return #MHD_DAUTH_OK if authenticated, | 2943 | * @return #MHD_DAUTH_OK if authenticated, |
2793 | * the error code otherwise | 2944 | * the error code otherwise |
2794 | * @sa #MHD_digest_auth_calc_userdigest() | 2945 | * @sa #MHD_digest_auth_calc_userdigest() |
@@ -2806,13 +2957,46 @@ MHD_digest_auth_check_digest3 (struct MHD_Connection *connection, | |||
2806 | enum MHD_DigestAuthMultiQOP mqop, | 2957 | enum MHD_DigestAuthMultiQOP mqop, |
2807 | enum MHD_DigestAuthMultiAlgo3 malgo3) | 2958 | enum MHD_DigestAuthMultiAlgo3 malgo3) |
2808 | { | 2959 | { |
2809 | if (((unsigned int) (MHD_DIGEST_BASE_ALGO_MD5 | 2960 | if (1 != (((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_MD5)) ? 1 : 0) |
2810 | | MHD_DIGEST_BASE_ALGO_SHA256)) == | 2961 | + ((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_SHA256)) ? 1 : 0) |
2811 | (((unsigned int) malgo3) & (MHD_DIGEST_BASE_ALGO_MD5 | 2962 | + ((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_SHA512_256)) ? 1 : 0))) |
2812 | | MHD_DIGEST_BASE_ALGO_SHA256))) | 2963 | MHD_PANIC (_ ("Wrong 'malgo3' value, only one base hashing algorithm " \ |
2813 | MHD_PANIC (_ ("Wrong 'malgo3' value, both MD5 and SHA-256 specified, " | 2964 | "(MD5, SHA-256 or SHA-512/256) must be specified, " \ |
2814 | "API violation")); | 2965 | "API violation")); |
2815 | 2966 | ||
2967 | #ifndef MHD_MD5_SUPPORT | ||
2968 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5)) | ||
2969 | { | ||
2970 | #ifdef HAVE_MESSAGES | ||
2971 | MHD_DLOG (connection->daemon, | ||
2972 | _ ("The MD5 algorithm is not supported by this MHD build.\n")); | ||
2973 | #endif /* HAVE_MESSAGES */ | ||
2974 | return MHD_DAUTH_WRONG_ALGO; | ||
2975 | } | ||
2976 | #endif /* ! MHD_MD5_SUPPORT */ | ||
2977 | #ifndef MHD_SHA256_SUPPORT | ||
2978 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256)) | ||
2979 | { | ||
2980 | #ifdef HAVE_MESSAGES | ||
2981 | MHD_DLOG (connection->daemon, | ||
2982 | _ ("The SHA-256 algorithm is not supported by " | ||
2983 | "this MHD build.\n")); | ||
2984 | #endif /* HAVE_MESSAGES */ | ||
2985 | return MHD_DAUTH_WRONG_ALGO; | ||
2986 | } | ||
2987 | #endif /* ! MHD_SHA256_SUPPORT */ | ||
2988 | #ifndef MHD_SHA512_256_SUPPORT | ||
2989 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256)) | ||
2990 | { | ||
2991 | #ifdef HAVE_MESSAGES | ||
2992 | MHD_DLOG (connection->daemon, | ||
2993 | _ ("The SHA-512/256 algorithm is not supported by " | ||
2994 | "this MHD build.\n")); | ||
2995 | #endif /* HAVE_MESSAGES */ | ||
2996 | return MHD_DAUTH_WRONG_ALGO; | ||
2997 | } | ||
2998 | #endif /* ! MHD_SHA512_256_SUPPORT */ | ||
2999 | |||
2816 | if (digest_get_hash_size ((enum MHD_DigestAuthAlgo3) malgo3) != | 3000 | if (digest_get_hash_size ((enum MHD_DigestAuthAlgo3) malgo3) != |
2817 | userdigest_size) | 3001 | userdigest_size) |
2818 | MHD_PANIC (_ ("Wrong 'userdigest_size' value, does not match 'malgo3', " | 3002 | MHD_PANIC (_ ("Wrong 'userdigest_size' value, does not match 'malgo3', " |
@@ -3072,12 +3256,45 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection, | |||
3072 | #endif /* HAVE_MESSAGES */ | 3256 | #endif /* HAVE_MESSAGES */ |
3073 | return MHD_NO; | 3257 | return MHD_NO; |
3074 | } | 3258 | } |
3259 | #ifndef MHD_SHA512_256_SUPPORT | ||
3260 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256)) | ||
3261 | { | ||
3262 | #ifdef HAVE_MESSAGES | ||
3263 | MHD_DLOG (connection->daemon, | ||
3264 | _ ("The SHA-512/256 algorithm is not enabled.\n")); | ||
3265 | #endif /* HAVE_MESSAGES */ | ||
3266 | return MHD_NO; | ||
3267 | } | ||
3268 | #endif /* ! MHD_SHA512_256_SUPPORT */ | ||
3269 | #ifdef MHD_MD5_SUPPORT | ||
3075 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5)) | 3270 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5)) |
3076 | s_algo = MHD_DIGEST_AUTH_ALGO3_MD5; | 3271 | s_algo = MHD_DIGEST_AUTH_ALGO3_MD5; |
3077 | else if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256)) | 3272 | else |
3273 | #endif /* MHD_MD5_SUPPORT */ | ||
3274 | #ifdef MHD_SHA256_SUPPORT | ||
3275 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256)) | ||
3078 | s_algo = MHD_DIGEST_AUTH_ALGO3_SHA256; | 3276 | s_algo = MHD_DIGEST_AUTH_ALGO3_SHA256; |
3079 | else | 3277 | else |
3080 | MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); | 3278 | #endif /* MHD_SHA256_SUPPORT */ |
3279 | #ifdef MHD_SHA512_256_SUPPORT | ||
3280 | if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256)) | ||
3281 | s_algo = MHD_DIGEST_AUTH_ALGO3_SHA512_256; | ||
3282 | else | ||
3283 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
3284 | { | ||
3285 | if (0 == (((unsigned int) malgo3) | ||
3286 | & (MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_BASE_ALGO_SHA512_256 | ||
3287 | | MHD_DIGEST_BASE_ALGO_SHA512_256))) | ||
3288 | MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); | ||
3289 | else | ||
3290 | { | ||
3291 | #ifdef HAVE_MESSAGES | ||
3292 | MHD_DLOG (connection->daemon, | ||
3293 | _ ("No requested algorithm is supported by this MHD build.\n")); | ||
3294 | #endif /* HAVE_MESSAGES */ | ||
3295 | } | ||
3296 | return MHD_NO; | ||
3297 | } | ||
3081 | 3298 | ||
3082 | if (((unsigned int) mqop) != | 3299 | if (((unsigned int) mqop) != |
3083 | (((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT)) | 3300 | (((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT)) |
@@ -3095,8 +3312,8 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection, | |||
3095 | "are not compatible with RFC2069 and ignored.\n")); | 3312 | "are not compatible with RFC2069 and ignored.\n")); |
3096 | if (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5)) | 3313 | if (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5)) |
3097 | MHD_DLOG (connection->daemon, | 3314 | MHD_DLOG (connection->daemon, |
3098 | _ ("RFC2069 with SHA-256 algorithm is non-standard " \ | 3315 | _ ("RFC2069 with SHA-256 or SHA-512/256 algorithm is " \ |
3099 | "extension.\n")); | 3316 | "non-standard extension.\n")); |
3100 | #endif | 3317 | #endif |
3101 | userhash_support = 0; | 3318 | userhash_support = 0; |
3102 | prefer_utf8 = 0; | 3319 | prefer_utf8 = 0; |
@@ -3141,12 +3358,22 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection, | |||
3141 | (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5))) | 3358 | (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5))) |
3142 | { | 3359 | { |
3143 | buf_size += MHD_STATICSTR_LEN_ (prefix_algo) + 2; /* 2 for ', ' */ | 3360 | buf_size += MHD_STATICSTR_LEN_ (prefix_algo) + 2; /* 2 for ', ' */ |
3361 | #ifdef MHD_MD5_SUPPORT | ||
3144 | if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) | 3362 | if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) |
3145 | buf_size += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); | 3363 | buf_size += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); |
3146 | else if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) | 3364 | else |
3365 | #endif /* MHD_MD5_SUPPORT */ | ||
3366 | #ifdef MHD_SHA256_SUPPORT | ||
3367 | if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) | ||
3147 | buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); | 3368 | buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); |
3148 | else | 3369 | else |
3149 | mhd_assert (0); | 3370 | #endif /* MHD_SHA256_SUPPORT */ |
3371 | #ifdef MHD_SHA512_256_SUPPORT | ||
3372 | if (MHD_DIGEST_AUTH_ALGO3_SHA512_256 == s_algo) | ||
3373 | buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN); | ||
3374 | else | ||
3375 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
3376 | mhd_assert (0); | ||
3150 | } | 3377 | } |
3151 | /* 'nonce="xxxx", ' */ | 3378 | /* 'nonce="xxxx", ' */ |
3152 | buf_size += MHD_STATICSTR_LEN_ (prefix_nonce) + 3; /* 3 for '", ' */ | 3379 | buf_size += MHD_STATICSTR_LEN_ (prefix_nonce) + 3; /* 3 for '", ' */ |
@@ -3243,18 +3470,34 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection, | |||
3243 | memcpy (buf + p, prefix_algo, | 3470 | memcpy (buf + p, prefix_algo, |
3244 | MHD_STATICSTR_LEN_ (prefix_algo)); | 3471 | MHD_STATICSTR_LEN_ (prefix_algo)); |
3245 | p += MHD_STATICSTR_LEN_ (prefix_algo); | 3472 | p += MHD_STATICSTR_LEN_ (prefix_algo); |
3473 | #ifdef MHD_MD5_SUPPORT | ||
3246 | if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) | 3474 | if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) |
3247 | { | 3475 | { |
3248 | memcpy (buf + p, _MHD_MD5_TOKEN, | 3476 | memcpy (buf + p, _MHD_MD5_TOKEN, |
3249 | MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN)); | 3477 | MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN)); |
3250 | p += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); | 3478 | p += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); |
3251 | } | 3479 | } |
3252 | else if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) | 3480 | else |
3481 | #endif /* MHD_MD5_SUPPORT */ | ||
3482 | #ifdef MHD_SHA256_SUPPORT | ||
3483 | if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) | ||
3253 | { | 3484 | { |
3254 | memcpy (buf + p, _MHD_SHA256_TOKEN, | 3485 | memcpy (buf + p, _MHD_SHA256_TOKEN, |
3255 | MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN)); | 3486 | MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN)); |
3256 | p += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); | 3487 | p += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); |
3257 | } | 3488 | } |
3489 | else | ||
3490 | #endif /* MHD_SHA256_SUPPORT */ | ||
3491 | #ifdef MHD_SHA512_256_SUPPORT | ||
3492 | if (MHD_DIGEST_AUTH_ALGO3_SHA512_256 == s_algo) | ||
3493 | { | ||
3494 | memcpy (buf + p, _MHD_SHA512_256_TOKEN, | ||
3495 | MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN)); | ||
3496 | p += MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN); | ||
3497 | } | ||
3498 | else | ||
3499 | #endif /* MHD_SHA512_256_SUPPORT */ | ||
3500 | mhd_assert (0); | ||
3258 | buf[p++] = ','; | 3501 | buf[p++] = ','; |
3259 | buf[p++] = ' '; | 3502 | buf[p++] = ' '; |
3260 | } | 3503 | } |
@@ -3382,7 +3625,7 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
3382 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_MD5; | 3625 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_MD5; |
3383 | else if (MHD_DIGEST_ALG_SHA256 == algo) | 3626 | else if (MHD_DIGEST_ALG_SHA256 == algo) |
3384 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_SHA256; | 3627 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_SHA256; |
3385 | else if ((MHD_DIGEST_ALG_MD5 == algo) || (MHD_DIGEST_ALG_AUTO == algo)) | 3628 | else if (MHD_DIGEST_ALG_AUTO == algo) |
3386 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION; | 3629 | algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION; |
3387 | else | 3630 | else |
3388 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ | 3631 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ |