challenger

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

commit 0ab453c2f96a0d8074df57f71f637e51a45cd67c
parent b8a0d6f5602e0b019eddb706cf7306d1fb217022
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 27 Apr 2023 21:09:41 +0200

-fix db ftbfs

Diffstat:
Msrc/challenger/challenger-httpd_challenge.c | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/challenger/challenger-httpd_login.c | 62++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/challenger/challenger-httpd_solve.c | 46+++++++++++++++++++++++++++++++++++++++++++---
Msrc/challengerdb/pg_challenge_set_address_and_pin.c | 13++++++-------
Msrc/challengerdb/pg_challenge_set_address_and_pin.h | 4++--
Msrc/challengerdb/pg_login_start.h | 1-
Msrc/challengerdb/pg_setup_nonce.c | 2+-
Msrc/challengerdb/plugin_challengerdb_postgres.c | 20+++++++++-----------
Msrc/include/challenger_database_plugin.h | 4++--
9 files changed, 194 insertions(+), 61 deletions(-)

diff --git a/src/challenger/challenger-httpd_challenge.c b/src/challenger/challenger-httpd_challenge.c @@ -126,7 +126,20 @@ CH_handler_challenge (struct CH_HandlerContext *hc, size_t *upload_data_size) { struct ChallengeContext *bc = hc->ctx; + 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); + } if (NULL == bc) { /* first call, setup internals */ @@ -178,29 +191,70 @@ CH_handler_challenge (struct CH_HandlerContext *hc, 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); + { + enum GNUNET_GenericReturnValue ret; + json_t *root = json_object (); + + GNUNET_assert (NULL != root); + GNUNET_break (0); + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + "internal-server-error.must", + NULL); + json_decref (root); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; + } 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); + { + enum GNUNET_GenericReturnValue ret; + json_t *root = json_object (); + + GNUNET_assert (NULL != root); + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_NOT_FOUND, + "validation-unknown.must", + NULL); + json_decref (root); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; + } 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); + enum GNUNET_GenericReturnValue ret; + json_t *root = json_object (); + + GNUNET_assert (NULL != root); + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_XXX, + "attempts-exhausted.must", + NULL, + NULL, + root); + json_decref (root); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; } if ( (GNUNET_TIME_relative_cmp (duration, (>), @@ -210,8 +264,8 @@ CH_handler_challenge (struct CH_HandlerContext *hc, /* Retransmit PIN */ } { - MHD_RESULT res; json_t *args; + enum GNUNET_GenericReturnValue ret; args = GNUNET_JSON_PACK ( GNUNET_JSON_pack_uint64 ("attempts_left", @@ -219,11 +273,20 @@ CH_handler_challenge (struct CH_HandlerContext *hc, 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; + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_OK, + "enter-pin-form.must", + NULL, + NULL, + args); + json_decref (args); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; } } } diff --git a/src/challenger/challenger-httpd_login.c b/src/challenger/challenger-httpd_login.c @@ -143,25 +143,52 @@ CH_handler_login (struct CH_HandlerContext *hc, 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); + { + enum GNUNET_GenericReturnValue ret; + json_t *root = json_object (); + + GNUNET_assert (NULL != root); + GNUNET_break (0); + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + "internal-server-error.must", + NULL); + json_decref (root); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; + } 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); + { + enum GNUNET_GenericReturnValue ret; + json_t *root = json_object (); + + GNUNET_assert (NULL != root); + ret = TALER_TEMPLATING_reply (hc->connection, + MHD_HTTP_NOT_FOUND, + "validation-unknown.must", + NULL); + json_decref (root); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; + } case GNUNET_DB_SUCCESS_ONE_RESULT: break; } { - MHD_RESULT res; + enum GNUNET_GenericReturnValue ret; json_t *args; args = GNUNET_JSON_PACK ( @@ -172,14 +199,21 @@ CH_handler_login (struct CH_HandlerContext *hc, GNUNET_JSON_pack_uint64 ("changes_left", address_attempts_left), ); - res = TALER_MHD_reply_with_html ( + ret = TALER_TEMPLATING_reply ( hc->connection, MHD_HTTP_OK, "enter-address-form.must", - + NULL, + NULL, args); json_decref (args); - return res; + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return MHD_NO; + } + GNUNET_break (GNUNET_OK == ret); + return MHD_YES; } } } diff --git a/src/challenger/challenger-httpd_solve.c b/src/challenger/challenger-httpd_solve.c @@ -37,6 +37,16 @@ struct SolveContext * Handle for processing uploaded data. */ struct MHD_PostProcessor *pp; + + /** + * 0-terminated PIN submitted to us. + */ + char *pin; + + /** + * Number of bytes in @a pin, excluding 0-terminator. + */ + size_t pin_len; }; @@ -55,6 +65,7 @@ cleanup_ctx (void *cls) GNUNET_break_op (MHD_YES == MHD_destroy_post_processor (bc->pp)); } + GNUENT_free (bc->pin); GNUNET_free (bc); } @@ -90,9 +101,23 @@ post_iter (void *cls, { struct SolveContext *bc = cls; - (void) bc; - GNUNET_break (0); - return MHD_NO; + (void) filename; + (void) content_type; + (void) transfer_encoding; + (void) off; + if (0 != strcmp (key, + "pin")) + return MHD_YES; + if (MHD_POSTDATA_KIND != kind) + return MHD_YES; + bc->pin = GNUNET_realloc (bc->pin, + bc->pin_len + size + 1); + memcpy (bc->pin + bc->pin_len, + data, + size); + bc->pin_len += size; + bc->pin[bc->pin_len] = '\0'; + return MHD_YES; } @@ -102,7 +127,20 @@ CH_handler_solve (struct CH_HandlerContext *hc, size_t *upload_data_size) { struct SolveContext *bc = hc->ctx; + 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); + } if (NULL == bc) { /* first call, setup internals */ @@ -130,6 +168,8 @@ CH_handler_solve (struct CH_HandlerContext *hc, /* FIXME: return more specific error if possible... */ return MHD_NO; } + /* FIXME: convert pin string to number */ + /* FIXME: check with DB ... */ /* FIXME: generate proper response */ return MHD_NO; diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.c b/src/challengerdb/pg_challenge_set_address_and_pin.c @@ -34,16 +34,15 @@ CH_PG_challenge_set_address_and_pin ( struct GNUNET_TIME_Absolute next_tx_time, struct GNUNET_TIME_Absolute *last_tx_time, uint32_t *last_pin, - uint32_t *pin_transmissions_left) + bool *pin_transmit) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (nonce), GNUNET_PQ_query_param_string (address), - GNUNET_PQ_query_param_abs_time (&next_tx_time), - GNUNET_PQ_query_param_abs_time (last_tx_time), + GNUNET_PQ_query_param_absolute_time (&next_tx_time), + GNUNET_PQ_query_param_absolute_time (last_tx_time), GNUNET_PQ_query_param_uint32 (last_pin), - GNUNET_PQ_query_param_uint32 (pin_transmissions_left), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { @@ -51,8 +50,8 @@ CH_PG_challenge_set_address_and_pin ( last_tx_time), GNUNET_PQ_result_spec_uint32 ("last_pin", last_pin), - GNUNET_PQ_result_spec_uint32 ("pin_attempts_left", - pin_attempts_left), + GNUNET_PQ_result_spec_bool ("pin_transmit", + pin_transmit), GNUNET_PQ_result_spec_end }; @@ -72,7 +71,7 @@ CH_PG_challenge_set_address_and_pin ( " ,END" " ,pin_transmissions_left=CASE" " WHEN address != $2" - " THEN $6" + " THEN 3" " ELSE WHEN last_tx_time < 3" " THEN pin_transmissions_left - 1" " ELSE pin_transmissions_left" diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.h b/src/challengerdb/pg_challenge_set_address_and_pin.h @@ -38,7 +38,7 @@ * @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_transmissions_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_transmit set to true if we should transmit the @a last_pin to the @a address * @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) @@ -52,7 +52,7 @@ CH_PG_challenge_set_address_and_pin ( struct GNUNET_TIME_Absolute next_tx_time, struct GNUNET_TIME_Absolute *last_tx_time, uint32_t *last_pin, - uint32_t *pin_transmissions_left); + bool *pin_transmit); #endif diff --git a/src/challengerdb/pg_login_start.h b/src/challengerdb/pg_login_start.h @@ -53,7 +53,6 @@ CH_PG_login_start (void *cls, const char *client_state, const char *client_redirect_url, char **last_address, - struct GNUNET_TIME_Absolute *last_tx_time, uint32_t *address_attempts_left); diff --git a/src/challengerdb/pg_setup_nonce.c b/src/challengerdb/pg_setup_nonce.c @@ -22,7 +22,7 @@ #include <taler/taler_error_codes.h> #include <taler/taler_dbevents.h> #include <taler/taler_pq_lib.h> -#include "pg_validation_setup.h" +#include "pg_setup_nonce.h" #include "pg_helper.h" diff --git a/src/challengerdb/plugin_challengerdb_postgres.c b/src/challengerdb/plugin_challengerdb_postgres.c @@ -29,9 +29,9 @@ #include "pg_client_add.h" #include "pg_client_delete.h" #include "pg_client_check.h" -#include "pg_validation_setup.h" -#include "pg_validate_login_address.h" -#include "pg_validate_login_pin.h" +#include "pg_setup_nonce.h" +#include "pg_login_start.h" +#include "pg_challenge_set_address_and_pin.h" #include "pg_validate_challenge_open.h" #include "pg_validate_solve_pin.h" #include "pg_validation_get.h" @@ -390,14 +390,12 @@ libchallenger_plugin_db_postgres_init (void *cls) = &CH_PG_client_delete; plugin->client_check = &CH_PG_client_check; - plugin->validation_setup - = &CH_PG_validation_setup; - plugin->validate_login_address - = &CH_PG_validate_login_address; - plugin->validate_login_pin - = &CH_PG_validate_login_pin; - plugin->validate_challenge_open - = &CH_PG_validate_challenge_open; + plugin->setup_nonce + = &CH_PG_setup_nonce; + plugin->login_start + = &CH_PG_login_start; + plugin->challenge_set_address_and_pin + = &CH_PG_challenge_set_address_and_pin; plugin->validate_solve_pin = &CH_PG_validate_solve_pin; plugin->validation_get diff --git a/src/include/challenger_database_plugin.h b/src/include/challenger_database_plugin.h @@ -247,7 +247,7 @@ struct CHALLENGER_DatabasePlugin * @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_transmissions_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_transmit set to true if we should transmit @a last_pin to the @a address * @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) @@ -261,7 +261,7 @@ struct CHALLENGER_DatabasePlugin struct GNUNET_TIME_Absolute next_tx_time, struct GNUNET_TIME_Absolute *last_tx_time, uint32_t *last_pin, - uint32_t *pin_transmissions_left); + bool *pin_transmit); /**