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.c570
1 files changed, 283 insertions, 287 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index ca66bff0..e6f68222 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -1522,324 +1522,320 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
1522 1522
1523 tmp2_size = 0; 1523 tmp2_size = 0;
1524 1524
1525 do /* Only to avoid "goto" */ 1525 params = get_rq_dauth_params (connection);
1526 { 1526 if (NULL == params)
1527 1527 return MHD_DAUTH_WRONG_HEADER;
1528 params = get_rq_dauth_params (connection);
1529 if (NULL == params)
1530 return MHD_DAUTH_WRONG_HEADER;
1531
1532 /* Check 'username' */
1533 if (NULL == params->username.value.str)
1534 return MHD_DAUTH_WRONG_HEADER;
1535
1536 username_len = strlen (username);
1537 if (! is_param_equal (&params->username, username, username_len))
1538 return MHD_DAUTH_WRONG_USERNAME;
1539 /* 'username' valid */
1540
1541 /* Check 'realm' */
1542 if (NULL == params->realm.value.str)
1543 return MHD_DAUTH_WRONG_HEADER;
1544 realm_len = strlen (realm);
1545 if (! is_param_equal (&params->realm, realm, realm_len))
1546 return MHD_DAUTH_WRONG_REALM;
1547 /* 'realm' valid */
1548
1549 /* Check 'nonce' */
1550 if (NULL == params->nonce.value.str)
1551 return MHD_DAUTH_WRONG_HEADER;
1552 else if (0 == params->nonce.value.len)
1553 return MHD_DAUTH_NONCE_WRONG;
1554 else if (NONCE_STD_LEN (digest_size) * 2 < params->nonce.value.len)
1555 return MHD_DAUTH_NONCE_WRONG;
1556 1528
1557 unq_res = get_unquoted_param (&params->nonce, tmp1, ptmp2, &tmp2_size, 1529 /* Check 'username' */
1558 &unquoted); 1530 if (NULL == params->username.value.str)
1559 if (_MHD_UNQ_OK != unq_res) 1531 return MHD_DAUTH_WRONG_HEADER;
1560 return MHD_DAUTH_ERROR; 1532
1561 if (NONCE_STD_LEN (digest_size) != unquoted.len) 1533 username_len = strlen (username);
1562 return MHD_DAUTH_NONCE_WRONG; 1534 if (! is_param_equal (&params->username, username, username_len))
1535 return MHD_DAUTH_WRONG_USERNAME;
1536 /* 'username' valid */
1537
1538 /* Check 'realm' */
1539 if (NULL == params->realm.value.str)
1540 return MHD_DAUTH_WRONG_HEADER;
1541 realm_len = strlen (realm);
1542 if (! is_param_equal (&params->realm, realm, realm_len))
1543 return MHD_DAUTH_WRONG_REALM;
1544 /* 'realm' valid */
1545
1546 /* Check 'nonce' */
1547 if (NULL == params->nonce.value.str)
1548 return MHD_DAUTH_WRONG_HEADER;
1549 else if (0 == params->nonce.value.len)
1550 return MHD_DAUTH_NONCE_WRONG;
1551 else if (NONCE_STD_LEN (digest_size) * 2 < params->nonce.value.len)
1552 return MHD_DAUTH_NONCE_WRONG;
1553
1554 unq_res = get_unquoted_param (&params->nonce, tmp1, ptmp2, &tmp2_size,
1555 &unquoted);
1556 if (_MHD_UNQ_OK != unq_res)
1557 return MHD_DAUTH_ERROR;
1558 if (NONCE_STD_LEN (digest_size) != unquoted.len)
1559 return MHD_DAUTH_NONCE_WRONG;
1560
1561 if (! get_nonce_timestamp (unquoted.str, unquoted.len, &nonce_time))
1562 {
1563#ifdef HAVE_MESSAGES
1564 MHD_DLOG (daemon,
1565 _ ("Authentication failed, invalid timestamp format.\n"));
1566#endif
1567 return MHD_DAUTH_NONCE_WRONG;
1568 }
1569 t = MHD_monotonic_msec_counter ();
1570 /*
1571 * First level vetting for the nonce validity: if the timestamp
1572 * attached to the nonce exceeds `nonce_timeout', then the nonce is
1573 * invalid.
1574 */
1575 if (TRIM_TO_TIMESTAMP (t - nonce_time) > (nonce_timeout * 1000))
1576 return MHD_DAUTH_NONCE_STALE; /* too old */
1563 1577
1564 if (! get_nonce_timestamp (unquoted.str, unquoted.len, &nonce_time)) 1578 calculate_nonce (nonce_time,
1565 { 1579 connection->method,
1580 daemon->digest_auth_random,
1581 daemon->digest_auth_rand_size,
1582 connection->url,
1583 realm,
1584 realm_len,
1585 da,
1586 noncehashexp);
1587 /*
1588 * Second level vetting for the nonce validity
1589 * if the timestamp attached to the nonce is valid
1590 * and possibly fabricated (in case of an attack)
1591 * the attacker must also know the random seed to be
1592 * able to generate a "sane" nonce, which if he does
1593 * not, the nonce fabrication process going to be
1594 * very hard to achieve.
1595 */
1596 if ((0 != strncmp (noncehashexp, unquoted.str, unquoted.len)) ||
1597 (0 != noncehashexp[unquoted.len]))
1598 return MHD_DAUTH_NONCE_WRONG;
1599 /* 'nonce' valid */
1600
1601 /* Get 'cnonce' */
1602 if (NULL == params->cnonce.value.str)
1603 return MHD_DAUTH_WRONG_HEADER;
1604 else if (0 == params->cnonce.value.len)
1605 return MHD_DAUTH_WRONG_HEADER;
1606 unq_res = get_unquoted_param (&params->cnonce, tmp1, ptmp2, &tmp2_size,
1607 &unquoted);
1608 if (_MHD_UNQ_OK != unq_res)
1609 return (_MHD_UNQ_TOO_LARGE == unq_res) ?
1610 MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
1611
1612 if (sizeof(cnonce) <= unquoted.len)
1613 return MHD_DAUTH_ERROR; /* TODO: handle large client nonces */
1614
1615 /* TODO: avoid memcpy() */
1616 memcpy (cnonce, unquoted.str, unquoted.len);
1617 cnonce[unquoted.len] = 0;
1618 /* Got 'cnonce' */
1619
1620 /* Get 'qop' */
1621 if (NULL == params->qop.value.str)
1622 return MHD_DAUTH_WRONG_HEADER;
1623 else if (0 == params->qop.value.len)
1624 return MHD_DAUTH_WRONG_QOP;
1625 else if (MHD_STATICSTR_LEN_ ("auth-int") * 2 < params->qop.value.len)
1626 return MHD_DAUTH_WRONG_QOP;
1627 unq_res = get_unquoted_param (&params->qop, tmp1, ptmp2, &tmp2_size,
1628 &unquoted);
1629 if (_MHD_UNQ_OK != unq_res)
1630 return MHD_DAUTH_ERROR;
1631
1632 if (sizeof(qop) <= unquoted.len)
1633 return MHD_DAUTH_ERROR; /* TODO: handle large client qop */
1634 /* TODO: avoid memcpy() */
1635 memcpy (qop, unquoted.str, unquoted.len);
1636 qop[unquoted.len] = 0;
1637 /* TODO: Really support empty value, support "auth-int" */
1638 if ( ((MHD_STATICSTR_LEN_ ("auth") != unquoted.len) ||
1639 (! MHD_str_equal_caseless_bin_n_ (qop, "auth", unquoted.len))) &&
1640 (0 != strcmp (qop,"")) )
1641 return MHD_DAUTH_WRONG_QOP;
1642 /* Got 'qop' */
1643
1644 /* Get 'nc' */
1645 if (NULL == params->nc.value.str)
1646 return MHD_DAUTH_WRONG_HEADER;
1647 else if (0 == params->nc.value.len)
1648 return MHD_DAUTH_WRONG_HEADER;
1649 else if (4 * 8 < params->nc.value.len) /* Four time more than needed */
1650 return MHD_DAUTH_NONCE_WRONG;
1651 unq_res = get_unquoted_param (&params->nc, tmp1, ptmp2, &tmp2_size,
1652 &unquoted);
1653 if (_MHD_UNQ_OK != unq_res)
1654 return MHD_DAUTH_ERROR;
1655
1656 if (sizeof(nc) <= unquoted.len)
1657 return MHD_DAUTH_ERROR;
1658 /* TODO: avoid memcpy() */
1659 memcpy (nc, unquoted.str, unquoted.len);
1660 nc[unquoted.len] = 0;
1661 if (unquoted.len != MHD_strx_to_uint64_n_ (nc,
1662 unquoted.len,
1663 &nci))
1664 {
1566#ifdef HAVE_MESSAGES 1665#ifdef HAVE_MESSAGES
1567 MHD_DLOG (daemon, 1666 MHD_DLOG (daemon,
1568 _ ("Authentication failed, invalid timestamp format.\n")); 1667 _ ("Authentication failed, invalid nc format.\n"));
1569#endif 1668#endif
1570 return MHD_DAUTH_NONCE_WRONG; 1669 return MHD_DAUTH_WRONG_HEADER; /* invalid nonce format */
1571 } 1670 }
1572 t = MHD_monotonic_msec_counter (); 1671 if (0 == nci)
1573 /* 1672 {
1574 * First level vetting for the nonce validity: if the timestamp 1673#ifdef HAVE_MESSAGES
1575 * attached to the nonce exceeds `nonce_timeout', then the nonce is 1674 MHD_DLOG (daemon,
1576 * invalid. 1675 _ ("Authentication failed, invalid 'nc' value.\n"));
1577 */ 1676#endif
1578 if (TRIM_TO_TIMESTAMP (t - nonce_time) > (nonce_timeout * 1000)) 1677 return MHD_DAUTH_WRONG_HEADER; /* invalid nc value */
1579 return MHD_DAUTH_NONCE_STALE; /* too old */ 1678 }
1580 1679 /* Got 'nc' */
1581 calculate_nonce (nonce_time, 1680
1582 connection->method, 1681 /* Get 'response' */
1583 daemon->digest_auth_random, 1682 if (NULL == params->response.value.str)
1584 daemon->digest_auth_rand_size, 1683 return MHD_DAUTH_WRONG_HEADER;
1585 connection->url, 1684 else if (0 == params->response.value.len)
1586 realm, 1685 return MHD_DAUTH_RESPONSE_WRONG;
1587 realm_len, 1686 else if (digest_size * 4 < params->response.value.len)
1588 da, 1687 return MHD_DAUTH_RESPONSE_WRONG;
1589 noncehashexp); 1688 unq_res = get_unquoted_param (&params->response, tmp1, ptmp2, &tmp2_size,
1689 &unquoted);
1690 if (_MHD_UNQ_OK != unq_res)
1691 return MHD_DAUTH_ERROR;
1692 if (digest_size * 2 != unquoted.len)
1693 return MHD_DAUTH_RESPONSE_WRONG;
1694
1695 mhd_assert (sizeof(response) > unquoted.len);
1696
1697 if (sizeof(response) <= unquoted.len)
1698 return MHD_DAUTH_ERROR;
1699 /* TODO: avoid memcpy() */
1700 memcpy (response, unquoted.str, unquoted.len);
1701 response[unquoted.len] = 0;
1702 /* Got 'response' */
1703
1704 if (1)
1705 {
1706 enum MHD_CheckNonceNC_ nonce_nc_check;
1590 /* 1707 /*
1591 * Second level vetting for the nonce validity 1708 * Checking if that combination of nonce and nc is sound
1592 * if the timestamp attached to the nonce is valid 1709 * and not a replay attack attempt. Refuse if nonce was not
1593 * and possibly fabricated (in case of an attack) 1710 * generated previously.
1594 * the attacker must also know the random seed to be
1595 * able to generate a "sane" nonce, which if he does
1596 * not, the nonce fabrication process going to be
1597 * very hard to achieve.
1598 */ 1711 */
1599 if ((0 != strncmp (noncehashexp, unquoted.str, unquoted.len)) || 1712 nonce_nc_check = check_nonce_nc (connection,
1600 (0 != noncehashexp[unquoted.len])) 1713 noncehashexp,
1601 return MHD_DAUTH_NONCE_WRONG; 1714 NONCE_STD_LEN (digest_size),
1602 /* 'nonce' valid */ 1715 nonce_time,
1603 1716 nci);
1604 /* Get 'cnonce' */ 1717 if (MHD_CHECK_NONCENC_STALE == nonce_nc_check)
1605 if (NULL == params->cnonce.value.str)
1606 return MHD_DAUTH_WRONG_HEADER;
1607 else if (0 == params->cnonce.value.len)
1608 return MHD_DAUTH_WRONG_HEADER;
1609 unq_res = get_unquoted_param (&params->cnonce, tmp1, ptmp2, &tmp2_size,
1610 &unquoted);
1611 if (_MHD_UNQ_OK != unq_res)
1612 return (_MHD_UNQ_TOO_LARGE == unq_res) ?
1613 MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
1614
1615 if (sizeof(cnonce) <= unquoted.len)
1616 return MHD_DAUTH_ERROR; /* TODO: handle large client nonces */
1617
1618 /* TODO: avoid memcpy() */
1619 memcpy (cnonce, unquoted.str, unquoted.len);
1620 cnonce[unquoted.len] = 0;
1621 /* Got 'cnonce' */
1622
1623 /* Get 'qop' */
1624 if (NULL == params->qop.value.str)
1625 return MHD_DAUTH_WRONG_HEADER;
1626 else if (0 == params->qop.value.len)
1627 return MHD_DAUTH_WRONG_QOP;
1628 else if (MHD_STATICSTR_LEN_ ("auth-int") * 2 < params->qop.value.len)
1629 return MHD_DAUTH_WRONG_QOP;
1630 unq_res = get_unquoted_param (&params->qop, tmp1, ptmp2, &tmp2_size,
1631 &unquoted);
1632 if (_MHD_UNQ_OK != unq_res)
1633 return MHD_DAUTH_ERROR;
1634
1635 if (sizeof(qop) <= unquoted.len)
1636 return MHD_DAUTH_ERROR; /* TODO: handle large client qop */
1637 /* TODO: avoid memcpy() */
1638 memcpy (qop, unquoted.str, unquoted.len);
1639 qop[unquoted.len] = 0;
1640 /* TODO: Really support empty value, support "auth-int" */
1641 if ( ((MHD_STATICSTR_LEN_ ("auth") != unquoted.len) ||
1642 (! MHD_str_equal_caseless_bin_n_ (qop, "auth", unquoted.len))) &&
1643 (0 != strcmp (qop,"")) )
1644 return MHD_DAUTH_WRONG_QOP;
1645 /* Got 'qop' */
1646
1647 /* Get 'nc' */
1648 if (NULL == params->nc.value.str)
1649 return MHD_DAUTH_WRONG_HEADER;
1650 else if (0 == params->nc.value.len)
1651 return MHD_DAUTH_WRONG_HEADER;
1652 else if (4 * 8 < params->nc.value.len) /* Four time more than needed */
1653 return MHD_DAUTH_NONCE_WRONG;
1654 unq_res = get_unquoted_param (&params->nc, tmp1, ptmp2, &tmp2_size,
1655 &unquoted);
1656 if (_MHD_UNQ_OK != unq_res)
1657 return MHD_DAUTH_ERROR;
1658
1659 if (sizeof(nc) <= unquoted.len)
1660 return MHD_DAUTH_ERROR;
1661 /* TODO: avoid memcpy() */
1662 memcpy (nc, unquoted.str, unquoted.len);
1663 nc[unquoted.len] = 0;
1664 if (unquoted.len != MHD_strx_to_uint64_n_ (nc,
1665 unquoted.len,
1666 &nci))
1667 { 1718 {
1668#ifdef HAVE_MESSAGES 1719#ifdef HAVE_MESSAGES
1669 MHD_DLOG (daemon, 1720 MHD_DLOG (daemon,
1670 _ ("Authentication failed, invalid nc format.\n")); 1721 _ ("Stale nonce received. If this happens a lot, you should "
1722 "probably increase the size of the nonce array.\n"));
1671#endif 1723#endif
1672 return MHD_DAUTH_WRONG_HEADER; /* invalid nonce format */ 1724 return MHD_DAUTH_NONCE_STALE;
1673 } 1725 }
1674 if (0 == nci) 1726 else if (MHD_CHECK_NONCENC_WRONG == nonce_nc_check)
1675 { 1727 {
1676#ifdef HAVE_MESSAGES 1728#ifdef HAVE_MESSAGES
1677 MHD_DLOG (daemon, 1729 MHD_DLOG (daemon,
1678 _ ("Authentication failed, invalid 'nc' value.\n")); 1730 _ ("Received nonce that technically valid, but was not "
1731 "generated by MHD. This may indicate an attack attempt.\n"));
1679#endif 1732#endif
1680 return MHD_DAUTH_WRONG_HEADER; /* invalid nc value */ 1733 return MHD_DAUTH_NONCE_WRONG;
1681 } 1734 }
1682 /* Got 'nc' */ 1735 mhd_assert (MHD_CHECK_NONCENC_OK == nonce_nc_check);
1683 1736 }
1684 /* Get 'response' */
1685 if (NULL == params->response.value.str)
1686 return MHD_DAUTH_WRONG_HEADER;
1687 else if (0 == params->response.value.len)
1688 return MHD_DAUTH_RESPONSE_WRONG;
1689 else if (digest_size * 4 < params->response.value.len)
1690 return MHD_DAUTH_RESPONSE_WRONG;
1691 unq_res = get_unquoted_param (&params->response, tmp1, ptmp2, &tmp2_size,
1692 &unquoted);
1693 if (_MHD_UNQ_OK != unq_res)
1694 return MHD_DAUTH_ERROR;
1695 if (digest_size * 2 != unquoted.len)
1696 return MHD_DAUTH_RESPONSE_WRONG;
1697
1698 mhd_assert (sizeof(response) > unquoted.len);
1699
1700 if (sizeof(response) <= unquoted.len)
1701 return MHD_DAUTH_ERROR;
1702 /* TODO: avoid memcpy() */
1703 memcpy (response, unquoted.str, unquoted.len);
1704 response[unquoted.len] = 0;
1705 /* Got 'response' */
1706 1737
1707 if (1) 1738 /* Get 'uri' */
1739 if (NULL == params->uri.value.str)
1740 return MHD_DAUTH_WRONG_HEADER;
1741 else if (0 == params->uri.value.len)
1742 return MHD_DAUTH_WRONG_URI;
1743 unq_res = get_unquoted_param_copy (&params->uri, tmp1, ptmp2, &tmp2_size,
1744 &unq_copy);
1745 if (_MHD_UNQ_OK != unq_res)
1746 return (_MHD_UNQ_TOO_LARGE == unq_res) ?
1747 MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
1748
1749 if (NULL != digest)
1750 {
1751 /* This will initialize da->digest_hex (ha1) */
1752 digest_calc_ha1_from_digest (digest_get_algo_name (da),
1753 da,
1754 digest,
1755 noncehashexp,
1756 cnonce);
1757 }
1758 else
1759 {
1760 /* This will initialize da->digest_hex (ha1) */
1761 mhd_assert (NULL != password); /* NULL == digest => password != NULL */
1762 digest_calc_ha1_from_user (digest_get_algo_name (da),
1763 username,
1764 username_len,
1765 realm,
1766 realm_len,
1767 password,
1768 noncehashexp,
1769 cnonce,
1770 da);
1771 }
1772 memcpy (ha1,
1773 digest_get_hex_buffer (da),
1774 digest_size * 2 + 1);
1775 /* This will initialize da->sessionkey (respexp) */
1776 digest_calc_response (ha1,
1777 noncehashexp,
1778 nc,
1779 cnonce,
1780 qop,
1781 connection->method,
1782 unq_copy.str,
1783 unq_copy.len,
1784 hentity,
1785 da);
1786 if (1)
1787 {
1788 char *uri;
1789 size_t uri_len;
1790 uri = unq_copy.str;
1791 uri_len = unq_copy.len;
1792
1793 uri[uri_len] = 0;
1794 qmark = memchr (uri,
1795 '?',
1796 uri_len);
1797 if (NULL != qmark)
1798 *qmark = '\0';
1799
1800 /* Need to unescape URI before comparing with connection->url */
1801 uri_len = daemon->unescape_callback (daemon->unescape_callback_cls,
1802 connection,
1803 uri);
1804 if ((uri_len != connection->url_len) ||
1805 (0 != memcmp (uri, connection->url, uri_len)))
1708 { 1806 {
1709 enum MHD_CheckNonceNC_ nonce_nc_check;
1710 /*
1711 * Checking if that combination of nonce and nc is sound
1712 * and not a replay attack attempt. Refuse if nonce was not
1713 * generated previously.
1714 */
1715 nonce_nc_check = check_nonce_nc (connection,
1716 noncehashexp,
1717 NONCE_STD_LEN (digest_size),
1718 nonce_time,
1719 nci);
1720 if (MHD_CHECK_NONCENC_STALE == nonce_nc_check)
1721 {
1722#ifdef HAVE_MESSAGES 1807#ifdef HAVE_MESSAGES
1723 MHD_DLOG (daemon, 1808 MHD_DLOG (daemon,
1724 _ ("Stale nonce received. If this happens a lot, you should " 1809 _ ("Authentication failed, URI does not match.\n"));
1725 "probably increase the size of the nonce array.\n"));
1726#endif
1727 return MHD_DAUTH_NONCE_STALE;
1728 }
1729 else if (MHD_CHECK_NONCENC_WRONG == nonce_nc_check)
1730 {
1731#ifdef HAVE_MESSAGES
1732 MHD_DLOG (daemon,
1733 _ ("Received nonce that technically valid, but was not "
1734 "generated by MHD. This may indicate an attack attempt.\n"));
1735#endif 1810#endif
1736 return MHD_DAUTH_NONCE_WRONG;
1737 }
1738 mhd_assert (MHD_CHECK_NONCENC_OK == nonce_nc_check);
1739 }
1740
1741 /* Get 'uri' */
1742 if (NULL == params->uri.value.str)
1743 return MHD_DAUTH_WRONG_HEADER;
1744 else if (0 == params->uri.value.len)
1745 return MHD_DAUTH_WRONG_URI; 1811 return MHD_DAUTH_WRONG_URI;
1746 unq_res = get_unquoted_param_copy (&params->uri, tmp1, ptmp2, &tmp2_size,
1747 &unq_copy);
1748 if (_MHD_UNQ_OK != unq_res)
1749 return (_MHD_UNQ_TOO_LARGE == unq_res) ?
1750 MHD_DAUTH_TOO_LARGE : MHD_DAUTH_ERROR;
1751
1752 if (NULL != digest)
1753 {
1754 /* This will initialize da->digest_hex (ha1) */
1755 digest_calc_ha1_from_digest (digest_get_algo_name (da),
1756 da,
1757 digest,
1758 noncehashexp,
1759 cnonce);
1760 }
1761 else
1762 {
1763 /* This will initialize da->digest_hex (ha1) */
1764 mhd_assert (NULL != password); /* NULL == digest => password != NULL */
1765 digest_calc_ha1_from_user (digest_get_algo_name (da),
1766 username,
1767 username_len,
1768 realm,
1769 realm_len,
1770 password,
1771 noncehashexp,
1772 cnonce,
1773 da);
1774 } 1812 }
1775 memcpy (ha1, 1813
1776 digest_get_hex_buffer (da),
1777 digest_size * 2 + 1);
1778 /* This will initialize da->sessionkey (respexp) */
1779 digest_calc_response (ha1,
1780 noncehashexp,
1781 nc,
1782 cnonce,
1783 qop,
1784 connection->method,
1785 unq_copy.str,
1786 unq_copy.len,
1787 hentity,
1788 da);
1789 if (1) 1814 if (1)
1790 { 1815 {
1791 char *uri; 1816 const char *args = qmark;
1792 size_t uri_len; 1817
1793 uri = unq_copy.str; 1818 if (NULL == args)
1794 uri_len = unq_copy.len; 1819 args = "";
1795 1820 else
1796 uri[uri_len] = 0; 1821 args++;
1797 qmark = memchr (uri, 1822 if (MHD_NO ==
1798 '?', 1823 check_argument_match (connection,
1799 uri_len); 1824 args) )
1800 if (NULL != qmark)
1801 *qmark = '\0';
1802
1803 /* Need to unescape URI before comparing with connection->url */
1804 uri_len = daemon->unescape_callback (daemon->unescape_callback_cls,
1805 connection,
1806 uri);
1807 if ((uri_len != connection->url_len) ||
1808 (0 != memcmp (uri, connection->url, uri_len)))
1809 { 1825 {
1810#ifdef HAVE_MESSAGES 1826#ifdef HAVE_MESSAGES
1811 MHD_DLOG (daemon, 1827 MHD_DLOG (daemon,
1812 _ ("Authentication failed, URI does not match.\n")); 1828 _ ("Authentication failed, arguments do not match.\n"));
1813#endif 1829#endif
1814 return MHD_DAUTH_WRONG_URI; 1830 return MHD_DAUTH_WRONG_URI;
1815 } 1831 }
1816
1817 if (1)
1818 {
1819 const char *args = qmark;
1820
1821 if (NULL == args)
1822 args = "";
1823 else
1824 args++;
1825 if (MHD_NO ==
1826 check_argument_match (connection,
1827 args) )
1828 {
1829#ifdef HAVE_MESSAGES
1830 MHD_DLOG (daemon,
1831 _ ("Authentication failed, arguments do not match.\n"));
1832#endif
1833 return MHD_DAUTH_WRONG_URI;
1834 }
1835 }
1836
1837 ret = (0 == strcmp (response,
1838 digest_get_hex_buffer (da)))
1839 ? MHD_DAUTH_OK
1840 : MHD_DAUTH_RESPONSE_WRONG;
1841 } 1832 }
1842 } while (0); 1833
1834 ret = (0 == strcmp (response,
1835 digest_get_hex_buffer (da)))
1836 ? MHD_DAUTH_OK
1837 : MHD_DAUTH_RESPONSE_WRONG;
1838 }
1843 1839
1844 return ret; 1840 return ret;
1845} 1841}