diff options
author | ng0 <ng0@n0.is> | 2019-05-07 14:35:32 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-05-07 14:35:32 +0000 |
commit | 105555b46975edef914fc39195941cf14d64e760 (patch) | |
tree | 81f2529f09a7b66f4510a8f6ef8099ce3ea2acfe /src/lib | |
parent | 0d8f5035437d5a0daff3505978bc60dad50f55f2 (diff) | |
parent | a16c32a4745634b77439200ee4831fed2811fd8a (diff) | |
download | exchange-105555b46975edef914fc39195941cf14d64e760.tar.gz exchange-105555b46975edef914fc39195941cf14d64e760.tar.bz2 exchange-105555b46975edef914fc39195941cf14d64e760.zip |
Merge branch 'master' of git.taler.net:exchange
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile.am | 6 | ||||
-rw-r--r-- | src/lib/auditor_api_curl_defaults.c | 2 | ||||
-rw-r--r-- | src/lib/auditor_api_deposit_confirmation.c | 39 | ||||
-rw-r--r-- | src/lib/auditor_api_handle.c | 12 | ||||
-rw-r--r-- | src/lib/auditor_api_handle.h | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_curl_defaults.c | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_deposit.c | 43 | ||||
-rw-r--r-- | src/lib/exchange_api_handle.c | 10 | ||||
-rw-r--r-- | src/lib/exchange_api_handle.h | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_payback.c | 34 | ||||
-rw-r--r-- | src/lib/exchange_api_refresh.c | 67 | ||||
-rw-r--r-- | src/lib/exchange_api_refund.c | 30 | ||||
-rw-r--r-- | src/lib/exchange_api_reserve.c | 43 | ||||
-rw-r--r-- | src/lib/exchange_api_track_transaction.c | 32 | ||||
-rw-r--r-- | src/lib/teah_common.c | 105 | ||||
-rw-r--r-- | src/lib/teah_common.h | 74 |
16 files changed, 361 insertions, 142 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8b20860b7..0aa78d7b8 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -27,7 +27,8 @@ libtalerexchange_la_SOURCES = \ exchange_api_reserve.c \ exchange_api_track_transaction.c \ exchange_api_track_transfer.c \ - exchange_api_wire.c + exchange_api_wire.c \ + teah_common.c teah_common.h libtalerexchange_la_LIBADD = \ libtalerauditor.la \ $(top_builddir)/src/json/libtalerjson.la \ @@ -46,7 +47,8 @@ libtalerauditor_la_SOURCES = \ auditor_api_curl_defaults.c auditor_api_curl_defaults.h \ auditor_api_handle.c auditor_api_handle.h \ auditor_api_deposit_confirmation.c \ - auditor_api_exchanges.c + auditor_api_exchanges.c \ + teah_common.c teah_common.h libtalerauditor_la_LIBADD = \ $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ diff --git a/src/lib/auditor_api_curl_defaults.c b/src/lib/auditor_api_curl_defaults.c index d5b924008..507ae0e55 100644 --- a/src/lib/auditor_api_curl_defaults.c +++ b/src/lib/auditor_api_curl_defaults.c @@ -44,12 +44,10 @@ TAL_curl_easy_get (const char *url) curl_easy_setopt (eh, CURLOPT_ENCODING, "deflate")); -#ifdef CURLOPT_TCP_FASTOPEN GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TCP_FASTOPEN, 1L)); -#endif { /* Unfortunately libcurl needs chunk to be alive until after curl_easy_perform. To avoid manual cleanup, we keep diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index c34890e63..bb637797a 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -49,9 +49,10 @@ struct TALER_AUDITOR_DepositConfirmationHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -338,26 +339,26 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor, dh->url = MAH_path_to_url (auditor, "/deposit-confirmation"); eh = TAL_curl_easy_get (dh->url); - GNUNET_assert (NULL != (dh->json_enc = - json_dumps (deposit_confirmation_obj, - JSON_COMPACT))); - json_decref (deposit_confirmation_obj); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "URL for deposit-confirmation: `%s'\n", - dh->url); - GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_CUSTOMREQUEST, "PUT")); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - dh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (dh->json_enc))); + if (GNUNET_OK != + TEAH_curl_easy_post (&dh->ctx, + eh, + deposit_confirmation_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (deposit_confirmation_obj); + GNUNET_free (dh->url); + GNUNET_free (dh); + return NULL; + } + json_decref (deposit_confirmation_obj); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "URL for deposit-confirmation: `%s'\n", + dh->url); ctx = MAH_handle_to_context (auditor); dh->job = GNUNET_CURL_job_add (ctx, eh, @@ -383,7 +384,7 @@ TALER_AUDITOR_deposit_confirmation_cancel (struct TALER_AUDITOR_DepositConfirmat deposit_confirmation->job = NULL; } GNUNET_free (deposit_confirmation->url); - GNUNET_free (deposit_confirmation->json_enc); + TEAH_curl_easy_post_finished (&deposit_confirmation->ctx); GNUNET_free (deposit_confirmation); } diff --git a/src/lib/auditor_api_handle.c b/src/lib/auditor_api_handle.c index 70bf6f715..870eed83d 100644 --- a/src/lib/auditor_api_handle.c +++ b/src/lib/auditor_api_handle.c @@ -15,7 +15,7 @@ <http://www.gnu.org/licenses/> */ /** - * @file auditor-lib/auditor_api_handle.c + * @file lib/auditor_api_handle.c * @brief Implementation of the "handle" component of the auditor's HTTP API * @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Christian Grothoff @@ -462,6 +462,16 @@ TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to auditor at URL `%s'.\n", url); + /* Disable 100 continue processing */ + GNUNET_break (GNUNET_OK == + GNUNET_CURL_append_header (ctx, + "Expect:")); +#if COMPRESS_BODIES + /* Tell auditor we compress bodies */ + GNUNET_break (GNUNET_OK == + GNUNET_CURL_append_header (ctx, + "Content-encoding: deflate")); +#endif auditor = GNUNET_new (struct TALER_AUDITOR_Handle); auditor->ctx = ctx; auditor->url = GNUNET_strdup (url); diff --git a/src/lib/auditor_api_handle.h b/src/lib/auditor_api_handle.h index c3c73f5c3..c053cbbc0 100644 --- a/src/lib/auditor_api_handle.h +++ b/src/lib/auditor_api_handle.h @@ -22,7 +22,7 @@ #include "platform.h" #include <gnunet/gnunet_curl_lib.h> #include "taler_auditor_service.h" - +#include "teah_common.h" /** * Get the context of a auditor. diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c index 3ac1dfdbe..57fae166d 100644 --- a/src/lib/exchange_api_curl_defaults.c +++ b/src/lib/exchange_api_curl_defaults.c @@ -49,11 +49,9 @@ TEL_curl_easy_get (const char *url) curl_easy_setopt (eh, CURLOPT_FOLLOWLOCATION, 1L)); -#ifdef CURLOPT_TCP_FASTOPEN GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TCP_FASTOPEN, 1L)); -#endif return eh; } diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 3f72ad956..b99c7a93f 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -60,9 +60,10 @@ struct TALER_EXCHANGE_DepositHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -359,6 +360,7 @@ handle_deposit_finished (void *cls, * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) * @param coin_pub coin’s public key * @param denom_pub denomination key with which the coin is signed + * @param denom_pub_hash hash of @a denom_pub * @param denom_sig exchange’s unblinded signature of the coin * @param timestamp timestamp when the deposit was finalized * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) @@ -374,6 +376,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_DenominationSignature *denom_sig, const struct TALER_DenominationPublicKey *denom_pub, + const struct GNUNET_HashCode *denom_pub_hash, struct GNUNET_TIME_Absolute timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, struct GNUNET_TIME_Absolute refund_deadline, @@ -414,10 +417,11 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, /* check coin signature */ coin_info.coin_pub = *coin_pub; - coin_info.denom_pub = *denom_pub; + coin_info.denom_pub_hash = *denom_pub_hash; coin_info.denom_sig = *denom_sig; if (GNUNET_YES != - TALER_test_coin_valid (&coin_info)) + TALER_test_coin_valid (&coin_info, + denom_pub)) { GNUNET_break_op (0); TALER_LOG_WARNING ("Invalid coin passed for /deposit\n"); @@ -489,6 +493,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, json_t *deposit_obj; CURL *eh; struct GNUNET_HashCode h_wire; + struct GNUNET_HashCode denom_pub_hash; struct TALER_Amount amount_without_fee; (void) GNUNET_TIME_round_abs (&wire_deadline); @@ -512,6 +517,8 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, TALER_amount_subtract (&amount_without_fee, amount, &dki->fee_deposit)); + GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, + &denom_pub_hash); if (GNUNET_OK != verify_signatures (dki, amount, @@ -520,6 +527,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, coin_pub, denom_sig, denom_pub, + &denom_pub_hash, timestamp, merchant_pub, refund_deadline, @@ -541,7 +549,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, "H_wire", GNUNET_JSON_from_data_auto (&h_wire), "h_contract_terms", GNUNET_JSON_from_data_auto (h_contract_terms), "coin_pub", GNUNET_JSON_from_data_auto (coin_pub), - "denom_pub", GNUNET_JSON_from_rsa_public_key (denom_pub->rsa_public_key), + "denom_pub_hash", GNUNET_JSON_from_data_auto (&denom_pub_hash), "ub_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature), "timestamp", GNUNET_JSON_from_time_abs (timestamp), "merchant_pub", GNUNET_JSON_from_data_auto (merchant_pub), @@ -574,21 +582,22 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, dh->coin_value = dki->value; eh = TEL_curl_easy_get (dh->url); - GNUNET_assert (NULL != (dh->json_enc = - json_dumps (deposit_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&dh->ctx, + eh, + deposit_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (deposit_obj); + GNUNET_free (dh->url); + GNUNET_free (dh); + return NULL; + } json_decref (deposit_obj); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URL for deposit: `%s'\n", dh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - dh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (dh->json_enc))); ctx = TEAH_handle_to_context (exchange); dh->job = GNUNET_CURL_job_add (ctx, eh, @@ -614,7 +623,7 @@ TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit) deposit->job = NULL; } GNUNET_free (deposit->url); - GNUNET_free (deposit->json_enc); + TEAH_curl_easy_post_finished (&deposit->ctx); GNUNET_free (deposit); } diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index cbcde724d..0f3cfe0ae 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -33,6 +33,7 @@ #include "exchange_api_handle.h" #include "exchange_api_curl_defaults.h" #include "backoff.h" +#include "teah_common.h" /** * Which revision of the Taler protocol is implemented @@ -432,7 +433,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key, */ static int parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, - int check_sigs, + int check_sigs, json_t *denom_key_obj, struct TALER_MasterPublicKeyP *master_key, struct GNUNET_HashContext *hash_context) @@ -1783,6 +1784,12 @@ TALER_EXCHANGE_connect GNUNET_break (GNUNET_OK == GNUNET_CURL_append_header (ctx, "Expect:")); +#if COMPRESS_BODIES + /* Tell exchange we compress bodies */ + GNUNET_break (GNUNET_OK == + GNUNET_CURL_append_header (ctx, + "Content-encoding: deflate")); +#endif exchange = GNUNET_new (struct TALER_EXCHANGE_Handle); exchange->ctx = ctx; exchange->url = GNUNET_strdup (url); @@ -1816,6 +1823,7 @@ TALER_EXCHANGE_connect } + /** * Initiate download of /keys from the exchange. * diff --git a/src/lib/exchange_api_handle.h b/src/lib/exchange_api_handle.h index 2c01e319a..6bb3fff28 100644 --- a/src/lib/exchange_api_handle.h +++ b/src/lib/exchange_api_handle.h @@ -24,7 +24,7 @@ #include "taler_auditor_service.h" #include "taler_exchange_service.h" #include "taler_crypto_lib.h" - +#include "teah_common.h" /** * Entry in DLL of auditors used by an exchange. diff --git a/src/lib/exchange_api_payback.c b/src/lib/exchange_api_payback.c index 6c1772aff..325263d71 100644 --- a/src/lib/exchange_api_payback.c +++ b/src/lib/exchange_api_payback.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_PaybackHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Denomination key of the coin. @@ -280,6 +281,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *ctx; struct TALER_PaybackRequestPS pr; struct TALER_CoinSpendSignatureP coin_sig; + struct GNUNET_HashCode h_denom_pub; json_t *payback_obj; CURL *eh; @@ -289,6 +291,8 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange, pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS)); GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv, &pr.coin_pub.eddsa_pub); + GNUNET_CRYPTO_rsa_public_key_hash (pk->key.rsa_public_key, + &h_denom_pub); pr.h_denom_pub = pk->h_key; pr.coin_blind = ps->blinding_key; GNUNET_assert (GNUNET_OK == @@ -299,7 +303,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange, payback_obj = json_pack ("{s:o, s:o," /* denom pub/sig */ " s:o, s:o," /* coin pub/sig */ " s:o}", /* coin_bks */ - "denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key), + "denom_pub_hash", GNUNET_JSON_from_data_auto (&h_denom_pub), "denom_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature), "coin_pub", GNUNET_JSON_from_data_auto (&pr.coin_pub), "coin_sig", GNUNET_JSON_from_data_auto (&coin_sig), @@ -318,29 +322,23 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange, ph->cb = payback_cb; ph->cb_cls = payback_cb_cls; ph->url = TEAH_path_to_url (exchange, "/payback"); - - ph->json_enc = json_dumps (payback_obj, - JSON_COMPACT); - json_decref (payback_obj); - if (NULL == ph->json_enc) + eh = TEL_curl_easy_get (ph->url); + if (GNUNET_OK != + TEAH_curl_easy_post (&ph->ctx, + eh, + payback_obj)) { GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (payback_obj); GNUNET_free (ph->url); GNUNET_free (ph); return NULL; } - eh = TEL_curl_easy_get (ph->url); + json_decref (payback_obj); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URL for payback: `%s'\n", ph->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - ph->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (ph->json_enc))); ctx = TEAH_handle_to_context (exchange); ph->job = GNUNET_CURL_job_add (ctx, eh, @@ -366,7 +364,7 @@ TALER_EXCHANGE_payback_cancel (struct TALER_EXCHANGE_PaybackHandle *ph) ph->job = NULL; } GNUNET_free (ph->url); - GNUNET_free (ph->json_enc); + TEAH_curl_easy_post_finished (&ph->ctx); GNUNET_free (ph); } diff --git a/src/lib/exchange_api_refresh.c b/src/lib/exchange_api_refresh.c index 230f445e6..30025d778 100644 --- a/src/lib/exchange_api_refresh.c +++ b/src/lib/exchange_api_refresh.c @@ -834,9 +834,10 @@ struct TALER_EXCHANGE_RefreshMeltHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -1151,6 +1152,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, struct MeltData *md; struct TALER_CoinSpendSignatureP confirm_sig; struct TALER_RefreshMeltCoinAffirmationPS melt; + struct GNUNET_HashCode h_denom_pub; GNUNET_assert (GNUNET_YES == TEAH_handle_is_ready (exchange)); @@ -1174,11 +1176,13 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_CRYPTO_eddsa_sign (&md->melted_coin.coin_priv.eddsa_priv, &melt.purpose, &confirm_sig.eddsa_signature); + GNUNET_CRYPTO_rsa_public_key_hash (md->melted_coin.pub_key.rsa_public_key, + &h_denom_pub); melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", "coin_pub", GNUNET_JSON_from_data_auto (&melt.coin_pub), - "denom_pub", - GNUNET_JSON_from_rsa_public_key (md->melted_coin.pub_key.rsa_public_key), + "denom_pub_hash", + GNUNET_JSON_from_data_auto (&h_denom_pub), "denom_sig", GNUNET_JSON_from_rsa_signature (md->melted_coin.sig.rsa_signature), "confirm_sig", @@ -1203,18 +1207,19 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, rmh->url = TEAH_path_to_url (exchange, "/refresh/melt"); eh = TEL_curl_easy_get (rmh->url); - GNUNET_assert (NULL != (rmh->json_enc = - json_dumps (melt_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&rmh->ctx, + eh, + melt_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (melt_obj); + GNUNET_free (rmh->url); + GNUNET_free (rmh); + return NULL; + } json_decref (melt_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - rmh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (rmh->json_enc))); ctx = TEAH_handle_to_context (exchange); rmh->job = GNUNET_CURL_job_add (ctx, eh, @@ -1242,7 +1247,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh free_melt_data (rmh->md); /* does not free 'md' itself */ GNUNET_free (rmh->md); GNUNET_free (rmh->url); - GNUNET_free (rmh->json_enc); + TEAH_curl_easy_post_finished (&rmh->ctx); GNUNET_free (rmh); } @@ -1267,9 +1272,10 @@ struct TALER_EXCHANGE_RefreshRevealHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -1631,18 +1637,19 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, "/refresh/reveal"); eh = TEL_curl_easy_get (rrh->url); - GNUNET_assert (NULL != (rrh->json_enc = - json_dumps (reveal_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&rrh->ctx, + eh, + reveal_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (reveal_obj); + GNUNET_free (rrh->url); + GNUNET_free (rrh); + return NULL; + } json_decref (reveal_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - rrh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (rrh->json_enc))); ctx = TEAH_handle_to_context (rrh->exchange); rrh->job = GNUNET_CURL_job_add (ctx, eh, @@ -1668,7 +1675,7 @@ TALER_EXCHANGE_refresh_reveal_cancel (struct TALER_EXCHANGE_RefreshRevealHandle rrh->job = NULL; } GNUNET_free (rrh->url); - GNUNET_free (rrh->json_enc); + TEAH_curl_easy_post_finished (&rrh->ctx); free_melt_data (rrh->md); /* does not free 'md' itself */ GNUNET_free (rrh->md); GNUNET_free (rrh); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 75ebdc4e3..142213177 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_RefundHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -368,21 +369,22 @@ refund_obj = json_pack ("{s:o, s:o," /* amount/fee */ refund_fee); eh = TEL_curl_easy_get (rh->url); - GNUNET_assert (NULL != (rh->json_enc = - json_dumps (refund_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&rh->ctx, + eh, + refund_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (refund_obj); + GNUNET_free (rh->url); + GNUNET_free (rh); + return NULL; + } json_decref (refund_obj); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URL for refund: `%s'\n", rh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - rh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (rh->json_enc))); ctx = TEAH_handle_to_context (exchange); rh->job = GNUNET_CURL_job_add (ctx, eh, @@ -408,7 +410,7 @@ TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund) refund->job = NULL; } GNUNET_free (refund->url); - GNUNET_free (refund->json_enc); + TEAH_curl_easy_post_finished (&refund->ctx); GNUNET_free (refund); } diff --git a/src/lib/exchange_api_reserve.c b/src/lib/exchange_api_reserve.c index 4aa5794fa..ae0bd01d0 100644 --- a/src/lib/exchange_api_reserve.c +++ b/src/lib/exchange_api_reserve.c @@ -187,8 +187,8 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_JSON_Specification withdraw_spec[] = { GNUNET_JSON_spec_fixed_auto ("reserve_sig", &sig), - TALER_JSON_spec_amount_nbo ("withdraw_fee", - &withdraw_purpose.withdraw_fee), + TALER_JSON_spec_amount_nbo ("withdraw_fee", + &withdraw_purpose.withdraw_fee), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", &withdraw_purpose.h_denomination_pub), GNUNET_JSON_spec_fixed_auto ("h_coin_envelope", @@ -677,9 +677,10 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -1001,6 +1002,7 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *ctx; json_t *withdraw_obj; CURL *eh; + struct GNUNET_HashCode h_denom_pub; wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle); wsh->exchange = exchange; @@ -1009,9 +1011,11 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, wsh->pk = pk; wsh->reserve_pub = *reserve_pub; wsh->c_hash = pd->c_hash; - withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */ + GNUNET_CRYPTO_rsa_public_key_hash (pk->key.rsa_public_key, + &h_denom_pub); + withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub_hash and coin_ev */ " s:o, s:o}",/* reserve_pub and reserve_sig */ - "denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key), + "denom_pub_hash", GNUNET_JSON_from_data_auto (&h_denom_pub), "coin_ev", GNUNET_JSON_from_data (pd->coin_ev, pd->coin_ev_size), "reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub), @@ -1019,25 +1023,26 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange, if (NULL == withdraw_obj) { GNUNET_break (0); + GNUNET_free (wsh); return NULL; } wsh->ps = *ps; wsh->url = TEAH_path_to_url (exchange, "/reserve/withdraw"); - eh = TEL_curl_easy_get (wsh->url); - GNUNET_assert (NULL != (wsh->json_enc = - json_dumps (withdraw_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&wsh->ctx, + eh, + withdraw_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (withdraw_obj); + GNUNET_free (wsh->url); + GNUNET_free (wsh); + return NULL; + } json_decref (withdraw_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - wsh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (wsh->json_enc))); ctx = TEAH_handle_to_context (exchange); wsh->job = GNUNET_CURL_job_add (ctx, eh, @@ -1196,7 +1201,7 @@ TALER_EXCHANGE_reserve_withdraw_cancel (struct TALER_EXCHANGE_ReserveWithdrawHan sign->job = NULL; } GNUNET_free (sign->url); - GNUNET_free (sign->json_enc); + TEAH_curl_easy_post_finished (&sign->ctx); GNUNET_free (sign); } diff --git a/src/lib/exchange_api_track_transaction.c b/src/lib/exchange_api_track_transaction.c index 0942ce84a..67efd77af 100644 --- a/src/lib/exchange_api_track_transaction.c +++ b/src/lib/exchange_api_track_transaction.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_TrackTransactionHandle char *url; /** - * JSON encoding of the request to POST. + * Context for #TEH_curl_easy_post(). Keeps the data that must + * persist for Curl to make the upload. */ - char *json_enc; + struct TEAH_PostContext ctx; /** * Handle for the request. @@ -322,18 +323,19 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange, dwh->depconf.coin_pub = *coin_pub; eh = TEL_curl_easy_get (dwh->url); - GNUNET_assert (NULL != (dwh->json_enc = - json_dumps (deposit_wtid_obj, - JSON_COMPACT))); + if (GNUNET_OK != + TEAH_curl_easy_post (&dwh->ctx, + eh, + deposit_wtid_obj)) + { + GNUNET_break (0); + curl_easy_cleanup (eh); + json_decref (deposit_wtid_obj); + GNUNET_free (dwh->url); + GNUNET_free (dwh); + return NULL; + } json_decref (deposit_wtid_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDS, - dwh->json_enc)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_POSTFIELDSIZE, - strlen (dwh->json_enc))); ctx = TEAH_handle_to_context (exchange); dwh->job = GNUNET_CURL_job_add (ctx, eh, @@ -359,9 +361,9 @@ TALER_EXCHANGE_track_transaction_cancel (struct TALER_EXCHANGE_TrackTransactionH dwh->job = NULL; } GNUNET_free (dwh->url); - GNUNET_free (dwh->json_enc); + TEAH_curl_easy_post_finished (&dwh->ctx); GNUNET_free (dwh); } -/* end of exchange_api_deposit_wtid.c */ +/* end of exchange_api_track_transaction.c */ diff --git a/src/lib/teah_common.c b/src/lib/teah_common.c new file mode 100644 index 000000000..8f994ef36 --- /dev/null +++ b/src/lib/teah_common.c @@ -0,0 +1,105 @@ +/* + This file is part of TALER + Copyright (C) 2019 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + TALER is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ + +/** + * @file lib/teah_common.c + * @brief Helper routines shared by libtalerexchange and libtalerauditor + * @author Christian Grothoff + */ +#include "platform.h" +#include "teah_common.h" + +#if COMPRESS_BODIES +#include <zlib.h> +#endif + + +/** + * Add the @a body as POST data to the easy handle in + * @a ctx. + * + * @param ctx[in,out] a request context (updated) + * @param eh easy handle to use + * @param body JSON body to add to @e ctx + * @return #GNUNET_OK on success #GNUNET_SYSERR on failure + */ +int +TEAH_curl_easy_post (struct TEAH_PostContext *ctx, + CURL *eh, + const json_t *body) +{ + char *str; + size_t slen; + + str = json_dumps (body, + JSON_COMPACT); + if (NULL == str) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + slen = strlen (str); +#if COMPRESS_BODIES + { + Bytef *cbuf; + uLongf cbuf_size; + int ret; + + cbuf_size = compressBound (slen); + cbuf = GNUNET_malloc (cbuf_size); + ret = compress (cbuf, + &cbuf_size, + (const Bytef *) str, + slen); + if (Z_OK != ret) + { + /* compression failed!? */ + GNUNET_break (0); + GNUNET_free (cbuf); + return GNUNET_SYSERR; + } + free (str); + slen = (size_t) cbuf_size; + ctx->json_enc = (char *) cbuf; + } +#else + ctx->json_enc = str; +#endif + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDS, + ctx->json_enc)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDSIZE, + slen)); + return GNUNET_OK; +} + + +/** + * Free the data in @a ctx. + * + * @param ctx[in] a request context (updated) + */ +void +TEAH_curl_easy_post_finished (struct TEAH_PostContext *ctx) +{ + GNUNET_free_non_null (ctx->json_enc); +} diff --git a/src/lib/teah_common.h b/src/lib/teah_common.h new file mode 100644 index 000000000..66937a261 --- /dev/null +++ b/src/lib/teah_common.h @@ -0,0 +1,74 @@ +/* + This file is part of TALER + Copyright (C) 2019 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + TALER is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/teah_common.h + * @brief Helper routines shared by libtalerexchange and libtalerauditor + * @author Christian Grothoff + */ +#ifndef TEAH_COMMON_H +#define TEAH_COMMON_H + +#include <gnunet/gnunet_curl_lib.h> +#include "taler_json_lib.h" + +/** + * Should we compress PUT/POST bodies with 'deflate' encoding? + */ +#define COMPRESS_BODIES 0 + +/** + * State used for #TEAL_curl_easy_post() and + * #TEAL_curl_easy_post_finished(). + */ +struct TEAH_PostContext +{ + /** + * JSON encoding of the request to POST. + */ + char *json_enc; + +}; + + +/** + * Add the @a body as POST data to the easy handle in + * @a ctx. + * + * @param ctx[in,out] a request context (updated) + * @param eh easy handle to use + * @param body JSON body to add to @e ctx + * @return #GNUNET_OK on success #GNUNET_SYSERR on failure + */ +int +TEAH_curl_easy_post (struct TEAH_PostContext *ctx, + CURL *eh, + const json_t *body); + + +/** + * Free the data in @a ctx. + * + * @param ctx[in] a request context (updated) + */ +void +TEAH_curl_easy_post_finished (struct TEAH_PostContext *ctx); + + + +#endif |