diff options
Diffstat (limited to 'src/reclaim/plugin_rest_openid_connect.c')
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 236 |
1 files changed, 192 insertions, 44 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 92a1de621..741094f21 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -120,6 +120,11 @@ | |||
120 | #define OIDC_NONCE_KEY "nonce" | 120 | #define OIDC_NONCE_KEY "nonce" |
121 | 121 | ||
122 | /** | 122 | /** |
123 | * OIDC claims key | ||
124 | */ | ||
125 | #define OIDC_CLAIMS_KEY "claims" | ||
126 | |||
127 | /** | ||
123 | * OIDC PKCE code challenge | 128 | * OIDC PKCE code challenge |
124 | */ | 129 | */ |
125 | #define OIDC_CODE_CHALLENGE_KEY "code_challenge" | 130 | #define OIDC_CODE_CHALLENGE_KEY "code_challenge" |
@@ -291,6 +296,11 @@ struct OIDC_Variables | |||
291 | char *nonce; | 296 | char *nonce; |
292 | 297 | ||
293 | /** | 298 | /** |
299 | * The OIDC claims | ||
300 | */ | ||
301 | char *claims; | ||
302 | |||
303 | /** | ||
294 | * The OIDC response type | 304 | * The OIDC response type |
295 | */ | 305 | */ |
296 | char *response_type; | 306 | char *response_type; |
@@ -560,7 +570,12 @@ cleanup_handle (struct RequestHandle *handle) | |||
560 | { | 570 | { |
561 | claim_tmp = claim_entry; | 571 | claim_tmp = claim_entry; |
562 | claim_entry = claim_entry->next; | 572 | claim_entry = claim_entry->next; |
563 | GNUNET_free (claim_tmp->claim); | 573 | if (NULL != claim_tmp->claim) |
574 | GNUNET_free (claim_tmp->claim); | ||
575 | if (NULL != claim_tmp->attest) | ||
576 | GNUNET_free (claim_tmp->attest); | ||
577 | if (NULL != claim_tmp->reference) | ||
578 | GNUNET_free (claim_tmp->reference); | ||
564 | GNUNET_free (claim_tmp); | 579 | GNUNET_free (claim_tmp); |
565 | } | 580 | } |
566 | GNUNET_free (handle->attr_list); | 581 | GNUNET_free (handle->attr_list); |
@@ -697,7 +712,7 @@ return_userinfo_response (void *cls) | |||
697 | struct MHD_Response *resp; | 712 | struct MHD_Response *resp; |
698 | 713 | ||
699 | result_str = json_dumps (handle->oidc->response, 0); | 714 | result_str = json_dumps (handle->oidc->response, 0); |
700 | 715 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str); | |
701 | resp = GNUNET_REST_create_response (result_str); | 716 | resp = GNUNET_REST_create_response (result_str); |
702 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 717 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
703 | GNUNET_free (result_str); | 718 | GNUNET_free (result_str); |
@@ -838,7 +853,7 @@ login_redirect (void *cls) | |||
838 | &login_base_url)) | 853 | &login_base_url)) |
839 | { | 854 | { |
840 | GNUNET_asprintf (&new_redirect, | 855 | GNUNET_asprintf (&new_redirect, |
841 | "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | 856 | "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", |
842 | login_base_url, | 857 | login_base_url, |
843 | OIDC_RESPONSE_TYPE_KEY, | 858 | OIDC_RESPONSE_TYPE_KEY, |
844 | handle->oidc->response_type, | 859 | handle->oidc->response_type, |
@@ -854,7 +869,10 @@ login_redirect (void *cls) | |||
854 | (NULL != handle->oidc->code_challenge) ? | 869 | (NULL != handle->oidc->code_challenge) ? |
855 | handle->oidc->code_challenge : "", | 870 | handle->oidc->code_challenge : "", |
856 | OIDC_NONCE_KEY, | 871 | OIDC_NONCE_KEY, |
857 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); | 872 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", |
873 | OIDC_CLAIMS_KEY, | ||
874 | (NULL != handle->oidc->claims) ? handle->oidc->claims : | ||
875 | ""); | ||
858 | resp = GNUNET_REST_create_response (""); | 876 | resp = GNUNET_REST_create_response (""); |
859 | MHD_add_response_header (resp, "Location", new_redirect); | 877 | MHD_add_response_header (resp, "Location", new_redirect); |
860 | GNUNET_free (login_base_url); | 878 | GNUNET_free (login_base_url); |
@@ -973,12 +991,14 @@ oidc_collect_finished_cb (void *cls) | |||
973 | 991 | ||
974 | 992 | ||
975 | /** | 993 | /** |
976 | * Collects all attributes for an ego if in scope parameter | 994 | * Collects all attributes/references for an ego if in scope parameter |
977 | */ | 995 | */ |
978 | static void | 996 | static void |
979 | oidc_attr_collect (void *cls, | 997 | oidc_attr_collect (void *cls, |
980 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | 998 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, |
981 | const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) | 999 | const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, |
1000 | const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, | ||
1001 | const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference) | ||
982 | { | 1002 | { |
983 | struct RequestHandle *handle = cls; | 1003 | struct RequestHandle *handle = cls; |
984 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | 1004 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; |
@@ -986,39 +1006,92 @@ oidc_attr_collect (void *cls, | |||
986 | char *scope_variable; | 1006 | char *scope_variable; |
987 | char delimiter[] = " "; | 1007 | char delimiter[] = " "; |
988 | 1008 | ||
989 | if ((NULL == attr->name) || (NULL == attr->data)) | 1009 | if ((NULL == attr) && (NULL == reference)) |
990 | { | 1010 | { |
991 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | 1011 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); |
992 | return; | 1012 | return; |
993 | } | 1013 | } |
994 | 1014 | if (NULL != reference) | |
995 | scope_variables = GNUNET_strdup (handle->oidc->scope); | ||
996 | scope_variable = strtok (scope_variables, delimiter); | ||
997 | while (NULL != scope_variable) | ||
998 | { | ||
999 | if (0 == strcmp (attr->name, scope_variable)) | ||
1000 | break; | ||
1001 | scope_variable = strtok (NULL, delimiter); | ||
1002 | } | ||
1003 | if (NULL == scope_variable) | ||
1004 | { | 1015 | { |
1005 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | 1016 | if ((NULL == reference->name) || (NULL == reference->reference_value)) |
1017 | { | ||
1018 | return; | ||
1019 | } | ||
1020 | scope_variables = GNUNET_strdup (handle->oidc->scope); | ||
1021 | scope_variable = strtok (scope_variables, delimiter); | ||
1022 | while (NULL != scope_variable) | ||
1023 | { | ||
1024 | if (0 == strcmp (reference->name, scope_variable)) | ||
1025 | break; | ||
1026 | scope_variable = strtok (NULL, delimiter); | ||
1027 | } | ||
1028 | if (NULL == scope_variable) | ||
1029 | { | ||
1030 | GNUNET_free (scope_variables); | ||
1031 | return; | ||
1032 | } | ||
1006 | GNUNET_free (scope_variables); | 1033 | GNUNET_free (scope_variables); |
1007 | return; | 1034 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2; |
1035 | le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); | ||
1036 | le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); | ||
1037 | le->claim = NULL; | ||
1038 | le->reference = NULL; | ||
1039 | le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (attest->name, | ||
1040 | attest->type, | ||
1041 | attest->data, | ||
1042 | attest->data_size); | ||
1043 | le->attest->id = attest->id; | ||
1044 | le2->attest = NULL; | ||
1045 | le2->claim = NULL; | ||
1046 | le2->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (reference->name, | ||
1047 | reference-> | ||
1048 | reference_value); | ||
1049 | le2->reference->id = reference->id; | ||
1050 | le2->reference->id_attest = reference->id_attest; | ||
1051 | GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, | ||
1052 | handle->attr_list->list_tail, | ||
1053 | le); | ||
1054 | GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, | ||
1055 | handle->attr_list->list_tail, | ||
1056 | le2); | ||
1057 | } | ||
1058 | else if (NULL != attr) | ||
1059 | { | ||
1060 | if ((NULL == attr->name) || (NULL == attr->data)) | ||
1061 | { | ||
1062 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | ||
1063 | return; | ||
1064 | } | ||
1065 | scope_variables = GNUNET_strdup (handle->oidc->scope); | ||
1066 | scope_variable = strtok (scope_variables, delimiter); | ||
1067 | while (NULL != scope_variable) | ||
1068 | { | ||
1069 | if (0 == strcmp (attr->name, scope_variable)) | ||
1070 | break; | ||
1071 | scope_variable = strtok (NULL, delimiter); | ||
1072 | } | ||
1073 | if (NULL == scope_variable) | ||
1074 | { | ||
1075 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | ||
1076 | GNUNET_free (scope_variables); | ||
1077 | return; | ||
1078 | } | ||
1079 | GNUNET_free (scope_variables); | ||
1080 | le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); | ||
1081 | le->reference = NULL; | ||
1082 | le->attest = NULL; | ||
1083 | le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name, | ||
1084 | attr->type, | ||
1085 | attr->data, | ||
1086 | attr->data_size); | ||
1087 | le->claim->id = attr->id; | ||
1088 | le->claim->flag = attr->flag; | ||
1089 | |||
1090 | GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, | ||
1091 | handle->attr_list->list_tail, | ||
1092 | le); | ||
1093 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | ||
1008 | } | 1094 | } |
1009 | GNUNET_free (scope_variables); | ||
1010 | |||
1011 | le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); | ||
1012 | le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name, | ||
1013 | attr->type, | ||
1014 | attr->data, | ||
1015 | attr->data_size); | ||
1016 | le->claim->id = attr->id; | ||
1017 | le->claim->version = attr->version; | ||
1018 | GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, | ||
1019 | handle->attr_list->list_tail, | ||
1020 | le); | ||
1021 | GNUNET_RECLAIM_get_attributes_next (handle->attr_it); | ||
1022 | } | 1095 | } |
1023 | 1096 | ||
1024 | 1097 | ||
@@ -1304,6 +1377,9 @@ build_authz_response (void *cls) | |||
1304 | // OPTIONAL value: nonce | 1377 | // OPTIONAL value: nonce |
1305 | handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY); | 1378 | handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY); |
1306 | 1379 | ||
1380 | // OPTIONAL value: claims | ||
1381 | handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY); | ||
1382 | |||
1307 | // TODO check other values if needed | 1383 | // TODO check other values if needed |
1308 | number_of_ignored_parameter = | 1384 | number_of_ignored_parameter = |
1309 | sizeof(OIDC_ignored_parameter_array) / sizeof(char *); | 1385 | sizeof(OIDC_ignored_parameter_array) / sizeof(char *); |
@@ -1454,6 +1530,9 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1454 | handle->ego_entry = handle->ego_tail; | 1530 | handle->ego_entry = handle->ego_tail; |
1455 | } | 1531 | } |
1456 | } | 1532 | } |
1533 | handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); | ||
1534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n",GNUNET_strdup ( | ||
1535 | handle->oidc->scope)); | ||
1457 | if (NULL == handle->tld) | 1536 | if (NULL == handle->tld) |
1458 | GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle); | 1537 | GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle); |
1459 | if (NULL == handle->tld) | 1538 | if (NULL == handle->tld) |
@@ -1857,28 +1936,97 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1857 | 1936 | ||
1858 | 1937 | ||
1859 | /** | 1938 | /** |
1860 | * Collects claims and stores them in handle | 1939 | * Collects claims and stores them in handle |
1861 | */ | 1940 | */ |
1862 | static void | 1941 | static void |
1863 | consume_ticket (void *cls, | 1942 | consume_ticket (void *cls, |
1864 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | 1943 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, |
1865 | const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) | 1944 | const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, |
1945 | const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, | ||
1946 | const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference) | ||
1866 | { | 1947 | { |
1867 | struct RequestHandle *handle = cls; | 1948 | struct RequestHandle *handle = cls; |
1868 | char *tmp_value; | ||
1869 | json_t *value; | ||
1870 | |||
1871 | if (NULL == identity) | 1949 | if (NULL == identity) |
1872 | { | 1950 | { |
1873 | GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); | 1951 | GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); |
1874 | return; | 1952 | return; |
1875 | } | 1953 | } |
1876 | tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, | 1954 | if (NULL != attr) |
1877 | attr->data, | 1955 | { |
1878 | attr->data_size); | 1956 | char *tmp_value; |
1879 | value = json_string (tmp_value); | 1957 | json_t *value; |
1880 | json_object_set_new (handle->oidc->response, attr->name, value); | 1958 | tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, |
1881 | GNUNET_free (tmp_value); | 1959 | attr->data, |
1960 | attr->data_size); | ||
1961 | value = json_string (tmp_value); | ||
1962 | json_object_set_new (handle->oidc->response, attr->name, value); | ||
1963 | GNUNET_free (tmp_value); | ||
1964 | } | ||
1965 | else if ((NULL != attest) && (NULL != reference)) | ||
1966 | { | ||
1967 | json_t *claim_sources; | ||
1968 | json_t *claim_sources_jwt; | ||
1969 | json_t *claim_names; | ||
1970 | char *attest_val_str; | ||
1971 | claim_sources=json_object_get(handle->oidc->response,"_claim_sources"); | ||
1972 | claim_names=json_object_get(handle->oidc->response,"_claim_names"); | ||
1973 | attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type, | ||
1974 | attest->data, | ||
1975 | attest-> | ||
1976 | data_size); | ||
1977 | if ((NULL == claim_sources) && (NULL == claim_names) ) | ||
1978 | { | ||
1979 | claim_sources = json_object (); | ||
1980 | claim_names = json_object (); | ||
1981 | } | ||
1982 | char *source_name; | ||
1983 | int i = 0; | ||
1984 | GNUNET_asprintf (&source_name,"src%d",i); | ||
1985 | while (NULL != (claim_sources_jwt = json_object_get (claim_sources, | ||
1986 | source_name))) | ||
1987 | { | ||
1988 | if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt, | ||
1989 | "JWT")), | ||
1990 | attest_val_str)) | ||
1991 | { | ||
1992 | // Adapt only the claim names | ||
1993 | json_object_set_new (claim_names, reference->name, json_string ( | ||
1994 | source_name)); | ||
1995 | json_object_set (handle->oidc->response, "_claim_names",claim_names); | ||
1996 | handle->oidc->response = json_deep_copy(handle->oidc->response); | ||
1997 | break; | ||
1998 | } | ||
1999 | i++; | ||
2000 | GNUNET_asprintf (&source_name,"src%d",i); | ||
2001 | } | ||
2002 | |||
2003 | // Create new one | ||
2004 | if (NULL == claim_sources_jwt) | ||
2005 | { | ||
2006 | claim_sources_jwt = json_object (); | ||
2007 | // Set the JWT for names | ||
2008 | json_object_set_new (claim_names, reference->name, json_string ( | ||
2009 | source_name)); | ||
2010 | // Set the JWT for the inner source | ||
2011 | json_object_set_new (claim_sources_jwt, "JWT", json_string ( | ||
2012 | attest_val_str)); | ||
2013 | // Set the JWT for the source | ||
2014 | json_object_set_new (claim_sources, source_name,claim_sources_jwt); | ||
2015 | // Set as claims | ||
2016 | json_object_set (handle->oidc->response, "_claim_names", claim_names); | ||
2017 | json_object_set (handle->oidc->response, "_claim_sources",claim_sources); | ||
2018 | handle->oidc->response = json_deep_copy(handle->oidc->response); | ||
2019 | } | ||
2020 | |||
2021 | json_decref (claim_sources); | ||
2022 | json_decref (claim_names); | ||
2023 | json_decref (claim_sources_jwt); | ||
2024 | GNUNET_free (attest_val_str); | ||
2025 | } | ||
2026 | else | ||
2027 | { | ||
2028 | // REMARK: We should not find any claim, one of attest/ref is NULL | ||
2029 | } | ||
1882 | } | 2030 | } |
1883 | 2031 | ||
1884 | 2032 | ||