diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-07-22 19:07:42 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-07-22 19:07:42 +0200 |
commit | cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98 (patch) | |
tree | a684e3dbf034090e48606e7b4869e7576b99cae0 /src/backend/taler-merchant-httpd_post-orders-ID-pay.c | |
parent | 334b2f954b029c85244472e2e22d1a84b9b592db (diff) | |
download | merchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.tar.gz merchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.tar.bz2 merchant-cb6dfdf2100ae0f15d93ad0907f52f67b04ffc98.zip |
-add double-coin detection logic
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-pay.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 152 |
1 files changed, 85 insertions, 67 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c index 94f40158..b72ae0ee 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -691,18 +691,18 @@ deposit_cb (void *cls, enum GNUNET_DB_QueryStatus qs; qs = TMH_db->insert_deposit (TMH_db->cls, - pc->hc->instance->settings.id, - deposit_timestamp, - &pc->h_contract_terms, - &dc->coin_pub, - dc->exchange_url, - &dc->amount_with_fee, - &dc->deposit_fee, - &dc->refund_fee, - &dc->wire_fee, - &pc->wm->h_wire, - exchange_sig, - exchange_pub); + pc->hc->instance->settings.id, + deposit_timestamp, + &pc->h_contract_terms, + &dc->coin_pub, + dc->exchange_url, + &dc->amount_with_fee, + &dc->deposit_fee, + &dc->refund_fee, + &dc->wire_fee, + &pc->wm->h_wire, + exchange_sig, + exchange_pub); if (0 > qs) { /* Special report if retries insufficient */ @@ -715,9 +715,9 @@ deposit_cb (void *cls, GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); /* Forward error including 'proof' for the body */ resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "deposit"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "deposit"); return; } } @@ -955,9 +955,9 @@ find_next_exchange (struct PayContext *pc) { GNUNET_break (0); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED, - "Failed to lookup exchange by URL"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED, + "Failed to lookup exchange by URL"); return; } return; @@ -1080,7 +1080,7 @@ check_payment_sufficient (struct PayContext *pc) if (0 == pc->coins_cnt) { - return ((0 == pc->amount.value) && + return ((0 == pc->amount.value) && (0 == pc->amount.fraction)); } @@ -1137,19 +1137,19 @@ check_payment_sufficient (struct PayContext *pc) new_exchange = false; break; } - - if (!new_exchange) + + if (! new_exchange) continue; if (GNUNET_OK != TALER_amount_cmp_currency (&total_wire_fee, - &dc->wire_fee)) + &dc->wire_fee)) { GNUNET_break_op (0); resume_pay_with_error (pc, - MHD_HTTP_CONFLICT, - TALER_EC_GENERIC_CURRENCY_MISMATCH, - total_wire_fee.currency); + MHD_HTTP_CONFLICT, + TALER_EC_GENERIC_CURRENCY_MISMATCH, + total_wire_fee.currency); return false; } if (0 > @@ -1159,9 +1159,9 @@ check_payment_sufficient (struct PayContext *pc) { GNUNET_break (0); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED, - "could not add exchange wire fee to total"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED, + "could not add exchange wire fee to total"); return false; } } @@ -1324,9 +1324,10 @@ check_payment_sufficient (struct PayContext *pc) return true; } + /** - * - * + * + * */ static void execute_pay_transaction (struct PayContext *pc) @@ -1379,7 +1380,7 @@ execute_pay_transaction (struct PayContext *pc) { enum GNUNET_DB_QueryStatus qs; - + /* Check if some of these coins already succeeded for _this_ contract. */ qs = TMH_db->lookup_deposits (TMH_db->cls, instance_id, @@ -1397,9 +1398,9 @@ execute_pay_transaction (struct PayContext *pc) /* Always report on hard error as well to enable diagnostics */ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "lookup deposits"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup deposits"); return; } } @@ -1409,10 +1410,10 @@ execute_pay_transaction (struct PayContext *pc) enum GNUNET_DB_QueryStatus qs; /* Check if we refunded some of the coins */ qs = TMH_db->lookup_refunds (TMH_db->cls, - instance_id, - &pc->h_contract_terms, - &check_coin_refunded, - pc); + instance_id, + &pc->h_contract_terms, + &check_coin_refunded, + pc); if (0 > qs) { TMH_db->rollback (TMH_db->cls); @@ -1424,9 +1425,9 @@ execute_pay_transaction (struct PayContext *pc) /* Always report on hard error as well to enable diagnostics */ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "lookup refunds"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup refunds"); return; } refunded = (qs > 0); @@ -1462,9 +1463,9 @@ execute_pay_transaction (struct PayContext *pc) enum GNUNET_DB_QueryStatus qs; qs = TMH_db->mark_contract_paid (TMH_db->cls, - instance_id, - &pc->h_contract_terms, - pc->session_id); + instance_id, + &pc->h_contract_terms, + pc->session_id); if (qs < 0) { TMH_db->rollback (TMH_db->cls); @@ -1475,9 +1476,9 @@ execute_pay_transaction (struct PayContext *pc) } GNUNET_break (0); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "mark contract paid"); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + "mark contract paid"); return; } } @@ -1498,9 +1499,9 @@ execute_pay_transaction (struct PayContext *pc) } GNUNET_break (0); resume_pay_with_error (pc, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_COMMIT_FAILED, - NULL); + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + NULL); return; } } @@ -1615,23 +1616,23 @@ parse_pay (struct MHD_Connection *connection, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return (MHD_YES == TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MISSING, - "'coins' must be an array")) - ? GNUNET_NO + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MISSING, + "'coins' must be an array")) + ? GNUNET_NO : GNUNET_SYSERR; } - pc->coins_cnt = json_array_size (coins); + pc->coins_cnt = json_array_size (coins); if (pc->coins_cnt > MAX_COIN_ALLOWED_COINS) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return (MHD_YES == TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "'coins' array too long")) - ? GNUNET_NO + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "'coins' array too long")) + ? GNUNET_NO : GNUNET_SYSERR; } @@ -1662,16 +1663,33 @@ parse_pay (struct MHD_Connection *connection, &exchange_url), GNUNET_JSON_spec_end () }; + enum GNUNET_GenericReturnValue res; - enum GNUNET_GenericReturnValue res = TALER_MHD_parse_json_data (connection, - coin, - ispec); + res = TALER_MHD_parse_json_data (connection, + coin, + ispec); if (GNUNET_YES != res) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return res; } + for (unsigned int j = 0; j<coins_index; j++) + { + if (0 == + GNUNET_memcmp (&dc->coin_pub, + &pc->dc[j].coin_pub)) + { + GNUNET_break_op (0); + return (MHD_YES == + TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "duplicate coin in list")) + ? GNUNET_NO + : GNUNET_SYSERR; + } + } dc->exchange_url = GNUNET_strdup (exchange_url); dc->index = coins_index; dc->pc = pc; @@ -1770,7 +1788,7 @@ parse_pay (struct MHD_Connection *connection, struct GNUNET_JSON_Specification espec[] = { TALER_JSON_spec_amount ("amount", &pc->amount), - GNUNET_JSON_spec_mark_optional( + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("fulfillment_url", &fulfillment_url)), TALER_JSON_spec_amount ("max_fee", @@ -1807,10 +1825,10 @@ parse_pay (struct MHD_Connection *connection, if ((0 != strcasecmp (pc->amount.currency, TMH_currency)) || - (0 != strcasecmp (pc->max_fee.currency, - TMH_currency) || - (0 != strcasecmp (pc->max_wire_fee.currency, - TMH_currency)))) + ((0 != strcasecmp (pc->max_fee.currency, + TMH_currency)) || + (0 != strcasecmp (pc->max_wire_fee.currency, + TMH_currency)))) { GNUNET_break (0); return TALER_MHD_reply_with_error (connection, |