30 #define HASH_MD5_HEX_LEN (2 * MD5_DIGEST_SIZE)
35 #define _BASE "Digest "
40 #define MAX_USERNAME_LENGTH 128
45 #define MAX_REALM_LENGTH 256
50 #define MAX_AUTH_RESPONSE_LENGTH 128
68 for (i = 0; i < len; ++i)
70 j = (bin[i] >> 4) & 0x0f;
71 hex[i * 2] = j <= 9 ? (j +
'0') : (j +
'a' - 10);
73 hex[i * 2 + 1] = j <= 9 ? (j +
'0') : (j +
'a' - 10);
104 MD5Update (&md5, username, strlen (username));
108 MD5Update (&md5, password, strlen (password));
110 if (0 == strcasecmp (alg,
"md5-sess"))
117 MD5Update (&md5, cnonce, strlen (cnonce));
120 cvthex (ha1,
sizeof (ha1), sessionkey);
140 const char *noncecount,
154 MD5Update (&md5, method, strlen(method));
158 if (0 == strcasecmp(qop,
"auth-int"))
164 MD5Update (&md5, hentity, strlen(hentity));
177 MD5Update (&md5, noncecount, strlen(noncecount));
179 MD5Update (&md5, cnonce, strlen(cnonce));
186 cvthex (resphash,
sizeof (resphash), response);
220 keylen = strlen (key);
224 if (
NULL == (eq = strchr (ptr,
'=')))
231 q2 = strchr (q1,
',');
237 q2 = strchr (q1,
'\"');
242 if ( (0 == strncasecmp (ptr,
245 (eq == &ptr[keylen]) )
249 len = strlen (q1) + 1;
261 if (size > (q2 - q1) + 1)
262 size = (q2 - q1) + 1;
273 ptr = strchr (qn,
',');
296 unsigned long int nc)
302 mod = connection->
daemon->nonce_nc_size;
310 off = (off << 8) | (*np ^ (off >> 24));
320 pthread_mutex_lock (&connection->
daemon->nnc_lock);
323 strcpy(connection->
daemon->nnc[off].nonce,
325 connection->
daemon->nnc[off].nc = 0;
326 pthread_mutex_unlock (&connection->
daemon->nnc_lock);
329 if ( (nc <= connection->daemon->nnc[off].nc) ||
330 (0 != strcmp(connection->
daemon->nnc[off].nonce, nonce)) )
332 pthread_mutex_unlock (&connection->
daemon->nnc_lock);
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");
339 connection->
daemon->nnc[off].nc = nc;
340 pthread_mutex_unlock (&connection->
daemon->nnc_lock);
363 if (0 != strncmp (header,
_BASE, strlen (
_BASE)))
365 header += strlen (
_BASE);
371 return strdup (user);
392 unsigned int rnd_size,
398 unsigned char timestamp[4];
400 char timestamphex[
sizeof(timestamp) * 2 + 1];
403 timestamp[0] = (nonce_time & 0xff000000) >> 0x18;
404 timestamp[1] = (nonce_time & 0x00ff0000) >> 0x10;
405 timestamp[2] = (nonce_time & 0x0000ff00) >> 0x08;
406 timestamp[3] = (nonce_time & 0x000000ff);
409 MD5Update (&md5, method, strlen(method));
418 cvthex (tmpnonce,
sizeof (tmpnonce), nonce);
419 cvthex (timestamp, 4, timestamphex);
420 strncat (nonce, timestamphex, 8);
445 if (0 != strcmp (key, pos->
header))
447 if ( (
NULL == value) &&
450 if ( (
NULL == value) ||
452 (0 != strcmp (value, pos->
value)) )
475 size_t slen = strlen (args) + 1;
480 unsigned int num_headers;
483 memcpy (argb, args, slen);
485 while ( (
NULL != argp) &&
488 equals = strchr (argp,
'=');
502 amper = strchr (equals,
'&');
527 if (0 != num_headers)
548 const char *username,
549 const char *password,
550 unsigned int nonce_timeout)
560 const char *hentity =
NULL;
567 unsigned long int nci;
574 if (0 != strncmp(header,
_BASE, strlen(
_BASE)))
576 header += strlen (
_BASE);
577 left = strlen (header);
586 (0 != strcmp(username, un)) )
588 left -= strlen (
"username") + len;
598 (0 != strcmp(realm, r)) )
600 left -= strlen (
"realm") + len;
607 left -= strlen (
"nonce") + len;
618 nonce_time = strtoul(nonce + len - 8, (
char **)
NULL, 16);
625 if ( (t > nonce_time + nonce_timeout) ||
626 (nonce_time + nonce_timeout < nonce_time) )
628 if (0 != strncmp (uri,
630 strlen (connection->
url)))
633 MHD_DLOG (connection->
daemon,
634 "Authentication failed, URI does not match.\n");
639 const char *args = strchr (uri,
'?');
650 MHD_DLOG (connection->
daemon,
651 "Authentication failed, arguments do not match.\n");
658 connection->
daemon->digest_auth_random,
659 connection->
daemon->digest_auth_rand_size,
673 if (0 != strcmp (nonce, noncehashexp))
677 header,
"cnonce")) ||
679 ( (0 != strcmp (qop,
"auth")) &&
680 (0 != strcmp (qop,
"")) ) ||
685 MHD_DLOG (connection->
daemon,
686 "Authentication failed, invalid format.\n");
690 nci = strtoul (nc, &end, 16);
691 if ( (
'\0' != *end) ||
692 ( (LONG_MAX == nci) &&
693 (ERANGE == errno) ) )
696 MHD_DLOG (connection->
daemon,
697 "Authentication failed, invalid format.\n");
726 return (0 == strcmp(response, respexp))
757 connection->
daemon->digest_auth_random,
758 connection->
daemon->digest_auth_rand_size,
765 MHD_DLOG (connection->
daemon,
766 "Could not register nonce (is the nonce array size zero?).\n");
771 hlen = snprintf (
NULL,
773 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
785 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",