gnunet-svn
[Top][All Lists]
Advanced

[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",
+                                &not_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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]