challenger

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

commit cb8c3b9ebc63ee3acc030ca4cac2e692323ba9f9
parent 56e0ccafe17796c8582631650e3082febf5860fa
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  7 May 2023 01:21:13 +0200

-misc bugfixes

Diffstat:
Mcontrib/enter-tan-form.must | 2+-
Msrc/challenger/cat.sh | 3++-
Msrc/challenger/challenger-httpd.c | 22+++++++++++-----------
Msrc/challenger/challenger-httpd_challenge.c | 29++++++++++++++++++++++-------
Msrc/challenger/challenger-httpd_common.c | 4++--
Msrc/challenger/challenger-httpd_info.c | 1-
Msrc/challenger/test-challenger.sh | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/challengerdb/challenger-0001.sql | 4++--
Msrc/challengerdb/pg_auth_add_grant.c | 4+++-
Msrc/challengerdb/pg_challenge_set_address_and_pin.c | 61+++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/challengerdb/pg_challenge_set_address_and_pin.h | 4++--
Msrc/challengerdb/pg_info_get_grant.c | 8++++----
Msrc/challengerdb/pg_validate_solve_pin.c | 12++++++------
Msrc/include/challenger_database_plugin.h | 4++--
14 files changed, 177 insertions(+), 78 deletions(-)

diff --git a/contrib/enter-tan-form.must b/contrib/enter-tan-form.must @@ -5,7 +5,7 @@ <body> {{#transmitted}} A TAN was sent to your address &quot;{{address}}&quot;. - {{transmitted}} + {{/transmitted}} {{^transmitted}} We recently already sent a TAN to your address &quot;{{address}}&quot;. A new TAN will not be transmitted again before {{next_tx_time}}. diff --git a/src/challenger/cat.sh b/src/challenger/cat.sh @@ -1,3 +1,4 @@ -#!/bin/sh +#!/bin/bash # This file is in the public domain. cat - > "$1" +exit 0 diff --git a/src/challenger/challenger-httpd.c b/src/challenger/challenger-httpd.c @@ -210,7 +210,7 @@ url_handler (void *cls, NULL, NULL, NULL } }; - struct CH_HandlerContext *hc; + struct CH_HandlerContext *hc = *con_cls; (void) cls; (void) version; @@ -218,13 +218,13 @@ url_handler (void *cls, "Handling %s request for `%s'\n", method, url); - hc = *con_cls; if (NULL == hc) { const char *correlation_id; bool found = false; hc = GNUNET_new (struct CH_HandlerContext); + *con_cls = hc; hc->connection = connection; GNUNET_async_scope_fresh (&hc->async_scope_id); GNUNET_SCHEDULER_begin_async_scope (&hc->async_scope_id); @@ -317,6 +317,8 @@ static void do_shutdown (void *cls) { (void) cls; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Stopping challenger-httpd\n"); CH_wakeup_challenge_on_shutdown (); if (NULL != mhd_task) { @@ -530,6 +532,7 @@ run (void *cls, go = TALER_MHD_GO_NONE; if (CH_challenger_connection_close) go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE; + TALER_MHD_setup (go); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (config, @@ -565,10 +568,10 @@ run (void *cls, return; } if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (config, - "CHALLENGER", - "ADDRESS_TYPE", - &CH_address_type)) + GNUNET_CONFIGURATION_get_value_string (config, + "CHALLENGER", + "ADDRESS_TYPE", + &CH_address_type)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "CHALLENGER", @@ -576,14 +579,9 @@ run (void *cls, return; } - TALER_MHD_setup (go); result = EXIT_NOTCONFIGURED; GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("challenger-httpd", - "WARNING", - NULL)); /* setup HTTP client event loop */ CH_ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, &rc); @@ -633,6 +631,8 @@ run (void *cls, } result = EXIT_SUCCESS; mhd_task = prepare_daemon (); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Challenger-httpd ready\n"); } diff --git a/src/challenger/challenger-httpd_challenge.c b/src/challenger/challenger-httpd_challenge.c @@ -207,6 +207,7 @@ child_done_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Child done\n"); + GNUNET_OS_process_destroy (bc->child); bc->child = NULL; bc->cwh = NULL; bc->pst = type; @@ -239,7 +240,7 @@ send_tan (struct ChallengeContext *bc) GNUNET_break (0); mres = TALER_TEMPLATING_reply_error (bc->hc->connection, "internal-error", - MHD_HTTP_NOT_FOUND, + MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_CHALLENGER_HELPER_EXEC_FAILED, "pipe"); bc->status = (MHD_YES == mres) @@ -247,6 +248,10 @@ send_tan (struct ChallengeContext *bc) : GNUNET_SYSERR; return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Running auth command `%s' on address `%s'\n", + CH_auth_command, + bc->address); bc->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, p, NULL, @@ -263,7 +268,7 @@ send_tan (struct ChallengeContext *bc) GNUNET_DISK_pipe_close (p); mres = TALER_TEMPLATING_reply_error (bc->hc->connection, "internal-error", - MHD_HTTP_NOT_FOUND, + MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_CHALLENGER_HELPER_EXEC_FAILED, "exec"); bc->status = (MHD_YES == mres) @@ -299,9 +304,10 @@ send_tan (struct ChallengeContext *bc) GNUNET_break (0); mres = TALER_TEMPLATING_reply_error (bc->hc->connection, "internal-error", - MHD_HTTP_NOT_FOUND, + MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_CHALLENGER_HELPER_EXEC_FAILED, "write"); + GNUNET_free (msg); bc->status = (MHD_YES == mres) ? GNUNET_NO : GNUNET_SYSERR; @@ -312,6 +318,7 @@ send_tan (struct ChallengeContext *bc) } GNUNET_DISK_file_close (pipe_stdin); } + GNUNET_free (msg); bc->cwh = GNUNET_wait_child (bc->child, &child_done_cb, bc); @@ -380,9 +387,6 @@ CH_handler_challenge (struct CH_HandlerContext *hc, { struct ChallengeContext *bc = hc->ctx; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Got /challenge request\n"); - if (NULL == bc) { /* first call, setup internals */ @@ -414,11 +418,18 @@ CH_handler_challenge (struct CH_HandlerContext *hc, } TALER_MHD_check_content_length (hc->connection, 1024); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Awaiting /challenge upload (%u)...\n", + (unsigned int) *upload_data_size); return MHD_YES; } GNUNET_assert (GNUNET_YES != bc->suspended); if (GNUNET_SYSERR == bc->suspended) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "/challenge ends in shutdown\n"); return MHD_NO; + } /* Handle case where helper process failed */ if ( ( (GNUNET_OS_PROCESS_UNKNOWN != bc->pst) && (GNUNET_OS_PROCESS_EXITED != bc->pst) ) || @@ -433,7 +444,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc, bc->pst); return TALER_TEMPLATING_reply_error (hc->connection, "internal-error", - MHD_HTTP_NOT_FOUND, + MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_CHALLENGER_HELPER_EXEC_FAILED, es); } @@ -442,6 +453,8 @@ CH_handler_challenge (struct CH_HandlerContext *hc, { enum MHD_Result res; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Processing /challenge upload...\n"); res = MHD_post_process (bc->pp, upload_data, *upload_data_size); @@ -489,6 +502,8 @@ CH_handler_challenge (struct CH_HandlerContext *hc, bc->db_finished = true; if (0 == bc->pin_attempts_left) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Attempts exhausted for this PIN\n"); return TALER_TEMPLATING_reply_error (hc->connection, "attempts-exhausted", MHD_HTTP_TOO_MANY_REQUESTS, diff --git a/src/challenger/challenger-httpd_common.c b/src/challenger/challenger-httpd_common.c @@ -82,8 +82,8 @@ CH_compute_code (const struct CHALLENGER_ValidationNonceP *nonce, strlen (client_redirect_url), NULL, 0)); - ns = GNUNET_STRINGS_data_to_string_alloc (&nonce, - sizeof (nonce)); + ns = GNUNET_STRINGS_data_to_string_alloc (nonce, + sizeof (*nonce)); hs = GNUNET_STRINGS_data_to_string_alloc (&h, sizeof (h)); GNUNET_asprintf (&code, diff --git a/src/challenger/challenger-httpd_info.c b/src/challenger/challenger-httpd_info.c @@ -98,7 +98,6 @@ CH_handler_info (struct CH_HandlerContext *hc, GNUNET_break (0); return GNUNET_NO; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break (0); return TALER_MHD_reply_with_error (hc->connection, MHD_HTTP_NOT_FOUND, TALER_EC_CHALLENGER_GRANT_UNKNOWN, diff --git a/src/challenger/test-challenger.sh b/src/challenger/test-challenger.sh @@ -11,14 +11,14 @@ function exit_skip() { # Exit, with error message (hard failure) function exit_fail() { - echo " FAIL: $1" + echo " FAIL: $@" exit 1 } # Cleanup to run whenever we exit function cleanup() { - for n in `jobs -p` + for n in $(jobs -p) do kill $n 2> /dev/null || true done @@ -26,7 +26,7 @@ function cleanup() wait } -LAST_RESPONSE=`mktemp responseXXXXXX.log` +LAST_RESPONSE=$(mktemp responseXXXXXX.log) FILENAME="test-challenger.txt" # Install cleanup handler (except for kill -9) @@ -61,10 +61,10 @@ echo " OK" CLIENT_ID=1 echo -n "Start challenger-httpd ..." -challenger-httpd -L INFO -c "${CONF}" &> httpd.log & +valgrind --leak-check=yes challenger-httpd -L INFO -c "${CONF}" &> httpd.log & # Wait for challenger to be available -for n in `seq 1 50` +for n in $(seq 1 50) do echo -n "." sleep 0.2 @@ -88,8 +88,7 @@ STATUS=$(curl "${BURL}/setup/${CLIENT_ID}" \ if [ "$STATUS" != "200" ] then - echo "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` - exit 1 + exit_fail "Expected 200 OK. Got: $STATUS" $(cat $LAST_RESPONSE) fi NONCE=`jq -r .nonce < "$LAST_RESPONSE"` echo " OK" @@ -109,7 +108,7 @@ STATUS=$(curl "${BURL}/login/${NONCE}" \ if [ "$STATUS" != "200" ] then - echo "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` + exit_fail "Expected 200 OK. Got: $STATUS" $(cat $LAST_RESPONSE) exit 1 fi echo "OK" @@ -123,22 +122,84 @@ STATUS=$(curl "${BURL}/challenge/${NONCE}" \ if [ "$STATUS" != "200" ] then - echo "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` - exit 1 + exit_fail "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` fi echo "OK" +PIN=$(cat ${FILENAME} | awk '{print $2}') +echo -n "Initiating PIN ${PIN} submission..." +RESULT=$(curl "${BURL}/solve/${NONCE}" \ + -X POST \ + --data-urlencode "pin=${PIN}" \ + -w "%{http_code} %{redirect_url}" -s -o $LAST_RESPONSE) +STATUS=$(echo "$RESULT" | awk '{print $1}') +TARGET=$(echo "$RESULT" | awk '{print $2}') +if [ "$STATUS" != "302" ] +then + exit_fail "Expected 302. Got: $STATUS" `cat $LAST_RESPONSE` +fi -exit 0 +TURL=$(echo "$TARGET" | sed -e "s/?.*//g") +TCODE=$(echo "$TARGET" | sed -e "s/.*?code=//g" -e "s/&.*//g") +TSTATE=$(echo "$TARGET" | sed -e "s/.*&state=//g") -# Archived for later... -echo -n "Initiating user login..." -STATUS=$(curl "${BURL}/login/${NONCE}?response_type=code&client_id=${CLIENT_ID}" \ - --data-urlencode "response_type=code" \ +if [ "${TURL}" != "${REDIRECT_URI}" ] +then + exit_fail "Invalid redirect URI ${TURL} returned, wanted ${REDIRECT_URI}" +fi +if [ "${TSTATE}" != "${CLIENT_STATE}" ] +then + exit_fail "Invalid client state ${TSTATE} returned, wanted ${CLIENT_STATE}" +fi +echo "OK" + +echo -n "Requesting authorization for client ..." +STATUS=$(curl "${BURL}/auth" \ + -X POST \ --data-urlencode "client_id=${CLIENT_ID}" \ --data-urlencode "redirect_uri=${REDIRECT_URI}" \ - --data-urlencode "state=${CLIENT_STATE}" \ - --data-urlencode "scope=${CLIENT_SCOPE}" \ - -w "%{http_code}" -o $LAST_RESPONSE) + --data-urlencode "client_secret=${CLIENT_SECRET}" \ + --data-urlencode "code=${TCODE}" \ + --data-urlencode "grant_type=authorization_code" \ + -w "%{http_code}" -s -o $LAST_RESPONSE) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` +fi +TOKEN_TYPE=`cat $LAST_RESPONSE | jq -r .token_type` +if [ "$TOKEN_TYPE" != "Bearer" ] +then + exit_fail "Expected Bearer token. Got: $TOKEN_TYPE" +fi +ACCESS_TOKEN=`cat $LAST_RESPONSE | jq -r .access_token` +EXPIRES_IN=`cat $LAST_RESPONSE | jq -r .expires_in` +echo "OK" + +echo -n "Requesting user information for client ..." +STATUS=$(curl "${BURL}/info" \ + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ + -w "%{http_code}" -s -o $LAST_RESPONSE) +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" `cat $LAST_RESPONSE` +fi + +TADDRESS=`cat $LAST_RESPONSE | jq -r .address` +TADDRESS_TYPE=`cat $LAST_RESPONSE | jq -r .address_type` + +if [ "$TADDRESS" != "$FILENAME" ] +then + exit_fail "Expected $FILENAME. Got: $TADDRESS" +fi + +if [ "$TADDRESS_TYPE" != "file-access" ] +then + exit_fail "Expected file-access. Got: $TADDRESS_TYPE" +fi +echo "OK" + + +exit 0 diff --git a/src/challengerdb/challenger-0001.sql b/src/challengerdb/challenger-0001.sql @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS validations ,last_tx_time INT8 NOT NULL DEFAULT (0) ,address_attempts_left INT4 DEFAULT(3) ,last_pin INT4 - ,pin_attempts_left INT4 DEFAULT(0) + ,pin_transmissions_left INT4 DEFAULT(0) ,auth_attempts_left INT4 DEFAULT(0) ,address VARCHAR ,client_scope VARCHAR @@ -79,7 +79,7 @@ COMMENT ON COLUMN validations.last_pin IS 'Last PIN code send to the user'; COMMENT ON COLUMN validations.address_attempts_left IS 'How many more address changes is the user allowed to make (guard against DoS and brute-forcing)'; -COMMENT ON COLUMN validations.pin_attempts_left +COMMENT ON COLUMN validations.pin_transmissions_left IS 'How many more PIN transmission attempts do we permit (guard against DoS and brute-forcing)'; COMMENT ON COLUMN validations.auth_attempts_left IS 'How many more authentication attempts do we permit (guard against brute-forcing)'; diff --git a/src/challengerdb/pg_auth_add_grant.c b/src/challengerdb/pg_auth_add_grant.c @@ -35,10 +35,12 @@ CH_PG_auth_add_grant ( struct GNUNET_TIME_Relative address_expiration) { struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute ge + = GNUNET_TIME_relative_to_absolute (grant_expiration); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (nonce), GNUNET_PQ_query_param_auto_from_type (grant), - GNUNET_PQ_query_param_relative_time (&grant_expiration), + GNUNET_PQ_query_param_absolute_time (&ge), GNUNET_PQ_query_param_relative_time (&address_expiration), GNUNET_PQ_query_param_end }; diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.c b/src/challengerdb/pg_challenge_set_address_and_pin.c @@ -34,7 +34,7 @@ CH_PG_challenge_set_address_and_pin ( struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, - uint32_t *pin_attempts_left, + uint32_t *auth_attempts_left, bool *pin_transmit) { struct PostgresClosure *pg = cls; @@ -58,8 +58,8 @@ CH_PG_challenge_set_address_and_pin ( tan), GNUNET_PQ_result_spec_bool ("pin_transmit", pin_transmit), - GNUNET_PQ_result_spec_uint32 ("pin_attempts_left", - pin_attempts_left), + GNUNET_PQ_result_spec_uint32 ("auth_attempts_left", + auth_attempts_left), GNUNET_PQ_result_spec_end }; @@ -67,46 +67,67 @@ CH_PG_challenge_set_address_and_pin ( "challenge_set_address_and_pin", "WITH decisions AS (" " SELECT " - " ,(address != $2) AND" + " ( (address IS NULL) OR" + " (address != $2) ) AND" " (address_attempts_left > 0)" " AS addr_changed" - " ,(pin_transmissions_left > 0) AND" - " ( (address != $2) OR" - " (last_tx_time < $3) ) AS send_pin" + " ,( (pin_transmissions_left > 0) OR" + " (address_attempts_left > 0) ) AND" + " ( (address IS NULL) OR" + " (address != $2) OR" + " (last_tx_time < $3) ) AS send_pin" " FROM validations" " WHERE nonce=$1" - ")" + ")," + "result AS (" "UPDATE validations SET" " address_attempts_left=CASE" - " WHEN decisions.addr_changed" + " WHEN (SELECT addr_changed FROM decisions)" " THEN address_attempts_left - 1 " " ELSE address_attempts_left " - " END " - ",last_pin = CASE " - " WHEN decisions.addr_changed" + " END" + " ,last_pin = CASE " + " WHEN (SELECT addr_changed FROM decisions)" " THEN $5" " ELSE last_pin" - " ,END" + " END" " ,pin_transmissions_left=CASE" - " WHEN decisions.addr_changed" + " WHEN (SELECT addr_changed FROM decisions)" " THEN 3 " - " ELSE WHEN decisions.send_pin" + " ELSE CASE" + " WHEN (SELECT send_pin FROM decisions)" " THEN pin_transmissions_left - 1" " ELSE pin_transmissions_left" " END" - " ,END" + " END" + " ,auth_attempts_left=CASE" + " WHEN (SELECT addr_changed FROM decisions)" + " THEN 3 " + " ELSE auth_attempts_left" + " END" " ,last_tx_time=CASE" - " WHEN decisions.send_pin" + " WHEN (SELECT send_pin FROM decisions)" " THEN $4" " ELSE last_tx_time" " END" - " ,address=$2" + " ,address=CASE" + " WHEN (SELECT addr_changed FROM decisions)" + " THEN $2" + " ELSE address" + " END" " WHERE nonce=$1" " RETURNING" " last_tx_time" - " ,decisions.send_pin AS pin_transmit" " ,last_pin" - " ,pin_attempts_left;"); + " ,auth_attempts_left" + ")" + " SELECT" + " last_tx_time" + " ,decisions.send_pin AS pin_transmit" + " ,last_pin" + " ,auth_attempts_left" + " FROM result" + " FULL OUTER JOIN decisions ON (TRUE);"); return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "challenge_set_address_and_pin", params, diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.h b/src/challengerdb/pg_challenge_set_address_and_pin.h @@ -39,7 +39,7 @@ * @param[in,out] tan set to the PIN/TAN last send to @a address, input should be random PIN/TAN to use if address did not change * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a address, input should be current time to use if the existing value for tx_time is past @a next_tx_time * @param[out] pin_transmit set to true if we should transmit the @a last_pin to the @a address - * @param[out] pin_attempts_left set to number of attempts the user has left on this pin + * @param[out] auth_attempts_left set to number of attempts the user has left on this pin * @return transaction status: * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the address was changed * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not permit further changes to the address (attempts exhausted) @@ -53,7 +53,7 @@ CH_PG_challenge_set_address_and_pin ( struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, - uint32_t *pin_attempts_left, + uint32_t *auth_attempts_left, bool *pin_transmit); diff --git a/src/challengerdb/pg_info_get_grant.c b/src/challengerdb/pg_info_get_grant.c @@ -45,7 +45,7 @@ CH_PG_info_get_grant ( struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_string ("address", address), - GNUNET_PQ_result_spec_absolute_time ("address_expiration_timestamp", + GNUNET_PQ_result_spec_absolute_time ("address_expiration_time", &at), GNUNET_PQ_result_spec_end }; @@ -55,12 +55,12 @@ CH_PG_info_get_grant ( "info_get_grant", "SELECT " " address" - " ,address_expiration_timestamp" + " ,address_expiration_time" " FROM grants" " WHERE access_token=$1" - " AND grant_expiration_time>=$2"); + " AND grant_expiration_time > $2"); qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "validation_get", + "info_get_grant", params, rs); if (qs > 0) diff --git a/src/challengerdb/pg_validate_solve_pin.c b/src/challengerdb/pg_validate_solve_pin.c @@ -51,24 +51,24 @@ CH_PG_validate_solve_pin (void *cls, "validate_solve_pin", "UPDATE validations SET" " auth_attempts_left=CASE" - " WHEN last_pin == $2" + " WHEN last_pin = $2" " THEN 0" " ELSE auth_attempts_left - 1" " END" " ,address_attempts_left=CASE" - " WHEN last_pin == $2" + " WHEN last_pin = $2" " THEN 0" " ELSE address_attempts_left" " END" - " ,pin_attempts_left=CASE" - " WHEN last_pin == $2" + " ,pin_transmissions_left=CASE" + " WHEN last_pin = $2" " THEN 0" - " ELSE pin_attempts_left" + " ELSE pin_transmissions_left" " END" " WHERE nonce=$1" " AND auth_attempts_left > 0" " RETURNING" - " (last_pin == $2) AS solved;"); + " (last_pin = $2) AS solved;"); return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "validate_solve_pin", params, diff --git a/src/include/challenger_database_plugin.h b/src/include/challenger_database_plugin.h @@ -260,7 +260,7 @@ struct CHALLENGER_DatabasePlugin * @param[in,out] tan set to the PIN/TAN last send to @a address, input should be random PIN/TAN to use if address did not change * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a address, input should be current time to use if the existing value for tx_time is past @a next_tx_time * @param[out] pin_transmit set to true if we should transmit the @a last_pin to the @a address - * @param[out] pin_attempts_left set to number of attempts the user has left on this pin + * @param[out] auth_attempts_left set to number of attempts the user has left on this pin * @return transaction status: * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the address was changed * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not permit further changes to the address (attempts exhausted) @@ -274,7 +274,7 @@ struct CHALLENGER_DatabasePlugin struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, - uint32_t *pin_attempts_left, + uint32_t *auth_attempts_left, bool *pin_transmit);