donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 2d22172b439ac035bb42dd0d8c48533dfa5933c3
parent df9104c9c9210e3daff7b53a3096b9da57286327
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 21 Jun 2025 14:04:37 +0200

fix DONAU FTBFS, memory leaks, style issues"

Diffstat:
Msrc/donau/donau-httpd.c | 139++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/donau/donau-httpd_csr.c | 5+++--
Msrc/donau/donau-httpd_history_get.c | 2+-
Msrc/donaudb/donaudb_plugin.c | 1+
Msrc/donaudb/pg_insert_submitted_receipts.c | 27++++++++++++---------------
Msrc/donaudb/pg_preflight.c | 10----------
Msrc/donaudb/pg_preflight.h | 14+++++++++++++-
Msrc/donaudb/plugin_donaudb_postgres.c | 6++++++
Msrc/json/json.c | 8+++++---
Msrc/json/json_pack.c | 1+
Msrc/lib/donau_api_batch_issue_receipts.c | 52++++++++++++++++++++++++----------------------------
Msrc/lib/donau_api_batch_submit_receipts.c | 18+++++++++---------
Msrc/lib/donau_api_charity_post.c | 75+++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/lib/donau_api_csr_post.c | 40++++++++++++++++++++++------------------
Msrc/lib/donau_api_donation_statement_get.c | 51+++++++++++++++++++++++++++------------------------
Msrc/lib/donau_api_handle.c | 91+++++++++++--------------------------------------------------------------------
Msrc/pq/pq_query_helper.c | 28++++++++++++++--------------
Msrc/pq/pq_result_helper.c | 3++-
Msrc/util/donau_os_installation.c | 1+
Msrc/util/qr.c | 39+++++++++++++--------------------------
20 files changed, 286 insertions(+), 325 deletions(-)

diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c @@ -95,9 +95,9 @@ static int allow_address_reuse; const struct GNUNET_CONFIGURATION_Handle *DH_cfg; /** - * Handle to the HTTP server. + * Set to true if we started *any* HTTP daemons. */ -static struct MHD_Daemon *mhd; +static bool have_daemons; /** * Our DB plugin. (global) @@ -147,11 +147,6 @@ bool DH_suicide; int DH_global_ret; /** - * Port to run the daemon on. - */ -static uint16_t serve_port; - -/** * Counter for the number of open connections. */ static unsigned long long active_connections; @@ -866,17 +861,11 @@ connection_done (void *cls, static void do_shutdown (void *cls) { - struct MHD_Daemon *mhd; (void) cls; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutdown initiated\n"); - mhd = TALER_MHD_daemon_stop (); - if (NULL != mhd) - { - MHD_stop_daemon (mhd); - mhd = NULL; - } + TALER_MHD_daemons_halt (); + TALER_MHD_daemons_destroy (); if (NULL != DH_plugin) { DONAUDB_plugin_unload (DH_plugin); @@ -896,6 +885,58 @@ do_shutdown (void *cls) /** + * Callback invoked on every listen socket to start the + * respective MHD HTTP daemon. + * + * @param cls unused + * @param lsock the listen socket + */ +static void +start_daemon (void *cls, + int lsock) +{ + struct MHD_Daemon *mhd; + + (void) cls; + GNUNET_assert (-1 != lsock); + mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME + | MHD_USE_PIPE_FOR_SHUTDOWN + | MHD_USE_DEBUG | MHD_USE_DUAL_STACK + | MHD_USE_TCP_FASTOPEN, + 0 /* port */, + NULL, NULL, + &handle_mhd_request, NULL, + MHD_OPTION_LISTEN_SOCKET, + lsock, + MHD_OPTION_EXTERNAL_LOGGER, + &TALER_MHD_handle_logs, + NULL, + MHD_OPTION_NOTIFY_COMPLETED, + &handle_mhd_completion_callback, + NULL, + MHD_OPTION_NOTIFY_CONNECTION, + &connection_done, + NULL, + MHD_OPTION_CONNECTION_TIMEOUT, + connection_timeout, + (0 == allow_address_reuse) + ? MHD_OPTION_END + : MHD_OPTION_LISTENING_ADDRESS_REUSE, + (unsigned int) allow_address_reuse, + MHD_OPTION_END); + if (NULL == mhd) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to launch HTTP service. Is the port in use?\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + have_daemons = true; + TALER_MHD_daemon_start (mhd); +} + + +/** * Main function that will be run by the scheduler. * * @param cls closure @@ -911,7 +952,6 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *config) { enum TALER_MHD_GlobalOptions go; - int fh; (void) cls; (void) args; @@ -960,51 +1000,34 @@ run (void *cls, return; } donau_curl_rc = GNUNET_CURL_gnunet_rc_create (DH_curl_ctx); - fh = TALER_MHD_bind (DH_cfg, - "donau", - &serve_port); - if ( (0 == serve_port) && - (-1 == fh) ) - { - GNUNET_SCHEDULER_shutdown (); - return; - } - mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME - | MHD_USE_PIPE_FOR_SHUTDOWN - | MHD_USE_DEBUG | MHD_USE_DUAL_STACK - | MHD_USE_TCP_FASTOPEN, - (-1 == fh) ? serve_port : 0, - NULL, NULL, - &handle_mhd_request, NULL, - MHD_OPTION_LISTEN_BACKLOG_SIZE, - (unsigned int) 1024, - MHD_OPTION_LISTEN_SOCKET, - fh, - MHD_OPTION_EXTERNAL_LOGGER, - &TALER_MHD_handle_logs, - NULL, - MHD_OPTION_NOTIFY_COMPLETED, - &handle_mhd_completion_callback, - NULL, - MHD_OPTION_NOTIFY_CONNECTION, - &connection_done, - NULL, - MHD_OPTION_CONNECTION_TIMEOUT, - connection_timeout, - (0 == allow_address_reuse) - ? MHD_OPTION_END - : MHD_OPTION_LISTENING_ADDRESS_REUSE, - (unsigned int) allow_address_reuse, - MHD_OPTION_END); - if (NULL == mhd) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to launch HTTP service. Is the port in use?\n"); - GNUNET_SCHEDULER_shutdown (); - return; + enum GNUNET_GenericReturnValue ret; + + ret = TALER_MHD_listen_bind (DH_cfg, + "donau", + &start_daemon, + NULL); + switch (ret) + { + case GNUNET_SYSERR: + DH_global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + case GNUNET_NO: + if (! have_daemons) + { + DH_global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Could not open all configured listen sockets\n"); + break; + case GNUNET_OK: + break; + } } DH_global_ret = EXIT_SUCCESS; - TALER_MHD_daemon_start (mhd); } diff --git a/src/donau/donau-httpd_csr.c b/src/donau/donau-httpd_csr.c @@ -97,6 +97,7 @@ DH_handler_csr_issue (struct DH_RequestContext *rc, /* derive r_pub */ { enum TALER_ErrorCode ec; + ec = DH_keys_donation_unit_cs_r_pub (&du_pub_hash, &nonce, &ewv.details.cs_values); @@ -109,14 +110,14 @@ DH_handler_csr_issue (struct DH_RequestContext *rc, } } { - struct TALER_ExchangeWithdrawValues exw = { + struct TALER_ExchangeBlindingValues exw = { .blinding_inputs = &ewv }; return TALER_MHD_REPLY_JSON_PACK ( rc->connection, MHD_HTTP_CREATED, - TALER_JSON_pack_exchange_withdraw_values ("ewv", + TALER_JSON_pack_exchange_blinding_values ("ewv", &exw)); } } diff --git a/src/donau/donau-httpd_history_get.c b/src/donau/donau-httpd_history_get.c @@ -40,7 +40,7 @@ * * @param cls closure */ -enum GNUNET_GenericReturnValue +static enum GNUNET_GenericReturnValue history_cb ( void *cls, unsigned long long charity_id, diff --git a/src/donaudb/donaudb_plugin.c b/src/donaudb/donaudb_plugin.c @@ -20,6 +20,7 @@ */ #include "donau_config.h" #include "donau_util.h" +#include "donaudb_lib.h" #include "donaudb_plugin.h" #include <ltdl.h> diff --git a/src/donaudb/pg_insert_submitted_receipts.c b/src/donaudb/pg_insert_submitted_receipts.c @@ -39,19 +39,6 @@ DH_PG_insert_submitted_receipts ( struct GNUNET_HashCode h_donation_unit_pubs[GNUNET_NZL (num_dr)]; uint32_t nonces[GNUNET_NZL (num_dr)]; struct DONAU_DonationUnitSignature donation_unit_sigs[GNUNET_NZL (num_dr)]; - - for (unsigned int i = 0; i < num_dr; i++) - { - const struct DONAU_DonationReceipt *dr = &donation_receipts[i]; - - h_donation_unit_pubs[i] = dr->h_donation_unit_pub.hash; - nonces[i] = dr->nonce.value; - donation_unit_sigs[i] = dr->donation_unit_sig; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Do insert submitted receipt\n"); - } - struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_donor_tax_id), GNUNET_PQ_query_param_array_auto_from_type (num_dr, @@ -66,7 +53,6 @@ DH_PG_insert_submitted_receipts ( GNUNET_PQ_query_param_uint64 (&donation_year), GNUNET_PQ_query_param_end }; - bool *conflicted; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_array_bool (pg->conn, @@ -75,9 +61,20 @@ DH_PG_insert_submitted_receipts ( &conflicted), GNUNET_PQ_result_spec_end }; - enum GNUNET_DB_QueryStatus qs; + for (unsigned int i = 0; i < num_dr; i++) + { + const struct DONAU_DonationReceipt *dr = &donation_receipts[i]; + + h_donation_unit_pubs[i] = dr->h_donation_unit_pub.hash; + nonces[i] = dr->nonce.value; + donation_unit_sigs[i] = dr->donation_unit_sig; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Do insert submitted receipt\n"); + } + + PREPARE (pg, "call_insert_submitted_receipts", "SELECT " diff --git a/src/donaudb/pg_preflight.c b/src/donaudb/pg_preflight.c @@ -26,16 +26,6 @@ #include "pg_helper.h" -/** - * Connect to the database if the connection does not exist yet. - * - * @param pg the plugin-specific state - * @return #GNUNET_OK on success - */ -enum GNUNET_GenericReturnValue -DH_PG_internal_setup (struct PostgresClosure *pg); - - enum GNUNET_GenericReturnValue DH_PG_preflight (void *cls) { diff --git a/src/donaudb/pg_preflight.h b/src/donaudb/pg_preflight.h @@ -36,9 +36,21 @@ * #GNUNET_NO if a transaction was rolled back * #GNUNET_SYSERR on hard errors */ +enum GNUNET_GenericReturnValue +DH_PG_preflight (void *cls); + +struct PostgresClosure; + +/** + * Connect to the database if the connection does not exist yet. + * + * @param pg the plugin-specific state + * @return #GNUNET_OK on success + */ enum GNUNET_GenericReturnValue -DH_PG_preflight (void *cls); +DH_PG_internal_setup (struct PostgresClosure *pg); + #endif diff --git a/src/donaudb/plugin_donaudb_postgres.c b/src/donaudb/plugin_donaudb_postgres.c @@ -147,6 +147,9 @@ DH_PG_internal_setup (struct PostgresClosure *pg) * DONAUDB_Plugin` */ void * +libtaler_plugin_donaudb_postgres_init (void *cls); + +void * libtaler_plugin_donaudb_postgres_init (void *cls) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; @@ -262,6 +265,9 @@ libtaler_plugin_donaudb_postgres_init (void *cls) * @return NULL (always) */ void * +libtaler_plugin_donaudb_postgres_done (void *cls); + +void * libtaler_plugin_donaudb_postgres_done (void *cls) { struct DONAUDB_Plugin *plugin = cls; diff --git a/src/json/json.c b/src/json/json.c @@ -20,6 +20,7 @@ * @author Christian Grothoff */ #include "donau_config.h" +#include "donau_json_lib.h" #include <gnunet/gnunet_util_lib.h> #include <taler/taler_util.h> #include <taler/taler_json_lib.h> @@ -588,6 +589,7 @@ parse_path (json_t *obj, /* Check for bracketed indices */ if (NULL != bracket) { + json_t *array; char *end_bracket = strchr (bracket, ']'); if (NULL == end_bracket) @@ -601,8 +603,8 @@ parse_path (json_t *obj, *bracket = '\0'; bracket++; - json_t *array = json_object_get (obj, - next_id); + array = json_object_get (obj, + next_id); if (0 == strcmp (bracket, "*")) { @@ -697,7 +699,7 @@ TALER_JSON_get_error_code (const json_t *json) return TALER_EC_INVALID; } if (json_is_integer (jc)) - return (enum TALER_ErrorCode) json_integer_value (jc); + return (enum TALER_ErrorCode) (int) json_integer_value (jc); GNUNET_break_op (0); return TALER_EC_INVALID; } diff --git a/src/json/json_pack.c b/src/json/json_pack.c @@ -20,6 +20,7 @@ * @author Lukas Matyja */ #include "donau_config.h" +#include "donau_json_lib.h" #include <gnunet/gnunet_util_lib.h> #include <taler/taler_util.h> #include <taler/taler_json_lib.h> diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c @@ -95,12 +95,6 @@ handle_batch_issue_ok (const json_t *resp_obj, struct DONAU_BatchIssueResponse *biresp) { struct TALER_Amount issued_amount = biresp->details.ok.issued_amount; - - if (JSON_OBJECT != json_typeof (resp_obj)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } const json_t *j_blind_signatures; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ("issued_amount", @@ -109,6 +103,7 @@ handle_batch_issue_ok (const json_t *resp_obj, &j_blind_signatures), GNUNET_JSON_spec_end () }; + if (GNUNET_OK != GNUNET_JSON_parse (resp_obj, spec, @@ -118,7 +113,6 @@ handle_batch_issue_ok (const json_t *resp_obj, GNUNET_break_op (0); return GNUNET_SYSERR; } - if ( (NULL == j_blind_signatures) || (! json_is_array (j_blind_signatures)) || (birh->num_blinded_sigs != json_array_size (j_blind_signatures)) ) @@ -129,29 +123,32 @@ handle_batch_issue_ok (const json_t *resp_obj, biresp->details.ok.blinded_sigs = GNUNET_new_array (birh->num_blinded_sigs, struct DONAU_BlindedDonationUnitSignature); - size_t index; - json_t *du_sig_obj; - json_array_foreach (j_blind_signatures, - index, - du_sig_obj) { - struct GNUNET_JSON_Specification spec[] = { - DONAU_JSON_spec_blinded_donation_unit_sig ( - "blinded_signature", - &biresp->details.ok.blinded_sigs[index]), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (du_sig_obj, - spec, - NULL, - NULL)) + size_t index; + json_t *du_sig_obj; + + json_array_foreach (j_blind_signatures, + index, + du_sig_obj) { - GNUNET_break_op (0); - return GNUNET_SYSERR; + struct GNUNET_JSON_Specification ispec[] = { + DONAU_JSON_spec_blinded_donation_unit_sig ( + "blinded_signature", + &biresp->details.ok.blinded_sigs[index]), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (du_sig_obj, + ispec, + NULL, + NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } } } - birh->cb (birh->cb_cls, biresp); birh->cb = NULL; @@ -175,8 +172,8 @@ issue_receipt_body_to_json ( const struct DONAU_CharitySignatureP *charity_sig) { json_t *budikeypairs = json_array (); - GNUNET_assert (NULL != budikeypairs); + GNUNET_assert (NULL != budikeypairs); for (size_t i = 0; i < num_bkp; i++) { json_t *budikeypair = GNUNET_JSON_PACK ( @@ -213,7 +210,6 @@ handle_batch_issue_finished (void *cls, { struct DONAU_BatchIssueReceiptHandle *birh = cls; const json_t *j = resp_obj; - struct DONAU_BatchIssueResponse biresp = { .hr.reply = j, .hr.http_status = (unsigned int) response_code diff --git a/src/lib/donau_api_batch_submit_receipts.c b/src/lib/donau_api_batch_submit_receipts.c @@ -76,16 +76,16 @@ struct DONAU_DonorReceiptsToStatementHandle * @param year corresponding year * @param h_tax_id salted and hashed tax id */ -json_t * -submit_request_body_to_json (const size_t num_drs, - const struct - DONAU_DonationReceipt drs[num_drs], - const uint64_t year, - const struct DONAU_HashDonorTaxId *h_tax_id) +static json_t * +submit_request_body_to_json ( + const size_t num_drs, + const struct DONAU_DonationReceipt drs[num_drs], + const uint64_t year, + const struct DONAU_HashDonorTaxId *h_tax_id) { json_t *donation_receipts = json_array (); - GNUNET_assert (NULL != donation_receipts); + GNUNET_assert (NULL != donation_receipts); for (size_t i = 0; i < num_drs; i++) { json_t *receipt = GNUNET_JSON_PACK ( @@ -95,6 +95,7 @@ submit_request_body_to_json (const size_t num_drs, &drs[i].nonce), DONAU_JSON_pack_donation_unit_sig ("donation_unit_sig", &drs[i].donation_unit_sig)); + GNUNET_assert (0 == json_array_append_new (donation_receipts, receipt)); @@ -124,7 +125,6 @@ handle_batch_submit_finished (void *cls, { struct DONAU_DonorReceiptsToStatementHandle *birh = cls; const json_t *j = resp_obj; - struct DONAU_DonorReceiptsToStatementResult biresp = { .hr.reply = j, .hr.http_status = (unsigned int) response_code @@ -192,12 +192,12 @@ DONAU_donor_receipts_to_statement ( void *cls) { struct DONAU_DonorReceiptsToStatementHandle *birh; - birh = GNUNET_new (struct DONAU_DonorReceiptsToStatementHandle); CURL *eh; json_t *body; TALER_LOG_DEBUG ("Connecting to the donau (%s)\n", url); + birh = GNUNET_new (struct DONAU_DonorReceiptsToStatementHandle); birh->url = GNUNET_strdup (url); birh->cb = cb; birh->cb_cls = cls; diff --git a/src/lib/donau_api_charity_post.c b/src/lib/donau_api_charity_post.c @@ -77,8 +77,8 @@ struct DONAU_CharityPostHandle */ static void handle_charity_post_finished (void *cls, - long response_code, - const void *resp_obj) + long response_code, + const void *resp_obj) { struct DONAU_CharityPostHandle *cph = cls; const json_t *j = resp_obj; @@ -92,21 +92,24 @@ handle_charity_post_finished (void *cls, switch (response_code) { case MHD_HTTP_CREATED: - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_uint64 ("charity-id", - &pcresp.details.ok.charity_id), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (j, - spec, - NULL, - NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not parse response from charity POST\n"); - GNUNET_break_op (0); - } + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_uint64 ("charity-id", + &pcresp.details.ok.charity_id), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not parse response from charity POST\n"); + GNUNET_break_op (0); + } + } break; case MHD_HTTP_NO_CONTENT: pcresp.hr.ec = TALER_JSON_get_error_code (j); @@ -167,12 +170,12 @@ DONAU_charity_post ( cph->cb_cls = cb_cls; cph->ctx = ctx; cph->url = TALER_url_join (url, - "charities", + "charities", NULL); if (NULL == cph->url) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not construct request URL.\n"); GNUNET_free (cph); return NULL; } @@ -180,18 +183,18 @@ DONAU_charity_post ( "POST a charity with URL `%s'.\n", cph->url); body = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("charity_pub", - &charity_req->charity_pub), - GNUNET_JSON_pack_string ("charity_url", - charity_req->charity_url), - GNUNET_JSON_pack_string ("charity_name", - charity_req->name), - TALER_JSON_pack_amount ("max_per_year", - &charity_req->max_per_year), - TALER_JSON_pack_amount ("receipts_to_date", - &charity_req->receipts_to_date), // really needed? - GNUNET_JSON_pack_uint64 ("current_year", - charity_req->current_year)); + GNUNET_JSON_pack_data_auto ("charity_pub", + &charity_req->charity_pub), + GNUNET_JSON_pack_string ("charity_url", + charity_req->charity_url), + GNUNET_JSON_pack_string ("charity_name", + charity_req->name), + TALER_JSON_pack_amount ("max_per_year", + &charity_req->max_per_year), + TALER_JSON_pack_amount ("receipts_to_date", + &charity_req->receipts_to_date), // really needed? + GNUNET_JSON_pack_uint64 ("current_year", + charity_req->current_year)); eh = DONAU_curl_easy_get_ (cph->url); if ( (NULL == eh) || (GNUNET_OK != @@ -208,10 +211,10 @@ DONAU_charity_post ( } json_decref (body); cph->job = GNUNET_CURL_job_add2 (ctx, - eh, - cph->post_ctx.headers, - &handle_charity_post_finished, - cph); + eh, + cph->post_ctx.headers, + &handle_charity_post_finished, + cph); return cph; } diff --git a/src/lib/donau_api_csr_post.c b/src/lib/donau_api_csr_post.c @@ -92,26 +92,30 @@ handle_csr_issue_post_finished (void *cls, switch (response_code) { case MHD_HTTP_CREATED: - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_exchange_withdraw_values ( // FIXME: method for GNUNET - "ewv", - (struct TALER_ExchangeWithdrawValues *) &csrresp.details.ok.alg_values), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (j, - spec, - NULL, - NULL)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not parse response from csr POST\n"); - GNUNET_break_op (0); + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_exchange_blinding_values ( + "ewv", + (struct TALER_ExchangeBlindingValues *) &csrresp.details.ok.alg_values + ), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not parse response from csr POST\n"); + GNUNET_break_op (0); + } + csrh->cb (csrh->cb_cls, + &csrresp); + csrh->cb = NULL; + break; } - csrh->cb (csrh->cb_cls, - &csrresp); - csrh->cb = NULL; - break; // Donation unit was revoked. case MHD_HTTP_GONE: csrresp.hr.ec = TALER_JSON_get_error_code (j); diff --git a/src/lib/donau_api_donation_statement_get.c b/src/lib/donau_api_donation_statement_get.c @@ -94,32 +94,35 @@ handle_donation_statement_get_finished (void *cls, dsresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ( - "donation_statement_sig", - &dsresp.details.ok.donation_statement_sig), - TALER_JSON_spec_amount_any ("total", - &dsresp.details.ok.total_amount), - GNUNET_JSON_spec_fixed_auto ("donau_pub", - &dsresp.details.ok.donau_pub), - GNUNET_JSON_spec_end () - }; - if (GNUNET_OK != - GNUNET_JSON_parse (j, - spec, - NULL, - NULL)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not parse response from donation-statement GET\n"); - GNUNET_break_op (0); - dsresp.hr.http_status = 0; - dsresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ( + "donation_statement_sig", + &dsresp.details.ok.donation_statement_sig), + TALER_JSON_spec_amount_any ("total", + &dsresp.details.ok.total_amount), + GNUNET_JSON_spec_fixed_auto ("donau_pub", + &dsresp.details.ok.donau_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not parse response from donation-statement GET\n"); + GNUNET_break_op (0); + dsresp.hr.http_status = 0; + dsresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + } + dsgh->cb (dsgh->cb_cls, + &dsresp); + dsgh->cb = NULL; + break; } - dsgh->cb (dsgh->cb_cls, - &dsresp); - dsgh->cb = NULL; - break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the donau is buggy (or API version conflict); just pass JSON reply to the application */ diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c @@ -28,8 +28,10 @@ #include <taler/taler_json_lib.h> #include "donau_service.h" #include "donau_api_curl_defaults.h" +#include "donau_util.h" #include "donau_json_lib.h" + /** * Which version of the Donau protocol is implemented * by this library? Used to determine compatibility. @@ -68,7 +70,7 @@ * how long do we assume the reply to be valid at least? */ #define MINIMUM_EXPIRATION GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MINUTES, 2) + GNUNET_TIME_UNIT_MINUTES, 2) /** @@ -118,9 +120,9 @@ struct DONAU_GetKeysHandle #define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) + do { \ + if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ + } while (0) /** * Parse a donau's signing key encoded in JSON. @@ -524,29 +526,6 @@ DONAU_get_donation_unit_key ( } -struct DONAU_DonationUnitInformation * -DONAU_copy_donation_unit_key ( - const struct DONAU_DonationUnitInformation *key) -{ - struct DONAU_DonationUnitInformation *copy; - - copy = GNUNET_new (struct DONAU_DonationUnitInformation); - *copy = *key; - DONAU_donation_unit_pub_deep_copy (&copy->key, // only increments rc, still same pointer - &key->key); - return copy; -} - - -void -DONAU_destroy_donation_unit_key ( - struct DONAU_DonationUnitInformation *key) -{ - DONAU_donation_unit_pub_free (&key->key); - GNUNET_free (key); -} - - const struct DONAU_DonationUnitInformation * DONAU_get_donation_unit_key_by_hash ( const struct DONAU_Keys *keys, @@ -660,60 +639,15 @@ struct GroupData }; -/** - * Add donation unit group represented by @a value - * to list of donation units in @a cls. Also frees - * the @a value. - * - * @param[in,out] cls a `json_t *` with an array to build - * @param key unused - * @param value a `struct GroupData *` - * @return #GNUNET_OK (continue to iterate) - */ -static enum GNUNET_GenericReturnValue -add_grp (void *cls, - const struct GNUNET_HashCode *key, - void *value) -{ - json_t *donation_units_by_group = cls; - struct GroupData *gd = value; - const char *cipher; - json_t *ge; - - (void) key; - switch (gd->meta.cipher) - { - case GNUNET_CRYPTO_BSA_RSA: - cipher = "RSA"; - break; - case GNUNET_CRYPTO_BSA_CS: - cipher = "CS"; - break; - default: - GNUNET_assert (false); - } - - ge = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - cipher), - GNUNET_JSON_pack_array_steal ("donation_units", - gd->json), - TALER_JSON_pack_amount ("value", - &gd->meta.value)); - GNUNET_assert (0 == - json_array_append_new (donation_units_by_group, - ge)); - GNUNET_free (gd); - return GNUNET_OK; -} - - json_t * DONAU_keys_to_json (const struct DONAU_Keys *kd) { // --- Create the array of signkeys (unchanged) --- json_t *signkeys = json_array (); json_t *keys; + json_t *donation_units; + json_t *currency_spec = NULL; + GNUNET_assert (NULL != signkeys); for (unsigned int i = 0; i < kd->num_sign_keys; i++) { @@ -734,7 +668,7 @@ DONAU_keys_to_json (const struct DONAU_Keys *kd) } // --- Create the array of donation_units --- - json_t *donation_units = json_array (); + donation_units = json_array (); GNUNET_assert (NULL != donation_units); for (unsigned int i = 0; i < kd->num_donation_unit_keys; i++) { @@ -746,7 +680,7 @@ DONAU_keys_to_json (const struct DONAU_Keys *kd) GNUNET_JSON_pack_uint64 ("year", du->year), GNUNET_JSON_pack_bool ("lost", du->lost), TALER_JSON_pack_amount ("value", &du->value) - ); + ); GNUNET_assert (NULL != donation_unit_obj); GNUNET_assert (0 == @@ -754,12 +688,11 @@ DONAU_keys_to_json (const struct DONAU_Keys *kd) donation_unit_obj)); } - json_t *currency_spec = NULL; if (NULL != kd->currency_specification.name) { currency_spec = TALER_CONFIG_currency_specs_to_json ( &kd->currency_specification - ); + ); } keys = GNUNET_JSON_PACK ( diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c @@ -23,6 +23,7 @@ #include <gnunet/gnunet_pq_lib.h> #include <taler/taler_pq_lib.h> #include "donau_util.h" +#include "donau_pq_lib.h" #include "pq_common.h" @@ -778,19 +779,17 @@ array_cleanup (void *cls, { struct ArrayResultCls *info = cls; void **dst = rd; + struct DONAU_BlindedDonationUnitSignature *du_sigs = *dst; - if ((0 == info->same_size) && - (NULL != info->sizes)) + if ( (0 == info->same_size) && + (NULL != info->sizes) ) GNUNET_free (*(info->sizes)); - struct DONAU_BlindedDonationUnitSignature *du_sigs = *dst; GNUNET_assert (NULL != info->num); for (size_t i = 0; i < *info->num; i++) GNUNET_free (du_sigs[i].blinded_sig); - GNUNET_free (cls); GNUNET_free (*dst); - *dst = NULL; } @@ -809,16 +808,17 @@ DONAU_PQ_result_spec_array_blinded_donation_unit_sig ( GNUNET_PQ_get_oid_by_name (db, "bytea", &info->oid)); + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = array_cleanup, + .dst = (void *) du_sigs, + .fname = name, + .cls = info + }; - struct GNUNET_PQ_ResultSpec res = { - .conv = extract_array_generic, - .cleaner = array_cleanup, - .dst = (void *) du_sigs, - .fname = name, - .cls = info - }; - return res; - + return res; + } } diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -20,7 +20,8 @@ */ #include "donau_config.h" #include <taler/taler_pq_lib.h> -#include <donau_util.h> +#include "donau_util.h" +#include "donau_pq_lib.h" /** * Extract data from a Postgres database @a result at row @a row. diff --git a/src/util/donau_os_installation.c b/src/util/donau_os_installation.c @@ -24,6 +24,7 @@ * @author Lukas Matyja */ #include "donau_config.h" +#include "donau_util.h" #include <taler/taler_util.h> #include <gnunet/gnunet_util_lib.h> diff --git a/src/util/qr.c b/src/util/qr.c @@ -30,45 +30,32 @@ generate_QR_string (const struct DONAU_DonauPublicKeyP *pub_key, const struct DONAU_DonationStatement *donation_statement) { /* The string will be structured as follows: YEAR/TOTALAMOUNT/TAXID/TAXIDSALT/ED25519SIGNATURE/PUBKEY */ - uint64_t total_size = 0; - - char *total_amount_string = TALER_amount_to_string ( - &donation_statement->total_amount); - total_size += strlen (total_amount_string); - total_size += strlen (donation_statement->donor_tax_id); - total_size += strlen (donation_statement->salt); - char *end_sig; - total_size += sizeof (struct DONAU_DonauSignatureP) * 2; + char *end_pub; char sig_str[sizeof (struct DONAU_DonauSignatureP) * 2]; + char pub_str[sizeof (struct DONAU_DonauPublicKeyP) * 2]; + char *qr_string; + end_sig = GNUNET_STRINGS_data_to_string ( &donation_statement->donation_statement_sig, sizeof (struct DONAU_DonauSignatureP), sig_str, sizeof (sig_str)); *end_sig = '\0'; - - char *end_pub; - total_size += sizeof (struct DONAU_DonauPublicKeyP) * 2; - char pub_str[sizeof (struct DONAU_DonauPublicKeyP) * 2]; end_pub = GNUNET_STRINGS_data_to_string ( pub_key, sizeof (struct DONAU_DonauPublicKeyP), pub_str, sizeof (pub_str)); *end_pub = '\0'; - - char *qr_string = GNUNET_malloc (total_size + 1); - GNUNET_assert (0 <= GNUNET_snprintf (qr_string, - total_size, - "%llu/%s/%s/%s/%s/%s", - (unsigned long long) - donation_statement->year, - total_amount_string, - donation_statement->donor_tax_id, - donation_statement->salt, - sig_str, - pub_str)); - + GNUNET_asprintf (&qr_string, + "%llu/%s/%s/%s/%s/%s", + (unsigned long long) + donation_statement->year, + TALER_amount2s (&donation_statement->total_amount), + donation_statement->donor_tax_id, + donation_statement->salt, + sig_str, + pub_str); return qr_string; }