diff options
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r-- | src/microhttpd/digestauth.c | 936 |
1 files changed, 471 insertions, 465 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c index ce7edb79..95aee7b4 100644 --- a/src/microhttpd/digestauth.c +++ b/src/microhttpd/digestauth.c | |||
@@ -82,13 +82,15 @@ | |||
82 | /** | 82 | /** |
83 | * Check that @a n is below #MAX_NONCE | 83 | * Check that @a n is below #MAX_NONCE |
84 | */ | 84 | */ |
85 | #define VLA_CHECK_LEN_DIGEST(n) do { if ((n) > MAX_DIGEST) mhd_panic(mhd_panic_cls, __FILE__, __LINE__, "VLA too big"); } while (0) | 85 | #define VLA_CHECK_LEN_DIGEST(n) do { if ((n) > MAX_DIGEST) mhd_panic ( \ |
86 | mhd_panic_cls, __FILE__, __LINE__, \ | ||
87 | "VLA too big"); } while (0) | ||
86 | 88 | ||
87 | 89 | ||
88 | /** | 90 | /** |
89 | * Beginning string for any valid Digest authentication header. | 91 | * Beginning string for any valid Digest authentication header. |
90 | */ | 92 | */ |
91 | #define _BASE "Digest " | 93 | #define _BASE "Digest " |
92 | 94 | ||
93 | /** | 95 | /** |
94 | * Maximum length of a username for digest authentication. | 96 | * Maximum length of a username for digest authentication. |
@@ -149,7 +151,7 @@ struct DigestAlgorithm | |||
149 | */ | 151 | */ |
150 | void | 152 | void |
151 | (*update)(void *ctx, | 153 | (*update)(void *ctx, |
152 | const uint8_t *data, | 154 | const uint8_t *data, |
153 | size_t length); | 155 | size_t length); |
154 | 156 | ||
155 | /** | 157 | /** |
@@ -161,7 +163,7 @@ struct DigestAlgorithm | |||
161 | */ | 163 | */ |
162 | void | 164 | void |
163 | (*digest)(void *ctx, | 165 | (*digest)(void *ctx, |
164 | uint8_t *digest); | 166 | uint8_t *digest); |
165 | }; | 167 | }; |
166 | 168 | ||
167 | 169 | ||
@@ -174,19 +176,19 @@ struct DigestAlgorithm | |||
174 | */ | 176 | */ |
175 | static void | 177 | static void |
176 | cvthex (const unsigned char *bin, | 178 | cvthex (const unsigned char *bin, |
177 | size_t len, | 179 | size_t len, |
178 | char *hex) | 180 | char *hex) |
179 | { | 181 | { |
180 | size_t i; | 182 | size_t i; |
181 | unsigned int j; | 183 | unsigned int j; |
182 | 184 | ||
183 | for (i = 0; i < len; ++i) | 185 | for (i = 0; i < len; ++i) |
184 | { | 186 | { |
185 | j = (bin[i] >> 4) & 0x0f; | 187 | j = (bin[i] >> 4) & 0x0f; |
186 | hex[i * 2] = (char)((j <= 9) ? (j + '0') : (j - 10 + 'a')); | 188 | hex[i * 2] = (char) ((j <= 9) ? (j + '0') : (j - 10 + 'a')); |
187 | j = bin[i] & 0x0f; | 189 | j = bin[i] & 0x0f; |
188 | hex[i * 2 + 1] = (char)((j <= 9) ? (j + '0') : (j - 10 + 'a')); | 190 | hex[i * 2 + 1] = (char) ((j <= 9) ? (j + '0') : (j - 10 + 'a')); |
189 | } | 191 | } |
190 | hex[len * 2] = '\0'; | 192 | hex[len * 2] = '\0'; |
191 | } | 193 | } |
192 | 194 | ||
@@ -201,54 +203,54 @@ cvthex (const unsigned char *bin, | |||
201 | * @param[in,out] da digest implementation, must match @a alg; the | 203 | * @param[in,out] da digest implementation, must match @a alg; the |
202 | * da->sessionkey will be initialized to the digest in HEX | 204 | * da->sessionkey will be initialized to the digest in HEX |
203 | * @param digest An `unsigned char *' pointer to the binary MD5 sum | 205 | * @param digest An `unsigned char *' pointer to the binary MD5 sum |
204 | * for the precalculated hash value "username:realm:password" | 206 | * for the precalculated hash value "username:realm:password" |
205 | * of #MHD_MD5_DIGEST_SIZE or #MHD_SHA256_DIGEST_SIZE bytes | 207 | * of #MHD_MD5_DIGEST_SIZE or #MHD_SHA256_DIGEST_SIZE bytes |
206 | * @param nonce A `char *' pointer to the nonce value | 208 | * @param nonce A `char *' pointer to the nonce value |
207 | * @param cnonce A `char *' pointer to the cnonce value | 209 | * @param cnonce A `char *' pointer to the cnonce value |
208 | */ | 210 | */ |
209 | static void | 211 | static void |
210 | digest_calc_ha1_from_digest (const char *alg, | 212 | digest_calc_ha1_from_digest (const char *alg, |
211 | struct DigestAlgorithm *da, | 213 | struct DigestAlgorithm *da, |
212 | const uint8_t *digest, | 214 | const uint8_t *digest, |
213 | const char *nonce, | 215 | const char *nonce, |
214 | const char *cnonce) | 216 | const char *cnonce) |
215 | { | 217 | { |
216 | if ( (MHD_str_equal_caseless_(alg, | 218 | if ( (MHD_str_equal_caseless_ (alg, |
217 | "md5-sess")) || | 219 | "md5-sess")) || |
218 | (MHD_str_equal_caseless_(alg, | 220 | (MHD_str_equal_caseless_ (alg, |
219 | "sha-256-sess")) ) | 221 | "sha-256-sess")) ) |
220 | { | 222 | { |
221 | uint8_t dig[VLA_ARRAY_LEN_DIGEST(da->digest_size)]; | 223 | uint8_t dig[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; |
222 | 224 | ||
223 | VLA_CHECK_LEN_DIGEST(da->digest_size); | 225 | VLA_CHECK_LEN_DIGEST (da->digest_size); |
224 | da->init (da->ctx); | 226 | da->init (da->ctx); |
225 | da->update (da->ctx, | 227 | da->update (da->ctx, |
226 | digest, | 228 | digest, |
227 | MHD_MD5_DIGEST_SIZE); | 229 | MHD_MD5_DIGEST_SIZE); |
228 | da->update (da->ctx, | 230 | da->update (da->ctx, |
229 | (const unsigned char *) ":", | 231 | (const unsigned char *) ":", |
230 | 1); | 232 | 1); |
231 | da->update (da->ctx, | 233 | da->update (da->ctx, |
232 | (const unsigned char *) nonce, | 234 | (const unsigned char *) nonce, |
233 | strlen (nonce)); | 235 | strlen (nonce)); |
234 | da->update (da->ctx, | 236 | da->update (da->ctx, |
235 | (const unsigned char *) ":", | 237 | (const unsigned char *) ":", |
236 | 1); | 238 | 1); |
237 | da->update (da->ctx, | 239 | da->update (da->ctx, |
238 | (const unsigned char *) cnonce, | 240 | (const unsigned char *) cnonce, |
239 | strlen (cnonce)); | 241 | strlen (cnonce)); |
240 | da->digest (da->ctx, | 242 | da->digest (da->ctx, |
241 | dig); | 243 | dig); |
242 | cvthex (dig, | 244 | cvthex (dig, |
243 | sizeof (dig), | 245 | sizeof (dig), |
244 | da->sessionkey); | 246 | da->sessionkey); |
245 | } | 247 | } |
246 | else | 248 | else |
247 | { | 249 | { |
248 | cvthex (digest, | 250 | cvthex (digest, |
249 | da->digest_size, | 251 | da->digest_size, |
250 | da->sessionkey); | 252 | da->sessionkey); |
251 | } | 253 | } |
252 | } | 254 | } |
253 | 255 | ||
254 | 256 | ||
@@ -268,20 +270,20 @@ digest_calc_ha1_from_digest (const char *alg, | |||
268 | */ | 270 | */ |
269 | static void | 271 | static void |
270 | digest_calc_ha1_from_user (const char *alg, | 272 | digest_calc_ha1_from_user (const char *alg, |
271 | const char *username, | 273 | const char *username, |
272 | const char *realm, | 274 | const char *realm, |
273 | const char *password, | 275 | const char *password, |
274 | const char *nonce, | 276 | const char *nonce, |
275 | const char *cnonce, | 277 | const char *cnonce, |
276 | struct DigestAlgorithm *da) | 278 | struct DigestAlgorithm *da) |
277 | { | 279 | { |
278 | unsigned char ha1[VLA_ARRAY_LEN_DIGEST(da->digest_size)]; | 280 | unsigned char ha1[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; |
279 | 281 | ||
280 | VLA_CHECK_LEN_DIGEST(da->digest_size); | 282 | VLA_CHECK_LEN_DIGEST (da->digest_size); |
281 | da->init (da->ctx); | 283 | da->init (da->ctx); |
282 | da->update (da->ctx, | 284 | da->update (da->ctx, |
283 | (const unsigned char *) username, | 285 | (const unsigned char *) username, |
284 | strlen (username)); | 286 | strlen (username)); |
285 | da->update (da->ctx, | 287 | da->update (da->ctx, |
286 | (const unsigned char *) ":", | 288 | (const unsigned char *) ":", |
287 | 1); | 289 | 1); |
@@ -322,20 +324,20 @@ digest_calc_ha1_from_user (const char *alg, | |||
322 | */ | 324 | */ |
323 | static void | 325 | static void |
324 | digest_calc_response (const char *ha1, | 326 | digest_calc_response (const char *ha1, |
325 | const char *nonce, | 327 | const char *nonce, |
326 | const char *noncecount, | 328 | const char *noncecount, |
327 | const char *cnonce, | 329 | const char *cnonce, |
328 | const char *qop, | 330 | const char *qop, |
329 | const char *method, | 331 | const char *method, |
330 | const char *uri, | 332 | const char *uri, |
331 | const char *hentity, | 333 | const char *hentity, |
332 | struct DigestAlgorithm *da) | 334 | struct DigestAlgorithm *da) |
333 | { | 335 | { |
334 | unsigned char ha2[VLA_ARRAY_LEN_DIGEST(da->digest_size)]; | 336 | unsigned char ha2[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; |
335 | unsigned char resphash[VLA_ARRAY_LEN_DIGEST(da->digest_size)]; | 337 | unsigned char resphash[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; |
336 | (void)hentity; /* Unused. Silence compiler warning. */ | 338 | (void) hentity; /* Unused. Silence compiler warning. */ |
337 | 339 | ||
338 | VLA_CHECK_LEN_DIGEST(da->digest_size); | 340 | VLA_CHECK_LEN_DIGEST (da->digest_size); |
339 | da->init (da->ctx); | 341 | da->init (da->ctx); |
340 | da->update (da->ctx, | 342 | da->update (da->ctx, |
341 | (const unsigned char *) method, | 343 | (const unsigned char *) method, |
@@ -344,22 +346,22 @@ digest_calc_response (const char *ha1, | |||
344 | (const unsigned char *) ":", | 346 | (const unsigned char *) ":", |
345 | 1); | 347 | 1); |
346 | da->update (da->ctx, | 348 | da->update (da->ctx, |
347 | (const unsigned char *) uri, | 349 | (const unsigned char *) uri, |
348 | strlen (uri)); | 350 | strlen (uri)); |
349 | #if 0 | 351 | #if 0 |
350 | if (0 == strcasecmp (qop, | 352 | if (0 == strcasecmp (qop, |
351 | "auth-int")) | 353 | "auth-int")) |
352 | { | 354 | { |
353 | /* This is dead code since the rest of this module does | 355 | /* This is dead code since the rest of this module does |
354 | not support auth-int. */ | 356 | not support auth-int. */ |
357 | da->update (da->ctx, | ||
358 | ":", | ||
359 | 1); | ||
360 | if (NULL != hentity) | ||
355 | da->update (da->ctx, | 361 | da->update (da->ctx, |
356 | ":", | 362 | hentity, |
357 | 1); | 363 | strlen (hentity)); |
358 | if (NULL != hentity) | 364 | } |
359 | da->update (da->ctx, | ||
360 | hentity, | ||
361 | strlen (hentity)); | ||
362 | } | ||
363 | #endif | 365 | #endif |
364 | da->digest (da->ctx, | 366 | da->digest (da->ctx, |
365 | ha2); | 367 | ha2); |
@@ -381,26 +383,26 @@ digest_calc_response (const char *ha1, | |||
381 | (const unsigned char*) ":", | 383 | (const unsigned char*) ":", |
382 | 1); | 384 | 1); |
383 | if ('\0' != *qop) | 385 | if ('\0' != *qop) |
384 | { | 386 | { |
385 | da->update (da->ctx, | 387 | da->update (da->ctx, |
386 | (const unsigned char *) noncecount, | 388 | (const unsigned char *) noncecount, |
387 | strlen (noncecount)); | 389 | strlen (noncecount)); |
388 | da->update (da->ctx, | 390 | da->update (da->ctx, |
389 | (const unsigned char *) ":", | 391 | (const unsigned char *) ":", |
390 | 1); | 392 | 1); |
391 | da->update (da->ctx, | 393 | da->update (da->ctx, |
392 | (const unsigned char *) cnonce, | 394 | (const unsigned char *) cnonce, |
393 | strlen (cnonce)); | 395 | strlen (cnonce)); |
394 | da->update (da->ctx, | 396 | da->update (da->ctx, |
395 | (const unsigned char *) ":", | 397 | (const unsigned char *) ":", |
396 | 1); | 398 | 1); |
397 | da->update (da->ctx, | 399 | da->update (da->ctx, |
398 | (const unsigned char *) qop, | 400 | (const unsigned char *) qop, |
399 | strlen (qop)); | 401 | strlen (qop)); |
400 | da->update (da->ctx, | 402 | da->update (da->ctx, |
401 | (const unsigned char *) ":", | 403 | (const unsigned char *) ":", |
402 | 1); | 404 | 1); |
403 | } | 405 | } |
404 | da->update (da->ctx, | 406 | da->update (da->ctx, |
405 | (const unsigned char *) da->sessionkey, | 407 | (const unsigned char *) da->sessionkey, |
406 | da->digest_size * 2); | 408 | da->digest_size * 2); |
@@ -428,9 +430,9 @@ digest_calc_response (const char *ha1, | |||
428 | */ | 430 | */ |
429 | static size_t | 431 | static size_t |
430 | lookup_sub_value (char *dest, | 432 | lookup_sub_value (char *dest, |
431 | size_t size, | 433 | size_t size, |
432 | const char *data, | 434 | const char *data, |
433 | const char *key) | 435 | const char *key) |
434 | { | 436 | { |
435 | size_t keylen; | 437 | size_t keylen; |
436 | size_t len; | 438 | size_t len; |
@@ -445,67 +447,67 @@ lookup_sub_value (char *dest, | |||
445 | keylen = strlen (key); | 447 | keylen = strlen (key); |
446 | ptr = data; | 448 | ptr = data; |
447 | while ('\0' != *ptr) | 449 | while ('\0' != *ptr) |
450 | { | ||
451 | if (NULL == (eq = strchr (ptr, | ||
452 | '='))) | ||
453 | return 0; | ||
454 | q1 = eq + 1; | ||
455 | while (' ' == *q1) | ||
456 | q1++; | ||
457 | if ('\"' != *q1) | ||
458 | { | ||
459 | q2 = strchr (q1, | ||
460 | ','); | ||
461 | qn = q2; | ||
462 | } | ||
463 | else | ||
464 | { | ||
465 | q1++; | ||
466 | q2 = strchr (q1, | ||
467 | '\"'); | ||
468 | if (NULL == q2) | ||
469 | return 0; /* end quote not found */ | ||
470 | qn = q2 + 1; | ||
471 | } | ||
472 | if ( (MHD_str_equal_caseless_n_ (ptr, | ||
473 | key, | ||
474 | keylen)) && | ||
475 | (eq == &ptr[keylen]) ) | ||
448 | { | 476 | { |
449 | if (NULL == (eq = strchr (ptr, | 477 | if (NULL == q2) |
450 | '='))) | 478 | { |
451 | return 0; | 479 | len = strlen (q1) + 1; |
452 | q1 = eq + 1; | 480 | if (size > len) |
453 | while (' ' == *q1) | 481 | size = len; |
454 | q1++; | 482 | size--; |
455 | if ('\"' != *q1) | 483 | strncpy (dest, |
456 | { | 484 | q1, |
457 | q2 = strchr (q1, | 485 | size); |
458 | ','); | 486 | dest[size] = '\0'; |
459 | qn = q2; | 487 | return size; |
460 | } | 488 | } |
461 | else | 489 | else |
462 | { | 490 | { |
463 | q1++; | 491 | if (size > (size_t) ((q2 - q1) + 1)) |
464 | q2 = strchr (q1, | 492 | size = (q2 - q1) + 1; |
465 | '\"'); | 493 | size--; |
466 | if (NULL == q2) | 494 | memcpy (dest, |
467 | return 0; /* end quote not found */ | 495 | q1, |
468 | qn = q2 + 1; | 496 | size); |
469 | } | 497 | dest[size] = '\0'; |
470 | if ( (MHD_str_equal_caseless_n_(ptr, | 498 | return size; |
471 | key, | 499 | } |
472 | keylen)) && | ||
473 | (eq == &ptr[keylen]) ) | ||
474 | { | ||
475 | if (NULL == q2) | ||
476 | { | ||
477 | len = strlen (q1) + 1; | ||
478 | if (size > len) | ||
479 | size = len; | ||
480 | size--; | ||
481 | strncpy (dest, | ||
482 | q1, | ||
483 | size); | ||
484 | dest[size] = '\0'; | ||
485 | return size; | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | if (size > (size_t) ((q2 - q1) + 1)) | ||
490 | size = (q2 - q1) + 1; | ||
491 | size--; | ||
492 | memcpy (dest, | ||
493 | q1, | ||
494 | size); | ||
495 | dest[size] = '\0'; | ||
496 | return size; | ||
497 | } | ||
498 | } | ||
499 | if (NULL == qn) | ||
500 | return 0; | ||
501 | ptr = strchr (qn, | ||
502 | ','); | ||
503 | if (NULL == ptr) | ||
504 | return 0; | ||
505 | ptr++; | ||
506 | while (' ' == *ptr) | ||
507 | ptr++; | ||
508 | } | 500 | } |
501 | if (NULL == qn) | ||
502 | return 0; | ||
503 | ptr = strchr (qn, | ||
504 | ','); | ||
505 | if (NULL == ptr) | ||
506 | return 0; | ||
507 | ptr++; | ||
508 | while (' ' == *ptr) | ||
509 | ptr++; | ||
510 | } | ||
509 | return 0; | 511 | return 0; |
510 | } | 512 | } |
511 | 513 | ||
@@ -521,8 +523,8 @@ lookup_sub_value (char *dest, | |||
521 | */ | 523 | */ |
522 | static int | 524 | static int |
523 | check_nonce_nc (struct MHD_Connection *connection, | 525 | check_nonce_nc (struct MHD_Connection *connection, |
524 | const char *nonce, | 526 | const char *nonce, |
525 | uint64_t nc) | 527 | uint64_t nc) |
526 | { | 528 | { |
527 | struct MHD_Daemon *daemon = connection->daemon; | 529 | struct MHD_Daemon *daemon = connection->daemon; |
528 | struct MHD_NonceNc *nn; | 530 | struct MHD_NonceNc *nn; |
@@ -544,10 +546,10 @@ check_nonce_nc (struct MHD_Connection *connection, | |||
544 | off = 0; | 546 | off = 0; |
545 | np = nonce; | 547 | np = nonce; |
546 | while ('\0' != *np) | 548 | while ('\0' != *np) |
547 | { | 549 | { |
548 | off = (off << 8) | (*np ^ (off >> 24)); | 550 | off = (off << 8) | (*np ^ (off >> 24)); |
549 | np++; | 551 | np++; |
550 | } | 552 | } |
551 | off = off % mod; | 553 | off = off % mod; |
552 | /* | 554 | /* |
553 | * Look for the nonce, if it does exist and its corresponding | 555 | * Look for the nonce, if it does exist and its corresponding |
@@ -559,47 +561,48 @@ check_nonce_nc (struct MHD_Connection *connection, | |||
559 | MHD_mutex_lock_chk_ (&daemon->nnc_lock); | 561 | MHD_mutex_lock_chk_ (&daemon->nnc_lock); |
560 | #endif | 562 | #endif |
561 | if (0 == nc) | 563 | if (0 == nc) |
562 | { | 564 | { |
563 | /* Fresh nonce, reinitialize array */ | 565 | /* Fresh nonce, reinitialize array */ |
564 | memcpy (nn->nonce, | 566 | memcpy (nn->nonce, |
565 | nonce, | 567 | nonce, |
566 | noncelen); | 568 | noncelen); |
567 | nn->nc = 0; | 569 | nn->nc = 0; |
568 | nn->nmask = 0; | 570 | nn->nmask = 0; |
569 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 571 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
570 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); | 572 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); |
571 | #endif | 573 | #endif |
572 | return MHD_YES; | 574 | return MHD_YES; |
573 | } | 575 | } |
574 | /* Note that we use 64 here, as we do not store the | 576 | /* Note that we use 64 here, as we do not store the |
575 | bit for 'nn->nc' itself in 'nn->nmask' */ | 577 | bit for 'nn->nc' itself in 'nn->nmask' */ |
576 | if ( (nc < nn->nc) && | 578 | if ( (nc < nn->nc) && |
577 | (nc + 64 > nc /* checking for overflow */) && | 579 | (nc + 64 > nc /* checking for overflow */) && |
578 | (nc + 64 >= nn->nc) && | 580 | (nc + 64 >= nn->nc) && |
579 | (0 == ((1LLU << (nn->nc - nc - 1)) & nn->nmask)) ) | 581 | (0 == ((1LLU << (nn->nc - nc - 1)) & nn->nmask)) ) |
580 | { | 582 | { |
581 | /* Out-of-order nonce, but within 64-bit bitmask, set bit */ | 583 | /* Out-of-order nonce, but within 64-bit bitmask, set bit */ |
582 | nn->nmask |= (1LLU << (nn->nc - nc - 1)); | 584 | nn->nmask |= (1LLU << (nn->nc - nc - 1)); |
583 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 585 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
584 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); | 586 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); |
585 | #endif | 587 | #endif |
586 | return MHD_YES; | 588 | return MHD_YES; |
587 | } | 589 | } |
588 | 590 | ||
589 | if ( (nc <= nn->nc) || | 591 | if ( (nc <= nn->nc) || |
590 | (0 != strcmp (nn->nonce, | 592 | (0 != strcmp (nn->nonce, |
591 | nonce)) ) | 593 | nonce)) ) |
592 | { | 594 | { |
593 | /* Nonce does not match, fail */ | 595 | /* Nonce does not match, fail */ |
594 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 596 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
595 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); | 597 | MHD_mutex_unlock_chk_ (&daemon->nnc_lock); |
596 | #endif | 598 | #endif |
597 | #ifdef HAVE_MESSAGES | 599 | #ifdef HAVE_MESSAGES |
598 | MHD_DLOG (daemon, | 600 | MHD_DLOG (daemon, |
599 | _("Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n")); | 601 | _ ( |
602 | "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n")); | ||
600 | #endif | 603 | #endif |
601 | return MHD_NO; | 604 | return MHD_NO; |
602 | } | 605 | } |
603 | /* Nonce is larger, shift bitmask and bump limit */ | 606 | /* Nonce is larger, shift bitmask and bump limit */ |
604 | if (64 > nc - nn->nc) | 607 | if (64 > nc - nn->nc) |
605 | nn->nmask <<= (nc - nn->nc); /* small jump, less than mask width */ | 608 | nn->nmask <<= (nc - nn->nc); /* small jump, less than mask width */ |
@@ -618,12 +621,12 @@ check_nonce_nc (struct MHD_Connection *connection, | |||
618 | * | 621 | * |
619 | * @param connection The MHD connection structure | 622 | * @param connection The MHD connection structure |
620 | * @return NULL if no username could be found, a pointer | 623 | * @return NULL if no username could be found, a pointer |
621 | * to the username if found | 624 | * to the username if found |
622 | * @warning Returned value must be freed by #MHD_free(). | 625 | * @warning Returned value must be freed by #MHD_free(). |
623 | * @ingroup authentication | 626 | * @ingroup authentication |
624 | */ | 627 | */ |
625 | char * | 628 | char * |
626 | MHD_digest_auth_get_username(struct MHD_Connection *connection) | 629 | MHD_digest_auth_get_username (struct MHD_Connection *connection) |
627 | { | 630 | { |
628 | size_t len; | 631 | size_t len; |
629 | char user[MAX_USERNAME_LENGTH]; | 632 | char user[MAX_USERNAME_LENGTH]; |
@@ -632,7 +635,8 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection) | |||
632 | if (MHD_NO == MHD_lookup_connection_value_n (connection, | 635 | if (MHD_NO == MHD_lookup_connection_value_n (connection, |
633 | MHD_HEADER_KIND, | 636 | MHD_HEADER_KIND, |
634 | MHD_HTTP_HEADER_AUTHORIZATION, | 637 | MHD_HTTP_HEADER_AUTHORIZATION, |
635 | MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION), | 638 | MHD_STATICSTR_LEN_ ( |
639 | MHD_HTTP_HEADER_AUTHORIZATION), | ||
636 | &header, | 640 | &header, |
637 | NULL)) | 641 | NULL)) |
638 | return NULL; | 642 | return NULL; |
@@ -642,9 +646,9 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection) | |||
642 | return NULL; | 646 | return NULL; |
643 | header += MHD_STATICSTR_LEN_ (_BASE); | 647 | header += MHD_STATICSTR_LEN_ (_BASE); |
644 | if (0 == (len = lookup_sub_value (user, | 648 | if (0 == (len = lookup_sub_value (user, |
645 | sizeof (user), | 649 | sizeof (user), |
646 | header, | 650 | header, |
647 | "username"))) | 651 | "username"))) |
648 | return NULL; | 652 | return NULL; |
649 | return strdup (user); | 653 | return strdup (user); |
650 | } | 654 | } |
@@ -667,24 +671,24 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection) | |||
667 | */ | 671 | */ |
668 | static void | 672 | static void |
669 | calculate_nonce (uint32_t nonce_time, | 673 | calculate_nonce (uint32_t nonce_time, |
670 | const char *method, | 674 | const char *method, |
671 | const char *rnd, | 675 | const char *rnd, |
672 | size_t rnd_size, | 676 | size_t rnd_size, |
673 | const char *uri, | 677 | const char *uri, |
674 | const char *realm, | 678 | const char *realm, |
675 | struct DigestAlgorithm *da, | 679 | struct DigestAlgorithm *da, |
676 | char *nonce) | 680 | char *nonce) |
677 | { | 681 | { |
678 | unsigned char timestamp[TIMESTAMP_BIN_SIZE]; | 682 | unsigned char timestamp[TIMESTAMP_BIN_SIZE]; |
679 | unsigned char tmpnonce[VLA_ARRAY_LEN_DIGEST(da->digest_size)]; | 683 | unsigned char tmpnonce[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; |
680 | char timestamphex[TIMESTAMP_BIN_SIZE * 2 + 1]; | 684 | char timestamphex[TIMESTAMP_BIN_SIZE * 2 + 1]; |
681 | 685 | ||
682 | VLA_CHECK_LEN_DIGEST(da->digest_size); | 686 | VLA_CHECK_LEN_DIGEST (da->digest_size); |
683 | da->init (da->ctx); | 687 | da->init (da->ctx); |
684 | timestamp[0] = (unsigned char)((nonce_time & 0xff000000) >> 0x18); | 688 | timestamp[0] = (unsigned char) ((nonce_time & 0xff000000) >> 0x18); |
685 | timestamp[1] = (unsigned char)((nonce_time & 0x00ff0000) >> 0x10); | 689 | timestamp[1] = (unsigned char) ((nonce_time & 0x00ff0000) >> 0x10); |
686 | timestamp[2] = (unsigned char)((nonce_time & 0x0000ff00) >> 0x08); | 690 | timestamp[2] = (unsigned char) ((nonce_time & 0x0000ff00) >> 0x08); |
687 | timestamp[3] = (unsigned char)((nonce_time & 0x000000ff)); | 691 | timestamp[3] = (unsigned char) ((nonce_time & 0x000000ff)); |
688 | da->update (da->ctx, | 692 | da->update (da->ctx, |
689 | timestamp, | 693 | timestamp, |
690 | sizeof (timestamp)); | 694 | sizeof (timestamp)); |
@@ -742,37 +746,37 @@ calculate_nonce (uint32_t nonce_time, | |||
742 | */ | 746 | */ |
743 | static int | 747 | static int |
744 | test_header (struct MHD_Connection *connection, | 748 | test_header (struct MHD_Connection *connection, |
745 | const char *key, | 749 | const char *key, |
746 | size_t key_size, | 750 | size_t key_size, |
747 | const char *value, | 751 | const char *value, |
748 | size_t value_size, | 752 | size_t value_size, |
749 | enum MHD_ValueKind kind) | 753 | enum MHD_ValueKind kind) |
750 | { | 754 | { |
751 | struct MHD_HTTP_Header *pos; | 755 | struct MHD_HTTP_Header *pos; |
752 | 756 | ||
753 | for (pos = connection->headers_received; NULL != pos; pos = pos->next) | 757 | for (pos = connection->headers_received; NULL != pos; pos = pos->next) |
754 | { | 758 | { |
755 | if (kind != pos->kind) | 759 | if (kind != pos->kind) |
756 | continue; | 760 | continue; |
757 | if (key_size != pos->header_size) | 761 | if (key_size != pos->header_size) |
758 | continue; | 762 | continue; |
759 | if (value_size != pos->value_size) | 763 | if (value_size != pos->value_size) |
760 | continue; | 764 | continue; |
761 | if (0 != memcmp (key, | 765 | if (0 != memcmp (key, |
762 | pos->header, | 766 | pos->header, |
763 | key_size)) | 767 | key_size)) |
764 | continue; | 768 | continue; |
765 | if ( (NULL == value) && | 769 | if ( (NULL == value) && |
766 | (NULL == pos->value) ) | 770 | (NULL == pos->value) ) |
767 | return MHD_YES; | ||
768 | if ( (NULL == value) || | ||
769 | (NULL == pos->value) || | ||
770 | (0 != memcmp (value, | ||
771 | pos->value, | ||
772 | value_size)) ) | ||
773 | continue; | ||
774 | return MHD_YES; | 771 | return MHD_YES; |
775 | } | 772 | if ( (NULL == value) || |
773 | (NULL == pos->value) || | ||
774 | (0 != memcmp (value, | ||
775 | pos->value, | ||
776 | value_size)) ) | ||
777 | continue; | ||
778 | return MHD_YES; | ||
779 | } | ||
776 | return MHD_NO; | 780 | return MHD_NO; |
777 | } | 781 | } |
778 | 782 | ||
@@ -789,7 +793,7 @@ test_header (struct MHD_Connection *connection, | |||
789 | */ | 793 | */ |
790 | static int | 794 | static int |
791 | check_argument_match (struct MHD_Connection *connection, | 795 | check_argument_match (struct MHD_Connection *connection, |
792 | const char *args) | 796 | const char *args) |
793 | { | 797 | { |
794 | struct MHD_HTTP_Header *pos; | 798 | struct MHD_HTTP_Header *pos; |
795 | char *argb; | 799 | char *argb; |
@@ -798,35 +802,35 @@ check_argument_match (struct MHD_Connection *connection, | |||
798 | 802 | ||
799 | argb = strdup (args); | 803 | argb = strdup (args); |
800 | if (NULL == argb) | 804 | if (NULL == argb) |
801 | { | 805 | { |
802 | #ifdef HAVE_MESSAGES | 806 | #ifdef HAVE_MESSAGES |
803 | MHD_DLOG (connection->daemon, | 807 | MHD_DLOG (connection->daemon, |
804 | _("Failed to allocate memory for copy of URI arguments\n")); | 808 | _ ("Failed to allocate memory for copy of URI arguments\n")); |
805 | #endif /* HAVE_MESSAGES */ | 809 | #endif /* HAVE_MESSAGES */ |
806 | return MHD_NO; | 810 | return MHD_NO; |
807 | } | 811 | } |
808 | ret = MHD_parse_arguments_ (connection, | 812 | ret = MHD_parse_arguments_ (connection, |
809 | MHD_GET_ARGUMENT_KIND, | 813 | MHD_GET_ARGUMENT_KIND, |
810 | argb, | 814 | argb, |
811 | &test_header, | 815 | &test_header, |
812 | &num_headers); | 816 | &num_headers); |
813 | free (argb); | 817 | free (argb); |
814 | if (MHD_YES != ret) | 818 | if (MHD_YES != ret) |
815 | { | 819 | { |
816 | return MHD_NO; | 820 | return MHD_NO; |
817 | } | 821 | } |
818 | /* also check that the number of headers matches */ | 822 | /* also check that the number of headers matches */ |
819 | for (pos = connection->headers_received; NULL != pos; pos = pos->next) | 823 | for (pos = connection->headers_received; NULL != pos; pos = pos->next) |
820 | { | 824 | { |
821 | if (MHD_GET_ARGUMENT_KIND != pos->kind) | 825 | if (MHD_GET_ARGUMENT_KIND != pos->kind) |
822 | continue; | 826 | continue; |
823 | num_headers--; | 827 | num_headers--; |
824 | } | 828 | } |
825 | if (0 != num_headers) | 829 | if (0 != num_headers) |
826 | { | 830 | { |
827 | /* argument count mismatch */ | 831 | /* argument count mismatch */ |
828 | return MHD_NO; | 832 | return MHD_NO; |
829 | } | 833 | } |
830 | return MHD_YES; | 834 | return MHD_YES; |
831 | } | 835 | } |
832 | 836 | ||
@@ -842,51 +846,52 @@ check_argument_match (struct MHD_Connection *connection, | |||
842 | * @param username The username needs to be authenticated | 846 | * @param username The username needs to be authenticated |
843 | * @param password The password used in the authentication | 847 | * @param password The password used in the authentication |
844 | * @param digest An optional binary hash | 848 | * @param digest An optional binary hash |
845 | * of the precalculated hash value "username:realm:password" | 849 | * of the precalculated hash value "username:realm:password" |
846 | * (must contain "da->digest_size" bytes or be NULL) | 850 | * (must contain "da->digest_size" bytes or be NULL) |
847 | * @param nonce_timeout The amount of time for a nonce to be | 851 | * @param nonce_timeout The amount of time for a nonce to be |
848 | * invalid in seconds | 852 | * invalid in seconds |
849 | * @return #MHD_YES if authenticated, #MHD_NO if not, | 853 | * @return #MHD_YES if authenticated, #MHD_NO if not, |
850 | * #MHD_INVALID_NONCE if nonce is invalid | 854 | * #MHD_INVALID_NONCE if nonce is invalid |
851 | * @ingroup authentication | 855 | * @ingroup authentication |
852 | */ | 856 | */ |
853 | static int | 857 | static int |
854 | digest_auth_check_all (struct MHD_Connection *connection, | 858 | digest_auth_check_all (struct MHD_Connection *connection, |
855 | struct DigestAlgorithm *da, | 859 | struct DigestAlgorithm *da, |
856 | const char *realm, | 860 | const char *realm, |
857 | const char *username, | 861 | const char *username, |
858 | const char *password, | 862 | const char *password, |
859 | const uint8_t *digest, | 863 | const uint8_t *digest, |
860 | unsigned int nonce_timeout) | 864 | unsigned int nonce_timeout) |
861 | { | 865 | { |
862 | struct MHD_Daemon *daemon = connection->daemon; | 866 | struct MHD_Daemon *daemon = connection->daemon; |
863 | size_t len; | 867 | size_t len; |
864 | const char *header; | 868 | const char *header; |
865 | char nonce[MAX_NONCE_LENGTH]; | 869 | char nonce[MAX_NONCE_LENGTH]; |
866 | char cnonce[MAX_NONCE_LENGTH]; | 870 | char cnonce[MAX_NONCE_LENGTH]; |
867 | char ha1[VLA_ARRAY_LEN_DIGEST(da->digest_size) * 2 + 1]; | 871 | char ha1[VLA_ARRAY_LEN_DIGEST (da->digest_size) * 2 + 1]; |
868 | char qop[15]; /* auth,auth-int */ | 872 | char qop[15]; /* auth,auth-int */ |
869 | char nc[20]; | 873 | char nc[20]; |
870 | char response[MAX_AUTH_RESPONSE_LENGTH]; | 874 | char response[MAX_AUTH_RESPONSE_LENGTH]; |
871 | const char *hentity = NULL; /* "auth-int" is not supported */ | 875 | const char *hentity = NULL; /* "auth-int" is not supported */ |
872 | char noncehashexp[NONCE_STD_LEN(VLA_ARRAY_LEN_DIGEST(da->digest_size)) + 1]; | 876 | char noncehashexp[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (da->digest_size)) + 1]; |
873 | uint32_t nonce_time; | 877 | uint32_t nonce_time; |
874 | uint32_t t; | 878 | uint32_t t; |
875 | size_t left; /* number of characters left in 'header' for 'uri' */ | 879 | size_t left; /* number of characters left in 'header' for 'uri' */ |
876 | uint64_t nci; | 880 | uint64_t nci; |
877 | char *qmark; | 881 | char *qmark; |
878 | 882 | ||
879 | VLA_CHECK_LEN_DIGEST(da->digest_size); | 883 | VLA_CHECK_LEN_DIGEST (da->digest_size); |
880 | if (MHD_NO == MHD_lookup_connection_value_n (connection, | 884 | if (MHD_NO == MHD_lookup_connection_value_n (connection, |
881 | MHD_HEADER_KIND, | 885 | MHD_HEADER_KIND, |
882 | MHD_HTTP_HEADER_AUTHORIZATION, | 886 | MHD_HTTP_HEADER_AUTHORIZATION, |
883 | MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION), | 887 | MHD_STATICSTR_LEN_ ( |
888 | MHD_HTTP_HEADER_AUTHORIZATION), | ||
884 | &header, | 889 | &header, |
885 | NULL)) | 890 | NULL)) |
886 | return MHD_NO; | 891 | return MHD_NO; |
887 | if (0 != strncmp (header, | 892 | if (0 != strncmp (header, |
888 | _BASE, | 893 | _BASE, |
889 | MHD_STATICSTR_LEN_(_BASE))) | 894 | MHD_STATICSTR_LEN_ (_BASE))) |
890 | return MHD_NO; | 895 | return MHD_NO; |
891 | header += MHD_STATICSTR_LEN_ (_BASE); | 896 | header += MHD_STATICSTR_LEN_ (_BASE); |
892 | left = strlen (header); | 897 | left = strlen (header); |
@@ -895,11 +900,11 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
895 | char un[MAX_USERNAME_LENGTH]; | 900 | char un[MAX_USERNAME_LENGTH]; |
896 | 901 | ||
897 | len = lookup_sub_value (un, | 902 | len = lookup_sub_value (un, |
898 | sizeof (un), | 903 | sizeof (un), |
899 | header, | 904 | header, |
900 | "username"); | 905 | "username"); |
901 | if ( (0 == len) || | 906 | if ( (0 == len) || |
902 | (0 != strcmp (username, | 907 | (0 != strcmp (username, |
903 | un)) ) | 908 | un)) ) |
904 | return MHD_NO; | 909 | return MHD_NO; |
905 | left -= strlen ("username") + len; | 910 | left -= strlen ("username") + len; |
@@ -913,15 +918,15 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
913 | header, | 918 | header, |
914 | "realm"); | 919 | "realm"); |
915 | if ( (0 == len) || | 920 | if ( (0 == len) || |
916 | (0 != strcmp (realm, | 921 | (0 != strcmp (realm, |
917 | r)) ) | 922 | r)) ) |
918 | return MHD_NO; | 923 | return MHD_NO; |
919 | left -= strlen ("realm") + len; | 924 | left -= strlen ("realm") + len; |
920 | } | 925 | } |
921 | 926 | ||
922 | if (0 == (len = lookup_sub_value (nonce, | 927 | if (0 == (len = lookup_sub_value (nonce, |
923 | sizeof (nonce), | 928 | sizeof (nonce), |
924 | header, | 929 | header, |
925 | "nonce"))) | 930 | "nonce"))) |
926 | return MHD_NO; | 931 | return MHD_NO; |
927 | left -= strlen ("nonce") + len; | 932 | left -= strlen ("nonce") + len; |
@@ -940,14 +945,14 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
940 | MHD_strx_to_uint32_n_ (nonce + len - TIMESTAMP_BIN_SIZE * 2, | 945 | MHD_strx_to_uint32_n_ (nonce + len - TIMESTAMP_BIN_SIZE * 2, |
941 | TIMESTAMP_BIN_SIZE * 2, | 946 | TIMESTAMP_BIN_SIZE * 2, |
942 | &nonce_time)) | 947 | &nonce_time)) |
943 | { | 948 | { |
944 | #ifdef HAVE_MESSAGES | 949 | #ifdef HAVE_MESSAGES |
945 | MHD_DLOG (daemon, | 950 | MHD_DLOG (daemon, |
946 | _("Authentication failed, invalid timestamp format.\n")); | 951 | _ ("Authentication failed, invalid timestamp format.\n")); |
947 | #endif | 952 | #endif |
948 | return MHD_NO; | 953 | return MHD_NO; |
949 | } | 954 | } |
950 | t = (uint32_t) MHD_monotonic_sec_counter(); | 955 | t = (uint32_t) MHD_monotonic_sec_counter (); |
951 | /* | 956 | /* |
952 | * First level vetting for the nonce validity: if the timestamp | 957 | * First level vetting for the nonce validity: if the timestamp |
953 | * attached to the nonce exceeds `nonce_timeout', then the nonce is | 958 | * attached to the nonce exceeds `nonce_timeout', then the nonce is |
@@ -955,10 +960,10 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
955 | */ | 960 | */ |
956 | if ( (t > nonce_time + nonce_timeout) || | 961 | if ( (t > nonce_time + nonce_timeout) || |
957 | (nonce_time + nonce_timeout < nonce_time) ) | 962 | (nonce_time + nonce_timeout < nonce_time) ) |
958 | { | 963 | { |
959 | /* too old */ | 964 | /* too old */ |
960 | return MHD_INVALID_NONCE; | 965 | return MHD_INVALID_NONCE; |
961 | } | 966 | } |
962 | 967 | ||
963 | calculate_nonce (nonce_time, | 968 | calculate_nonce (nonce_time, |
964 | connection->method, | 969 | connection->method, |
@@ -980,9 +985,9 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
980 | 985 | ||
981 | if (0 != strcmp (nonce, | 986 | if (0 != strcmp (nonce, |
982 | noncehashexp)) | 987 | noncehashexp)) |
983 | { | 988 | { |
984 | return MHD_INVALID_NONCE; | 989 | return MHD_INVALID_NONCE; |
985 | } | 990 | } |
986 | if ( (0 == lookup_sub_value (cnonce, | 991 | if ( (0 == lookup_sub_value (cnonce, |
987 | sizeof (cnonce), | 992 | sizeof (cnonce), |
988 | header, | 993 | header, |
@@ -1003,23 +1008,23 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1003 | sizeof (response), | 1008 | sizeof (response), |
1004 | header, | 1009 | header, |
1005 | "response")) ) | 1010 | "response")) ) |
1006 | { | 1011 | { |
1007 | #ifdef HAVE_MESSAGES | 1012 | #ifdef HAVE_MESSAGES |
1008 | MHD_DLOG (daemon, | 1013 | MHD_DLOG (daemon, |
1009 | _("Authentication failed, invalid format.\n")); | 1014 | _ ("Authentication failed, invalid format.\n")); |
1010 | #endif | 1015 | #endif |
1011 | return MHD_NO; | 1016 | return MHD_NO; |
1012 | } | 1017 | } |
1013 | if (len != MHD_strx_to_uint64_n_ (nc, | 1018 | if (len != MHD_strx_to_uint64_n_ (nc, |
1014 | len, | 1019 | len, |
1015 | &nci)) | 1020 | &nci)) |
1016 | { | 1021 | { |
1017 | #ifdef HAVE_MESSAGES | 1022 | #ifdef HAVE_MESSAGES |
1018 | MHD_DLOG (daemon, | 1023 | MHD_DLOG (daemon, |
1019 | _("Authentication failed, invalid nc format.\n")); | 1024 | _ ("Authentication failed, invalid nc format.\n")); |
1020 | #endif | 1025 | #endif |
1021 | return MHD_NO; /* invalid nonce format */ | 1026 | return MHD_NO; /* invalid nonce format */ |
1022 | } | 1027 | } |
1023 | 1028 | ||
1024 | /* | 1029 | /* |
1025 | * Checking if that combination of nonce and nc is sound | 1030 | * Checking if that combination of nonce and nc is sound |
@@ -1030,64 +1035,64 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1030 | check_nonce_nc (connection, | 1035 | check_nonce_nc (connection, |
1031 | nonce, | 1036 | nonce, |
1032 | nci)) | 1037 | nci)) |
1033 | { | 1038 | { |
1034 | return MHD_NO; | 1039 | return MHD_NO; |
1035 | } | 1040 | } |
1036 | 1041 | ||
1037 | { | 1042 | { |
1038 | char *uri; | 1043 | char *uri; |
1039 | 1044 | ||
1040 | uri = malloc (left + 1); | 1045 | uri = malloc (left + 1); |
1041 | if (NULL == uri) | 1046 | if (NULL == uri) |
1042 | { | 1047 | { |
1043 | #ifdef HAVE_MESSAGES | 1048 | #ifdef HAVE_MESSAGES |
1044 | MHD_DLOG(daemon, | 1049 | MHD_DLOG (daemon, |
1045 | _("Failed to allocate memory for auth header processing\n")); | 1050 | _ ("Failed to allocate memory for auth header processing\n")); |
1046 | #endif /* HAVE_MESSAGES */ | 1051 | #endif /* HAVE_MESSAGES */ |
1047 | return MHD_NO; | 1052 | return MHD_NO; |
1048 | } | 1053 | } |
1049 | if (0 == lookup_sub_value (uri, | 1054 | if (0 == lookup_sub_value (uri, |
1050 | left + 1, | 1055 | left + 1, |
1051 | header, | 1056 | header, |
1052 | "uri")) | 1057 | "uri")) |
1053 | { | 1058 | { |
1054 | free (uri); | 1059 | free (uri); |
1055 | return MHD_NO; | 1060 | return MHD_NO; |
1056 | } | 1061 | } |
1057 | if (NULL != digest) | 1062 | if (NULL != digest) |
1058 | { | 1063 | { |
1059 | /* This will initialize da->sessionkey (ha1) */ | 1064 | /* This will initialize da->sessionkey (ha1) */ |
1060 | digest_calc_ha1_from_digest (da->alg, | 1065 | digest_calc_ha1_from_digest (da->alg, |
1061 | da, | 1066 | da, |
1062 | digest, | 1067 | digest, |
1063 | nonce, | 1068 | nonce, |
1064 | cnonce); | 1069 | cnonce); |
1065 | } | 1070 | } |
1066 | else | 1071 | else |
1067 | { | 1072 | { |
1068 | /* This will initialize da->sessionkey (ha1) */ | 1073 | /* This will initialize da->sessionkey (ha1) */ |
1069 | mhd_assert (NULL != password); /* NULL == digest => password != NULL */ | 1074 | mhd_assert (NULL != password); /* NULL == digest => password != NULL */ |
1070 | digest_calc_ha1_from_user (da->alg, | 1075 | digest_calc_ha1_from_user (da->alg, |
1071 | username, | 1076 | username, |
1072 | realm, | 1077 | realm, |
1073 | password, | 1078 | password, |
1074 | nonce, | 1079 | nonce, |
1075 | cnonce, | 1080 | cnonce, |
1076 | da); | 1081 | da); |
1077 | } | 1082 | } |
1078 | memcpy (ha1, | 1083 | memcpy (ha1, |
1079 | da->sessionkey, | 1084 | da->sessionkey, |
1080 | sizeof (ha1)); | 1085 | sizeof (ha1)); |
1081 | /* This will initialize da->sessionkey (respexp) */ | 1086 | /* This will initialize da->sessionkey (respexp) */ |
1082 | digest_calc_response (ha1, | 1087 | digest_calc_response (ha1, |
1083 | nonce, | 1088 | nonce, |
1084 | nc, | 1089 | nc, |
1085 | cnonce, | 1090 | cnonce, |
1086 | qop, | 1091 | qop, |
1087 | connection->method, | 1092 | connection->method, |
1088 | uri, | 1093 | uri, |
1089 | hentity, | 1094 | hentity, |
1090 | da); | 1095 | da); |
1091 | qmark = strchr (uri, | 1096 | qmark = strchr (uri, |
1092 | '?'); | 1097 | '?'); |
1093 | if (NULL != qmark) | 1098 | if (NULL != qmark) |
@@ -1102,7 +1107,7 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1102 | { | 1107 | { |
1103 | #ifdef HAVE_MESSAGES | 1108 | #ifdef HAVE_MESSAGES |
1104 | MHD_DLOG (daemon, | 1109 | MHD_DLOG (daemon, |
1105 | _("Authentication failed, URI does not match.\n")); | 1110 | _ ("Authentication failed, URI does not match.\n")); |
1106 | #endif | 1111 | #endif |
1107 | free (uri); | 1112 | free (uri); |
1108 | return MHD_NO; | 1113 | return MHD_NO; |
@@ -1112,26 +1117,26 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1112 | const char *args = qmark; | 1117 | const char *args = qmark; |
1113 | 1118 | ||
1114 | if (NULL == args) | 1119 | if (NULL == args) |
1115 | args = ""; | 1120 | args = ""; |
1116 | else | 1121 | else |
1117 | args++; | 1122 | args++; |
1118 | if (MHD_YES != | 1123 | if (MHD_YES != |
1119 | check_argument_match (connection, | 1124 | check_argument_match (connection, |
1120 | args) ) | 1125 | args) ) |
1121 | { | 1126 | { |
1122 | #ifdef HAVE_MESSAGES | 1127 | #ifdef HAVE_MESSAGES |
1123 | MHD_DLOG (daemon, | 1128 | MHD_DLOG (daemon, |
1124 | _("Authentication failed, arguments do not match.\n")); | 1129 | _ ("Authentication failed, arguments do not match.\n")); |
1125 | #endif | 1130 | #endif |
1126 | free (uri); | 1131 | free (uri); |
1127 | return MHD_NO; | 1132 | return MHD_NO; |
1128 | } | 1133 | } |
1129 | } | 1134 | } |
1130 | free (uri); | 1135 | free (uri); |
1131 | return (0 == strcmp (response, | 1136 | return (0 == strcmp (response, |
1132 | da->sessionkey)) | 1137 | da->sessionkey)) |
1133 | ? MHD_YES | 1138 | ? MHD_YES |
1134 | : MHD_NO; | 1139 | : MHD_NO; |
1135 | } | 1140 | } |
1136 | } | 1141 | } |
1137 | 1142 | ||
@@ -1148,17 +1153,17 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1148 | * @param username The username needs to be authenticated | 1153 | * @param username The username needs to be authenticated |
1149 | * @param password The password used in the authentication | 1154 | * @param password The password used in the authentication |
1150 | * @param nonce_timeout The amount of time for a nonce to be | 1155 | * @param nonce_timeout The amount of time for a nonce to be |
1151 | * invalid in seconds | 1156 | * invalid in seconds |
1152 | * @return #MHD_YES if authenticated, #MHD_NO if not, | 1157 | * @return #MHD_YES if authenticated, #MHD_NO if not, |
1153 | * #MHD_INVALID_NONCE if nonce is invalid | 1158 | * #MHD_INVALID_NONCE if nonce is invalid |
1154 | * @ingroup authentication | 1159 | * @ingroup authentication |
1155 | */ | 1160 | */ |
1156 | _MHD_EXTERN int | 1161 | _MHD_EXTERN int |
1157 | MHD_digest_auth_check (struct MHD_Connection *connection, | 1162 | MHD_digest_auth_check (struct MHD_Connection *connection, |
1158 | const char *realm, | 1163 | const char *realm, |
1159 | const char *username, | 1164 | const char *username, |
1160 | const char *password, | 1165 | const char *password, |
1161 | unsigned int nonce_timeout) | 1166 | unsigned int nonce_timeout) |
1162 | { | 1167 | { |
1163 | return MHD_digest_auth_check2 (connection, | 1168 | return MHD_digest_auth_check2 (connection, |
1164 | realm, | 1169 | realm, |
@@ -1189,29 +1194,29 @@ MHD_digest_auth_check (struct MHD_Connection *connection, | |||
1189 | struct DigestAlgorithm da; \ | 1194 | struct DigestAlgorithm da; \ |
1190 | \ | 1195 | \ |
1191 | do { \ | 1196 | do { \ |
1192 | switch (algo) { \ | 1197 | switch (algo) { \ |
1193 | case MHD_DIGEST_ALG_MD5: \ | 1198 | case MHD_DIGEST_ALG_MD5: \ |
1194 | da.digest_size = MD5_DIGEST_SIZE; \ | 1199 | da.digest_size = MD5_DIGEST_SIZE; \ |
1195 | da.ctx = &ctx.md5; \ | 1200 | da.ctx = &ctx.md5; \ |
1196 | da.alg = "md5"; \ | 1201 | da.alg = "md5"; \ |
1197 | da.sessionkey = skey.md5; \ | 1202 | da.sessionkey = skey.md5; \ |
1198 | da.init = &MHD_MD5Init; \ | 1203 | da.init = &MHD_MD5Init; \ |
1199 | da.update = &MHD_MD5Update; \ | 1204 | da.update = &MHD_MD5Update; \ |
1200 | da.digest = &MHD_MD5Final; \ | 1205 | da.digest = &MHD_MD5Final; \ |
1201 | break; \ | 1206 | break; \ |
1202 | case MHD_DIGEST_ALG_AUTO: \ | 1207 | case MHD_DIGEST_ALG_AUTO: \ |
1203 | /* auto == SHA256, fall-though thus intentional! */ \ | 1208 | /* auto == SHA256, fall-though thus intentional! */ \ |
1204 | case MHD_DIGEST_ALG_SHA256: \ | 1209 | case MHD_DIGEST_ALG_SHA256: \ |
1205 | da.digest_size = SHA256_DIGEST_SIZE; \ | 1210 | da.digest_size = SHA256_DIGEST_SIZE; \ |
1206 | da.ctx = &ctx.sha256; \ | 1211 | da.ctx = &ctx.sha256; \ |
1207 | da.alg = "sha-256"; \ | 1212 | da.alg = "sha-256"; \ |
1208 | da.sessionkey = skey.sha256; \ | 1213 | da.sessionkey = skey.sha256; \ |
1209 | da.init = &MHD_SHA256_init; \ | 1214 | da.init = &MHD_SHA256_init; \ |
1210 | da.update = &MHD_SHA256_update; \ | 1215 | da.update = &MHD_SHA256_update; \ |
1211 | da.digest = &sha256_finish; \ | 1216 | da.digest = &sha256_finish; \ |
1212 | break; \ | 1217 | break; \ |
1213 | } \ | 1218 | } \ |
1214 | } while(0) | 1219 | } while (0) |
1215 | 1220 | ||
1216 | 1221 | ||
1217 | 1222 | ||
@@ -1223,19 +1228,19 @@ MHD_digest_auth_check (struct MHD_Connection *connection, | |||
1223 | * @param username The username needs to be authenticated | 1228 | * @param username The username needs to be authenticated |
1224 | * @param password The password used in the authentication | 1229 | * @param password The password used in the authentication |
1225 | * @param nonce_timeout The amount of time for a nonce to be | 1230 | * @param nonce_timeout The amount of time for a nonce to be |
1226 | * invalid in seconds | 1231 | * invalid in seconds |
1227 | * @param algo digest algorithms allowed for verification | 1232 | * @param algo digest algorithms allowed for verification |
1228 | * @return #MHD_YES if authenticated, #MHD_NO if not, | 1233 | * @return #MHD_YES if authenticated, #MHD_NO if not, |
1229 | * #MHD_INVALID_NONCE if nonce is invalid | 1234 | * #MHD_INVALID_NONCE if nonce is invalid |
1230 | * @ingroup authentication | 1235 | * @ingroup authentication |
1231 | */ | 1236 | */ |
1232 | _MHD_EXTERN int | 1237 | _MHD_EXTERN int |
1233 | MHD_digest_auth_check2 (struct MHD_Connection *connection, | 1238 | MHD_digest_auth_check2 (struct MHD_Connection *connection, |
1234 | const char *realm, | 1239 | const char *realm, |
1235 | const char *username, | 1240 | const char *username, |
1236 | const char *password, | 1241 | const char *password, |
1237 | unsigned int nonce_timeout, | 1242 | unsigned int nonce_timeout, |
1238 | enum MHD_DigestAuthAlgorithm algo) | 1243 | enum MHD_DigestAuthAlgorithm algo) |
1239 | { | 1244 | { |
1240 | SETUP_DA (algo, da); | 1245 | SETUP_DA (algo, da); |
1241 | 1246 | ||
@@ -1256,36 +1261,36 @@ MHD_digest_auth_check2 (struct MHD_Connection *connection, | |||
1256 | * @param realm The realm presented to the client | 1261 | * @param realm The realm presented to the client |
1257 | * @param username The username needs to be authenticated | 1262 | * @param username The username needs to be authenticated |
1258 | * @param digest An `unsigned char *' pointer to the binary MD5 sum | 1263 | * @param digest An `unsigned char *' pointer to the binary MD5 sum |
1259 | * for the precalculated hash value "username:realm:password" | 1264 | * for the precalculated hash value "username:realm:password" |
1260 | * of #MHD_MD5_DIGEST_SIZE bytes | 1265 | * of #MHD_MD5_DIGEST_SIZE bytes |
1261 | * @param digest_size number of bytes in @a digest | 1266 | * @param digest_size number of bytes in @a digest |
1262 | * @param nonce_timeout The amount of time for a nonce to be | 1267 | * @param nonce_timeout The amount of time for a nonce to be |
1263 | * invalid in seconds | 1268 | * invalid in seconds |
1264 | * @param algo digest algorithms allowed for verification | 1269 | * @param algo digest algorithms allowed for verification |
1265 | * @return #MHD_YES if authenticated, #MHD_NO if not, | 1270 | * @return #MHD_YES if authenticated, #MHD_NO if not, |
1266 | * #MHD_INVALID_NONCE if nonce is invalid | 1271 | * #MHD_INVALID_NONCE if nonce is invalid |
1267 | * @ingroup authentication | 1272 | * @ingroup authentication |
1268 | */ | 1273 | */ |
1269 | _MHD_EXTERN int | 1274 | _MHD_EXTERN int |
1270 | MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, | 1275 | MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, |
1271 | const char *realm, | 1276 | const char *realm, |
1272 | const char *username, | 1277 | const char *username, |
1273 | const uint8_t *digest, | 1278 | const uint8_t *digest, |
1274 | size_t digest_size, | 1279 | size_t digest_size, |
1275 | unsigned int nonce_timeout, | 1280 | unsigned int nonce_timeout, |
1276 | enum MHD_DigestAuthAlgorithm algo) | 1281 | enum MHD_DigestAuthAlgorithm algo) |
1277 | { | 1282 | { |
1278 | SETUP_DA (algo, da); | 1283 | SETUP_DA (algo, da); |
1279 | 1284 | ||
1280 | if (da.digest_size != digest_size) | 1285 | if (da.digest_size != digest_size) |
1281 | MHD_PANIC (_("digest size missmatch")); /* API violation! */ | 1286 | MHD_PANIC (_ ("digest size missmatch")); /* API violation! */ |
1282 | return digest_auth_check_all (connection, | 1287 | return digest_auth_check_all (connection, |
1283 | &da, | 1288 | &da, |
1284 | realm, | 1289 | realm, |
1285 | username, | 1290 | username, |
1286 | NULL, | 1291 | NULL, |
1287 | digest, | 1292 | digest, |
1288 | nonce_timeout); | 1293 | nonce_timeout); |
1289 | } | 1294 | } |
1290 | 1295 | ||
1291 | 1296 | ||
@@ -1298,20 +1303,20 @@ MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, | |||
1298 | * @param realm The realm presented to the client | 1303 | * @param realm The realm presented to the client |
1299 | * @param username The username needs to be authenticated | 1304 | * @param username The username needs to be authenticated |
1300 | * @param digest An `unsigned char *' pointer to the binary digest | 1305 | * @param digest An `unsigned char *' pointer to the binary digest |
1301 | * for the precalculated hash value "username:realm:password" | 1306 | * for the precalculated hash value "username:realm:password" |
1302 | * of @a digest_size bytes | 1307 | * of @a digest_size bytes |
1303 | * @param nonce_timeout The amount of time for a nonce to be | 1308 | * @param nonce_timeout The amount of time for a nonce to be |
1304 | * invalid in seconds | 1309 | * invalid in seconds |
1305 | * @return #MHD_YES if authenticated, #MHD_NO if not, | 1310 | * @return #MHD_YES if authenticated, #MHD_NO if not, |
1306 | * #MHD_INVALID_NONCE if nonce is invalid | 1311 | * #MHD_INVALID_NONCE if nonce is invalid |
1307 | * @ingroup authentication | 1312 | * @ingroup authentication |
1308 | */ | 1313 | */ |
1309 | _MHD_EXTERN int | 1314 | _MHD_EXTERN int |
1310 | MHD_digest_auth_check_digest (struct MHD_Connection *connection, | 1315 | MHD_digest_auth_check_digest (struct MHD_Connection *connection, |
1311 | const char *realm, | 1316 | const char *realm, |
1312 | const char *username, | 1317 | const char *username, |
1313 | const uint8_t digest[MHD_MD5_DIGEST_SIZE], | 1318 | const uint8_t digest[MHD_MD5_DIGEST_SIZE], |
1314 | unsigned int nonce_timeout) | 1319 | unsigned int nonce_timeout) |
1315 | { | 1320 | { |
1316 | return MHD_digest_auth_check_digest2 (connection, | 1321 | return MHD_digest_auth_check_digest2 (connection, |
1317 | realm, | 1322 | realm, |
@@ -1333,29 +1338,29 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection, | |||
1333 | * body; note that this function will set the "WWW Authenticate" | 1338 | * body; note that this function will set the "WWW Authenticate" |
1334 | * header and that the caller should not do this | 1339 | * header and that the caller should not do this |
1335 | * @param signal_stale #MHD_YES if the nonce is invalid to add | 1340 | * @param signal_stale #MHD_YES if the nonce is invalid to add |
1336 | * 'stale=true' to the authentication header | 1341 | * 'stale=true' to the authentication header |
1337 | * @param algo digest algorithm to use | 1342 | * @param algo digest algorithm to use |
1338 | * @return #MHD_YES on success, #MHD_NO otherwise | 1343 | * @return #MHD_YES on success, #MHD_NO otherwise |
1339 | * @ingroup authentication | 1344 | * @ingroup authentication |
1340 | */ | 1345 | */ |
1341 | int | 1346 | int |
1342 | MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | 1347 | MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, |
1343 | const char *realm, | 1348 | const char *realm, |
1344 | const char *opaque, | 1349 | const char *opaque, |
1345 | struct MHD_Response *response, | 1350 | struct MHD_Response *response, |
1346 | int signal_stale, | 1351 | int signal_stale, |
1347 | enum MHD_DigestAuthAlgorithm algo) | 1352 | enum MHD_DigestAuthAlgorithm algo) |
1348 | { | 1353 | { |
1349 | int ret; | 1354 | int ret; |
1350 | int hlen; | 1355 | int hlen; |
1351 | SETUP_DA (algo, da); | 1356 | SETUP_DA (algo, da); |
1352 | 1357 | ||
1353 | { | 1358 | { |
1354 | char nonce[NONCE_STD_LEN(VLA_ARRAY_LEN_DIGEST (da.digest_size)) + 1]; | 1359 | char nonce[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (da.digest_size)) + 1]; |
1355 | 1360 | ||
1356 | VLA_CHECK_LEN_DIGEST(da.digest_size); | 1361 | VLA_CHECK_LEN_DIGEST (da.digest_size); |
1357 | /* Generating the server nonce */ | 1362 | /* Generating the server nonce */ |
1358 | calculate_nonce ((uint32_t) MHD_monotonic_sec_counter(), | 1363 | calculate_nonce ((uint32_t) MHD_monotonic_sec_counter (), |
1359 | connection->method, | 1364 | connection->method, |
1360 | connection->daemon->digest_auth_random, | 1365 | connection->daemon->digest_auth_random, |
1361 | connection->daemon->digest_auth_rand_size, | 1366 | connection->daemon->digest_auth_rand_size, |
@@ -1367,13 +1372,14 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1367 | check_nonce_nc (connection, | 1372 | check_nonce_nc (connection, |
1368 | nonce, | 1373 | nonce, |
1369 | 0)) | 1374 | 0)) |
1370 | { | 1375 | { |
1371 | #ifdef HAVE_MESSAGES | 1376 | #ifdef HAVE_MESSAGES |
1372 | MHD_DLOG (connection->daemon, | 1377 | MHD_DLOG (connection->daemon, |
1373 | _("Could not register nonce (is the nonce array size zero?).\n")); | 1378 | _ ( |
1379 | "Could not register nonce (is the nonce array size zero?).\n")); | ||
1374 | #endif | 1380 | #endif |
1375 | return MHD_NO; | 1381 | return MHD_NO; |
1376 | } | 1382 | } |
1377 | /* Building the authentication header */ | 1383 | /* Building the authentication header */ |
1378 | hlen = MHD_snprintf_ (NULL, | 1384 | hlen = MHD_snprintf_ (NULL, |
1379 | 0, | 1385 | 0, |
@@ -1386,54 +1392,54 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1386 | ? ",stale=\"true\"" | 1392 | ? ",stale=\"true\"" |
1387 | : ""); | 1393 | : ""); |
1388 | if (hlen > 0) | 1394 | if (hlen > 0) |
1389 | { | 1395 | { |
1390 | char *header; | 1396 | char *header; |
1391 | 1397 | ||
1392 | header = MHD_calloc_ (1, | 1398 | header = MHD_calloc_ (1, |
1393 | hlen + 1); | 1399 | hlen + 1); |
1394 | if (NULL == header) | 1400 | if (NULL == header) |
1395 | { | 1401 | { |
1396 | #ifdef HAVE_MESSAGES | 1402 | #ifdef HAVE_MESSAGES |
1397 | MHD_DLOG(connection->daemon, | 1403 | MHD_DLOG (connection->daemon, |
1398 | _("Failed to allocate memory for auth response header\n")); | 1404 | _ ("Failed to allocate memory for auth response header\n")); |
1399 | #endif /* HAVE_MESSAGES */ | 1405 | #endif /* HAVE_MESSAGES */ |
1400 | return MHD_NO; | 1406 | return MHD_NO; |
1401 | } | ||
1402 | |||
1403 | if (MHD_snprintf_ (header, | ||
1404 | hlen + 1, | ||
1405 | "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s", | ||
1406 | realm, | ||
1407 | nonce, | ||
1408 | opaque, | ||
1409 | da.alg, | ||
1410 | signal_stale | ||
1411 | ? ",stale=\"true\"" | ||
1412 | : "") == hlen) | ||
1413 | ret = MHD_add_response_header(response, | ||
1414 | MHD_HTTP_HEADER_WWW_AUTHENTICATE, | ||
1415 | header); | ||
1416 | else | ||
1417 | ret = MHD_NO; | ||
1418 | free (header); | ||
1419 | } | 1407 | } |
1408 | |||
1409 | if (MHD_snprintf_ (header, | ||
1410 | hlen + 1, | ||
1411 | "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s", | ||
1412 | realm, | ||
1413 | nonce, | ||
1414 | opaque, | ||
1415 | da.alg, | ||
1416 | signal_stale | ||
1417 | ? ",stale=\"true\"" | ||
1418 | : "") == hlen) | ||
1419 | ret = MHD_add_response_header (response, | ||
1420 | MHD_HTTP_HEADER_WWW_AUTHENTICATE, | ||
1421 | header); | ||
1422 | else | ||
1423 | ret = MHD_NO; | ||
1424 | free (header); | ||
1425 | } | ||
1420 | else | 1426 | else |
1421 | ret = MHD_NO; | 1427 | ret = MHD_NO; |
1422 | } | 1428 | } |
1423 | 1429 | ||
1424 | if (MHD_YES == ret) | 1430 | if (MHD_YES == ret) |
1425 | { | 1431 | { |
1426 | ret = MHD_queue_response (connection, | 1432 | ret = MHD_queue_response (connection, |
1427 | MHD_HTTP_UNAUTHORIZED, | 1433 | MHD_HTTP_UNAUTHORIZED, |
1428 | response); | 1434 | response); |
1429 | } | 1435 | } |
1430 | else | 1436 | else |
1431 | { | 1437 | { |
1432 | #ifdef HAVE_MESSAGES | 1438 | #ifdef HAVE_MESSAGES |
1433 | MHD_DLOG (connection->daemon, | 1439 | MHD_DLOG (connection->daemon, |
1434 | _("Failed to add Digest auth header\n")); | 1440 | _ ("Failed to add Digest auth header\n")); |
1435 | #endif /* HAVE_MESSAGES */ | 1441 | #endif /* HAVE_MESSAGES */ |
1436 | } | 1442 | } |
1437 | return ret; | 1443 | return ret; |
1438 | } | 1444 | } |
1439 | 1445 | ||
@@ -1450,16 +1456,16 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1450 | * body; note that this function will set the "WWW Authenticate" | 1456 | * body; note that this function will set the "WWW Authenticate" |
1451 | * header and that the caller should not do this | 1457 | * header and that the caller should not do this |
1452 | * @param signal_stale #MHD_YES if the nonce is invalid to add | 1458 | * @param signal_stale #MHD_YES if the nonce is invalid to add |
1453 | * 'stale=true' to the authentication header | 1459 | * 'stale=true' to the authentication header |
1454 | * @return #MHD_YES on success, #MHD_NO otherwise | 1460 | * @return #MHD_YES on success, #MHD_NO otherwise |
1455 | * @ingroup authentication | 1461 | * @ingroup authentication |
1456 | */ | 1462 | */ |
1457 | int | 1463 | int |
1458 | MHD_queue_auth_fail_response (struct MHD_Connection *connection, | 1464 | MHD_queue_auth_fail_response (struct MHD_Connection *connection, |
1459 | const char *realm, | 1465 | const char *realm, |
1460 | const char *opaque, | 1466 | const char *opaque, |
1461 | struct MHD_Response *response, | 1467 | struct MHD_Response *response, |
1462 | int signal_stale) | 1468 | int signal_stale) |
1463 | { | 1469 | { |
1464 | return MHD_queue_auth_fail_response2 (connection, | 1470 | return MHD_queue_auth_fail_response2 (connection, |
1465 | realm, | 1471 | realm, |