challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit 9dbfd462d51e0369d0c1ff09675eb411c8fe9280
parent 3be28f75159fe713ee9313db5c6cba4aa80a2618
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon, 13 Jul 2026 20:57:06 +0200

handle serialization issues

Diffstat:
Msrc/challenger/challenger-httpd_token.c | 171+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 103 insertions(+), 68 deletions(-)

diff --git a/src/challenger/challenger-httpd_token.c b/src/challenger/challenger-httpd_token.c @@ -31,6 +31,7 @@ #include "challenger-database/client_check.h" #include "challenger-database/token_add_token.h" +#define MAX_RETRIES 3 /** * Compare two NUL-terminated strings @a a and @a b in constant time @@ -346,33 +347,44 @@ CH_handler_token (struct CH_HandlerContext *hc, "client_id"); } - qs = CHALLENGERDB_client_check (CH_context, - client_id, - bc->client_secret, - 0, /* do not increment */ - &client_url); - switch (qs) + for (unsigned int r = 0; r < MAX_RETRIES; r++) + { + qs = CHALLENGERDB_client_check (CH_context, + client_id, + bc->client_secret, + 0, /* do not increment */ + &client_url); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "client_check"); + case GNUNET_DB_STATUS_SOFT_ERROR: + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break_op (0); + return CH_reply_with_oauth_error ( + hc->connection, + MHD_HTTP_UNAUTHORIZED, + "invalid_client", + TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN, + NULL); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { - case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); return TALER_MHD_reply_with_error ( hc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, + TALER_EC_GENERIC_DB_SOFT_FAILURE, "client_check"); - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return MHD_NO; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break_op (0); - return CH_reply_with_oauth_error ( - hc->connection, - MHD_HTTP_UNAUTHORIZED, - "invalid_client", - TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN, - NULL); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; } if ( (NULL != client_url) && (0 != strcmp (client_url, @@ -424,38 +436,49 @@ CH_handler_token (struct CH_HandlerContext *hc, "%llu%c", &code_client_id, &code_dummy)); - qs = CHALLENGERDB_validation_get_pkce (CH_context, - &bc->nonce, - (uint64_t) code_client_id, - &client_secret, - &address, - &client_scope, - &client_state, - &client_redirect_uri, - &code_challenge, - &code_challenge_method); - switch (qs) + for (unsigned int r = 0; r < MAX_RETRIES; r++) + { + qs = CHALLENGERDB_validation_get_pkce (CH_context, + &bc->nonce, + (uint64_t) code_client_id, + &client_secret, + &address, + &client_scope, + &client_state, + &client_redirect_uri, + &code_challenge, + &code_challenge_method); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "validation_get_pkce"); + case GNUNET_DB_STATUS_SOFT_ERROR: + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break_op (0); + return CH_reply_with_oauth_error ( + hc->connection, + MHD_HTTP_UNAUTHORIZED, + "invalid_grant", + TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN, + "validation_get_pkce"); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { - case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); return TALER_MHD_reply_with_error ( hc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, + TALER_EC_GENERIC_DB_SOFT_FAILURE, "validation_get_pkce"); - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return MHD_NO; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break_op (0); - return CH_reply_with_oauth_error ( - hc->connection, - MHD_HTTP_UNAUTHORIZED, - "invalid_grant", - TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN, - "validation_get_pkce"); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; } code_challenge_method_enum = CHALLENGER_cm_from_int ( @@ -710,35 +733,47 @@ CH_handler_token (struct CH_HandlerContext *hc, GNUNET_CRYPTO_random_block (&token, sizeof (token)); - qs = CHALLENGERDB_token_add_token (CH_context, - &bc->nonce, - &token, - CH_token_expiration, - CH_validation_expiration); - switch (qs) + for (unsigned int r = 0; r < MAX_RETRIES; r++) + { + qs = CHALLENGERDB_token_add_token (CH_context, + &bc->nonce, + &token, + CH_token_expiration, + CH_validation_expiration); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "token_add_token"); + case GNUNET_DB_STATUS_SOFT_ERROR: + continue; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); + return CH_reply_with_oauth_error ( + hc->connection, + MHD_HTTP_UNAUTHORIZED, + "invalid_grant", + TALER_EC_CHALLENGER_GRANT_UNKNOWN, + "token_add_token"); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { - case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); return TALER_MHD_reply_with_error ( hc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, + TALER_EC_GENERIC_DB_SOFT_FAILURE, "token_add_token"); - case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return MHD_NO; - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break (0); - return CH_reply_with_oauth_error ( - hc->connection, - MHD_HTTP_UNAUTHORIZED, - "invalid_grant", - TALER_EC_CHALLENGER_GRANT_UNKNOWN, - "token_add_token"); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; } + return TALER_MHD_REPLY_JSON_PACK ( hc->connection, MHD_HTTP_OK,