challenger

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

commit c27d8132dac61656b399b0882e4f0a2b8b2cccfc
parent 4308863d8255d66cc635de39d1d6828fddbe794f
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 11 Aug 2026 14:02:52 +0200

fix #11107

Diffstat:
Msrc/challenger/cat-once.sh | 7++++++-
Msrc/challenger/challenger-httpd_challenge.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/src/challenger/cat-once.sh b/src/challenger/cat-once.sh @@ -4,10 +4,15 @@ # Like cat.sh, but only for the first challenge: every later invocation # fails without delivering anything, simulating an SMS/e-mail gateway # that went down between two TAN transmissions. +# +# Exit 30 ("provider outage or internal error", see challenger-send-sms(1)) +# is what a real helper reports for that. Note that exit 1 would NOT work: +# under the helper exit-code scheme anything below 10 means the TAN was +# transmitted, and 1 specifically means "accepted, delivery not confirmed". TARGET="$(echo $1 | jq -r ".filename")" if [ -e "${TARGET}.sent" ] then - exit 1 + exit 30 fi touch "${TARGET}.sent" cat - > "${TARGET}" diff --git a/src/challenger/challenger-httpd_challenge.c b/src/challenger/challenger-httpd_challenge.c @@ -305,6 +305,55 @@ reply_error (struct ChallengeContext *bc, /** + * Map the exit status of a TAN transmission helper onto an HTTP status and + * error code. + * + * The helpers use a banded exit-code scheme documented in + * challenger-send-sms(1): anything below 10 means the TAN was transmitted (0 + * confirmed on the handset, 1 accepted by the provider, 2 suppressed as a + * duplicate of a message already in flight), 10-19 blames the address the user + * gave us, 20-29 is a recipient that is temporarily unreachable, 30-39 is the + * transmission provider and 40-49 is our own configuration. + * + * Codes we do not recognise are reported as an upstream failure rather than + * blamed on the user, so that a helper predating this scheme -- which used + * small ad-hoc exit codes -- never yields a 400. + * + * @param exit_code exit status of the helper, which must have exited normally + * @param[out] http_status set to the HTTP status to return + * @return error code to return, #TALER_EC_NONE if the TAN was transmitted + */ +static enum TALER_ErrorCode +classify_helper_status (unsigned long int exit_code, + unsigned int *http_status) +{ + if (exit_code < 10) + { + *http_status = MHD_HTTP_OK; + return TALER_EC_NONE; + } + if (exit_code < 20) + { + *http_status = MHD_HTTP_BAD_REQUEST; + return TALER_EC_CHALLENGER_ADDRESS_UNUSABLE; + } + if (exit_code < 30) + { + *http_status = MHD_HTTP_SERVICE_UNAVAILABLE; + return TALER_EC_CHALLENGER_ADDRESS_UNREACHABLE; + } + if ( (exit_code >= 40) && + (exit_code < 50) ) + { + *http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; + return TALER_EC_CHALLENGER_HELPER_MISCONFIGURED; + } + *http_status = MHD_HTTP_BAD_GATEWAY; + return TALER_EC_CHALLENGER_HELPER_EXEC_FAILED; +} + + +/** * Function called when our TAN transmission helper has terminated. * * @param cls our `struct ChallengeContext *` @@ -834,11 +883,24 @@ CH_handler_challenge (struct CH_HandlerContext *hc, if ( (GNUNET_OS_PROCESS_UNKNOWN != bc->pst) && (NULL == bc->child) && ( (GNUNET_OS_PROCESS_EXITED != bc->pst) || - (0 != bc->exit_code) ) ) + (bc->exit_code >= 10) ) ) { char es[32]; + unsigned int http_status; + enum TALER_ErrorCode ec; - GNUNET_break (0); + if (GNUNET_OS_PROCESS_EXITED != bc->pst) + { + /* Killed by a signal or otherwise abnormal: there is no exit code to + classify. */ + http_status = MHD_HTTP_BAD_GATEWAY; + ec = TALER_EC_CHALLENGER_HELPER_EXEC_FAILED; + } + else + { + ec = classify_helper_status (bc->exit_code, + &http_status); + } GNUNET_snprintf (es, sizeof (es), "%u/%d", @@ -850,8 +912,8 @@ CH_handler_challenge (struct CH_HandlerContext *hc, (int) bc->exit_code); return TALER_MHD_reply_with_error ( hc->connection, - MHD_HTTP_BAD_GATEWAY, - TALER_EC_CHALLENGER_HELPER_EXEC_FAILED, + http_status, + ec, es); } /* handle upload */