[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-challenger] 02/02: preparations for #8405
From: |
gnunet |
Subject: |
[taler-challenger] 02/02: preparations for #8405 |
Date: |
Wed, 14 Feb 2024 20:55:03 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository challenger.
commit 713758141eeb9d0d26fafd8eb59a73167d98f706
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Feb 14 20:54:57 2024 +0100
preparations for #8405
---
src/challenger/challenger-httpd_solve.c | 92 +++++++++++++++++++++++++-------
src/challengerdb/pg_validate_solve_pin.c | 68 +++++++++++++----------
src/challengerdb/pg_validate_solve_pin.h | 17 ++++--
src/challengerdb/procedures.sql.in | 1 +
src/include/challenger_database_plugin.h | 10 +++-
5 files changed, 136 insertions(+), 52 deletions(-)
diff --git a/src/challenger/challenger-httpd_solve.c
b/src/challenger/challenger-httpd_solve.c
index 19a44a0..54017b1 100644
--- a/src/challenger/challenger-httpd_solve.c
+++ b/src/challenger/challenger-httpd_solve.c
@@ -45,6 +45,11 @@ struct SolveContext
*/
struct MHD_PostProcessor *pp;
+ /**
+ * OAuth2 client redirection URI for error reporting.
+ */
+ char *client_redirect_uri;
+
/**
* 0-terminated PIN submitted to us.
*/
@@ -54,6 +59,22 @@ struct SolveContext
* Number of bytes in @a pin, excluding 0-terminator.
*/
size_t pin_len;
+
+ /**
+ * How many address changes are still allowed?
+ */
+ uint32_t addr_left;
+
+ /**
+ * How many authentication attempts are still allowed?
+ */
+ uint32_t auth_attempts_left;
+
+ /**
+ * How many pin transmissions can still be requested?
+ */
+ uint32_t pin_transmissions_left;
+
};
@@ -206,36 +227,71 @@ CH_handler_solve (struct CH_HandlerContext *hc,
qs = CH_db->validate_solve_pin (CH_db->cls,
&bc->nonce,
pin,
- &solved);
+ &solved,
+ &bc->addr_left,
+ &bc->auth_attempts_left,
+ &bc->pin_transmissions_left,
+ &bc->client_redirect_uri);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
- return TALER_TEMPLATING_reply_error (hc->connection,
- "internal-error",
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validate_solve_pin");
+ return TALER_TEMPLATING_reply_error (
+ hc->connection,
+ "internal-error",
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "validate_solve_pin");
case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
return MHD_NO;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- return TALER_TEMPLATING_reply_error (hc->connection,
- "validation-unknown",
- MHD_HTTP_NOT_FOUND,
-
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
- NULL);
+ return TALER_TEMPLATING_reply_error (
+ hc->connection,
+ "validation-unknown",
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
+ NULL);
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
break;
}
if (! solved)
{
- // FIXME: if no more attempts remaining,
- // redirect to server instead!
- return TALER_TEMPLATING_reply_error (hc->connection,
- "invalid-pin",
- MHD_HTTP_FORBIDDEN,
- TALER_EC_CHALLENGER_INVALID_PIN,
- NULL);
+ MHD_RESULT ret;
+ json_t *details;
+
+ if ( (0 == bc->addr_left) &&
+ (0 == bc->pin_transmissions_left) &&
+ (0 == bc->auth_attempts_left) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Client exhausted all chances to satisfy challenge\n");
+ return TALER_MHD_redirect_with_oauth_status (
+ hc->connection,
+ bc->client_redirect_uri,
+ "access_denied",
+ "users exhausted all possibilities of passing the check",
+ NULL);
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Invalid PIN supplied, client has chance to solve it
again\n");
+ details = GNUNET_JSON_PACK (
+ TALER_JSON_pack_ec (TALER_EC_CHALLENGER_INVALID_PIN),
+ GNUNET_JSON_pack_uint64 ("addresses_left",
+ bc->addr_left),
+ GNUNET_JSON_pack_uint64 ("pin_transmissions_left",
+ bc->pin_transmissions_left),
+ GNUNET_JSON_pack_uint64 ("auth_attempts_left",
+ bc->auth_attempts_left)
+ );
+ ret = TALER_TEMPLATING_reply (hc->connection,
+ MHD_HTTP_FORBIDDEN,
+ "invalid-pin",
+ NULL,
+ NULL,
+ details);
+ json_decref (details);
+ return ret;
}
}
diff --git a/src/challengerdb/pg_validate_solve_pin.c
b/src/challengerdb/pg_validate_solve_pin.c
index 61f4837..077134f 100644
--- a/src/challengerdb/pg_validate_solve_pin.c
+++ b/src/challengerdb/pg_validate_solve_pin.c
@@ -30,7 +30,11 @@ enum GNUNET_DB_QueryStatus
CH_PG_validate_solve_pin (void *cls,
const struct CHALLENGER_ValidationNonceP *nonce,
uint32_t new_pin,
- bool *solved)
+ bool *solved,
+ uint32_t *addr_left,
+ uint32_t *auth_attempts_left,
+ uint32_t *pin_transmissions_left,
+ char **client_redirect_uri)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -38,39 +42,45 @@ CH_PG_validate_solve_pin (void *cls,
GNUNET_PQ_query_param_uint32 (&new_pin),
GNUNET_PQ_query_param_end
};
+ bool not_found;
struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("not_found",
+ ¬_found),
GNUNET_PQ_result_spec_bool ("solved",
solved),
+ GNUNET_PQ_result_spec_uint32 ("address_attempts_left",
+ addr_left),
+ GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
+ auth_attempts_left),
+ GNUNET_PQ_result_spec_uint32 ("pin_transmissions_left",
+ pin_transmissions_left),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_redirect_uri",
+ client_redirect_uri),
+ NULL),
GNUNET_PQ_result_spec_end
};
+ enum GNUNET_DB_QueryStatus qs;
- /* We set all remaining attempts to zero to prevent
- user from changing the address after already having
- succeeded with the process. */
+ *client_redirect_uri = NULL;
PREPARE (pg,
- "validate_solve_pin",
- "UPDATE validations SET"
- " auth_attempts_left=CASE"
- " WHEN last_pin = $2"
- " THEN 0"
- " ELSE auth_attempts_left - 1"
- " END"
- " ,address_attempts_left=CASE"
- " WHEN last_pin = $2"
- " THEN 0"
- " ELSE address_attempts_left"
- " END"
- " ,pin_transmissions_left=CASE"
- " WHEN last_pin = $2"
- " THEN 0"
- " ELSE pin_transmissions_left"
- " END"
- " WHERE nonce=$1"
- " AND auth_attempts_left > 0"
- " RETURNING"
- " (last_pin = $2) AS solved;");
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "validate_solve_pin",
- params,
- rs);
+ "do_validate_solve_pin",
+ "SELECT "
+ " out_not_found AS not_found"
+ ",out_solved AS solved"
+ ",out_address_attempts_left AS address_attempts_left"
+ ",out_auth_attempts_left AS auth_attempts_left"
+ ",out_pin_transmissions_left AS pin_transmissions_left"
+ ",out_client_redirect_uri AS client_redirect_uri"
+ " FROM challenger_do_validate_solve_pin"
+ " ($1,$2);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "do_validate_solve_pin",
+ params,
+ rs);
+ if (qs <= 0)
+ return qs;
+ if (not_found)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ return qs;
}
diff --git a/src/challengerdb/pg_validate_solve_pin.h
b/src/challengerdb/pg_validate_solve_pin.h
index 91870d6..a2d7c6d 100644
--- a/src/challengerdb/pg_validate_solve_pin.h
+++ b/src/challengerdb/pg_validate_solve_pin.h
@@ -33,16 +33,25 @@
* @param nonce unique nonce to use to identify the validation
* @param new_pin the PIN the user entered
* @param[out] solved set to true if the PIN was correct
+ * @param[out] addr_left set to number of address changes remaining
+ * @param[out] auth_attempts_left set to number of authentication attempts
remaining
+ * @param[out] pin_transmissions_left set to number of times the PIN can still
be re-requested
+ * @param[out] client_redirect_uri set to OAuth2 client redirect URI
* @return transaction status:
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
* #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
* #GNUNET_DB_STATUS_HARD_ERROR on failure
*/
enum GNUNET_DB_QueryStatus
-CH_PG_validate_solve_pin (void *cls,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint32_t new_pin,
- bool *solved);
+CH_PG_validate_solve_pin (
+ void *cls,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint32_t new_pin,
+ bool *solved,
+ uint32_t *addr_left,
+ uint32_t *auth_attempts_left,
+ uint32_t *pin_transmissions_left,
+ char **client_redirect_uri);
#endif
diff --git a/src/challengerdb/procedures.sql.in
b/src/challengerdb/procedures.sql.in
index 70c1539..3636b94 100644
--- a/src/challengerdb/procedures.sql.in
+++ b/src/challengerdb/procedures.sql.in
@@ -19,5 +19,6 @@ BEGIN;
SET search_path TO challenger;
#include "challenger_do_challenge_set_address_and_pin.sql"
+#include "challenger_do_validate_and_solve_pin.sql"
COMMIT;
diff --git a/src/include/challenger_database_plugin.h
b/src/include/challenger_database_plugin.h
index c2123a0..3d35cc2 100644
--- a/src/include/challenger_database_plugin.h
+++ b/src/include/challenger_database_plugin.h
@@ -289,6 +289,10 @@ struct CHALLENGER_DatabasePlugin
* @param nonce unique nonce to use to identify the validation
* @param new_pin the PIN the user entered
* @param[out] solved set to true if the PIN was correct
+ * @param[out] addr_left set to number of address changes remaining
+ * @param[out] auth_attempts_left set to number of authentication attempts
remaining
+ * @param[out] pin_transmissions_left set to number of times the PIN can
still be re-requested
+ * @param[out] client_redirect_uri set to OAuth2 client redirect URI
* @return transaction status:
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
* #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
@@ -298,7 +302,11 @@ struct CHALLENGER_DatabasePlugin
(*validate_solve_pin)(void *cls,
const struct CHALLENGER_ValidationNonceP *nonce,
uint32_t new_pin,
- bool *solved);
+ bool *solved,
+ uint32_t *addr_left,
+ uint32_t *auth_attempts_left,
+ uint32_t *pin_transmissions_left,
+ char **client_redirect_uri);
/**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.