From 1d4f5263ae72c12a42ec166ec8b1769620baaeda Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Thu, 6 Aug 2020 08:45:40 +0200 Subject: reclaim: Refactoring and more standards compliance with respect to scopes --- src/reclaim/oidc_helper.c | 313 ++++++++++++++++++++++++------- src/reclaim/oidc_helper.h | 30 ++- src/reclaim/plugin_rest_openid_connect.c | 198 +++++++------------ 3 files changed, 341 insertions(+), 200 deletions(-) diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 4da387564..cb99a749d 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -69,6 +69,51 @@ struct OIDC_Parameters GNUNET_NETWORK_STRUCT_END +/** + * Standard claims represented by the "profile" scope in OIDC + */ +static char OIDC_profile_claims[14][32] = { + "name", "family_name", "given_name", "middle_name", "nickname", + "preferred_username", "profile", "picture", "website", "gender", "birthdate", + "zoneinfo", "locale", "updated_at" +}; + +/** + * Standard claims represented by the "email" scope in OIDC + */ +static char OIDC_email_claims[2][16] = { + "email", "email_verified" +}; + +/** + * Standard claims represented by the "phone" scope in OIDC + */ +static char OIDC_phone_claims[2][32] = { + "phone_number", "phone_number_verified" +}; + +/** + * Standard claims represented by the "address" scope in OIDC + */ +static char OIDC_address_claims[5][32] = { + "street_address", "locality", "region", "postal_code", "country" +}; + +static enum GNUNET_GenericReturnValue +is_claim_in_address_scope (const char *claim) +{ + int i; + for (i = 0; i < 5; i++) + { + if (0 == strcmp (claim, OIDC_address_claims[i])) + { + return GNUNET_YES; + } + } + return GNUNET_NO; +} + + static char * create_jwt_header (void) { @@ -109,49 +154,24 @@ fix_base64 (char *str) replace_char (str, '/', '_'); } - -/** - * Create a JWT from attributes - * - * @param aud_key the public of the audience - * @param sub_key the public key of the subject - * @param attrs the attribute list - * @param expiration_time the validity of the token - * @param secret_key the key used to sign the JWT - * @return a new base64-encoded JWT string. - */ -char * -OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_AttestationList *attests, - const struct GNUNET_TIME_Relative *expiration_time, - const char *nonce, - const char *secret_key) +static json_t* +generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests) { struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_AttestationListEntry *ale; - struct GNUNET_HashCode signature; - struct GNUNET_TIME_Absolute exp_time; - struct GNUNET_TIME_Absolute time_now; - char *audience; char *subject; - char *header; - char *body_str; char *aggr_names_str; char *aggr_sources_str; char *source_name; - char *result; - char *header_base64; - char *body_base64; - char *signature_target; - char *signature_base64; char *attr_val_str; char *attest_val_str; json_t *body; json_t *aggr_names; json_t *aggr_sources; json_t *aggr_sources_jwt; + json_t *addr_claim; int num_attestations = 0; for (le = attrs->list_head; NULL != le; le = le->next) { @@ -159,22 +179,10 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, num_attestations++; } - // iat REQUIRED time now - time_now = GNUNET_TIME_absolute_get (); - // exp REQUIRED time expired from config - exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); - // auth_time only if max_age - // nonce only if nonce - // OPTIONAL acr,amr,azp subject = GNUNET_STRINGS_data_to_string_alloc (sub_key, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); - audience = - GNUNET_STRINGS_data_to_string_alloc (aud_key, - sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); - header = create_jwt_header (); body = json_object (); aggr_names = json_object (); aggr_sources = json_object (); @@ -185,23 +193,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); // sub REQUIRED public key identity, not exceed 255 ASCII length json_object_set_new (body, "sub", json_string (subject)); - // aud REQUIRED public key client_id must be there - json_object_set_new (body, "aud", json_string (audience)); - // iat - json_object_set_new (body, - "iat", - json_integer (time_now.abs_value_us / (1000 * 1000))); - // exp - json_object_set_new (body, - "exp", - json_integer (exp_time.abs_value_us / (1000 * 1000))); - // nbf - json_object_set_new (body, - "nbf", - json_integer (time_now.abs_value_us / (1000 * 1000))); - // nonce - if (NULL != nonce) - json_object_set_new (body, "nonce", json_string (nonce)); attest_val_str = NULL; aggr_names_str = NULL; aggr_sources_str = NULL; @@ -236,8 +227,28 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type, le->attribute->data, le->attribute->data_size); - json_object_set_new (body, le->attribute->name, - json_string (attr_val_str)); + /** + * There is this wierd quirk that the individual address claim(s) must be + * inside a JSON object of the "address" claim. + * FIXME: Possibly include formatted claim here + */ + if (GNUNET_YES == is_claim_in_address_scope (le->attribute->name)) + { + if (NULL == addr_claim) + { + addr_claim = json_object (); + json_object_set_new (body, "address", + addr_claim); + } + json_object_set_new (addr_claim, le->attribute->name, + json_string (attr_val_str)); + + } + else + { + json_object_set_new (body, le->attribute->name, + json_string (attr_val_str)); + } GNUNET_free (attr_val_str); } else @@ -277,6 +288,102 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, json_decref (aggr_names); json_decref (aggr_sources); + return body; +} + +/** + * Generate userinfo JSON as string + * + * @param sub_key the subject (user) + * @param attrs user attribute list + * @param attests user attribute attestation list (may be empty) + * @return Userinfo JSON + */ +char * +OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests) +{ + char *body_str; + json_t* body = generate_userinfo_json (sub_key, + attrs, + attests); + body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); + json_decref (body); + return body_str; +} + + +/** + * Create a JWT from attributes + * + * @param aud_key the public of the audience + * @param sub_key the public key of the subject + * @param attrs the attribute list + * @param expiration_time the validity of the token + * @param secret_key the key used to sign the JWT + * @return a new base64-encoded JWT string. + */ +char * +OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests, + const struct GNUNET_TIME_Relative *expiration_time, + const char *nonce, + const char *secret_key) +{ + struct GNUNET_HashCode signature; + struct GNUNET_TIME_Absolute exp_time; + struct GNUNET_TIME_Absolute time_now; + char *audience; + char *subject; + char *header; + char *body_str; + char *result; + char *header_base64; + char *body_base64; + char *signature_target; + char *signature_base64; + json_t *body; + + body = generate_userinfo_json (sub_key, + attrs, + attests); + // iat REQUIRED time now + time_now = GNUNET_TIME_absolute_get (); + // exp REQUIRED time expired from config + exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); + // auth_time only if max_age + // nonce only if nonce + // OPTIONAL acr,amr,azp + subject = + GNUNET_STRINGS_data_to_string_alloc (sub_key, + sizeof(struct + GNUNET_CRYPTO_EcdsaPublicKey)); + audience = + GNUNET_STRINGS_data_to_string_alloc (aud_key, + sizeof(struct + GNUNET_CRYPTO_EcdsaPublicKey)); + header = create_jwt_header (); + + // aud REQUIRED public key client_id must be there + json_object_set_new (body, "aud", json_string (audience)); + // iat + json_object_set_new (body, + "iat", + json_integer (time_now.abs_value_us / (1000 * 1000))); + // exp + json_object_set_new (body, + "exp", + json_integer (exp_time.abs_value_us / (1000 * 1000))); + // nbf + json_object_set_new (body, + "nbf", + json_integer (time_now.abs_value_us / (1000 * 1000))); + // nonce + if (NULL != nonce) + json_object_set_new (body, "nonce", json_string (nonce)); body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); json_decref (body); @@ -315,10 +422,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_free (signature_target); GNUNET_free (header); GNUNET_free (body_str); - if (NULL != aggr_sources_str) - GNUNET_free (aggr_sources_str); - if (NULL != aggr_names_str) - GNUNET_free (aggr_names_str); GNUNET_free (signature_base64); GNUNET_free (body_base64); GNUNET_free (header_base64); @@ -552,7 +655,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, code_challenge = ((char *) ¶ms[1]); GNUNET_free (code_verifier_hash); if (0 != - strncmp (expected_code_challenge, code_challenge, code_challenge_len)) + strncmp (expected_code_challenge, code_challenge, code_challenge_len)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier! Expected: %s, Got: %.*s\n", @@ -575,8 +678,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, // Ticket memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); - // Signature - //GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); + // Signature + // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); if (0 != GNUNET_memcmp (audience, &ticket->audience)) { GNUNET_free (code_payload); @@ -675,3 +778,77 @@ OIDC_access_token_parse (const char*token, return GNUNET_SYSERR; return GNUNET_OK; } + + +/** + * Checks if a claim is implicitly requested through standard + * scope(s) + * + * @param scopes the scopes which have been requested + * @param attr the attribute name to check + * @return GNUNET_YES if attribute is implcitly requested + */ +enum GNUNET_GenericReturnValue +OIDC_check_scopes_for_claim_request (const char*scopes, + const char*attr) +{ + char *scope_variables; + char *scope_variable; + char delimiter[] = " "; + int i; + + scope_variables = GNUNET_strdup (scopes); + scope_variable = strtok (scope_variables, delimiter); + while (NULL != scope_variable) + { + if (0 == strcmp ("profile", scope_variable)) + { + for (i = 0; i < 14; i++) + { + if (0 == strcmp (attr, OIDC_profile_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("address", scope_variable)) + { + for (i = 0; i < 5; i++) + { + if (0 == strcmp (attr, OIDC_address_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("email", scope_variable)) + { + for (i = 0; i < 2; i++) + { + if (0 == strcmp (attr, OIDC_email_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("phone", scope_variable)) + { + for (i = 0; i < 2; i++) + { + if (0 == strcmp (attr, OIDC_phone_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + + } + scope_variable = strtok (NULL, delimiter); + } + GNUNET_free (scope_variables); + return GNUNET_NO; + +} diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index e71a7ad1c..e713dab62 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -49,7 +49,7 @@ * @return a new base64-encoded JWT string. */ char* -OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, +OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, struct GNUNET_RECLAIM_AttributeList *attrs, struct GNUNET_RECLAIM_AttestationList *attests, @@ -125,4 +125,32 @@ OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); int OIDC_access_token_parse (const char* token, struct GNUNET_RECLAIM_Ticket **ticket); + + +/** + * Checks if a claim is implicitly requested through standard + * scope(s) + * + * @param scopes the scopes which have been requested + * @param attr the attribute name to check + * @return GNUNET_YES if attribute is implcitly requested + */ +enum GNUNET_GenericReturnValue +OIDC_check_scopes_for_claim_request (const char*scopes, + const char*attr); + + +/** + * Generate userinfo JSON as string + * + * @param sub_key the subject (user) + * @param attrs user attribute list + * @param attests user attribute attestation list (may be empty) + * @return Userinfo JSON + */ +char * +OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests); + #endif diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 238cffb85..b294ba166 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -357,10 +357,6 @@ struct OIDC_Variables */ char *code_verifier; - /** - * The response JSON - */ - json_t *response; }; /** @@ -569,7 +565,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_free (handle->oidc->response_type); GNUNET_free (handle->oidc->scope); GNUNET_free (handle->oidc->state); - json_decref (handle->oidc->response); GNUNET_free (handle->oidc); } if (NULL!=handle->attr_idtoken_list) @@ -690,27 +685,6 @@ do_timeout (void *cls) } -/** - * Return attributes for claim - * - * @param cls the request handle - */ -static void -return_userinfo_response (void *cls) -{ - char *result_str; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - result_str = json_dumps (handle->oidc->response, 0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - cleanup_handle (handle); -} - - /** * Respond to OPTIONS request * @@ -1153,9 +1127,6 @@ attr_in_claims_request (struct RequestHandle *handle, const char *attr_name, const char *claims_parameter) { - char *scope_variables; - char *scope_variable; - char delimiter[] = " "; int ret = GNUNET_NO; json_t *root; json_error_t error; @@ -1163,19 +1134,12 @@ attr_in_claims_request (struct RequestHandle *handle, const char *key; json_t *value; - scope_variables = GNUNET_strdup (handle->oidc->scope); - scope_variable = strtok (scope_variables, delimiter); - while (NULL != scope_variable) - { - if (0 == strcmp (attr_name, scope_variable)) - break; - scope_variable = strtok (NULL, delimiter); - } - if (NULL != scope_variable) - ret = GNUNET_YES; - GNUNET_free (scope_variables); + /** Check if attribute is requested through standard scope **/ + if (GNUNET_YES == OIDC_check_scopes_for_claim_request (handle->oidc->scope, + attr_name)) + return GNUNET_YES; - /** Try claims parameter if no in scope */ + /** Try claims parameter if not in scope */ if ((NULL != handle->oidc->claims) && (GNUNET_YES != ret)) { @@ -2122,13 +2086,13 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - id_token = OIDC_id_token_new (&ticket.audience, - &ticket.identity, - cl, - al, - &expiration_time, - (NULL != nonce) ? nonce : NULL, - jwt_secret); + id_token = OIDC_generate_id_token (&ticket.audience, + &ticket.identity, + cl, + al, + &expiration_time, + (NULL != nonce) ? nonce : NULL, + jwt_secret); access_token = OIDC_access_token_new (&ticket); OIDC_build_token_response (access_token, id_token, @@ -2159,83 +2123,55 @@ consume_ticket (void *cls, const struct GNUNET_RECLAIM_Attestation *attest) { struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_AttributeListEntry *ale; + struct GNUNET_RECLAIM_AttestationListEntry *atle; + struct MHD_Response *resp; + char *result_str; handle->idp_op = NULL; if (NULL == identity) { - GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); + result_str = OIDC_generate_userinfo (&handle->ticket.identity, + handle->attr_userinfo_list, + handle->attests_list); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); + resp = GNUNET_REST_create_response (result_str); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (result_str); + cleanup_handle (handle); return; } - if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->attestation)) + ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry); + ale->attribute = GNUNET_RECLAIM_attribute_new (attr->name, + &attr->attestation, + attr->type, + attr->data, + attr->data_size); + ale->attribute->id = attr->id; + ale->attribute->flag = attr->flag; + ale->attribute->attestation = attr->attestation; + GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head, + handle->attr_userinfo_list->list_tail, + ale); + for (atle = handle->attests_list->list_head; NULL != atle; atle = atle->next) + { + if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->attestation->id, + &attest->id)) + continue; + break; /** already in list **/ + } + if (NULL == atle) { - char *tmp_value; - json_t *value; - tmp_value = GNUNET_RECLAIM_attribute_value_to_string (attr->type, - attr->data, - attr->data_size); - value = json_string (tmp_value); - json_object_set_new (handle->oidc->response, attr->name, value); - GNUNET_free (tmp_value); - return; + /** Attestation matches for attribute, add **/ + atle = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry); + atle->attestation = GNUNET_RECLAIM_attestation_new (attest->name, + attest->type, + attest->data, + attest->data_size); + GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head, + handle->attests_list->list_tail, + atle); } - json_t *claim_sources; - json_t *claim_sources_jwt; - json_t *claim_names; - char *attest_val_str; - claim_sources = json_object_get (handle->oidc->response,"_claim_sources"); - claim_names = json_object_get (handle->oidc->response,"_claim_names"); - attest_val_str = - GNUNET_RECLAIM_attestation_value_to_string (attest->type, - attest->data, - attest->data_size); - if ((NULL == claim_sources) && (NULL == claim_names) ) - { - claim_sources = json_object (); - claim_names = json_object (); - } - char *source_name; - int i = 0; - GNUNET_asprintf (&source_name, "src%d", i); - while (NULL != (claim_sources_jwt = json_object_get (claim_sources, - source_name))) - { - if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt, - "JWT")), - attest_val_str)) - { - // Adapt only the claim names - json_object_set_new (claim_names, attr->data, - json_string (source_name)); - json_object_set (handle->oidc->response, - "_claim_names", claim_names); - break; - } - i++; - GNUNET_free (source_name); - GNUNET_asprintf (&source_name, "src%d", i); - } - - // Create new one - if (NULL == claim_sources_jwt) - { - claim_sources_jwt = json_object (); - // Set the JWT for names - json_object_set_new (claim_names, attr->data, - json_string (source_name)); - // Set the JWT for the inner source - json_object_set_new (claim_sources_jwt, "JWT", - json_string (attest_val_str)); - // Set the JWT for the source - json_object_set_new (claim_sources, source_name, claim_sources_jwt); - // Set as claims - json_object_set (handle->oidc->response, "_claim_names", claim_names); - json_object_set (handle->oidc->response, "_claim_sources",claim_sources); - } - - json_decref (claim_sources); - json_decref (claim_names); - json_decref (claim_sources_jwt); - GNUNET_free (attest_val_str); } @@ -2253,14 +2189,13 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, { // TODO expiration time struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_Ticket *ticket; char delimiter[] = " "; struct GNUNET_HashCode cache_key; char *authorization; char *authorization_type; char *authorization_access_token; - struct GNUNET_RECLAIM_Ticket *ticket; const struct EgoEntry *aud_ego; - const struct EgoEntry *iss_ego; const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, @@ -2316,9 +2251,10 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } GNUNET_assert (NULL != ticket); - aud_ego = find_ego (handle, &ticket->audience); - iss_ego = find_ego (handle, &ticket->identity); - if ((NULL == aud_ego) || (NULL == iss_ego)) + handle->ticket = *ticket; + GNUNET_free (ticket); + aud_ego = find_ego (handle, &handle->ticket.audience); + if (NULL == aud_ego) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); handle->edesc = GNUNET_strdup ("The access token expired"); @@ -2328,16 +2264,16 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, return; } - handle->oidc->response = json_object (); - json_object_set_new (handle->oidc->response, - "sub", - json_string (iss_ego->keystring)); privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); + handle->attr_userinfo_list = + GNUNET_new (struct GNUNET_RECLAIM_AttributeList); + handle->attests_list = + GNUNET_new (struct GNUNET_RECLAIM_AttestationList); handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, privkey, - ticket, - consume_ticket, + &handle->ticket, + &consume_ticket, handle); GNUNET_free (authorization); } @@ -2535,6 +2471,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, cleanup_handle (handle); } + /** * Respond to OPTIONS request * @@ -2544,8 +2481,8 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, */ static void oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, - const char *url, - void *cls) + const char *url, + void *cls) { struct MHD_Response *resp; struct RequestHandle *handle = cls; @@ -2560,7 +2497,6 @@ oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, } - static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, -- cgit v1.2.3