[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-challenger] branch master updated: more work on challenger skeleton,
gnunet <=