aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-03 19:37:23 +0200
committerMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-03 19:37:23 +0200
commit8c86c44720790095726fa1597d6bb8a50f322b28 (patch)
treec9767d9185ba18d2913aa36b9cd900e5c3e29c14 /src
parenta899a94dccabeae11ccef5565751a9ace2f6cd01 (diff)
downloadgnunet-8c86c44720790095726fa1597d6bb8a50f322b28.tar.gz
gnunet-8c86c44720790095726fa1597d6bb8a50f322b28.zip
reclaim: support client credentials in POST body for token request
Diffstat (limited to 'src')
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c120
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
1798static int 1799static int
1799check_authorization (struct RequestHandle *handle, 1800parse_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
1854static int
1855parse_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
1891static int
1892check_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