32 #define HASH_MD5_HEX_LEN (2 * MD5_DIGEST_SIZE)
37 #define _BASE "Digest "
42 #define _BASIC_BASE "Basic "
47 #define MAX_USERNAME_LENGTH 128
52 #define MAX_REALM_LENGTH 256
57 #define MAX_AUTH_RESPONSE_LENGTH 128
74 for (i = 0; i < len; ++i)
76 j = (bin[i] >> 4) & 0x0f;
77 hex[i * 2] = j <= 9 ? (j +
'0') : (j +
'a' - 10);
79 hex[i * 2 + 1] = j <= 9 ? (j +
'0') : (j +
'a' - 10);
100 const char *password,
109 MD5Update (&md5, username, strlen (username));
113 MD5Update (&md5, password, strlen (password));
115 if (0 == strcasecmp(alg,
"md5-sess"))
122 MD5Update (&md5, cnonce, strlen (cnonce));
125 cvthex(ha1,
sizeof (ha1), sessionkey);
145 const char *noncecount,
159 MD5Update (&md5, method, strlen(method));
163 if (strcasecmp(qop,
"auth-int") == 0)
169 MD5Update (&md5, hentity, strlen(hentity));
182 MD5Update (&md5, noncecount, strlen(noncecount));
184 MD5Update (&md5, cnonce, strlen(cnonce));
191 cvthex(resphash,
sizeof (resphash), response);
215 size_t keylen = strlen(key);
217 const char *ptr = data;
227 if (
NULL == (eq = strstr (ptr,
"=")))
234 q2 = strstr (q1,
",");
240 q2 = strstr (q1,
"\"");
245 if ( (0 == strncasecmp (ptr,
248 (eq == &ptr[keylen]) )
252 len = strlen (q1) + 1;
264 if (size > (q2 - q1) + 1)
265 size = (q2 - q1) + 1;
276 ptr = strstr (qn,
",");
305 mod = connection->
daemon->nonce_nc_size;
313 off = (off << 8) | (*np ^ (off >> 24));
323 pthread_mutex_lock(&connection->
daemon->nnc_lock);
326 strcpy(connection->
daemon->nnc[off].nonce,
328 connection->
daemon->nnc[off].nc = 0;
329 pthread_mutex_unlock(&connection->
daemon->nnc_lock);
332 if ( (nc <= connection->daemon->nnc[off].nc) ||
333 (0 != strcmp(connection->
daemon->nnc[off].nonce, nonce)) )
335 pthread_mutex_unlock(&connection->
daemon->nnc_lock);
337 MHD_DLOG (connection->
daemon,
338 "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n");
342 connection->
daemon->nnc[off].nc = nc;
343 pthread_mutex_unlock(&connection->
daemon->nnc_lock);
367 if (strncmp(header,
_BASE, strlen(
_BASE)) != 0)
369 header += strlen (
_BASE);
397 unsigned int rnd_size,
403 unsigned char timestamp[4];
405 char timestamphex[
sizeof(timestamp)*2+1];
408 timestamp[0] = (nonce_time & 0xff000000) >> 0x18;
409 timestamp[1] = (nonce_time & 0x00ff0000) >> 0x10;
410 timestamp[2] = (nonce_time & 0x0000ff00) >> 0x08;
411 timestamp[3] = (nonce_time & 0x000000ff);
423 cvthex(tmpnonce,
sizeof (tmpnonce), nonce);
424 cvthex(timestamp, 4, timestamphex);
425 strncat(nonce, timestamphex, 8);
444 const char *username,
445 const char *password,
446 unsigned int nonce_timeout)
455 const char *hentity =
NULL;
469 if (strncmp(header,
_BASE, strlen(
_BASE)) != 0)
471 header += strlen (
_BASE);
472 left = strlen (header);
480 (strcmp(username, un) != 0) )
482 left -= strlen (
"username") + len;
491 (strcmp(realm, r) != 0) )
493 left -= strlen (
"realm") + len;
500 left -= strlen (
"nonce") + len;
511 nonce_time = strtoul(nonce + len - 8, (
char **)
NULL, 16);
512 t = (uint32_t) time(
NULL);
519 if (t > nonce_time + nonce_timeout)
523 connection->
daemon->digest_auth_random,
524 connection->
daemon->digest_auth_rand_size,
538 if (0 != strcmp(nonce, noncehashexp))
542 header,
"cnonce")) ||
544 ( (0 != strcmp (qop,
"auth")) &&
545 (0 != strcmp (qop,
"")) ) ||
547 (1 != sscanf (nc,
"%u", &nci)) ||
605 connection->
daemon->digest_auth_random,
606 connection->
daemon->digest_auth_rand_size,
613 MHD_DLOG (connection->
daemon,
614 "Could not register nonce (is the nonce array size zero?).\n");
619 hlen = snprintf(
NULL,
621 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
625 signal_stale ?
",stale=\"true\"" :
"");
627 char header[hlen + 1];
630 "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
634 signal_stale ?
",stale=\"true\"" :
"");
661 const char *separator;
676 MHD_DLOG(connection->
daemon,
677 "Error decoding basic authentication\n");
682 separator = strstr(decode,
":");
683 if (separator ==
NULL)
686 MHD_DLOG(connection->
daemon,
687 "Basic authentication doesn't contain ':' separator\n");
692 user = strdup(decode);
698 user[separator - decode] =
'\0';
699 if (password !=
NULL)
701 *password = strdup(separator + 1);
702 if (
NULL == *password)
705 MHD_DLOG(connection->
daemon,
706 "Failed to allocate memory for password\n");
731 size_t hlen = strlen(realm) + strlen(
"Basic realm=\"\"") + 1;
736 "Basic realm=\"%s\"",