diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 6 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_pay.c | 76 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_proposal.c | 62 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_track-transaction.c | 40 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_track-transfer.c | 2 |
5 files changed, 144 insertions, 42 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 35894fde..b5632b09 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -164,7 +164,7 @@ url_handler (void *cls, { "/", MHD_HTTP_METHOD_GET, "text/plain", "Hello, I'm a merchant's Taler backend. This HTTP server is not for humans.\n", 0, &TMH_MHD_handler_static_response, MHD_HTTP_OK }, - { "/proposal", MHD_HTTP_METHOD_PUT, "application/json", + { "/proposal", MHD_HTTP_METHOD_POST, "application/json", NULL, 0, &MH_handler_proposal_put, MHD_HTTP_OK }, { "/pay", MHD_HTTP_METHOD_POST, "application/json", @@ -192,7 +192,7 @@ url_handler (void *cls, "Only GET is allowed", 0, &MH_handler_proposal_lookup, MHD_HTTP_OK}, { "/proposal", NULL, "text/plain", - "Only GET/PUT are allowed", 0, + "Only GET/POST are allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, {NULL, NULL, NULL, NULL, 0, 0 } @@ -723,7 +723,7 @@ run (void *cls, NULL); GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-merchant-httpd", - "INFO", + "DEBUG", NULL)); if (GNUNET_SYSERR == TMH_EXCHANGES_init (config)) diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c index 31eec043..de8649a3 100644 --- a/src/backend/taler-merchant-httpd_pay.c +++ b/src/backend/taler-merchant-httpd_pay.c @@ -159,7 +159,7 @@ struct PayContext /** * Transaction ID given in @e root. */ - const char *transaction_id; + const char *order_id; /** * Maximum fee the merchant is willing to pay, from @e root. @@ -395,9 +395,13 @@ deposit_cb (void *cls, return; } /* store result to DB */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing successful payment for h_proposal_data '%s'\n", + GNUNET_h2s (&pc->h_proposal_data)); + if (GNUNET_OK != db->store_deposit (db->cls, - pc->transaction_id, + &pc->h_proposal_data, &pc->mi->pubkey, &dc->coin_pub, &dc->amount_with_fee, @@ -430,9 +434,9 @@ deposit_cb (void *cls, resume_pay_with_response (pc, MHD_HTTP_OK, TMH_RESPONSE_make_json_pack ("{s:s, s:o}", - "merchant_sig", + "sig", json_string_value (GNUNET_JSON_from_data_auto (&sig)), - "hash", + "h_proposal_data", GNUNET_JSON_from_data (&pc->h_proposal_data, sizeof (struct GNUNET_HashCode)))); } @@ -854,6 +858,33 @@ get_instance (struct json_t *json); /** + * Just a stub used to double-check if a transaction + * has been correctly inserted into db. + * + * @param cls closure + * @param transaction_id of the contract + * @param merchant's public key + * @param exchange_uri URI of the exchange + * @param h_contract hash of the contract + * @param h_wire hash of our wire details + * @param timestamp time of the confirmation + * @param refund refund deadline + * @param total_amount total amount we receive for the contract after fees + */ +static void +transaction_double_check (void *cls, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *exchange_uri, + const struct GNUNET_HashCode *h_proposal_data, + const struct GNUNET_HashCode *h_wire, + struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute refund, + const struct TALER_Amount *total_amount) +{ + return; +} + +/** * Accomplish this payment. * * @param rh context of the handler @@ -945,14 +976,13 @@ MH_handler_pay (struct TMH_RequestHandler *rh, struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount ("amount", &pc->amount), GNUNET_JSON_spec_json ("coins", &coins), - GNUNET_JSON_spec_fixed_auto ("H_contract", &pc->h_proposal_data), + GNUNET_JSON_spec_fixed_auto ("h_proposal_data", &pc->h_proposal_data), TALER_JSON_spec_amount ("max_fee", &pc->max_fee), GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig), GNUNET_JSON_spec_string ("exchange", &chosen_exchange), GNUNET_JSON_spec_absolute_time ("refund_deadline", &pc->refund_deadline), GNUNET_JSON_spec_absolute_time ("pay_deadline", &pc->pay_deadline), GNUNET_JSON_spec_absolute_time ("timestamp", &pc->timestamp), - GNUNET_JSON_spec_string ("transaction_id", &pc->transaction_id), GNUNET_JSON_spec_end() }; @@ -990,6 +1020,27 @@ MH_handler_pay (struct TMH_RequestHandler *rh, pdps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT); pdps.purpose.size = htonl (sizeof (pdps)); pdps.hash = pc->h_proposal_data; + + struct GNUNET_HashCode dummy; + + GNUNET_CRYPTO_hash (&merchant_sig.eddsa_sig, + sizeof (merchant_sig.eddsa_sig), + &dummy); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Verifying signature '%s'\n", + GNUNET_h2s (&dummy)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "of hashed data '%s'\n", + GNUNET_h2s (&pc->h_proposal_data)); + + GNUNET_CRYPTO_hash (&pc->mi->privkey.eddsa_priv, + sizeof (pc->mi->privkey.eddsa_priv), + &dummy); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "with private key '%s'\n", + GNUNET_h2s (&dummy)); + if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_CONTRACT, &pdps.purpose, @@ -1159,7 +1210,9 @@ MH_handler_pay (struct TMH_RequestHandler *rh, } if (GNUNET_NO == pc->transaction_exits) { - /* #4521 goes here: Check if the customer respects pay_deadline */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Dealing with new transaction '%s'\n", + GNUNET_h2s (&pc->h_proposal_data)); now = GNUNET_TIME_absolute_get (); if (now.abs_value_us > pc->pay_deadline.abs_value_us) { @@ -1176,6 +1229,9 @@ MH_handler_pay (struct TMH_RequestHandler *rh, "The time to pay for this contract has expired."); } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing transaction '%s'\n", + GNUNET_h2s (&pc->h_proposal_data)); if (GNUNET_OK != db->store_transaction (db->cls, &pc->h_proposal_data, @@ -1192,6 +1248,12 @@ MH_handler_pay (struct TMH_RequestHandler *rh, TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR, "Merchant database error"); } + if (GNUNET_OK != db->find_transaction (db->cls, + &pc->h_proposal_data, + &pc->mi->pubkey, + &transaction_double_check, + NULL)) + GNUNET_break (0); } MHD_suspend_connection (connection); diff --git a/src/backend/taler-merchant-httpd_proposal.c b/src/backend/taler-merchant-httpd_proposal.c index 7fb2abc6..6e45b2db 100644 --- a/src/backend/taler-merchant-httpd_proposal.c +++ b/src/backend/taler-merchant-httpd_proposal.c @@ -148,8 +148,8 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh, struct GNUNET_CRYPTO_EddsaSignature merchant_sig; struct TALER_Amount total; struct TALER_Amount max_fee; - const char *transaction_id; - struct GNUNET_HashCode h_tid; + const char *order_id; + struct GNUNET_HashCode h_oid; json_t *products; json_t *merchant; struct GNUNET_TIME_Absolute timestamp; @@ -158,7 +158,7 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh, struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount ("amount", &total), TALER_JSON_spec_amount ("max_fee", &max_fee), - GNUNET_JSON_spec_string ("transaction_id", &transaction_id), + GNUNET_JSON_spec_string ("order_id", &order_id), /* The following entries we don't actually need, except to check that the order is well-formed */ GNUNET_JSON_spec_json ("products", &products), @@ -259,17 +259,39 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh, GNUNET_assert (GNUNET_OK == TALER_JSON_hash (order, &pdps.hash)); + + /*FIXME: do NOT keep in production, private key logged!*/ + struct GNUNET_HashCode dummy; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Signing h_proposal_data '%s'\n", + GNUNET_h2s (&pdps.hash)); + + GNUNET_CRYPTO_hash (&mi->privkey.eddsa_priv, + sizeof (mi->privkey.eddsa_priv), + &dummy); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "with private key '%s'\n", + GNUNET_h2s (&dummy)); + GNUNET_CRYPTO_eddsa_sign (&mi->privkey.eddsa_priv, &pdps.purpose, &merchant_sig); - - GNUNET_CRYPTO_hash (transaction_id, - strlen (transaction_id), - &h_tid); + GNUNET_CRYPTO_hash (&merchant_sig, + sizeof (merchant_sig), + &dummy); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "generating signature '%s'\n", + GNUNET_h2s (&dummy)); + + GNUNET_CRYPTO_hash (order_id, + strlen (order_id), + &h_oid); if (GNUNET_OK != db->insert_proposal_data (db->cls, - &h_tid, + &h_oid, order)) return TMH_RESPONSE_reply_internal_error (connection, TALER_EC_PROPOSAL_STORE_DB_ERROR, @@ -280,7 +302,7 @@ MH_handler_proposal_put (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:O, s:o s:o}", "data", order, - "merchant_sig", GNUNET_JSON_from_data_auto (&merchant_sig), + "sig", GNUNET_JSON_from_data_auto (&merchant_sig), "hash", GNUNET_JSON_from_data_auto (&pdps.hash)); GNUNET_JSON_parse_free (spec); json_decref (root); @@ -306,25 +328,25 @@ MH_handler_proposal_lookup (struct TMH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size) { - const char *transaction_id; - struct GNUNET_HashCode h_tid; + const char *order_id; + struct GNUNET_HashCode h_oid; int res; json_t *proposal_data; - transaction_id = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "transaction_id"); - if (NULL == transaction_id) + order_id = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "order_id"); + if (NULL == order_id) return TMH_RESPONSE_reply_arg_missing (connection, TALER_EC_PARAMETER_MISSING, - "transaction_id"); - GNUNET_CRYPTO_hash (transaction_id, - strlen (transaction_id), - &h_tid); + "order_id"); + GNUNET_CRYPTO_hash (order_id, + strlen (order_id), + &h_oid); res = db->find_proposal_data (db->cls, &proposal_data, - &h_tid); + &h_oid); if (GNUNET_NO == res) return TMH_RESPONSE_reply_not_found (connection, TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND, diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c index 94b3f6d1..0e48b3c6 100644 --- a/src/backend/taler-merchant-httpd_track-transaction.c +++ b/src/backend/taler-merchant-httpd_track-transaction.c @@ -844,11 +844,13 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, size_t *upload_data_size) { struct TrackTransactionContext *tctx; - const char *h_proposal_data_str; + const char *order_id; const char *instance; int ret; struct GNUNET_HashCode h_instance; + struct GNUNET_HashCode h_order_id; struct GNUNET_HashCode h_proposal_data; + struct json_t *proposal_data; if (NULL == *connection_cls) { @@ -893,13 +895,13 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, "Not sure why we are here, should be suspended\n"); return MHD_YES; /* still work in progress */ } - h_proposal_data_str = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "hash"); - if (NULL == h_proposal_data_str) + order_id = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "order_id"); + if (NULL == order_id) return TMH_RESPONSE_reply_arg_missing (connection, TALER_EC_PARAMETER_MISSING, - "hash"); + "order_id"); instance = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "instance"); @@ -908,9 +910,11 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, GNUNET_CRYPTO_hash (instance, strlen (instance), &h_instance); - GNUNET_CRYPTO_hash (h_proposal_data_str, - strlen (h_proposal_data_str), - &h_proposal_data); + GNUNET_CRYPTO_hash (order_id, + strlen (order_id), + &h_order_id); + + tctx->mi = GNUNET_CONTAINER_multihashmap_get (by_id_map, &h_instance); @@ -918,6 +922,21 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, return TMH_RESPONSE_reply_not_found (connection, TALER_EC_TRACK_TRANSACTION_INSTANCE_UNKNOWN, "unknown instance"); + + if (GNUNET_YES != db->find_proposal_data (db->cls, + &proposal_data, + &h_order_id)) + + return TMH_RESPONSE_reply_not_found (connection, + TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND, + "Given order_id doesn't map to any proposal"); + TALER_JSON_hash (proposal_data, + &h_proposal_data); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Trying to track h_proposal_data '%s'\n", + GNUNET_h2s (&h_proposal_data)); + ret = db->find_transaction (db->cls, &h_proposal_data, &tctx->mi->pubkey, @@ -927,7 +946,7 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, { return TMH_RESPONSE_reply_not_found (connection, TALER_EC_TRACK_TRANSACTION_TRANSACTION_UNKNOWN, - "id"); + "h_proposal_data is unknown"); } if ( (GNUNET_SYSERR == ret) || (0 != memcmp (&tctx->h_proposal_data, @@ -974,5 +993,4 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh, return MHD_YES; } - /* end of taler-merchant-httpd_track-transaction.c */ diff --git a/src/backend/taler-merchant-httpd_track-transfer.c b/src/backend/taler-merchant-httpd_track-transfer.c index 66dd9205..6f4d49ac 100644 --- a/src/backend/taler-merchant-httpd_track-transfer.c +++ b/src/backend/taler-merchant-httpd_track-transfer.c @@ -175,7 +175,7 @@ resume_track_transfer_with_response (struct TrackTransferContext *rctx, rctx->response_code = response_code; rctx->response = response; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Resuming /track/transaction handling as exchange interaction is done (%u)\n", + "Resuming /track/transfer handling as exchange interaction is done (%u)\n", response_code); if (NULL != rctx->timeout_task) { |