breaking protocol changes towards fixing #7810 (incomplete, taler-exchange-offline still unfinished)
This commit is contained in:
parent
5ee567d1ba
commit
75f75c4a51
@ -1 +1 @@
|
||||
Subproject commit bd4e73b2ed06269fdee42eaad21acb5be8be9302
|
||||
Subproject commit 5cfe18c5bbfd404a5f7cf27a78577c881ddb9ebd
|
@ -1483,10 +1483,10 @@ history_debit_cb (void *cls,
|
||||
switch (dhr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<dhr->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<dhr->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_DebitDetails *dd
|
||||
= &dhr->details.success.details[i];
|
||||
= &dhr->details.ok.details[i];
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Analyzing bank DEBIT at %s of %s with WTID %s\n",
|
||||
GNUNET_TIME_timestamp2s (dd->execution_date),
|
||||
@ -1978,10 +1978,10 @@ history_credit_cb (void *cls,
|
||||
switch (chr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<chr->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<chr->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_CreditDetails *cd
|
||||
= &chr->details.success.details[i];
|
||||
= &chr->details.ok.details[i];
|
||||
|
||||
if (! analyze_credit (wa,
|
||||
cd))
|
||||
|
@ -131,8 +131,8 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
chr.details.success.details_length = len;
|
||||
chr.details.success.details = cd;
|
||||
chr.details.ok.details_length = len;
|
||||
chr.details.ok.details = cd;
|
||||
hh->hcb (hh->hcb_cls,
|
||||
&chr);
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle *hh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
dhr.details.success.details_length = len;
|
||||
dhr.details.success.details = dd;
|
||||
dhr.details.ok.details_length = len;
|
||||
dhr.details.ok.details = dd;
|
||||
hh->hcb (hh->hcb_cls,
|
||||
&dhr);
|
||||
}
|
||||
|
@ -179,10 +179,10 @@ credit_history_cb (void *cls,
|
||||
global_ret = 0;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<reply->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<reply->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_CreditDetails *cd =
|
||||
&reply->details.success.details[i];
|
||||
&reply->details.ok.details[i];
|
||||
|
||||
/* If credit/debit accounts were specified, use as a filter */
|
||||
if ( (NULL != credit_account) &&
|
||||
@ -279,10 +279,10 @@ debit_history_cb (void *cls,
|
||||
global_ret = 0;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<reply->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<reply->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_DebitDetails *dd =
|
||||
&reply->details.success.details[i];
|
||||
&reply->details.ok.details[i];
|
||||
|
||||
/* If credit/debit accounts were specified, use as a filter */
|
||||
if ( (NULL != credit_account) &&
|
||||
|
@ -644,26 +644,19 @@ do_upload (char *const *args)
|
||||
* a particular exchange and what keys the exchange is using.
|
||||
*
|
||||
* @param cls closure with the `char **` remaining args
|
||||
* @param hr HTTP response data
|
||||
* @param keys information about the various keys used
|
||||
* by the exchange, NULL if /keys failed
|
||||
* @param compat protocol compatibility information
|
||||
* @param kr response data
|
||||
*/
|
||||
static void
|
||||
keys_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_EXCHANGE_Keys *keys,
|
||||
enum TALER_EXCHANGE_VersionCompatibility compat)
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
{
|
||||
char *const *args = cls;
|
||||
|
||||
(void) keys;
|
||||
(void) compat;
|
||||
switch (hr->http_status)
|
||||
switch (kr->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
if (! json_is_object (hr->reply))
|
||||
if (! json_is_object (kr->hr.reply))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
@ -676,9 +669,9 @@ keys_cb (
|
||||
default:
|
||||
fprintf (stderr,
|
||||
"Failed to download keys: %s (HTTP status: %u/%u)\n",
|
||||
hr->hint,
|
||||
hr->http_status,
|
||||
(unsigned int) hr->ec);
|
||||
kr->hr.hint,
|
||||
kr->hr.http_status,
|
||||
(unsigned int) kr->hr.ec);
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
exchange = NULL;
|
||||
test_shutdown ();
|
||||
@ -689,7 +682,7 @@ keys_cb (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
OP_INPUT_KEYS),
|
||||
GNUNET_JSON_pack_object_incref ("arguments",
|
||||
(json_t *) hr->reply));
|
||||
(json_t *) kr->hr.reply));
|
||||
if (NULL == args[0])
|
||||
{
|
||||
json_dumpf (in,
|
||||
|
@ -1119,14 +1119,15 @@ load_offline_key (int do_create)
|
||||
* Function called with information about the post revocation operation result.
|
||||
*
|
||||
* @param cls closure with a `struct DenomRevocationRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param dr response data
|
||||
*/
|
||||
static void
|
||||
denom_revocation_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *dr)
|
||||
{
|
||||
struct DenomRevocationRequest *drr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &dr->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -1208,14 +1209,15 @@ upload_denom_revocation (const char *exchange_url,
|
||||
* Function called with information about the post revocation operation result.
|
||||
*
|
||||
* @param cls closure with a `struct SignkeyRevocationRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param sr response data
|
||||
*/
|
||||
static void
|
||||
signkey_revocation_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *sr)
|
||||
{
|
||||
struct SignkeyRevocationRequest *srr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &sr->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -1489,13 +1491,14 @@ upload_auditor_del (const char *exchange_url,
|
||||
* Function called with information about the post wire add operation result.
|
||||
*
|
||||
* @param cls closure with a `struct WireAddRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param wer response data
|
||||
*/
|
||||
static void
|
||||
wire_add_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer)
|
||||
{
|
||||
struct WireAddRequest *war = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &wer->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -1533,10 +1536,21 @@ upload_wire_add (const char *exchange_url,
|
||||
struct GNUNET_TIME_Timestamp start_time;
|
||||
struct WireAddRequest *war;
|
||||
const char *err_name;
|
||||
const char *conversion_url = NULL;
|
||||
json_t *debit_restrictions;
|
||||
json_t *credit_restrictions;
|
||||
unsigned int err_line;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("payto_uri",
|
||||
&payto_uri),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("conversion_url",
|
||||
&conversion_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_json ("debit_restrictions",
|
||||
&debit_restrictions),
|
||||
GNUNET_JSON_spec_json ("credit_restrictions",
|
||||
&credit_restrictions),
|
||||
GNUNET_JSON_spec_timestamp ("validity_start",
|
||||
&start_time),
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig_add",
|
||||
@ -1561,6 +1575,7 @@ upload_wire_add (const char *exchange_url,
|
||||
stderr,
|
||||
JSON_INDENT (2));
|
||||
global_ret = EXIT_FAILURE;
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
test_shutdown ();
|
||||
return;
|
||||
}
|
||||
@ -1574,6 +1589,7 @@ upload_wire_add (const char *exchange_url,
|
||||
"payto:// URI `%s' is malformed\n",
|
||||
payto_uri);
|
||||
global_ret = EXIT_FAILURE;
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
test_shutdown ();
|
||||
return;
|
||||
}
|
||||
@ -1588,6 +1604,7 @@ upload_wire_add (const char *exchange_url,
|
||||
"payto URI is malformed: %s\n",
|
||||
msg);
|
||||
GNUNET_free (msg);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
test_shutdown ();
|
||||
global_ret = EXIT_INVALIDARGUMENT;
|
||||
return;
|
||||
@ -1599,6 +1616,9 @@ upload_wire_add (const char *exchange_url,
|
||||
TALER_EXCHANGE_management_enable_wire (ctx,
|
||||
exchange_url,
|
||||
payto_uri,
|
||||
conversion_url,
|
||||
debit_restrictions,
|
||||
credit_restrictions,
|
||||
start_time,
|
||||
&master_sig_add,
|
||||
&master_sig_wire,
|
||||
@ -1607,6 +1627,7 @@ upload_wire_add (const char *exchange_url,
|
||||
GNUNET_CONTAINER_DLL_insert (war_head,
|
||||
war_tail,
|
||||
war);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
}
|
||||
|
||||
|
||||
@ -1614,13 +1635,14 @@ upload_wire_add (const char *exchange_url,
|
||||
* Function called with information about the post wire del operation result.
|
||||
*
|
||||
* @param cls closure with a `struct WireDelRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param wdres response data
|
||||
*/
|
||||
static void
|
||||
wire_del_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdres)
|
||||
{
|
||||
struct WireDelRequest *wdr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &wdres->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -1927,14 +1949,15 @@ upload_global_fee (const char *exchange_url,
|
||||
* Function called with information about the drain profits operation.
|
||||
*
|
||||
* @param cls closure with a `struct DrainProfitsRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param mdr response data
|
||||
*/
|
||||
static void
|
||||
drain_profits_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementDrainResponse *mdr)
|
||||
{
|
||||
struct DrainProfitsRequest *dpr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &mdr->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -2033,14 +2056,15 @@ upload_drain (const char *exchange_url,
|
||||
* Function called with information about the post upload keys operation result.
|
||||
*
|
||||
* @param cls closure with a `struct UploadKeysRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param mr response data
|
||||
*/
|
||||
static void
|
||||
keys_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementPostKeysResponse *mr)
|
||||
{
|
||||
struct UploadKeysRequest *ukr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &mr->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -2206,14 +2230,15 @@ upload_keys (const char *exchange_url,
|
||||
* Function called with information about the post upload extensions operation result.
|
||||
*
|
||||
* @param cls closure with a `struct UploadExtensionsRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param er response data
|
||||
*/
|
||||
static void
|
||||
extensions_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementPostExtensionsResponse *er)
|
||||
{
|
||||
struct UploadExtensionsRequest *uer = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &er->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -2447,14 +2472,15 @@ add_partner (const char *exchange_url,
|
||||
* Function called with information about the AML officer update operation.
|
||||
*
|
||||
* @param cls closure with a `struct AmlStaffRequest`
|
||||
* @param hr HTTP response data
|
||||
* @param ar response data
|
||||
*/
|
||||
static void
|
||||
update_aml_officer_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *ar)
|
||||
{
|
||||
struct AmlStaffRequest *asr = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &ar->hr;
|
||||
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
@ -2961,6 +2987,10 @@ do_add_wire (char *const *args)
|
||||
struct TALER_MasterSignatureP master_sig_add;
|
||||
struct TALER_MasterSignatureP master_sig_wire;
|
||||
struct GNUNET_TIME_Timestamp now;
|
||||
const char *conversion_url = NULL;
|
||||
json_t *debit_restrictions;
|
||||
json_t *credit_restrictions;
|
||||
unsigned int num_args = 1;
|
||||
|
||||
if (NULL != in)
|
||||
{
|
||||
@ -3011,24 +3041,43 @@ do_add_wire (char *const *args)
|
||||
}
|
||||
GNUNET_free (wire_method);
|
||||
}
|
||||
// FIXME: init new args properly!
|
||||
debit_restrictions = json_array ();
|
||||
GNUNET_assert (NULL != debit_restrictions);
|
||||
credit_restrictions = json_array ();
|
||||
GNUNET_assert (NULL != credit_restrictions);
|
||||
|
||||
TALER_exchange_offline_wire_add_sign (args[0],
|
||||
conversion_url,
|
||||
debit_restrictions,
|
||||
credit_restrictions,
|
||||
now,
|
||||
&master_priv,
|
||||
&master_sig_add);
|
||||
TALER_exchange_wire_signature_make (args[0],
|
||||
conversion_url,
|
||||
debit_restrictions,
|
||||
credit_restrictions,
|
||||
&master_priv,
|
||||
&master_sig_wire);
|
||||
output_operation (OP_ENABLE_WIRE,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("payto_uri",
|
||||
args[0]),
|
||||
GNUNET_JSON_pack_array_steal ("debit_restrictions",
|
||||
debit_restrictions),
|
||||
GNUNET_JSON_pack_array_steal ("credit_restrictions",
|
||||
credit_restrictions),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_string ("conversion_url",
|
||||
conversion_url)),
|
||||
GNUNET_JSON_pack_timestamp ("validity_start",
|
||||
now),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig_add",
|
||||
&master_sig_add),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig_wire",
|
||||
&master_sig_wire)));
|
||||
next (args + 1);
|
||||
next (args + num_args);
|
||||
}
|
||||
|
||||
|
||||
@ -3643,18 +3692,15 @@ enable_aml_staff (char *const *args)
|
||||
* whether there are subsequent commands).
|
||||
*
|
||||
* @param cls closure with the `char **` remaining args
|
||||
* @param hr HTTP response data
|
||||
* @param keys information about the various keys used
|
||||
* by the exchange, NULL if /management/keys failed
|
||||
* @param mgr response data
|
||||
*/
|
||||
static void
|
||||
download_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_EXCHANGE_FutureKeys *keys)
|
||||
const struct TALER_EXCHANGE_ManagementGetKeysResponse *mgr)
|
||||
{
|
||||
char *const *args = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &mgr->hr;
|
||||
|
||||
(void) keys;
|
||||
mgkh = NULL;
|
||||
switch (hr->http_status)
|
||||
{
|
||||
|
@ -41,7 +41,7 @@
|
||||
*
|
||||
* Returned via both /config and /keys endpoints.
|
||||
*/
|
||||
#define EXCHANGE_PROTOCOL_VERSION "14:0:2"
|
||||
#define EXCHANGE_PROTOCOL_VERSION "15:0:0"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
@ -114,6 +114,9 @@ del_wire (void *cls,
|
||||
}
|
||||
qs = TEH_plugin->update_wire (TEH_plugin->cls,
|
||||
awc->payto_uri,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
awc->validity_end,
|
||||
false);
|
||||
if (qs < 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
@ -54,6 +54,21 @@ struct AddWireContext
|
||||
*/
|
||||
const char *payto_uri;
|
||||
|
||||
/**
|
||||
* (optional) address of a conversion service for this account.
|
||||
*/
|
||||
const char *conversion_url;
|
||||
|
||||
/**
|
||||
* Restrictions imposed when crediting this account.
|
||||
*/
|
||||
json_t *credit_restrictions;
|
||||
|
||||
/**
|
||||
* Restrictions imposed when debiting this account.
|
||||
*/
|
||||
json_t *debit_restrictions;
|
||||
|
||||
/**
|
||||
* Timestamp for checking against replay attacks.
|
||||
*/
|
||||
@ -114,11 +129,17 @@ add_wire (void *cls,
|
||||
if (0 == qs)
|
||||
qs = TEH_plugin->insert_wire (TEH_plugin->cls,
|
||||
awc->payto_uri,
|
||||
awc->conversion_url,
|
||||
awc->debit_restrictions,
|
||||
awc->credit_restrictions,
|
||||
awc->validity_start,
|
||||
&awc->master_sig_wire);
|
||||
else
|
||||
qs = TEH_plugin->update_wire (TEH_plugin->cls,
|
||||
awc->payto_uri,
|
||||
awc->conversion_url,
|
||||
awc->debit_restrictions,
|
||||
awc->credit_restrictions,
|
||||
awc->validity_start,
|
||||
true);
|
||||
if (qs < 0)
|
||||
@ -141,7 +162,9 @@ TEH_handler_management_post_wire (
|
||||
struct MHD_Connection *connection,
|
||||
const json_t *root)
|
||||
{
|
||||
struct AddWireContext awc;
|
||||
struct AddWireContext awc = {
|
||||
.conversion_url = NULL
|
||||
};
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig_wire",
|
||||
&awc.master_sig_wire),
|
||||
@ -149,6 +172,14 @@ TEH_handler_management_post_wire (
|
||||
&awc.master_sig_add),
|
||||
GNUNET_JSON_spec_string ("payto_uri",
|
||||
&awc.payto_uri),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("conversion_url",
|
||||
&awc.conversion_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_json ("credit_restrictions",
|
||||
&awc.credit_restrictions),
|
||||
GNUNET_JSON_spec_json ("debit_restrictions",
|
||||
&awc.debit_restrictions),
|
||||
GNUNET_JSON_spec_timestamp ("validity_start",
|
||||
&awc.validity_start),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -179,17 +210,22 @@ TEH_handler_management_post_wire (
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PAYTO_URI_MALFORMED,
|
||||
msg);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
GNUNET_free (msg);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_offline_wire_add_verify (awc.payto_uri,
|
||||
awc.conversion_url,
|
||||
awc.debit_restrictions,
|
||||
awc.credit_restrictions,
|
||||
awc.validity_start,
|
||||
&TEH_master_public_key,
|
||||
&awc.master_sig_add))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
@ -199,10 +235,14 @@ TEH_handler_management_post_wire (
|
||||
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_wire_signature_check (awc.payto_uri,
|
||||
awc.conversion_url,
|
||||
awc.debit_restrictions,
|
||||
awc.credit_restrictions,
|
||||
&TEH_master_public_key,
|
||||
&awc.master_sig_wire))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
@ -218,6 +258,7 @@ TEH_handler_management_post_wire (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"payto:// URI `%s' is malformed\n",
|
||||
awc.payto_uri);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
@ -237,6 +278,7 @@ TEH_handler_management_post_wire (
|
||||
&ret,
|
||||
&add_wire,
|
||||
&awc);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
if (GNUNET_SYSERR == res)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2015-2022 Taler Systems SA
|
||||
Copyright (C) 2015-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
@ -224,12 +224,18 @@ TEH_wire_done ()
|
||||
*
|
||||
* @param cls a `json_t *` object to expand with wire account details
|
||||
* @param payto_uri the exchange bank account URI to add
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account
|
||||
* @param master_sig master key signature affirming that this is a bank
|
||||
* account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS)
|
||||
*/
|
||||
static void
|
||||
add_wire_account (void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterSignatureP *master_sig)
|
||||
{
|
||||
json_t *a = cls;
|
||||
@ -240,6 +246,13 @@ add_wire_account (void *cls,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("payto_uri",
|
||||
payto_uri),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_string ("conversion_url",
|
||||
conversion_url)),
|
||||
GNUNET_JSON_pack_array_incref ("debit_restrictions",
|
||||
(json_t *) debit_restrictions),
|
||||
GNUNET_JSON_pack_array_incref ("credit_restrictions",
|
||||
(json_t *) credit_restrictions),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig",
|
||||
master_sig))))
|
||||
{
|
||||
@ -462,6 +475,8 @@ build_wire_state (void)
|
||||
wsh->wire_reply = TALER_MHD_MAKE_JSON_PACK (
|
||||
GNUNET_JSON_pack_array_steal ("accounts",
|
||||
wire_accounts_array),
|
||||
GNUNET_JSON_pack_array_steal ("wads", /* #7271 */
|
||||
json_array ()),
|
||||
GNUNET_JSON_pack_object_steal ("fees",
|
||||
wire_fee_object),
|
||||
GNUNET_JSON_pack_data_auto ("master_public_key",
|
||||
|
@ -731,8 +731,8 @@ history_cb (void *cls,
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
process_reply (wrap_size,
|
||||
reply->details.success.details,
|
||||
reply->details.success.details_length);
|
||||
reply->details.ok.details,
|
||||
reply->details.ok.details_length);
|
||||
return;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
transaction_completed ();
|
||||
|
1
src/exchangedb/.gitignore
vendored
1
src/exchangedb/.gitignore
vendored
@ -13,3 +13,4 @@ test-exchangedb-by-j-postgres
|
||||
test-exchangedb-populate-link-data-postgres
|
||||
test-exchangedb-populate-ready-deposit-postgres
|
||||
test-exchangedb-populate-select-refunds-by-coin-postgres
|
||||
exchange-0004.sql
|
||||
|
26
src/exchangedb/0004-wire_accounts.sql
Normal file
26
src/exchangedb/0004-wire_accounts.sql
Normal file
@ -0,0 +1,26 @@
|
||||
--
|
||||
-- This file is part of TALER
|
||||
-- Copyright (C) 2023 Taler Systems SA
|
||||
--
|
||||
-- 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/>
|
||||
--
|
||||
|
||||
ALTER TABLE wire_accounts
|
||||
ADD COLUMN conversion_url VARCHAR DEFAULT (NULL),
|
||||
ADD COLUMN debit_restrictions VARCHAR DEFAULT (NULL),
|
||||
ADD COLUMN credit_restrictions VARCHAR DEFAULT (NULL);
|
||||
COMMENT ON COLUMN wire_accounts.conversion_url
|
||||
IS 'URL of a currency conversion service if conversion is needed when this account is used; NULL if there is no conversion.';
|
||||
COMMENT ON COLUMN wire_accounts.debit_restrictions
|
||||
IS 'JSON array describing restrictions imposed when debiting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.';
|
||||
COMMENT ON COLUMN wire_accounts.credit_restrictions
|
||||
IS 'JSON array describing restrictions imposed when crediting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.';
|
@ -20,7 +20,9 @@ sqlinputs = \
|
||||
0002-*.sql \
|
||||
exchange-0002.sql.in \
|
||||
0003-*.sql \
|
||||
exchange-0003.sql.in
|
||||
exchange-0003.sql.in \
|
||||
0004-*.sql \
|
||||
exchange-0004.sql.in
|
||||
|
||||
sql_DATA = \
|
||||
benchmark-0001.sql \
|
||||
@ -28,6 +30,7 @@ sql_DATA = \
|
||||
exchange-0001.sql \
|
||||
exchange-0002.sql \
|
||||
exchange-0003.sql \
|
||||
exchange-0004.sql \
|
||||
drop.sql \
|
||||
procedures.sql
|
||||
|
||||
@ -39,7 +42,8 @@ BUILT_SOURCES = \
|
||||
|
||||
CLEANFILES = \
|
||||
exchange-0002.sql \
|
||||
exchange-0003.sql
|
||||
exchange-0003.sql \
|
||||
exchange-0004.sql
|
||||
|
||||
procedures.sql: procedures.sql.in exchange_do_*.sql
|
||||
chmod +w $@ || true
|
||||
@ -56,6 +60,11 @@ exchange-0003.sql: exchange-0003.sql.in 0003-*.sql
|
||||
gcc -E -P -undef - < exchange-0003.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
||||
chmod ugo-w $@
|
||||
|
||||
exchange-0004.sql: exchange-0004.sql.in 0004-*.sql
|
||||
chmod +w $@ || true
|
||||
gcc -E -P -undef - < exchange-0004.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
||||
chmod ugo-w $@
|
||||
|
||||
EXTRA_DIST = \
|
||||
exchangedb.conf \
|
||||
exchangedb-postgres.conf \
|
||||
|
@ -21,6 +21,7 @@ BEGIN;
|
||||
SELECT _v.unregister_patch('exchange-0001');
|
||||
SELECT _v.unregister_patch('exchange-0002');
|
||||
SELECT _v.unregister_patch('exchange-0003');
|
||||
SELECT _v.unregister_patch('exchange-0004');
|
||||
|
||||
DROP SCHEMA exchange CASCADE;
|
||||
|
||||
|
24
src/exchangedb/exchange-0004.sql.in
Normal file
24
src/exchangedb/exchange-0004.sql.in
Normal file
@ -0,0 +1,24 @@
|
||||
--
|
||||
-- This file is part of TALER
|
||||
-- Copyright (C) 2014--2023 Taler Systems SA
|
||||
--
|
||||
-- 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/>
|
||||
--
|
||||
|
||||
BEGIN;
|
||||
|
||||
SELECT _v.register_patch('exchange-0004', NULL, NULL);
|
||||
SET search_path TO exchange;
|
||||
|
||||
#include "0004-wire_accounts.sql"
|
||||
|
||||
COMMIT;
|
@ -66,10 +66,25 @@ get_wire_accounts_cb (void *cls,
|
||||
for (unsigned int i = 0; i < num_results; i++)
|
||||
{
|
||||
char *payto_uri;
|
||||
char *conversion_url = NULL;
|
||||
json_t *debit_restrictions = NULL;
|
||||
json_t *credit_restrictions = NULL;
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_string ("payto_uri",
|
||||
&payto_uri),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
GNUNET_PQ_result_spec_string ("conversion_url",
|
||||
&conversion_url),
|
||||
NULL),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
TALER_PQ_result_spec_json ("debit_restrictions",
|
||||
&debit_restrictions),
|
||||
NULL),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
TALER_PQ_result_spec_json ("credit_restrictions",
|
||||
&credit_restrictions),
|
||||
NULL),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
|
||||
&master_sig),
|
||||
GNUNET_PQ_result_spec_end
|
||||
@ -84,8 +99,21 @@ get_wire_accounts_cb (void *cls,
|
||||
ctx->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
if (NULL == debit_restrictions)
|
||||
{
|
||||
debit_restrictions = json_array ();
|
||||
GNUNET_assert (NULL != debit_restrictions);
|
||||
}
|
||||
if (NULL == credit_restrictions)
|
||||
{
|
||||
credit_restrictions = json_array ();
|
||||
GNUNET_assert (NULL != credit_restrictions);
|
||||
}
|
||||
ctx->cb (ctx->cb_cls,
|
||||
payto_uri,
|
||||
conversion_url,
|
||||
debit_restrictions,
|
||||
credit_restrictions,
|
||||
&master_sig);
|
||||
GNUNET_PQ_cleanup_result (rs);
|
||||
}
|
||||
@ -112,6 +140,9 @@ TEH_PG_get_wire_accounts (void *cls,
|
||||
"get_wire_accounts",
|
||||
"SELECT"
|
||||
" payto_uri"
|
||||
",conversion_url"
|
||||
",debit_restrictions"
|
||||
",credit_restrictions"
|
||||
",master_sig"
|
||||
" FROM wire_accounts"
|
||||
" WHERE is_active");
|
||||
@ -123,5 +154,4 @@ TEH_PG_get_wire_accounts (void *cls,
|
||||
if (GNUNET_OK != ctx.status)
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
return qs;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022, 2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -29,12 +29,20 @@
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TEH_PG_insert_wire (void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp start_date,
|
||||
const struct TALER_MasterSignatureP *master_sig)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_string (payto_uri),
|
||||
NULL == conversion_url
|
||||
? GNUNET_PQ_query_param_null ()
|
||||
: GNUNET_PQ_query_param_string (conversion_url),
|
||||
TALER_PQ_query_param_json (debit_restrictions),
|
||||
TALER_PQ_query_param_json (credit_restrictions),
|
||||
GNUNET_PQ_query_param_auto_from_type (master_sig),
|
||||
GNUNET_PQ_query_param_timestamp (&start_date),
|
||||
GNUNET_PQ_query_param_end
|
||||
@ -44,11 +52,14 @@ TEH_PG_insert_wire (void *cls,
|
||||
"insert_wire",
|
||||
"INSERT INTO wire_accounts "
|
||||
"(payto_uri"
|
||||
",conversion_url"
|
||||
",debit_restrictions"
|
||||
",credit_restrictions"
|
||||
",master_sig"
|
||||
",is_active"
|
||||
",last_change"
|
||||
") VALUES "
|
||||
"($1, $2, true, $3);");
|
||||
"($1, $2, $3, $4, $5, true, $6);");
|
||||
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"insert_wire",
|
||||
params);
|
||||
|
@ -29,6 +29,9 @@
|
||||
*
|
||||
* @param cls closure
|
||||
* @param payto_uri wire account of the exchange
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account
|
||||
* @param start_date date when the account was added by the offline system
|
||||
* (only to be used for replay detection)
|
||||
* @param master_sig public signature affirming the existence of the account,
|
||||
@ -38,6 +41,9 @@
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TEH_PG_insert_wire (void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp start_date,
|
||||
const struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022, 2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -29,6 +29,9 @@
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TEH_PG_update_wire (void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp change_date,
|
||||
bool enabled)
|
||||
{
|
||||
@ -36,17 +39,28 @@ TEH_PG_update_wire (void *cls,
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_string (payto_uri),
|
||||
GNUNET_PQ_query_param_bool (enabled),
|
||||
NULL == conversion_url
|
||||
? GNUNET_PQ_query_param_null ()
|
||||
: GNUNET_PQ_query_param_string (conversion_url),
|
||||
enabled
|
||||
? TALER_PQ_query_param_json (debit_restrictions)
|
||||
: GNUNET_PQ_query_param_null (),
|
||||
enabled
|
||||
? TALER_PQ_query_param_json (credit_restrictions)
|
||||
: GNUNET_PQ_query_param_null (),
|
||||
GNUNET_PQ_query_param_timestamp (&change_date),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
/* used in #postgres_update_wire() */
|
||||
PREPARE (pg,
|
||||
"update_wire",
|
||||
"UPDATE wire_accounts"
|
||||
" SET"
|
||||
" is_active=$2"
|
||||
" ,last_change=$3"
|
||||
" ,conversion_url=$3"
|
||||
" ,debit_restrictions=$4"
|
||||
" ,credit_restrictions=$5"
|
||||
" ,last_change=$6"
|
||||
" WHERE payto_uri=$1");
|
||||
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"update_wire",
|
||||
|
@ -24,11 +24,16 @@
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_exchangedb_plugin.h"
|
||||
|
||||
|
||||
/**
|
||||
* Update information about a wire account of the exchange.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param payto_uri account the update is about
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled
|
||||
* @param change_date date when the account status was last changed
|
||||
* (only to be used for replay detection)
|
||||
* @param enabled true to enable, false to disable (the actual change)
|
||||
@ -37,6 +42,9 @@
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TEH_PG_update_wire (void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp change_date,
|
||||
bool enabled);
|
||||
|
||||
|
@ -111,6 +111,7 @@ struct TALER_BANK_AdminAddIncomingHandle;
|
||||
* @param timestamp time when the transaction was made.
|
||||
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
||||
*/
|
||||
// FIXME: bad API
|
||||
typedef void
|
||||
(*TALER_BANK_AdminAddIncomingCallback) (
|
||||
void *cls,
|
||||
@ -199,6 +200,7 @@ struct TALER_BANK_TransferHandle;
|
||||
* @param row_id unique ID of the wire transfer in the bank's records
|
||||
* @param timestamp when did the transaction go into effect
|
||||
*/
|
||||
// FIXME: bad API
|
||||
typedef void
|
||||
(*TALER_BANK_TransferCallback)(
|
||||
void *cls,
|
||||
@ -337,7 +339,7 @@ struct TALER_BANK_CreditHistoryResponse
|
||||
*/
|
||||
unsigned int details_length;
|
||||
|
||||
} success;
|
||||
} ok;
|
||||
|
||||
} details;
|
||||
|
||||
@ -493,7 +495,7 @@ struct TALER_BANK_DebitHistoryResponse
|
||||
*/
|
||||
unsigned int details_length;
|
||||
|
||||
} success;
|
||||
} ok;
|
||||
|
||||
} details;
|
||||
|
||||
|
@ -5512,6 +5512,9 @@ TALER_exchange_offline_global_fee_verify (
|
||||
* Create wire account addition signature.
|
||||
*
|
||||
* @param payto_uri bank account
|
||||
* @param conversion_url URL of the conversion service, or NULL if none
|
||||
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param now timestamp to use for the signature (rounded)
|
||||
* @param master_priv private key to sign with
|
||||
* @param[out] master_sig where to write the signature
|
||||
@ -5519,6 +5522,9 @@ TALER_exchange_offline_global_fee_verify (
|
||||
void
|
||||
TALER_exchange_offline_wire_add_sign (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp now,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig);
|
||||
@ -5528,6 +5534,9 @@ TALER_exchange_offline_wire_add_sign (
|
||||
* Verify wire account addition signature.
|
||||
*
|
||||
* @param payto_uri bank account
|
||||
* @param conversion_url URL of the conversion service, or NULL if none
|
||||
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param sign_time timestamp when signature was created
|
||||
* @param master_pub public key to verify against
|
||||
* @param master_sig the signature the signature
|
||||
@ -5536,6 +5545,9 @@ TALER_exchange_offline_wire_add_sign (
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_offline_wire_add_verify (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp sign_time,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig);
|
||||
@ -5578,6 +5590,9 @@ TALER_exchange_offline_wire_del_verify (
|
||||
* Check the signature in @a master_sig.
|
||||
*
|
||||
* @param payto_uri URI that is signed
|
||||
* @param conversion_url URL of the conversion service, or NULL if none
|
||||
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param master_pub master public key of the exchange
|
||||
* @param master_sig signature of the exchange
|
||||
* @return #GNUNET_OK if signature is valid
|
||||
@ -5585,6 +5600,9 @@ TALER_exchange_offline_wire_del_verify (
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_wire_signature_check (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
@ -5593,12 +5611,18 @@ TALER_exchange_wire_signature_check (
|
||||
* Create a signed wire statement for the given account.
|
||||
*
|
||||
* @param payto_uri account specification
|
||||
* @param conversion_url URL of the conversion service, or NULL if none
|
||||
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
|
||||
* @param master_priv private key to sign with
|
||||
* @param[out] master_sig where to write the signature
|
||||
*/
|
||||
void
|
||||
TALER_exchange_wire_signature_make (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2881,6 +2881,9 @@ typedef enum GNUNET_GenericReturnValue
|
||||
*
|
||||
* @param cls closure
|
||||
* @param payto_uri the exchange bank account URI
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account
|
||||
* @param master_sig master key signature affirming that this is a bank
|
||||
* account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS)
|
||||
*/
|
||||
@ -2888,6 +2891,9 @@ typedef void
|
||||
(*TALER_EXCHANGEDB_WireAccountCallback)(
|
||||
void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
|
||||
@ -5544,6 +5550,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
*
|
||||
* @param cls closure
|
||||
* @param payto_uri wire account of the exchange
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account
|
||||
* @param start_date date when the account was added by the offline system
|
||||
* (only to be used for replay detection)
|
||||
* @param master_sig public signature affirming the existence of the account,
|
||||
@ -5553,6 +5562,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*insert_wire)(void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp start_date,
|
||||
const struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
@ -5562,6 +5574,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
*
|
||||
* @param cls closure
|
||||
* @param payto_uri account the update is about
|
||||
* @param conversion_url URL of a conversion service, NULL if there is no conversion
|
||||
* @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled
|
||||
* @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled
|
||||
* @param change_date date when the account status was last changed
|
||||
* (only to be used for replay detection)
|
||||
* @param enabled true to enable, false to disable (the actual change)
|
||||
@ -5570,6 +5585,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*update_wire)(void *cls,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
json_t *debit_restrictions,
|
||||
json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp change_date,
|
||||
bool enabled);
|
||||
|
||||
|
@ -674,33 +674,6 @@ TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s,
|
||||
struct TALER_MerchantWireHashP *hc);
|
||||
|
||||
|
||||
/**
|
||||
* Check the signature in @a wire_s. Also performs rudimentary
|
||||
* checks on the account data *if* supported.
|
||||
*
|
||||
* @param wire_s signed wire information of an exchange
|
||||
* @param master_pub master public key of the exchange
|
||||
* @return #GNUNET_OK if signature is valid
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_JSON_exchange_wire_signature_check (
|
||||
const json_t *wire_s,
|
||||
const struct TALER_MasterPublicKeyP *master_pub);
|
||||
|
||||
|
||||
/**
|
||||
* Create a signed wire statement for the given account.
|
||||
*
|
||||
* @param payto_uri account specification
|
||||
* @param master_priv private key to sign with
|
||||
* @return NULL if @a payto_uri is malformed
|
||||
*/
|
||||
json_t *
|
||||
TALER_JSON_exchange_wire_signature_make (
|
||||
const char *payto_uri,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv);
|
||||
|
||||
|
||||
/**
|
||||
* Extract a string from @a object under the field @a field, but respecting
|
||||
* the Taler i18n rules and the language preferences expressed in @a
|
||||
|
@ -147,15 +147,11 @@ TALER_TESTING_prepare_exchange (const char *config_filename,
|
||||
*
|
||||
* @param cls closure, typically, the "run" method containing
|
||||
* all the commands to be run, and a closure for it.
|
||||
* @param hr http response details
|
||||
* @param keys the exchange's keys.
|
||||
* @param compat protocol compatibility information.
|
||||
* @param kr response details
|
||||
*/
|
||||
void
|
||||
TALER_TESTING_cert_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_EXCHANGE_Keys *keys,
|
||||
enum TALER_EXCHANGE_VersionCompatibility compat);
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -28,12 +28,10 @@ libtalerjson_la_LIBADD = \
|
||||
$(XLIB)
|
||||
|
||||
TESTS = \
|
||||
test_json \
|
||||
test_json_wire
|
||||
test_json
|
||||
|
||||
check_PROGRAMS= \
|
||||
test_json \
|
||||
test_json_wire
|
||||
test_json
|
||||
|
||||
test_json_SOURCES = \
|
||||
test_json.c
|
||||
@ -43,13 +41,3 @@ test_json_LDADD = \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetutil \
|
||||
-ljansson
|
||||
|
||||
|
||||
test_json_wire_SOURCES = \
|
||||
test_json_wire.c
|
||||
test_json_wire_LDADD = \
|
||||
$(top_builddir)/src/json/libtalerjson.la \
|
||||
-lgnunetjson \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetutil \
|
||||
-ljansson
|
||||
|
@ -70,80 +70,6 @@ TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s,
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_JSON_exchange_wire_signature_check (
|
||||
const json_t *wire_s,
|
||||
const struct TALER_MasterPublicKeyP *master_pub)
|
||||
{
|
||||
const char *payto_uri;
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("payto_uri",
|
||||
&payto_uri),
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig",
|
||||
&master_sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (wire_s,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
{
|
||||
char *err;
|
||||
|
||||
err = TALER_payto_validate (payto_uri);
|
||||
if (NULL != err)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"URI `%s' ill-formed: %s\n",
|
||||
payto_uri,
|
||||
err);
|
||||
GNUNET_free (err);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
|
||||
return TALER_exchange_wire_signature_check (payto_uri,
|
||||
master_pub,
|
||||
&master_sig);
|
||||
}
|
||||
|
||||
|
||||
json_t *
|
||||
TALER_JSON_exchange_wire_signature_make (
|
||||
const char *payto_uri,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv)
|
||||
{
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
char *err;
|
||||
|
||||
if (NULL !=
|
||||
(err = TALER_payto_validate (payto_uri)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Invalid payto URI `%s': %s\n",
|
||||
payto_uri,
|
||||
err);
|
||||
GNUNET_free (err);
|
||||
return NULL;
|
||||
}
|
||||
TALER_exchange_wire_signature_make (payto_uri,
|
||||
master_priv,
|
||||
&master_sig);
|
||||
return GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("payto_uri",
|
||||
payto_uri),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig",
|
||||
&master_sig));
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
TALER_JSON_wire_to_payto (const json_t *wire_s)
|
||||
{
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2015, 2016 Taler Systems SA
|
||||
|
||||
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 json/test_json_wire.c
|
||||
* @brief Tests for Taler-specific crypto logic
|
||||
* @author Christian Grothoff <christian@grothoff.org>
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
const char *const argv[])
|
||||
{
|
||||
struct TALER_MasterPublicKeyP master_pub;
|
||||
struct TALER_MasterPrivateKeyP master_priv;
|
||||
json_t *wire_xtalerbank;
|
||||
json_t *wire_iban;
|
||||
const char *payto_xtalerbank = "payto://x-taler-bank/42";
|
||||
const char *payto_iban =
|
||||
"payto://iban/BIC-TO-BE-SKIPPED/DE89370400440532013000?receiver-name=Test";
|
||||
char *p_xtalerbank;
|
||||
char *p_iban;
|
||||
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
GNUNET_log_setup ("test-json-wire",
|
||||
"WARNING",
|
||||
NULL);
|
||||
GNUNET_CRYPTO_eddsa_key_create (&master_priv.eddsa_priv);
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
|
||||
&master_pub.eddsa_pub);
|
||||
wire_xtalerbank = TALER_JSON_exchange_wire_signature_make (payto_xtalerbank,
|
||||
&master_priv);
|
||||
wire_iban = TALER_JSON_exchange_wire_signature_make (payto_iban,
|
||||
&master_priv);
|
||||
if (NULL == wire_iban)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Could not parse payto/IBAN (%s) into 'wire object'\n",
|
||||
payto_iban);
|
||||
return 1;
|
||||
}
|
||||
p_xtalerbank = TALER_JSON_wire_to_payto (wire_xtalerbank);
|
||||
p_iban = TALER_JSON_wire_to_payto (wire_iban);
|
||||
GNUNET_assert (0 == strcmp (p_xtalerbank, payto_xtalerbank));
|
||||
GNUNET_assert (0 == strcmp (p_iban, payto_iban));
|
||||
GNUNET_free (p_xtalerbank);
|
||||
GNUNET_free (p_iban);
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_JSON_exchange_wire_signature_check (wire_xtalerbank,
|
||||
&master_pub));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_JSON_exchange_wire_signature_check (wire_iban,
|
||||
&master_pub));
|
||||
json_decref (wire_xtalerbank);
|
||||
json_decref (wire_iban);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* end of test_json_wire.c */
|
@ -247,7 +247,7 @@ handle_deposit_finished (void *cls,
|
||||
&dh->exchange_pub),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("transaction_base_url",
|
||||
&dr.details.success.transaction_base_url),
|
||||
&dr.details.ok.transaction_base_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&dh->exchange_timestamp),
|
||||
@ -341,10 +341,10 @@ handle_deposit_finished (void *cls,
|
||||
dh);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
}
|
||||
dr.details.success.exchange_sigs = dh->exchange_sigs;
|
||||
dr.details.success.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.success.deposit_timestamp = dh->exchange_timestamp;
|
||||
dr.details.success.num_signatures = dh->num_cdds;
|
||||
dr.details.ok.exchange_sigs = dh->exchange_sigs;
|
||||
dr.details.ok.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.ok.deposit_timestamp = dh->exchange_timestamp;
|
||||
dr.details.ok.num_signatures = dh->num_cdds;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
|
@ -144,37 +144,34 @@ struct TALER_EXCHANGE_BatchWithdrawHandle
|
||||
* HTTP /reserves/$RESERVE_PUB/batch-withdraw request.
|
||||
*
|
||||
* @param cls the `struct TALER_EXCHANGE_BatchWithdrawHandle`
|
||||
* @param hr HTTP response data
|
||||
* @param blind_sigs array of blind signatures over the coins, NULL on error
|
||||
* @param blind_sigs_length length of the @a blind_sigs array
|
||||
* @param bw2r response data
|
||||
*/
|
||||
static void
|
||||
handle_reserve_batch_withdraw_finished (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_BlindedDenominationSignature *blind_sigs,
|
||||
unsigned int blind_sigs_length)
|
||||
const struct TALER_EXCHANGE_BatchWithdraw2Response *bw2r)
|
||||
{
|
||||
struct TALER_EXCHANGE_BatchWithdrawHandle *wh = cls;
|
||||
struct TALER_EXCHANGE_BatchWithdrawResponse wr = {
|
||||
.hr = *hr
|
||||
.hr = bw2r->hr
|
||||
};
|
||||
struct TALER_EXCHANGE_PrivateCoinDetails coins[wh->num_coins];
|
||||
struct TALER_EXCHANGE_PrivateCoinDetails coins[GNUNET_NZL (wh->num_coins)];
|
||||
|
||||
wh->wh2 = NULL;
|
||||
memset (coins,
|
||||
0,
|
||||
sizeof (coins));
|
||||
if (blind_sigs_length != wh->num_coins)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
}
|
||||
switch (hr->http_status)
|
||||
switch (bw2r->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
if (bw2r->details.ok.blind_sigs_length != wh->num_coins)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
for (unsigned int i = 0; i<wh->num_coins; i++)
|
||||
{
|
||||
struct CoinData *cd = &wh->coins[i];
|
||||
@ -183,7 +180,7 @@ handle_reserve_batch_withdraw_finished (
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_planchet_to_coin (&cd->pk.key,
|
||||
&blind_sigs[i],
|
||||
&bw2r->details.ok.blind_sigs[i],
|
||||
&cd->bks,
|
||||
&cd->priv,
|
||||
cd->ach,
|
||||
@ -200,8 +197,8 @@ handle_reserve_batch_withdraw_finished (
|
||||
coin->sig = fc.sig;
|
||||
coin->exchange_vals = cd->alg_values;
|
||||
}
|
||||
wr.details.success.coins = coins;
|
||||
wr.details.success.num_coins = wh->num_coins;
|
||||
wr.details.ok.coins = coins;
|
||||
wr.details.ok.num_coins = wh->num_coins;
|
||||
break;
|
||||
}
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
@ -217,7 +214,7 @@ handle_reserve_batch_withdraw_finished (
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (hr->reply,
|
||||
GNUNET_JSON_parse (bw2r->hr.reply,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
@ -289,7 +286,7 @@ withdraw_cs_stage_two_callback (
|
||||
switch (csrr->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
cd->alg_values = csrr->details.success.alg_values;
|
||||
cd->alg_values = csrr->details.ok.alg_values;
|
||||
TALER_planchet_setup_coin_priv (&cd->ps,
|
||||
&cd->alg_values,
|
||||
&cd->priv);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -108,9 +108,9 @@ reserve_batch_withdraw_ok (struct TALER_EXCHANGE_BatchWithdraw2Handle *wh,
|
||||
"ev_sigs");
|
||||
const json_t *j;
|
||||
unsigned int index;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = MHD_HTTP_OK
|
||||
struct TALER_EXCHANGE_BatchWithdraw2Response bwr = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = MHD_HTTP_OK
|
||||
};
|
||||
|
||||
if ( (NULL == ja) ||
|
||||
@ -141,10 +141,10 @@ reserve_batch_withdraw_ok (struct TALER_EXCHANGE_BatchWithdraw2Handle *wh,
|
||||
}
|
||||
|
||||
/* signature is valid, return it to the application */
|
||||
bwr.details.ok.blind_sigs = blind_sigs;
|
||||
bwr.details.ok.blind_sigs_length = wh->num_coins;
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
blind_sigs,
|
||||
wh->num_coins);
|
||||
&bwr);
|
||||
/* make sure callback isn't called again after return */
|
||||
wh->cb = NULL;
|
||||
for (unsigned int i = 0; i<wh->num_coins; i++)
|
||||
@ -264,16 +264,16 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_BatchWithdraw2Handle *wh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_BatchWithdraw2Response bwr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
wh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
bwr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK !=
|
||||
@ -281,8 +281,8 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
bwr.hr.http_status = 0;
|
||||
bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
GNUNET_assert (NULL == wh->cb);
|
||||
@ -304,8 +304,8 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
bwr.hr.http_status = 0;
|
||||
bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -313,24 +313,24 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
GNUNET_break_op (0);
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, the exchange basically just says
|
||||
that it doesn't know this reserve. Can happen if we
|
||||
query before the wire transfer went through.
|
||||
We should simply pass the JSON reply to the application. */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
/* The exchange says that the reserve has insufficient funds;
|
||||
@ -340,13 +340,13 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
bwr.hr.http_status = 0;
|
||||
bwr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
@ -354,32 +354,30 @@ handle_reserve_batch_withdraw_finished (void *cls,
|
||||
/* Note: one might want to check /keys for revocation
|
||||
signature here, alas tricky in case our /keys
|
||||
is outdated => left to clients */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
bwr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
bwr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange batch withdraw\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) bwr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
NULL,
|
||||
0);
|
||||
&bwr);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_batch_withdraw2_cancel (wh);
|
||||
|
@ -109,7 +109,7 @@ handle_contract_get_finished (void *cls,
|
||||
struct TALER_PurseContractSignatureP econtract_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("purse_pub",
|
||||
&dr.details.success.purse_pub),
|
||||
&dr.details.ok.purse_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("econtract_sig",
|
||||
&econtract_sig),
|
||||
GNUNET_JSON_spec_varsize ("econtract",
|
||||
@ -133,7 +133,7 @@ handle_contract_get_finished (void *cls,
|
||||
econtract,
|
||||
econtract_size,
|
||||
&cgh->cpub,
|
||||
&dr.details.success.purse_pub,
|
||||
&dr.details.ok.purse_pub,
|
||||
&econtract_sig))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -142,8 +142,8 @@ handle_contract_get_finished (void *cls,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
break;
|
||||
}
|
||||
dr.details.success.econtract = econtract;
|
||||
dr.details.success.econtract_size = econtract_size;
|
||||
dr.details.ok.econtract = econtract;
|
||||
dr.details.ok.econtract_size = econtract_size;
|
||||
cgh->cb (cgh->cb_cls,
|
||||
&dr);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
|
@ -94,8 +94,8 @@ csr_ok (struct TALER_EXCHANGE_CsRMeltHandle *csrh,
|
||||
struct TALER_ExchangeWithdrawValues alg_values[GNUNET_NZL (alen)];
|
||||
struct TALER_EXCHANGE_CsRMeltResponse csrr = {
|
||||
.hr = *hr,
|
||||
.details.success.alg_values_len = alen,
|
||||
.details.success.alg_values = alg_values
|
||||
.details.ok.alg_values_len = alen,
|
||||
.details.ok.alg_values = alg_values
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i<alen; i++)
|
||||
|
@ -96,7 +96,7 @@ csr_ok (struct TALER_EXCHANGE_CsRWithdrawHandle *csrh,
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_exchange_withdraw_values (
|
||||
"ewv",
|
||||
&csrr.details.success.alg_values),
|
||||
&csrr.details.ok.alg_values),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
|
@ -236,7 +236,7 @@ handle_deposit_finished (void *cls,
|
||||
&dh->exchange_pub),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("transaction_base_url",
|
||||
&dr.details.success.transaction_base_url),
|
||||
&dr.details.ok.transaction_base_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&dh->exchange_timestamp),
|
||||
@ -297,9 +297,9 @@ handle_deposit_finished (void *cls,
|
||||
&auditor_cb,
|
||||
dh);
|
||||
}
|
||||
dr.details.success.exchange_sig = &dh->exchange_sig;
|
||||
dr.details.success.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.success.deposit_timestamp = dh->exchange_timestamp;
|
||||
dr.details.ok.exchange_sig = &dh->exchange_sig;
|
||||
dr.details.ok.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.ok.deposit_timestamp = dh->exchange_timestamp;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
|
@ -118,15 +118,15 @@ handle_deposit_wtid_finished (void *cls,
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("wtid",
|
||||
&dr.details.success.wtid),
|
||||
&dr.details.ok.wtid),
|
||||
GNUNET_JSON_spec_timestamp ("execution_time",
|
||||
&dr.details.success.execution_time),
|
||||
&dr.details.ok.execution_time),
|
||||
TALER_JSON_spec_amount_any ("coin_contribution",
|
||||
&dr.details.success.coin_contribution),
|
||||
&dr.details.ok.coin_contribution),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&dr.details.success.exchange_sig),
|
||||
&dr.details.ok.exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&dr.details.success.exchange_pub),
|
||||
&dr.details.ok.exchange_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
@ -145,7 +145,7 @@ handle_deposit_wtid_finished (void *cls,
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&dr.details.success.exchange_pub))
|
||||
&dr.details.ok.exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
@ -156,12 +156,12 @@ handle_deposit_wtid_finished (void *cls,
|
||||
TALER_exchange_online_confirm_wire_verify (
|
||||
&dwh->h_wire,
|
||||
&dwh->h_contract_terms,
|
||||
&dr.details.success.wtid,
|
||||
&dr.details.ok.wtid,
|
||||
&dwh->coin_pub,
|
||||
dr.details.success.execution_time,
|
||||
&dr.details.success.coin_contribution,
|
||||
&dr.details.success.exchange_pub,
|
||||
&dr.details.success.exchange_sig))
|
||||
dr.details.ok.execution_time,
|
||||
&dr.details.ok.coin_contribution,
|
||||
&dr.details.ok.exchange_pub,
|
||||
&dr.details.ok.exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
@ -40,7 +40,7 @@
|
||||
* Which version of the Taler protocol is implemented
|
||||
* by this library? Used to determine compatibility.
|
||||
*/
|
||||
#define EXCHANGE_PROTOCOL_CURRENT 14
|
||||
#define EXCHANGE_PROTOCOL_CURRENT 15
|
||||
|
||||
/**
|
||||
* How many versions are we backwards compatible with?
|
||||
@ -1305,15 +1305,18 @@ keys_completed_cb (void *cls,
|
||||
{
|
||||
struct KeysRequest *kr = cls;
|
||||
struct TALER_EXCHANGE_Handle *exchange = kr->exchange;
|
||||
struct TALER_EXCHANGE_Keys kd;
|
||||
struct TALER_EXCHANGE_Keys kd_old;
|
||||
enum TALER_EXCHANGE_VersionCompatibility vc;
|
||||
const json_t *j = resp_obj;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_Keys kd;
|
||||
struct TALER_EXCHANGE_KeysResponse kresp = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.details.ok.compat = TALER_EXCHANGE_VC_PROTOCOL_ERROR,
|
||||
};
|
||||
|
||||
memset (&kd,
|
||||
0,
|
||||
sizeof (kd));
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Received keys from URL `%s' with status %ld and expiration %s.\n",
|
||||
kr->url,
|
||||
@ -1330,10 +1333,6 @@ keys_completed_cb (void *cls,
|
||||
GNUNET_TIME_relative_to_absolute (DEFAULT_EXPIRATION));
|
||||
}
|
||||
kd_old = exchange->key_data;
|
||||
memset (&kd,
|
||||
0,
|
||||
sizeof (struct TALER_EXCHANGE_Keys));
|
||||
vc = TALER_EXCHANGE_VC_PROTOCOL_ERROR;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -1358,8 +1357,10 @@ keys_completed_cb (void *cls,
|
||||
}
|
||||
/* We keep the denomination keys and auditor signatures from the
|
||||
previous iteration (/keys cherry picking) */
|
||||
kd.num_denom_keys = kd_old.num_denom_keys;
|
||||
kd.last_denom_issue_date = kd_old.last_denom_issue_date;
|
||||
kd.num_denom_keys
|
||||
= kd_old.num_denom_keys;
|
||||
kd.last_denom_issue_date
|
||||
= kd_old.last_denom_issue_date;
|
||||
GNUNET_array_grow (kd.denom_keys,
|
||||
kd.denom_keys_size,
|
||||
kd.num_denom_keys);
|
||||
@ -1401,11 +1402,11 @@ keys_completed_cb (void *cls,
|
||||
decode_keys_json (j,
|
||||
true,
|
||||
&kd,
|
||||
&vc))
|
||||
&kresp.details.ok.compat))
|
||||
{
|
||||
TALER_LOG_ERROR ("Could not decode /keys response\n");
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
kresp.hr.http_status = 0;
|
||||
kresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
for (unsigned int i = 0; i<kd.num_auditors; i++)
|
||||
{
|
||||
struct TALER_EXCHANGE_AuditorInformation *anew = &kd.auditors[i];
|
||||
@ -1436,13 +1437,13 @@ keys_completed_cb (void *cls,
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
if (NULL == j)
|
||||
{
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = TALER_ErrorCode_get_hint (hr.ec);
|
||||
kresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
kresp.hr.hint = TALER_ErrorCode_get_hint (kresp.hr.ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
kresp.hr.ec = TALER_JSON_get_error_code (j);
|
||||
kresp.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1450,18 +1451,18 @@ keys_completed_cb (void *cls,
|
||||
exchange->keys_error_count++;
|
||||
if (NULL == j)
|
||||
{
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = TALER_ErrorCode_get_hint (hr.ec);
|
||||
kresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
kresp.hr.hint = TALER_ErrorCode_get_hint (kresp.hr.ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
kresp.hr.ec = TALER_JSON_get_error_code (j);
|
||||
kresp.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) kresp.hr.ec);
|
||||
break;
|
||||
}
|
||||
exchange->key_data = kd;
|
||||
@ -1491,9 +1492,7 @@ keys_completed_cb (void *cls,
|
||||
free_key_data (&kd_old);
|
||||
/* notify application that we failed */
|
||||
exchange->cert_cb (exchange->cert_cb_cls,
|
||||
&hr,
|
||||
NULL,
|
||||
vc);
|
||||
&kresp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1504,11 +1503,11 @@ keys_completed_cb (void *cls,
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Successfully downloaded exchange's keys\n");
|
||||
update_auditors (exchange);
|
||||
kresp.details.ok.keys = &exchange->key_data;
|
||||
|
||||
/* notify application about the key information */
|
||||
exchange->cert_cb (exchange->cert_cb_cls,
|
||||
&hr,
|
||||
&exchange->key_data,
|
||||
vc);
|
||||
&kresp);
|
||||
free_key_data (&kd_old);
|
||||
}
|
||||
|
||||
@ -1702,7 +1701,6 @@ static void
|
||||
deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
|
||||
const json_t *data)
|
||||
{
|
||||
enum TALER_EXCHANGE_VersionCompatibility vc;
|
||||
json_t *keys;
|
||||
const char *url;
|
||||
uint32_t version;
|
||||
@ -1719,10 +1717,11 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_Keys key_data;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.ec = TALER_EC_NONE,
|
||||
.http_status = MHD_HTTP_OK,
|
||||
.reply = data
|
||||
struct TALER_EXCHANGE_KeysResponse kresp = {
|
||||
.hr.ec = TALER_EC_NONE,
|
||||
.hr.http_status = MHD_HTTP_OK,
|
||||
.hr.reply = data,
|
||||
.details.ok.keys = &exchange->key_data
|
||||
};
|
||||
|
||||
if (NULL == data)
|
||||
@ -1754,7 +1753,7 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
|
||||
decode_keys_json (keys,
|
||||
false,
|
||||
&key_data,
|
||||
&vc))
|
||||
&kresp.details.ok.compat))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -1771,9 +1770,7 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
|
||||
update_auditors (exchange);
|
||||
/* notify application about the key information */
|
||||
exchange->cert_cb (exchange->cert_cb_cls,
|
||||
&hr,
|
||||
&exchange->key_data,
|
||||
vc);
|
||||
&kresp);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
}
|
||||
|
||||
@ -2056,17 +2053,18 @@ request_keys (void *cls)
|
||||
url);
|
||||
if (NULL == kr->url)
|
||||
{
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.ec = TALER_EC_GENERIC_CONFIGURATION_INVALID
|
||||
struct TALER_EXCHANGE_KeysResponse kresp = {
|
||||
.hr.ec = TALER_EC_GENERIC_CONFIGURATION_INVALID,
|
||||
/* Next line is technically unnecessary, as the
|
||||
http status we set is 0 */
|
||||
.details.ok.compat = TALER_EXCHANGE_VC_PROTOCOL_ERROR
|
||||
};
|
||||
|
||||
GNUNET_free (kr);
|
||||
exchange->keys_error_count++;
|
||||
exchange->state = MHS_FAILED;
|
||||
exchange->cert_cb (exchange->cert_cb_cls,
|
||||
&hr,
|
||||
NULL,
|
||||
TALER_EXCHANGE_VC_PROTOCOL_ERROR);
|
||||
&kresp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -100,11 +100,11 @@ handle_kyc_check_finished (void *cls,
|
||||
uint32_t status;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&ks.details.success.exchange_sig),
|
||||
&ks.details.ok.exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&ks.details.success.exchange_pub),
|
||||
&ks.details.ok.exchange_pub),
|
||||
GNUNET_JSON_spec_timestamp ("now",
|
||||
&ks.details.success.timestamp),
|
||||
&ks.details.ok.timestamp),
|
||||
GNUNET_JSON_spec_json ("kyc_details",
|
||||
&kyc_details),
|
||||
GNUNET_JSON_spec_uint32 ("aml_status",
|
||||
@ -123,13 +123,13 @@ handle_kyc_check_finished (void *cls,
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
}
|
||||
ks.details.success.kyc_details = kyc_details;
|
||||
ks.details.success.aml_status
|
||||
ks.details.ok.kyc_details = kyc_details;
|
||||
ks.details.ok.aml_status
|
||||
= (enum TALER_AmlDecisionState) status;
|
||||
key_state = TALER_EXCHANGE_get_keys (kch->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&ks.details.success.exchange_pub))
|
||||
&ks.details.ok.exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
@ -141,10 +141,10 @@ handle_kyc_check_finished (void *cls,
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_account_setup_success_verify (
|
||||
&kch->h_payto,
|
||||
ks.details.success.kyc_details,
|
||||
ks.details.success.timestamp,
|
||||
&ks.details.success.exchange_pub,
|
||||
&ks.details.success.exchange_sig))
|
||||
ks.details.ok.kyc_details,
|
||||
ks.details.ok.timestamp,
|
||||
&ks.details.ok.exchange_pub,
|
||||
&ks.details.ok.exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
|
@ -365,8 +365,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
|
||||
if (off_coin == num_coins)
|
||||
{
|
||||
lr.details.success.num_coins = num_coins;
|
||||
lr.details.success.coins = lcis;
|
||||
lr.details.ok.num_coins = num_coins;
|
||||
lr.details.ok.coins = lcis;
|
||||
lh->link_cb (lh->link_cb_cls,
|
||||
&lr);
|
||||
lh->link_cb = NULL;
|
||||
|
@ -190,17 +190,17 @@ parse_decision_ok (struct TALER_EXCHANGE_LookupAmlDecision *lh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
lr.details.success.aml_history_length = json_array_size (aml_history);
|
||||
lr.details.success.kyc_attributes_length = json_array_size (kyc_attributes);
|
||||
lr.details.ok.aml_history_length = json_array_size (aml_history);
|
||||
lr.details.ok.kyc_attributes_length = json_array_size (kyc_attributes);
|
||||
{
|
||||
struct TALER_EXCHANGE_AmlDecisionDetail aml_history_ar[
|
||||
GNUNET_NZL (lr.details.success.aml_history_length)];
|
||||
GNUNET_NZL (lr.details.ok.aml_history_length)];
|
||||
struct TALER_EXCHANGE_KycHistoryDetail kyc_attributes_ar[
|
||||
lr.details.success.kyc_attributes_length];
|
||||
lr.details.ok.kyc_attributes_length];
|
||||
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
|
||||
|
||||
lr.details.success.aml_history = aml_history_ar;
|
||||
lr.details.success.kyc_attributes = kyc_attributes_ar;
|
||||
lr.details.ok.aml_history = aml_history_ar;
|
||||
lr.details.ok.kyc_attributes = kyc_attributes_ar;
|
||||
ret = parse_aml_history (aml_history,
|
||||
aml_history_ar);
|
||||
if (GNUNET_OK == ret)
|
||||
|
@ -139,13 +139,13 @@ parse_decisions_ok (struct TALER_EXCHANGE_LookupAmlDecisions *lh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
lr.details.success.decisions_length = json_array_size (records);
|
||||
lr.details.ok.decisions_length = json_array_size (records);
|
||||
{
|
||||
struct TALER_EXCHANGE_AmlDecisionSummary decisions[
|
||||
GNUNET_NZL (lr.details.success.decisions_length)];
|
||||
GNUNET_NZL (lr.details.ok.decisions_length)];
|
||||
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
|
||||
|
||||
lr.details.success.decisions = decisions;
|
||||
lr.details.ok.decisions = decisions;
|
||||
ret = parse_aml_decisions (records,
|
||||
decisions);
|
||||
if (GNUNET_OK == ret)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020-2022 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -79,9 +79,9 @@ handle_drain_profits_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementDrainResponse dr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
dp->job = NULL;
|
||||
@ -90,32 +90,32 @@ handle_drain_profits_finished (void *cls,
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_PRECONDITION_FAILED:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management drain profits\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) dr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != dp->cb)
|
||||
{
|
||||
dp->cb (dp->cb_cls,
|
||||
&hr);
|
||||
&dr);
|
||||
dp->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_drain_profits_cancel (dp);
|
||||
|
@ -75,11 +75,16 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle
|
||||
* @param response the response
|
||||
* @return #GNUNET_OK if the response was well-formed
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
const json_t *response)
|
||||
{
|
||||
struct TALER_EXCHANGE_FutureKeys fk;
|
||||
struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = {
|
||||
.hr.http_status = MHD_HTTP_OK,
|
||||
.hr.reply = response,
|
||||
};
|
||||
struct TALER_EXCHANGE_FutureKeys *fk
|
||||
= &gkr.details.ok.keys;
|
||||
json_t *sk;
|
||||
json_t *dk;
|
||||
bool ok;
|
||||
@ -89,13 +94,13 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
GNUNET_JSON_spec_json ("future_signkeys",
|
||||
&sk),
|
||||
GNUNET_JSON_spec_fixed_auto ("master_pub",
|
||||
&fk.master_pub),
|
||||
&fk->master_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
|
||||
&fk.denom_secmod_public_key),
|
||||
&fk->denom_secmod_public_key),
|
||||
GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key",
|
||||
&fk.denom_secmod_cs_public_key),
|
||||
&fk->denom_secmod_cs_public_key),
|
||||
GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key",
|
||||
&fk.signkey_secmod_public_key),
|
||||
&fk->signkey_secmod_public_key),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -107,21 +112,21 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
fk.num_sign_keys = json_array_size (sk);
|
||||
fk.num_denom_keys = json_array_size (dk);
|
||||
fk.sign_keys = GNUNET_new_array (
|
||||
fk.num_sign_keys,
|
||||
fk->num_sign_keys = json_array_size (sk);
|
||||
fk->num_denom_keys = json_array_size (dk);
|
||||
fk->sign_keys = GNUNET_new_array (
|
||||
fk->num_sign_keys,
|
||||
struct TALER_EXCHANGE_FutureSigningPublicKey);
|
||||
fk.denom_keys = GNUNET_new_array (
|
||||
fk.num_denom_keys,
|
||||
fk->denom_keys = GNUNET_new_array (
|
||||
fk->num_denom_keys,
|
||||
struct TALER_EXCHANGE_FutureDenomPublicKey);
|
||||
ok = true;
|
||||
for (unsigned int i = 0; i<fk.num_sign_keys; i++)
|
||||
for (unsigned int i = 0; i<fk->num_sign_keys; i++)
|
||||
{
|
||||
json_t *j = json_array_get (sk,
|
||||
i);
|
||||
struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key
|
||||
= &fk.sign_keys[i];
|
||||
= &fk->sign_keys[i];
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("key",
|
||||
&sign_key->key),
|
||||
@ -155,7 +160,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
&sign_key->key,
|
||||
sign_key->valid_from,
|
||||
duration,
|
||||
&fk.signkey_secmod_public_key,
|
||||
&fk->signkey_secmod_public_key,
|
||||
&sign_key->signkey_secmod_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -164,12 +169,12 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i<fk.num_denom_keys; i++)
|
||||
for (unsigned int i = 0; i<fk->num_denom_keys; i++)
|
||||
{
|
||||
json_t *j = json_array_get (dk,
|
||||
i);
|
||||
struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key
|
||||
= &fk.denom_keys[i];
|
||||
= &fk->denom_keys[i];
|
||||
const char *section_name;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any ("value",
|
||||
@ -236,7 +241,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
section_name,
|
||||
denom_key->valid_from,
|
||||
duration,
|
||||
&fk.denom_secmod_public_key,
|
||||
&fk->denom_secmod_public_key,
|
||||
&denom_key->denom_secmod_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -256,7 +261,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
section_name,
|
||||
denom_key->valid_from,
|
||||
duration,
|
||||
&fk.denom_secmod_cs_public_key,
|
||||
&fk->denom_secmod_cs_public_key,
|
||||
&denom_key->denom_secmod_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -277,19 +282,13 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh,
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = MHD_HTTP_OK,
|
||||
.reply = response
|
||||
};
|
||||
|
||||
gh->cb (gh->cb_cls,
|
||||
&hr,
|
||||
&fk);
|
||||
&gkr);
|
||||
}
|
||||
for (unsigned int i = 0; i<fk.num_denom_keys; i++)
|
||||
TALER_denom_pub_free (&fk.denom_keys[i].key);
|
||||
GNUNET_free (fk.sign_keys);
|
||||
GNUNET_free (fk.denom_keys);
|
||||
for (unsigned int i = 0; i<fk->num_denom_keys; i++)
|
||||
TALER_denom_pub_free (&fk->denom_keys[i].key);
|
||||
GNUNET_free (fk->sign_keys);
|
||||
GNUNET_free (fk->denom_keys);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return (ok) ? GNUNET_OK : GNUNET_SYSERR;
|
||||
}
|
||||
@ -310,9 +309,9 @@ handle_get_keys_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementGetKeysHandle *gh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
gh->job = NULL;
|
||||
@ -334,25 +333,24 @@ handle_get_keys_finished (void *cls,
|
||||
/* unexpected response code */
|
||||
if (NULL != json)
|
||||
{
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
gkr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
gkr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = TALER_ErrorCode_get_hint (hr.ec);
|
||||
gkr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
gkr.hr.hint = TALER_ErrorCode_get_hint (gkr.hr.ec);
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management get keys\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) gkr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != gh->cb)
|
||||
{
|
||||
gh->cb (gh->cb_cls,
|
||||
&hr,
|
||||
NULL);
|
||||
&gkr);
|
||||
gh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_get_management_keys_cancel (gh);
|
||||
|
@ -83,9 +83,9 @@ handle_post_extensions_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementPostExtensionsResponse per = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
ph->job = NULL;
|
||||
@ -94,28 +94,28 @@ handle_post_extensions_finished (void *cls,
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
per.hr.ec = TALER_JSON_get_error_code (json);
|
||||
per.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
per.hr.ec = TALER_JSON_get_error_code (json);
|
||||
per.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
per.hr.ec = TALER_JSON_get_error_code (json);
|
||||
per.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management post extensions\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) per.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != ph->cb)
|
||||
{
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr);
|
||||
&per);
|
||||
ph->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_post_extensions_cancel (ph);
|
||||
|
@ -82,9 +82,9 @@ handle_post_keys_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementPostKeysHandle *ph = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementPostKeysResponse pkr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
ph->job = NULL;
|
||||
@ -93,32 +93,32 @@ handle_post_keys_finished (void *cls,
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
pkr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
pkr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
pkr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
pkr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
pkr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
pkr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
pkr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
pkr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management post keys\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) pkr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != ph->cb)
|
||||
{
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr);
|
||||
&pkr);
|
||||
ph->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_post_management_keys_cancel (ph);
|
||||
|
@ -82,9 +82,9 @@ handle_revoke_denomination_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementRevokeDenominationResponse rdr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
rh->job = NULL;
|
||||
@ -92,30 +92,30 @@ handle_revoke_denomination_finished (void *cls,
|
||||
{
|
||||
case 0:
|
||||
/* no reply */
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = "server offline?";
|
||||
rdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rdr.hr.hint = "server offline?";
|
||||
break;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
rdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
rdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
rdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
rdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management revoke denomination\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) rdr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != rh->cb)
|
||||
{
|
||||
rh->cb (rh->cb_cls,
|
||||
&hr);
|
||||
&rdr);
|
||||
rh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_revoke_denomination_key_cancel (rh);
|
||||
|
@ -79,9 +79,9 @@ handle_revoke_signing_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse rsr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
rh->job = NULL;
|
||||
@ -89,30 +89,30 @@ handle_revoke_signing_finished (void *cls,
|
||||
{
|
||||
case 0:
|
||||
/* no reply */
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = "server offline?";
|
||||
rsr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rsr.hr.hint = "server offline?";
|
||||
break;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
rsr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
rsr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
rsr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
rsr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management revoke signkey\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) rsr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != rh->cb)
|
||||
{
|
||||
rh->cb (rh->cb_cls,
|
||||
&hr);
|
||||
&rsr);
|
||||
rh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_revoke_signing_key_cancel (rh);
|
||||
|
@ -79,9 +79,9 @@ handle_update_aml_officer_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse uar = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
wh->job = NULL;
|
||||
@ -89,34 +89,34 @@ handle_update_aml_officer_finished (void *cls,
|
||||
{
|
||||
case 0:
|
||||
/* no reply */
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = "server offline?";
|
||||
uar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
uar.hr.hint = "server offline?";
|
||||
break;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
uar.hr.ec = TALER_JSON_get_error_code (json);
|
||||
uar.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
uar.hr.ec = TALER_JSON_get_error_code (json);
|
||||
uar.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
uar.hr.ec = TALER_JSON_get_error_code (json);
|
||||
uar.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management update AML officer\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) uar.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr);
|
||||
&uar);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_update_aml_officer_cancel (wh);
|
||||
|
@ -79,9 +79,9 @@ handle_auditor_disable_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementWireDisableHandle *wh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementWireDisableResponse wdr = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
wh->job = NULL;
|
||||
@ -89,38 +89,38 @@ handle_auditor_disable_finished (void *cls,
|
||||
{
|
||||
case 0:
|
||||
/* no reply */
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = "server offline?";
|
||||
wdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
wdr.hr.hint = "server offline?";
|
||||
break;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wdr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wdr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d exchange management disable wire\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) wdr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr);
|
||||
&wdr);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_disable_wire_cancel (wh);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2015-2021 Taler Systems SA
|
||||
Copyright (C) 2015-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -79,9 +79,9 @@ handle_auditor_enable_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_ManagementWireEnableHandle *wh = cls;
|
||||
const json_t *json = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.http_status = (unsigned int) response_code,
|
||||
.reply = json
|
||||
struct TALER_EXCHANGE_ManagementWireEnableResponse wer = {
|
||||
.hr.http_status = (unsigned int) response_code,
|
||||
.hr.reply = json
|
||||
};
|
||||
|
||||
wh->job = NULL;
|
||||
@ -89,34 +89,34 @@ handle_auditor_enable_finished (void *cls,
|
||||
{
|
||||
case 0:
|
||||
/* no reply */
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
hr.hint = "server offline?";
|
||||
wer.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
wer.hr.hint = "server offline?";
|
||||
break;
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wer.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wer.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wer.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wer.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
wer.hr.ec = TALER_JSON_get_error_code (json);
|
||||
wer.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange management enable wire\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) wer.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr);
|
||||
&wer);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_management_enable_wire_cancel (wh);
|
||||
@ -128,6 +128,9 @@ TALER_EXCHANGE_management_enable_wire (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp validity_start,
|
||||
const struct TALER_MasterSignatureP *master_sig1,
|
||||
const struct TALER_MasterSignatureP *master_sig2,
|
||||
@ -167,6 +170,13 @@ TALER_EXCHANGE_management_enable_wire (
|
||||
body = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("payto_uri",
|
||||
payto_uri),
|
||||
GNUNET_JSON_pack_array_incref ("debit_restrictions",
|
||||
(json_t *) debit_restrictions),
|
||||
GNUNET_JSON_pack_array_incref ("credit_restrictions",
|
||||
(json_t *) credit_restrictions),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_string ("conversion_url",
|
||||
conversion_url)),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig_add",
|
||||
master_sig1),
|
||||
GNUNET_JSON_pack_data_auto ("master_sig_wire",
|
||||
|
@ -221,16 +221,16 @@ handle_melt_finished (void *cls,
|
||||
if (GNUNET_OK !=
|
||||
verify_melt_signature_ok (mh,
|
||||
j,
|
||||
&mr.details.success.sign_key))
|
||||
&mr.details.ok.sign_key))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
mr.hr.http_status = 0;
|
||||
mr.hr.ec = TALER_EC_EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
mr.details.success.noreveal_index = mh->noreveal_index;
|
||||
mr.details.success.num_mbds = mh->rd->fresh_pks_len;
|
||||
mr.details.success.mbds = mh->mbds;
|
||||
mr.details.ok.noreveal_index = mh->noreveal_index;
|
||||
mr.details.ok.num_mbds = mh->rd->fresh_pks_len;
|
||||
mr.details.ok.mbds = mh->mbds;
|
||||
mh->melt_cb (mh->melt_cb_cls,
|
||||
&mr);
|
||||
mh->melt_cb = NULL;
|
||||
@ -478,7 +478,7 @@ csr_cb (void *cls,
|
||||
break;
|
||||
case TALER_DENOMINATION_CS:
|
||||
GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher);
|
||||
*wv = csrr->details.success.alg_values[nks_off];
|
||||
*wv = csrr->details.ok.alg_values[nks_off];
|
||||
nks_off++;
|
||||
break;
|
||||
}
|
||||
|
@ -164,17 +164,17 @@ handle_purse_deposit_finished (void *cls,
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&exchange_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
|
||||
&dr.details.success.h_contract_terms),
|
||||
&dr.details.ok.h_contract_terms),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&etime),
|
||||
GNUNET_JSON_spec_timestamp ("purse_expiration",
|
||||
&dr.details.success.purse_expiration),
|
||||
&dr.details.ok.purse_expiration),
|
||||
TALER_JSON_spec_amount ("total_deposited",
|
||||
keys->currency,
|
||||
&dr.details.success.total_deposited),
|
||||
&dr.details.ok.total_deposited),
|
||||
TALER_JSON_spec_amount ("purse_value_after_fees",
|
||||
keys->currency,
|
||||
&dr.details.success.purse_value_after_fees),
|
||||
&dr.details.ok.purse_value_after_fees),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -200,11 +200,11 @@ handle_purse_deposit_finished (void *cls,
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_purse_created_verify (
|
||||
etime,
|
||||
dr.details.success.purse_expiration,
|
||||
&dr.details.success.purse_value_after_fees,
|
||||
&dr.details.success.total_deposited,
|
||||
dr.details.ok.purse_expiration,
|
||||
&dr.details.ok.purse_value_after_fees,
|
||||
&dr.details.ok.total_deposited,
|
||||
&pch->purse_pub,
|
||||
&dr.details.success.h_contract_terms,
|
||||
&dr.details.ok.h_contract_terms,
|
||||
&exchange_pub,
|
||||
&exchange_sig))
|
||||
{
|
||||
|
@ -152,11 +152,11 @@ handle_purse_merge_finished (void *cls,
|
||||
struct TALER_Amount total_deposited;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&dr.details.success.exchange_sig),
|
||||
&dr.details.ok.exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&dr.details.success.exchange_pub),
|
||||
&dr.details.ok.exchange_pub),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&dr.details.success.etime),
|
||||
&dr.details.ok.etime),
|
||||
TALER_JSON_spec_amount ("merge_amount",
|
||||
pch->purse_value_after_fees.currency,
|
||||
&total_deposited),
|
||||
@ -176,7 +176,7 @@ handle_purse_merge_finished (void *cls,
|
||||
key_state = TALER_EXCHANGE_get_keys (pch->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&dr.details.success.exchange_pub))
|
||||
&dr.details.ok.exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
@ -185,15 +185,15 @@ handle_purse_merge_finished (void *cls,
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_purse_merged_verify (
|
||||
dr.details.success.etime,
|
||||
dr.details.ok.etime,
|
||||
pch->purse_expiration,
|
||||
&pch->purse_value_after_fees,
|
||||
&pch->purse_pub,
|
||||
&pch->h_contract_terms,
|
||||
&pch->reserve_pub,
|
||||
pch->provider_url,
|
||||
&dr.details.success.exchange_pub,
|
||||
&dr.details.success.exchange_sig))
|
||||
&dr.details.ok.exchange_pub,
|
||||
&dr.details.ok.exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
|
@ -101,16 +101,16 @@ handle_purse_get_finished (void *cls,
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_timestamp ("merge_timestamp",
|
||||
&dr.details.success.merge_timestamp),
|
||||
&dr.details.ok.merge_timestamp),
|
||||
&no_merge),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_timestamp ("deposit_timestamp",
|
||||
&dr.details.success.deposit_timestamp),
|
||||
&dr.details.ok.deposit_timestamp),
|
||||
&no_deposit),
|
||||
TALER_JSON_spec_amount_any ("balance",
|
||||
&dr.details.success.balance),
|
||||
&dr.details.ok.balance),
|
||||
GNUNET_JSON_spec_timestamp ("purse_expiration",
|
||||
&dr.details.success.purse_expiration),
|
||||
&dr.details.ok.purse_expiration),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&exchange_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
@ -142,9 +142,9 @@ handle_purse_get_finished (void *cls,
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_purse_status_verify (
|
||||
dr.details.success.merge_timestamp,
|
||||
dr.details.success.deposit_timestamp,
|
||||
&dr.details.success.balance,
|
||||
dr.details.ok.merge_timestamp,
|
||||
dr.details.ok.deposit_timestamp,
|
||||
&dr.details.ok.balance,
|
||||
&exchange_pub,
|
||||
&exchange_sig))
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2017-2022 Taler Systems SA
|
||||
Copyright (C) 2017-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -100,16 +100,15 @@ static enum GNUNET_GenericReturnValue
|
||||
process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
|
||||
const json_t *json)
|
||||
{
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_EXCHANGE_RecoupResponse rr = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = MHD_HTTP_OK
|
||||
};
|
||||
struct GNUNET_JSON_Specification spec_withdraw[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("reserve_pub",
|
||||
&reserve_pub),
|
||||
&rr.details.ok.reserve_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = MHD_HTTP_OK
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (json,
|
||||
@ -120,8 +119,7 @@ process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr,
|
||||
&reserve_pub);
|
||||
&rr);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
@ -141,9 +139,9 @@ handle_recoup_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupHandle *ph = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_RecoupResponse rr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
@ -152,7 +150,7 @@ handle_recoup_finished (void *cls,
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK !=
|
||||
@ -160,8 +158,8 @@ handle_recoup_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
TALER_EXCHANGE_recoup_cancel (ph);
|
||||
@ -169,22 +167,22 @@ handle_recoup_finished (void *cls,
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
{
|
||||
struct TALER_Amount min_key;
|
||||
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_get_min_denomination_ (keys,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
@ -197,8 +195,8 @@ handle_recoup_finished (void *cls,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -207,41 +205,40 @@ handle_recoup_finished (void *cls,
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
/* Kind of normal: the money was already sent to the merchant
|
||||
(it was too late for the refund). */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange recoup\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) rr.hr.ec);
|
||||
GNUNET_break (0);
|
||||
break;
|
||||
}
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr,
|
||||
NULL);
|
||||
&rr);
|
||||
TALER_EXCHANGE_recoup_cancel (ph);
|
||||
}
|
||||
|
||||
|
@ -101,16 +101,15 @@ process_recoup_response (
|
||||
const struct TALER_EXCHANGE_RecoupRefreshHandle *ph,
|
||||
const json_t *json)
|
||||
{
|
||||
struct TALER_CoinSpendPublicKeyP old_coin_pub;
|
||||
struct TALER_EXCHANGE_RecoupRefreshResponse rrr = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = MHD_HTTP_OK
|
||||
};
|
||||
struct GNUNET_JSON_Specification spec_refresh[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
|
||||
&old_coin_pub),
|
||||
&rrr.details.ok.old_coin_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = MHD_HTTP_OK
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (json,
|
||||
@ -121,8 +120,7 @@ process_recoup_response (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr,
|
||||
&old_coin_pub);
|
||||
&rrr);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
@ -142,9 +140,9 @@ handle_recoup_refresh_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupRefreshHandle *ph = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_RecoupRefreshResponse rrr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
@ -153,7 +151,7 @@ handle_recoup_refresh_finished (void *cls,
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK !=
|
||||
@ -161,8 +159,8 @@ handle_recoup_refresh_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rrr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
TALER_EXCHANGE_recoup_refresh_cancel (ph);
|
||||
@ -170,35 +168,35 @@ handle_recoup_refresh_finished (void *cls,
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
{
|
||||
struct TALER_Amount min_key;
|
||||
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_get_min_denomination_ (keys,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rrr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
@ -211,8 +209,8 @@ handle_recoup_refresh_finished (void *cls,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rrr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -220,29 +218,28 @@ handle_recoup_refresh_finished (void *cls,
|
||||
case MHD_HTTP_GONE:
|
||||
/* Kind of normal: the money was already sent to the merchant
|
||||
(it was too late for the refund). */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange recoup\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) rrr.hr.ec);
|
||||
GNUNET_break (0);
|
||||
break;
|
||||
}
|
||||
ph->cb (ph->cb_cls,
|
||||
&hr,
|
||||
NULL);
|
||||
&rrr);
|
||||
TALER_EXCHANGE_recoup_refresh_cancel (ph);
|
||||
}
|
||||
|
||||
|
@ -266,8 +266,8 @@ handle_refresh_reveal_finished (void *cls,
|
||||
else
|
||||
{
|
||||
GNUNET_assert (rrh->noreveal_index < TALER_CNC_KAPPA);
|
||||
rr.details.success.num_coins = rrh->md.num_fresh_coins;
|
||||
rr.details.success.coins = rcis;
|
||||
rr.details.ok.num_coins = rrh->md.num_fresh_coins;
|
||||
rr.details.ok.coins = rcis;
|
||||
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||
&rr);
|
||||
rrh->reveal_cb = NULL;
|
||||
|
@ -585,37 +585,28 @@ handle_refund_finished (void *cls,
|
||||
const void *response)
|
||||
{
|
||||
struct TALER_EXCHANGE_RefundHandle *rh = cls;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
struct TALER_ExchangePublicKeyP *ep = NULL;
|
||||
struct TALER_ExchangeSignatureP *es = NULL;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_RefundResponse rr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
rh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK !=
|
||||
verify_refund_signature_ok (rh,
|
||||
j,
|
||||
&exchange_pub,
|
||||
&exchange_sig))
|
||||
&rr.details.ok.exchange_pub,
|
||||
&rr.details.ok.exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ep = &exchange_pub;
|
||||
es = &exchange_sig;
|
||||
rr.hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
@ -623,21 +614,21 @@ handle_refund_finished (void *cls,
|
||||
(or API version conflict); also can happen if the currency
|
||||
differs (which we should obviously never support).
|
||||
Just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
/* Requested total refunds exceed deposited amount */
|
||||
@ -649,19 +640,19 @@ handle_refund_finished (void *cls,
|
||||
json_dumpf (j,
|
||||
stderr,
|
||||
JSON_INDENT (2));
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE;
|
||||
hr.hint = "conflict information provided by exchange is invalid";
|
||||
rr.hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE;
|
||||
rr.hr.hint = "conflict information provided by exchange is invalid";
|
||||
break;
|
||||
}
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
/* Kind of normal: the money was already sent to the merchant
|
||||
(it was too late for the refund). */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_PRECONDITION_FAILED:
|
||||
if (GNUNET_OK !=
|
||||
@ -669,37 +660,35 @@ handle_refund_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE;
|
||||
hr.hint = "failed precondition proof returned by exchange is invalid";
|
||||
rr.hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE;
|
||||
rr.hr.hint = "failed precondition proof returned by exchange is invalid";
|
||||
break;
|
||||
}
|
||||
/* Two different refund requests were made about the same deposit, but
|
||||
carrying identical refund transaction ids. */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange refund\n",
|
||||
(unsigned int) response_code,
|
||||
hr.ec);
|
||||
rr.hr.ec);
|
||||
break;
|
||||
}
|
||||
rh->cb (rh->cb_cls,
|
||||
&hr,
|
||||
ep,
|
||||
es);
|
||||
&rr);
|
||||
TALER_EXCHANGE_refund_cancel (rh);
|
||||
}
|
||||
|
||||
|
@ -85,23 +85,32 @@ check_transfers_get_response_ok (
|
||||
const json_t *json)
|
||||
{
|
||||
json_t *details_j;
|
||||
struct TALER_EXCHANGE_TransferData td;
|
||||
struct TALER_Amount total_expected;
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any ("total", &td.total_amount),
|
||||
TALER_JSON_spec_amount_any ("wire_fee", &td.wire_fee),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_payto", &td.h_payto),
|
||||
GNUNET_JSON_spec_timestamp ("execution_time", &td.execution_time),
|
||||
GNUNET_JSON_spec_json ("deposits", &details_j),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
struct TALER_EXCHANGE_TransfersGetResponse tgr = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = MHD_HTTP_OK
|
||||
};
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = MHD_HTTP_OK
|
||||
struct TALER_EXCHANGE_TransferData *td
|
||||
= &tgr.details.ok.td;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any ("total",
|
||||
&td->total_amount),
|
||||
TALER_JSON_spec_amount_any ("wire_fee",
|
||||
&td->wire_fee),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub",
|
||||
&merchant_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_payto",
|
||||
&td->h_payto),
|
||||
GNUNET_JSON_spec_timestamp ("execution_time",
|
||||
&td->execution_time),
|
||||
GNUNET_JSON_spec_json ("deposits",
|
||||
&details_j),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&td->exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&td->exchange_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
@ -113,7 +122,7 @@ check_transfers_get_response_ok (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_amount_set_zero (td.total_amount.currency,
|
||||
TALER_amount_set_zero (td->total_amount.currency,
|
||||
&total_expected))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -123,22 +132,22 @@ check_transfers_get_response_ok (
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (
|
||||
TALER_EXCHANGE_get_keys (wdh->exchange),
|
||||
&td.exchange_pub))
|
||||
&td->exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
td.details_length = json_array_size (details_j);
|
||||
td->details_length = json_array_size (details_j);
|
||||
{
|
||||
struct GNUNET_HashContext *hash_context;
|
||||
struct TALER_TrackTransferDetails *details;
|
||||
|
||||
details = GNUNET_new_array (td.details_length,
|
||||
details = GNUNET_new_array (td->details_length,
|
||||
struct TALER_TrackTransferDetails);
|
||||
td.details = details;
|
||||
td->details = details;
|
||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||
for (unsigned int i = 0; i<td.details_length; i++)
|
||||
for (unsigned int i = 0; i<td->details_length; i++)
|
||||
{
|
||||
struct TALER_TrackTransferDetails *detail = &details[i];
|
||||
struct json_t *detail_j = json_array_get (details_j, i);
|
||||
@ -180,7 +189,7 @@ check_transfers_get_response_ok (
|
||||
TALER_exchange_online_wire_deposit_append (
|
||||
hash_context,
|
||||
&detail->h_contract_terms,
|
||||
td.execution_time,
|
||||
td->execution_time,
|
||||
&detail->coin_pub,
|
||||
&detail->coin_value,
|
||||
&detail->coin_fee);
|
||||
@ -193,13 +202,13 @@ check_transfers_get_response_ok (
|
||||
&h_details);
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_wire_deposit_verify (
|
||||
&td.total_amount,
|
||||
&td.wire_fee,
|
||||
&td->total_amount,
|
||||
&td->wire_fee,
|
||||
&merchant_pub,
|
||||
&td.h_payto,
|
||||
&td->h_payto,
|
||||
&h_details,
|
||||
&td.exchange_pub,
|
||||
&td.exchange_sig))
|
||||
&td->exchange_pub,
|
||||
&td->exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -211,7 +220,7 @@ check_transfers_get_response_ok (
|
||||
if (0 >
|
||||
TALER_amount_subtract (&total_expected,
|
||||
&total_expected,
|
||||
&td.wire_fee))
|
||||
&td->wire_fee))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -220,7 +229,7 @@ check_transfers_get_response_ok (
|
||||
}
|
||||
if (0 !=
|
||||
TALER_amount_cmp (&total_expected,
|
||||
&td.total_amount))
|
||||
&td->total_amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -228,8 +237,7 @@ check_transfers_get_response_ok (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
wdh->cb (wdh->cb_cls,
|
||||
&hr,
|
||||
&td);
|
||||
&tgr);
|
||||
GNUNET_free (details);
|
||||
}
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -253,16 +261,16 @@ handle_transfers_get_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_TransfersGetHandle *wdh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_TransfersGetResponse tgr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
wdh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK ==
|
||||
@ -270,48 +278,47 @@ handle_transfers_get_finished (void *cls,
|
||||
j))
|
||||
return;
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
tgr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
tgr.hr.http_status = 0;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
tgr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
tgr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
tgr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
tgr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Exchange does not know about transaction;
|
||||
we should pass the reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
tgr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
tgr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
tgr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
tgr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
tgr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
tgr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for transfers get\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) tgr.hr.ec);
|
||||
break;
|
||||
}
|
||||
wdh->cb (wdh->cb_cls,
|
||||
&hr,
|
||||
NULL);
|
||||
&tgr);
|
||||
TALER_EXCHANGE_transfers_get_cancel (wdh);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -66,82 +66,65 @@ struct TALER_EXCHANGE_WireHandle
|
||||
|
||||
|
||||
/**
|
||||
* List of wire fees by method.
|
||||
*/
|
||||
struct FeeMap
|
||||
{
|
||||
/**
|
||||
* Next entry in list.
|
||||
*/
|
||||
struct FeeMap *next;
|
||||
|
||||
/**
|
||||
* Wire method this fee structure is for.
|
||||
*/
|
||||
char *method;
|
||||
|
||||
/**
|
||||
* Array of wire fees, also linked list, but allocated
|
||||
* only once.
|
||||
*/
|
||||
struct TALER_EXCHANGE_WireAggregateFees *fee_list;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Frees @a fm.
|
||||
* Frees @a wfm array.
|
||||
*
|
||||
* @param fm memory to release
|
||||
* @param wfm fee array to release
|
||||
* @param wfm_len length of the @a wfm array
|
||||
*/
|
||||
static void
|
||||
free_fees (struct FeeMap *fm)
|
||||
free_fees (struct TALER_EXCHANGE_WireFeesByMethod *wfm,
|
||||
unsigned int wfm_len)
|
||||
{
|
||||
while (NULL != fm)
|
||||
for (unsigned int i = 0; i<wfm_len; i++)
|
||||
{
|
||||
struct FeeMap *fe = fm->next;
|
||||
struct TALER_EXCHANGE_WireFeesByMethod *wfmi = &wfm[i];
|
||||
|
||||
GNUNET_free (fm->fee_list);
|
||||
GNUNET_free (fm->method);
|
||||
GNUNET_free (fm);
|
||||
fm = fe;
|
||||
while (NULL != wfmi->fees_head)
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAggregateFees *fe
|
||||
= wfmi->fees_head;
|
||||
|
||||
wfmi->fees_head = fe->next;
|
||||
GNUNET_free (fe);
|
||||
}
|
||||
}
|
||||
GNUNET_free (wfm);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse wire @a fees and return map.
|
||||
* Parse wire @a fees and return array.
|
||||
*
|
||||
* @param master_pub master public key to use to check signatures
|
||||
* @param fees json AggregateTransferFee to parse
|
||||
* @param[out] fees_len set to length of returned array
|
||||
* @return NULL on error
|
||||
*/
|
||||
static struct FeeMap *
|
||||
static struct TALER_EXCHANGE_WireFeesByMethod *
|
||||
parse_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
json_t *fees)
|
||||
const json_t *fees,
|
||||
unsigned int *fees_len)
|
||||
{
|
||||
struct FeeMap *fm = NULL;
|
||||
struct TALER_EXCHANGE_WireFeesByMethod *fbm;
|
||||
unsigned int fbml = json_object_size (fees);
|
||||
unsigned int i = 0;
|
||||
const char *key;
|
||||
json_t *fee_array;
|
||||
const json_t *fee_array;
|
||||
|
||||
json_object_foreach (fees, key, fee_array) {
|
||||
struct FeeMap *fe = GNUNET_new (struct FeeMap);
|
||||
unsigned int len;
|
||||
fbm = GNUNET_new_array (fbml,
|
||||
struct TALER_EXCHANGE_WireFeesByMethod);
|
||||
*fees_len = fbml;
|
||||
json_object_foreach ((json_t *) fees, key, fee_array) {
|
||||
struct TALER_EXCHANGE_WireFeesByMethod *fe = &fbm[i++];
|
||||
unsigned int idx;
|
||||
json_t *fee;
|
||||
|
||||
if (0 == (len = json_array_size (fee_array)))
|
||||
{
|
||||
GNUNET_free (fe);
|
||||
continue; /* skip */
|
||||
}
|
||||
fe->method = GNUNET_strdup (key);
|
||||
fe->next = fm;
|
||||
fe->fee_list = GNUNET_new_array (len,
|
||||
struct TALER_EXCHANGE_WireAggregateFees);
|
||||
fm = fe;
|
||||
fe->method = key;
|
||||
fe->fees_head = NULL;
|
||||
json_array_foreach (fee_array, idx, fee)
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAggregateFees *wa = &fe->fee_list[idx];
|
||||
struct TALER_EXCHANGE_WireAggregateFees *wa
|
||||
= GNUNET_new (struct TALER_EXCHANGE_WireAggregateFees);
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("sig",
|
||||
&wa->master_sig),
|
||||
@ -156,6 +139,8 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
wa->next = fe->fees_head;
|
||||
fe->fees_head = wa;
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (fee,
|
||||
spec,
|
||||
@ -163,7 +148,8 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
free_fees (fm);
|
||||
free_fees (fbm,
|
||||
i);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
@ -176,35 +162,122 @@ parse_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
&wa->master_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
free_fees (fm);
|
||||
free_fees (fbm,
|
||||
i);
|
||||
return NULL;
|
||||
}
|
||||
if (idx + 1 < len)
|
||||
wa->next = &fe->fee_list[idx + 1];
|
||||
else
|
||||
wa->next = NULL;
|
||||
}
|
||||
}
|
||||
return fm;
|
||||
} /* for all fees over time */
|
||||
} /* for all methods */
|
||||
GNUNET_assert (i == fbml);
|
||||
return fbm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find fee by @a method.
|
||||
* Parse account restriction in @a jrest into @a rest.
|
||||
*
|
||||
* @param fm map to look in
|
||||
* @param method key to look for
|
||||
* @return NULL if fee is not specified in @a fm
|
||||
* @param jrest array of account restrictions in JSON
|
||||
* @param[out] resta_len set to length of @a resta
|
||||
* @param[out] resta account restriction array to set
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static const struct TALER_EXCHANGE_WireAggregateFees *
|
||||
lookup_fee (const struct FeeMap *fm,
|
||||
const char *method)
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_restrictions (const json_t *jresta,
|
||||
unsigned int *resta_len,
|
||||
struct TALER_EXCHANGE_AccountRestriction **resta)
|
||||
{
|
||||
for (; NULL != fm; fm = fm->next)
|
||||
if (0 == strcasecmp (fm->method,
|
||||
method))
|
||||
return fm->fee_list;
|
||||
return NULL;
|
||||
if (! json_is_array (jresta))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
*resta_len = json_array_size (jresta);
|
||||
if (0 == *resta_len)
|
||||
{
|
||||
/* no restrictions, perfectly OK */
|
||||
*resta = NULL;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
*resta = GNUNET_new_array (*resta_len,
|
||||
struct TALER_EXCHANGE_AccountRestriction);
|
||||
for (unsigned int i = 0; i<*resta_len; i++)
|
||||
{
|
||||
const json_t *jr = json_array_get (jresta,
|
||||
i);
|
||||
struct TALER_EXCHANGE_AccountRestriction *ar = &(*resta)[i];
|
||||
const char *type = json_string_value (json_object_get (jr,
|
||||
"type"));
|
||||
|
||||
if (NULL == type)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
goto fail;
|
||||
}
|
||||
if (0 == strcmp (type,
|
||||
"deny"))
|
||||
{
|
||||
ar->type = TALER_EXCHANGE_AR_DENY;
|
||||
continue;
|
||||
}
|
||||
if (0 == strcmp (type,
|
||||
"regex"))
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string (
|
||||
"payto_regex",
|
||||
&ar->details.regex.posix_egrep),
|
||||
GNUNET_JSON_spec_string (
|
||||
"human_hint",
|
||||
&ar->details.regex.human_hint),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_object_const (
|
||||
"human_hint_i18n",
|
||||
&ar->details.regex.human_hint_i18n),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (jr,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
goto fail;
|
||||
}
|
||||
ar->type = TALER_EXCHANGE_AR_REGEX;
|
||||
continue;
|
||||
}
|
||||
/* unsupported type */
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
fail:
|
||||
GNUNET_free (*resta);
|
||||
*resta_len = 0;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free data within @a was, but not @a was itself.
|
||||
*
|
||||
* @param was array of wire account data
|
||||
* @param was_len length of the @a was array
|
||||
*/
|
||||
static void
|
||||
free_accounts (struct TALER_EXCHANGE_WireAccount *was,
|
||||
unsigned int was_len)
|
||||
{
|
||||
for (unsigned int i = 0; i<was_len; i++)
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAccount *wa = &was[i];
|
||||
|
||||
GNUNET_free (wa->credit_restrictions);
|
||||
GNUNET_free (wa->debit_restrictions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -223,9 +296,9 @@ handle_wire_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_WireHandle *wh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_WireResponse wr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
TALER_LOG_DEBUG ("Checking raw /wire response\n");
|
||||
@ -233,28 +306,29 @@ handle_wire_finished (void *cls,
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
wr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
wh->exchange->wire_error_count++;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
json_t *accounts;
|
||||
json_t *fees;
|
||||
unsigned int num_accounts;
|
||||
struct FeeMap *fm;
|
||||
const json_t *accounts;
|
||||
const json_t *fees;
|
||||
const json_t *wads;
|
||||
struct TALER_EXCHANGE_WireFeesByMethod *fbm;
|
||||
struct TALER_MasterPublicKeyP master_pub;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("master_public_key",
|
||||
&master_pub),
|
||||
GNUNET_JSON_spec_json ("accounts",
|
||||
&accounts),
|
||||
GNUNET_JSON_spec_json ("fees",
|
||||
&fees),
|
||||
GNUNET_JSON_spec_array_const ("accounts",
|
||||
&accounts),
|
||||
GNUNET_JSON_spec_object_const ("fees",
|
||||
&fees),
|
||||
GNUNET_JSON_spec_array_const ("wads",
|
||||
&wads),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
wh->exchange->wire_error_count = 0;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
@ -262,8 +336,8 @@ handle_wire_finished (void *cls,
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
{
|
||||
@ -275,61 +349,70 @@ handle_wire_finished (void *cls,
|
||||
{
|
||||
/* bogus reply: master public key in /wire differs from that in /keys */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == (num_accounts = json_array_size (accounts)))
|
||||
wr.details.ok.accounts_len
|
||||
= json_array_size (accounts);
|
||||
if (0 == wr.details.ok.accounts_len)
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
if (NULL == (fm = parse_fees (&master_pub,
|
||||
fees)))
|
||||
fbm = parse_fees (&master_pub,
|
||||
fees,
|
||||
&wr.details.ok.fees_len);
|
||||
if (NULL == fbm)
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* parse accounts */
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAccount was[num_accounts];
|
||||
struct TALER_EXCHANGE_WireAccount was[wr.details.ok.accounts_len];
|
||||
|
||||
for (unsigned int i = 0; i<num_accounts; i++)
|
||||
memset (was,
|
||||
0,
|
||||
sizeof (was));
|
||||
wr.details.ok.accounts = was;
|
||||
for (unsigned int i = 0;
|
||||
i<wr.details.ok.accounts_len;
|
||||
i++)
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAccount *wa = &was[i];
|
||||
json_t *account;
|
||||
json_t *credit_restrictions;
|
||||
json_t *debit_restrictions;
|
||||
struct GNUNET_JSON_Specification spec_account[] = {
|
||||
GNUNET_JSON_spec_string ("payto_uri",
|
||||
&wa->payto_uri),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("conversion_url",
|
||||
&wa->conversion_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_json ("credit_restrictions",
|
||||
&credit_restrictions),
|
||||
GNUNET_JSON_spec_json ("debit_restrictions",
|
||||
&debit_restrictions),
|
||||
GNUNET_JSON_spec_fixed_auto ("master_sig",
|
||||
&wa->master_sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
char *method;
|
||||
json_t *account;
|
||||
|
||||
account = json_array_get (accounts,
|
||||
i);
|
||||
if (GNUNET_OK !=
|
||||
TALER_JSON_exchange_wire_signature_check (account,
|
||||
&master_pub))
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_EXCHANGE_WIRE_SIGNATURE_INVALID;
|
||||
break;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (account,
|
||||
spec_account,
|
||||
@ -337,80 +420,104 @@ handle_wire_finished (void *cls,
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
if (NULL == (method = TALER_payto_get_method (wa->payto_uri)))
|
||||
{
|
||||
char *err;
|
||||
|
||||
err = TALER_payto_validate (wa->payto_uri);
|
||||
if (NULL != err)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
GNUNET_free (err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_wire_signature_check (wa->payto_uri,
|
||||
wa->conversion_url,
|
||||
debit_restrictions,
|
||||
credit_restrictions,
|
||||
&master_pub,
|
||||
&wa->master_sig))
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_EXCHANGE_WIRE_SIGNATURE_INVALID;
|
||||
break;
|
||||
}
|
||||
if (NULL == (wa->fees = lookup_fee (fm,
|
||||
method)))
|
||||
if ( (GNUNET_OK !=
|
||||
parse_restrictions (credit_restrictions,
|
||||
&wa->credit_restrictions_length,
|
||||
&wa->credit_restrictions)) ||
|
||||
(GNUNET_OK !=
|
||||
parse_restrictions (debit_restrictions,
|
||||
&wa->debit_restrictions_length,
|
||||
&wa->debit_restrictions)) )
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
GNUNET_free (method);
|
||||
wr.hr.http_status = 0;
|
||||
wr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
GNUNET_free (method);
|
||||
GNUNET_JSON_parse_free (spec_account);
|
||||
} /* end 'for all accounts */
|
||||
if ( (0 != response_code) &&
|
||||
if ( (0 != wr.hr.http_status) &&
|
||||
(NULL != wh->cb) )
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
num_accounts,
|
||||
was);
|
||||
&wr);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
free_accounts (was,
|
||||
wr.details.ok.accounts_len);
|
||||
} /* end of 'parse accounts */
|
||||
free_fees (fm);
|
||||
free_fees (fbm,
|
||||
wr.details.ok.fees_len);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
} /* end of MHD_HTTP_OK */
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
wr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
wr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
wr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
if (MHD_HTTP_GATEWAY_TIMEOUT == response_code)
|
||||
wh->exchange->wire_error_count++;
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
wr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
wr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange wire\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) wr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
0,
|
||||
NULL);
|
||||
&wr);
|
||||
TALER_EXCHANGE_wire_cancel (wh);
|
||||
}
|
||||
|
||||
|
@ -116,22 +116,20 @@ struct TALER_EXCHANGE_WithdrawHandle
|
||||
* HTTP /reserves/$RESERVE_PUB/withdraw request.
|
||||
*
|
||||
* @param cls the `struct TALER_EXCHANGE_WithdrawHandle`
|
||||
* @param hr HTTP response data
|
||||
* @param blind_sig blind signature over the coin, NULL on error
|
||||
* @param w2r response data
|
||||
*/
|
||||
static void
|
||||
handle_reserve_withdraw_finished (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_BlindedDenominationSignature *blind_sig)
|
||||
const struct TALER_EXCHANGE_Withdraw2Response *w2r)
|
||||
{
|
||||
struct TALER_EXCHANGE_WithdrawHandle *wh = cls;
|
||||
struct TALER_EXCHANGE_WithdrawResponse wr = {
|
||||
.hr = *hr
|
||||
.hr = w2r->hr
|
||||
};
|
||||
|
||||
wh->wh2 = NULL;
|
||||
switch (hr->http_status)
|
||||
switch (w2r->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
@ -139,7 +137,7 @@ handle_reserve_withdraw_finished (
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_planchet_to_coin (&wh->pk.key,
|
||||
blind_sig,
|
||||
&w2r->details.ok.blind_sig,
|
||||
&wh->bks,
|
||||
&wh->priv,
|
||||
wh->ach,
|
||||
@ -151,10 +149,10 @@ handle_reserve_withdraw_finished (
|
||||
wr.hr.ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE;
|
||||
break;
|
||||
}
|
||||
wr.details.success.coin_priv = wh->priv;
|
||||
wr.details.success.bks = wh->bks;
|
||||
wr.details.success.sig = fc.sig;
|
||||
wr.details.success.exchange_vals = wh->alg_values;
|
||||
wr.details.ok.coin_priv = wh->priv;
|
||||
wr.details.ok.bks = wh->bks;
|
||||
wr.details.ok.sig = fc.sig;
|
||||
wr.details.ok.exchange_vals = wh->alg_values;
|
||||
break;
|
||||
}
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
@ -170,7 +168,7 @@ handle_reserve_withdraw_finished (
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (hr->reply,
|
||||
GNUNET_JSON_parse (w2r->hr.reply,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
@ -186,8 +184,8 @@ handle_reserve_withdraw_finished (
|
||||
}
|
||||
wh->cb (wh->cb_cls,
|
||||
&wr);
|
||||
if (MHD_HTTP_OK == hr->http_status)
|
||||
TALER_denom_sig_free (&wr.details.success.sig);
|
||||
if (MHD_HTTP_OK == w2r->hr.http_status)
|
||||
TALER_denom_sig_free (&wr.details.ok.sig);
|
||||
TALER_EXCHANGE_withdraw_cancel (wh);
|
||||
}
|
||||
|
||||
@ -213,7 +211,7 @@ withdraw_cs_stage_two_callback (
|
||||
switch (csrr->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
wh->alg_values = csrr->details.success.alg_values;
|
||||
wh->alg_values = csrr->details.ok.alg_values;
|
||||
TALER_planchet_setup_coin_priv (&wh->ps,
|
||||
&wh->alg_values,
|
||||
&wh->priv);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -99,16 +99,15 @@ static enum GNUNET_GenericReturnValue
|
||||
reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,
|
||||
const json_t *json)
|
||||
{
|
||||
struct TALER_BlindedDenominationSignature blind_sig;
|
||||
struct TALER_EXCHANGE_Withdraw2Response w2r = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = MHD_HTTP_OK
|
||||
};
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_blinded_denom_sig ("ev_sig",
|
||||
&blind_sig),
|
||||
&w2r.details.ok.blind_sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = MHD_HTTP_OK
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (json,
|
||||
@ -121,8 +120,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,
|
||||
|
||||
/* signature is valid, return it to the application */
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
&blind_sig);
|
||||
&w2r);
|
||||
/* make sure callback isn't called again after return */
|
||||
wh->cb = NULL;
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -240,16 +238,16 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_Withdraw2Handle *wh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_Withdraw2Response w2r = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
wh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
w2r.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (GNUNET_OK !=
|
||||
@ -257,8 +255,8 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
w2r.hr.http_status = 0;
|
||||
w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
GNUNET_assert (NULL == wh->cb);
|
||||
@ -267,24 +265,24 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
GNUNET_break_op (0);
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, the exchange basically just says
|
||||
that it doesn't know this reserve. Can happen if we
|
||||
query before the wire transfer went through.
|
||||
We should simply pass the JSON reply to the application. */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
/* The exchange says that the reserve has insufficient funds;
|
||||
@ -294,13 +292,13 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
w2r.hr.http_status = 0;
|
||||
w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
@ -308,8 +306,8 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
/* Note: one might want to check /keys for revocation
|
||||
signature here, alas tricky in case our /keys
|
||||
is outdated => left to clients */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
/* only validate reply is well-formed */
|
||||
@ -327,8 +325,8 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
w2r.hr.http_status = 0;
|
||||
w2r.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -336,25 +334,24 @@ handle_reserve_withdraw_finished (void *cls,
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
w2r.hr.ec = TALER_JSON_get_error_code (j);
|
||||
w2r.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange withdraw\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) w2r.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != wh->cb)
|
||||
{
|
||||
wh->cb (wh->cb_cls,
|
||||
&hr,
|
||||
NULL);
|
||||
&w2r);
|
||||
wh->cb = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_withdraw2_cancel (wh);
|
||||
|
@ -386,10 +386,10 @@ history_cb (void *cls,
|
||||
GNUNET_break (0);
|
||||
goto error;
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<chr->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<chr->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_CreditDetails *cd =
|
||||
&chr->details.success.details[i];
|
||||
&chr->details.ok.details[i];
|
||||
|
||||
/* check current element */
|
||||
if (GNUNET_OK !=
|
||||
|
@ -378,10 +378,10 @@ history_cb (void *cls,
|
||||
GNUNET_break (0);
|
||||
goto error;
|
||||
case MHD_HTTP_OK:
|
||||
for (unsigned int i = 0; i<dhr->details.success.details_length; i++)
|
||||
for (unsigned int i = 0; i<dhr->details.ok.details_length; i++)
|
||||
{
|
||||
const struct TALER_BANK_DebitDetails *dd =
|
||||
&dhr->details.success.details[i];
|
||||
&dhr->details.ok.details[i];
|
||||
|
||||
/* check current element */
|
||||
if (GNUNET_OK !=
|
||||
|
@ -212,17 +212,17 @@ batch_deposit_cb (void *cls,
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
{
|
||||
if (ds->num_coins != dr->details.success.num_signatures)
|
||||
if (ds->num_coins != dr->details.ok.num_signatures)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (ds->is);
|
||||
return;
|
||||
}
|
||||
ds->deposit_succeeded = GNUNET_YES;
|
||||
ds->exchange_timestamp = dr->details.success.deposit_timestamp;
|
||||
ds->exchange_pub = *dr->details.success.exchange_pub;
|
||||
ds->exchange_sigs = GNUNET_memdup (dr->details.success.exchange_sigs,
|
||||
dr->details.success.num_signatures
|
||||
ds->exchange_timestamp = dr->details.ok.deposit_timestamp;
|
||||
ds->exchange_pub = *dr->details.ok.exchange_pub;
|
||||
ds->exchange_sigs = GNUNET_memdup (dr->details.ok.exchange_sigs,
|
||||
dr->details.ok.num_signatures
|
||||
* sizeof (struct
|
||||
TALER_ExchangeSignatureP));
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ reserve_batch_withdraw_cb (void *cls,
|
||||
{
|
||||
struct CoinState *cs = &ws->coins[i];
|
||||
const struct TALER_EXCHANGE_PrivateCoinDetails *pcd
|
||||
= &wr->details.success.coins[i];
|
||||
= &wr->details.ok.coins[i];
|
||||
|
||||
TALER_denom_sig_deep_copy (&cs->sig,
|
||||
&pcd->sig);
|
||||
|
@ -116,10 +116,10 @@ check_aml_decision_cb (void *cls,
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_TESTING_get_trait_amount (ref,
|
||||
&amount));
|
||||
for (unsigned int i = 0; i<adr->details.success.aml_history_length; i++)
|
||||
for (unsigned int i = 0; i<adr->details.ok.aml_history_length; i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_AmlDecisionDetail *aml_history
|
||||
= &adr->details.success.aml_history[i];
|
||||
= &adr->details.ok.aml_history[i];
|
||||
|
||||
if ( (NULL == oldest) ||
|
||||
(0 !=
|
||||
|
@ -121,7 +121,7 @@ get_cb (void *cls,
|
||||
const struct TALER_PurseMergePrivateKeyP *mp;
|
||||
const json_t *ct;
|
||||
|
||||
ds->purse_pub = dr->details.success.purse_pub;
|
||||
ds->purse_pub = dr->details.ok.purse_pub;
|
||||
if (ds->merge)
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
@ -136,8 +136,8 @@ get_cb (void *cls,
|
||||
TALER_CRYPTO_contract_decrypt_for_merge (
|
||||
&ds->contract_priv,
|
||||
&ds->purse_pub,
|
||||
dr->details.success.econtract,
|
||||
dr->details.success.econtract_size,
|
||||
dr->details.ok.econtract,
|
||||
dr->details.ok.econtract_size,
|
||||
&ds->merge_priv);
|
||||
if (0 !=
|
||||
GNUNET_memcmp (mp,
|
||||
@ -153,8 +153,8 @@ get_cb (void *cls,
|
||||
ds->contract_terms =
|
||||
TALER_CRYPTO_contract_decrypt_for_deposit (
|
||||
&ds->contract_priv,
|
||||
dr->details.success.econtract,
|
||||
dr->details.success.econtract_size);
|
||||
dr->details.ok.econtract,
|
||||
dr->details.ok.econtract_size);
|
||||
}
|
||||
if (NULL == ds->contract_terms)
|
||||
{
|
||||
|
@ -264,9 +264,9 @@ deposit_cb (void *cls,
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
{
|
||||
ds->deposit_succeeded = GNUNET_YES;
|
||||
ds->exchange_timestamp = dr->details.success.deposit_timestamp;
|
||||
ds->exchange_pub = *dr->details.success.exchange_pub;
|
||||
ds->exchange_sig = *dr->details.success.exchange_sig;
|
||||
ds->exchange_timestamp = dr->details.ok.deposit_timestamp;
|
||||
ds->exchange_pub = *dr->details.ok.exchange_pub;
|
||||
ds->exchange_sig = *dr->details.ok.exchange_sig;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ deposit_wtid_cb (void *cls,
|
||||
switch (dr->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
tts->wtid = dr->details.success.wtid;
|
||||
tts->wtid = dr->details.ok.wtid;
|
||||
if (NULL != tts->bank_transfer_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *bank_transfer_cmd;
|
||||
@ -155,7 +155,7 @@ deposit_wtid_cb (void *cls,
|
||||
}
|
||||
|
||||
/* Compare that expected and gotten subjects match. */
|
||||
if (0 != GNUNET_memcmp (&dr->details.success.wtid,
|
||||
if (0 != GNUNET_memcmp (&dr->details.ok.wtid,
|
||||
wtid_want))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
|
@ -80,6 +80,7 @@ nft_run (void *cls,
|
||||
"wget",
|
||||
"--header=Content-Type:application/json",
|
||||
"--auth-no-challenge",
|
||||
"--output-file=/dev/null",
|
||||
"--post-data={\"level\":\"all\",\"rangeType\":\"latest\"}",
|
||||
user,
|
||||
pass,
|
||||
|
@ -176,8 +176,8 @@ deposit_cb (void *cls,
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
{
|
||||
ds->exchange_pub = dr->details.success.exchange_pub;
|
||||
ds->exchange_sig = dr->details.success.exchange_sig;
|
||||
ds->exchange_pub = dr->details.ok.exchange_pub;
|
||||
ds->exchange_sig = dr->details.ok.exchange_sig;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
}
|
||||
|
@ -152,8 +152,8 @@ deposit_cb (void *cls,
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
{
|
||||
if (-1 !=
|
||||
TALER_amount_cmp (&dr->details.success.total_deposited,
|
||||
&dr->details.success.purse_value_after_fees))
|
||||
TALER_amount_cmp (&dr->details.ok.total_deposited,
|
||||
&dr->details.ok.purse_value_after_fees))
|
||||
{
|
||||
const struct TALER_TESTING_Command *purse_cmd;
|
||||
const struct TALER_ReserveSignatureP *reserve_sig;
|
||||
@ -213,7 +213,7 @@ deposit_cb (void *cls,
|
||||
|
||||
/* Note: change when flags below changes! */
|
||||
ds->reserve_history.amount
|
||||
= dr->details.success.purse_value_after_fees;
|
||||
= dr->details.ok.purse_value_after_fees;
|
||||
if (true)
|
||||
{
|
||||
ds->reserve_history.details.merge_details.purse_fee = gf->fees.purse;
|
||||
@ -226,7 +226,7 @@ deposit_cb (void *cls,
|
||||
}
|
||||
}
|
||||
ds->reserve_history.details.merge_details.h_contract_terms
|
||||
= dr->details.success.h_contract_terms;
|
||||
= dr->details.ok.h_contract_terms;
|
||||
ds->reserve_history.details.merge_details.merge_pub
|
||||
= *merge_pub;
|
||||
ds->reserve_history.details.merge_details.purse_pub
|
||||
@ -236,7 +236,7 @@ deposit_cb (void *cls,
|
||||
ds->reserve_history.details.merge_details.merge_timestamp
|
||||
= *merge_timestamp;
|
||||
ds->reserve_history.details.merge_details.purse_expiration
|
||||
= dr->details.success.purse_expiration;
|
||||
= dr->details.ok.purse_expiration;
|
||||
ds->reserve_history.details.merge_details.min_age
|
||||
= ds->min_age;
|
||||
ds->reserve_history.details.merge_details.flags
|
||||
|
@ -147,11 +147,11 @@ purse_status_cb (void *cls,
|
||||
TALER_string_to_amount (ss->expected_balance,
|
||||
&eb));
|
||||
if (0 != TALER_amount_cmp (&eb,
|
||||
&rs->details.success.balance))
|
||||
&rs->details.ok.balance))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected amount in purse: %s\n",
|
||||
TALER_amount_to_string (&rs->details.success.balance));
|
||||
TALER_amount_to_string (&rs->details.ok.balance));
|
||||
TALER_TESTING_interpreter_fail (ss->is);
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2018 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as
|
||||
@ -73,15 +73,14 @@ struct RecoupState
|
||||
* was paid back belonged to the right reserve.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response details
|
||||
* @param reserve_pub public key of the reserve receiving the recoup
|
||||
* @param rr response details
|
||||
*/
|
||||
static void
|
||||
recoup_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub)
|
||||
const struct TALER_EXCHANGE_RecoupResponse *rr)
|
||||
{
|
||||
struct RecoupState *ps = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
|
||||
struct TALER_TESTING_Interpreter *is = ps->is;
|
||||
struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
|
||||
const struct TALER_TESTING_Command *reserve_cmd;
|
||||
@ -135,12 +134,6 @@ recoup_cb (void *cls,
|
||||
{
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv;
|
||||
|
||||
if (NULL == reserve_pub)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_reserve_priv (reserve_cmd,
|
||||
&reserve_priv))
|
||||
@ -151,7 +144,7 @@ recoup_cb (void *cls,
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||
&ps->reserve_pub.eddsa_pub);
|
||||
if (0 != GNUNET_memcmp (reserve_pub,
|
||||
if (0 != GNUNET_memcmp (&rr->details.ok.reserve_pub,
|
||||
&ps->reserve_pub))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
|
@ -73,15 +73,14 @@ struct RecoupRefreshState
|
||||
* was paid back belonged to the right old coin.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response details
|
||||
* @param old_coin_pub public key of the dirty coin
|
||||
* @param rrr response details
|
||||
*/
|
||||
static void
|
||||
recoup_refresh_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_CoinSpendPublicKeyP *old_coin_pub)
|
||||
const struct TALER_EXCHANGE_RecoupRefreshResponse *rrr)
|
||||
{
|
||||
struct RecoupRefreshState *rrs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rrr->hr;
|
||||
struct TALER_TESTING_Interpreter *is = rrs->is;
|
||||
struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
|
||||
char *cref;
|
||||
@ -150,7 +149,7 @@ recoup_refresh_cb (void *cls,
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&dirty_priv->eddsa_priv,
|
||||
&oc.eddsa_pub);
|
||||
if (0 != GNUNET_memcmp (&oc,
|
||||
old_coin_pub))
|
||||
&rrr->details.ok.old_coin_pub))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
|
@ -411,7 +411,7 @@ reveal_cb (void *cls,
|
||||
switch (hr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
rrs->num_fresh_coins = rr->details.success.num_coins;
|
||||
rrs->num_fresh_coins = rr->details.ok.num_coins;
|
||||
rrs->psa = GNUNET_new_array (rrs->num_fresh_coins,
|
||||
struct TALER_PlanchetMasterSecretP);
|
||||
rrs->fresh_coins = GNUNET_new_array (rrs->num_fresh_coins,
|
||||
@ -419,7 +419,7 @@ reveal_cb (void *cls,
|
||||
for (unsigned int i = 0; i<rrs->num_fresh_coins; i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_RevealedCoinInfo *coin
|
||||
= &rr->details.success.coins[i];
|
||||
= &rr->details.ok.coins[i];
|
||||
struct TALER_TESTING_FreshCoinData *fc = &rrs->fresh_coins[i];
|
||||
|
||||
rrs->psa[i] = coin->ps;
|
||||
@ -675,11 +675,11 @@ link_cb (void *cls,
|
||||
TALER_TESTING_interpreter_fail (rls->is);
|
||||
return;
|
||||
}
|
||||
if (lr->details.success.num_coins != *num_fresh_coins)
|
||||
if (lr->details.ok.num_coins != *num_fresh_coins)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected number of fresh coins: %d vs %d in %s:%u\n",
|
||||
lr->details.success.num_coins,
|
||||
lr->details.ok.num_coins,
|
||||
*num_fresh_coins,
|
||||
__FILE__,
|
||||
__LINE__);
|
||||
@ -687,11 +687,11 @@ link_cb (void *cls,
|
||||
return;
|
||||
}
|
||||
/* check that the coins match */
|
||||
for (unsigned int i = 0; i<lr->details.success.num_coins; i++)
|
||||
for (unsigned int j = i + 1; j<lr->details.success.num_coins; j++)
|
||||
for (unsigned int i = 0; i<lr->details.ok.num_coins; i++)
|
||||
for (unsigned int j = i + 1; j<lr->details.ok.num_coins; j++)
|
||||
if (0 ==
|
||||
GNUNET_memcmp (&lr->details.success.coins[i].coin_priv,
|
||||
&lr->details.success.coins[j].coin_priv))
|
||||
GNUNET_memcmp (&lr->details.ok.coins[i].coin_priv,
|
||||
&lr->details.ok.coins[j].coin_priv))
|
||||
GNUNET_break (0);
|
||||
/* Note: coins might be legitimately permutated in here... */
|
||||
found = 0;
|
||||
@ -709,12 +709,12 @@ link_cb (void *cls,
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i<lr->details.success.num_coins; i++)
|
||||
for (unsigned int i = 0; i<lr->details.ok.num_coins; i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_LinkedCoinInfo *lci_i
|
||||
= &lr->details.success.coins[i];
|
||||
= &lr->details.ok.coins[i];
|
||||
|
||||
for (unsigned int j = 0; j<lr->details.success.num_coins; j++)
|
||||
for (unsigned int j = 0; j<lr->details.ok.num_coins; j++)
|
||||
{
|
||||
const struct TALER_TESTING_FreshCoinData *fcj
|
||||
= &(*fc)[j];
|
||||
@ -735,12 +735,12 @@ link_cb (void *cls,
|
||||
} /* for j*/
|
||||
} /* for i */
|
||||
}
|
||||
if (found != lr->details.success.num_coins)
|
||||
if (found != lr->details.ok.num_coins)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Only %u/%u coins match expectations\n",
|
||||
found,
|
||||
lr->details.success.num_coins);
|
||||
lr->details.ok.num_coins);
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (rls->is);
|
||||
return;
|
||||
@ -952,16 +952,16 @@ melt_cb (void *cls,
|
||||
}
|
||||
if (MHD_HTTP_OK == hr->http_status)
|
||||
{
|
||||
rms->noreveal_index = mr->details.success.noreveal_index;
|
||||
if (mr->details.success.num_mbds != rms->num_fresh_coins)
|
||||
rms->noreveal_index = mr->details.ok.noreveal_index;
|
||||
if (mr->details.ok.num_mbds != rms->num_fresh_coins)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (rms->is);
|
||||
return;
|
||||
}
|
||||
GNUNET_free (rms->mbds);
|
||||
rms->mbds = GNUNET_memdup (mr->details.success.mbds,
|
||||
mr->details.success.num_mbds
|
||||
rms->mbds = GNUNET_memdup (mr->details.ok.mbds,
|
||||
mr->details.ok.num_mbds
|
||||
* sizeof (struct
|
||||
TALER_EXCHANGE_MeltBlindingDetail));
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2020 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as
|
||||
@ -75,19 +75,14 @@ struct RefundState
|
||||
* response code is acceptable.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response details
|
||||
* @param exchange_pub public key the exchange
|
||||
* used for signing @a obj.
|
||||
* @param exchange_sig actual signature confirming the refund
|
||||
* @param rr response details
|
||||
*/
|
||||
static void
|
||||
refund_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||
const struct TALER_ExchangeSignatureP *exchange_sig)
|
||||
const struct TALER_EXCHANGE_RefundResponse *rr)
|
||||
{
|
||||
|
||||
struct RefundState *rs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
|
||||
struct TALER_TESTING_Command *refund_cmd;
|
||||
|
||||
refund_cmd = &rs->is->commands[rs->is->ip];
|
||||
|
@ -65,14 +65,15 @@ struct RevokeState
|
||||
* Function called with information about the post revocation operation result.
|
||||
*
|
||||
* @param cls closure with a `struct RevokeState *`
|
||||
* @param hr HTTP response data
|
||||
* @param rdr response data
|
||||
*/
|
||||
static void
|
||||
success_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *rdr)
|
||||
{
|
||||
struct RevokeState *rs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rdr->hr;
|
||||
|
||||
rs->kh = NULL;
|
||||
if (rs->expected_response_code != hr->http_status)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2020 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as
|
||||
@ -65,14 +65,15 @@ struct RevokeState
|
||||
* Function called with information about the post revocation operation result.
|
||||
*
|
||||
* @param cls closure with a `struct RevokeState *`
|
||||
* @param hr HTTP response data
|
||||
* @param rsr response data
|
||||
*/
|
||||
static void
|
||||
success_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *rsr)
|
||||
{
|
||||
struct RevokeState *rs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rsr->hr;
|
||||
|
||||
rs->kh = NULL;
|
||||
if (rs->expected_response_code != hr->http_status)
|
||||
|
@ -84,13 +84,15 @@ struct SetOfficerState
|
||||
* if the response code is acceptable.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param ar response details
|
||||
*/
|
||||
static void
|
||||
set_officer_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct
|
||||
TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *ar)
|
||||
{
|
||||
struct SetOfficerState *ds = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &ar->hr;
|
||||
|
||||
ds->dh = NULL;
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
|
@ -115,15 +115,14 @@ track_transfer_cleanup (void *cls,
|
||||
* wire fees and hashed wire details as well.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param ta transfer data returned by the exchange
|
||||
* @param tgr response details
|
||||
*/
|
||||
static void
|
||||
track_transfer_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_EXCHANGE_TransferData *ta)
|
||||
const struct TALER_EXCHANGE_TransfersGetResponse *tgr)
|
||||
{
|
||||
struct TrackTransferState *tts = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &tgr->hr;
|
||||
struct TALER_TESTING_Interpreter *is = tts->is;
|
||||
struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
|
||||
struct TALER_Amount expected_amount;
|
||||
@ -148,138 +147,62 @@ track_transfer_cb (void *cls,
|
||||
switch (hr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
if (NULL == tts->expected_total_amount)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (NULL == tts->expected_wire_fee)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
const struct TALER_EXCHANGE_TransferData *ta
|
||||
= &tgr->details.ok.td;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (tts->expected_total_amount,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (0 != TALER_amount_cmp (&ta->total_amount,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Total amount mismatch to command %s - "
|
||||
"%s vs %s\n",
|
||||
cmd->label,
|
||||
TALER_amount_to_string (&ta->total_amount),
|
||||
TALER_amount_to_string (&expected_amount));
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
fprintf (stderr, "\n");
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (tts->expected_wire_fee,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != TALER_amount_cmp (&ta->wire_fee,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire fee mismatch to command %s\n",
|
||||
cmd->label);
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally checking: (1) wire-details for this transfer
|
||||
* match the ones from a referenced "deposit" operation -
|
||||
* or any operation that could provide wire-details. (2)
|
||||
* Total amount for this transfer matches the one from any
|
||||
* referenced command that could provide one.
|
||||
*/
|
||||
if (NULL != tts->wire_details_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *wire_details_cmd;
|
||||
const char **payto_uri;
|
||||
struct TALER_PaytoHashP h_payto;
|
||||
|
||||
wire_details_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
tts->wire_details_reference);
|
||||
if (NULL == wire_details_cmd)
|
||||
if (NULL == tts->expected_total_amount)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (NULL == tts->expected_wire_fee)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_payto_uri (wire_details_cmd,
|
||||
&payto_uri))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
TALER_payto_hash (*payto_uri,
|
||||
&h_payto);
|
||||
if (0 != GNUNET_memcmp (&h_payto,
|
||||
&ta->h_payto))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire hash missmath to command %s\n",
|
||||
cmd->label);
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NULL != tts->total_amount_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *total_amount_cmd;
|
||||
const struct TALER_Amount *total_amount_from_reference;
|
||||
|
||||
total_amount_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
tts->total_amount_reference);
|
||||
if (NULL == total_amount_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_amount (total_amount_cmd,
|
||||
&total_amount_from_reference))
|
||||
TALER_string_to_amount (tts->expected_total_amount,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (0 != TALER_amount_cmp (&ta->total_amount,
|
||||
total_amount_from_reference))
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Amount missmath to command %s\n",
|
||||
"Total amount mismatch to command %s - "
|
||||
"%s vs %s\n",
|
||||
cmd->label,
|
||||
TALER_amount_to_string (&ta->total_amount),
|
||||
TALER_amount_to_string (&expected_amount));
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
fprintf (stderr, "\n");
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (tts->expected_wire_fee,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != TALER_amount_cmp (&ta->wire_fee,
|
||||
&expected_amount))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire fee mismatch to command %s\n",
|
||||
cmd->label);
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
@ -287,8 +210,92 @@ track_transfer_cb (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally checking: (1) wire-details for this transfer
|
||||
* match the ones from a referenced "deposit" operation -
|
||||
* or any operation that could provide wire-details. (2)
|
||||
* Total amount for this transfer matches the one from any
|
||||
* referenced command that could provide one.
|
||||
*/
|
||||
if (NULL != tts->wire_details_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *wire_details_cmd;
|
||||
const char **payto_uri;
|
||||
struct TALER_PaytoHashP h_payto;
|
||||
|
||||
wire_details_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
tts->
|
||||
wire_details_reference);
|
||||
if (NULL == wire_details_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_payto_uri (wire_details_cmd,
|
||||
&payto_uri))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
TALER_payto_hash (*payto_uri,
|
||||
&h_payto);
|
||||
if (0 != GNUNET_memcmp (&h_payto,
|
||||
&ta->h_payto))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire hash missmath to command %s\n",
|
||||
cmd->label);
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NULL != tts->total_amount_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *total_amount_cmd;
|
||||
const struct TALER_Amount *total_amount_from_reference;
|
||||
|
||||
total_amount_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
tts->
|
||||
total_amount_reference);
|
||||
if (NULL == total_amount_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_amount (total_amount_cmd,
|
||||
&total_amount_from_reference))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (0 != TALER_amount_cmp (&ta->total_amount,
|
||||
total_amount_from_reference))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Amount missmath to command %s\n",
|
||||
cmd->label);
|
||||
json_dumpf (hr->reply,
|
||||
stderr,
|
||||
0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* case OK */
|
||||
} /* switch on status */
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
}
|
||||
|
||||
|
@ -72,18 +72,14 @@ struct WireState
|
||||
* that the wire fee is acceptable too.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param accounts_len length of the @a accounts array.
|
||||
* @param accounts list of wire accounts of the exchange,
|
||||
* NULL on error.
|
||||
* @param wr response details
|
||||
*/
|
||||
static void
|
||||
wire_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
unsigned int accounts_len,
|
||||
const struct TALER_EXCHANGE_WireAccount *accounts)
|
||||
const struct TALER_EXCHANGE_WireResponse *wr)
|
||||
{
|
||||
struct WireState *ws = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &wr->hr;
|
||||
struct TALER_TESTING_Command *cmd = &ws->is->commands[ws->is->ip];
|
||||
struct TALER_Amount expected_fee;
|
||||
|
||||
@ -100,6 +96,15 @@ wire_cb (void *cls,
|
||||
|
||||
if (MHD_HTTP_OK == hr->http_status)
|
||||
{
|
||||
unsigned int accounts_len
|
||||
= wr->details.ok.accounts_len;
|
||||
unsigned int fees_len
|
||||
= wr->details.ok.fees_len;
|
||||
const struct TALER_EXCHANGE_WireAccount *accounts
|
||||
= wr->details.ok.accounts;
|
||||
const struct TALER_EXCHANGE_WireFeesByMethod *fees
|
||||
= wr->details.ok.fees;
|
||||
|
||||
for (unsigned int i = 0; i<accounts_len; i++)
|
||||
{
|
||||
char *method;
|
||||
@ -115,32 +120,46 @@ wire_cb (void *cls,
|
||||
method))
|
||||
{
|
||||
ws->method_found = GNUNET_OK;
|
||||
if (NULL != ws->expected_fee)
|
||||
}
|
||||
GNUNET_free (method);
|
||||
}
|
||||
if (NULL != ws->expected_fee)
|
||||
{
|
||||
bool fee_found = false;
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (ws->expected_fee,
|
||||
&expected_fee));
|
||||
for (unsigned int i = 0; i<fees_len; i++)
|
||||
{
|
||||
if (0 != strcmp (fees[i].method,
|
||||
ws->expected_method))
|
||||
continue;
|
||||
for (const struct TALER_EXCHANGE_WireAggregateFees *waf
|
||||
= fees[i].fees_head;
|
||||
NULL != waf;
|
||||
waf = waf->next)
|
||||
{
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_string_to_amount (ws->expected_fee,
|
||||
&expected_fee));
|
||||
for (const struct TALER_EXCHANGE_WireAggregateFees *waf
|
||||
= accounts[i].fees;
|
||||
NULL != waf;
|
||||
waf = waf->next)
|
||||
if (0 != TALER_amount_cmp (&waf->fees.wire,
|
||||
&expected_fee))
|
||||
{
|
||||
if (0 != TALER_amount_cmp (&waf->fees.wire,
|
||||
&expected_fee))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire fee mismatch to command %s\n",
|
||||
cmd->label);
|
||||
TALER_TESTING_interpreter_fail (ws->is);
|
||||
GNUNET_free (method);
|
||||
return;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire fee mismatch to command %s\n",
|
||||
cmd->label);
|
||||
TALER_TESTING_interpreter_fail (ws->is);
|
||||
return;
|
||||
}
|
||||
fee_found = true;
|
||||
}
|
||||
}
|
||||
TALER_LOG_DEBUG ("Freeing method '%s'\n",
|
||||
method);
|
||||
GNUNET_free (method);
|
||||
if (! fee_found)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"/wire does not contain expected fee '%s'\n",
|
||||
ws->expected_fee);
|
||||
TALER_TESTING_interpreter_fail (ws->is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (GNUNET_OK != ws->method_found)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
@ -67,13 +67,14 @@ struct WireAddState
|
||||
* if the response code is acceptable.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param wer response details
|
||||
*/
|
||||
static void
|
||||
wire_add_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer)
|
||||
{
|
||||
struct WireAddState *ds = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &wer->hr;
|
||||
|
||||
ds->dh = NULL;
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
@ -110,10 +111,14 @@ wire_add_run (void *cls,
|
||||
struct TALER_MasterSignatureP master_sig1;
|
||||
struct TALER_MasterSignatureP master_sig2;
|
||||
struct GNUNET_TIME_Timestamp now;
|
||||
json_t *credit_rest;
|
||||
json_t *debit_rest;
|
||||
|
||||
(void) cmd;
|
||||
now = GNUNET_TIME_timestamp_get ();
|
||||
ds->is = is;
|
||||
debit_rest = json_array ();
|
||||
credit_rest = json_array ();
|
||||
if (ds->bad_sig)
|
||||
{
|
||||
memset (&master_sig1,
|
||||
@ -126,10 +131,16 @@ wire_add_run (void *cls,
|
||||
else
|
||||
{
|
||||
TALER_exchange_offline_wire_add_sign (ds->payto_uri,
|
||||
NULL,
|
||||
debit_rest,
|
||||
credit_rest,
|
||||
now,
|
||||
&is->master_priv,
|
||||
&master_sig1);
|
||||
TALER_exchange_wire_signature_make (ds->payto_uri,
|
||||
NULL,
|
||||
debit_rest,
|
||||
credit_rest,
|
||||
&is->master_priv,
|
||||
&master_sig2);
|
||||
}
|
||||
@ -137,11 +148,16 @@ wire_add_run (void *cls,
|
||||
is->ctx,
|
||||
is->exchange_url,
|
||||
ds->payto_uri,
|
||||
NULL,
|
||||
debit_rest,
|
||||
credit_rest,
|
||||
now,
|
||||
&master_sig1,
|
||||
&master_sig2,
|
||||
&wire_add_cb,
|
||||
ds);
|
||||
json_decref (debit_rest);
|
||||
json_decref (credit_rest);
|
||||
if (NULL == ds->dh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
Copyright (C) 2020, 2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
@ -67,13 +67,14 @@ struct WireDelState
|
||||
* if the response code is acceptable.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param wdr response details
|
||||
*/
|
||||
static void
|
||||
wire_del_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr)
|
||||
const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdr)
|
||||
{
|
||||
struct WireDelState *ds = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &wdr->hr;
|
||||
|
||||
ds->dh = NULL;
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
|
@ -297,10 +297,10 @@ reserve_withdraw_cb (void *cls,
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
TALER_denom_sig_deep_copy (&ws->sig,
|
||||
&wr->details.success.sig);
|
||||
ws->coin_priv = wr->details.success.coin_priv;
|
||||
ws->bks = wr->details.success.bks;
|
||||
ws->exchange_vals = wr->details.success.exchange_vals;
|
||||
&wr->details.ok.sig);
|
||||
ws->coin_priv = wr->details.ok.coin_priv;
|
||||
ws->bks = wr->details.ok.bks;
|
||||
ws->exchange_vals = wr->details.ok.exchange_vals;
|
||||
if (0 != ws->total_backoff.rel_value_us)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
|
@ -526,49 +526,46 @@ sighandler_child_death (void)
|
||||
|
||||
void
|
||||
TALER_TESTING_cert_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
const struct TALER_EXCHANGE_Keys *keys,
|
||||
enum TALER_EXCHANGE_VersionCompatibility compat)
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
{
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &kr->hr;
|
||||
struct MainContext *main_ctx = cls;
|
||||
struct TALER_TESTING_Interpreter *is = main_ctx->is;
|
||||
|
||||
(void) compat;
|
||||
if (NULL == keys)
|
||||
switch (hr->http_status)
|
||||
{
|
||||
if (GNUNET_NO == is->working)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Got NULL response for /keys during startup (%u/%d), retrying!\n",
|
||||
hr->http_status,
|
||||
(int) hr->ec);
|
||||
TALER_EXCHANGE_disconnect (is->exchange);
|
||||
GNUNET_assert (
|
||||
NULL != (is->exchange
|
||||
= TALER_EXCHANGE_connect (is->ctx,
|
||||
main_ctx->exchange_url,
|
||||
&TALER_TESTING_cert_cb,
|
||||
main_ctx,
|
||||
TALER_EXCHANGE_OPTION_END)));
|
||||
return;
|
||||
}
|
||||
else
|
||||
case MHD_HTTP_OK:
|
||||
/* dealt with below */
|
||||
break;
|
||||
default:
|
||||
if (GNUNET_YES == is->working)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Got NULL response for /keys during execution (%u/%d)!\n",
|
||||
hr->http_status,
|
||||
(int) hr->ec);
|
||||
return;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Got failure response for /keys during startup (%u/%d), retrying!\n",
|
||||
hr->http_status,
|
||||
(int) hr->ec);
|
||||
TALER_EXCHANGE_disconnect (is->exchange);
|
||||
GNUNET_assert (
|
||||
NULL != (is->exchange
|
||||
= TALER_EXCHANGE_connect (is->ctx,
|
||||
main_ctx->exchange_url,
|
||||
&TALER_TESTING_cert_cb,
|
||||
main_ctx,
|
||||
TALER_EXCHANGE_OPTION_END)));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Got %d DK from /keys in generation %u\n",
|
||||
keys->num_denom_keys,
|
||||
is->key_generation + 1);
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Got %d DK from /keys in generation %u\n",
|
||||
kr->details.ok.keys->num_denom_keys,
|
||||
is->key_generation + 1);
|
||||
is->key_generation++;
|
||||
is->keys = keys;
|
||||
is->keys = kr->details.ok.keys;
|
||||
|
||||
/* /keys has been called for some reason and
|
||||
* the interpreter is already running. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020-2022 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -677,6 +677,22 @@ struct TALER_MasterAddWirePS
|
||||
* Hash over the exchange's payto URI.
|
||||
*/
|
||||
struct TALER_PaytoHashP h_payto GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* Hash over the conversion URL, all zeros if there
|
||||
* is no conversion URL.
|
||||
*/
|
||||
struct GNUNET_HashCode h_conversion_url;
|
||||
|
||||
/**
|
||||
* Hash over the debit restrictions.
|
||||
*/
|
||||
struct GNUNET_HashCode h_debit_restrictions;
|
||||
|
||||
/**
|
||||
* Hash over the credit restrictions.
|
||||
*/
|
||||
struct GNUNET_HashCode h_credit_restrictions;
|
||||
};
|
||||
|
||||
GNUNET_NETWORK_STRUCT_END
|
||||
@ -685,6 +701,9 @@ GNUNET_NETWORK_STRUCT_END
|
||||
void
|
||||
TALER_exchange_offline_wire_add_sign (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp now,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig)
|
||||
@ -697,6 +716,14 @@ TALER_exchange_offline_wire_add_sign (
|
||||
|
||||
TALER_payto_hash (payto_uri,
|
||||
&kv.h_payto);
|
||||
if (NULL != conversion_url)
|
||||
GNUNET_CRYPTO_hash (conversion_url,
|
||||
strlen (conversion_url),
|
||||
&kv.h_conversion_url);
|
||||
TALER_json_hash (debit_restrictions,
|
||||
&kv.h_debit_restrictions);
|
||||
TALER_json_hash (credit_restrictions,
|
||||
&kv.h_credit_restrictions);
|
||||
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
|
||||
&kv,
|
||||
&master_sig->eddsa_signature);
|
||||
@ -706,6 +733,9 @@ TALER_exchange_offline_wire_add_sign (
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_offline_wire_add_verify (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
struct GNUNET_TIME_Timestamp sign_time,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig)
|
||||
@ -718,6 +748,14 @@ TALER_exchange_offline_wire_add_verify (
|
||||
|
||||
TALER_payto_hash (payto_uri,
|
||||
&aw.h_payto);
|
||||
if (NULL != conversion_url)
|
||||
GNUNET_CRYPTO_hash (conversion_url,
|
||||
strlen (conversion_url),
|
||||
&aw.h_conversion_url);
|
||||
TALER_json_hash (debit_restrictions,
|
||||
&aw.h_debit_restrictions);
|
||||
TALER_json_hash (credit_restrictions,
|
||||
&aw.h_credit_restrictions);
|
||||
return
|
||||
GNUNET_CRYPTO_eddsa_verify (
|
||||
TALER_SIGNATURE_MASTER_ADD_WIRE,
|
||||
@ -1095,6 +1133,22 @@ struct TALER_MasterWireDetailsPS
|
||||
*/
|
||||
struct TALER_PaytoHashP h_wire_details GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* Hash over the conversion URL, all zeros if there
|
||||
* is no conversion URL.
|
||||
*/
|
||||
struct GNUNET_HashCode h_conversion_url;
|
||||
|
||||
/**
|
||||
* Hash over the debit restrictions.
|
||||
*/
|
||||
struct GNUNET_HashCode h_debit_restrictions;
|
||||
|
||||
/**
|
||||
* Hash over the credit restrictions.
|
||||
*/
|
||||
struct GNUNET_HashCode h_credit_restrictions;
|
||||
|
||||
};
|
||||
|
||||
GNUNET_NETWORK_STRUCT_END
|
||||
@ -1103,6 +1157,9 @@ GNUNET_NETWORK_STRUCT_END
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_wire_signature_check (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig)
|
||||
{
|
||||
@ -1113,6 +1170,14 @@ TALER_exchange_wire_signature_check (
|
||||
|
||||
TALER_payto_hash (payto_uri,
|
||||
&wd.h_wire_details);
|
||||
if (NULL != conversion_url)
|
||||
GNUNET_CRYPTO_hash (conversion_url,
|
||||
strlen (conversion_url),
|
||||
&wd.h_conversion_url);
|
||||
TALER_json_hash (debit_restrictions,
|
||||
&wd.h_debit_restrictions);
|
||||
TALER_json_hash (credit_restrictions,
|
||||
&wd.h_credit_restrictions);
|
||||
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS,
|
||||
&wd,
|
||||
&master_sig->eddsa_signature,
|
||||
@ -1123,6 +1188,9 @@ TALER_exchange_wire_signature_check (
|
||||
void
|
||||
TALER_exchange_wire_signature_make (
|
||||
const char *payto_uri,
|
||||
const char *conversion_url,
|
||||
const json_t *debit_restrictions,
|
||||
const json_t *credit_restrictions,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig)
|
||||
{
|
||||
@ -1133,6 +1201,14 @@ TALER_exchange_wire_signature_make (
|
||||
|
||||
TALER_payto_hash (payto_uri,
|
||||
&wd.h_wire_details);
|
||||
if (NULL != conversion_url)
|
||||
GNUNET_CRYPTO_hash (conversion_url,
|
||||
strlen (conversion_url),
|
||||
&wd.h_conversion_url);
|
||||
TALER_json_hash (debit_restrictions,
|
||||
&wd.h_debit_restrictions);
|
||||
TALER_json_hash (credit_restrictions,
|
||||
&wd.h_credit_restrictions);
|
||||
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
|
||||
&wd,
|
||||
&master_sig->eddsa_signature);
|
||||
|
Loading…
Reference in New Issue
Block a user