diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-08-03 19:37:23 +0200 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2020-08-03 19:37:23 +0200 |
commit | 8c86c44720790095726fa1597d6bb8a50f322b28 (patch) | |
tree | c9767d9185ba18d2913aa36b9cd900e5c3e29c14 /src/reclaim | |
parent | a899a94dccabeae11ccef5565751a9ace2f6cd01 (diff) | |
download | gnunet-8c86c44720790095726fa1597d6bb8a50f322b28.tar.gz gnunet-8c86c44720790095726fa1597d6bb8a50f322b28.zip |
reclaim: support client credentials in POST body for token request
Diffstat (limited to 'src/reclaim')
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 6c71155ef..e54473162 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -999,6 +999,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | |||
999 | handle->redirect_prefix, | 999 | handle->redirect_prefix, |
1000 | handle->tld, | 1000 | handle->tld, |
1001 | handle->redirect_suffix, | 1001 | handle->redirect_suffix, |
1002 | (NULL == strchr(handle->redirect_suffix, '?') ? "?" : "&"), | ||
1002 | handle->oidc->response_type, | 1003 | handle->oidc->response_type, |
1003 | code_string, | 1004 | code_string, |
1004 | handle->oidc->state); | 1005 | handle->oidc->state); |
@@ -1006,8 +1007,9 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | |||
1006 | else | 1007 | else |
1007 | { | 1008 | { |
1008 | GNUNET_asprintf (&redirect_uri, | 1009 | GNUNET_asprintf (&redirect_uri, |
1009 | "%s?%s=%s&state=%s", | 1010 | "%s%s%s=%s&state=%s", |
1010 | handle->oidc->redirect_uri, | 1011 | handle->oidc->redirect_uri, |
1012 | (NULL == strchr(handle->oidc->redirect_uri, '?') ? "?" : "&"), | ||
1011 | handle->oidc->response_type, | 1013 | handle->oidc->response_type, |
1012 | code_string, | 1014 | code_string, |
1013 | handle->oidc->state); | 1015 | handle->oidc->state); |
@@ -1794,18 +1796,17 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1794 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 1796 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); |
1795 | } | 1797 | } |
1796 | 1798 | ||
1797 | |||
1798 | static int | 1799 | static int |
1799 | check_authorization (struct RequestHandle *handle, | 1800 | parse_credentials_basic_auth (struct RequestHandle *handle, |
1800 | struct GNUNET_CRYPTO_EcdsaPublicKey *cid) | 1801 | char **client_id, |
1802 | char **client_secret) | ||
1801 | { | 1803 | { |
1802 | struct GNUNET_HashCode cache_key; | 1804 | struct GNUNET_HashCode cache_key; |
1803 | char *authorization; | 1805 | char *authorization; |
1804 | char *credentials; | 1806 | char *credentials; |
1805 | char *basic_authorization; | 1807 | char *basic_authorization; |
1806 | char *client_id; | 1808 | char *client_id_tmp; |
1807 | char *pass; | 1809 | char *pass; |
1808 | char *expected_pass; | ||
1809 | 1810 | ||
1810 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | 1811 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, |
1811 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), | 1812 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), |
@@ -1813,12 +1814,7 @@ check_authorization (struct RequestHandle *handle, | |||
1813 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | 1814 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle |
1814 | ->header_param_map, | 1815 | ->header_param_map, |
1815 | &cache_key)) | 1816 | &cache_key)) |
1816 | { | ||
1817 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1818 | handle->edesc = GNUNET_strdup ("missing authorization"); | ||
1819 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1820 | return GNUNET_SYSERR; | 1817 | return GNUNET_SYSERR; |
1821 | } | ||
1822 | authorization = | 1818 | authorization = |
1823 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, | 1819 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, |
1824 | &cache_key); | 1820 | &cache_key); |
@@ -1826,40 +1822,93 @@ check_authorization (struct RequestHandle *handle, | |||
1826 | // split header in "Basic" and [content] | 1822 | // split header in "Basic" and [content] |
1827 | credentials = strtok (authorization, " "); | 1823 | credentials = strtok (authorization, " "); |
1828 | if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) | 1824 | if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) |
1829 | { | ||
1830 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1831 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1832 | return GNUNET_SYSERR; | 1825 | return GNUNET_SYSERR; |
1833 | } | ||
1834 | credentials = strtok (NULL, " "); | 1826 | credentials = strtok (NULL, " "); |
1835 | if (NULL == credentials) | 1827 | if (NULL == credentials) |
1836 | { | ||
1837 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1838 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1839 | return GNUNET_SYSERR; | 1828 | return GNUNET_SYSERR; |
1840 | } | ||
1841 | GNUNET_STRINGS_base64_decode (credentials, | 1829 | GNUNET_STRINGS_base64_decode (credentials, |
1842 | strlen (credentials), | 1830 | strlen (credentials), |
1843 | (void **) &basic_authorization); | 1831 | (void **) &basic_authorization); |
1844 | 1832 | ||
1845 | if (NULL == basic_authorization) | 1833 | if (NULL == basic_authorization) |
1846 | { | ||
1847 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1848 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1849 | return GNUNET_SYSERR; | 1834 | return GNUNET_SYSERR; |
1850 | } | 1835 | client_id_tmp = strtok (basic_authorization, ":"); |
1851 | client_id = strtok (basic_authorization, ":"); | 1836 | if (NULL == client_id_tmp) |
1852 | if (NULL == client_id) | ||
1853 | { | 1837 | { |
1854 | GNUNET_free (basic_authorization); | 1838 | GNUNET_free (basic_authorization); |
1855 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | ||
1856 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
1857 | return GNUNET_SYSERR; | 1839 | return GNUNET_SYSERR; |
1858 | } | 1840 | } |
1859 | pass = strtok (NULL, ":"); | 1841 | pass = strtok (NULL, ":"); |
1860 | if (NULL == pass) | 1842 | if (NULL == pass) |
1861 | { | 1843 | { |
1862 | GNUNET_free (basic_authorization); | 1844 | GNUNET_free (basic_authorization); |
1845 | return GNUNET_SYSERR; | ||
1846 | } | ||
1847 | *client_id = strdup (client_id_tmp); | ||
1848 | *client_secret = strdup (pass); | ||
1849 | GNUNET_free (basic_authorization); | ||
1850 | return GNUNET_OK; | ||
1851 | } | ||
1852 | |||
1853 | |||
1854 | static int | ||
1855 | parse_credentials_post_body (struct RequestHandle *handle, | ||
1856 | char **client_id, | ||
1857 | char **client_secret) | ||
1858 | { | ||
1859 | struct GNUNET_HashCode cache_key; | ||
1860 | char *client_id_tmp; | ||
1861 | char *pass; | ||
1862 | |||
1863 | GNUNET_CRYPTO_hash ("client_id", | ||
1864 | strlen ("client_id"), | ||
1865 | &cache_key); | ||
1866 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | ||
1867 | ->url_param_map, | ||
1868 | &cache_key)) | ||
1869 | return GNUNET_SYSERR; | ||
1870 | client_id_tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
1871 | &cache_key); | ||
1872 | if (NULL == client_id_tmp) | ||
1873 | return GNUNET_SYSERR; | ||
1874 | *client_id = strdup (client_id_tmp); | ||
1875 | GNUNET_CRYPTO_hash ("client_secret", | ||
1876 | strlen ("client_secret"), | ||
1877 | &cache_key); | ||
1878 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle | ||
1879 | ->url_param_map, | ||
1880 | &cache_key)) | ||
1881 | return GNUNET_SYSERR; | ||
1882 | pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
1883 | &cache_key); | ||
1884 | if (NULL == pass) | ||
1885 | return GNUNET_SYSERR; | ||
1886 | *client_secret = strdup (pass); | ||
1887 | return GNUNET_OK; | ||
1888 | } | ||
1889 | |||
1890 | |||
1891 | static int | ||
1892 | check_authorization (struct RequestHandle *handle, | ||
1893 | struct GNUNET_CRYPTO_EcdsaPublicKey *cid) | ||
1894 | { | ||
1895 | char *expected_pass; | ||
1896 | char *received_cid; | ||
1897 | char *received_cpw; | ||
1898 | |||
1899 | if (GNUNET_OK == parse_credentials_basic_auth (handle, | ||
1900 | &received_cid, | ||
1901 | &received_cpw)) | ||
1902 | { | ||
1903 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1904 | "Received client credentials in HTTP AuthZ header\n"); | ||
1905 | } else if (GNUNET_OK == parse_credentials_post_body (handle, | ||
1906 | &received_cid, | ||
1907 | &received_cpw)) | ||
1908 | { | ||
1909 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1910 | "Received client credentials in POST body\n"); | ||
1911 | } else { | ||
1863 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1912 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); |
1864 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1913 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
1865 | return GNUNET_SYSERR; | 1914 | return GNUNET_SYSERR; |
@@ -1871,9 +1920,8 @@ check_authorization (struct RequestHandle *handle, | |||
1871 | "OIDC_CLIENT_SECRET", | 1920 | "OIDC_CLIENT_SECRET", |
1872 | &expected_pass)) | 1921 | &expected_pass)) |
1873 | { | 1922 | { |
1874 | if (0 != strcmp (expected_pass, pass)) | 1923 | if (0 != strcmp (expected_pass, received_cpw)) |
1875 | { | 1924 | { |
1876 | GNUNET_free (basic_authorization); | ||
1877 | GNUNET_free (expected_pass); | 1925 | GNUNET_free (expected_pass); |
1878 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1926 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); |
1879 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1927 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
@@ -1883,33 +1931,33 @@ check_authorization (struct RequestHandle *handle, | |||
1883 | } | 1931 | } |
1884 | else | 1932 | else |
1885 | { | 1933 | { |
1886 | GNUNET_free (basic_authorization); | ||
1887 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); | 1934 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); |
1888 | handle->edesc = GNUNET_strdup ("gnunet configuration failed"); | 1935 | handle->edesc = GNUNET_strdup ("gnunet configuration failed"); |
1889 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1936 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; |
1890 | return GNUNET_SYSERR; | 1937 | return GNUNET_SYSERR; |
1891 | } | 1938 | } |
1892 | |||
1893 | // check client_id | 1939 | // check client_id |
1894 | for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; | 1940 | for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; |
1895 | handle->ego_entry = handle->ego_entry->next) | 1941 | handle->ego_entry = handle->ego_entry->next) |
1896 | { | 1942 | { |
1897 | if (0 == strcmp (handle->ego_entry->keystring, client_id)) | 1943 | if (0 == strcmp (handle->ego_entry->keystring, received_cid)) |
1898 | break; | 1944 | break; |
1899 | } | 1945 | } |
1900 | if (NULL == handle->ego_entry) | 1946 | if (NULL == handle->ego_entry) |
1901 | { | 1947 | { |
1902 | GNUNET_free (basic_authorization); | 1948 | GNUNET_free (received_cpw); |
1949 | GNUNET_free (received_cid); | ||
1903 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); | 1950 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); |
1904 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | 1951 | handle->response_code = MHD_HTTP_UNAUTHORIZED; |
1905 | return GNUNET_SYSERR; | 1952 | return GNUNET_SYSERR; |
1906 | } | 1953 | } |
1907 | GNUNET_STRINGS_string_to_data (client_id, | 1954 | GNUNET_STRINGS_string_to_data (received_cid, |
1908 | strlen (client_id), | 1955 | strlen (received_cid), |
1909 | cid, | 1956 | cid, |
1910 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); | 1957 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); |
1911 | 1958 | ||
1912 | GNUNET_free (basic_authorization); | 1959 | GNUNET_free (received_cpw); |
1960 | GNUNET_free (received_cid); | ||
1913 | return GNUNET_OK; | 1961 | return GNUNET_OK; |
1914 | } | 1962 | } |
1915 | 1963 | ||