commit 9dbfd462d51e0369d0c1ff09675eb411c8fe9280
parent 3be28f75159fe713ee9313db5c6cba4aa80a2618
Author: Christian Grothoff <grothoff@gnunet.org>
Date: Mon, 13 Jul 2026 20:57:06 +0200
handle serialization issues
Diffstat:
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,