gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: fix #6939 in exchange


From: gnunet
Subject: [taler-exchange] branch master updated: fix #6939 in exchange
Date: Sat, 24 Jul 2021 09:01:22 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 42decef9 fix #6939 in exchange
42decef9 is described below

commit 42decef957861689c41d16a0dcfa8af3d9052816
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jul 24 09:00:35 2021 +0200

    fix #6939 in exchange
---
 src/auditor/taler-auditor-httpd.c                  |  6 +--
 src/auditor/taler-auditor-httpd.h                  |  4 ++
 .../taler-auditor-httpd_deposit-confirmation.c     | 40 +++++++++-----
 src/bank-lib/bank_api_credit.c                     |  4 +-
 src/bank-lib/bank_api_debit.c                      |  4 +-
 src/bank-lib/fakebank.c                            |  2 +
 src/exchange-tools/taler-auditor-offline.c         | 22 ++++++++
 src/exchange-tools/taler-exchange-offline.c        | 24 +++++++++
 src/exchange/taler-exchange-httpd_deposit.c        | 12 +----
 .../taler-exchange-httpd_management_wire_fees.c    | 24 +--------
 src/exchange/taler-exchange-httpd_melt.c           | 13 +----
 src/exchange/taler-exchange-httpd_refund.c         | 16 +-----
 src/include/taler_json_lib.h                       | 41 +++++++++++++-
 src/json/json_helper.c                             | 62 +++++++++++++++++++++-
 src/json/test_json.c                               |  4 +-
 src/lib/exchange_api_common.c                      | 40 +++++++-------
 src/lib/exchange_api_deposits_get.c                |  2 +-
 src/lib/exchange_api_handle.c                      | 20 +++----
 src/lib/exchange_api_management_get_keys.c         | 20 +++----
 src/lib/exchange_api_melt.c                        |  4 +-
 src/lib/exchange_api_refund.c                      | 20 +++----
 src/lib/exchange_api_reserves_get.c                |  2 +-
 src/lib/exchange_api_transfers_get.c               |  8 +--
 src/lib/exchange_api_wire.c                        |  8 +--
 src/lib/exchange_api_withdraw2.c                   |  2 +-
 25 files changed, 258 insertions(+), 146 deletions(-)

diff --git a/src/auditor/taler-auditor-httpd.c 
b/src/auditor/taler-auditor-httpd.c
index d77b2418..36d0547f 100644
--- a/src/auditor/taler-auditor-httpd.c
+++ b/src/auditor/taler-auditor-httpd.c
@@ -108,7 +108,7 @@ static mode_t unixpath_mode;
 /**
  * Our currency.
  */
-static char *currency;
+char *TAH_currency;
 
 /**
  * Pipe used for signaling reloading of our key state.
@@ -325,7 +325,7 @@ handle_version (struct TAH_RequestHandler *rh,
   {
     ver = json_pack ("{s:s, s:s, s:o}",
                      "version", AUDITOR_PROTOCOL_VERSION,
-                     "currency", currency,
+                     "currency", TAH_currency,
                      "auditor_public_key", GNUNET_JSON_from_data_auto (
                        &auditor_pub));
   }
@@ -461,7 +461,7 @@ auditor_serve_process_config (void)
   }
   if (GNUNET_OK !=
       TALER_config_get_currency (cfg,
-                                 &currency))
+                                 &TAH_currency))
   {
     return GNUNET_SYSERR;
   }
diff --git a/src/auditor/taler-auditor-httpd.h 
b/src/auditor/taler-auditor-httpd.h
index 25e37427..79e56ff5 100644
--- a/src/auditor/taler-auditor-httpd.h
+++ b/src/auditor/taler-auditor-httpd.h
@@ -38,6 +38,10 @@ extern struct TALER_AUDITORDB_Plugin *TAH_plugin;
  */
 extern struct TALER_EXCHANGEDB_Plugin *TAH_eplugin;
 
+/**
+ * Our currency.
+ */
+extern char *TAH_currency;
 
 /**
  * @brief Struct describing an URL and the handler for it.
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c 
b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 5c1ee9f0..31d7a719 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -259,21 +259,35 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct 
TAH_RequestHandler *rh,
   struct TALER_AUDITORDB_DepositConfirmation dc;
   struct TALER_AUDITORDB_ExchangeSigningKey es;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &dc.h_contract_terms),
-    GNUNET_JSON_spec_fixed_auto ("h_wire", &dc.h_wire),
+    GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
+                                 &dc.h_contract_terms),
+    GNUNET_JSON_spec_fixed_auto ("h_wire",
+                                 &dc.h_wire),
     TALER_JSON_spec_absolute_time ("exchange_timestamp",
                                    &dc.exchange_timestamp),
-    TALER_JSON_spec_absolute_time ("refund_deadline", &dc.refund_deadline),
-    TALER_JSON_spec_amount ("amount_without_fee", &dc.amount_without_fee),
-    GNUNET_JSON_spec_fixed_auto ("coin_pub", &dc.coin_pub),
-    GNUNET_JSON_spec_fixed_auto ("merchant_pub", &dc.merchant),
-    GNUNET_JSON_spec_fixed_auto ("exchange_sig",  &dc.exchange_sig),
-    GNUNET_JSON_spec_fixed_auto ("exchange_pub",  &dc.exchange_pub),
-    GNUNET_JSON_spec_fixed_auto ("master_pub",  &es.master_public_key),
-    TALER_JSON_spec_absolute_time ("ep_start",  &es.ep_start),
-    TALER_JSON_spec_absolute_time ("ep_expire",  &es.ep_expire),
-    TALER_JSON_spec_absolute_time ("ep_end",  &es.ep_end),
-    GNUNET_JSON_spec_fixed_auto ("master_sig",  &es.master_sig),
+    TALER_JSON_spec_absolute_time ("refund_deadline",
+                                   &dc.refund_deadline),
+    TALER_JSON_spec_amount ("amount_without_fee",
+                            TAH_currency,
+                            &dc.amount_without_fee),
+    GNUNET_JSON_spec_fixed_auto ("coin_pub",
+                                 &dc.coin_pub),
+    GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+                                 &dc.merchant),
+    GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+                                 &dc.exchange_sig),
+    GNUNET_JSON_spec_fixed_auto ("exchange_pub",
+                                 &dc.exchange_pub),
+    GNUNET_JSON_spec_fixed_auto ("master_pub",
+                                 &es.master_public_key),
+    TALER_JSON_spec_absolute_time ("ep_start",
+                                   &es.ep_start),
+    TALER_JSON_spec_absolute_time ("ep_expire",
+                                   &es.ep_expire),
+    TALER_JSON_spec_absolute_time ("ep_end",
+                                   &es.ep_end),
+    GNUNET_JSON_spec_fixed_auto ("master_sig",
+                                 &es.master_sig),
     GNUNET_JSON_spec_end ()
   };
 
diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c
index 290a6484..adbc3233 100644
--- a/src/bank-lib/bank_api_credit.c
+++ b/src/bank-lib/bank_api_credit.c
@@ -88,8 +88,8 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle 
*hh,
     struct TALER_BANK_CreditDetails td;
     uint64_t row_id;
     struct GNUNET_JSON_Specification hist_spec[] = {
-      TALER_JSON_spec_amount ("amount",
-                              &td.amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &td.amount),
       TALER_JSON_spec_absolute_time ("date",
                                      &td.execution_date),
       GNUNET_JSON_spec_uint64 ("row_id",
diff --git a/src/bank-lib/bank_api_debit.c b/src/bank-lib/bank_api_debit.c
index 604e89b4..fcbe1bfd 100644
--- a/src/bank-lib/bank_api_debit.c
+++ b/src/bank-lib/bank_api_debit.c
@@ -88,8 +88,8 @@ parse_account_history (struct TALER_BANK_DebitHistoryHandle 
*hh,
     struct TALER_BANK_DebitDetails td;
     uint64_t row_id;
     struct GNUNET_JSON_Specification hist_spec[] = {
-      TALER_JSON_spec_amount ("amount",
-                              &td.amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &td.amount),
       TALER_JSON_spec_absolute_time ("date",
                                      &td.execution_date),
       GNUNET_JSON_spec_uint64 ("row_id",
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index f728ca47..c6871938 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -1027,6 +1027,7 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle 
*h,
       GNUNET_JSON_spec_string ("debit_account",
                                &debit_account),
       TALER_JSON_spec_amount ("amount",
+                              h->currency,
                               &amount),
       GNUNET_JSON_spec_end ()
     };
@@ -1148,6 +1149,7 @@ handle_transfer (struct TALER_FAKEBANK_Handle *h,
       GNUNET_JSON_spec_fixed_auto ("request_uid",
                                    &uuid),
       TALER_JSON_spec_amount ("amount",
+                              h->currency,
                               &amount),
       GNUNET_JSON_spec_string ("exchange_base_url",
                                &base_url),
diff --git a/src/exchange-tools/taler-auditor-offline.c 
b/src/exchange-tools/taler-auditor-offline.c
index 7b6d0a89..33743bb3 100644
--- a/src/exchange-tools/taler-auditor-offline.c
+++ b/src/exchange-tools/taler-auditor-offline.c
@@ -98,6 +98,11 @@ static json_t *in;
  */
 static json_t *out;
 
+/**
+ * Currency supported by this auditor.
+ */
+static char *currency;
+
 
 /**
  * A subcommand supported by this program.
@@ -749,14 +754,19 @@ show_denomkeys (const json_t *denomkeys)
       GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                        &denom_pub.rsa_public_key),
       TALER_JSON_spec_amount ("value",
+                              currency,
                               &coin_value),
       TALER_JSON_spec_amount ("fee_withdraw",
+                              currency,
                               &fee_withdraw),
       TALER_JSON_spec_amount ("fee_deposit",
+                              currency,
                               &fee_deposit),
       TALER_JSON_spec_amount ("fee_refresh",
+                              currency,
                               &fee_refresh),
       TALER_JSON_spec_amount ("fee_refund",
+                              currency,
                               &fee_refund),
       GNUNET_JSON_spec_absolute_time ("stamp_start",
                                       &stamp_start),
@@ -1044,14 +1054,19 @@ sign_denomkeys (const json_t *denomkeys)
       GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                        &denom_pub.rsa_public_key),
       TALER_JSON_spec_amount ("value",
+                              currency,
                               &coin_value),
       TALER_JSON_spec_amount ("fee_withdraw",
+                              currency,
                               &fee_withdraw),
       TALER_JSON_spec_amount ("fee_deposit",
+                              currency,
                               &fee_deposit),
       TALER_JSON_spec_amount ("fee_refresh",
+                              currency,
                               &fee_refresh),
       TALER_JSON_spec_amount ("fee_refund",
+                              currency,
                               &fee_refund),
       GNUNET_JSON_spec_absolute_time ("stamp_start",
                                       &stamp_start),
@@ -1346,6 +1361,13 @@ run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   kcfg = cfg;
+  if (GNUNET_OK !=
+      TALER_config_get_currency (kcfg,
+                                 &currency))
+  {
+    global_ret = 1;
+    return;
+  }
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (kcfg,
                                              "auditor",
diff --git a/src/exchange-tools/taler-exchange-offline.c 
b/src/exchange-tools/taler-exchange-offline.c
index 6164a810..79b8dd47 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -134,6 +134,11 @@ static json_t *in;
  */
 static json_t *out;
 
+/**
+ * Currency we have configured.
+ */
+static char *currency;
+
 
 /**
  * A subcommand supported by this program.
@@ -1424,8 +1429,10 @@ upload_wire_fee (const char *exchange_url,
     GNUNET_JSON_spec_string ("wire_method",
                              &wire_method),
     TALER_JSON_spec_amount ("wire_fee",
+                            currency,
                             &wire_fee),
     TALER_JSON_spec_amount ("closing_fee",
+                            currency,
                             &closing_fee),
     GNUNET_JSON_spec_absolute_time ("start_time",
                                     &start_time),
@@ -2590,14 +2597,19 @@ show_denomkeys (const struct 
TALER_SecurityModulePublicKeyP *secm_pub,
       GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                        &denom_pub.rsa_public_key),
       TALER_JSON_spec_amount ("value",
+                              currency,
                               &coin_value),
       TALER_JSON_spec_amount ("fee_withdraw",
+                              currency,
                               &fee_withdraw),
       TALER_JSON_spec_amount ("fee_deposit",
+                              currency,
                               &fee_deposit),
       TALER_JSON_spec_amount ("fee_refresh",
+                              currency,
                               &fee_refresh),
       TALER_JSON_spec_amount ("fee_refund",
+                              currency,
                               &fee_refund),
       GNUNET_JSON_spec_absolute_time ("stamp_start",
                                       &stamp_start),
@@ -3004,14 +3016,19 @@ sign_denomkeys (const struct 
TALER_SecurityModulePublicKeyP *secm_pub,
       GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                        &denom_pub.rsa_public_key),
       TALER_JSON_spec_amount ("value",
+                              currency,
                               &coin_value),
       TALER_JSON_spec_amount ("fee_withdraw",
+                              currency,
                               &fee_withdraw),
       TALER_JSON_spec_amount ("fee_deposit",
+                              currency,
                               &fee_deposit),
       TALER_JSON_spec_amount ("fee_refresh",
+                              currency,
                               &fee_refresh),
       TALER_JSON_spec_amount ("fee_refund",
+                              currency,
                               &fee_refund),
       GNUNET_JSON_spec_absolute_time ("stamp_start",
                                       &stamp_start),
@@ -3385,6 +3402,13 @@ run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   kcfg = cfg;
+  if (GNUNET_OK !=
+      TALER_config_get_currency (kcfg,
+                                 &currency))
+  {
+    global_ret = 1;
+    return;
+  }
   ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
                           &rc);
   rc = GNUNET_CURL_gnunet_rc_create (ctx);
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index 8e93d998..5e802fb0 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -332,6 +332,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_json ("wire", &wire),
     TALER_JSON_spec_amount ("contribution",
+                            TEH_currency,
                             &deposit.amount_with_fee),
     GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
                                  &deposit.coin.denom_pub_hash),
@@ -488,17 +489,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
     }
 
     deposit.deposit_fee = dk->meta.fee_deposit;
-    if (GNUNET_YES !=
-        TALER_amount_cmp_currency (&deposit.amount_with_fee,
-                                   &deposit.deposit_fee) )
-    {
-      GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                                         deposit.deposit_fee.currency);
-    }
     /* check coin signature */
     if (GNUNET_YES !=
         TALER_test_coin_valid (&deposit.coin,
diff --git a/src/exchange/taler-exchange-httpd_management_wire_fees.c 
b/src/exchange/taler-exchange-httpd_management_wire_fees.c
index 0a011bc0..0a8bf4d1 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_fees.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_fees.c
@@ -180,8 +180,10 @@ TEH_handler_management_post_wire_fees (
     TALER_JSON_spec_absolute_time ("fee_end",
                                    &afc.end_time),
     TALER_JSON_spec_amount ("closing_fee",
+                            TEH_currency,
                             &afc.closing_fee),
     TALER_JSON_spec_amount ("wire_fee",
+                            TEH_currency,
                             &afc.wire_fee),
     GNUNET_JSON_spec_end ()
   };
@@ -200,28 +202,6 @@ TEH_handler_management_post_wire_fees (
       return MHD_YES; /* failure */
   }
 
-  if (GNUNET_OK !=
-      TALER_amount_cmp_currency (&afc.closing_fee,
-                                 &afc.wire_fee))
-  {
-    /* currencies of the two fees must be identical */
-    GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                                       NULL);
-  }
-  if (0 !=
-      strcasecmp (afc.wire_fee.currency,
-                  TEH_currency))
-  {
-    /* currency does not match exchange's currency */
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_PRECONDITION_FAILED,
-                                       TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                                       TEH_currency);
-  }
-
   if (GNUNET_OK !=
       TALER_exchange_offline_wire_fee_verify (
         afc.wire_method,
diff --git a/src/exchange/taler-exchange-httpd_melt.c 
b/src/exchange/taler-exchange-httpd_melt.c
index a11d608b..8e51a417 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -554,18 +554,6 @@ check_for_denomination_key (struct MHD_Connection 
*connection,
 
   rmc->coin_refresh_fee = dk->meta.fee_refresh;
   rmc->coin_value = dk->meta.value;
-  /* check client used sane currency */
-  if (GNUNET_YES !=
-      TALER_amount_cmp_currency (&rmc->refresh_session.amount_with_fee,
-                                 &rmc->coin_value) )
-  {
-    GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (
-      connection,
-      MHD_HTTP_BAD_REQUEST,
-      TALER_EC_GENERIC_CURRENCY_MISMATCH,
-      rmc->refresh_session.amount_with_fee.currency);
-  }
   /* check coin is actually properly signed */
   if (GNUNET_OK !=
       TALER_test_coin_valid (&rmc->refresh_session.coin,
@@ -621,6 +609,7 @@ TEH_handler_melt (struct MHD_Connection *connection,
     GNUNET_JSON_spec_fixed_auto ("confirm_sig",
                                  &rmc.refresh_session.coin_sig),
     TALER_JSON_spec_amount ("value_with_fee",
+                            TEH_currency,
                             &rmc.refresh_session.amount_with_fee),
     GNUNET_JSON_spec_fixed_auto ("rc",
                                  &rmc.refresh_session.rc),
diff --git a/src/exchange/taler-exchange-httpd_refund.c 
b/src/exchange/taler-exchange-httpd_refund.c
index d0865dd8..35b179be 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -312,21 +312,6 @@ refund_transaction (void *cls,
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
-  /* check currency is compatible */
-  if (GNUNET_YES !=
-      TALER_amount_cmp_currency (&refund->details.refund_amount,
-                                 &deposit_total))
-  {
-    GNUNET_break_op (0); /* currency mismatch */
-    TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
-                                            tlx);
-    *mhd_ret = TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           TALER_EC_GENERIC_CURRENCY_MISMATCH,
-                                           deposit_total.currency);
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  }
-
   /* check total refund amount is sufficiently low */
   if (refund_found)
     GNUNET_break (0 <=
@@ -505,6 +490,7 @@ TEH_handler_refund (struct MHD_Connection *connection,
   };
   struct GNUNET_JSON_Specification spec[] = {
     TALER_JSON_spec_amount ("refund_amount",
+                            TEH_currency,
                             &refund.details.refund_amount),
     GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
                                  &refund.details.h_contract_terms),
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 145a5d2e..1089f5bd 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015, 2016 Taler Systems SA
+  Copyright (C) 2014, 2015, 2016, 2021 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
@@ -59,33 +59,70 @@ TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO 
*amount);
 
 /**
  * Provide specification to parse given JSON object to an amount.
+ * The @a currency must be a valid pointer while the
+ * parsing is done, a copy is not made.
  *
  * @param name name of the amount field in the JSON
+ * @param currency the currency the amount must be in
  * @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
  */
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_amount (const char *name,
+                        const char *currency,
                         struct TALER_Amount *r_amount);
 
 
 /**
  * Provide specification to parse given JSON object to an amount
  * in network byte order.
+ * The @a currency must be a valid pointer while the
+ * parsing is done, a copy is not made.
  *
  * @param name name of the amount field in the JSON
+ * @param currency the currency the amount must be in
  * @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
  */
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_amount_nbo (const char *name,
+                            const char *currency,
                             struct TALER_AmountNBO *r_amount);
 
 
+/**
+ * Provide specification to parse given JSON object to an amount
+ * in any currency.
+ *
+ * @param name name of the amount field in the JSON
+ * @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_any (const char *name,
+                            struct TALER_Amount *r_amount);
+
+
+/**
+ * Provide specification to parse given JSON object to an amount
+ * in any currency in network byte order.
+ *
+ * @param name name of the amount field in the JSON
+ * @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_any_nbo (const char *name,
+                                struct TALER_AmountNBO *r_amount);
+
+
 /**
  * Provide specification to parse given JSON object to an absolute time.
  * The absolute time value is expected to be already rounded.
  *
  * @param name name of the time field in the JSON
  * @param[out] r_time where the time has to be written
+ * @return spec for parsing an absolute time
  */
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_absolute_time (const char *name,
@@ -99,6 +136,7 @@ TALER_JSON_spec_absolute_time (const char *name,
  *
  * @param name name of the time field in the JSON
  * @param[out] r_time where the time has to be written
+ * @return spec for parsing an absolute time
  */
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_absolute_time_nbo (const char *name,
@@ -111,6 +149,7 @@ TALER_JSON_spec_absolute_time_nbo (const char *name,
  *
  * @param name name of the time field in the JSON
  * @param[out] r_time where the time has to be written
+ * @return spec for parsing a relative time
  */
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_relative_time (const char *name,
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 866c094d..1f8d320b 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -55,7 +55,7 @@ TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO 
*amount)
 /**
  * Parse given JSON object to Amount
  *
- * @param cls closure, NULL
+ * @param cls closure, expected currency, or NULL
  * @param root the json object representing data
  * @param[out] spec where to write the data
  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
@@ -65,6 +65,7 @@ parse_amount (void *cls,
               json_t *root,
               struct GNUNET_JSON_Specification *spec)
 {
+  const char *currency = cls;
   struct TALER_Amount *r_amount = spec->ptr;
 
   (void) cls;
@@ -80,13 +81,41 @@ parse_amount (void *cls,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
+  if ( (NULL != currency) &&
+       (0 !=
+        strcasecmp (currency,
+                    r_amount->currency)) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
   return GNUNET_OK;
 }
 
 
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_amount (const char *name,
+                        const char *currency,
                         struct TALER_Amount *r_amount)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_amount,
+    .cleaner = NULL,
+    .cls = (void *) currency,
+    .field = name,
+    .ptr = r_amount,
+    .ptr_size = 0,
+    .size_ptr = NULL
+  };
+
+  GNUNET_assert (NULL != currency);
+  return ret;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_any (const char *name,
+                            struct TALER_Amount *r_amount)
 {
   struct GNUNET_JSON_Specification ret = {
     .parser = &parse_amount,
@@ -97,6 +126,7 @@ TALER_JSON_spec_amount (const char *name,
     .ptr_size = 0,
     .size_ptr = NULL
   };
+
   return ret;
 }
 
@@ -114,6 +144,7 @@ parse_amount_nbo (void *cls,
                   json_t *root,
                   struct GNUNET_JSON_Specification *spec)
 {
+  const char *currency = cls;
   struct TALER_AmountNBO *r_amount = spec->ptr;
   const char *sv;
 
@@ -134,13 +165,41 @@ parse_amount_nbo (void *cls,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
+  if ( (NULL != currency) &&
+       (0 !=
+        strcasecmp (currency,
+                    r_amount->currency)) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
   return GNUNET_OK;
 }
 
 
 struct GNUNET_JSON_Specification
 TALER_JSON_spec_amount_nbo (const char *name,
+                            const char *currency,
                             struct TALER_AmountNBO *r_amount)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_amount_nbo,
+    .cleaner = NULL,
+    .cls = (void *) currency,
+    .field = name,
+    .ptr = r_amount,
+    .ptr_size = 0,
+    .size_ptr = NULL
+  };
+
+  GNUNET_assert (NULL != currency);
+  return ret;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_any_nbo (const char *name,
+                                struct TALER_AmountNBO *r_amount)
 {
   struct GNUNET_JSON_Specification ret = {
     .parser = &parse_amount_nbo,
@@ -151,6 +210,7 @@ TALER_JSON_spec_amount_nbo (const char *name,
     .ptr_size = 0,
     .size_ptr = NULL
   };
+
   return ret;
 }
 
diff --git a/src/json/test_json.c b/src/json/test_json.c
index bedea76a..e312a4ed 100644
--- a/src/json/test_json.c
+++ b/src/json/test_json.c
@@ -36,7 +36,9 @@ test_amount (void)
   struct TALER_Amount a1;
   struct TALER_Amount a2;
   struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("amount", &a2),
+    TALER_JSON_spec_amount ("amount",
+                            "EUR",
+                            &a2),
     GNUNET_JSON_spec_end ()
   };
 
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 2ad55e6c..a564a367 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -73,8 +73,8 @@ TALER_EXCHANGE_parse_reserve_history (
     struct GNUNET_JSON_Specification hist_spec[] = {
       GNUNET_JSON_spec_string ("type",
                                &type),
-      TALER_JSON_spec_amount ("amount",
-                              &amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &amount),
       /* 'wire' and 'signature' are optional depending on 'type'! */
       GNUNET_JSON_spec_end ()
     };
@@ -145,8 +145,8 @@ TALER_EXCHANGE_parse_reserve_history (
       struct GNUNET_JSON_Specification withdraw_spec[] = {
         GNUNET_JSON_spec_fixed_auto ("reserve_sig",
                                      &sig),
-        TALER_JSON_spec_amount ("withdraw_fee",
-                                &withdraw_fee),
+        TALER_JSON_spec_amount_any ("withdraw_fee",
+                                    &withdraw_fee),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                      &withdraw_purpose.h_denomination_pub),
         GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
@@ -321,8 +321,8 @@ TALER_EXCHANGE_parse_reserve_history (
                                      &rh->details.close_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &rh->details.close_details.exchange_pub),
-        TALER_JSON_spec_amount_nbo ("closing_fee",
-                                    &rcc.closing_fee),
+        TALER_JSON_spec_amount_any_nbo ("closing_fee",
+                                        &rcc.closing_fee),
         TALER_JSON_spec_absolute_time_nbo ("timestamp",
                                            &rcc.timestamp),
         GNUNET_JSON_spec_end ()
@@ -482,8 +482,8 @@ TALER_EXCHANGE_verify_coin_history (
     struct TALER_Amount amount;
     const char *type;
     struct GNUNET_JSON_Specification spec_glob[] = {
-      TALER_JSON_spec_amount ("amount",
-                              &amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &amount),
       GNUNET_JSON_spec_string ("type",
                                &type),
       GNUNET_JSON_spec_end ()
@@ -529,8 +529,8 @@ TALER_EXCHANGE_verify_coin_history (
                                            &dr.wallet_timestamp),
         TALER_JSON_spec_absolute_time_nbo ("refund_deadline",
                                            &dr.refund_deadline),
-        TALER_JSON_spec_amount_nbo ("deposit_fee",
-                                    &dr.deposit_fee),
+        TALER_JSON_spec_amount_any_nbo ("deposit_fee",
+                                        &dr.deposit_fee),
         GNUNET_JSON_spec_fixed_auto ("merchant_pub",
                                      &dr.merchant),
         GNUNET_JSON_spec_end ()
@@ -586,8 +586,8 @@ TALER_EXCHANGE_verify_coin_history (
                                      &rm.rc),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                      &rm.h_denom_pub),
-        TALER_JSON_spec_amount_nbo ("melt_fee",
-                                    &rm.melt_fee),
+        TALER_JSON_spec_amount_any_nbo ("melt_fee",
+                                        &rm.melt_fee),
         GNUNET_JSON_spec_end ()
       };
 
@@ -644,8 +644,8 @@ TALER_EXCHANGE_verify_coin_history (
         .coin_pub = *coin_pub
       };
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount ("refund_fee",
-                                &refund_fee),
+        TALER_JSON_spec_amount_any ("refund_fee",
+                                    &refund_fee),
         GNUNET_JSON_spec_fixed_auto ("merchant_sig",
                                      &sig),
         GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
@@ -728,8 +728,8 @@ TALER_EXCHANGE_verify_coin_history (
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_nbo ("amount",
-                                    &pc.recoup_amount),
+        TALER_JSON_spec_amount_any_nbo ("amount",
+                                        &pc.recoup_amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -796,8 +796,8 @@ TALER_EXCHANGE_verify_coin_history (
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_nbo ("amount",
-                                    &pc.recoup_amount),
+        TALER_JSON_spec_amount_any_nbo ("amount",
+                                        &pc.recoup_amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -859,8 +859,8 @@ TALER_EXCHANGE_verify_coin_history (
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_nbo ("amount",
-                                    &pc.recoup_amount),
+        TALER_JSON_spec_amount_any_nbo ("amount",
+                                        &pc.recoup_amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
diff --git a/src/lib/exchange_api_deposits_get.c 
b/src/lib/exchange_api_deposits_get.c
index b4bcfbcd..efe9070f 100644
--- a/src/lib/exchange_api_deposits_get.c
+++ b/src/lib/exchange_api_deposits_get.c
@@ -150,7 +150,7 @@ handle_deposit_wtid_finished (void *cls,
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid),
         TALER_JSON_spec_absolute_time ("execution_time", &dd.execution_time),
-        TALER_JSON_spec_amount ("coin_contribution", &dd.coin_contribution),
+        TALER_JSON_spec_amount_any ("coin_contribution", 
&dd.coin_contribution),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig", &dd.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dd.exchange_pub),
         GNUNET_JSON_spec_end ()
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 6eba658f..43eac97a 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -335,16 +335,16 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey 
*denom_key,
                                    &denom_key->valid_from),
     TALER_JSON_spec_absolute_time ("stamp_expire_legal",
                                    &denom_key->expire_legal),
-    TALER_JSON_spec_amount ("value",
-                            &denom_key->value),
-    TALER_JSON_spec_amount ("fee_withdraw",
-                            &denom_key->fee_withdraw),
-    TALER_JSON_spec_amount ("fee_deposit",
-                            &denom_key->fee_deposit),
-    TALER_JSON_spec_amount ("fee_refresh",
-                            &denom_key->fee_refresh),
-    TALER_JSON_spec_amount ("fee_refund",
-                            &denom_key->fee_refund),
+    TALER_JSON_spec_amount_any ("value",
+                                &denom_key->value),
+    TALER_JSON_spec_amount_any ("fee_withdraw",
+                                &denom_key->fee_withdraw),
+    TALER_JSON_spec_amount_any ("fee_deposit",
+                                &denom_key->fee_deposit),
+    TALER_JSON_spec_amount_any ("fee_refresh",
+                                &denom_key->fee_refresh),
+    TALER_JSON_spec_amount_any ("fee_refund",
+                                &denom_key->fee_refund),
     GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                      &denom_key->key.rsa_public_key),
     GNUNET_JSON_spec_end ()
diff --git a/src/lib/exchange_api_management_get_keys.c 
b/src/lib/exchange_api_management_get_keys.c
index 925ca804..840629a1 100644
--- a/src/lib/exchange_api_management_get_keys.c
+++ b/src/lib/exchange_api_management_get_keys.c
@@ -169,8 +169,8 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
       = &fk.denom_keys[i];
     const char *section_name;
     struct GNUNET_JSON_Specification spec[] = {
-      TALER_JSON_spec_amount ("value",
-                              &denom_key->value),
+      TALER_JSON_spec_amount_any ("value",
+                                  &denom_key->value),
       TALER_JSON_spec_absolute_time ("stamp_start",
                                      &denom_key->valid_from),
       TALER_JSON_spec_absolute_time ("stamp_expire_withdraw",
@@ -181,14 +181,14 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
                                      &denom_key->expire_legal),
       GNUNET_JSON_spec_rsa_public_key ("denom_pub",
                                        &denom_key->key.rsa_public_key),
-      TALER_JSON_spec_amount ("fee_withdraw",
-                              &denom_key->fee_withdraw),
-      TALER_JSON_spec_amount ("fee_deposit",
-                              &denom_key->fee_deposit),
-      TALER_JSON_spec_amount ("fee_refresh",
-                              &denom_key->fee_refresh),
-      TALER_JSON_spec_amount ("fee_refund",
-                              &denom_key->fee_refund),
+      TALER_JSON_spec_amount_any ("fee_withdraw",
+                                  &denom_key->fee_withdraw),
+      TALER_JSON_spec_amount_any ("fee_deposit",
+                                  &denom_key->fee_deposit),
+      TALER_JSON_spec_amount_any ("fee_refresh",
+                                  &denom_key->fee_refresh),
+      TALER_JSON_spec_amount_any ("fee_refund",
+                                  &denom_key->fee_refund),
       GNUNET_JSON_spec_fixed_auto ("denom_secmod_sig",
                                    &denom_key->denom_secmod_sig),
       GNUNET_JSON_spec_string ("section_name",
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index c3e59905..1f369c11 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -220,8 +220,8 @@ verify_melt_signature_spend_conflict (struct 
TALER_EXCHANGE_MeltHandle *mh,
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_json ("history", &history),
     GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
-    TALER_JSON_spec_amount ("original_value", &original_value),
-    TALER_JSON_spec_amount ("requested_value", &melt_value_with_fee),
+    TALER_JSON_spec_amount_any ("original_value", &original_value),
+    TALER_JSON_spec_amount_any ("requested_value", &melt_value_with_fee),
     GNUNET_JSON_spec_end ()
   };
   const struct MeltedCoin *mc;
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index f991c5f5..2ac612db 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -176,8 +176,8 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
     struct TALER_Amount amount;
     const char *type;
     struct GNUNET_JSON_Specification spec_glob[] = {
-      TALER_JSON_spec_amount ("amount",
-                              &amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &amount),
       GNUNET_JSON_spec_string ("type",
                                &type),
       GNUNET_JSON_spec_end ()
@@ -215,8 +215,8 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                            &dr.wallet_timestamp),
         TALER_JSON_spec_absolute_time_nbo ("refund_deadline",
                                            &dr.refund_deadline),
-        TALER_JSON_spec_amount_nbo ("deposit_fee",
-                                    &dr.deposit_fee),
+        TALER_JSON_spec_amount_any_nbo ("deposit_fee",
+                                        &dr.deposit_fee),
         GNUNET_JSON_spec_fixed_auto ("merchant_pub",
                                      &dr.merchant),
         GNUNET_JSON_spec_end ()
@@ -283,8 +283,8 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
         .coin_pub = rh->depconf.coin_pub
       };
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount ("refund_fee",
-                                &refund_fee),
+        TALER_JSON_spec_amount_any ("refund_fee",
+                                    &refund_fee),
         GNUNET_JSON_spec_fixed_auto ("merchant_sig",
                                      &sig),
         GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
@@ -452,12 +452,12 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
     };
     uint64_t rtransaction_id;
     struct GNUNET_JSON_Specification spec[] = {
-      TALER_JSON_spec_amount ("amount",
-                              &amount),
+      TALER_JSON_spec_amount_any ("amount",
+                                  &amount),
       GNUNET_JSON_spec_string ("type",
                                &type),
-      TALER_JSON_spec_amount ("refund_fee",
-                              &refund_fee),
+      TALER_JSON_spec_amount_any ("refund_fee",
+                                  &refund_fee),
       GNUNET_JSON_spec_fixed_auto ("merchant_sig",
                                    &sig),
       GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
diff --git a/src/lib/exchange_api_reserves_get.c 
b/src/lib/exchange_api_reserves_get.c
index 8977495e..563deeaf 100644
--- a/src/lib/exchange_api_reserves_get.c
+++ b/src/lib/exchange_api_reserves_get.c
@@ -88,7 +88,7 @@ handle_reserves_get_ok (struct 
TALER_EXCHANGE_ReservesGetHandle *rgh,
   struct TALER_Amount balance;
   struct TALER_Amount balance_from_history;
   struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("balance", &balance),
+    TALER_JSON_spec_amount_any ("balance", &balance),
     GNUNET_JSON_spec_end ()
   };
   struct TALER_EXCHANGE_HttpResponse hr = {
diff --git a/src/lib/exchange_api_transfers_get.c 
b/src/lib/exchange_api_transfers_get.c
index a3a82368..1f6e419c 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -89,8 +89,8 @@ check_transfers_get_response_ok (
   struct TALER_Amount total_expected;
   struct TALER_MerchantPublicKeyP merchant_pub;
   struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("total", &td.total_amount),
-    TALER_JSON_spec_amount ("wire_fee", &td.wire_fee),
+    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_wire", &td.h_wire),
     TALER_JSON_spec_absolute_time ("execution_time", &td.execution_time),
@@ -146,8 +146,8 @@ check_transfers_get_response_ok (
         GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
                                      &detail->h_contract_terms),
         GNUNET_JSON_spec_fixed_auto ("coin_pub", &detail->coin_pub),
-        TALER_JSON_spec_amount ("deposit_value", &detail->coin_value),
-        TALER_JSON_spec_amount ("deposit_fee", &detail->coin_fee),
+        TALER_JSON_spec_amount_any ("deposit_value", &detail->coin_value),
+        TALER_JSON_spec_amount_any ("deposit_fee", &detail->coin_fee),
         GNUNET_JSON_spec_end ()
       };
 
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index 4586d2ea..5d5a0f4a 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -143,10 +143,10 @@ parse_fees (json_t *fees)
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_fixed_auto ("sig",
                                      &wa->master_sig),
-        TALER_JSON_spec_amount ("wire_fee",
-                                &wa->wire_fee),
-        TALER_JSON_spec_amount ("closing_fee",
-                                &wa->closing_fee),
+        TALER_JSON_spec_amount_any ("wire_fee",
+                                    &wa->wire_fee),
+        TALER_JSON_spec_amount_any ("closing_fee",
+                                    &wa->closing_fee),
         TALER_JSON_spec_absolute_time ("start_date",
                                        &wa->start_date),
         TALER_JSON_spec_absolute_time ("end_date",
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index 585cd921..6adf8552 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -152,7 +152,7 @@ reserve_withdraw_payment_required (
   json_t *history;
   size_t len;
   struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("balance", &balance),
+    TALER_JSON_spec_amount_any ("balance", &balance),
     GNUNET_JSON_spec_end ()
   };
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]