aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/digestauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r--src/microhttpd/digestauth.c178
1 files changed, 94 insertions, 84 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index 77f6e3b1..5cef1cfe 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -51,7 +51,7 @@
51 51
52 52
53/** 53/**
54 * convert bin to hex 54 * convert bin to hex
55 * 55 *
56 * @param bin binary data 56 * @param bin binary data
57 * @param len number of bytes in bin 57 * @param len number of bytes in bin
@@ -64,12 +64,12 @@ cvthex (const unsigned char *bin,
64{ 64{
65 size_t i; 65 size_t i;
66 unsigned int j; 66 unsigned int j;
67 67
68 for (i = 0; i < len; ++i) 68 for (i = 0; i < len; ++i)
69 { 69 {
70 j = (bin[i] >> 4) & 0x0f; 70 j = (bin[i] >> 4) & 0x0f;
71 hex[i * 2] = j <= 9 ? (j + '0') : (j + 'a' - 10); 71 hex[i * 2] = j <= 9 ? (j + '0') : (j + 'a' - 10);
72 j = bin[i] & 0x0f; 72 j = bin[i] & 0x0f;
73 hex[i * 2 + 1] = j <= 9 ? (j + '0') : (j + 'a' - 10); 73 hex[i * 2 + 1] = j <= 9 ? (j + '0') : (j + 'a' - 10);
74 } 74 }
75 hex[len * 2] = '\0'; 75 hex[len * 2] = '\0';
@@ -99,7 +99,7 @@ digest_calc_ha1 (const char *alg,
99{ 99{
100 struct MD5Context md5; 100 struct MD5Context md5;
101 unsigned char ha1[MD5_DIGEST_SIZE]; 101 unsigned char ha1[MD5_DIGEST_SIZE];
102 102
103 MD5Init (&md5); 103 MD5Init (&md5);
104 MD5Update (&md5, username, strlen (username)); 104 MD5Update (&md5, username, strlen (username));
105 MD5Update (&md5, ":", 1); 105 MD5Update (&md5, ":", 1);
@@ -107,7 +107,7 @@ digest_calc_ha1 (const char *alg,
107 MD5Update (&md5, ":", 1); 107 MD5Update (&md5, ":", 1);
108 MD5Update (&md5, password, strlen (password)); 108 MD5Update (&md5, password, strlen (password));
109 MD5Final (ha1, &md5); 109 MD5Final (ha1, &md5);
110 if (0 == strcasecmp (alg, "md5-sess")) 110 if (0 == strcasecmp (alg, "md5-sess"))
111 { 111 {
112 MD5Init (&md5); 112 MD5Init (&md5);
113 MD5Update (&md5, ha1, sizeof (ha1)); 113 MD5Update (&md5, ha1, sizeof (ha1));
@@ -122,8 +122,8 @@ digest_calc_ha1 (const char *alg,
122 122
123 123
124/** 124/**
125 * Calculate request-digest/response-digest as per RFC2617 spec 125 * Calculate request-digest/response-digest as per RFC2617 spec
126 * 126 *
127 * @param ha1 H(A1) 127 * @param ha1 H(A1)
128 * @param nonce nonce from server 128 * @param nonce nonce from server
129 * @param noncecount 8 hex digits 129 * @param noncecount 8 hex digits
@@ -149,11 +149,11 @@ digest_calc_response (const char *ha1,
149 unsigned char ha2[MD5_DIGEST_SIZE]; 149 unsigned char ha2[MD5_DIGEST_SIZE];
150 unsigned char resphash[MD5_DIGEST_SIZE]; 150 unsigned char resphash[MD5_DIGEST_SIZE];
151 char ha2hex[HASH_MD5_HEX_LEN + 1]; 151 char ha2hex[HASH_MD5_HEX_LEN + 1];
152 152
153 MD5Init (&md5); 153 MD5Init (&md5);
154 MD5Update (&md5, method, strlen(method)); 154 MD5Update (&md5, method, strlen(method));
155 MD5Update (&md5, ":", 1); 155 MD5Update (&md5, ":", 1);
156 MD5Update (&md5, uri, strlen(uri)); 156 MD5Update (&md5, uri, strlen(uri));
157#if 0 157#if 0
158 if (0 == strcasecmp(qop, "auth-int")) 158 if (0 == strcasecmp(qop, "auth-int"))
159 { 159 {
@@ -163,15 +163,15 @@ digest_calc_response (const char *ha1,
163 if (NULL != hentity) 163 if (NULL != hentity)
164 MD5Update (&md5, hentity, strlen(hentity)); 164 MD5Update (&md5, hentity, strlen(hentity));
165 } 165 }
166#endif 166#endif
167 MD5Final (ha2, &md5); 167 MD5Final (ha2, &md5);
168 cvthex (ha2, MD5_DIGEST_SIZE, ha2hex); 168 cvthex (ha2, MD5_DIGEST_SIZE, ha2hex);
169 MD5Init (&md5); 169 MD5Init (&md5);
170 /* calculate response */ 170 /* calculate response */
171 MD5Update (&md5, ha1, HASH_MD5_HEX_LEN); 171 MD5Update (&md5, ha1, HASH_MD5_HEX_LEN);
172 MD5Update (&md5, ":", 1); 172 MD5Update (&md5, ":", 1);
173 MD5Update (&md5, nonce, strlen(nonce)); 173 MD5Update (&md5, nonce, strlen(nonce));
174 MD5Update (&md5, ":", 1); 174 MD5Update (&md5, ":", 1);
175 if ('\0' != *qop) 175 if ('\0' != *qop)
176 { 176 {
177 MD5Update (&md5, noncecount, strlen(noncecount)); 177 MD5Update (&md5, noncecount, strlen(noncecount));
@@ -180,7 +180,7 @@ digest_calc_response (const char *ha1,
180 MD5Update (&md5, ":", 1); 180 MD5Update (&md5, ":", 1);
181 MD5Update (&md5, qop, strlen(qop)); 181 MD5Update (&md5, qop, strlen(qop));
182 MD5Update (&md5, ":", 1); 182 MD5Update (&md5, ":", 1);
183 } 183 }
184 MD5Update (&md5, ha2hex, HASH_MD5_HEX_LEN); 184 MD5Update (&md5, ha2hex, HASH_MD5_HEX_LEN);
185 MD5Final (resphash, &md5); 185 MD5Final (resphash, &md5);
186 cvthex (resphash, sizeof (resphash), response); 186 cvthex (resphash, sizeof (resphash), response);
@@ -225,7 +225,7 @@ lookup_sub_value (char *dest,
225 return 0; 225 return 0;
226 q1 = eq + 1; 226 q1 = eq + 1;
227 while (' ' == *q1) 227 while (' ' == *q1)
228 q1++; 228 q1++;
229 if ('\"' != *q1) 229 if ('\"' != *q1)
230 { 230 {
231 q2 = strchr (q1, ','); 231 q2 = strchr (q1, ',');
@@ -238,7 +238,7 @@ lookup_sub_value (char *dest,
238 if (NULL == q2) 238 if (NULL == q2)
239 return 0; /* end quote not found */ 239 return 0; /* end quote not found */
240 qn = q2 + 1; 240 qn = q2 + 1;
241 } 241 }
242 if ( (0 == strncasecmp (ptr, 242 if ( (0 == strncasecmp (ptr,
243 key, 243 key,
244 keylen)) && 244 keylen)) &&
@@ -261,7 +261,7 @@ lookup_sub_value (char *dest,
261 if (size > (q2 - q1) + 1) 261 if (size > (q2 - q1) + 1)
262 size = (q2 - q1) + 1; 262 size = (q2 - q1) + 1;
263 size--; 263 size--;
264 memcpy (dest, 264 memcpy (dest,
265 q1, 265 q1,
266 size); 266 size);
267 dest[size] = '\0'; 267 dest[size] = '\0';
@@ -316,13 +316,13 @@ check_nonce_nc (struct MHD_Connection *connection,
316 * nonce counter is less than the current nonce counter by 1, 316 * nonce counter is less than the current nonce counter by 1,
317 * then only increase the nonce counter by one. 317 * then only increase the nonce counter by one.
318 */ 318 */
319 319
320 (void) pthread_mutex_lock (&connection->daemon->nnc_lock); 320 (void) pthread_mutex_lock (&connection->daemon->nnc_lock);
321 if (0 == nc) 321 if (0 == nc)
322 { 322 {
323 strcpy(connection->daemon->nnc[off].nonce, 323 strcpy(connection->daemon->nnc[off].nonce,
324 nonce); 324 nonce);
325 connection->daemon->nnc[off].nc = 0; 325 connection->daemon->nnc[off].nc = 0;
326 (void) pthread_mutex_unlock (&connection->daemon->nnc_lock); 326 (void) pthread_mutex_unlock (&connection->daemon->nnc_lock);
327 return MHD_YES; 327 return MHD_YES;
328 } 328 }
@@ -331,7 +331,7 @@ check_nonce_nc (struct MHD_Connection *connection,
331 { 331 {
332 (void) pthread_mutex_unlock (&connection->daemon->nnc_lock); 332 (void) pthread_mutex_unlock (&connection->daemon->nnc_lock);
333#if HAVE_MESSAGES 333#if HAVE_MESSAGES
334 MHD_DLOG (connection->daemon, 334 MHD_DLOG (connection->daemon,
335 "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"); 335 "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n");
336#endif 336#endif
337 return MHD_NO; 337 return MHD_NO;
@@ -356,9 +356,9 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection)
356 size_t len; 356 size_t len;
357 char user[MAX_USERNAME_LENGTH]; 357 char user[MAX_USERNAME_LENGTH];
358 const char *header; 358 const char *header;
359 359
360 if (NULL == (header = MHD_lookup_connection_value (connection, 360 if (NULL == (header = MHD_lookup_connection_value (connection,
361 MHD_HEADER_KIND, 361 MHD_HEADER_KIND,
362 MHD_HTTP_HEADER_AUTHORIZATION))) 362 MHD_HTTP_HEADER_AUTHORIZATION)))
363 return NULL; 363 return NULL;
364 if (0 != strncmp (header, _BASE, strlen (_BASE))) 364 if (0 != strncmp (header, _BASE, strlen (_BASE)))
@@ -366,7 +366,7 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection)
366 header += strlen (_BASE); 366 header += strlen (_BASE);
367 if (0 == (len = lookup_sub_value (user, 367 if (0 == (len = lookup_sub_value (user,
368 sizeof (user), 368 sizeof (user),
369 header, 369 header,
370 "username"))) 370 "username")))
371 return NULL; 371 return NULL;
372 return strdup (user); 372 return strdup (user);
@@ -404,7 +404,7 @@ calculate_nonce (uint32_t nonce_time,
404 timestamp[0] = (nonce_time & 0xff000000) >> 0x18; 404 timestamp[0] = (nonce_time & 0xff000000) >> 0x18;
405 timestamp[1] = (nonce_time & 0x00ff0000) >> 0x10; 405 timestamp[1] = (nonce_time & 0x00ff0000) >> 0x10;
406 timestamp[2] = (nonce_time & 0x0000ff00) >> 0x08; 406 timestamp[2] = (nonce_time & 0x0000ff00) >> 0x08;
407 timestamp[3] = (nonce_time & 0x000000ff); 407 timestamp[3] = (nonce_time & 0x000000ff);
408 MD5Update (&md5, timestamp, 4); 408 MD5Update (&md5, timestamp, 4);
409 MD5Update (&md5, ":", 1); 409 MD5Update (&md5, ":", 1);
410 MD5Update (&md5, method, strlen(method)); 410 MD5Update (&md5, method, strlen(method));
@@ -415,8 +415,8 @@ calculate_nonce (uint32_t nonce_time,
415 MD5Update (&md5, uri, strlen(uri)); 415 MD5Update (&md5, uri, strlen(uri));
416 MD5Update (&md5, ":", 1); 416 MD5Update (&md5, ":", 1);
417 MD5Update (&md5, realm, strlen(realm)); 417 MD5Update (&md5, realm, strlen(realm));
418 MD5Final (tmpnonce, &md5); 418 MD5Final (tmpnonce, &md5);
419 cvthex (tmpnonce, sizeof (tmpnonce), nonce); 419 cvthex (tmpnonce, sizeof (tmpnonce), nonce);
420 cvthex (timestamp, 4, timestamphex); 420 cvthex (timestamp, 4, timestamphex);
421 strncat (nonce, timestamphex, 8); 421 strncat (nonce, timestamphex, 8);
422} 422}
@@ -429,7 +429,7 @@ calculate_nonce (uint32_t nonce_time,
429 * @param connection the connection 429 * @param connection the connection
430 * @param key the key 430 * @param key the key
431 * @param value the value, can be NULL 431 * @param value the value, can be NULL
432 * @return MHD_YES if the key-value pair is in the headers, 432 * @return MHD_YES if the key-value pair is in the headers,
433 * MHD_NO if not 433 * MHD_NO if not
434 */ 434 */
435static int 435static int
@@ -445,14 +445,14 @@ test_header (struct MHD_Connection *connection,
445 continue; 445 continue;
446 if (0 != strcmp (key, pos->header)) 446 if (0 != strcmp (key, pos->header))
447 continue; 447 continue;
448 if ( (NULL == value) && 448 if ( (NULL == value) &&
449 (NULL == pos->value) ) 449 (NULL == pos->value) )
450 return MHD_YES; 450 return MHD_YES;
451 if ( (NULL == value) || 451 if ( (NULL == value) ||
452 (NULL == pos->value) || 452 (NULL == pos->value) ||
453 (0 != strcmp (value, pos->value)) ) 453 (0 != strcmp (value, pos->value)) )
454 continue; 454 continue;
455 return MHD_YES; 455 return MHD_YES;
456 } 456 }
457 return MHD_NO; 457 return MHD_NO;
458} 458}
@@ -487,8 +487,8 @@ check_argument_match (struct MHD_Connection *connection,
487 ('\0' != argp[0]) ) 487 ('\0' != argp[0]) )
488 { 488 {
489 equals = strchr (argp, '='); 489 equals = strchr (argp, '=');
490 if (NULL == equals) 490 if (NULL == equals)
491 { 491 {
492 /* add with 'value' NULL */ 492 /* add with 'value' NULL */
493 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, 493 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
494 connection, 494 connection,
@@ -517,7 +517,7 @@ check_argument_match (struct MHD_Connection *connection,
517 num_headers++; 517 num_headers++;
518 argp = amper; 518 argp = amper;
519 } 519 }
520 520
521 /* also check that the number of headers matches */ 521 /* also check that the number of headers matches */
522 for (pos = connection->headers_received; NULL != pos; pos = pos->next) 522 for (pos = connection->headers_received; NULL != pos; pos = pos->next)
523 { 523 {
@@ -525,7 +525,7 @@ check_argument_match (struct MHD_Connection *connection,
525 continue; 525 continue;
526 num_headers--; 526 num_headers--;
527 } 527 }
528 if (0 != num_headers) 528 if (0 != num_headers)
529 return MHD_NO; 529 return MHD_NO;
530 return MHD_YES; 530 return MHD_YES;
531} 531}
@@ -570,10 +570,10 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
570 570
571 header = MHD_lookup_connection_value (connection, 571 header = MHD_lookup_connection_value (connection,
572 MHD_HEADER_KIND, 572 MHD_HEADER_KIND,
573 MHD_HTTP_HEADER_AUTHORIZATION); 573 MHD_HTTP_HEADER_AUTHORIZATION);
574 if (NULL == header) 574 if (NULL == header)
575 return MHD_NO; 575 return MHD_NO;
576 if (0 != strncmp(header, _BASE, strlen(_BASE))) 576 if (0 != strncmp(header, _BASE, strlen(_BASE)))
577 return MHD_NO; 577 return MHD_NO;
578 header += strlen (_BASE); 578 header += strlen (_BASE);
579 left = strlen (header); 579 left = strlen (header);
@@ -585,7 +585,7 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
585 sizeof (un), 585 sizeof (un),
586 header, "username"); 586 header, "username");
587 if ( (0 == len) || 587 if ( (0 == len) ||
588 (0 != strcmp(username, un)) ) 588 (0 != strcmp(username, un)) )
589 return MHD_NO; 589 return MHD_NO;
590 left -= strlen ("username") + len; 590 left -= strlen ("username") + len;
591 } 591 }
@@ -593,32 +593,42 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
593 { 593 {
594 char r[MAX_REALM_LENGTH]; 594 char r[MAX_REALM_LENGTH];
595 595
596 len = lookup_sub_value(r, 596 len = lookup_sub_value(r,
597 sizeof (r), 597 sizeof (r),
598 header, "realm"); 598 header, "realm");
599 if ( (0 == len) || 599 if ( (0 == len) ||
600 (0 != strcmp(realm, r)) ) 600 (0 != strcmp(realm, r)) )
601 return MHD_NO; 601 return MHD_NO;
602 left -= strlen ("realm") + len; 602 left -= strlen ("realm") + len;
603 } 603 }
604 604
605 if (0 == (len = lookup_sub_value (nonce, 605 if (0 == (len = lookup_sub_value (nonce,
606 sizeof (nonce), 606 sizeof (nonce),
607 header, "nonce"))) 607 header, "nonce")))
608 return MHD_NO; 608 return MHD_NO;
609 left -= strlen ("nonce") + len; 609 left -= strlen ("nonce") + len;
610 610 if (left > 32 * 1024)
611 { 611 {
612 char uri[left]; 612 /* we do not permit URIs longer than 32k, as we want to
613 613 make sure to not blow our stack (or per-connection
614 if (0 == lookup_sub_value(uri, 614 heap memory limit). Besides, 32k is already insanely
615 sizeof (uri), 615 large, but of course in theory the
616 header, "uri")) 616 #MHD_OPTION_CONNECTION_MEMORY_LIMIT might be very large
617 and would thus permit sending a >32k authorization
618 header value. */
619 return MHD_NO;
620 }
621 {
622 char uri[left];
623
624 if (0 == lookup_sub_value (uri,
625 sizeof (uri),
626 header, "uri"))
617 return MHD_NO; 627 return MHD_NO;
618 628
619 /* 8 = 4 hexadecimal numbers for the timestamp */ 629 /* 8 = 4 hexadecimal numbers for the timestamp */
620 nonce_time = strtoul(nonce + len - 8, (char **)NULL, 16); 630 nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
621 t = (uint32_t) MHD_monotonic_time(); 631 t = (uint32_t) MHD_monotonic_time();
622 /* 632 /*
623 * First level vetting for the nonce validity if the timestamp 633 * First level vetting for the nonce validity if the timestamp
624 * attached to the nonce exceeds `nonce_timeout' then the nonce is 634 * attached to the nonce exceeds `nonce_timeout' then the nonce is
@@ -632,7 +642,7 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
632 strlen (connection->url))) 642 strlen (connection->url)))
633 { 643 {
634#if HAVE_MESSAGES 644#if HAVE_MESSAGES
635 MHD_DLOG (connection->daemon, 645 MHD_DLOG (connection->daemon,
636 "Authentication failed, URI does not match.\n"); 646 "Authentication failed, URI does not match.\n");
637#endif 647#endif
638 return MHD_NO; 648 return MHD_NO;
@@ -646,10 +656,10 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
646 args++; 656 args++;
647 if (MHD_YES != 657 if (MHD_YES !=
648 check_argument_match (connection, 658 check_argument_match (connection,
649 args) ) 659 args) )
650 { 660 {
651#if HAVE_MESSAGES 661#if HAVE_MESSAGES
652 MHD_DLOG (connection->daemon, 662 MHD_DLOG (connection->daemon,
653 "Authentication failed, arguments do not match.\n"); 663 "Authentication failed, arguments do not match.\n");
654#endif 664#endif
655 return MHD_NO; 665 return MHD_NO;
@@ -671,31 +681,31 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
671 * not, the nonce fabrication process going to be 681 * not, the nonce fabrication process going to be
672 * very hard to achieve. 682 * very hard to achieve.
673 */ 683 */
674 684
675 if (0 != strcmp (nonce, noncehashexp)) 685 if (0 != strcmp (nonce, noncehashexp))
676 return MHD_INVALID_NONCE; 686 return MHD_INVALID_NONCE;
677 if ( (0 == lookup_sub_value (cnonce, 687 if ( (0 == lookup_sub_value (cnonce,
678 sizeof (cnonce), 688 sizeof (cnonce),
679 header, "cnonce")) || 689 header, "cnonce")) ||
680 (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) || 690 (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) ||
681 ( (0 != strcmp (qop, "auth")) && 691 ( (0 != strcmp (qop, "auth")) &&
682 (0 != strcmp (qop, "")) ) || 692 (0 != strcmp (qop, "")) ) ||
683 (0 == lookup_sub_value (nc, sizeof (nc), header, "nc")) || 693 (0 == lookup_sub_value (nc, sizeof (nc), header, "nc")) ||
684 (0 == lookup_sub_value (response, sizeof (response), header, "response")) ) 694 (0 == lookup_sub_value (response, sizeof (response), header, "response")) )
685 { 695 {
686#if HAVE_MESSAGES 696#if HAVE_MESSAGES
687 MHD_DLOG (connection->daemon, 697 MHD_DLOG (connection->daemon,
688 "Authentication failed, invalid format.\n"); 698 "Authentication failed, invalid format.\n");
689#endif 699#endif
690 return MHD_NO; 700 return MHD_NO;
691 } 701 }
692 nci = strtoul (nc, &end, 16); 702 nci = strtoul (nc, &end, 16);
693 if ( ('\0' != *end) || 703 if ( ('\0' != *end) ||
694 ( (LONG_MAX == nci) && 704 ( (LONG_MAX == nci) &&
695 (ERANGE == errno) ) ) 705 (ERANGE == errno) ) )
696 { 706 {
697#if HAVE_MESSAGES 707#if HAVE_MESSAGES
698 MHD_DLOG (connection->daemon, 708 MHD_DLOG (connection->daemon,
699 "Authentication failed, invalid format.\n"); 709 "Authentication failed, invalid format.\n");
700#endif 710#endif
701 return MHD_NO; /* invalid nonce format */ 711 return MHD_NO; /* invalid nonce format */
@@ -705,10 +715,10 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
705 * and not a replay attack attempt. Also adds the nonce 715 * and not a replay attack attempt. Also adds the nonce
706 * to the nonce-nc map if it does not exist there. 716 * to the nonce-nc map if it does not exist there.
707 */ 717 */
708 718
709 if (MHD_YES != check_nonce_nc (connection, nonce, nci)) 719 if (MHD_YES != check_nonce_nc (connection, nonce, nci))
710 return MHD_NO; 720 return MHD_NO;
711 721
712 digest_calc_ha1("md5", 722 digest_calc_ha1("md5",
713 username, 723 username,
714 realm, 724 realm,
@@ -724,9 +734,9 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
724 connection->method, 734 connection->method,
725 uri, 735 uri,
726 hentity, 736 hentity,
727 respexp); 737 respexp);
728 return (0 == strcmp(response, respexp)) 738 return (0 == strcmp(response, respexp))
729 ? MHD_YES 739 ? MHD_YES
730 : MHD_NO; 740 : MHD_NO;
731 } 741 }
732} 742}
@@ -757,7 +767,7 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
757 size_t hlen; 767 size_t hlen;
758 char nonce[HASH_MD5_HEX_LEN + 9]; 768 char nonce[HASH_MD5_HEX_LEN + 9];
759 769
760 /* Generating the server nonce */ 770 /* Generating the server nonce */
761 calculate_nonce ((uint32_t) MHD_monotonic_time(), 771 calculate_nonce ((uint32_t) MHD_monotonic_time(),
762 connection->method, 772 connection->method,
763 connection->daemon->digest_auth_random, 773 connection->daemon->digest_auth_random,
@@ -768,20 +778,20 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
768 if (MHD_YES != check_nonce_nc (connection, nonce, 0)) 778 if (MHD_YES != check_nonce_nc (connection, nonce, 0))
769 { 779 {
770#if HAVE_MESSAGES 780#if HAVE_MESSAGES
771 MHD_DLOG (connection->daemon, 781 MHD_DLOG (connection->daemon,
772 "Could not register nonce (is the nonce array size zero?).\n"); 782 "Could not register nonce (is the nonce array size zero?).\n");
773#endif 783#endif
774 return MHD_NO; 784 return MHD_NO;
775 } 785 }
776 /* Building the authentication header */ 786 /* Building the authentication header */
777 hlen = snprintf (NULL, 787 hlen = snprintf (NULL,
778 0, 788 0,
779 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", 789 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
780 realm, 790 realm,
781 nonce, 791 nonce,
782 opaque, 792 opaque,
783 signal_stale 793 signal_stale
784 ? ",stale=\"true\"" 794 ? ",stale=\"true\""
785 : ""); 795 : "");
786 { 796 {
787 char header[hlen + 1]; 797 char header[hlen + 1];
@@ -789,20 +799,20 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
789 snprintf (header, 799 snprintf (header,
790 sizeof(header), 800 sizeof(header),
791 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", 801 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
792 realm, 802 realm,
793 nonce, 803 nonce,
794 opaque, 804 opaque,
795 signal_stale 805 signal_stale
796 ? ",stale=\"true\"" 806 ? ",stale=\"true\""
797 : ""); 807 : "");
798 ret = MHD_add_response_header(response, 808 ret = MHD_add_response_header(response,
799 MHD_HTTP_HEADER_WWW_AUTHENTICATE, 809 MHD_HTTP_HEADER_WWW_AUTHENTICATE,
800 header); 810 header);
801 } 811 }
802 if (MHD_YES == ret) 812 if (MHD_YES == ret)
803 ret = MHD_queue_response(connection, 813 ret = MHD_queue_response(connection,
804 MHD_HTTP_UNAUTHORIZED, 814 MHD_HTTP_UNAUTHORIZED,
805 response); 815 response);
806 return ret; 816 return ret;
807} 817}
808 818