-handle withdraw CS nonce reuse more nicely

This commit is contained in:
Christian Grothoff 2022-07-05 12:56:55 +02:00
parent 82cff16eea
commit 7201ce3166
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 26 additions and 6 deletions

View File

@ -97,6 +97,7 @@ withdraw_transaction (void *cls,
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
bool found = false; bool found = false;
bool balance_ok = false; bool balance_ok = false;
bool nonce_ok = false;
struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp now;
uint64_t ruuid; uint64_t ruuid;
const struct TALER_CsNonce *nonce; const struct TALER_CsNonce *nonce;
@ -108,16 +109,13 @@ withdraw_transaction (void *cls,
(TALER_DENOMINATION_CS == bp->cipher) (TALER_DENOMINATION_CS == bp->cipher)
? &bp->details.cs_blinded_planchet.nonce ? &bp->details.cs_blinded_planchet.nonce
: NULL; : NULL;
// FIXME: what error is returned on nonce reuse?
// Should expand function to return this error
// specifically, and then we should return a
// TALER_EC_EXCHANGE_WITHDRAW_NONCE_REUSE,
qs = TEH_plugin->do_withdraw (TEH_plugin->cls, qs = TEH_plugin->do_withdraw (TEH_plugin->cls,
nonce, nonce,
&wc->collectable, &wc->collectable,
now, now,
&found, &found,
&balance_ok, &balance_ok,
&nonce_ok,
&wc->kyc, &wc->kyc,
&ruuid); &ruuid);
if (0 > qs) if (0 > qs)
@ -146,6 +144,15 @@ withdraw_transaction (void *cls,
&wc->collectable.reserve_pub); &wc->collectable.reserve_pub);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (! nonce_ok)
{
TEH_plugin->rollback (TEH_plugin->cls);
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_CONFLICT,
TALER_EC_EXCHANGE_WITHDRAW_NONCE_REUSE,
NULL);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if ( (TEH_KYC_NONE != TEH_kyc_config.mode) && if ( (TEH_KYC_NONE != TEH_kyc_config.mode) &&
(! wc->kyc.ok) && (! wc->kyc.ok) &&
(TALER_EXCHANGEDB_KYC_W2W == wc->kyc.type) ) (TALER_EXCHANGEDB_KYC_W2W == wc->kyc.type) )

View File

@ -1422,6 +1422,7 @@ CREATE OR REPLACE FUNCTION exchange_do_withdraw(
IN min_reserve_gc INT8, IN min_reserve_gc INT8,
OUT reserve_found BOOLEAN, OUT reserve_found BOOLEAN,
OUT balance_ok BOOLEAN, OUT balance_ok BOOLEAN,
OUT nonce_ok BOOLEAN,
OUT kycok BOOLEAN, OUT kycok BOOLEAN,
OUT account_uuid INT8, OUT account_uuid INT8,
OUT ruuid INT8) OUT ruuid INT8)
@ -1478,6 +1479,7 @@ THEN
-- reserve unknown -- reserve unknown
reserve_found=FALSE; reserve_found=FALSE;
balance_ok=FALSE; balance_ok=FALSE;
nonce_ok=TRUE;
kycok=FALSE; kycok=FALSE;
account_uuid=0; account_uuid=0;
ruuid=2; ruuid=2;
@ -1511,6 +1513,7 @@ THEN
-- idempotent query, all constraints must be satisfied -- idempotent query, all constraints must be satisfied
reserve_found=TRUE; reserve_found=TRUE;
balance_ok=TRUE; balance_ok=TRUE;
nonce_ok=TRUE;
kycok=TRUE; kycok=TRUE;
account_uuid=0; account_uuid=0;
RETURN; RETURN;
@ -1534,6 +1537,7 @@ ELSE
reserve_frac=reserve_frac - amount_frac; reserve_frac=reserve_frac - amount_frac;
ELSE ELSE
reserve_found=TRUE; reserve_found=TRUE;
nonce_ok=TRUE; -- we do not really know
balance_ok=FALSE; balance_ok=FALSE;
kycok=FALSE; -- we do not really know or care kycok=FALSE; -- we do not really know or care
account_uuid=0; account_uuid=0;
@ -1585,10 +1589,12 @@ THEN
balance_ok=FALSE; balance_ok=FALSE;
kycok=FALSE; kycok=FALSE;
account_uuid=0; account_uuid=0;
ruuid=1; -- FIXME: return error message more nicely! nonce_ok=FALSE;
ASSERT false, 'nonce reuse attempted by client'; RETURN;
END IF; END IF;
END IF; END IF;
ELSE
nonce_ok=TRUE; -- no nonce, hence OK!
END IF; END IF;

View File

@ -827,6 +827,7 @@ prepare_statements (struct PostgresClosure *pg)
"SELECT " "SELECT "
" reserve_found" " reserve_found"
",balance_ok" ",balance_ok"
",nonce_ok"
",kycok AS kyc_ok" ",kycok AS kyc_ok"
",account_uuid AS payment_target_uuid" ",account_uuid AS payment_target_uuid"
",ruuid" ",ruuid"
@ -5906,6 +5907,7 @@ postgres_get_withdraw_info (
* @param now current time (rounded) * @param now current time (rounded)
* @param[out] found set to true if the reserve was found * @param[out] found set to true if the reserve was found
* @param[out] balance_ok set to true if the balance was sufficient * @param[out] balance_ok set to true if the balance was sufficient
* @param[out] nonce_ok set to false if the nonce was reused
* @param[out] kyc set to true if the kyc status of the reserve is satisfied * @param[out] kyc set to true if the kyc status of the reserve is satisfied
* @param[out] ruuid set to the reserve's UUID (reserves table row) * @param[out] ruuid set to the reserve's UUID (reserves table row)
* @return query execution status * @return query execution status
@ -5918,6 +5920,7 @@ postgres_do_withdraw (
struct GNUNET_TIME_Timestamp now, struct GNUNET_TIME_Timestamp now,
bool *found, bool *found,
bool *balance_ok, bool *balance_ok,
bool *nonce_ok,
struct TALER_EXCHANGEDB_KycStatus *kyc, struct TALER_EXCHANGEDB_KycStatus *kyc,
uint64_t *ruuid) uint64_t *ruuid)
{ {
@ -5944,6 +5947,8 @@ postgres_do_withdraw (
balance_ok), balance_ok),
GNUNET_PQ_result_spec_bool ("kyc_ok", GNUNET_PQ_result_spec_bool ("kyc_ok",
&kyc->ok), &kyc->ok),
GNUNET_PQ_result_spec_bool ("nonce_ok",
nonce_ok),
GNUNET_PQ_result_spec_uint64 ("payment_target_uuid", GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
&kyc->payment_target_uuid), &kyc->payment_target_uuid),
GNUNET_PQ_result_spec_uint64 ("ruuid", GNUNET_PQ_result_spec_uint64 ("ruuid",

View File

@ -3171,6 +3171,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param now current time (rounded) * @param now current time (rounded)
* @param[out] found set to true if the reserve was found * @param[out] found set to true if the reserve was found
* @param[out] balance_ok set to true if the balance was sufficient * @param[out] balance_ok set to true if the balance was sufficient
* @param[out] nonce_ok set to false if the nonce was reused
* @param[out] kyc set to the KYC status of the reserve * @param[out] kyc set to the KYC status of the reserve
* @param[out] ruuid set to the reserve's UUID (reserves table row) * @param[out] ruuid set to the reserve's UUID (reserves table row)
* @return query execution status * @return query execution status
@ -3183,6 +3184,7 @@ struct TALER_EXCHANGEDB_Plugin
struct GNUNET_TIME_Timestamp now, struct GNUNET_TIME_Timestamp now,
bool *found, bool *found,
bool *balance_ok, bool *balance_ok,
bool *nonce_ok,
struct TALER_EXCHANGEDB_KycStatus *kyc_ok, struct TALER_EXCHANGEDB_KycStatus *kyc_ok,
uint64_t *ruuid); uint64_t *ruuid);