gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-challenger] branch master updated: more work on challenger skelet


From: gnunet
Subject: [taler-challenger] branch master updated: more work on challenger skeleton
Date: Thu, 27 Apr 2023 01:31:57 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository challenger.

The following commit(s) were added to refs/heads/master by this push:
     new 7e1fc8a  more work on challenger skeleton
7e1fc8a is described below

commit 7e1fc8ae32812a6529c631650b5f7fa6c83ba5fd
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Apr 27 01:31:52 2023 +0200

    more work on challenger skeleton
---
 src/challenger/challenger-httpd_challenge.c | 103 +++++++++++++++++-
 src/challenger/challenger-httpd_login.c     | 162 +++++++++++++++++++++++++++-
 src/include/challenger_database_plugin.h    |  75 ++++++-------
 3 files changed, 287 insertions(+), 53 deletions(-)

diff --git a/src/challenger/challenger-httpd_challenge.c 
b/src/challenger/challenger-httpd_challenge.c
index 63aeeda..541ed5c 100644
--- a/src/challenger/challenger-httpd_challenge.c
+++ b/src/challenger/challenger-httpd_challenge.c
@@ -37,6 +37,16 @@ struct ChallengeContext
    * Handle for processing uploaded data.
    */
   struct MHD_PostProcessor *pp;
+
+  /**
+   * 0-terminated address information submitted to us.
+   */
+  char *addressp;
+
+  /**
+   * Number of bytes in @a address, excluding 0-terminator.
+   */
+  size_t address_len;
 };
 
 
@@ -90,9 +100,23 @@ post_iter (void *cls,
 {
   struct ChallengeContext *bc = cls;
 
-  (void) bc;
-  GNUNET_break (0);
-  return MHD_NO;
+  (void) filename;
+  (void) content_type;
+  (void) transfer_encoding;
+  (void) off;
+  if (0 != strcmp (key,
+                   "address"))
+    return MHD_YES;
+  if (MHD_POSTDATA_KIND != kind)
+    return MHD_YES;
+  bc->address = GNUNET_realloc (bc->address,
+                                bc->address_len + size + 1);
+  memcpy (bc->address + bc->address_len,
+          data,
+          size);
+  bc->address_len += size;
+  bc->address[bc->address_len] = '\0';
+  return MHD_YES;
 }
 
 
@@ -131,6 +155,75 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
     return MHD_NO;
   }
 
-  /* FIXME: generate proper response */
-  return MHD_NO;
+  {
+    struct GNUNET_TIME_Absolute last_tx_time
+      = GNUNET_TIME_absolute_get ();
+    uint32_t last_pin
+      = GNUNET_CRYPTO_random_uint32 (GNUNET_CRYPTO_RANDOM_NONCE) % 100000000;
+    uint32_t pin_transmissions_left;
+    uint32_t pin_attempts_left = 3; /* if addr is new */
+    enum GNUNET_DB_QueryStatus qs;
+    struct GNUNET_TIME_Absolute next_tx_time;
+
+    next_tx_time = GNUNET_TIME_absolute_subtract (last_tx_time,
+                                                  get_duration);
+    qs = db->challenge_set_address_and_pin (db->cls,
+                                            &nonce,
+                                            address,
+                                            next_tx_time,
+                                            &last_tx,
+                                            &last_pin,
+                                            &pin_transmissions_left,
+                                            &pin_attempts_left);
+    switch (qs)
+    {
+    case GNUNET_DB_SUCCESS_HARD_ERROR:
+      GNUNET_break (0);
+      return TALER_MHD_reply_with_html (hc->connection,
+                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                        "internal-server-error.must",
+                                        NULL);
+    case GNUNET_DB_SUCCESS_SOFT_ERROR:
+      GNUNET_break (0);
+      return GNUNET_NO;
+    case GNUNET_DB_SUCCESS_NO_RESULTS:
+      /* nonce unknown */
+      return TALER_MHD_reply_with_html (hc->connection,
+                                        MHD_HTTP_NOT_FOUND,
+                                        "validation-unknown.must",
+                                        NULL);
+    case GNUNET_DB_SUCCESS_ONE_RESULT:
+      break;
+    }
+    if (0 == pin_attempts_left)
+    {
+      return TALER_MHD_reply_with_html (hc->connection,
+                                        MHD_HTTP_XXX,
+                                        "attempts-exhausted.must",
+                                        NULL);
+    }
+    if ( (GNUNET_TIME_relative_cmp (duration,
+                                    (>),
+                                    CH_pin_retransmission_frequency)) &&
+         (pin_transmissions_left > 0) )
+    {
+      /* Retransmit PIN */
+    }
+    {
+      MHD_RESULT res;
+      json_t *args;
+
+      args = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_uint64 ("attempts_left",
+                                 pin_attempts_left),
+        GNUNET_JSON_pack_absolute_time ("next_tx_time",
+                                        next_tx_time),
+        );
+      res = TALER_MHD_reply_with_html (hc->connection,
+                                       MHD_HTTP_OK,
+                                       "enter-pin-form.must",
+                                       args);
+      return res;
+    }
+  }
 }
diff --git a/src/challenger/challenger-httpd_login.c 
b/src/challenger/challenger-httpd_login.c
index cf394f3..f8035f2 100644
--- a/src/challenger/challenger-httpd_login.c
+++ b/src/challenger/challenger-httpd_login.c
@@ -29,8 +29,162 @@ CH_handler_login (struct CH_HandlerContext *hc,
                   const char *upload_data,
                   size_t *upload_data_size)
 {
-  return TALER_MHD_reply_with_error (hc->connection,
-                                     MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                     
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
-                                     NULL);
+  const char *response_type;
+  unsigned long long client_id;
+  const char *redirect_uri;
+  const char *state;
+  const char *scope;
+  struct CHALLENGER_ValidationNonceP nonce;
+
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data (hc->path,
+                                     strlen (hc->path),
+                                     &nonce,
+                                     sizeof (nonce)))
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       TALER_EC_GENERIC_PARAMETER_MISSING,
+                                       hc->path);
+  }
+  response_type
+    = MHD_lookup_connection_value (connection,
+                                   MHD_GET_ARGUMENT_KIND,
+                                   "response_type");
+  if (NULL == response_type)
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MISSING,
+                                       "response_type");
+  }
+  if (0 != strcmp (response_type,
+                   "code"))
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                       "response_type (mus be 'code')");
+  }
+
+  {
+    const char *client_id_str;
+    char dummy;
+
+    client_id_str
+      = MHD_lookup_connection_value (connection,
+                                     MHD_GET_ARGUMENT_KIND,
+                                     "client_id");
+    if (NULL == client_id_str)
+    {
+      GNUNET_break_op (0);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         TALER_EC_GENERIC_PARAMETER_MISSING,
+                                         "client_id");
+    }
+    if (1 != sscanf (client_id_str,
+                     "%llu%c",
+                     &client_id,
+                     &dummy))
+    {
+      GNUNET_break_op (0);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                         "client_id");
+    }
+  }
+  redirect_uri
+    = MHD_lookup_connection_value (connection,
+                                   MHD_GET_ARGUMENT_KIND,
+                                   "redirect_uri");
+  if ( (NULL != redirect_uri) &&
+       (0 != strncmp (redirect_uri,
+                      "http://";,
+                      strlen ("http://";))) &&
+       (0 != strncmp (redirect_uri,
+                      "https://";,
+                      strlen ("https://";))) )
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                       "redirect_uri (has to start with 
'http://' or 'https://')");
+  }
+  state
+    = MHD_lookup_connection_value (connection,
+                                   MHD_GET_ARGUMENT_KIND,
+                                   "state");
+  if (NULL == state)
+    state = "";
+  scope
+    = MHD_lookup_connection_value (connection,
+                                   MHD_GET_ARGUMENT_KIND,
+                                   "scope");
+  (void) scope; /* ignored */
+  {
+    struct GNUNET_TIME_Absolute last_tx_time;
+    uint32_t pin_attempts_left;
+    enum GNUNET_DB_QueryStatus qs;
+    struct GNUNET_TIME_Absolute next_tx_time;
+
+    qs = db->validate_login_start (db->cls,
+                                   &nonce,
+                                   client_scope,
+                                   client_state,
+                                   client_redirect_url,
+                                   &last_tx,
+                                   &pin_attempts_left);
+    switch (qs)
+    {
+    case GNUNET_DB_SUCCESS_HARD_ERROR:
+      GNUNET_break (0);
+      return TALER_MHD_reply_with_html (hc->connection,
+                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                        "internal-server-error.must",
+                                        NULL);
+    case GNUNET_DB_SUCCESS_SOFT_ERROR:
+      GNUNET_break (0);
+      return GNUNET_NO;
+    case GNUNET_DB_SUCCESS_NO_RESULTS:
+      /* nonce unknown */
+      return TALER_MHD_reply_with_html (hc->connection,
+                                        MHD_HTTP_NOT_FOUND,
+                                        "validation-unknown.must",
+                                        NULL);
+    case GNUNET_DB_SUCCESS_ONE_RESULT:
+      break;
+    }
+    if (0 == pin_attempts_left)
+    {
+      /* FIXME: return human-readable HTML saying that they tried to often */
+      return TALER_MHD_reply_with_html (connection,
+                                        MHD_HTTP_FORBIDDEN,
+                                        "too-many-attempts.must",
+                                        NULL /* OK? or pass empty object? */);
+    }
+    next_tx_time = GNUNET_TIME_absolute_add (last_tx_time,
+                                             CH_pin_retransmission_frequency);
+    {
+      MHD_RESULT res;
+      json_t *args;
+
+      args = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_uint64 ("attempts_left",
+                                 pin_attempts_left),
+        GNUNET_JSON_pack_absolute_time ("next_tx_time",
+                                        next_tx_time),
+        );
+      res = TALER_MHD_reply_with_html (hc->connection,
+                                       MHD_HTTP_OK,
+                                       "enter-address-form.must",
+                                       args);
+      return res;
+    }
+  }
 }
diff --git a/src/include/challenger_database_plugin.h 
b/src/include/challenger_database_plugin.h
index c62ba8c..8933427 100644
--- a/src/include/challenger_database_plugin.h
+++ b/src/include/challenger_database_plugin.h
@@ -199,10 +199,10 @@ struct CHALLENGER_DatabasePlugin
    * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
-  (*validation_setup)(void *cls,
-                      uint64_t client_id,
-                      const struct CHALLENGER_ValidationNonceP *nonce,
-                      struct GNUNET_TIME_Absolute expiration_time);
+  (*setup_nonce)(void *cls,
+                 uint64_t client_id,
+                 const struct CHALLENGER_ValidationNonceP *nonce,
+                 struct GNUNET_TIME_Absolute expiration_time);
 
 
   /**
@@ -213,66 +213,53 @@ struct CHALLENGER_DatabasePlugin
    *
    * @param cls
    * @param nonce unique nonce to use to identify the validation
-   * @param address the new address to validate
    * @param client_scope scope of the validation
    * @param client_state state of the client
    * @param client_redirect_url where to redirect at the end, NULL to use a 
unique one registered for the client
    * @param[out] last_tx_time set to the last time when we (presumably) send a 
PIN to @a address; 0 if never sent
-   * @param[out] last_pin set to the PIN last send to @a address, 0 if never 
sent
-   * @param[in,out] pin_attempts_left set to number of PIN transmission 
attempts left for this address; input is value to be used if address is new, 
output is possibly different if address was not new
+   * @param[out] pin_attempts_left set to number of PIN transmission attempts 
left for this address; input is value to be used if address is new, output is 
possibly different if address was not new
    * @return transaction status:
    *   #GNUNET_DB_SUCCESS_ONE_RESULT if the address was changed
    *   #GNUNET_DB_SUCCESS_NO_RESULTS if we do not permit further changes to 
the address (attempts exhausted)
    *   #GNUNET_DB_SUCCESS_HARD_ERROR on failure
    */
   enum GNUNET_DB_QueryStatus
-  (*validate_login_address)(void *cls,
-                            const struct CHALLENGER_ValidationNonceP *nonce,
-                            const char *address,
-                            const char *client_scope,
-                            const char *client_state,
-                            const char *client_redirect_url,
-                            struct GNUNET_TIME_Absolute *last_tx_time,
-                            uint32_t *last_pin,
-                            uint32_t *pin_attempts_left);
-
-
-  /**
-   * Store a new PIN to be used to validate an address.
-   *
-   * @param cls
-   * @param nonce unique nonce to use to identify the validation
-   * @param tx_time the current time
-   * @param new_pin the PIN we are sending
-   * @param auth_attempts_allowed how many attempts do we give to the user to 
enter the correct PIN
-   * @return transaction status:
-   *   #GNUNET_DB_SUCCESS_ONE_RESULT if the pin was stored
-   *   #GNUNET_DB_SUCCESS_NO_RESULTS if we do not know the @a nonce or if pin 
attempts left is zero
-   *   #GNUNET_DB_SUCCESS_HARD_ERROR on failure
-   */
-  enum GNUNET_DB_QueryStatus
-  (*validate_login_pin)(void *cls,
-                        const struct CHALLENGER_ValidationNonceP *nonce,
-                        struct GNUNET_TIME_Absolute tx_time,
-                        uint32_t new_pin,
-                        uint32_t auth_attempts_allowed);
+  (*login_start)(void *cls,
+                 const struct CHALLENGER_ValidationNonceP *nonce,
+                 const char *client_scope,
+                 const char *client_state,
+                 const char *client_redirect_url,
+                 struct GNUNET_TIME_Absolute *last_tx_time,
+                 uint32_t *pin_attempts_left);
 
 
   /**
-   * Check if challenge is pending to validate an address.
+   * Set the user-provided address in a validation process. Updates
+   * the address and decrements the "addresses left" counter.  If the
+   * address did not change, the operation is successful even without
+   * the counter change.
    *
    * @param cls
    * @param nonce unique nonce to use to identify the validation
-   * @param[out] is_open set to true if a challenge was sent
+   * @param address the new address to validate
+   * @param next_tx_time tx time we must have sent earlier before to 
retransmit now
+   * @param[in,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[in,out] last_pin set to the PIN last send to @a address, input 
should be random PIN to use if address did not change
+   * @param[in,out] pin_attempts_left set to number of PIN transmission 
attempts left for this address; input is value to be used if address is new, 
output is possibly different if address was not new
    * @return transaction status:
-   *   #GNUNET_DB_SUCCESS_ONE_RESULT if the nonce was found
-   *   #GNUNET_DB_SUCCESS_NO_RESULTS if we do not know the nonce
+   *   #GNUNET_DB_SUCCESS_ONE_RESULT if the address was changed
+   *   #GNUNET_DB_SUCCESS_NO_RESULTS if we do not permit further changes to 
the address (attempts exhausted)
    *   #GNUNET_DB_SUCCESS_HARD_ERROR on failure
    */
   enum GNUNET_DB_QueryStatus
-  (*validate_challenge_open)(void *cls,
-                             const struct CHALLENGER_ValidationNonceP *nonce,
-                             bool *is_open);
+  (*challenge_set_address_and_pin)(
+    void *cls,
+    const struct CHALLENGER_ValidationNonceP *nonce,
+    const char *address,
+    struct GNUNET_TIME_Absolute next_tx_time,
+    struct GNUNET_TIME_Absolute *last_tx_time,
+    uint32_t *last_pin,
+    uint32_t *pin_attempts_left);
 
 
   /**

-- 
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]