From b5cba3251053c22bf1df46282f1dd0a4c46f6a38 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 1 Mar 2016 15:35:04 +0100 Subject: renaming mint->exchange --- src/wire/plugin_wire_sepa.c | 4 ++-- src/wire/plugin_wire_template.c | 4 ++-- src/wire/plugin_wire_test.c | 4 ++-- src/wire/test_sepa_wireformat.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/wire') diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c index 00d19d4b0..4d902f962 100644 --- a/src/wire/plugin_wire_sepa.c +++ b/src/wire/plugin_wire_sepa.c @@ -501,12 +501,12 @@ libtaler_plugin_wire_sepa_init (void *cls) sc = GNUNET_new (struct SepaClosure); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, - "mint", + "exchange", "CURRENCY", &sc->currency)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mint", + "exchange", "CURRENCY"); GNUNET_free (sc); return NULL; diff --git a/src/wire/plugin_wire_template.c b/src/wire/plugin_wire_template.c index baf0ee7d5..2e9512e57 100644 --- a/src/wire/plugin_wire_template.c +++ b/src/wire/plugin_wire_template.c @@ -197,12 +197,12 @@ libtaler_plugin_wire_template_init (void *cls) } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, - "mint", + "exchange", "CURRENCY", &tc->currency)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mint", + "exchange", "CURRENCY"); GNUNET_free (tc->bank_uri); GNUNET_free (tc); diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 8a6f98ea2..2f679bbaa 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -553,12 +553,12 @@ libtaler_plugin_wire_test_init (void *cls) tc = GNUNET_new (struct TestClosure); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, - "mint", + "exchange", "CURRENCY", &tc->currency)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mint", + "exchange", "CURRENCY"); GNUNET_free (uri); GNUNET_free (tc); diff --git a/src/wire/test_sepa_wireformat.c b/src/wire/test_sepa_wireformat.c index edbe5bc45..5081cbe86 100644 --- a/src/wire/test_sepa_wireformat.c +++ b/src/wire/test_sepa_wireformat.c @@ -77,7 +77,7 @@ main(int argc, NULL); cfg = GNUNET_CONFIGURATION_create (); GNUNET_CONFIGURATION_set_value_string (cfg, - "mint", + "exchange", "currency", "EUR"); plugin = TALER_WIRE_plugin_load (cfg, -- cgit v1.2.3 From 531272a92a5aa08559436138ff5106a6bff1b361 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 2 Mar 2016 21:02:46 +0100 Subject: towards fixing #4230 --- src/bank-lib/bank_api_admin.c | 13 ++++++++----- src/bank-lib/test_bank_api.c | 15 +++++++++++---- src/include/taler_bank_service.h | 6 ++++-- src/wire/plugin_wire_test.c | 20 ++++++-------------- 4 files changed, 29 insertions(+), 25 deletions(-) (limited to 'src/wire') diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c index bfcf16a23..5deb4aa72 100644 --- a/src/bank-lib/bank_api_admin.c +++ b/src/bank-lib/bank_api_admin.c @@ -150,7 +150,8 @@ handle_admin_add_incoming_finished (void *cls, * @param reserve_pub public key of the reserve * @param amount amount that was deposited * @param execution_date when did we receive the amount - * @param account_no account number (53 bits at most) + * @param debit_account_no account number to withdraw from (53 bits at most) + * @param credit_account_no account number to deposit into (53 bits at most) * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return NULL @@ -161,7 +162,8 @@ struct TALER_BANK_AdminAddIncomingHandle * TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *amount, - uint64_t account_no, + uint64_t debit_account_no, + uint64_t credit_account_no, TALER_BANK_AdminAddIncomingResultCallback res_cb, void *res_cb_cls) { @@ -169,12 +171,13 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, json_t *admin_obj; CURL *eh; - admin_obj = json_pack ("{s:o, s:o," /* reserve_pub/amount */ - " s:I}", /* execution_Date/wire */ + admin_obj = json_pack ("{s:o, s:o," + " s:I, s:I}", "wtid", TALER_json_from_data (wtid, sizeof (*wtid)), "amount", TALER_json_from_amount (amount), - "account", (json_int_t) account_no); + "debit_account", (json_int_t) debit_account_no, + "credit_account", (json_int_t) credit_account_no); aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle); aai->bank = bank; aai->cb = res_cb; diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c index b14f523ba..5e38ae2ec 100644 --- a/src/bank-lib/test_bank_api.c +++ b/src/bank-lib/test_bank_api.c @@ -103,9 +103,14 @@ struct Command const char *amount; /** - * Account number. + * Credited account number. */ - uint64_t account_no; + uint64_t credit_account_no; + + /** + * Debited account number. + */ + uint64_t debit_account_no; /** * Wire transfer identifier to use. Initialized to @@ -310,7 +315,8 @@ interpreter_run (void *cls, = TALER_BANK_admin_add_incoming (ctx, &cmd->details.admin_add_incoming.wtid, &amount, - cmd->details.admin_add_incoming.account_no, + cmd->details.admin_add_incoming.debit_account_no, + cmd->details.admin_add_incoming.credit_account_no, &add_incoming_cb, is); if (NULL == cmd->details.admin_add_incoming.aih) @@ -470,7 +476,8 @@ run (void *cls, { .oc = OC_ADMIN_ADD_INCOMING, .label = "deposit-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.account_no = 42, + .details.admin_add_incoming.credit_account_no = 1, + .details.admin_add_incoming.debit_account_no = 2, .details.admin_add_incoming.amount = "EUR:5.01" }, { .oc = OC_END } diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h index a4f33fc97..508ca714b 100644 --- a/src/include/taler_bank_service.h +++ b/src/include/taler_bank_service.h @@ -133,7 +133,8 @@ typedef void * @param reserve_pub public key of the reserve * @param amount amount that was deposited * @param execution_date when did we receive the amount - * @param account_no account number (53 bits at most) + * @param debit_account_no account number to withdraw from (53 bits at most) + * @param credit_account_no account number to deposit into (53 bits at most) * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return NULL @@ -144,7 +145,8 @@ struct TALER_BANK_AdminAddIncomingHandle * TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *amount, - uint64_t account_no, + uint64_t debit_account_no, + uint64_t credit_account_no, TALER_BANK_AdminAddIncomingResultCallback res_cb, void *res_cb_cls); diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 8a6f98ea2..d6bf411c1 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -43,6 +43,11 @@ struct TestClosure */ char *currency; + /** + * Number of the account that the exchange has at the bank. + */ + uint64_t exchange_account_no; + /** * Handle to the bank task, or NULL. */ @@ -482,7 +487,7 @@ test_execute_wire_transfer (void *cls, GNUNET_break (0); return NULL; } - + eh = GNUNET_new (struct TALER_WIRE_ExecuteHandle); eh->cc = cc; eh->cc_cls = cc_cls; @@ -551,19 +556,6 @@ libtaler_plugin_wire_test_init (void *cls) return NULL; } tc = GNUNET_new (struct TestClosure); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "mint", - "CURRENCY", - &tc->currency)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "mint", - "CURRENCY"); - GNUNET_free (uri); - GNUNET_free (tc); - return NULL; - } tc->bank = TALER_BANK_init (uri); if (NULL == tc->bank) { -- cgit v1.2.3 From d06fb4d8182e5213e6d59cf0c5fe2c8d4c4cef36 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 4 Mar 2016 11:43:11 +0100 Subject: towards returning account numbers in /wire/test --- .../exchange-template/config/exchange-common.conf | 4 +-- .../test-exchange-home/config/exchange-common.conf | 2 +- src/exchange/taler-exchange-httpd_wire.c | 37 ++++++++++++++-------- src/wire/plugin_wire_test.c | 6 ++-- 4 files changed, 30 insertions(+), 19 deletions(-) (limited to 'src/wire') diff --git a/contrib/exchange-template/config/exchange-common.conf b/contrib/exchange-template/config/exchange-common.conf index 5214fd816..183ae47ad 100644 --- a/contrib/exchange-template/config/exchange-common.conf +++ b/contrib/exchange-template/config/exchange-common.conf @@ -25,5 +25,5 @@ DB_CONN_STR = "postgres:///talercheck" SEPA_RESPONSE_FILE = "sepa.json" [wire-test] -REDIRECT_URL = "http://test/" -BANK_URI = "http://bank/ +BANK_URI = "http://bank/" +BANK_ACCOUNT_NUMBER = 1 diff --git a/src/exchange-lib/test-exchange-home/config/exchange-common.conf b/src/exchange-lib/test-exchange-home/config/exchange-common.conf index 9e46fcb3b..35711a8f3 100644 --- a/src/exchange-lib/test-exchange-home/config/exchange-common.conf +++ b/src/exchange-lib/test-exchange-home/config/exchange-common.conf @@ -26,5 +26,5 @@ DB_CONN_STR = "postgres:///talercheck" SEPA_RESPONSE_FILE = "test-exchange-home/sepa.json" [wire-test] -REDIRECT_URL = "http://www.taler.net/" BANK_URI = "http://localhost/" +BANK_ACCOUNT_NUMBER = 1 diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index faf018b99..0d1e3f3f1 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 GNUnet e.V. + Copyright (C) 2015, 2016 GNUnet e.V. and INRIA 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 @@ -83,7 +83,8 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh, { struct MHD_Response *response; int ret; - char *wire_test_redirect; + char *bank_uri; + unsigned long long account_number; response = MHD_create_response_from_buffer (0, NULL, MHD_RESPMEM_PERSISTENT); @@ -105,22 +106,32 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "wire-test", - "REDIRECT_URL", - &wire_test_redirect)) + "BANK_URI", + &bank_uri)) { /* oopsie, configuration error */ MHD_destroy_response (response); return TMH_RESPONSE_reply_internal_error (connection, - "REDIRECT_URL not configured"); + "BANK_URI not configured"); } - MHD_add_response_header (response, - MHD_HTTP_HEADER_LOCATION, - wire_test_redirect); - GNUNET_free (wire_test_redirect); - ret = MHD_queue_response (connection, - rh->response_code, - response); - MHD_destroy_response (response); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "wire-test", + "BANK_ACCOUNT_NUMBER", + &account_number)) + { + /* oopsie, configuration error */ + MHD_destroy_response (response); + return TMH_RESPONSE_reply_internal_error (connection, + "BANK_URI not configured"); + } + ret = TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s, s:I, s:s}", + "type", "test", + "account_number", (json_int_t) account_number, + "bank_uri", bank_uri); + GNUNET_free (bank_uri); return ret; } diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 2f679bbaa..98d9281ce 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -482,7 +482,7 @@ test_execute_wire_transfer (void *cls, GNUNET_break (0); return NULL; } - + eh = GNUNET_new (struct TALER_WIRE_ExecuteHandle); eh->cc = cc; eh->cc_cls = cc_cls; @@ -542,12 +542,12 @@ libtaler_plugin_wire_test_init (void *cls) if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "wire-test", - "bank_uri", + "BANK_URI", &uri)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "wire-test", - "bank_uri"); + "BANK_URI"); return NULL; } tc = GNUNET_new (struct TestClosure); -- cgit v1.2.3 From 0d1eced630f4ed05ad95fdbb4354fd428c9cdbf6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 19 Mar 2016 15:23:11 +0100 Subject: first refactoring of JSON logic to address #4150 and #4237 --- configure.ac | 11 +- src/Makefile.am | 2 +- src/bank-lib/Makefile.am | 3 +- src/bank-lib/bank_api_admin.c | 7 +- src/bank-lib/bank_api_context.h | 1 + src/bank-lib/bank_api_json.c | 525 ------------------------- src/bank-lib/bank_api_json.h | 352 ----------------- src/exchange-lib/Makefile.am | 4 + src/exchange-lib/exchange_api_admin.c | 10 +- src/exchange-lib/exchange_api_deposit.c | 28 +- src/exchange-lib/exchange_api_deposit_wtid.c | 11 +- src/exchange-lib/exchange_api_json.c | 42 +- src/exchange-lib/exchange_api_refresh.c | 26 +- src/exchange-lib/exchange_api_reserve.c | 9 +- src/exchange-lib/exchange_api_wire.c | 146 ++----- src/exchange-lib/exchange_api_wire_deposits.c | 1 + src/exchange-lib/test-exchange-home/sepa.json | 9 +- src/exchange-lib/test_exchange_api.c | 27 +- src/exchange-tools/Makefile.am | 4 +- src/exchange-tools/taler-exchange-keyup.c | 14 +- src/exchange-tools/taler-exchange-sepa.c | 38 +- src/exchange/Makefile.am | 5 +- src/exchange/taler-exchange-aggregator.c | 3 +- src/exchange/taler-exchange-httpd.c | 4 +- src/exchange/taler-exchange-httpd.h | 2 +- src/exchange/taler-exchange-httpd_db.c | 10 +- src/exchange/taler-exchange-httpd_deposit.c | 4 +- src/exchange/taler-exchange-httpd_keystate.c | 49 +-- src/exchange/taler-exchange-httpd_parsing.c | 19 +- src/exchange/taler-exchange-httpd_responses.c | 90 ++--- src/exchange/taler-exchange-httpd_test.c | 19 +- src/exchange/taler-exchange-httpd_validation.c | 5 +- src/exchange/taler-exchange-httpd_wire.c | 5 +- src/include/taler_exchange_service.h | 23 +- src/include/taler_exchangedb_plugin.h | 1 + src/include/taler_json_lib.h | 127 +----- src/include/taler_pq_lib.h | 1 + src/include/taler_util.h | 26 -- src/include/taler_wire_plugin.h | 6 +- src/json/Makefile.am | 38 ++ src/json/json.c | 53 +++ src/json/json_helper.c | 146 +++++++ src/json/test_json.c | 71 ++++ src/pq/pq_result_helper.c | 25 +- src/util/Makefile.am | 20 +- src/util/json.c | 400 ------------------- src/util/test_json.c | 182 --------- src/util/util.c | 42 +- src/util/wireformats.c | 441 --------------------- src/wire/Makefile.am | 3 +- src/wire/plugin_wire_sepa.c | 151 +++++-- src/wire/plugin_wire_template.c | 6 +- src/wire/plugin_wire_test.c | 119 +++--- src/wire/test_sepa_wireformat.c | 40 +- 54 files changed, 884 insertions(+), 2522 deletions(-) delete mode 100644 src/bank-lib/bank_api_json.c delete mode 100644 src/bank-lib/bank_api_json.h create mode 100644 src/json/Makefile.am create mode 100644 src/json/json.c create mode 100644 src/json/json_helper.c create mode 100644 src/json/test_json.c delete mode 100644 src/util/json.c delete mode 100644 src/util/test_json.c delete mode 100644 src/util/wireformats.c (limited to 'src/wire') diff --git a/configure.ac b/configure.ac index 6004a7d66..bd8ad9f50 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ # AC_PREREQ([2.69]) AC_INIT([taler-exchange], [0.0.0], [taler-bug@gnunet.org]) -AC_CONFIG_SRCDIR([src/util/json.c]) +AC_CONFIG_SRCDIR([src/util/util.c]) AC_CONFIG_HEADERS([taler_config.h]) # support for non-recursive builds AM_INIT_AUTOMAKE([subdir-objects]) @@ -354,14 +354,15 @@ AC_CONFIG_FILES([Makefile doc/Makefile doc/doxygen/Makefile src/Makefile - src/include/Makefile - src/util/Makefile - src/pq/Makefile src/bank-lib/Makefile - src/wire/Makefile src/exchangedb/Makefile src/exchange/Makefile src/exchange-tools/Makefile src/exchange-lib/Makefile + src/include/Makefile + src/json/Makefile + src/pq/Makefile + src/util/Makefile + src/wire/Makefile ]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 37c902e65..6e0fb2049 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ if WALLET_ONLY SUBDIRS = include util else -SUBDIRS = include util $(PQ_DIR) $(BANK_LIB) wire exchangedb exchange exchange-tools +SUBDIRS = include util json $(PQ_DIR) $(BANK_LIB) wire exchangedb exchange exchange-tools if HAVE_LIBCURL SUBDIRS += exchange-lib else diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am index 2f44adada..4cf3472ec 100644 --- a/src/bank-lib/Makefile.am +++ b/src/bank-lib/Makefile.am @@ -15,10 +15,11 @@ libtalerbank_la_LDFLAGS = \ libtalerbank_la_SOURCES = \ bank_api_context.c bank_api_context.h \ - bank_api_json.c bank_api_json.h \ bank_api_admin.c libtalerbank_la_LIBADD = \ + $(top_builddir)/src/json/libtalerjson.la \ + -lgnunetjson \ -lgnunetutil \ -ljansson \ $(XLIB) diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c index 5deb4aa72..443f24a8a 100644 --- a/src/bank-lib/bank_api_admin.c +++ b/src/bank-lib/bank_api_admin.c @@ -24,8 +24,9 @@ #include #include /* just for HTTP status codes */ #include +#include #include "taler_bank_service.h" -#include "bank_api_json.h" +#include "taler_json_lib.h" #include "bank_api_context.h" #include "taler_signatures.h" @@ -173,9 +174,9 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, admin_obj = json_pack ("{s:o, s:o," " s:I, s:I}", - "wtid", TALER_json_from_data (wtid, + "wtid", GNUNET_JSON_from_data (wtid, sizeof (*wtid)), - "amount", TALER_json_from_amount (amount), + "amount", TALER_JSON_from_amount (amount), "debit_account", (json_int_t) debit_account_no, "credit_account", (json_int_t) credit_account_no); aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle); diff --git a/src/bank-lib/bank_api_context.h b/src/bank-lib/bank_api_context.h index 552cbe440..1f21cb8d2 100644 --- a/src/bank-lib/bank_api_context.h +++ b/src/bank-lib/bank_api_context.h @@ -21,6 +21,7 @@ * @author Christian Grothoff */ #include "platform.h" +#include #include #include #include "taler_bank_service.h" diff --git a/src/bank-lib/bank_api_json.c b/src/bank-lib/bank_api_json.c deleted file mode 100644 index 2a09e5272..000000000 --- a/src/bank-lib/bank_api_json.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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 - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, If not, see -*/ -/** - * @file bank-lib/bank_api_json.c - * @brief functions to parse incoming requests (JSON snippets) - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include "bank_api_json.h" - -/** - * Navigate and parse data in a JSON tree. - * - * @param root the JSON node to start the navigation at. - * @param spec parse specification array - * @return offset in @a spec where parsing failed, -1 on success (!) - */ -static int -parse_json (json_t *root, - struct BAJ_Specification *spec) -{ - int i; - json_t *pos; /* what's our current position? */ - - pos = root; - for (i=0;BAJ_CMD_END != spec[i].cmd;i++) - { - pos = json_object_get (root, - spec[i].field); - if (NULL == pos) - { - GNUNET_break_op (0); - return i; - } - switch (spec[i].cmd) - { - case BAJ_CMD_END: - GNUNET_assert (0); - return i; - case BAJ_CMD_AMOUNT: - if (GNUNET_OK != - TALER_json_to_amount (pos, - spec[i].details.amount)) - { - GNUNET_break_op (0); - return i; - } - break; - case BAJ_CMD_TIME_ABSOLUTE: - if (GNUNET_OK != - TALER_json_to_abs (pos, - spec[i].details.abs_time)) - { - GNUNET_break_op (0); - return i; - } - break; - - case BAJ_CMD_STRING: - { - const char *str; - - str = json_string_value (pos); - if (NULL == str) - { - GNUNET_break_op (0); - return i; - } - *spec[i].details.strptr = str; - } - break; - - case BAJ_CMD_BINARY_FIXED: - { - const char *str; - int res; - - str = json_string_value (pos); - if (NULL == str) - { - GNUNET_break_op (0); - return i; - } - res = GNUNET_STRINGS_string_to_data (str, strlen (str), - spec[i].details.fixed_data.dest, - spec[i].details.fixed_data.dest_size); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - return i; - } - } - break; - - case BAJ_CMD_BINARY_VARIABLE: - { - const char *str; - size_t size; - void *data; - int res; - - str = json_string_value (pos); - if (NULL == str) - { - GNUNET_break_op (0); - return i; - } - size = (strlen (str) * 5) / 8; - if (size >= 1024) - { - GNUNET_break_op (0); - return i; - } - data = GNUNET_malloc (size); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - data, - size); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - GNUNET_free (data); - return i; - } - *spec[i].details.variable_data.dest_p = data; - *spec[i].details.variable_data.dest_size_p = size; - } - break; - - case BAJ_CMD_RSA_PUBLIC_KEY: - { - size_t size; - const char *str; - int res; - void *buf; - - str = json_string_value (pos); - if (NULL == str) - { - GNUNET_break_op (0); - return i; - } - size = (strlen (str) * 5) / 8; - buf = GNUNET_malloc (size); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - buf, - size); - if (GNUNET_OK != res) - { - GNUNET_free (buf); - GNUNET_break_op (0); - return i; - } - *spec[i].details.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_decode (buf, - size); - GNUNET_free (buf); - if (NULL == spec[i].details.rsa_public_key) - { - GNUNET_break_op (0); - return i; - } - } - break; - - case BAJ_CMD_RSA_SIGNATURE: - { - size_t size; - const char *str; - int res; - void *buf; - - str = json_string_value (pos); - if (NULL == str) - { - GNUNET_break_op (0); - return i; - } - size = (strlen (str) * 5) / 8; - buf = GNUNET_malloc (size); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - buf, - size); - if (GNUNET_OK != res) - { - GNUNET_free (buf); - GNUNET_break_op (0); - return i; - } - *spec[i].details.rsa_signature - = GNUNET_CRYPTO_rsa_signature_decode (buf, - size); - GNUNET_free (buf); - if (NULL == spec[i].details.rsa_signature) - return i; - } - break; - - case BAJ_CMD_UINT16: - { - json_int_t val; - - if (! json_is_integer (pos)) - { - GNUNET_break_op (0); - return i; - } - val = json_integer_value (pos); - if ( (0 > val) || (val > UINT16_MAX) ) - { - GNUNET_break_op (0); - return i; - } - *spec[i].details.u16 = (uint16_t) val; - } - break; - - case BAJ_CMD_UINT64: - { - json_int_t val; - - if (! json_is_integer (pos)) - { - GNUNET_break_op (0); - return i; - } - val = json_integer_value (pos); - *spec[i].details.u64 = (uint64_t) val; - } - break; - - case BAJ_CMD_JSON_OBJECT: - { - if (! (json_is_object (pos) || json_is_array (pos)) ) - { - GNUNET_break_op (0); - return i; - } - json_incref (pos); - *spec[i].details.obj = pos; - } - break; - - default: - GNUNET_break (0); - return i; - } - } - return -1; /* all OK! */ -} - - -/** - * Free all elements allocated during a - * #BAJ_parse_json() operation. - * - * @param spec specification of the parse operation - * @param end number of elements in @a spec to process - */ -static void -parse_free (struct BAJ_Specification *spec, - int end) -{ - int i; - - for (i=0;i -*/ -/** - * @file exchange-lib/exchange_api_json.h - * @brief functions to parse incoming requests (JSON snippets) - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include "taler_util.h" -#include - - -/** - * Enumeration with the various commands for the - * #BAJ_parse_json interpreter. - */ -enum BAJ_Command -{ - - /** - * End of command list. - */ - BAJ_CMD_END, - - /** - * Parse amount at current position. - */ - BAJ_CMD_AMOUNT, - - /** - * Parse absolute time at current position. - */ - BAJ_CMD_TIME_ABSOLUTE, - - /** - * Parse fixed binary value at current position. - */ - BAJ_CMD_BINARY_FIXED, - - /** - * Parse variable-size binary value at current position. - */ - BAJ_CMD_BINARY_VARIABLE, - - /** - * Parse RSA public key at current position. - */ - BAJ_CMD_RSA_PUBLIC_KEY, - - /** - * Parse RSA signature at current position. - */ - BAJ_CMD_RSA_SIGNATURE, - - /** - * Parse `const char *` JSON string at current position. - */ - BAJ_CMD_STRING, - - /** - * Parse `uint16_t` integer at the current position. - */ - BAJ_CMD_UINT16, - - /** - * Parse `uint64_t` integer at the current position. - */ - BAJ_CMD_UINT64, - - /** - * Parse JSON object at the current position. - */ - BAJ_CMD_JSON_OBJECT, - - /** - * Parse ??? at current position. - */ - BAJ_CMD_C - -}; - - -/** - * @brief Entry in parser specification for #BAJ_parse_json. - */ -struct BAJ_Specification -{ - - /** - * Command to execute. - */ - enum BAJ_Command cmd; - - /** - * Name of the field to access. - */ - const char *field; - - /** - * Further details for the command. - */ - union { - - /** - * Where to store amount for #BAJ_CMD_AMOUNT. - */ - struct TALER_Amount *amount; - - /** - * Where to store time, for #BAJ_CMD_TIME_ABSOLUTE. - */ - struct GNUNET_TIME_Absolute *abs_time; - - /** - * Where to write binary data, for #BAJ_CMD_BINARY_FIXED. - */ - struct { - /** - * Where to write the data. - */ - void *dest; - - /** - * How many bytes to write to @e dest. - */ - size_t dest_size; - - } fixed_data; - - /** - * Where to write binary data, for #BAJ_CMD_BINARY_VARIABLE. - */ - struct { - /** - * Where to store the pointer with the data (is allocated). - */ - void **dest_p; - - /** - * Where to store the number of bytes allocated at `*dest`. - */ - size_t *dest_size_p; - - } variable_data; - - /** - * Where to store the RSA public key for #BAJ_CMD_RSA_PUBLIC_KEY - */ - struct GNUNET_CRYPTO_rsa_PublicKey **rsa_public_key; - - /** - * Where to store the RSA signature for #BAJ_CMD_RSA_SIGNATURE - */ - struct GNUNET_CRYPTO_rsa_Signature **rsa_signature; - - /** - * Details for #BAJ_CMD_EDDSA_SIGNATURE - */ - struct { - - /** - * Where to store the purpose. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p; - - /** - * Key to verify the signature against. - */ - const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key; - - } eddsa_signature; - - /** - * Where to store a pointer to the string. - */ - const char **strptr; - - /** - * Where to store 16-bit integer. - */ - uint16_t *u16; - - /** - * Where to store 64-bit integer. - */ - uint64_t *u64; - - /** - * Where to store a JSON object. - */ - json_t **obj; - - } details; - -}; - - -/** - * Navigate and parse data in a JSON tree. - * - * @param root the JSON node to start the navigation at. - * @param spec parse specification array - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -int -BAJ_parse_json (const json_t *root, - struct BAJ_Specification *spec); - - -/** - * Free all elements allocated during a - * #BAJ_parse_json() operation. - * - * @param spec specification of the parse operation - */ -void -BAJ_parse_free (struct BAJ_Specification *spec); - - -/** - * End of a parser specification. - */ -#define BAJ_spec_end { .cmd = BAJ_CMD_END } - -/** - * Fixed size object (in network byte order, encoded using Crockford - * Base32hex encoding). - * - * @param name name of the JSON field - * @param obj pointer where to write the data (type of `*obj` will determine size) - */ -#define BAJ_spec_fixed_auto(name,obj) { .cmd = BAJ_CMD_BINARY_FIXED, .field = name, .details.fixed_data.dest = obj, .details.fixed_data.dest_size = sizeof (*obj) } - - -/** - * Variable size object (in network byte order, encoded using Crockford - * Base32hex encoding). - * - * @param name name of the JSON field - * @param obj pointer where to write the data (a `void **`) - * @param size where to store the number of bytes allocated for @a obj (of type `size_t *` - */ -#define BAJ_spec_varsize(name,obj,size) { .cmd = BAJ_CMD_BINARY_VARIABLE, .field = name, .details.variable_data.dest_p = obj, .details.variable_data.dest_size_p = size } - - -/** - * The expected field stores a string. - * - * @param name name of the JSON field - * @param strptr where to store a pointer to the field - */ -struct BAJ_Specification -BAJ_spec_string (const char *name, - const char **strptr); - - -/** - * Absolute time. - * - * @param name name of the JSON field - * @param[out] at where to store the absolute time found under @a name - */ -struct BAJ_Specification -BAJ_spec_absolute_time (const char *name, - struct GNUNET_TIME_Absolute *at); - - -/** - * 16-bit integer. - * - * @param name name of the JSON field - * @param[out] u16 where to store the integer found under @a name - */ -struct BAJ_Specification -BAJ_spec_uint16 (const char *name, - uint16_t *u16); - - -/** - * 64-bit integer. - * - * @param name name of the JSON field - * @param[out] u64 where to store the integer found under @a name - */ -struct BAJ_Specification -BAJ_spec_uint64 (const char *name, - uint64_t *u64); - - -/** - * JSON object. - * - * @param name name of the JSON field - * @param[out] jsonp where to store the JSON found under @a name - */ -struct BAJ_Specification -BAJ_spec_json (const char *name, - json_t **jsonp); - - -/** - * Specification for parsing an amount value. - * - * @param name name of the JSON field - * @param amount where to store the amount under @a name - */ -struct BAJ_Specification -BAJ_spec_amount (const char *name, - struct TALER_Amount *amount); - - -/** - * Specification for parsing an RSA public key. - * - * @param name name of the JSON field - * @param pk where to store the RSA key found under @a name - */ -struct BAJ_Specification -BAJ_spec_rsa_public_key (const char *name, - struct GNUNET_CRYPTO_rsa_PublicKey **pk); - - -/** - * Specification for parsing an RSA signature. - * - * @param name name of the JSON field - * @param sig where to store the RSA signature found under @a name - */ -struct BAJ_Specification -BAJ_spec_rsa_signature (const char *name, - struct GNUNET_CRYPTO_rsa_Signature **sig); - - - - -/* end of exchange_api_json.h */ diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 6d5e842be..a043e8601 100644 --- a/src/exchange-lib/Makefile.am +++ b/src/exchange-lib/Makefile.am @@ -28,6 +28,9 @@ libtalerexchange_la_SOURCES = \ exchange_api_wire_deposits.c libtalerexchange_la_LIBADD = \ + $(top_builddir)/src/json/libtalerjson.la \ + $(top_builddir)/src/util/libtalerutil.la \ + -lgnunetjson \ -lgnunetutil \ -ljansson \ $(XLIB) @@ -51,6 +54,7 @@ test_exchange_api_SOURCES = \ test_exchange_api_LDADD = \ libtalerexchange.la \ $(LIBGCRYPT_LIBS) \ + $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil \ -ljansson diff --git a/src/exchange-lib/exchange_api_admin.c b/src/exchange-lib/exchange_api_admin.c index 3dcbb80e9..4ed761fb2 100644 --- a/src/exchange-lib/exchange_api_admin.c +++ b/src/exchange-lib/exchange_api_admin.c @@ -24,6 +24,8 @@ #include #include /* just for HTTP status codes */ #include +#include +#include "taler_json_lib.h" #include "taler_exchange_service.h" #include "exchange_api_json.h" #include "exchange_api_context.h" @@ -174,7 +176,7 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange, CURL *eh; GNUNET_assert (GNUNET_OK == - TALER_round_abs_time (&execution_date)); + GNUNET_TIME_round_abs (&execution_date)); if (GNUNET_YES != MAH_handle_is_ready (exchange)) { @@ -183,10 +185,10 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange, } admin_obj = json_pack ("{s:o, s:o," /* reserve_pub/amount */ " s:o, s:O}", /* execution_Date/wire */ - "reserve_pub", TALER_json_from_data (reserve_pub, + "reserve_pub", GNUNET_JSON_from_data (reserve_pub, sizeof (*reserve_pub)), - "amount", TALER_json_from_amount (amount), - "execution_date", TALER_json_from_abs (execution_date), + "amount", TALER_JSON_from_amount (amount), + "execution_date", GNUNET_JSON_from_time_abs (execution_date), "wire", wire); aai = GNUNET_new (struct TALER_EXCHANGE_AdminAddIncomingHandle); aai->exchange = exchange; diff --git a/src/exchange-lib/exchange_api_deposit.c b/src/exchange-lib/exchange_api_deposit.c index deba4877d..ef7a59e69 100644 --- a/src/exchange-lib/exchange_api_deposit.c +++ b/src/exchange-lib/exchange_api_deposit.c @@ -25,6 +25,8 @@ #include #include /* just for HTTP status codes */ #include +#include +#include "taler_json_lib.h" #include "taler_exchange_service.h" #include "exchange_api_common.h" #include "exchange_api_json.h" @@ -411,7 +413,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_HashCode h_wire; struct TALER_Amount amount_without_fee; - (void) TALER_round_abs_time (&wire_deadline); + (void) GNUNET_TIME_round_abs (&wire_deadline); if (GNUNET_YES != MAH_handle_is_ready (exchange)) { @@ -420,7 +422,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, } /* initialize h_wire */ if (GNUNET_OK != - TALER_hash_json (wire_details, + TALER_JSON_hash (wire_details, &h_wire)) { GNUNET_break (0); @@ -468,23 +470,23 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange, " s:I, s:o," /* transaction id, merchant_pub */ " s:o, s:o," /* refund_deadline, wire_deadline */ " s:o}", /* coin_sig */ - "f", TALER_json_from_amount (amount), + "f", TALER_JSON_from_amount (amount), "wire", wire_details, - "H_wire", TALER_json_from_data (&h_wire, + "H_wire", GNUNET_JSON_from_data (&h_wire, sizeof (h_wire)), - "H_contract", TALER_json_from_data (h_contract, + "H_contract", GNUNET_JSON_from_data (h_contract, sizeof (struct GNUNET_HashCode)), - "coin_pub", TALER_json_from_data (coin_pub, + "coin_pub", GNUNET_JSON_from_data (coin_pub, sizeof (*coin_pub)), - "denom_pub", TALER_json_from_rsa_public_key (denom_pub->rsa_public_key), - "ub_sig", TALER_json_from_rsa_signature (denom_sig->rsa_signature), - "timestamp", TALER_json_from_abs (timestamp), + "denom_pub", GNUNET_JSON_from_rsa_public_key (denom_pub->rsa_public_key), + "ub_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature), + "timestamp", GNUNET_JSON_from_time_abs (timestamp), "transaction_id", (json_int_t) transaction_id, - "merchant_pub", TALER_json_from_data (merchant_pub, + "merchant_pub", GNUNET_JSON_from_data (merchant_pub, sizeof (*merchant_pub)), - "refund_deadline", TALER_json_from_abs (refund_deadline), - "edate", TALER_json_from_abs (wire_deadline), - "coin_sig", TALER_json_from_data (coin_sig, + "refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline), + "edate", GNUNET_JSON_from_time_abs (wire_deadline), + "coin_sig", GNUNET_JSON_from_data (coin_sig, sizeof (*coin_sig)) ); diff --git a/src/exchange-lib/exchange_api_deposit_wtid.c b/src/exchange-lib/exchange_api_deposit_wtid.c index 83beb03ae..f3b5d2c0d 100644 --- a/src/exchange-lib/exchange_api_deposit_wtid.c +++ b/src/exchange-lib/exchange_api_deposit_wtid.c @@ -24,6 +24,7 @@ #include #include /* just for HTTP status codes */ #include +#include #include "taler_exchange_service.h" #include "exchange_api_common.h" #include "exchange_api_json.h" @@ -296,16 +297,16 @@ TALER_EXCHANGE_deposit_wtid (struct TALER_EXCHANGE_Handle *exchange, deposit_wtid_obj = json_pack ("{s:o, s:o," /* H_wire, H_contract */ " s:o, s:I," /* coin_pub, transaction_id */ " s:o, s:o}", /* merchant_pub, merchant_sig */ - "H_wire", TALER_json_from_data (h_wire, + "H_wire", GNUNET_JSON_from_data (h_wire, sizeof (struct GNUNET_HashCode)), - "H_contract", TALER_json_from_data (h_contract, + "H_contract", GNUNET_JSON_from_data (h_contract, sizeof (struct GNUNET_HashCode)), - "coin_pub", TALER_json_from_data (coin_pub, + "coin_pub", GNUNET_JSON_from_data (coin_pub, sizeof (*coin_pub)), "transaction_id", (json_int_t) transaction_id, - "merchant_pub", TALER_json_from_data (&dtp.merchant, + "merchant_pub", GNUNET_JSON_from_data (&dtp.merchant, sizeof (struct TALER_MerchantPublicKeyP)), - "merchant_sig", TALER_json_from_data (&merchant_sig, + "merchant_sig", GNUNET_JSON_from_data (&merchant_sig, sizeof (merchant_sig))); dwh = GNUNET_new (struct TALER_EXCHANGE_DepositWtidHandle); diff --git a/src/exchange-lib/exchange_api_json.c b/src/exchange-lib/exchange_api_json.c index d91feba0e..d6c54be5b 100644 --- a/src/exchange-lib/exchange_api_json.c +++ b/src/exchange-lib/exchange_api_json.c @@ -22,6 +22,7 @@ */ #include "platform.h" #include "exchange_api_json.h" +#include "taler_json_lib.h" /** * Navigate and parse data in a JSON tree. @@ -53,24 +54,39 @@ parse_json (json_t *root, GNUNET_assert (0); return i; case MAJ_CMD_AMOUNT: - if (GNUNET_OK != - TALER_json_to_amount (pos, - spec[i].details.amount)) { - GNUNET_break_op (0); - return i; + struct GNUNET_JSON_Specification nspec[] = { + TALER_JSON_spec_amount (NULL, spec[i].details.amount), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (pos, + nspec, + NULL, NULL)) + { + GNUNET_break_op (0); + return i; + } + break; } - break; case MAJ_CMD_TIME_ABSOLUTE: - if (GNUNET_OK != - TALER_json_to_abs (pos, - spec[i].details.abs_time)) { - GNUNET_break_op (0); - return i; + struct GNUNET_JSON_Specification nspec[] = { + GNUNET_JSON_spec_absolute_time (NULL, spec[i].details.abs_time), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (pos, + nspec, + NULL, NULL)) + { + GNUNET_break_op (0); + return i; + } + break; } - break; - case MAJ_CMD_STRING: { const char *str; diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 03d59ea3b..bcec13544 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -24,6 +24,8 @@ #include #include /* just for HTTP status codes */ #include +#include +#include "taler_json_lib.h" #include "taler_exchange_service.h" #include "exchange_api_common.h" #include "exchange_api_json.h" @@ -1373,17 +1375,17 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash, &confirm_sig.eddsa_signature); return json_pack ("{s:o, s:o, s:o, s:o, s:o}", "coin_pub", - TALER_json_from_data (&melt.coin_pub, + GNUNET_JSON_from_data (&melt.coin_pub, sizeof (melt.coin_pub)), "denom_pub", - TALER_json_from_rsa_public_key (mc->pub_key.rsa_public_key), + GNUNET_JSON_from_rsa_public_key (mc->pub_key.rsa_public_key), "denom_sig", - TALER_json_from_rsa_signature (mc->sig.rsa_signature), + GNUNET_JSON_from_rsa_signature (mc->sig.rsa_signature), "confirm_sig", - TALER_json_from_data (&confirm_sig, + GNUNET_JSON_from_data (&confirm_sig, sizeof (confirm_sig)), "value_with_fee", - TALER_json_from_amount (&mc->melt_amount_with_fee)); + TALER_JSON_from_amount (&mc->melt_amount_with_fee)); } @@ -1472,7 +1474,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv, &transfer_pub.ecdhe_pub); json_array_append (tmp, - TALER_json_from_data (&transfer_pub, + GNUNET_JSON_from_data (&transfer_pub, sizeof (transfer_pub))); } json_array_append (transfer_pubs, @@ -1497,7 +1499,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, &trans_sec, &els)); json_array_append (tmp, - TALER_json_from_data (&els, + GNUNET_JSON_from_data (&els, sizeof (els))); } json_array_append (secret_encs, @@ -1508,7 +1510,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, for (i=0;inum_fresh_coins;i++) { json_array_append (new_denoms, - TALER_json_from_rsa_public_key + GNUNET_JSON_from_rsa_public_key (md->fresh_pks[i].rsa_public_key)); } @@ -1533,7 +1535,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, &buf_len); GNUNET_assert (NULL != buf); json_array_append (tmp, - TALER_json_from_data (buf, + GNUNET_JSON_from_data (buf, buf_len)); GNUNET_free (buf); GNUNET_free (rle); @@ -1564,7 +1566,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, md->fresh_pks[i].rsa_public_key, &coin_ev); json_array_append (tmp, - TALER_json_from_data (coin_ev, + GNUNET_JSON_from_data (coin_ev, coin_ev_size)); GNUNET_free (coin_ev); } @@ -1975,7 +1977,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, const struct MeltedCoin *mc = &md->melted_coins[i]; json_array_append (tmp, - TALER_json_from_data (&mc->transfer_priv[j], + GNUNET_JSON_from_data (&mc->transfer_priv[j], sizeof (struct TALER_TransferPrivateKeyP))); } json_array_append (transfer_privs, @@ -1985,7 +1987,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, /* build main JSON request */ reveal_obj = json_pack ("{s:o, s:o}", "session_hash", - TALER_json_from_data (&md->melt_session_hash, + GNUNET_JSON_from_data (&md->melt_session_hash, sizeof (struct GNUNET_HashCode)), "transfer_privs", transfer_privs); diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c index e694b8d95..1237f7cbe 100644 --- a/src/exchange-lib/exchange_api_reserve.c +++ b/src/exchange-lib/exchange_api_reserve.c @@ -24,6 +24,7 @@ #include #include /* just for HTTP status codes */ #include +#include #include "taler_exchange_service.h" #include "exchange_api_json.h" #include "exchange_api_context.h" @@ -859,12 +860,12 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange, &reserve_sig.eddsa_signature)); withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */ " s:o, s:o}",/* reserve_pub and reserve_sig */ - "denom_pub", TALER_json_from_rsa_public_key (pk->key.rsa_public_key), - "coin_ev", TALER_json_from_data (coin_ev, + "denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key), + "coin_ev", GNUNET_JSON_from_data (coin_ev, coin_ev_size), - "reserve_pub", TALER_json_from_data (&wsh->reserve_pub, + "reserve_pub", GNUNET_JSON_from_data (&wsh->reserve_pub, sizeof (struct TALER_ReservePublicKeyP)), - "reserve_sig", TALER_json_from_data (&reserve_sig, + "reserve_sig", GNUNET_JSON_from_data (&reserve_sig, sizeof (reserve_sig))); GNUNET_free (coin_ev); diff --git a/src/exchange-lib/exchange_api_wire.c b/src/exchange-lib/exchange_api_wire.c index f01c5000b..35c443ff5 100644 --- a/src/exchange-lib/exchange_api_wire.c +++ b/src/exchange-lib/exchange_api_wire.c @@ -25,11 +25,11 @@ #include /* just for HTTP status codes */ #include #include "taler_exchange_service.h" +#include "taler_wire_plugin.h" #include "exchange_api_common.h" #include "exchange_api_json.h" #include "exchange_api_context.h" #include "exchange_api_handle.h" -#include "taler_signatures.h" /** @@ -82,93 +82,6 @@ struct TALER_EXCHANGE_WireHandle }; -/** - * Verify that the signature on the "200 OK" response - * for /wire/test from the exchange is valid. - * Accepts everything. - * - * @param wh wire handle - * @param json json reply with the signature - * @return #GNUNET_SYSERR if @a json is invalid, - * #GNUNET_NO if the method is unknown, - * #GNUNET_OK if the json is valid - */ -static int -verify_wire_test_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh, - json_t *json) -{ - return GNUNET_OK; -} - - -/** - * Verify that the signature on the "200 OK" response - * for /wire/sepa from the exchange is valid. - * - * @param wh wire handle - * @param json json reply with the signature - * @return #GNUNET_SYSERR if @a json is invalid, - * #GNUNET_NO if the method is unknown, - * #GNUNET_OK if the json is valid - */ -static int -verify_wire_sepa_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh, - json_t *json) -{ - struct TALER_MasterSignatureP exchange_sig; - struct TALER_MasterWireSepaDetailsPS mp; - const char *receiver_name; - const char *iban; - const char *bic; - const struct TALER_EXCHANGE_Keys *key_state; - struct GNUNET_HashContext *hc; - struct MAJ_Specification spec[] = { - MAJ_spec_fixed_auto ("sig", &exchange_sig), - MAJ_spec_string ("receiver_name", &receiver_name), - MAJ_spec_string ("iban", &iban), - MAJ_spec_string ("bic", &bic), - MAJ_spec_end - }; - - if (GNUNET_OK != - MAJ_parse_json (json, - spec)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - key_state = TALER_EXCHANGE_get_keys (wh->exchange); - mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS); - mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS)); - hc = GNUNET_CRYPTO_hash_context_start (); - GNUNET_CRYPTO_hash_context_read (hc, - receiver_name, - strlen (receiver_name) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - iban, - strlen (iban) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - bic, - strlen (bic) + 1); - GNUNET_CRYPTO_hash_context_finish (hc, - &mp.h_sepa_details); - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS, - &mp.purpose, - &exchange_sig.eddsa_signature, - &key_state->master_pub.eddsa_pub)) - { - GNUNET_break_op (0); - MAJ_parse_free (spec); - return GNUNET_SYSERR; - } - MAJ_parse_free (spec); - return GNUNET_OK; -} - - /** * Verify that the signature on the "200 OK" response * for /wire/METHOD from the exchange is valid. @@ -185,37 +98,33 @@ verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh, const char *method, json_t *json) { - struct - { - /** - * Name fo the method. - */ - const char *method; - - /** - * Handler to invoke to verify signature. - * - * @param wh wire handle with key material - * @param json json reply with signature to verify - */ - int (*handler)(const struct TALER_EXCHANGE_WireHandle *wh, - json_t *json); - } handlers[] = { - { "test", &verify_wire_test_signature_ok }, - { "sepa", &verify_wire_sepa_signature_ok }, - { NULL, NULL } - }; - unsigned int i; + const struct TALER_EXCHANGE_Keys *key_state; + struct TALER_WIRE_Plugin *plugin; + char *lib_name; + int ret; - for (i=0;NULL != handlers[i].method; i++) - if (0 == strcasecmp (handlers[i].method, - method)) - return handlers[i].handler (wh, - json); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Wire transfer method `%s' not supported\n", - method); - return GNUNET_NO; + key_state = TALER_EXCHANGE_get_keys (wh->exchange); + (void) GNUNET_asprintf (&lib_name, + "libtaler_plugin_wire_%s", + method); + plugin = GNUNET_PLUGIN_load (lib_name, + NULL); + if (NULL == plugin) + { + GNUNET_free (lib_name); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Wire transfer method `%s' not supported\n", + method); + return GNUNET_NO; + } + plugin->library_name = lib_name; + ret = plugin->wire_validate (plugin->cls, + json, + &key_state->master_pub); + GNUNET_PLUGIN_unload (lib_name, + plugin); + GNUNET_free (lib_name); + return (GNUNET_YES == ret) ? GNUNET_OK : GNUNET_SYSERR; } @@ -312,6 +221,7 @@ handle_wire_method_finished (void *cls, json_string_value (json_array_get (wh->methods, wh->methods_off-1)), json); + json_decref (json); /* trigger request for the next /wire/method */ request_wire_method (wh); } diff --git a/src/exchange-lib/exchange_api_wire_deposits.c b/src/exchange-lib/exchange_api_wire_deposits.c index 281ae2097..406256025 100644 --- a/src/exchange-lib/exchange_api_wire_deposits.c +++ b/src/exchange-lib/exchange_api_wire_deposits.c @@ -24,6 +24,7 @@ #include #include /* just for HTTP status codes */ #include +#include #include "taler_exchange_service.h" #include "exchange_api_common.h" #include "exchange_api_json.h" diff --git a/src/exchange-lib/test-exchange-home/sepa.json b/src/exchange-lib/test-exchange-home/sepa.json index 36d12f661..92ca25566 100644 --- a/src/exchange-lib/test-exchange-home/sepa.json +++ b/src/exchange-lib/test-exchange-home/sepa.json @@ -1,6 +1,9 @@ { - "receiver_name": "Max Mustermann", - "iban": "DE89370400440532013000", + "type": "sepa", "bic": "COBADEFF370", - "sig": "8M5YJXM68PRAXKH76HYEBCJW657B23JA0RFGNDMZK2379YZMT626H1BN89KC0M1KJBWGYEN5Z763Q0Y7MCTZQ6BPPT7D9KFCTW60C10" + "address": "Musterstadt", + "iban": "DE89370400440532013000", + "receiver_name": "Max Musterman", + "salt": "J5AP2BJ8MQAM1WQYQ9YPTAHZVTDXCT3RKHX851S5Q2A42T11K796MNMKJ78VBGDKCFMETMBDPM35D81NCCN77YRW92GDFSQ6P4CZ720", + "sig": "FF4JZ1FPNVEFPM6ZXD3QN1M225T9X912PX1GJDWGGJX6KBSTR2EZHK24E1PYW7P64YGGQG7Q9HJW0XE36HBBYZWXW83PKVZEYNVG038" } \ No newline at end of file diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 890e80756..fc0945d62 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -23,6 +23,7 @@ #include "taler_util.h" #include "taler_signatures.h" #include "taler_exchange_service.h" +#include "taler_json_lib.h" #include #include @@ -1502,7 +1503,7 @@ interpreter_run (void *cls, return; } execution_date = GNUNET_TIME_absolute_get (); - TALER_round_abs_time (&execution_date); + GNUNET_TIME_round_abs (&execution_date); cmd->details.admin_add_incoming.aih = TALER_EXCHANGE_admin_add_incoming (exchange, &reserve_pub, @@ -1664,7 +1665,7 @@ interpreter_run (void *cls, fail (is); return; } - TALER_hash_json (contract, + TALER_JSON_hash (contract, &h_contract); wire = json_loads (cmd->details.deposit.wire_details, JSON_REJECT_DUPLICATES, @@ -1698,7 +1699,7 @@ interpreter_run (void *cls, wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS); timestamp = GNUNET_TIME_absolute_get (); - TALER_round_abs_time (×tamp); + GNUNET_TIME_round_abs (×tamp); { struct TALER_DepositRequestPS dr; @@ -1706,7 +1707,7 @@ interpreter_run (void *cls, dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); dr.h_contract = h_contract; - TALER_hash_json (wire, + TALER_JSON_hash (wire, &dr.h_wire); dr.timestamp = GNUNET_TIME_absolute_hton (timestamp); dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); @@ -1964,14 +1965,14 @@ interpreter_run (void *cls, JSON_REJECT_DUPLICATES, NULL); GNUNET_assert (NULL != wire); - TALER_hash_json (wire, + TALER_JSON_hash (wire, &h_wire); json_decref (wire); contract = json_loads (ref->details.deposit.contract, JSON_REJECT_DUPLICATES, NULL); GNUNET_assert (NULL != contract); - TALER_hash_json (contract, + TALER_JSON_hash (contract, &h_contract); json_decref (contract); cmd->details.deposit_wtid.dwh @@ -2349,7 +2350,7 @@ run (void *cls, { .oc = OC_ADMIN_ADD_INCOMING, .label = "create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account_number\":42 }", + .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":42 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2370,7 +2371,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_OK, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 1 }, @@ -2387,7 +2388,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":43 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":43 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 1 }, /* Try to double-spend the 5 EUR coin at the same merchant (but different @@ -2397,7 +2398,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 2 }, /* Try to double-spend the 5 EUR coin at the same merchant (but different @@ -2407,7 +2408,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\":[{ \"name\":\"ice cream\", \"value\":2 } ] }", .details.deposit.transaction_id = 1 }, @@ -2417,7 +2418,7 @@ run (void *cls, { .oc = OC_ADMIN_ADD_INCOMING, .label = "refresh-create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account_number\":424 }", + .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":424 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2432,7 +2433,7 @@ run (void *cls, .expected_response_code = MHD_HTTP_OK, .details.deposit.amount = "EUR:1", .details.deposit.coin_ref = "refresh-withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:1\" } ] }", .details.deposit.transaction_id = 42421 }, diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am index 4ffabd15d..fda9cefa3 100644 --- a/src/exchange-tools/Makefile.am +++ b/src/exchange-tools/Makefile.am @@ -38,7 +38,9 @@ taler_exchange_sepa_SOURCES = \ taler_exchange_sepa_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/util/libtalerutil.la \ - -lgnunetutil -ljansson $(XLIB) + -lgnunetjson \ + -lgnunetutil \ + -ljansson $(XLIB) taler_exchange_sepa_LDFLAGS = $(POSTGRESQL_LDFLAGS) taler_exchange_keycheck_SOURCES = \ diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c index 779e3a3d3..861a9a7c8 100644 --- a/src/exchange-tools/taler-exchange-keyup.c +++ b/src/exchange-tools/taler-exchange-keyup.c @@ -518,7 +518,7 @@ exchange_keys_update_signkeys () "must be longer than signkey_duration"); return GNUNET_SYSERR; } - TALER_round_rel_time (&signkey_duration); + GNUNET_TIME_round_rel (&signkey_duration); GNUNET_asprintf (&signkey_dir, "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS, exchange_directory); @@ -600,7 +600,7 @@ get_cointype_params (const char *ct, "duration_withdraw"); return GNUNET_SYSERR; } - TALER_round_rel_time (¶ms->duration_withdraw); + GNUNET_TIME_round_rel (¶ms->duration_withdraw); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (kcfg, ct, @@ -612,7 +612,7 @@ get_cointype_params (const char *ct, "duration_spend"); return GNUNET_SYSERR; } - TALER_round_rel_time (¶ms->duration_spend); + GNUNET_TIME_round_rel (¶ms->duration_spend); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (kcfg, ct, @@ -624,7 +624,7 @@ get_cointype_params (const char *ct, "duration_legal"); return GNUNET_SYSERR; } - TALER_round_rel_time (¶ms->duration_legal); + GNUNET_TIME_round_rel (¶ms->duration_legal); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (kcfg, ct, @@ -636,7 +636,7 @@ get_cointype_params (const char *ct, "exchange_denom_duration_overlap"); return GNUNET_SYSERR; } - TALER_round_rel_time (¶ms->duration_overlap); + GNUNET_TIME_round_rel (¶ms->duration_overlap); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (kcfg, ct, @@ -927,7 +927,7 @@ main (int argc, { now = GNUNET_TIME_absolute_get (); } - TALER_round_abs_time (&now); + GNUNET_TIME_round_abs (&now); kcfg = TALER_config_load (exchange_directory); if (NULL == kcfg) @@ -1017,7 +1017,7 @@ main (int argc, _("must not be zero")); return GNUNET_SYSERR; } - TALER_round_rel_time (&lookahead_sign); + GNUNET_TIME_round_rel (&lookahead_sign); lookahead_sign_stamp = GNUNET_TIME_absolute_add (now, lookahead_sign); diff --git a/src/exchange-tools/taler-exchange-sepa.c b/src/exchange-tools/taler-exchange-sepa.c index a3ac95436..1bfb49132 100644 --- a/src/exchange-tools/taler-exchange-sepa.c +++ b/src/exchange-tools/taler-exchange-sepa.c @@ -20,6 +20,7 @@ */ #include #include +#include #include "taler_crypto_lib.h" #include "taler_signatures.h" @@ -34,6 +35,11 @@ static char *masterkeyfile; */ static char *sepa_name; +/** + * Account holder address. + */ +static char *sepa_address; + /** * IBAN number. */ @@ -63,6 +69,9 @@ main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'a', "address", "ADDRESS", + "account holder address", 1, + &GNUNET_GETOPT_set_string, &sepa_address}, {'b', "bic", "BICCODE", "bank BIC code", 1, &GNUNET_GETOPT_set_string, &bic}, @@ -88,6 +97,7 @@ main (int argc, struct GNUNET_HashContext *hc; json_t *reply; char *json_str; + struct GNUNET_HashCode salt; GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-exchange-sepa", @@ -112,8 +122,20 @@ main (int argc, masterkeyfile); return 1; } + if ( (NULL == sepa_address) || + (NULL == iban) || + (NULL == sepa_name) || + (NULL == bic) ) + { + fprintf (stderr, + "Required arguments missing\n"); + return 1; + } /* Compute message to sign */ + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &salt, + sizeof (salt)); hc = GNUNET_CRYPTO_hash_context_start (); GNUNET_CRYPTO_hash_context_read (hc, sepa_name, @@ -132,27 +154,31 @@ main (int argc, &wsd.purpose, &sig.eddsa_signature); GNUNET_free (eddsa_priv); - + /* build JSON message */ - reply = json_pack ("{s:s, s:s, s:s, s:o}", + reply = json_pack ("{s:s, s:s, s:s, s:s, s:s, s:o, s:o}", + "type", "sepa", + "address", sepa_address, "receiver_name", sepa_name, "iban", iban, "bic", bic, - "sig", TALER_json_from_data (&sig, - sizeof (sig))); + "salt", GNUNET_JSON_from_data (&salt, + sizeof (salt)), + "sig", GNUNET_JSON_from_data (&sig, + sizeof (sig))); GNUNET_assert (NULL != reply); /* dump result to stdout */ json_str = json_dumps (reply, JSON_INDENT(2)); GNUNET_assert (NULL != json_str); - + if (NULL != output_filename) { fclose (stdout); stdout = fopen (output_filename, "w+"); } - fprintf (stdout, + fprintf (stdout, "%s", json_str); fflush (stdout); diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 443ac511a..e29a51bbb 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -14,6 +14,7 @@ taler_exchange_aggregator_SOURCES = \ taler-exchange-aggregator.c taler_exchange_aggregator_LDADD = \ $(LIBGCRYPT_LIBS) \ + $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ @@ -36,11 +37,13 @@ taler_exchange_httpd_SOURCES = \ taler-exchange-httpd_validation.c taler-exchange-httpd_validation.h taler_exchange_httpd_LDADD = \ $(LIBGCRYPT_LIBS) \ + $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ -lmicrohttpd \ - -ljansson \ -lgnunetutil \ + -lgnunetjson \ + -ljansson \ -lpthread if HAVE_DEVELOPER diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 3ffce1d3f..e399a422e 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -29,6 +29,7 @@ #include #include "taler_exchangedb_lib.h" #include "taler_exchangedb_plugin.h" +#include "taler_json_lib.h" #include "taler_wire_lib.h" /** @@ -277,7 +278,7 @@ deposit_cb (void *cls, au->row_id = row_id; au->wire = (json_t *) wire; au->execution_time = GNUNET_TIME_absolute_get (); - TALER_hash_json (au->wire, + TALER_JSON_hash (au->wire, &au->h_wire); json_incref (au->wire); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index c16e26409..877876dbb 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -65,7 +65,7 @@ struct GNUNET_CONFIGURATION_Handle *cfg; * Master public key (according to the * configuration in the exchange directory). */ -struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key; +struct TALER_MasterPublicKeyP TMH_master_public_key; /** * Our DB plugin. @@ -424,7 +424,7 @@ exchange_serve_process_config (const char *exchange_directory) if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (TMH_master_public_key_str, strlen (TMH_master_public_key_str), - &TMH_master_public_key)) + &TMH_master_public_key.eddsa_pub)) { fprintf (stderr, "Invalid master public key given in exchange configuration."); diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 5f17eac5b..236df9e19 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -57,7 +57,7 @@ extern char *TMH_exchange_directory; * Master public key (according to the * configuration in the exchange directory). */ -extern struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key; +extern struct TALER_MasterPublicKeyP TMH_master_public_key; /** * Private key of the exchange we use to sign messages. diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 9d04efa9b..e96653a63 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -21,6 +21,8 @@ #include "platform.h" #include #include +#include +#include "taler_json_lib.h" #include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_keystate.h" @@ -1673,12 +1675,12 @@ handle_transaction_data (void *cls, is also ugly if we ever add signatures over this data. (#4135) */ json_array_append (ctx->deposits, json_pack ("{s:o, s:o, s:o, s:I, s:o}", - "deposit_value", TALER_json_from_amount (deposit_value), - "deposit_fee", TALER_json_from_amount (deposit_fee), - "H_contract", TALER_json_from_data (h_contract, + "deposit_value", TALER_JSON_from_amount (deposit_value), + "deposit_fee", TALER_JSON_from_amount (deposit_fee), + "H_contract", GNUNET_JSON_from_data (h_contract, sizeof (struct GNUNET_HashCode)), "transaction_id", (json_int_t) transaction_id, - "coin_pub", TALER_json_from_data (coin_pub, + "coin_pub", GNUNET_JSON_from_data (coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP)))); } diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 629d6f8b5..82dcf1a55 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -27,9 +27,11 @@ */ #include "platform.h" #include +#include #include #include #include +#include "taler_json_lib.h" #include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_deposit.h" #include "taler-exchange-httpd_responses.h" @@ -170,7 +172,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, "wire"); } if (GNUNET_OK != - TALER_hash_json (wire, + TALER_JSON_hash (wire, &my_h_wire)) { TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n"); diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index e278882fe..bf91b8183 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -22,6 +22,7 @@ */ #include "platform.h" #include +#include "taler_json_lib.h" #include "taler-exchange-httpd_keystate.h" #include "taler-exchange-httpd_responses.h" #include "taler_exchangedb_plugin.h" @@ -144,26 +145,26 @@ denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk, return json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}", "master_sig", - TALER_json_from_data (&dki->signature, + GNUNET_JSON_from_data (&dki->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature)), "stamp_start", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.start)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.start)), "stamp_expire_withdraw", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)), "stamp_expire_deposit", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)), "stamp_expire_legal", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)), "denom_pub", - TALER_json_from_rsa_public_key (pk->rsa_public_key), + GNUNET_JSON_from_rsa_public_key (pk->rsa_public_key), "value", - TALER_json_from_amount (&value), + TALER_JSON_from_amount (&value), "fee_withdraw", - TALER_json_from_amount (&fee_withdraw), + TALER_JSON_from_amount (&fee_withdraw), "fee_deposit", - TALER_json_from_amount (&fee_deposit), + TALER_JSON_from_amount (&fee_deposit), "fee_refresh", - TALER_json_from_amount (&fee_refresh)); + TALER_JSON_from_amount (&fee_refresh)); } @@ -342,19 +343,19 @@ sign_key_issue_to_json (const struct TALER_ExchangeSigningKeyValidityPS *ski) return json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", "stamp_start", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->start)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->start)), "stamp_expire", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->expire)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->expire)), "stamp_end", - TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->end)), + GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->end)), "master_pub", - TALER_json_from_data (&ski->master_public_key, + GNUNET_JSON_from_data (&ski->master_public_key, sizeof (struct TALER_MasterPublicKeyP)), "master_sig", - TALER_json_from_data (&ski->signature, + GNUNET_JSON_from_data (&ski->signature, sizeof (struct TALER_MasterSignatureP)), "key", - TALER_json_from_data (&ski->signkey_pub, + GNUNET_JSON_from_data (&ski->signkey_pub, sizeof (struct TALER_ExchangePublicKeyP))); } @@ -437,16 +438,16 @@ auditor_to_json (const struct TALER_AuditorPublicKeyP *apub, json_array_append_new (ja, json_pack ("{s:o, s:o}", "denom_pub_h", - TALER_json_from_data (&dki[i]->denom_hash, + GNUNET_JSON_from_data (&dki[i]->denom_hash, sizeof (struct GNUNET_HashCode)), "auditor_sig", - TALER_json_from_data (asigs[i], + GNUNET_JSON_from_data (asigs[i], sizeof (struct TALER_AuditorSignatureP)))); return json_pack ("{s:o, s:o}", "denomination_keys", ja, "auditor_pub", - TALER_json_from_data (apub, + GNUNET_JSON_from_data (apub, sizeof (struct TALER_AuditorPublicKeyP))); } @@ -633,7 +634,7 @@ TMH_KS_acquire_ (const char *location) key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); key_state->reload_time = GNUNET_TIME_absolute_get (); - TALER_round_abs_time (&key_state->reload_time); + GNUNET_TIME_round_abs (&key_state->reload_time); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loading keys from `%s'\n", TMH_exchange_directory); @@ -663,15 +664,15 @@ TMH_KS_acquire_ (const char *location) keys = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o}", "master_public_key", - TALER_json_from_data (&TMH_master_public_key, + GNUNET_JSON_from_data (&TMH_master_public_key, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)), "signkeys", key_state->sign_keys_array, "denoms", key_state->denom_keys_array, "auditors", key_state->auditors_array, - "list_issue_date", TALER_json_from_abs (key_state->reload_time), - "eddsa_pub", TALER_json_from_data (&key_state->current_sign_key_issue.issue.signkey_pub, + "list_issue_date", GNUNET_JSON_from_time_abs (key_state->reload_time), + "eddsa_pub", GNUNET_JSON_from_data (&key_state->current_sign_key_issue.issue.signkey_pub, sizeof (struct TALER_ExchangePublicKeyP)), - "eddsa_sig", TALER_json_from_data (&sig, + "eddsa_sig", GNUNET_JSON_from_data (&sig, sizeof (struct TALER_ExchangeSignatureP))); key_state->auditors_array = NULL; key_state->sign_keys_array = NULL; diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c index 25539aeb7..3fd69ae50 100644 --- a/src/exchange/taler-exchange-httpd_parsing.c +++ b/src/exchange/taler-exchange-httpd_parsing.c @@ -24,6 +24,7 @@ #include "platform.h" #include +#include "taler_json_lib.h" #include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_responses.h" @@ -786,10 +787,15 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection, case TMH_PARSE_JNC_RET_AMOUNT: { struct TALER_Amount *where = va_arg (argp, void *); + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount (NULL, where), + GNUNET_JSON_spec_end () + }; if (GNUNET_OK != - TALER_json_to_amount ((json_t *) root, - where)) + GNUNET_JSON_parse ((json_t *) root, + spec, + NULL, NULL)) { GNUNET_break_op (0); ret = (MHD_YES != @@ -823,10 +829,15 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection, case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: { struct GNUNET_TIME_Absolute *where = va_arg (argp, void *); + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_absolute_time (NULL, where), + GNUNET_JSON_spec_end () + }; if (GNUNET_OK != - TALER_json_to_abs ((json_t *) root, - where)) + GNUNET_JSON_parse ((json_t *) root, + spec, + NULL, NULL)) { GNUNET_break_op (0); ret = (MHD_YES != diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index d6cf81bb7..a47b29cae 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -25,7 +25,7 @@ #include "platform.h" #include "taler-exchange-httpd_responses.h" #include "taler_util.h" -#include +#include "taler_json_lib.h" #include "taler-exchange-httpd_keystate.h" @@ -388,9 +388,9 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, MHD_HTTP_OK, "{s:s, s:o, s:o}", "status", "DEPOSIT_OK", - "sig", TALER_json_from_data (&sig, + "sig", GNUNET_JSON_from_data (&sig, sizeof (sig)), - "pub", TALER_json_from_data (&pub, + "pub", GNUNET_JSON_from_data (&pub, sizeof (pub))); } @@ -449,7 +449,7 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl) return NULL; } - details = TALER_json_from_data (&dr.purpose, + details = GNUNET_JSON_from_data (&dr.purpose, sizeof (struct TALER_DepositRequestPS)); break; } @@ -481,7 +481,7 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl) return NULL; } - details = TALER_json_from_data (&ms.purpose, + details = GNUNET_JSON_from_data (&ms.purpose, sizeof (struct TALER_RefreshMeltCoinAffirmationPS)); } break; @@ -491,8 +491,8 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl) json_array_append_new (history, json_pack ("{s:s, s:o, s:o, s:o}", "type", type, - "amount", TALER_json_from_amount (&value), - "signature", TALER_json_from_data (sig, + "amount", TALER_JSON_from_amount (&value), + "signature", GNUNET_JSON_from_data (sig, sizeof (struct TALER_CoinSpendSignatureP)), "details", details)); } @@ -569,7 +569,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh, json_pack ("{s:s, s:O, s:o}", "type", "DEPOSIT", "wire", pos->details.bank->wire, - "amount", TALER_json_from_amount (&pos->details.bank->amount))); + "amount", TALER_JSON_from_amount (&pos->details.bank->amount))); break; case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: break; @@ -614,11 +614,11 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh, json_array_append_new (json_history, json_pack ("{s:s, s:o, s:o, s:o}", "type", "WITHDRAW", - "signature", TALER_json_from_data (&pos->details.withdraw->reserve_sig, + "signature", GNUNET_JSON_from_data (&pos->details.withdraw->reserve_sig, sizeof (struct TALER_ReserveSignatureP)), - "details", TALER_json_from_data (&wr, + "details", GNUNET_JSON_from_data (&wr, sizeof (wr)), - "amount", TALER_json_from_amount (&value))); + "amount", TALER_JSON_from_amount (&value))); break; } } @@ -662,7 +662,7 @@ TMH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection, if (NULL == json_history) return TMH_RESPONSE_reply_internal_error (connection, "balance calculation failure"); - json_balance = TALER_json_from_amount (&balance); + json_balance = TALER_JSON_from_amount (&balance); return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o}", @@ -693,7 +693,7 @@ TMH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c if (NULL == json_history) return TMH_RESPONSE_reply_internal_error (connection, "balance calculation failure"); - json_balance = TALER_json_from_amount (&balance); + json_balance = TALER_JSON_from_amount (&balance); return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_PAYMENT_REQUIRED, "{s:s, s:o, s:o}", @@ -716,7 +716,7 @@ TMH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection, { json_t *sig_json; - sig_json = TALER_json_from_rsa_signature (collectable->sig.rsa_signature); + sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature); return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o}", @@ -758,14 +758,14 @@ TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne "error", "insufficient funds", "coin_pub", - TALER_json_from_data (coin_pub, + GNUNET_JSON_from_data (coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP)), "original_value", - TALER_json_from_amount (&coin_value), + TALER_JSON_from_amount (&coin_value), "residual_value", - TALER_json_from_amount (&residual), + TALER_JSON_from_amount (&residual), "requested_value", - TALER_json_from_amount (&requested), + TALER_JSON_from_amount (&requested), "history", history); } @@ -797,7 +797,7 @@ TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection, TMH_KS_sign (&body.purpose, &pub, &sig); - sig_json = TALER_json_from_data (&sig, + sig_json = GNUNET_JSON_from_data (&sig, sizeof (sig)); GNUNET_assert (NULL != sig_json); return TMH_RESPONSE_reply_json_pack (connection, @@ -805,7 +805,7 @@ TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection, "{s:i, s:o, s:o}", "noreveal_index", (int) noreveal_index, "exchange_sig", sig_json, - "exchange_pub", TALER_json_from_data (&pub, + "exchange_pub", GNUNET_JSON_from_data (&pub, sizeof (pub))); } @@ -835,7 +835,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, obj = json_object (); json_object_set_new (obj, "ev_sig", - TALER_json_from_rsa_signature (sigs[newcoin_index].rsa_signature)); + GNUNET_JSON_from_rsa_signature (sigs[newcoin_index].rsa_signature)); json_array_append_new (list, obj); } @@ -889,18 +889,18 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, rm_json = json_object (); json_object_set_new (rm_json, "coin_sig", - TALER_json_from_data (&rm->coin_sig, + GNUNET_JSON_from_data (&rm->coin_sig, sizeof (struct TALER_CoinSpendSignatureP))); json_object_set_new (rm_json, "coin_pub", - TALER_json_from_data (&rm->coin.coin_pub, + GNUNET_JSON_from_data (&rm->coin.coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP))); json_object_set_new (rm_json, "melt_amount_with_fee", - TALER_json_from_amount (&rm->amount_with_fee)); + TALER_JSON_from_amount (&rm->amount_with_fee)); json_object_set_new (rm_json, "melt_fee", - TALER_json_from_amount (&rm->melt_fee)); + TALER_JSON_from_amount (&rm->melt_fee)); json_array_append_new (info_old, rm_json); } @@ -911,7 +911,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, pk = &mc->denom_pubs[i]; json_array_append_new (info_new, - TALER_json_from_rsa_public_key (pk->rsa_public_key)); + GNUNET_JSON_from_rsa_public_key (pk->rsa_public_key)); } info_commit = json_array (); @@ -931,15 +931,15 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, cc_json = json_object (); json_object_set_new (cc_json, "coin_ev", - TALER_json_from_data (cc->coin_ev, + GNUNET_JSON_from_data (cc->coin_ev, cc->coin_ev_size)); json_object_set_new (cc_json, "coin_priv_enc", - TALER_json_from_data (cc->refresh_link->coin_priv_enc, + GNUNET_JSON_from_data (cc->refresh_link->coin_priv_enc, sizeof (struct TALER_CoinSpendPrivateKeyP))); json_object_set_new (cc_json, "blinding_key_enc", - TALER_json_from_data (cc->refresh_link->blinding_key_enc, + GNUNET_JSON_from_data (cc->refresh_link->blinding_key_enc, cc->refresh_link->blinding_key_enc_size)); json_array_append_new (info_commit_k, @@ -957,11 +957,11 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, cl_json = json_object (); json_object_set_new (cl_json, "transfer_pub", - TALER_json_from_data (&cl->transfer_pub, + GNUNET_JSON_from_data (&cl->transfer_pub, sizeof (struct TALER_TransferPublicKeyP))); json_object_set_new (cl_json, "shared_secret_enc", - TALER_json_from_data (&cl->shared_secret_enc, + GNUNET_JSON_from_data (&cl->shared_secret_enc, sizeof (struct TALER_EncryptedLinkSecretP))); json_array_append_new (info_link_k, cl_json); @@ -1015,15 +1015,15 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection, obj = json_object (); json_object_set_new (obj, "link_enc", - TALER_json_from_data (pos->link_data_enc->coin_priv_enc, + GNUNET_JSON_from_data (pos->link_data_enc->coin_priv_enc, sizeof (struct TALER_CoinSpendPrivateKeyP) + pos->link_data_enc->blinding_key_enc_size)); json_object_set_new (obj, "denom_pub", - TALER_json_from_rsa_public_key (pos->denom_pub.rsa_public_key)); + GNUNET_JSON_from_rsa_public_key (pos->denom_pub.rsa_public_key)); json_object_set_new (obj, "ev_sig", - TALER_json_from_rsa_signature (pos->ev_sig.rsa_signature)); + GNUNET_JSON_from_rsa_signature (pos->ev_sig.rsa_signature)); json_array_append_new (list, obj); } @@ -1033,11 +1033,11 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection, list); json_object_set_new (root, "transfer_pub", - TALER_json_from_data (&sessions[i].transfer_pub, + GNUNET_JSON_from_data (&sessions[i].transfer_pub, sizeof (struct TALER_TransferPublicKeyP))); json_object_set_new (root, "secret_enc", - TALER_json_from_data (&sessions[i].shared_secret_enc, + GNUNET_JSON_from_data (&sessions[i].shared_secret_enc, sizeof (struct TALER_EncryptedLinkSecretP))); json_array_append_new (mlist, root); @@ -1083,7 +1083,7 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection, return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_ACCEPTED, "{s:o}", - "execution_time", TALER_json_from_abs (planned_exec_time)); + "execution_time", GNUNET_JSON_from_time_abs (planned_exec_time)); } @@ -1132,13 +1132,13 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o, s:o, s:o}", - "wtid", TALER_json_from_data (wtid, + "wtid", GNUNET_JSON_from_data (wtid, sizeof (*wtid)), - "execution_time", TALER_json_from_abs (exec_time), - "coin_contribution", TALER_json_from_amount (coin_contribution), - "exchange_sig", TALER_json_from_data (&sig, + "execution_time", GNUNET_JSON_from_time_abs (exec_time), + "coin_contribution", TALER_JSON_from_amount (coin_contribution), + "exchange_sig", GNUNET_JSON_from_data (&sig, sizeof (sig)), - "exchange_pub", TALER_json_from_data (&pub, + "exchange_pub", GNUNET_JSON_from_data (&pub, sizeof (pub))); } @@ -1165,10 +1165,10 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection, return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o}", - "total", TALER_json_from_amount (total), - "merchant_pub", TALER_json_from_data (merchant_pub, + "total", TALER_JSON_from_amount (total), + "merchant_pub", GNUNET_JSON_from_data (merchant_pub, sizeof (struct TALER_MerchantPublicKeyP)), - "h_wire", TALER_json_from_data (h_wire, + "h_wire", GNUNET_JSON_from_data (h_wire, sizeof (struct GNUNET_HashCode)), "deposits", deposits); } diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c index 876869d86..7b6438cae 100644 --- a/src/exchange/taler-exchange-httpd_test.c +++ b/src/exchange/taler-exchange-httpd_test.c @@ -21,6 +21,7 @@ */ #include "platform.h" #include +#include #include #include #include "taler_signatures.h" @@ -90,7 +91,7 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o}", "output", - TALER_json_from_data (&hc, sizeof (struct GNUNET_HashCode))); + GNUNET_JSON_from_data (&hc, sizeof (struct GNUNET_HashCode))); } @@ -164,7 +165,7 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh, &skey, &iv, out)); - json = TALER_json_from_data (out, + json = GNUNET_JSON_from_data (out, in_ptr_size); GNUNET_free (out); TMH_PARSE_release_data (spec); @@ -231,7 +232,7 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh, in_ptr_size, NULL, 0); TMH_PARSE_release_data (spec); - json = TALER_json_from_data (&hc, + json = GNUNET_JSON_from_data (&hc, sizeof (struct GNUNET_HashCode)); return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, @@ -302,7 +303,7 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o}", "ecdh_hash", - TALER_json_from_data (&hc, + GNUNET_JSON_from_data (&hc, sizeof (hc))); } @@ -387,10 +388,10 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o, s:o}", "eddsa_pub", - TALER_json_from_data (&pub, + GNUNET_JSON_from_data (&pub, sizeof (pub)), "eddsa_sig", - TALER_json_from_data (&sig, + GNUNET_JSON_from_data (&sig, sizeof (sig))); } @@ -435,7 +436,7 @@ TMH_TEST_handler_test_rsa_get (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o}", "rsa_pub", - TALER_json_from_rsa_public_key (pub)); + GNUNET_JSON_from_rsa_public_key (pub)); GNUNET_CRYPTO_rsa_public_key_free (pub); return res; } @@ -509,7 +510,7 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o}", "rsa_blind_sig", - TALER_json_from_rsa_signature (sig)); + GNUNET_JSON_from_rsa_signature (sig)); GNUNET_CRYPTO_rsa_signature_free (sig); return res; } @@ -578,7 +579,7 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o}", "secret", - TALER_json_from_data (&secret, + GNUNET_JSON_from_data (&secret, sizeof (secret))); } diff --git a/src/exchange/taler-exchange-httpd_validation.c b/src/exchange/taler-exchange-httpd_validation.c index 9132e3e02..b7e8a7f80 100644 --- a/src/exchange/taler-exchange-httpd_validation.c +++ b/src/exchange/taler-exchange-httpd_validation.c @@ -21,6 +21,7 @@ */ #include "platform.h" #include +#include "taler-exchange-httpd.h" #include "taler-exchange-httpd_validation.h" #include "taler_wire_plugin.h" @@ -172,7 +173,9 @@ TMH_json_validate_wireformat (const json_t *wire) for (p=wire_head; NULL != p; p = p->next) if (0 == strcasecmp (p->type, stype)) - return p->plugin->wire_validate (wire); + return p->plugin->wire_validate (p->plugin->cls, + wire, + &TMH_master_public_key); return GNUNET_NO; } diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index cec041762..1b3d3b541 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -19,6 +19,7 @@ * @author Christian Grothoff */ #include "platform.h" +#include #include "taler-exchange-httpd_keystate.h" #include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_validation.h" @@ -57,9 +58,9 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh, MHD_HTTP_OK, "{s:o, s:o, s:o}", "methods", methods, - "sig", TALER_json_from_data (&sig, + "sig", GNUNET_JSON_from_data (&sig, sizeof (sig)), - "pub", TALER_json_from_data (&pub, + "pub", GNUNET_JSON_from_data (&pub, sizeof (pub))); } diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 566dec6f8..c3ecba968 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -22,6 +22,7 @@ #ifndef _TALER_EXCHANGE_SERVICE_H #define _TALER_EXCHANGE_SERVICE_H +#include #include "taler_util.h" /* ********************* event loop *********************** */ @@ -292,7 +293,7 @@ struct TALER_EXCHANGE_Keys */ typedef void (*TALER_EXCHANGE_CertificationCallback) (void *cls, - const struct TALER_EXCHANGE_Keys *keys); + const struct TALER_EXCHANGE_Keys *keys); /** @@ -319,10 +320,10 @@ struct TALER_EXCHANGE_Handle; */ struct TALER_EXCHANGE_Handle * TALER_EXCHANGE_connect (struct TALER_EXCHANGE_Context *ctx, - const char *url, - TALER_EXCHANGE_CertificationCallback cert_cb, - void *cert_cb_cls, - ...); + const char *url, + TALER_EXCHANGE_CertificationCallback cert_cb, + void *cert_cb_cls, + ...); /** @@ -354,7 +355,7 @@ TALER_EXCHANGE_get_keys (const struct TALER_EXCHANGE_Handle *exchange); */ int TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys, - const struct TALER_ExchangePublicKeyP *pub); + const struct TALER_ExchangePublicKeyP *pub); /** @@ -367,7 +368,7 @@ TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys, */ const struct TALER_EXCHANGE_DenomPublicKey * TALER_EXCHANGE_get_denomination_key (const struct TALER_EXCHANGE_Keys *keys, - const struct TALER_DenominationPublicKey *pk); + const struct TALER_DenominationPublicKey *pk); /** @@ -379,7 +380,7 @@ TALER_EXCHANGE_get_denomination_key (const struct TALER_EXCHANGE_Keys *keys, */ const struct TALER_EXCHANGE_DenomPublicKey * TALER_EXCHANGE_get_denomination_key_by_hash (const struct TALER_EXCHANGE_Keys *keys, - const struct GNUNET_HashCode *hc); + const struct GNUNET_HashCode *hc); /* ********************* /wire *********************** */ @@ -423,9 +424,9 @@ struct TALER_EXCHANGE_WireHandle; */ typedef void (*TALER_EXCHANGE_WireResultCallback) (void *cls, - unsigned int http_status, - const char *method, - json_t *obj); + unsigned int http_status, + const char *method, + json_t *obj); /** diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index aecb050a7..f45014463 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -22,6 +22,7 @@ #ifndef TALER_EXCHANGEDB_PLUGIN_H #define TALER_EXCHANGEDB_PLUGIN_H +#include #include #include "taler_exchangedb_lib.h" diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index d9fa05188..aee151b97 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 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. 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 @@ -17,14 +17,18 @@ * @file include/taler_json_lib.h * @brief helper functions for JSON processing using libjansson * @author Sree Harsha Totakura + * @author Christian Grothoff */ -#ifndef TALER_json_LIB_H_ -#define TALER_json_LIB_H_ +#ifndef TALER_JSON_LIB_H_ +#define TALER_JSON_LIB_H_ #include +#include +#include "taler_util.h" /** * Print JSON parsing related error information + * @deprecated */ #define TALER_json_warn(error) \ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \ @@ -39,106 +43,18 @@ * @return a json object describing the amount */ json_t * -TALER_json_from_amount (const struct TALER_Amount *amount); +TALER_JSON_from_amount (const struct TALER_Amount *amount); /** - * Convert absolute timestamp to a json string. + * Provide specification to parse given JSON object to an amount. * - * @param stamp the time stamp - * @return a json string with the timestamp in @a stamp - */ -json_t * -TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp); - - -/** - * Convert RSA public key to JSON. - * - * @param pk public key to convert - * @return corresponding JSON encoding - */ -json_t * -TALER_json_from_rsa_public_key (struct GNUNET_CRYPTO_rsa_PublicKey *pk); - - -/** - * Convert RSA signature to JSON. - * - * @param sig signature to convert - * @return corresponding JSON encoding - */ -json_t * -TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig); - - -/** - * Convert binary data to a JSON string - * with the base32crockford encoding. - * - * @param data binary data - * @param size size of @a data in bytes - * @return json string that encodes @a data - */ -json_t * -TALER_json_from_data (const void *data, - size_t size); - - -/** - * Parse given JSON object to Amount - * - * @param json the json object representing Amount + * @param name name of the amount field in the JSON * @param[out] r_amount where the amount has to be written - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_amount (json_t *json, - struct TALER_Amount *r_amount); - -/** - * Parse given JSON object to absolute time. - * - * @param json the json object representing absolute time in seconds - * @param[out] abs where the time has to be written - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_abs (json_t *json, - struct GNUNET_TIME_Absolute *abs); - -/** - * Parse given JSON object to data - * - * @param json the json object representing data - * @param out the pointer to hold the parsed data. - * @param out_size the size of @a out - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_data (json_t *json, - void *out, - size_t out_size); - - -/** - * Convert JSON to RSA public key. - * - * @param json JSON encoding to convert - * @return corresponding public key */ -struct GNUNET_CRYPTO_rsa_PublicKey * -TALER_json_to_rsa_public_key (json_t *json); - - -/** - * Convert JSON to RSA signature. - * - * @param json JSON encoding to convert - * @return corresponding signature - */ -struct GNUNET_CRYPTO_rsa_Signature * -TALER_json_to_rsa_signature (json_t *json); +struct GNUNET_JSON_Specification +TALER_JSON_spec_amount (const char *name, + struct TALER_Amount *r_amount); /** @@ -149,22 +65,9 @@ TALER_json_to_rsa_signature (json_t *json); * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -TALER_hash_json (json_t *json, +TALER_JSON_hash (json_t *json, struct GNUNET_HashCode *hc); - -/** - * Check if the given wire format JSON object is correctly formatted - * - * @param allowed NULL-terminated array of allowed wire format types - * @param wire the JSON wire format object - * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not - */ -int -TALER_json_validate_wireformat (const char **allowed, - const json_t *wire); - - -#endif /* TALER_json_LIB_H_ */ +#endif /* TALER_JSON_LIB_H_ */ /* End of taler_json_lib.h */ diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 49e067846..dfcea30e1 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -24,6 +24,7 @@ #define TALER_PQ_LIB_H_ #include +#include #include #include "taler_util.h" diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 380901812..f0da795a4 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -24,8 +24,6 @@ #include #include "taler_amount_lib.h" #include "taler_crypto_lib.h" -#include "taler_json_lib.h" - /* Define logging functions */ @@ -97,30 +95,6 @@ TALER_b2s (const void *buf, #define TALER_B2S(obj) TALER_b2s (obj, sizeof (*obj)) -/** - * Round a time value so that it is suitable for transmission - * via JSON encodings. - * - * @param at time to round - * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if - * it was just now rounded - */ -int -TALER_round_abs_time (struct GNUNET_TIME_Absolute *at); - - -/** - * Round a time value so that it is suitable for transmission - * via JSON encodings. - * - * @param rt time to round - * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if - * it was just now rounded - */ -int -TALER_round_rel_time (struct GNUNET_TIME_Relative *rt); - - /** * Load configuration by parsing all configuration * files in the given directory. diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h index 8fb194c57..c80aa2e49 100644 --- a/src/include/taler_wire_plugin.h +++ b/src/include/taler_wire_plugin.h @@ -101,11 +101,15 @@ struct TALER_WIRE_Plugin /** * Check if the given wire format JSON object is correctly formatted * + * @param cls the @e cls of this struct with the plugin-specific state * @param wire the JSON wire format object + * @param master_pub public key of the exchange to verify against * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ int - (*wire_validate) (const json_t *wire); + (*wire_validate) (void *cls, + const json_t *wire, + const struct TALER_MasterPublicKeyP *master_pub); /** diff --git a/src/json/Makefile.am b/src/json/Makefile.am new file mode 100644 index 000000000..6f71b8718 --- /dev/null +++ b/src/json/Makefile.am @@ -0,0 +1,38 @@ +# This Makefile.am is in the public domain +AM_CPPFLAGS = -I$(top_srcdir)/src/include + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 + XLIB = -lgcov +endif + +lib_LTLIBRARIES = \ + libtalerjson.la + +libtalerjson_la_SOURCES = \ + json.c \ + json_helper.c +libtalerjson_la_LDFLAGS = \ + -version-info 0:0:0 \ + -export-dynamic -no-undefined +libtalerjson_la_LIBADD = \ + -lgnunetjson \ + $(top_builddir)/src/util/libtalerutil.la \ + -lgnunetutil \ + -ljansson \ + $(XLIB) + +TESTS = \ + test_json + +check_PROGRAMS= \ + test_json + +test_json_SOURCES = \ + test_json.c +test_json_LDADD = \ + -ltalerjson \ + -lgnunetjson \ + $(top_builddir)/src/util/libtalerutil.la \ + -lgnunetutil \ + -ljansson diff --git a/src/json/json.c b/src/json/json.c new file mode 100644 index 000000000..1fbc59a73 --- /dev/null +++ b/src/json/json.c @@ -0,0 +1,53 @@ +/* + This file is part of TALER + Copyright (C) 2014, 2015, 2016 GNUnet e.V. + + 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, If not, see +*/ +/** + * @file json/json.c + * @brief helper functions for JSON processing using libjansson + * @author Sree Harsha Totakura + */ +#include "platform.h" +#include +#include "taler_util.h" +#include "taler_json_lib.h" + + +/** + * Hash a JSON for binary signing. + * + * @param[in] json some JSON value + * @param[out] hc resulting hash code + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +TALER_JSON_hash (json_t *json, + struct GNUNET_HashCode *hc) +{ + char *wire_enc; + size_t len; + + if (NULL == (wire_enc = json_dumps (json, + JSON_COMPACT | JSON_SORT_KEYS))) + return GNUNET_SYSERR; + len = strlen (wire_enc) + 1; + GNUNET_CRYPTO_hash (wire_enc, + len, + hc); + free (wire_enc); + return GNUNET_OK; +} + + +/* End of json/json.c */ diff --git a/src/json/json_helper.c b/src/json/json_helper.c new file mode 100644 index 000000000..b61fe21a6 --- /dev/null +++ b/src/json/json_helper.c @@ -0,0 +1,146 @@ +/* + This file is part of TALER + Copyright (C) 2014, 2015, 2016 GNUnet e.V. + + 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, If not, see +*/ +/** + * @file json/json_helper.c + * @brief helper functions to generate specifications to parse + * Taler-specific JSON objects with libgnunetjson + * @author Sree Harsha Totakura + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include "taler_util.h" +#include "taler_json_lib.h" + + +/** + * Convert a TALER amount to a JSON object. + * + * @param amount the amount + * @return a json object describing the amount + */ +json_t * +TALER_JSON_from_amount (const struct TALER_Amount *amount) +{ + json_t *j; + + if ( (amount->value != (uint64_t) ((json_int_t) amount->value)) || + (0 > ((json_int_t) amount->value)) ) + { + /* Theoretically, json_int_t can be a 32-bit "long", or we might + have a 64-bit value which converted to a 63-bit signed long + long causes problems here. So we check. Note that depending + on the platform, the compiler may be able to statically tell + that at least the first check is always false. */ + GNUNET_break (0); + return NULL; + } + j = json_pack ("{s:s, s:I, s:I}", + "currency", amount->currency, + "value", (json_int_t) amount->value, + "fraction", (json_int_t) amount->fraction); + GNUNET_assert (NULL != j); + return j; +} + + +/** + * Parse given JSON object to Amount + * + * @param cls closure, 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 + */ +static int +parse_amount (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_Amount *r_amount = spec->ptr; + json_int_t value; + json_int_t fraction; + const char *currency; + + memset (r_amount, + 0, + sizeof (struct TALER_Amount)); + if (0 != json_unpack (root, + "{s:I, s:I, s:s}", + "value", &value, + "fraction", &fraction, + "currency", ¤cy)) + { + char *json_enc; + + if (NULL == (json_enc = json_dumps (root, + JSON_COMPACT | JSON_ENCODE_ANY))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Malformed JSON amount: %s\n", + json_enc); + free (json_enc); + return GNUNET_SYSERR; + } + if ( (value < 0) || + (fraction < 0) || + (value > UINT64_MAX) || + (fraction > UINT32_MAX) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (strlen (currency) >= TALER_CURRENCY_LEN) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + r_amount->value = (uint64_t) value; + r_amount->fraction = (uint32_t) fraction; + strcpy (r_amount->currency, currency); + (void) TALER_amount_normalize (r_amount); + return GNUNET_OK; +} + + + +/** + * Provide specification to parse given JSON object to an amount. + * + * @param name name of the amount field in the JSON + * @param[out] r_amount where the amount has to be written + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_amount (const char *name, + struct TALER_Amount *r_amount) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_amount, + .cleaner = NULL, + .cls = NULL, + .field = name, + .ptr = r_amount, + .ptr_size = 0, + .size_ptr = NULL + }; + return ret; +} + + +/* end of json/json_helper.c */ diff --git a/src/json/test_json.c b/src/json/test_json.c new file mode 100644 index 000000000..9f42dbd34 --- /dev/null +++ b/src/json/test_json.c @@ -0,0 +1,71 @@ +/* + This file is part of TALER + (C) 2015, 2016 GNUnet e.V. and Inria + + 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, If not, see +*/ + +/** + * @file json/test_json.c + * @brief Tests for Taler-specific crypto logic + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_json_lib.h" + + +/** + * Test amount conversion from/to JSON. + * + * @return 0 on success + */ +static int +test_amount () +{ + json_t *j; + struct TALER_Amount a1; + struct TALER_Amount a2; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount (NULL, &a2), + GNUNET_JSON_spec_end() + }; + + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4.3", + &a1)); + j = TALER_JSON_from_amount (&a1); + GNUNET_assert (NULL != j); + GNUNET_assert (GNUNET_OK == + GNUNET_JSON_parse (j, spec, + NULL, NULL)); + GNUNET_assert (0 == + TALER_amount_cmp (&a1, + &a2)); + json_decref (j); + return 0; +} + + +int +main(int argc, + const char *const argv[]) +{ + GNUNET_log_setup ("test-json", + "WARNING", + NULL); + if (0 != test_amount ()) + return 1; + return 0; +} + +/* end of test_json.c */ diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 748ce0c29..49d0668a0 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -72,7 +72,7 @@ extract_amount_nbo_helper (PGresult *result, frac_name); curr_num = PQfnumber (result, curr_name); - if (val_num < 0) + if (val_num < 0) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Field `%s' does not exist in result\n", @@ -140,7 +140,7 @@ extract_amount_nbo_helper (PGresult *result, * #GNUNET_YES if all results could be extracted * #GNUNET_NO if at least one result was NULL * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ + */ static int extract_amount_nbo (void *cls, PGresult *result, @@ -153,7 +153,7 @@ extract_amount_nbo (void *cls, char *frac_name; char *curr_name; int ret; - + GNUNET_asprintf (&val_name, "%s_val", fname); @@ -189,7 +189,7 @@ TALER_PQ_result_spec_amount_nbo (const char *name, { struct GNUNET_PQ_ResultSpec res = { &extract_amount_nbo, NULL, NULL, - (void *) amount, sizeof (*amount), + (void *) amount, sizeof (*amount), name, NULL }; return res; } @@ -208,7 +208,7 @@ TALER_PQ_result_spec_amount_nbo (const char *name, * #GNUNET_YES if all results could be extracted * #GNUNET_NO if at least one result was NULL * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ + */ static int extract_amount (void *cls, PGresult *result, @@ -223,7 +223,7 @@ extract_amount (void *cls, char *curr_name; struct TALER_AmountNBO amount_nbo; int ret; - + GNUNET_asprintf (&val_name, "%s_val", fname); @@ -280,7 +280,7 @@ TALER_PQ_result_spec_amount (const char *name, * #GNUNET_YES if all results could be extracted * #GNUNET_NO if at least one result was NULL * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ + */ static int extract_json (void *cls, PGresult *result, @@ -294,7 +294,7 @@ extract_json (void *cls, int fnum; json_error_t json_error; size_t slen; - + fnum = PQfnumber (result, fname); if (fnum < 0) @@ -320,10 +320,11 @@ extract_json (void *cls, &json_error); if (NULL == *j_dst) { - TALER_json_warn (json_error); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse JSON result for field `%s'\n", - fname); + "Failed to parse JSON result for field `%s': %s (%s)\n", + fname, + json_error.text, + json_error.source); return GNUNET_SYSERR; } return GNUNET_OK; @@ -364,7 +365,7 @@ TALER_PQ_result_spec_json (const char *name, { struct GNUNET_PQ_ResultSpec res = { &extract_json, &clean_json, NULL, - (void *) jp, 0, + (void *) jp, 0, name, NULL }; return res; } diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 8efc3987a..41afcc97f 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -1,5 +1,5 @@ # This Makefile.am is in the public domain -AM_CPPFLAGS = -I$(top_srcdir)/src/include $(LIBGCRYPT_CFLAGS) $(POSTGRESQL_CPPFLAGS) +AM_CPPFLAGS = -I$(top_srcdir)/src/include $(LIBGCRYPT_CFLAGS) if USE_COVERAGE AM_CFLAGS = --coverage -O0 @@ -31,15 +31,12 @@ libtalerutil_la_SOURCES = \ amount.c \ crypto.c \ util.c \ - json.c \ os_installation.c \ - plugin.c \ - wireformats.c + plugin.c libtalerutil_la_LIBADD = \ -lgnunetutil \ $(LIBGCRYPT_LIBS) \ - -ljansson \ -lmicrohttpd $(XLIB) libtalerutil_la_LDFLAGS = \ @@ -48,13 +45,11 @@ libtalerutil_la_LDFLAGS = \ TESTS = \ test_amount \ - test_crypto \ - test_json + test_crypto check_PROGRAMS= \ test_amount \ - test_crypto \ - test_json + test_crypto test_amount_SOURCES = \ @@ -68,10 +63,3 @@ test_crypto_SOURCES = \ test_crypto_LDADD = \ -lgnunetutil \ libtalerutil.la - -test_json_SOURCES = \ - test_json.c -test_json_LDADD = \ - -lgnunetutil \ - -ljansson \ - libtalerutil.la diff --git a/src/util/json.c b/src/util/json.c deleted file mode 100644 index 6aca7548c..000000000 --- a/src/util/json.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see -*/ -/** - * @file util/json.c - * @brief helper functions for JSON processing using libjansson - * @author Sree Harsha Totakura - */ -#include "platform.h" -#if HAVE_GNUNET_GNUNET_UTIL_TALER_WALLET_LIB_H -#include -#endif -#if HAVE_GNUNET_GNUNET_UTIL_LIB_H -#include -#endif -#include "taler_util.h" - -/** - * Shorthand for exit jumps. - */ -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - -/** - * Shorthand for JSON parsing related exit jumps. - */ -#define UNPACK_EXITIF(cond) \ - do { \ - if (cond) { TALER_json_warn (error); goto EXITIF_exit; } \ - } while (0) - - -/** - * Convert a TALER amount to a JSON - * object. - * - * @param amount the amount - * @return a json object describing the amount - */ -json_t * -TALER_json_from_amount (const struct TALER_Amount *amount) -{ - json_t *j; - - if ( (amount->value != (uint64_t) ((json_int_t) amount->value)) || - (0 > ((json_int_t) amount->value)) ) - { - /* Theoretically, json_int_t can be a 32-bit "long", or we might - have a 64-bit value which converted to a 63-bit signed long - long causes problems here. So we check. Note that depending - on the platform, the compiler may be able to statically tell - that at least the first check is always false. */ - GNUNET_break (0); - return NULL; - } - j = json_pack ("{s:s, s:I, s:I}", - "currency", amount->currency, - "value", (json_int_t) amount->value, - "fraction", (json_int_t) amount->fraction); - GNUNET_assert (NULL != j); - return j; -} - - -/** - * Convert absolute timestamp to a json string. - * - * @param stamp the time stamp - * @return a json string with the timestamp in @a stamp - */ -json_t * -TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp) -{ - json_t *j; - char *mystr; - int ret; - - GNUNET_assert (GNUNET_OK == - TALER_round_abs_time (&stamp)); - if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) - return json_string ("/never/"); - ret = GNUNET_asprintf (&mystr, - "/Date(%llu)/", - (unsigned long long) (stamp.abs_value_us / (1000LL * 1000LL))); - GNUNET_assert (ret > 0); - j = json_string (mystr); - GNUNET_free (mystr); - return j; -} - - -/** - * Convert RSA public key to JSON. - * - * @param pk public key to convert - * @return corresponding JSON encoding - */ -json_t * -TALER_json_from_rsa_public_key (struct GNUNET_CRYPTO_rsa_PublicKey *pk) -{ - char *buf; - size_t buf_len; - json_t *ret; - - buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pk, - &buf); - ret = TALER_json_from_data (buf, - buf_len); - GNUNET_free (buf); - return ret; -} - - -/** - * Convert JSON to RSA public key. - * - * @param json JSON encoding to convert - * @return corresponding public key - */ -struct GNUNET_CRYPTO_rsa_PublicKey * -TALER_json_to_rsa_public_key (json_t *json) -{ - const char *enc; - char *buf; - size_t len; - size_t buf_len; - struct GNUNET_CRYPTO_rsa_PublicKey *pk; - - buf = NULL; - EXITIF (NULL == (enc = json_string_value (json))); - len = strlen (enc); - buf_len = (len * 5) / 8; - buf = GNUNET_malloc (buf_len); - EXITIF (GNUNET_OK != - GNUNET_STRINGS_string_to_data (enc, - len, - buf, - buf_len)); - EXITIF (NULL == (pk = GNUNET_CRYPTO_rsa_public_key_decode (buf, - buf_len))); - GNUNET_free (buf); - return pk; - EXITIF_exit: - GNUNET_free_non_null (buf); - return NULL; -} - - -/** - * Convert JSON to RSA signature. - * - * @param json JSON encoding to convert - * @return corresponding signature - */ -struct GNUNET_CRYPTO_rsa_Signature * -TALER_json_to_rsa_signature (json_t *json) -{ - const char *enc; - char *buf; - size_t len; - size_t buf_len; - struct GNUNET_CRYPTO_rsa_Signature *sig; - - buf = NULL; - EXITIF (NULL == (enc = json_string_value (json))); - len = strlen (enc); - buf_len = (len * 5) / 8; - buf = GNUNET_malloc (buf_len); - EXITIF (GNUNET_OK != - GNUNET_STRINGS_string_to_data (enc, - len, - buf, - buf_len)); - EXITIF (NULL == (sig = GNUNET_CRYPTO_rsa_signature_decode (buf, - buf_len))); - GNUNET_free (buf); - return sig; - EXITIF_exit: - GNUNET_free_non_null (buf); - return NULL; -} - - -/** - * Convert RSA signature to JSON. - * - * @param sig signature to convert - * @return corresponding JSON encoding - */ -json_t * -TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig) -{ - char *buf; - size_t buf_len; - json_t *ret; - - buf_len = GNUNET_CRYPTO_rsa_signature_encode (sig, - &buf); - ret = TALER_json_from_data (buf, - buf_len); - GNUNET_free (buf); - return ret; -} - - -/** - * Convert binary data to a JSON string - * with the base32crockford encoding. - * - * @param data binary data - * @param size size of @a data in bytes - * @return json string that encodes @a data - */ -json_t * -TALER_json_from_data (const void *data, - size_t size) -{ - char *buf; - json_t *json; - - buf = GNUNET_STRINGS_data_to_string_alloc (data, size); - json = json_string (buf); - GNUNET_free (buf); - return json; -} - - -/** - * Parse given JSON object to Amount - * - * @param json the json object representing Amount - * @param[out] r_amount where the amount has to be written - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_amount (json_t *json, - struct TALER_Amount *r_amount) -{ - json_int_t value; - json_int_t fraction; - const char *currency; - - memset (r_amount, - 0, - sizeof (struct TALER_Amount)); - if (0 != json_unpack (json, - "{s:I, s:I, s:s}", - "value", &value, - "fraction", &fraction, - "currency", ¤cy)) - { - char *json_enc; - - if (NULL == (json_enc = json_dumps (json, - JSON_COMPACT | JSON_ENCODE_ANY))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Malformed JSON amount: %s\n", - json_enc); - free (json_enc); - return GNUNET_SYSERR; - } - if ( (value < 0) || - (fraction < 0) || - (value > UINT64_MAX) || - (fraction > UINT32_MAX) ) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (strlen (currency) >= TALER_CURRENCY_LEN) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - r_amount->value = (uint64_t) value; - r_amount->fraction = (uint32_t) fraction; - strcpy (r_amount->currency, currency); - (void) TALER_amount_normalize (r_amount); - return GNUNET_OK; -} - - -/** - * Parse given JSON object to absolute time. - * - * @param json the json object representing Amount - * @param[out] abs where the amount has to be written - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_abs (json_t *json, - struct GNUNET_TIME_Absolute *abs) -{ - const char *val; - unsigned long long int tval; - - val = json_string_value (json); - if (NULL == val) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (0 == strcasecmp (val, - "/forever/")) || - (0 == strcasecmp (val, - "/never/")) ) - { - *abs = GNUNET_TIME_UNIT_FOREVER_ABS; - return GNUNET_OK; - } - if (1 != sscanf (val, - "/Date(%llu)/", - &tval)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ - abs->abs_value_us = tval * 1000LL * 1000LL; - if ( (abs->abs_value_us) / 1000LL / 1000LL != tval) - { - /* Integer overflow */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Parse given JSON object to data - * - * @param json the json object representing data - * @param out the pointer to hold the parsed data. - * @param out_size the size of @a out - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -int -TALER_json_to_data (json_t *json, - void *out, - size_t out_size) -{ - const char *enc; - unsigned int len; - - EXITIF (NULL == (enc = json_string_value (json))); - len = strlen (enc); - EXITIF (((len * 5) / 8) != out_size); - EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, len, out, out_size)); - return GNUNET_OK; - EXITIF_exit: - return GNUNET_SYSERR; -} - - -/** - * Hash a JSON for binary signing. - * - * @param[in] json some JSON value - * @param[out] hc resulting hash code - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -int -TALER_hash_json (json_t *json, - struct GNUNET_HashCode *hc) -{ - char *wire_enc; - size_t len; - - if (NULL == (wire_enc = json_dumps (json, - JSON_COMPACT | JSON_SORT_KEYS))) - return GNUNET_SYSERR; - len = strlen (wire_enc) + 1; - GNUNET_CRYPTO_hash (wire_enc, - len, - hc); - free (wire_enc); - return GNUNET_OK; -} - - -/* End of util/json.c */ diff --git a/src/util/test_json.c b/src/util/test_json.c deleted file mode 100644 index 5e2f50fe8..000000000 --- a/src/util/test_json.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - This file is part of TALER - (C) 2015 GNUnet e.V. - - 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, If not, see -*/ - -/** - * @file util/test_json.c - * @brief Tests for Taler-specific crypto logic - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_util.h" -#include "taler_json_lib.h" - - -/** - * Test amount conversion from/to JSON. - * - * @return 0 on success - */ -static int -test_amount () -{ - json_t *j; - struct TALER_Amount a1; - struct TALER_Amount a2; - - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:4.3", - &a1)); - j = TALER_json_from_amount (&a1); - GNUNET_assert (NULL != j); - GNUNET_assert (GNUNET_OK == - TALER_json_to_amount (j, - &a2)); - GNUNET_assert (0 == - TALER_amount_cmp (&a1, - &a2)); - json_decref (j); - return 0; -} - - -/** - * Test time conversion from/to JSON. - * - * @return 0 on success - */ -static int -test_time () -{ - json_t *j; - struct GNUNET_TIME_Absolute a1; - struct GNUNET_TIME_Absolute a2; - - a1 = GNUNET_TIME_absolute_get (); - TALER_round_abs_time (&a1); - j = TALER_json_from_abs (a1); - GNUNET_assert (NULL != j); - GNUNET_assert (GNUNET_OK == - TALER_json_to_abs (j, - &a2)); - GNUNET_assert (a1.abs_value_us == - a2.abs_value_us); - json_decref (j); - - a1 = GNUNET_TIME_UNIT_FOREVER_ABS; - j = TALER_json_from_abs (a1); - GNUNET_assert (NULL != j); - GNUNET_assert (GNUNET_OK == - TALER_json_to_abs (j, - &a2)); - GNUNET_assert (a1.abs_value_us == - a2.abs_value_us); - json_decref (j); - return 0; -} - - -/** - * Test raw (binary) conversion from/to JSON. - * - * @return 0 on success - */ -static int -test_raw () -{ - char blob[256]; - char blob2[256]; - unsigned int i; - json_t *j; - - for (i=0;i<=256;i++) - { - memset (blob, i, i); - j = TALER_json_from_data (blob, i); - GNUNET_assert (NULL != j); - GNUNET_assert (GNUNET_OK == - TALER_json_to_data (j, - blob2, - i)); - GNUNET_assert (0 == - memcmp (blob, - blob2, - i)); - } - return 0; -} - - -/** - * Test rsa conversions from/to JSON. - * - * @return 0 on success - */ -static int -test_rsa () -{ - struct GNUNET_CRYPTO_rsa_PublicKey *pub; - struct GNUNET_CRYPTO_rsa_PublicKey *pub2; - struct GNUNET_CRYPTO_rsa_Signature *sig; - struct GNUNET_CRYPTO_rsa_Signature *sig2; - struct GNUNET_CRYPTO_rsa_PrivateKey *priv; - char msg[] = "Hello"; - json_t *jp; - json_t *js; - - priv = GNUNET_CRYPTO_rsa_private_key_create (1024); - pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); - sig = GNUNET_CRYPTO_rsa_sign (priv, - msg, - sizeof (msg)); - GNUNET_assert (NULL != (jp = TALER_json_from_rsa_public_key (pub))); - GNUNET_assert (NULL != (js = TALER_json_from_rsa_signature (sig))); - GNUNET_assert (NULL != (pub2 = TALER_json_to_rsa_public_key (jp))); - GNUNET_assert (NULL != (sig2 = TALER_json_to_rsa_signature (js))); - GNUNET_break (0 == - GNUNET_CRYPTO_rsa_signature_cmp (sig, - sig2)); - GNUNET_break (0 == - GNUNET_CRYPTO_rsa_public_key_cmp (pub, - pub2)); - GNUNET_CRYPTO_rsa_signature_free (sig); - GNUNET_CRYPTO_rsa_signature_free (sig2); - GNUNET_CRYPTO_rsa_private_key_free (priv); - GNUNET_CRYPTO_rsa_public_key_free (pub); - GNUNET_CRYPTO_rsa_public_key_free (pub2); - return 0; -} - - -int -main(int argc, - const char *const argv[]) -{ - GNUNET_log_setup ("test-json", - "WARNING", - NULL); - if (0 != test_amount ()) - return 1; - if (0 != test_time ()) - return 1; - if (0 != test_raw ()) - return 1; - if (0 != test_rsa ()) - return 1; - /* FIXME: test EdDSA signature conversion... */ - return 0; -} - -/* end of test_json.c */ diff --git a/src/util/util.c b/src/util/util.c index addafacf7..6dcd0dc29 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -56,7 +56,7 @@ TALER_b2s (const void *buf, GNUNET_free (tmp); ret[8] = '\0'; return ret; -} +} /** @@ -89,46 +89,6 @@ TALER_config_get_denom (struct GNUNET_CONFIGURATION_Handle *cfg, } -/** - * Round a time value so that it is suitable for transmission - * via JSON encodings. - * - * @param at time to round - * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if - * it was just now rounded - */ -int -TALER_round_abs_time (struct GNUNET_TIME_Absolute *at) -{ - if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) - return GNUNET_OK; - if (0 == at->abs_value_us % 1000000) - return GNUNET_OK; - at->abs_value_us -= at->abs_value_us % 1000000; - return GNUNET_NO; -} - - -/** - * Round a time value so that it is suitable for transmission - * via JSON encodings. - * - * @param rt time to round - * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if - * it was just now rounded - */ -int -TALER_round_rel_time (struct GNUNET_TIME_Relative *rt) -{ - if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) - return GNUNET_OK; - if (0 == rt->rel_value_us % 1000000) - return GNUNET_OK; - rt->rel_value_us -= rt->rel_value_us % 1000000; - return GNUNET_NO; -} - - /** * Load configuration by parsing all configuration * files in the given directory. diff --git a/src/util/wireformats.c b/src/util/wireformats.c deleted file mode 100644 index a69e8a093..000000000 --- a/src/util/wireformats.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. - - 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, If not, see -*/ -/** - * @file util/wireformats.c - * @brief helper functions for JSON processing using libjansson - * @author Sree Harsha Totakura - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include "taler_util.h" - -/** - * Shorthand for exit jumps. - */ -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - -/** - * Shorthand for JSON parsing related exit jumps. - */ -#define UNPACK_EXITIF(cond) \ - do { \ - if (cond) { TALER_json_warn (error); goto EXITIF_exit; } \ - } while (0) - - -/* Taken from GNU gettext */ - -/** - * Entry in the country table. - */ -struct table_entry -{ - /** - * 2-Character international country code. - */ - const char *code; - - /** - * Long English name of the country. - */ - const char *english; -}; - -/* Keep the following table in sync with gettext. - WARNING: the entries should stay sorted according to the code */ -/** - * List of country codes. - */ -static const struct table_entry country_table[] = - { - { "AE", "U.A.E." }, - { "AF", "Afghanistan" }, - { "AL", "Albania" }, - { "AM", "Armenia" }, - { "AN", "Netherlands Antilles" }, - { "AR", "Argentina" }, - { "AT", "Austria" }, - { "AU", "Australia" }, - { "AZ", "Azerbaijan" }, - { "BA", "Bosnia and Herzegovina" }, - { "BD", "Bangladesh" }, - { "BE", "Belgium" }, - { "BG", "Bulgaria" }, - { "BH", "Bahrain" }, - { "BN", "Brunei Darussalam" }, - { "BO", "Bolivia" }, - { "BR", "Brazil" }, - { "BT", "Bhutan" }, - { "BY", "Belarus" }, - { "BZ", "Belize" }, - { "CA", "Canada" }, - { "CG", "Congo" }, - { "CH", "Switzerland" }, - { "CI", "Cote d'Ivoire" }, - { "CL", "Chile" }, - { "CM", "Cameroon" }, - { "CN", "People's Republic of China" }, - { "CO", "Colombia" }, - { "CR", "Costa Rica" }, - { "CS", "Serbia and Montenegro" }, - { "CZ", "Czech Republic" }, - { "DE", "Germany" }, - { "DK", "Denmark" }, - { "DO", "Dominican Republic" }, - { "DZ", "Algeria" }, - { "EC", "Ecuador" }, - { "EE", "Estonia" }, - { "EG", "Egypt" }, - { "ER", "Eritrea" }, - { "ES", "Spain" }, - { "ET", "Ethiopia" }, - { "FI", "Finland" }, - { "FO", "Faroe Islands" }, - { "FR", "France" }, - { "GB", "United Kingdom" }, - { "GD", "Caribbean" }, - { "GE", "Georgia" }, - { "GL", "Greenland" }, - { "GR", "Greece" }, - { "GT", "Guatemala" }, - { "HK", "Hong Kong" }, - { "HK", "Hong Kong S.A.R." }, - { "HN", "Honduras" }, - { "HR", "Croatia" }, - { "HT", "Haiti" }, - { "HU", "Hungary" }, - { "ID", "Indonesia" }, - { "IE", "Ireland" }, - { "IL", "Israel" }, - { "IN", "India" }, - { "IQ", "Iraq" }, - { "IR", "Iran" }, - { "IS", "Iceland" }, - { "IT", "Italy" }, - { "JM", "Jamaica" }, - { "JO", "Jordan" }, - { "JP", "Japan" }, - { "KE", "Kenya" }, - { "KG", "Kyrgyzstan" }, - { "KH", "Cambodia" }, - { "KR", "South Korea" }, - { "KW", "Kuwait" }, - { "KZ", "Kazakhstan" }, - { "LA", "Laos" }, - { "LB", "Lebanon" }, - { "LI", "Liechtenstein" }, - { "LK", "Sri Lanka" }, - { "LT", "Lithuania" }, - { "LU", "Luxembourg" }, - { "LV", "Latvia" }, - { "LY", "Libya" }, - { "MA", "Morocco" }, - { "MC", "Principality of Monaco" }, - { "MD", "Moldava" }, - { "MD", "Moldova" }, - { "ME", "Montenegro" }, - { "MK", "Former Yugoslav Republic of Macedonia" }, - { "ML", "Mali" }, - { "MM", "Myanmar" }, - { "MN", "Mongolia" }, - { "MO", "Macau S.A.R." }, - { "MT", "Malta" }, - { "MV", "Maldives" }, - { "MX", "Mexico" }, - { "MY", "Malaysia" }, - { "NG", "Nigeria" }, - { "NI", "Nicaragua" }, - { "NL", "Netherlands" }, - { "NO", "Norway" }, - { "NP", "Nepal" }, - { "NZ", "New Zealand" }, - { "OM", "Oman" }, - { "PA", "Panama" }, - { "PE", "Peru" }, - { "PH", "Philippines" }, - { "PK", "Islamic Republic of Pakistan" }, - { "PL", "Poland" }, - { "PR", "Puerto Rico" }, - { "PT", "Portugal" }, - { "PY", "Paraguay" }, - { "QA", "Qatar" }, - { "RE", "Reunion" }, - { "RO", "Romania" }, - { "RS", "Serbia" }, - { "RU", "Russia" }, - { "RW", "Rwanda" }, - { "SA", "Saudi Arabia" }, - { "SE", "Sweden" }, - { "SG", "Singapore" }, - { "SI", "Slovenia" }, - { "SK", "Slovak" }, - { "SN", "Senegal" }, - { "SO", "Somalia" }, - { "SR", "Suriname" }, - { "SV", "El Salvador" }, - { "SY", "Syria" }, - { "TH", "Thailand" }, - { "TJ", "Tajikistan" }, - { "TM", "Turkmenistan" }, - { "TN", "Tunisia" }, - { "TR", "Turkey" }, - { "TT", "Trinidad and Tobago" }, - { "TW", "Taiwan" }, - { "TZ", "Tanzania" }, - { "UA", "Ukraine" }, - { "US", "United States" }, - { "UY", "Uruguay" }, - { "VA", "Vatican" }, - { "VE", "Venezuela" }, - { "VN", "Viet Nam" }, - { "YE", "Yemen" }, - { "ZA", "South Africa" }, - { "ZW", "Zimbabwe" } - }; - - -/** - * Country code comparator function, for binary search with bsearch(). - * - * @param ptr1 pointer to a `struct table_entry` - * @param ptr2 pointer to a `struct table_entry` - * @return result of strncmp()'ing the 2-digit country codes of the entries - */ -static int -cmp_country_code (const void *ptr1, - const void *ptr2) -{ - const struct table_entry *cc1 = ptr1; - const struct table_entry *cc2 = ptr2; - - return strncmp (cc1->code, cc2->code, 2); -} - - -/** - * Validates given IBAN according to the European Banking Standards. See: - * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf - * - * @param iban the IBAN number to validate - * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not - */ -static int -validate_iban (const char *iban) -{ - char cc[2]; - char ibancpy[35]; - struct table_entry cc_entry; - unsigned int len; - char *nbuf; - unsigned int i; - unsigned int j; - unsigned long long dividend; - unsigned long long remainder; - int nread; - int ret; - - len = strlen (iban); - if (len > 34) - return GNUNET_NO; - strncpy (cc, iban, 2); - strncpy (ibancpy, iban + 4, len - 4); - strncpy (ibancpy + len - 4, iban, 4); - ibancpy[len] = '\0'; - cc_entry.code = cc; - cc_entry.english = NULL; - if (NULL == - bsearch (&cc_entry, - country_table, - sizeof (country_table) / sizeof (struct table_entry), - sizeof (struct table_entry), - &cmp_country_code)) - return GNUNET_NO; - nbuf = GNUNET_malloc ((len * 2) + 1); - for (i=0, j=0; i < len; i++) - { - if (isalpha ((int) ibancpy[i])) - { - EXITIF(2 != snprintf(&nbuf[j], - 3, - "%2u", - (ibancpy[i] - 'A' + 10))); - j += 2; - continue; - } - nbuf[j] = ibancpy[i]; - j++; - } - for (j=0;'\0' != nbuf[j];j++) - GNUNET_assert (isdigit(nbuf[j])); - GNUNET_assert (sizeof(dividend) >= 8); - remainder = 0; - for (i=0; i /** @@ -58,6 +60,8 @@ sepa_amount_round (void *cls, struct SepaClosure *sc = cls; uint32_t delta; + if (NULL == sc->currency) + return GNUNET_SYSERR; if (0 != strcasecmp (amount->currency, sc->currency)) { @@ -347,42 +351,116 @@ validate_iban (const char *iban) } +/** + * Verify that the signature in the @a json for /wire/sepa is valid. + * + * @param json json reply with the signature + * @param master_pub public key of the exchange to verify against + * @return #GNUNET_SYSERR if @a json is invalid, + * #GNUNET_NO if the method is unknown, + * #GNUNET_OK if the json is valid + */ +static int +verify_wire_sepa_signature_ok (const json_t *json, + const struct TALER_MasterPublicKeyP *master_pub) +{ + struct TALER_MasterSignatureP exchange_sig; + struct TALER_MasterWireSepaDetailsPS mp; + const char *receiver_name; + const char *iban; + const char *bic; + struct GNUNET_HashContext *hc; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig), + GNUNET_JSON_spec_string ("receiver_name", &receiver_name), + GNUNET_JSON_spec_string ("iban", &iban), + GNUNET_JSON_spec_string ("bic", &bic), + GNUNET_JSON_spec_end() + }; + + if (NULL == master_pub) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Skipping signature check as master public key not given\n"); + return GNUNET_OK; + } + if (GNUNET_OK != + GNUNET_JSON_parse (json, spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS); + mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS)); + hc = GNUNET_CRYPTO_hash_context_start (); + GNUNET_CRYPTO_hash_context_read (hc, + receiver_name, + strlen (receiver_name) + 1); + GNUNET_CRYPTO_hash_context_read (hc, + iban, + strlen (iban) + 1); + GNUNET_CRYPTO_hash_context_read (hc, + bic, + strlen (bic) + 1); + GNUNET_CRYPTO_hash_context_finish (hc, + &mp.h_sepa_details); + + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS, + &mp.purpose, + &exchange_sig.eddsa_signature, + &master_pub->eddsa_pub)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return GNUNET_SYSERR; + } + GNUNET_JSON_parse_free (spec); + return GNUNET_OK; +} + + /** * Check if the given wire format JSON object is correctly formatted * + * @param cls the @e cls of this struct with the plugin-specific state * @param wire the JSON wire format object + * @param master_pub public key of the exchange to verify against * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ static int -sepa_wire_validate (const json_t *wire) +sepa_wire_validate (void *cls, + const json_t *wire, + const struct TALER_MasterPublicKeyP *master_pub) { json_error_t error; const char *type; const char *iban; const char *name; const char *bic; - uint64_t r; - const char *address; if (0 != json_unpack_ex ((json_t *) wire, - &error, JSON_STRICT, + &error, 0, "{" - "s:s," /* TYPE: sepa */ - "s:s," /* IBAN: iban */ - "s:s," /* name: beneficiary name */ - "s:s," /* BIC: beneficiary bank's BIC */ - "s:i," /* r: random 64-bit integer nounce */ - "s:s" /* address: address of the beneficiary */ + "s:s," /* type: sepa */ + "s:s," /* iban: IBAN */ + "s:s," /* receiver_name: beneficiary name */ + "s:s" /* bic: beneficiary bank's BIC */ "}", "type", &type, - "IBAN", &iban, - "name", &name, - "bic", &bic, - "r", &r, - "address", &address)) + "iban", &iban, + "receiver_name", &name, + "bic", &bic)) { - TALER_json_warn (error); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "JSON parsing failed at %s:%u: %s (%s)\n", + __FILE__, __LINE__, + error.text, error.source); + json_dumpf (wire, stderr, 0); + fprintf (stderr, "\n"); return GNUNET_SYSERR; } if (0 != strcasecmp (type, @@ -400,6 +478,15 @@ sepa_wire_validate (const json_t *wire) iban); return GNUNET_NO; } + /* FIXME: don't parse again, integrate properly... */ + if (GNUNET_OK != + verify_wire_sepa_signature_ok (wire, + master_pub)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Signature invalid\n"); + return GNUNET_NO; + } return GNUNET_YES; } @@ -499,19 +586,21 @@ libtaler_plugin_wire_sepa_init (void *cls) struct TALER_WIRE_Plugin *plugin; sc = GNUNET_new (struct SepaClosure); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "exchange", - "CURRENCY", - &sc->currency)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "exchange", - "CURRENCY"); - GNUNET_free (sc); - return NULL; - } - + if (NULL != cfg) + { + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "exchange", + "CURRENCY", + &sc->currency)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "CURRENCY"); + GNUNET_free (sc); + return NULL; + } + } plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = sc; plugin->amount_round = &sepa_amount_round; @@ -536,7 +625,7 @@ libtaler_plugin_wire_sepa_done (void *cls) struct TALER_WIRE_Plugin *plugin = cls; struct SepaClosure *sc = plugin->cls; - GNUNET_free (sc->currency); + GNUNET_free_non_null (sc->currency); GNUNET_free (sc); GNUNET_free (plugin); return NULL; diff --git a/src/wire/plugin_wire_template.c b/src/wire/plugin_wire_template.c index 2e9512e57..91b380c38 100644 --- a/src/wire/plugin_wire_template.c +++ b/src/wire/plugin_wire_template.c @@ -76,11 +76,15 @@ template_amount_round (void *cls, /** * Check if the given wire format JSON object is correctly formatted * + * @param cls the @e cls of this struct with the plugin-specific state * @param wire the JSON wire format object + * @param master_pub public key of the exchange to verify against * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ static int -template_wire_validate (const json_t *wire) +template_wire_validate (void *cls, + const json_t *wire, + const struct TALER_MasterPublicKeyP *master_pub) { GNUNET_break (0); return GNUNET_SYSERR; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 1d19edf57..70cf82462 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2016 GNUnet e.V. + Copyright (C) 2016 GNUnet e.V. & Inria 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 @@ -215,6 +215,8 @@ test_amount_round (void *cls, struct TestClosure *tc = cls; uint32_t delta; + if (NULL == tc->currency) + return GNUNET_SYSERR; /* not configured with currency */ if (0 != strcasecmp (amount->currency, tc->currency)) { @@ -235,11 +237,15 @@ test_amount_round (void *cls, * Right now, the only thing we require is a field * "account_number" which must contain a positive 53-bit integer. * + * @param cls the @e cls of this struct with the plugin-specific state * @param wire the JSON wire format object + * @param master_pub public key of the exchange to verify against * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ static int -test_wire_validate (const json_t *wire) +test_wire_validate (void *cls, + const json_t *wire, + const struct TALER_MasterPublicKeyP *master_pub) { json_error_t error; json_int_t account_no; @@ -368,7 +374,9 @@ test_prepare_wire_transfer (void *cls, struct TALER_WIRE_PrepareHandle *pth; if (GNUNET_YES != - test_wire_validate (wire)) + test_wire_validate (cls, + wire, + NULL)) { GNUNET_break (0); return NULL; @@ -456,6 +464,8 @@ test_execute_wire_transfer (void *cls, json_int_t account_no; struct BufFormatP bf; + if (NULL == tc->bank) + return NULL; /* not initialized with configuration, cannot do transfers */ if ( (buf_size <= sizeof (struct BufFormatP)) || ('\0' != buf[buf_size -1]) ) { @@ -476,7 +486,9 @@ test_execute_wire_transfer (void *cls, return NULL; } GNUNET_assert (GNUNET_YES == - test_wire_validate (wire)); + test_wire_validate (NULL, + wire, + NULL)); if (0 != json_unpack_ex (wire, &error, @@ -545,53 +557,56 @@ libtaler_plugin_wire_test_init (void *cls) struct TALER_WIRE_Plugin *plugin; char *uri; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-test", - "BANK_URI", - &uri)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "wire-test", - "BANK_URI"); - return NULL; - } tc = GNUNET_new (struct TestClosure); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, - "wire-test", - "BANK_ACCOUNT_NO_OUTGOING", - &tc->exchange_account_no)) + if (NULL != cfg) { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "wire-test", - "BANK_ACCOUNT_NO_OUTGOING"); - GNUNET_free (uri); - GNUNET_free (tc); - return NULL; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "exchange", - "CURRENCY", - &tc->currency)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "exchange", - "CURRENCY"); - GNUNET_free (uri); - GNUNET_free (tc); - return NULL; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "wire-test", + "BANK_URI", + &uri)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "wire-test", + "BANK_URI"); + GNUNET_free (tc); + return NULL; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "wire-test", + "BANK_ACCOUNT_NO_OUTGOING", + &tc->exchange_account_no)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "wire-test", + "BANK_ACCOUNT_NO_OUTGOING"); + GNUNET_free (uri); + GNUNET_free (tc); + return NULL; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "exchange", + "CURRENCY", + &tc->currency)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "CURRENCY"); + GNUNET_free (uri); + GNUNET_free (tc); + return NULL; + } + tc->bank = TALER_BANK_init (uri); + if (NULL == tc->bank) + { + GNUNET_break (0); + GNUNET_free (tc->currency); + GNUNET_free (tc); + return NULL; + } } - tc->bank = TALER_BANK_init (uri); - if (NULL == tc->bank) - { - GNUNET_break (0); - GNUNET_free (tc->currency); - GNUNET_free (tc); - return NULL; - } - plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = tc; plugin->amount_round = &test_amount_round; @@ -621,8 +636,12 @@ libtaler_plugin_wire_test_done (void *cls) GNUNET_SCHEDULER_cancel (tc->bt); tc->bt = NULL; } - TALER_BANK_fini (tc->bank); - GNUNET_free (tc->currency); + if (NULL != tc->bank) + { + TALER_BANK_fini (tc->bank); + tc->bank = NULL; + } + GNUNET_free_non_null (tc->currency); GNUNET_free (tc); GNUNET_free (plugin); return NULL; diff --git a/src/wire/test_sepa_wireformat.c b/src/wire/test_sepa_wireformat.c index 5081cbe86..f016cf635 100644 --- a/src/wire/test_sepa_wireformat.c +++ b/src/wire/test_sepa_wireformat.c @@ -28,37 +28,37 @@ /* Valid SEPA data */ static const char * const valid_wire_str = "{ \"type\":\"SEPA\", \ -\"IBAN\":\"DE67830654080004822650\", \ -\"name\":\"GNUnet e.V.\", \ +\"iban\":\"DE67830654080004822650\", \ +\"receiver_name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ -\"r\":123456789, \ +\"salt\":\"123456789\", \ \"address\": \"foobar\"}"; /* IBAN has wrong country code */ static const char * const invalid_wire_str = "{ \"type\":\"SEPA\", \ -\"IBAN\":\"XX67830654080004822650\", \ -\"name\":\"GNUnet e.V.\", \ +\"iban\":\"XX67830654080004822650\", \ +\"receiver_name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ -\"r\":123456789, \ +\"salt\":\"123456789\", \ \"address\": \"foobar\"}"; /* IBAN has wrong checksum */ static const char * const invalid_wire_str2 = "{ \"type\":\"SEPA\", \ -\"IBAN\":\"DE67830654080004822651\", \ -\"name\":\"GNUnet e.V.\", \ +\"iban\":\"DE67830654080004822651\", \ +\"receiver_name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ -\"r\":123456789, \ +\"salt\":\"123456789\", \ \"address\": \"foobar\"}"; /* Unsupported wireformat type */ static const char * const unsupported_wire_str = "{ \"type\":\"unsupported\", \ -\"IBAN\":\"DE67830654080004822650\", \ -\"name\":\"GNUnet e.V.\", \ +\"iban\":\"DE67830654080004822650\", \ +\"receiver_name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ -\"r\":123456789, \ +\"salt\":\"123456789\", \ \"address\": \"foobar\"}"; @@ -85,16 +85,24 @@ main(int argc, GNUNET_assert (NULL != plugin); (void) memset(&error, 0, sizeof(error)); GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL))); - GNUNET_assert (GNUNET_YES != plugin->wire_validate (wire)); + GNUNET_assert (GNUNET_YES != plugin->wire_validate (NULL, + wire, + NULL)); json_decref (wire); GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL))); - GNUNET_assert (GNUNET_NO == plugin->wire_validate (wire)); + GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL, + wire, + NULL)); json_decref (wire); GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL))); - GNUNET_assert (GNUNET_NO == plugin->wire_validate (wire)); + GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL, + wire, + NULL)); json_decref (wire); GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error))); - ret = plugin->wire_validate (wire); + ret = plugin->wire_validate (NULL, + wire, + NULL); json_decref (wire); TALER_WIRE_plugin_unload (plugin); GNUNET_CONFIGURATION_destroy (cfg); -- cgit v1.2.3 From 92907bee45681b1273172a3c88461a60bcae8589 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 Apr 2016 08:37:44 +0200 Subject: return nicer error message from bank API and fix compiler warning --- src/wire/plugin_wire_test.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/wire') diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 70cf82462..3ef76aa6b 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -419,22 +419,40 @@ test_prepare_wire_transfer_cancel (void *cls, * @param cls closure with the `struct TALER_WIRE_ExecuteHandle` * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the bank's reply is bogus (fails to follow the protocol) + * @param json detailed response from the HTTPD, or NULL if reply was not JSON */ static void execute_cb (void *cls, - unsigned int http_status) + unsigned int http_status, + json_t *json) { struct TALER_WIRE_ExecuteHandle *eh = cls; - char s[14]; + json_t *reason; + const char *emsg; + char *s; eh->aaih = NULL; - GNUNET_snprintf (s, - sizeof (s), - "%u", - http_status); + emsg = NULL; + if (NULL != json) + { + reason = json_object_get (json, + "reason"); + if (NULL != reason) + emsg = json_string_value (reason); + } + if (NULL != emsg) + GNUNET_asprintf (&s, + "%u (%s)", + http_status, + emsg); + else + GNUNET_asprintf (&s, + "%u", + http_status); eh->cc (eh->cc_cls, (MHD_HTTP_OK == http_status) ? GNUNET_OK : GNUNET_SYSERR, (MHD_HTTP_OK == http_status) ? NULL : s); + GNUNET_free (s); GNUNET_free (eh); } -- cgit v1.2.3 From de3e26303e0069614d4a5aa425e4fa5ddb088b8b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 Apr 2016 16:15:35 +0200 Subject: implementing #4356, tests still failing, but main logic should now be updated --- src/exchange-lib/exchange_api_wire.c | 319 ++++--------------------- src/exchange-lib/test_exchange_api.c | 96 +++----- src/exchange/taler-exchange-httpd.c | 16 +- src/exchange/taler-exchange-httpd_validation.c | 38 +-- src/exchange/taler-exchange-httpd_validation.h | 9 +- src/exchange/taler-exchange-httpd_wire.c | 188 +-------------- src/exchange/taler-exchange-httpd_wire.h | 37 +-- src/include/taler_exchange_service.h | 46 ++-- src/include/taler_signatures.h | 26 -- src/include/taler_wire_plugin.h | 15 ++ src/wire/plugin_wire_sepa.c | 60 ++++- src/wire/plugin_wire_template.c | 20 ++ src/wire/plugin_wire_test.c | 53 ++++ 13 files changed, 277 insertions(+), 646 deletions(-) (limited to 'src/wire') diff --git a/src/exchange-lib/exchange_api_wire.c b/src/exchange-lib/exchange_api_wire.c index 27ae1dce7..0e93a9d20 100644 --- a/src/exchange-lib/exchange_api_wire.c +++ b/src/exchange-lib/exchange_api_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 Inria and GNUnet e.V. 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 @@ -128,257 +128,6 @@ verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh, } -/** - * Perform the next /wire/method request or signal - * the end of the iteration. - * - * @param wh the wire handle - * @return a handle for this request - */ -static void -request_wire_method (struct TALER_EXCHANGE_WireHandle *wh); - - -/** - * Function called when we're done processing the - * HTTP /wire/METHOD request. - * - * @param cls the `struct TALER_EXCHANGE_WireHandle` - * @param eh the curl request handle - */ -static void -handle_wire_method_finished (void *cls, - CURL *eh) -{ - struct TALER_EXCHANGE_WireHandle *wh = cls; - long response_code; - json_t *json; - - wh->job = NULL; - json = MAC_download_get_result (&wh->db, - eh, - &response_code); - switch (response_code) - { - case 0: - break; - case MHD_HTTP_OK: - { - const char *method; - - method = json_string_value (json_array_get (wh->methods, - wh->methods_off - 1)); - if (GNUNET_OK != - verify_wire_method_signature_ok (wh, - method, - json)) - { - GNUNET_break_op (0); - response_code = 0; - break; - } - break; - } - case MHD_HTTP_FOUND: - /* /wire/test returns a 302 redirect, we should just give - this information back to the callback below */ - 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 */ - break; - case MHD_HTTP_NOT_FOUND: - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the application */ - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ - break; - default: - /* unexpected response code */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u\n", - response_code); - GNUNET_break (0); - response_code = 0; - break; - } - if (0 == response_code) - { - /* signal end of iteration */ - wh->cb (wh->cb_cls, - 0, - NULL, - NULL); - json_decref (json); - TALER_EXCHANGE_wire_cancel (wh); - return; - } - /* pass on successful reply */ - wh->cb (wh->cb_cls, - response_code, - json_string_value (json_array_get (wh->methods, - wh->methods_off-1)), - json); - json_decref (json); - /* trigger request for the next /wire/method */ - request_wire_method (wh); -} - - -/** - * Perform the next /wire/method request or signal - * the end of the iteration. - * - * @param wh the wire handle - * @return a handle for this request - */ -static void -request_wire_method (struct TALER_EXCHANGE_WireHandle *wh) -{ - struct TALER_EXCHANGE_Context *ctx; - CURL *eh; - char *path; - - if (json_array_size (wh->methods) <= wh->methods_off) - { - /* we are done, signal end of iteration */ - wh->cb (wh->cb_cls, - 0, - NULL, - NULL); - TALER_EXCHANGE_wire_cancel (wh); - return; - } - GNUNET_free_non_null (wh->db.buf); - wh->db.buf = NULL; - wh->db.buf_size = 0; - wh->db.eno = 0; - GNUNET_free_non_null (wh->url); - GNUNET_asprintf (&path, - "/wire/%s", - json_string_value (json_array_get (wh->methods, - wh->methods_off++))); - wh->url = MAH_path_to_url (wh->exchange, - path); - GNUNET_free (path); - - eh = curl_easy_init (); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_URL, - wh->url)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_WRITEFUNCTION, - &MAC_download_cb)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_WRITEDATA, - &wh->db)); - /* The default is 'disabled', but let's be sure */ - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_FOLLOWLOCATION, - (long) 0)); - ctx = MAH_handle_to_context (wh->exchange); - wh->job = MAC_job_add (ctx, - eh, - GNUNET_YES, - &handle_wire_method_finished, - wh); - TALER_EXCHANGE_perform (ctx); -} - - -/** - * Verify that the signature on the "200 OK" response - * for /wire from the exchange is valid. - * - * @param wh wire handle - * @param json json reply with the signature - * @return NULL if @a json is invalid, otherwise the - * "methods" array (with an RC of 1) - */ -static json_t * -verify_wire_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh, - json_t *json) -{ - struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; - struct TALER_ExchangeWireSupportMethodsPS mp; - json_t *methods; - const struct TALER_EXCHANGE_Keys *key_state; - struct GNUNET_HashContext *hc; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", &exchange_pub), - GNUNET_JSON_spec_json ("methods", &methods), - GNUNET_JSON_spec_end() - }; - unsigned int i; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return NULL; - } - if (! json_is_array (methods)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return NULL; - } - - key_state = TALER_EXCHANGE_get_keys (wh->exchange); - if (GNUNET_OK != - TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) - { - GNUNET_break_op (0); - return NULL; - } - hc = GNUNET_CRYPTO_hash_context_start (); - for (i=0;imethods = methods; - request_wire_method (wh); - return; + else + { + /* some supported methods were invalid, release 'keep', preserve + full 'json' for application-level error handling. */ + json_decref (keep); + } } break; case MHD_HTTP_BAD_REQUEST: @@ -440,19 +217,9 @@ handle_wire_finished (void *cls, response_code = 0; break; } - if (0 != response_code) - { - /* pass on successful reply */ - wh->cb (wh->cb_cls, - response_code, - NULL, - json); - } - /* signal end of iteration */ wh->cb (wh->cb_cls, - 0, - NULL, - NULL); + response_code, + json); if (NULL != json) json_decref (json); TALER_EXCHANGE_wire_cancel (wh); @@ -481,8 +248,8 @@ handle_wire_finished (void *cls, */ struct TALER_EXCHANGE_WireHandle * TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange, - TALER_EXCHANGE_WireResultCallback wire_cb, - void *wire_cb_cls) + TALER_EXCHANGE_WireResultCallback wire_cb, + void *wire_cb_cls) { struct TALER_EXCHANGE_WireHandle *wh; struct TALER_EXCHANGE_Context *ctx; diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 2a7f670cd..6eae08f4d 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. and Inria 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 @@ -1213,76 +1213,56 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys, * Callbacks called with the result(s) of a * wire format inquiry request to the exchange. * - * The callback is invoked multiple times, once for each supported @a - * method. Finally, it is invoked one more time with cls/0/NULL/NULL - * to indicate the end of the iteration. If any request fails to - * generate a valid response from the exchange, @a http_status will also - * be zero and the iteration will also end. Thus, the iteration - * always ends with a final call with an @a http_status of 0. If the - * @a http_status is already 0 on the first call, then the response to - * the /wire request was invalid. Later, clients can tell the - * difference between @a http_status of 0 indicating a failed - * /wire/method request and a regular end of the iteration by @a - * method being non-NULL. If the exchange simply correctly asserts that - * it does not support any methods, @a method will be NULL but the @a - * http_status will be #MHD_HTTP_OK for the first call (followed by a - * cls/0/NULL/NULL call to signal the end of the iteration). - * * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request; * 0 if the exchange's reply is bogus (fails to follow the protocol) - * @param method wire format method supported, i.e. "test" or "sepa", or NULL - * if already the /wire request failed. * @param obj the received JSON reply, if successful this should be the wire - * format details as provided by /wire/METHOD/, or NULL if the - * reply was not in JSON format (in this case, the client might - * want to do an HTTP request to /wire/METHOD/ with a browser to - * provide more information to the user about the @a method). + * format details as provided by /wire. */ static void wire_cb (void *cls, unsigned int http_status, - const char *method, json_t *obj) { struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; - if (0 == http_status) - { - /* 0 always signals the end of the iteration */ - cmd->details.wire.wh = NULL; - } - else if ( (NULL != method) && - (0 != strcasecmp (method, - cmd->details.wire.format)) ) - { - /* not the method we care about, skip */ - return; - } if (cmd->expected_response_code != http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s/%s\n", + "Unexpected response code %u to command %s\n", http_status, - cmd->label, - method); + cmd->label); json_dumpf (obj, stderr, 0); fail (is); return; } - if (0 == http_status) + switch (http_status) { - /* end of iteration, move to next command */ - is->ip++; - is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, - is); - return; + case MHD_HTTP_OK: + { + json_t *method; + + method = json_object_get (obj, + cmd->details.wire.format); + if (NULL == method) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected method `%s' not included in response to command %s\n", + cmd->details.wire.format, + cmd->label); + json_dumpf (obj, stderr, 0); + fail (is); + return; + } + } + break; + default: + break; } - /* For now, we only support to be called only once - with a "positive" result; so we switch to an - expected value of 0 for the 2nd iteration */ - cmd->expected_response_code = 0; + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); } @@ -1899,9 +1879,9 @@ interpreter_run (void *cls, /* finally, use private key from withdraw sign command */ cmd->details.refresh_link.rlh = TALER_EXCHANGE_refresh_link (exchange, - &ref->details.reserve_withdraw.coin_priv, - &link_cb, - is); + &ref->details.reserve_withdraw.coin_priv, + &link_cb, + is); if (NULL == cmd->details.refresh_link.rlh) { GNUNET_break (0); @@ -1912,8 +1892,8 @@ interpreter_run (void *cls, return; case OC_WIRE: cmd->details.wire.wh = TALER_EXCHANGE_wire (exchange, - &wire_cb, - is); + &wire_cb, + is); trigger_context_task (); return; case OC_WIRE_DEPOSITS: @@ -1926,9 +1906,9 @@ interpreter_run (void *cls, } cmd->details.wire_deposits.wdh = TALER_EXCHANGE_wire_deposits (exchange, - &cmd->details.wire_deposits.wtid, - &wire_deposits_cb, - is); + &cmd->details.wire_deposits.wtid, + &wire_deposits_cb, + is); trigger_context_task (); return; case OC_DEPOSIT_WTID: @@ -2337,14 +2317,14 @@ run (void *cls, #if WIRE_TEST { .oc = OC_WIRE, .label = "wire-test", - /* /wire/test replies with a 200 OK */ + /* expecting 'test' method in response */ .expected_response_code = MHD_HTTP_OK, .details.wire.format = "test" }, #endif #if WIRE_SEPA { .oc = OC_WIRE, .label = "wire-sepa", - /* /wire/sepa replies with a 200 redirect */ + /* expecting 'sepa' method in response */ .expected_response_code = MHD_HTTP_OK, .details.wire.format = "sepa" }, #endif diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 877876dbb..2ef58b0f7 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 Inria and GNUnet e.V. 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 @@ -177,20 +177,6 @@ handle_mhd_request (void *cls, "Only GET is allowed", 0, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, - { "/wire/test", MHD_HTTP_METHOD_GET, "application/json", - NULL, 0, - &TMH_WIRE_handler_wire_test, MHD_HTTP_FOUND }, - { "/wire/test", NULL, "text/plain", - "Only GET is allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, - - { "/wire/sepa", MHD_HTTP_METHOD_GET, "application/json", - NULL, 0, - &TMH_WIRE_handler_wire_sepa, MHD_HTTP_OK }, - { "/wire/sepa", NULL, "text/plain", - "Only GET is allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, - /* Withdrawing coins / interaction with reserves */ { "/reserve/status", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, diff --git a/src/exchange/taler-exchange-httpd_validation.c b/src/exchange/taler-exchange-httpd_validation.c index b7e8a7f80..0b72960c5 100644 --- a/src/exchange/taler-exchange-httpd_validation.c +++ b/src/exchange/taler-exchange-httpd_validation.c @@ -200,33 +200,39 @@ TMH_VALIDATION_test_method (const char *type) /** - * Obtain supported validation methods as a JSON array, - * and as a hash. + * Obtain JSON of the supported wire methods for a given + * account name prefix. * - * @param[out] h set to the hash of the JSON methods + * @param prefix prefix for the account, the suffix will + * be determined by the name of the plugin * @return JSON array with the supported validation methods */ json_t * -TMH_VALIDATION_get_methods (struct GNUNET_HashCode *h) +TMH_VALIDATION_get_wire_methods (const char *prefix) { json_t *methods; - struct GNUNET_HashContext *hc; - const char *wf; + json_t *method; struct Plugin *p; + struct TALER_WIRE_Plugin *plugin; + char *account_name; - methods = json_array (); - hc = GNUNET_CRYPTO_hash_context_start (); + methods = json_object (); for (p=wire_head;NULL != p;p = p->next) { - wf = p->type; - json_array_append_new (methods, - json_string (wf)); - GNUNET_CRYPTO_hash_context_read (hc, - wf, - strlen (wf) + 1); + plugin = p->plugin; + GNUNET_asprintf (&account_name, + "%s-%s\n", + prefix, + p->type); + method = plugin->get_wire_details (plugin->cls, + cfg, + account_name); + if (NULL != method) + json_object_set_new (methods, + p->type, + method); + GNUNET_free (account_name); } - GNUNET_CRYPTO_hash_context_finish (hc, - h); return methods; } diff --git a/src/exchange/taler-exchange-httpd_validation.h b/src/exchange/taler-exchange-httpd_validation.h index f41e2ee5f..a5403edd4 100644 --- a/src/exchange/taler-exchange-httpd_validation.h +++ b/src/exchange/taler-exchange-httpd_validation.h @@ -63,14 +63,15 @@ TMH_VALIDATION_test_method (const char *type); /** - * Obtain supported validation methods as a JSON array, - * and as a hash. + * Obtain JSON of the supported wire methods for a given + * account name prefix. * - * @param[out] h set to the hash of the JSON methods + * @param prefix prefix for the account, the suffix will + * be determined by the name of the plugin * @return JSON array with the supported validation methods */ json_t * -TMH_VALIDATION_get_methods (struct GNUNET_HashCode *h); +TMH_VALIDATION_get_wire_methods (const char *prefix); #endif diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index 1b3d3b541..975788b35 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -43,191 +43,15 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size) { - struct TALER_ExchangeWireSupportMethodsPS wsm; - struct TALER_ExchangePublicKeyP pub; - struct TALER_ExchangeSignatureP sig; - json_t *methods; + static json_t *wire_methods; - wsm.purpose.size = htonl (sizeof (wsm)); - wsm.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_WIRE_TYPES); - methods = TMH_VALIDATION_get_methods (&wsm.h_wire_types); - TMH_KS_sign (&wsm.purpose, - &pub, - &sig); - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:o, s:o, s:o}", - "methods", methods, - "sig", GNUNET_JSON_from_data (&sig, - sizeof (sig)), - "pub", GNUNET_JSON_from_data (&pub, - sizeof (pub))); -} - - -/** - * Handle a "/wire/test" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -int -TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - struct MHD_Response *response; - int ret; - char *bank_uri; - unsigned long long account_number; + if (NULL == wire_methods) + wire_methods = TMH_VALIDATION_get_wire_methods ("wire-incoming"); - response = MHD_create_response_from_buffer (0, NULL, - MHD_RESPMEM_PERSISTENT); - if (NULL == response) - { - GNUNET_break (0); - return MHD_NO; - } - TMH_RESPONSE_add_global_headers (response); - if (GNUNET_NO == TMH_VALIDATION_test_method ("test")) - { - /* Return 501: not implemented */ - ret = MHD_queue_response (connection, - MHD_HTTP_NOT_IMPLEMENTED, - response); - MHD_destroy_response (response); - return ret; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-test", - "BANK_URI", - &bank_uri)) - { - /* oopsie, configuration error */ - MHD_destroy_response (response); - return TMH_RESPONSE_reply_internal_error (connection, - "BANK_URI not configured"); - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, - "wire-test", - "BANK_ACCOUNT_NO_INCOMING", - &account_number)) - { - /* oopsie, configuration error */ - MHD_destroy_response (response); - GNUNET_free (bank_uri); - return TMH_RESPONSE_reply_internal_error (connection, - "BANK_ACCOUNT_NO_INCOMING not configured"); - } - ret = TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:s, s:I, s:s}", - "type", "test", - "account_number", (json_int_t) account_number, - "bank_uri", bank_uri); - GNUNET_free (bank_uri); - return ret; + return TMH_RESPONSE_reply_json (connection, + wire_methods, + MHD_HTTP_OK); } -/** - * Handle a "/wire/sepa" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -int -TMH_WIRE_handler_wire_sepa (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - struct MHD_Response *response; - int ret; - char *sepa_wire_file; - int fd; - struct stat sbuf; - - if (GNUNET_NO == TMH_VALIDATION_test_method ("sepa")) - { - /* Return 501: not implemented */ - response = MHD_create_response_from_buffer (0, NULL, - MHD_RESPMEM_PERSISTENT); - if (NULL == response) - { - GNUNET_break (0); - return MHD_NO; - } - TMH_RESPONSE_add_global_headers (response); - ret = MHD_queue_response (connection, - MHD_HTTP_NOT_IMPLEMENTED, - response); - MHD_destroy_response (response); - return ret; - } - /* Fetch reply */ - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, - "wire-sepa", - "SEPA_RESPONSE_FILE", - &sepa_wire_file)) - { - return TMH_RESPONSE_reply_internal_error (connection, - "SEPA_RESPONSE_FILE not configured"); - } - fd = open (sepa_wire_file, - O_RDONLY); - if (-1 == fd) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, - "open", - sepa_wire_file); - GNUNET_free (sepa_wire_file); - return TMH_RESPONSE_reply_internal_error (connection, - "Failed to open SEPA_RESPONSE_FILE"); - } - if (0 != fstat (fd, &sbuf)) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, - "fstat", - sepa_wire_file); - (void) close (fd); - GNUNET_free (sepa_wire_file); - return TMH_RESPONSE_reply_internal_error (connection, - "Failed to open SEPA_RESPONSE_FILE"); - } - response = MHD_create_response_from_fd ((size_t) sbuf.st_size, - fd); - GNUNET_free (sepa_wire_file); - if (NULL == response) - { - (void) close (fd); - GNUNET_break (0); - return MHD_NO; - } - TMH_RESPONSE_add_global_headers (response); - if (NULL != rh->mime_type) - (void) MHD_add_response_header (response, - MHD_HTTP_HEADER_CONTENT_TYPE, - rh->mime_type); - ret = MHD_queue_response (connection, - rh->response_code, - response); - MHD_destroy_response (response); - return ret; -} - /* end of taler-exchange-httpd_wire.c */ diff --git a/src/exchange/taler-exchange-httpd_wire.h b/src/exchange/taler-exchange-httpd_wire.h index dc6dcc0f4..cf04f16ff 100644 --- a/src/exchange/taler-exchange-httpd_wire.h +++ b/src/exchange/taler-exchange-httpd_wire.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 Inria and GNUnet e.V. 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 @@ -44,39 +44,4 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh, size_t *upload_data_size); -/** - * Handle a "/wire/test" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -int -TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - - -/** - * Handle a "/wire/sepa" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[in,out] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[in,out] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -int -TMH_WIRE_handler_wire_sepa (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - #endif diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e4aa89a59..4a1592cf2 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -396,53 +396,35 @@ struct TALER_EXCHANGE_WireHandle; * Callbacks of this type are used to serve the result of submitting a * wire format inquiry request to a exchange. * - * The callback is invoked multiple times, once for each supported @a - * method. Finally, it is invoked one more time with cls/0/NULL/NULL - * to indicate the end of the iteration. If any request fails to - * generate a valid response from the exchange, @a http_status will also - * be zero and the iteration will also end. Thus, the iteration - * always ends with a final call with an @a http_status of 0. If the - * @a http_status is already 0 on the first call, then the response to - * the /wire request was invalid. Later, clients can tell the - * difference between @a http_status of 0 indicating a failed - * /wire/method request and a regular end of the iteration by @a - * method being non-NULL. If the exchange simply correctly asserts that - * it does not support any methods, @a method will be NULL but the @a - * http_status will be #MHD_HTTP_OK for the first call (followed by a - * cls/0/NULL/NULL call to signal the end of the iteration). + * If the request fails to generate a valid response from the + * exchange, @a http_status will also be zero. * * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request; * 0 if the exchange's reply is bogus (fails to follow the protocol) - * @param method wire format method supported, i.e. "test" or "sepa", or NULL - * if already the /wire request failed. * @param obj the received JSON reply, if successful this should be the wire - * format details as provided by /wire/METHOD/, or NULL if the - * reply was not in JSON format (in this case, the client might - * want to do an HTTP request to /wire/METHOD/ with a browser to - * provide more information to the user about the @a method). + * format details as provided by /wire, or NULL if the + * reply was not in JSON format. */ typedef void (*TALER_EXCHANGE_WireResultCallback) (void *cls, unsigned int http_status, - const char *method, json_t *obj); /** - * Obtain information about a exchange's wire instructions. - * A exchange may provide wire instructions for creating - * a reserve. The wire instructions also indicate - * which wire formats merchants may use with the exchange. - * This API is typically used by a wallet for wiring - * funds, and possibly by a merchant to determine - * supported wire formats. + * Obtain information about a exchange's wire instructions. A + * exchange may provide wire instructions for creating a reserve. The + * wire instructions also indicate which wire formats merchants may + * use with the exchange. This API is typically used by a wallet for + * wiring funds, and possibly by a merchant to determine supported + * wire formats. * * Note that while we return the (main) response verbatim to the * caller for further processing, we do already verify that the * response is well-formed (i.e. that signatures included in the - * response are all valid). If the exchange's reply is not well-formed, - * we return an HTTP status code of zero to @a cb. + * response are all valid). If the exchange's reply is not + * well-formed, we return an HTTP status code of zero to @a cb. * * @param exchange the exchange handle; the exchange must be ready to operate * @param wire_cb the callback to call when a reply for this request is available @@ -451,8 +433,8 @@ typedef void */ struct TALER_EXCHANGE_WireHandle * TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange, - TALER_EXCHANGE_WireResultCallback wire_cb, - void *wire_cb_cls); + TALER_EXCHANGE_WireResultCallback wire_cb, + void *wire_cb_cls); /** diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index d958f16ba..23bdaa578 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -101,11 +101,6 @@ */ #define TALER_SIGNATURE_EXCHANGE_KEY_SET 1035 -/** - * Signature where the Exchange confirms the /wire response. - */ -#define TALER_SIGNATURE_EXCHANGE_WIRE_TYPES 1036 - /** * Signature where the Exchange confirms the /deposit/wtid response. */ @@ -784,27 +779,6 @@ struct TALER_MasterWireSepaDetailsPS }; -/** - * @brief Information signed by a exchange's online signing key affirming - * the wire formats supported by the exchange. - */ -struct TALER_ExchangeWireSupportMethodsPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_WIRE_TYPES. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the various wire formats supported by this exchange - * (all as 0-terminated strings). - */ - struct GNUNET_HashCode h_wire_types GNUNET_PACKED; - -}; - - /** * @brief Format used to generate the signature on a request to obtain * the wire transfer identifier associated with a deposit. diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h index c80aa2e49..e166558a7 100644 --- a/src/include/taler_wire_plugin.h +++ b/src/include/taler_wire_plugin.h @@ -98,6 +98,21 @@ struct TALER_WIRE_Plugin struct TALER_Amount *amount); + /** + * Obtain wire transfer details in the plugin-specific format + * from the configuration. + * + * @param cls closure + * @param cfg configuration with details about wire accounts + * @param account_name which section in the configuration should we parse + * @return NULL if @a cfg fails to have valid wire details for @a account_name + */ + json_t * + (*get_wire_details)(void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *account_name); + + /** * Check if the given wire format JSON object is correctly formatted * diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c index 904afa9bf..995436725 100644 --- a/src/wire/plugin_wire_sepa.c +++ b/src/wire/plugin_wire_sepa.c @@ -380,7 +380,7 @@ verify_wire_sepa_signature_ok (const json_t *json, if (NULL == master_pub) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping signature check as master public key not given\n"); return GNUNET_OK; } @@ -491,6 +491,63 @@ sepa_wire_validate (void *cls, } +/** + * Obtain wire transfer details in the plugin-specific format + * from the configuration. + * + * @param cls closure + * @param cfg configuration with details about wire accounts + * @param account_name which section in the configuration should we parse + * @return NULL if @a cfg fails to have valid wire details for @a account_name + */ +static json_t * +sepa_get_wire_details (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *account_name) +{ + char *sepa_wire_file; + json_error_t err; + json_t *ret; + + /* Fetch reply */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + account_name, + "SEPA_RESPONSE_FILE", + &sepa_wire_file)) + { + return NULL; + } + ret = json_load_file (sepa_wire_file, + JSON_REJECT_DUPLICATES, + &err); + if (NULL == ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse JSON in %s: %s (%s:%u)\n", + sepa_wire_file, + err.text, + err.source, + err.line); + GNUNET_free (sepa_wire_file); + return NULL; + } + if (GNUNET_YES != sepa_wire_validate (cls, + ret, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to validate SEPA data in %s\n", + sepa_wire_file); + GNUNET_free (sepa_wire_file); + json_decref (ret); + return NULL; + } + GNUNET_free (sepa_wire_file); + return ret; +} + + /** * Prepare for exeuction of a wire transfer. * @@ -604,6 +661,7 @@ libtaler_plugin_wire_sepa_init (void *cls) plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = sc; plugin->amount_round = &sepa_amount_round; + plugin->get_wire_details = &sepa_get_wire_details; plugin->wire_validate = &sepa_wire_validate; plugin->prepare_wire_transfer = &sepa_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel; diff --git a/src/wire/plugin_wire_template.c b/src/wire/plugin_wire_template.c index 91b380c38..fd6fbfbe9 100644 --- a/src/wire/plugin_wire_template.c +++ b/src/wire/plugin_wire_template.c @@ -73,6 +73,25 @@ template_amount_round (void *cls, } +/** + * Obtain wire transfer details in the plugin-specific format + * from the configuration. + * + * @param cls closure + * @param cfg configuration with details about wire accounts + * @param account_name which section in the configuration should we parse + * @return NULL if @a cfg fails to have valid wire details for @a account_name + */ +static json_t * +template_get_wire_details (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *account_name) +{ + GNUNET_break (0); + return NULL; +} + + /** * Check if the given wire format JSON object is correctly formatted * @@ -216,6 +235,7 @@ libtaler_plugin_wire_template_init (void *cls) plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = tc; plugin->amount_round = &template_amount_round; + plugin->get_wire_details = &template_get_wire_details; plugin->wire_validate = &template_wire_validate; plugin->prepare_wire_transfer = &template_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 3ef76aa6b..a03f8127d 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -232,6 +232,58 @@ test_amount_round (void *cls, } +/** + * Obtain wire transfer details in the plugin-specific format + * from the configuration. + * + * @param cls closure + * @param cfg configuration with details about wire accounts + * @param account_name which section in the configuration should we parse + * @return NULL if @a cfg fails to have valid wire details for @a account_name + */ +static json_t * +test_get_wire_details (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *account_name) +{ + json_t *ret; + char *bank_uri; + unsigned long long account_number; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + account_name, + "BANK_URI", + &bank_uri)) + { + /* oopsie, configuration error */ + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + account_name, + "BANK_URI"); + return NULL; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + account_name, + "BANK_ACCOUNT_NUMBER", + &account_number)) + { + /* oopsie, configuration error */ + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + account_name, + "BANK_URI"); + GNUNET_free (bank_uri); + return NULL; + } + ret = json_pack ("{s:s, s:I, s:s}", + "type", "test", + "account_number", (json_int_t) account_number, + "bank_uri", bank_uri); + GNUNET_free (bank_uri); + return ret; +} + + /** * Check if the given wire format JSON object is correctly formatted. * Right now, the only thing we require is a field @@ -628,6 +680,7 @@ libtaler_plugin_wire_test_init (void *cls) plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = tc; plugin->amount_round = &test_amount_round; + plugin->get_wire_details = &test_get_wire_details; plugin->wire_validate = &test_wire_validate; plugin->prepare_wire_transfer = &test_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel; -- cgit v1.2.3 From 9bc96506bb6441467c6558f5252e803c4292c9fe Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 Apr 2016 17:32:10 +0200 Subject: update man pages and templates to use current options --- .../exchange-template/config/exchange-common.conf | 16 ++++++++++++---- doc/taler.conf.5 | 16 +++++++++------- .../test-exchange-home/config/exchange-common.conf | 21 +++++++++++++-------- src/exchange-lib/test_exchange_api.c | 1 + .../test-exchange-home/config/exchange-common.conf | 12 +++++++++--- src/wire/plugin_wire_test.c | 21 +++++++++++---------- 6 files changed, 55 insertions(+), 32 deletions(-) (limited to 'src/wire') diff --git a/contrib/exchange-template/config/exchange-common.conf b/contrib/exchange-template/config/exchange-common.conf index 26bf4ff94..eddde3c32 100644 --- a/contrib/exchange-template/config/exchange-common.conf +++ b/contrib/exchange-template/config/exchange-common.conf @@ -21,15 +21,23 @@ TESTRUN = YES [exchangedb-postgres] DB_CONN_STR = "postgres:///talercheck" -[wire-sepa] +[wire-incoming-sepa] SEPA_RESPONSE_FILE = "sepa.json" -[wire-test] +[wire-outgoing-sepa] +SEPA_RESPONSE_FILE = "sepa.json" + + +[wire-incoming-test] # What is the main website of the bank? BANK_URI = "https://bank/" # Into which account at the 'bank' should incoming # wire transfers be made? -BANK_ACCOUNT_NO_INCOMING = 2 +BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] +# What is the main website of the bank? +BANK_URI = "https://bank/" # From which account at the 'bank' should outgoing # wire transfers be made? -BANK_ACCOUNT_NO_OUTGOING = 2 +BANK_ACCOUNT_NUMBER = 2 diff --git a/doc/taler.conf.5 b/doc/taler.conf.5 index f9d9d6312..e4c7083d6 100644 --- a/doc/taler.conf.5 +++ b/doc/taler.conf.5 @@ -28,20 +28,23 @@ The following options are from the "[exchange]" section and used by most exchang .SH WIRE transfer details -The following options must be in section "[exchange-wire-test]": +The following options must be in section "[wire\-incoming\-test]" and "[wire\-outgoing\-test]": -.IP REDIRECT_URL - URL to redirect /wire/test to. Should contain a Web form the user can use to charge his wallet with coins in a "test" currency for testing. If this option is not provided, /wire/test will return "501 NOT IMPLEMENTED". +.IP BANK_URI + URL of the Taler bank. -The following options must be in section "[exchange-wire-sepa]": +.IP BANK_ACCOUNT_NUMBER + Number of the bank account of the exchange. + +The following options must be in section "[wire\-incoming\-sepa]" and "[wire\-outgoing\-sepa]": .IP SEPA_RESPONSE_FILE - Filename with the JSON body for the /wire/sepa response, signed using the exchange's long-term offline master key. If this option is not provided, /wire/test will return "501 NOT IMPLEMENTED". Use "taler-exchange-sepa" to create the SEPA_RESPONSE_FILE. + Filename with the JSON body for the /wire response, signed using the exchange\'s long-term offline master key. Use taler\-exchange\-sepa to create the SEPA_RESPONSE_FILE. .SH Postgres database options -The following options must be in section "[exchangedb-postgres]": +The following options must be in section "[exchangedb\-postgres]": .IP DB_CONN_STR How to access the database, i.e. "postgres:///taler" to use the "taler" database. Testcases use "talercheck". @@ -86,4 +89,3 @@ Report bugs by using Mantis or by sending electronic .SH "SEE ALSO" \fBtaler\-exchange\-httpd\fP(1), \fBtaler\-exchange\-keyup\fP(1), \fBtaler\-exchange\-reservemod\fP(1), \fBtaler\-exchange\-dbinit\fP(1), \fBtaler\-exchange\-sepa(1) - diff --git a/src/exchange-lib/test-exchange-home/config/exchange-common.conf b/src/exchange-lib/test-exchange-home/config/exchange-common.conf index 89b7f5182..97947f111 100644 --- a/src/exchange-lib/test-exchange-home/config/exchange-common.conf +++ b/src/exchange-lib/test-exchange-home/config/exchange-common.conf @@ -22,15 +22,20 @@ TESTRUN = YES [exchangedb-postgres] DB_CONN_STR = "postgres:///talercheck" -[wire-sepa] +[wire-incoming-sepa] SEPA_RESPONSE_FILE = "test-exchange-home/sepa.json" -[wire-test] +[wire-incoming-sepa] +SEPA_RESPONSE_FILE = "test-exchange-home/sepa.json" + +[wire-incoming-test] +# What is the main website of the bank? +BANK_URI = "http://localhost/" +# Into which account at the 'bank' should (incoming) wire transfers be made? +BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] # What is the main website of the bank? BANK_URI = "http://localhost/" -# Into which account at the 'bank' should incoming -# wire transfers be made? -BANK_ACCOUNT_NO_INCOMING = 2 -# From which account at the 'bank' should outgoing -# wire transfers be made? -BANK_ACCOUNT_NO_OUTGOING = 2 \ No newline at end of file +# Into which account at the 'bank' should (incoming) wire transfers be made? +BANK_ACCOUNT_NUMBER = 2 diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 6eae08f4d..bfe54d507 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -1227,6 +1227,7 @@ wire_cb (void *cls, struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; + cmd->details.wire.wh = NULL; if (cmd->expected_response_code != http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/exchange/test-exchange-home/config/exchange-common.conf b/src/exchange/test-exchange-home/config/exchange-common.conf index e4ff2a4d6..4078cbee5 100644 --- a/src/exchange/test-exchange-home/config/exchange-common.conf +++ b/src/exchange/test-exchange-home/config/exchange-common.conf @@ -22,12 +22,18 @@ TESTRUN = YES [exchangedb-postgres] DB_CONN_STR = "postgres:///talercheck" -[wire-test] + +[wire-incoming-test] # What is the main website of the bank? BANK_URI = "http://localhost:8082/" # Into which account at the 'bank' should incoming # wire transfers be made? -BANK_ACCOUNT_NO_INCOMING = 2 +BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] +# What is the main website of the bank? +BANK_URI = "http://localhost:8082/" + # From which account at the 'bank' should outgoing # wire transfers be made? -BANK_ACCOUNT_NO_OUTGOING = 3 +BANK_ACCOUNT_NUMBER = 3 diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index a03f8127d..888501afb 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -44,9 +44,10 @@ struct TestClosure char *currency; /** - * Number of the account that the exchange has at the bank. + * Number of the account that the exchange has at the bank for outgoing + * transfers. */ - unsigned long long exchange_account_no; + unsigned long long exchange_account_outgoing_no; /** * Handle to the bank task, or NULL. @@ -576,7 +577,7 @@ test_execute_wire_transfer (void *cls, eh->aaih = TALER_BANK_admin_add_incoming (tc->bank, &bf.wtid, &amount, - (uint64_t) tc->exchange_account_no, + (uint64_t) tc->exchange_account_outgoing_no, (uint64_t) account_no, &execute_cb, eh); @@ -632,25 +633,25 @@ libtaler_plugin_wire_test_init (void *cls) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-test", + "wire-outgoing-test", "BANK_URI", &uri)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "wire-test", + "wire-outgoing-test", "BANK_URI"); GNUNET_free (tc); return NULL; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, - "wire-test", - "BANK_ACCOUNT_NO_OUTGOING", - &tc->exchange_account_no)) + "wire-outgoing-test", + "BANK_ACCOUNT_NUMBER", + &tc->exchange_account_outgoing_no)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "wire-test", - "BANK_ACCOUNT_NO_OUTGOING"); + "wire-incoming-test", + "BANK_ACCOUNT_NUMBER"); GNUNET_free (uri); GNUNET_free (tc); return NULL; -- cgit v1.2.3 From 116801016058023e90b33e1e0576e127685d87f3 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 Apr 2016 20:30:52 +0200 Subject: fix error message --- src/wire/plugin_wire_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/wire') diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 888501afb..304380721 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -272,7 +272,7 @@ test_get_wire_details (void *cls, /* oopsie, configuration error */ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, account_name, - "BANK_URI"); + "BANK_ACCOUNT_NUMBER"); GNUNET_free (bank_uri); return NULL; } -- cgit v1.2.3 From d7d33b681216c397c0b0b4c7e633eee068f48b45 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 1 Apr 2016 20:35:22 +0200 Subject: set environment variable to ensure plugins are found during tests --- src/exchange-lib/Makefile.am | 2 ++ src/exchange/Makefile.am | 2 ++ src/exchangedb/Makefile.am | 1 + src/wire/Makefile.am | 2 ++ 4 files changed, 7 insertions(+) (limited to 'src/wire') diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 10188c8fe..49cb234a1 100644 --- a/src/exchange-lib/Makefile.am +++ b/src/exchange-lib/Makefile.am @@ -45,6 +45,8 @@ endif check_PROGRAMS = \ test_exchange_api +AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; + TESTS = \ $(check_PROGRAMS) diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 18a7c1b54..3375a41d5 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -74,6 +74,8 @@ test_taler_exchange_aggregator_postgres_LDADD = \ check_PROGRAMS = \ test_taler_exchange_aggregator-postgres +AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; + TESTS = \ $(check_SCRIPTS) \ $(check_PROGRAMS) diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index d56d6676a..416d5688f 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -53,6 +53,7 @@ check_PROGRAMS = \ test-perf-taler-exchangedb \ perf-exchangedb +AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; TESTS = \ test-exchangedb-postgres \ test-perf-taler-exchangedb diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index 67a559a36..fd59c8eb7 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -62,6 +62,8 @@ libtalerwire_la_LDFLAGS = \ -export-dynamic -no-undefined +AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; + TESTS = \ test_sepa_wireformat -- cgit v1.2.3 From daae3d3ddf1cbee4761a6a2c0066732fb4723fb0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 2 Apr 2016 20:58:22 +0200 Subject: change taler-exchange-sepa to a more generic taler-exchange-wire tool using the wire plugins (#4237) --- doc/Makefile.am | 1 + doc/taler-exchange-sepa.1 | 41 ------- doc/taler-exchange-wire.1 | 38 ++++++ src/exchange-tools/Makefile.am | 10 +- src/exchange-tools/taler-exchange-sepa.c | 189 ----------------------------- src/exchange-tools/taler-exchange-wire.c | 201 +++++++++++++++++++++++++++++++ src/include/taler_signatures.h | 13 +- src/include/taler_wire_plugin.h | 18 +++ src/wire/plugin_wire_sepa.c | 132 ++++++++++++++++---- src/wire/plugin_wire_template.c | 23 ++++ src/wire/plugin_wire_test.c | 93 ++++++++++++++ 11 files changed, 499 insertions(+), 260 deletions(-) delete mode 100644 doc/taler-exchange-sepa.1 create mode 100644 doc/taler-exchange-wire.1 delete mode 100644 src/exchange-tools/taler-exchange-sepa.c create mode 100644 src/exchange-tools/taler-exchange-wire.c (limited to 'src/wire') diff --git a/doc/Makefile.am b/doc/Makefile.am index 5a9de87a0..0ccd84746 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -10,6 +10,7 @@ man_MANS = \ taler-exchange-keyup.1 \ taler-exchange-keycheck.1 \ taler-exchange-reservemod.1 \ + taler-exchange-wire.1 \ taler.conf.5 EXTRA_DIST = \ diff --git a/doc/taler-exchange-sepa.1 b/doc/taler-exchange-sepa.1 deleted file mode 100644 index b24828d96..000000000 --- a/doc/taler-exchange-sepa.1 +++ /dev/null @@ -1,41 +0,0 @@ -.TH TALER\-EXCHANGE\-SEPA 1 "Apr 22, 2015" "GNU Taler" - -.SH NAME -taler\-exchange\-sepa \- Create the master-key signed response to /wire/sepa. - -.SH SYNOPSIS -.B taler\-exchange\-sepa -.RI [ options ] -.br - -.SH DESCRIPTION -\fBtaler\-exchange\-sepa\fP is used to create the exchange's reply to a /wire/sepa request. It converts the bank details into the appropriate signed response. This needs to be done using the long-term offline master key. - -.SH OPTIONS -.B -.IP "\-b BIC, \-\-bic=BIC" -Specifies the BIC code to use. -.B -.IP "\-i IBAN, \-\-iban=IBAN" -Specifies the IBAN to use. -.B -.IP "\-n NAME, \-\-name=NAME" -Specifies the name of the account holder. -.B -.IP "\-m MASTERKEYFILE, \-\-master=MASTERKEYFILE" -Specifies the name of the file containing the exchange's master key. -.B -.IP "\-o FILENAME, \-\-output=FILENAME" -Where to write the SEPA_RESPONSE_FILE. -.B -.IP "\-h, \-\-help" -Print short help on options. -.B -.IP "\-v, \-\-version" -Print version information. - -.SH BUGS -Report bugs by using Mantis or by sending electronic mail to - -.SH "SEE ALSO" -\fBtaler\-exchange\-httpd\fP(1), \fBtaler.conf\fP(5) diff --git a/doc/taler-exchange-wire.1 b/doc/taler-exchange-wire.1 new file mode 100644 index 000000000..546d8eb74 --- /dev/null +++ b/doc/taler-exchange-wire.1 @@ -0,0 +1,38 @@ +.TH TALER\-EXCHANGE\-WIRE 1 "Apr 2, 2016" "GNU Taler" + +.SH NAME +taler\-exchange\-wire \- Create the master-key signed responses to /wire. + +.SH SYNOPSIS +.B taler\-exchange\-wire +.RI [ options ] +.br + +.SH DESCRIPTION +\fBtaler\-exchange\-wire\fP is used to create the exchange's reply to a /wire request. It converts the bank details into the appropriate signed response. This needs to be done using the long-term offline master key. + +.SH OPTIONS +.B +.IP "\-j JSON, \-\-json=JSON" +Gives JSON with all of the relevant account details in a method-specific format. +.B +.IP "\-t METHOD, \-\-type=METHOD" +Specifies the wire transfer method to use. Common are 'test' and 'sepa'. +.B +.IP "\-m MASTERKEYFILE, \-\-master=MASTERKEYFILE" +Specifies the name of the file containing the exchange's master key. +.B +.IP "\-o FILENAME, \-\-output=FILENAME" +Where to write the SEPA_RESPONSE_FILE. +.B +.IP "\-h, \-\-help" +Print short help on options. +.B +.IP "\-v, \-\-version" +Print version information. + +.SH BUGS +Report bugs by using Mantis or by sending electronic mail to + +.SH "SEE ALSO" +\fBtaler\-exchange\-httpd\fP(1), \fBtaler.conf\fP(5) diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am index fda9cefa3..feb3c314f 100644 --- a/src/exchange-tools/Makefile.am +++ b/src/exchange-tools/Makefile.am @@ -11,7 +11,7 @@ bin_PROGRAMS = \ taler-exchange-keyup \ taler-exchange-keycheck \ taler-exchange-reservemod \ - taler-exchange-sepa \ + taler-exchange-wire \ taler-exchange-dbinit taler_exchange_keyup_SOURCES = \ @@ -33,15 +33,15 @@ taler_auditor_sign_LDADD = \ -lgnunetutil $(XLIB) -taler_exchange_sepa_SOURCES = \ - taler-exchange-sepa.c -taler_exchange_sepa_LDADD = \ +taler_exchange_wire_SOURCES = \ + taler-exchange-wire.c +taler_exchange_wire_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetjson \ -lgnunetutil \ -ljansson $(XLIB) -taler_exchange_sepa_LDFLAGS = $(POSTGRESQL_LDFLAGS) +taler_exchange_wire_LDFLAGS = $(POSTGRESQL_LDFLAGS) taler_exchange_keycheck_SOURCES = \ taler-exchange-keycheck.c diff --git a/src/exchange-tools/taler-exchange-sepa.c b/src/exchange-tools/taler-exchange-sepa.c deleted file mode 100644 index 1bfb49132..000000000 --- a/src/exchange-tools/taler-exchange-sepa.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2015 GNUnet e.V. - - 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, If not, see -*/ -/** - * @file taler-exchange-sepa.c - * @brief Create signed response for /wire/sepa requests. - * @author Christian Grothoff - */ -#include -#include -#include -#include "taler_crypto_lib.h" -#include "taler_signatures.h" - - -/** - * Filename of the master private key. - */ -static char *masterkeyfile; - -/** - * Account holder name. - */ -static char *sepa_name; - -/** - * Account holder address. - */ -static char *sepa_address; - -/** - * IBAN number. - */ -static char *iban; - -/** - * BIC number. - */ -static char *bic; - -/** - * Where to write the result. - */ -static char *output_filename; - - -/** - * The main function of the taler-exchange-sepa tool. This tool is used - * to sign the SEPA bank account details using the master key. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error - */ -int -main (int argc, - char *const *argv) -{ - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'a', "address", "ADDRESS", - "account holder address", 1, - &GNUNET_GETOPT_set_string, &sepa_address}, - {'b', "bic", "BICCODE", - "bank BIC code", 1, - &GNUNET_GETOPT_set_string, &bic}, - {'i', "iban", "IBAN", - "IBAN number of the account", 1, - &GNUNET_GETOPT_set_string, &iban}, - {'m', "master-key", "FILE", - "master key file (private key)", 1, - &GNUNET_GETOPT_set_filename, &masterkeyfile}, - {'n', "name", "NAME", - "name of the account holder", 1, - &GNUNET_GETOPT_set_string, &sepa_name}, - {'o', "output", "FILE", - "where to write the result", 1, - &GNUNET_GETOPT_set_filename, &output_filename}, - TALER_GETOPT_OPTION_HELP ("Setup /wire/sepa response"), - GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), - GNUNET_GETOPT_OPTION_END - }; - struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv; - struct TALER_MasterWireSepaDetailsPS wsd; - struct TALER_MasterSignatureP sig; - struct GNUNET_HashContext *hc; - json_t *reply; - char *json_str; - struct GNUNET_HashCode salt; - - GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("taler-exchange-sepa", - "WARNING", - NULL)); - - if (GNUNET_GETOPT_run ("taler-exchange-sepa", - options, - argc, argv) < 0) - return 1; - if (NULL == masterkeyfile) - { - fprintf (stderr, - "Master key file not given\n"); - return 1; - } - eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile); - if (NULL == eddsa_priv) - { - fprintf (stderr, - "Failed to initialize master key from file `%s'\n", - masterkeyfile); - return 1; - } - if ( (NULL == sepa_address) || - (NULL == iban) || - (NULL == sepa_name) || - (NULL == bic) ) - { - fprintf (stderr, - "Required arguments missing\n"); - return 1; - } - - /* Compute message to sign */ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, - &salt, - sizeof (salt)); - hc = GNUNET_CRYPTO_hash_context_start (); - GNUNET_CRYPTO_hash_context_read (hc, - sepa_name, - strlen (sepa_name) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - iban, - strlen (iban) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - bic, - strlen (bic) + 1); - wsd.purpose.size = htonl (sizeof (wsd)); - wsd.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS); - GNUNET_CRYPTO_hash_context_finish (hc, - &wsd.h_sepa_details); - GNUNET_CRYPTO_eddsa_sign (eddsa_priv, - &wsd.purpose, - &sig.eddsa_signature); - GNUNET_free (eddsa_priv); - - /* build JSON message */ - reply = json_pack ("{s:s, s:s, s:s, s:s, s:s, s:o, s:o}", - "type", "sepa", - "address", sepa_address, - "receiver_name", sepa_name, - "iban", iban, - "bic", bic, - "salt", GNUNET_JSON_from_data (&salt, - sizeof (salt)), - "sig", GNUNET_JSON_from_data (&sig, - sizeof (sig))); - GNUNET_assert (NULL != reply); - - /* dump result to stdout */ - json_str = json_dumps (reply, JSON_INDENT(2)); - GNUNET_assert (NULL != json_str); - - if (NULL != output_filename) - { - fclose (stdout); - stdout = fopen (output_filename, - "w+"); - } - fprintf (stdout, - "%s", - json_str); - fflush (stdout); - free (json_str); - return 0; -} - -/* end of taler-exchange-sepa.c */ diff --git a/src/exchange-tools/taler-exchange-wire.c b/src/exchange-tools/taler-exchange-wire.c new file mode 100644 index 000000000..3bea78f67 --- /dev/null +++ b/src/exchange-tools/taler-exchange-wire.c @@ -0,0 +1,201 @@ +/* + This file is part of TALER + Copyright (C) 2015, 2016 Inria + + 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, If not, see +*/ +/** + * @file taler-exchange-wire.c + * @brief Create signed response for /wire requests. + * @author Christian Grothoff + */ +#include +#include +#include +#include "taler_crypto_lib.h" +#include "taler_wire_plugin.h" +#include "taler_signatures.h" + + +/** + * Filename of the master private key. + */ +static char *masterkeyfile; + +/** + * Account holder information in JSON format. + */ +static char *json_in; + +/** + * Which wire method is this for? + */ +static char *method; + +/** + * Where to write the result. + */ +static char *output_filename; + + +/** + * The main function of the taler-exchange-sepa tool. This tool is used + * to sign the SEPA bank account details using the master key. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, + char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'j', "json", "JSON", + "account information in JSON format", 1, + &GNUNET_GETOPT_set_string, &json_in}, + {'m', "master-key", "FILE", + "master key file (private key)", 1, + &GNUNET_GETOPT_set_filename, &masterkeyfile}, + {'t', "type", "METHOD", + "which wire transfer method (i.e. 'test' or 'sepa') is this for?", 1, + &GNUNET_GETOPT_set_filename, &method}, + {'o', "output", "FILE", + "where to write the result", 1, + &GNUNET_GETOPT_set_filename, &output_filename}, + TALER_GETOPT_OPTION_HELP ("Setup /wire response"), + GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), + GNUNET_GETOPT_OPTION_END + }; + struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv; + struct TALER_MasterPrivateKeyP key; + struct TALER_MasterSignatureP sig; + json_t *j; + json_error_t err; + char *json_out; + struct GNUNET_HashCode salt; + char *lib_name; + struct TALER_WIRE_Plugin *plugin; + + GNUNET_assert (GNUNET_OK == + GNUNET_log_setup ("taler-exchange-wire", + "WARNING", + NULL)); + + if (GNUNET_GETOPT_run ("taler-exchange-wire", + options, + argc, argv) < 0) + return 1; + if (NULL == masterkeyfile) + { + fprintf (stderr, + "Master key file not given\n"); + return 1; + } + eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile); + if (NULL == eddsa_priv) + { + fprintf (stderr, + "Failed to initialize master key from file `%s'\n", + masterkeyfile); + return 1; + } + if (NULL == json_in) + { + fprintf (stderr, + "Required -j argument missing\n"); + return 1; + } + if (NULL == method) + { + fprintf (stderr, + "Required -t argument missing\n"); + return 1; + } + j = json_loads (json_in, + JSON_REJECT_DUPLICATES, + &err); + if (NULL == j) + { + fprintf (stderr, + "Failed to parse JSON: %s (at offset %u)\n", + err.text, + (unsigned int) err.position); + return 1; + } + key.eddsa_priv = *eddsa_priv; + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &salt, + sizeof (salt)); + (void) GNUNET_asprintf (&lib_name, + "libtaler_plugin_wire_%s", + method); + plugin = GNUNET_PLUGIN_load (lib_name, + NULL); + if (NULL == plugin) + { + GNUNET_free (lib_name); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Wire transfer method `%s' not supported\n", + method); + return 1; + } + plugin->library_name = lib_name; + if (GNUNET_OK != + plugin->sign_wire_details (plugin->cls, + j, + &key, + &salt, + &sig)) + { + /* sign function should have logged applicable errors */ + json_decref (j); + GNUNET_PLUGIN_unload (lib_name, + plugin); + GNUNET_free (lib_name); + return 1; + } + GNUNET_PLUGIN_unload (lib_name, + plugin); + GNUNET_free (lib_name); + GNUNET_free (eddsa_priv); + + /* add signature and salt to JSON message */ + json_object_set_new (j, + "salt", + GNUNET_JSON_from_data (&salt, + sizeof (salt))); + json_object_set_new (j, + "sig", + GNUNET_JSON_from_data (&sig, + sizeof (sig))); + + /* dump result to stdout */ + json_out = json_dumps (j, JSON_INDENT(2)); + json_decref (j); + GNUNET_assert (NULL != json_out); + + if (NULL != output_filename) + { + fclose (stdout); + stdout = fopen (output_filename, + "w+"); + } + fprintf (stdout, + "%s", + json_out); + fflush (stdout); + free (json_out); + return 0; +} + +/* end of taler-exchange-wire.c */ diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 23bdaa578..587cdcee5 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -69,10 +69,16 @@ /** * Signature where the Exchange confirms its SEPA details in - * the /wire/sepa response. + * the /wire response. */ #define TALER_SIGNATURE_MASTER_SEPA_DETAILS 1026 +/** + * Signature where the Exchange confirms its TEST details in + * the /wire response. + */ +#define TALER_SIGNATURE_MASTER_TEST_DETAILS 1027 + /*********************************************/ /* Exchange online signatures (with signing key) */ @@ -762,11 +768,12 @@ struct TALER_RefreshCommitLinkP * @brief Information signed by the exchange's master * key affirming the SEPA details for the exchange. */ -struct TALER_MasterWireSepaDetailsPS +struct TALER_MasterWireDetailsPS { /** - * Purpose is #TALER_SIGNATURE_MASTER_SEPA_DETAILS. + * Purpose is #TALER_SIGNATURE_MASTER_SEPA_DETAILS or + * #TALER_SIGNATURE_MASTER_TEST_DETAILS. */ struct GNUNET_CRYPTO_EccSignaturePurpose purpose; diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h index e166558a7..9b2bc8fde 100644 --- a/src/include/taler_wire_plugin.h +++ b/src/include/taler_wire_plugin.h @@ -113,6 +113,24 @@ struct TALER_WIRE_Plugin const char *account_name); + /** + * Sign wire transfer details in the plugin-specific format. + * + * @param cls closure + * @param in wire transfer details in JSON format + * @param key private signing key to use + * @param salt salt to add + * @param[out] sig where to write the signature + * @return #GNUNET_OK on success + */ + int + (*sign_wire_details)(void *cls, + const json_t *in, + const struct TALER_MasterPrivateKeyP *key, + const struct GNUNET_HashCode *salt, + struct TALER_MasterSignatureP *sig); + + /** * Check if the given wire format JSON object is correctly formatted * diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c index 995436725..466e450be 100644 --- a/src/wire/plugin_wire_sepa.c +++ b/src/wire/plugin_wire_sepa.c @@ -351,6 +351,42 @@ validate_iban (const char *iban) } +/** + * Compute purpose for signing. + * + * @param sepa_name name of the account holder + * @param iban bank account number in IBAN format + * @param bic bank identifier + * @param[out] mp purpose to be signed + */ +static void +compute_purpose (const char *sepa_name, + const char *iban, + const char *bic, + struct TALER_MasterWireDetailsPS *wsd) +{ + struct GNUNET_HashContext *hc; + + wsd->purpose.size = htonl (sizeof (struct TALER_MasterWireDetailsPS)); + wsd->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS); + hc = GNUNET_CRYPTO_hash_context_start (); + GNUNET_CRYPTO_hash_context_read (hc, + "sepa", + strlen ("sepa") + 1); + GNUNET_CRYPTO_hash_context_read (hc, + sepa_name, + strlen (sepa_name) + 1); + GNUNET_CRYPTO_hash_context_read (hc, + iban, + strlen (iban) + 1); + GNUNET_CRYPTO_hash_context_read (hc, + bic, + strlen (bic) + 1); + GNUNET_CRYPTO_hash_context_finish (hc, + &wsd->h_sepa_details); +} + + /** * Verify that the signature in the @a json for /wire/sepa is valid. * @@ -365,14 +401,13 @@ verify_wire_sepa_signature_ok (const json_t *json, const struct TALER_MasterPublicKeyP *master_pub) { struct TALER_MasterSignatureP exchange_sig; - struct TALER_MasterWireSepaDetailsPS mp; - const char *receiver_name; + struct TALER_MasterWireDetailsPS mp; + const char *name; const char *iban; const char *bic; - struct GNUNET_HashContext *hc; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig), - GNUNET_JSON_spec_string ("receiver_name", &receiver_name), + GNUNET_JSON_spec_string ("name", &name), GNUNET_JSON_spec_string ("iban", &iban), GNUNET_JSON_spec_string ("bic", &bic), GNUNET_JSON_spec_end() @@ -391,22 +426,10 @@ verify_wire_sepa_signature_ok (const json_t *json, GNUNET_break_op (0); return GNUNET_SYSERR; } - - mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS); - mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS)); - hc = GNUNET_CRYPTO_hash_context_start (); - GNUNET_CRYPTO_hash_context_read (hc, - receiver_name, - strlen (receiver_name) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - iban, - strlen (iban) + 1); - GNUNET_CRYPTO_hash_context_read (hc, - bic, - strlen (bic) + 1); - GNUNET_CRYPTO_hash_context_finish (hc, - &mp.h_sepa_details); - + compute_purpose (name, + iban, + bic, + &mp); if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS, &mp.purpose, @@ -447,12 +470,12 @@ sepa_wire_validate (void *cls, "{" "s:s," /* type: sepa */ "s:s," /* iban: IBAN */ - "s:s," /* receiver_name: beneficiary name */ + "s:s," /* name: beneficiary name */ "s:s" /* bic: beneficiary bank's BIC */ "}", "type", &type, "iban", &iban, - "receiver_name", &name, + "name", &name, "bic", &bic)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -548,6 +571,70 @@ sepa_get_wire_details (void *cls, } +/** + * Sign wire transfer details in the plugin-specific format. + * + * @param cls closure + * @param in wire transfer details in JSON format + * @param key private signing key to use + * @param salt salt to add + * @param[out] sig where to write the signature + * @return #GNUNET_OK on success + */ +static int +sepa_sign_wire_details (void *cls, + const json_t *in, + const struct TALER_MasterPrivateKeyP *key, + const struct GNUNET_HashCode *salt, + struct TALER_MasterSignatureP *sig) +{ + struct TALER_MasterWireDetailsPS wsd; + const char *sepa_name; + const char *iban; + const char *bic; + const char *type; + json_error_t err; + + if (0 != + json_unpack_ex ((json_t *) in, + &err, + 0 /* flags */, + "{s:s, s:s, s:s, s:s}", + "type", &type, + "name", &sepa_name, + "iban", &iban, + "bic", &bic)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to unpack JSON: %s (at %u)\n", + err.text, + err.position); + return GNUNET_SYSERR; + } + if (0 != strcmp (type, + "sepa")) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`type' must be `sepa' for SEPA wire details\n"); + return GNUNET_SYSERR; + } + if (1 != validate_iban (iban)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "IBAN invalid in SEPA wire details\n"); + return GNUNET_SYSERR; + } + compute_purpose (sepa_name, + iban, + bic, + &wsd); + GNUNET_CRYPTO_eddsa_sign (&key->eddsa_priv, + &wsd.purpose, + &sig->eddsa_signature); + return GNUNET_OK; +} + + /** * Prepare for exeuction of a wire transfer. * @@ -662,6 +749,7 @@ libtaler_plugin_wire_sepa_init (void *cls) plugin->cls = sc; plugin->amount_round = &sepa_amount_round; plugin->get_wire_details = &sepa_get_wire_details; + plugin->sign_wire_details = &sepa_sign_wire_details; plugin->wire_validate = &sepa_wire_validate; plugin->prepare_wire_transfer = &sepa_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel; diff --git a/src/wire/plugin_wire_template.c b/src/wire/plugin_wire_template.c index fd6fbfbe9..46908c297 100644 --- a/src/wire/plugin_wire_template.c +++ b/src/wire/plugin_wire_template.c @@ -171,6 +171,28 @@ template_execute_wire_transfer (void *cls, } +/** + * Sign wire transfer details in the plugin-specific format. + * + * @param cls closure + * @param in wire transfer details in JSON format + * @param key private signing key to use + * @param salt salt to add + * @param[out] sig where to write the signature + * @return #GNUNET_OK on success + */ +static int +template_sign_wire_details (void *cls, + const json_t *in, + const struct TALER_MasterPrivateKeyP *key, + const struct GNUNET_HashCode *salt, + struct TALER_MasterSignatureP *sig) +{ + GNUNET_break (0); + return GNUNET_SYSERR; +} + + /** * Abort execution of a wire transfer. For example, because we are * shutting down. Note that if an execution is aborted, it may or @@ -236,6 +258,7 @@ libtaler_plugin_wire_template_init (void *cls) plugin->cls = tc; plugin->amount_round = &template_amount_round; plugin->get_wire_details = &template_get_wire_details; + plugin->sign_wire_details = &template_sign_wire_details; plugin->wire_validate = &template_wire_validate; plugin->prepare_wire_transfer = &template_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 304380721..8c03d155e 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -22,6 +22,7 @@ #include "platform.h" #include "taler_wire_plugin.h" #include "taler_bank_service.h" +#include "taler_signatures.h" /* only for HTTP status codes */ #include @@ -285,6 +286,38 @@ test_get_wire_details (void *cls, } +/** + * Compute purpose for signing. + * + * @param account number of the account + * @param bank_uri URI of the bank + * @param[out] mp purpose to be signed + */ +static void +compute_purpose (uint64_t account, + const char *bank_uri, + struct TALER_MasterWireDetailsPS *wsd) +{ + struct GNUNET_HashContext *hc; + uint64_t n = GNUNET_htonll (account); + + wsd->purpose.size = htonl (sizeof (struct TALER_MasterWireDetailsPS)); + wsd->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_TEST_DETAILS); + hc = GNUNET_CRYPTO_hash_context_start (); + GNUNET_CRYPTO_hash_context_read (hc, + "test", + strlen ("test") + 1); + GNUNET_CRYPTO_hash_context_read (hc, + &n, + sizeof (n)); + GNUNET_CRYPTO_hash_context_read (hc, + bank_uri, + strlen (bank_uri) + 1); + GNUNET_CRYPTO_hash_context_finish (hc, + &wsd->h_sepa_details); +} + + /** * Check if the given wire format JSON object is correctly formatted. * Right now, the only thing we require is a field @@ -319,6 +352,10 @@ test_wire_validate (void *cls, GNUNET_break (0); return GNUNET_SYSERR; } + /* FIXME: should check signature here in the future! + (note: right now the sig is not properly provided + by the exchange due to the way account data is + specified in the configuration) */ return GNUNET_YES; } @@ -510,6 +547,61 @@ execute_cb (void *cls, } +/** + * Sign wire transfer details in the plugin-specific format. + * + * @param cls closure + * @param in wire transfer details in JSON format + * @param key private signing key to use + * @param salt salt to add + * @param[out] sig where to write the signature + * @return #GNUNET_OK on success + */ +static int +test_sign_wire_details (void *cls, + const json_t *in, + const struct TALER_MasterPrivateKeyP *key, + const struct GNUNET_HashCode *salt, + struct TALER_MasterSignatureP *sig) +{ + struct TALER_MasterWireDetailsPS wsd; + const char *bank_uri; + const char *type; + json_int_t account; + json_error_t err; + + if (0 != + json_unpack_ex ((json_t *) in, + &err, + 0 /* flags */, + "{s:s, s:s, s:I}", + "type", &type, + "bank_uri", &bank_uri, + "account_number", &account)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to unpack JSON: %s (at %u)\n", + err.text, + err.position); + return GNUNET_SYSERR; + } + if (0 != strcmp (type, + "test")) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`type' must be `test' for test wire details\n"); + return GNUNET_SYSERR; + } + compute_purpose (account, + bank_uri, + &wsd); + GNUNET_CRYPTO_eddsa_sign (&key->eddsa_priv, + &wsd.purpose, + &sig->eddsa_signature); + return GNUNET_OK; +} + + /** * Execute a wire transfer. * @@ -682,6 +774,7 @@ libtaler_plugin_wire_test_init (void *cls) plugin->cls = tc; plugin->amount_round = &test_amount_round; plugin->get_wire_details = &test_get_wire_details; + plugin->sign_wire_details = &test_sign_wire_details; plugin->wire_validate = &test_wire_validate; plugin->prepare_wire_transfer = &test_prepare_wire_transfer; plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel; -- cgit v1.2.3 From 08e9c295706048bf5aa502e581c5c54bec48ff5f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 Apr 2016 21:10:10 +0200 Subject: Fix testcase to match latest spec without receiver_ --- src/wire/test_sepa_wireformat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/wire') diff --git a/src/wire/test_sepa_wireformat.c b/src/wire/test_sepa_wireformat.c index f016cf635..cd31a971c 100644 --- a/src/wire/test_sepa_wireformat.c +++ b/src/wire/test_sepa_wireformat.c @@ -29,7 +29,7 @@ static const char * const valid_wire_str = "{ \"type\":\"SEPA\", \ \"iban\":\"DE67830654080004822650\", \ -\"receiver_name\":\"GNUnet e.V.\", \ +\"name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ \"salt\":\"123456789\", \ \"address\": \"foobar\"}"; @@ -38,7 +38,7 @@ static const char * const valid_wire_str = static const char * const invalid_wire_str = "{ \"type\":\"SEPA\", \ \"iban\":\"XX67830654080004822650\", \ -\"receiver_name\":\"GNUnet e.V.\", \ +\"name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ \"salt\":\"123456789\", \ \"address\": \"foobar\"}"; @@ -47,7 +47,7 @@ static const char * const invalid_wire_str = static const char * const invalid_wire_str2 = "{ \"type\":\"SEPA\", \ \"iban\":\"DE67830654080004822651\", \ -\"receiver_name\":\"GNUnet e.V.\", \ +\"name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ \"salt\":\"123456789\", \ \"address\": \"foobar\"}"; @@ -56,7 +56,7 @@ static const char * const invalid_wire_str2 = static const char * const unsupported_wire_str = "{ \"type\":\"unsupported\", \ \"iban\":\"DE67830654080004822650\", \ -\"receiver_name\":\"GNUnet e.V.\", \ +\"name\":\"GNUnet e.V.\", \ \"bic\":\"GENODEF1SLR\", \ \"salt\":\"123456789\", \ \"address\": \"foobar\"}"; -- cgit v1.2.3 From afb1ab2a116bb0b33b5d23d043222965892e8edf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 4 Apr 2016 17:40:51 +0200 Subject: -fix mem leaks --- src/exchange/taler-exchange-aggregator.c | 12 ++++++++++++ src/exchangedb/plugin_exchangedb_postgres.c | 9 +++++---- src/wire/plugin_wire_sepa.c | 24 ++++++++++++------------ src/wire/plugin_wire_test.c | 1 + 4 files changed, 30 insertions(+), 16 deletions(-) (limited to 'src/wire') diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 2d5fd71d8..a6b7de211 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -472,6 +472,8 @@ run_aggregation (void *cls, au); if (GNUNET_OK != ret) { + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); db_plugin->rollback (db_plugin->cls, session); @@ -510,6 +512,8 @@ run_aggregation (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to execute deposit iteration!\n"); GNUNET_free_non_null (au->additional_rows); + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); db_plugin->rollback (db_plugin->cls, session); @@ -538,6 +542,8 @@ run_aggregation (void *cls, "Failed to start database transaction!\n"); *global_ret = GNUNET_SYSERR; GNUNET_free_non_null (au->additional_rows); + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); return; } @@ -564,6 +570,8 @@ run_aggregation (void *cls, "Failed to commit database transaction!\n"); } GNUNET_free_non_null (au->additional_rows); + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); /* start again */ task = GNUNET_SCHEDULER_add_now (&run_aggregation, @@ -586,6 +594,8 @@ run_aggregation (void *cls, db_plugin->rollback (db_plugin->cls, session); GNUNET_free_non_null (au->additional_rows); + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); /* start again */ task = GNUNET_SCHEDULER_add_now (&run_aggregation, @@ -625,6 +635,8 @@ prepare_cb (void *cls, struct TALER_EXCHANGEDB_Session *session = au->session; GNUNET_free_non_null (au->additional_rows); + if (NULL != au->wire) + json_decref (au->wire); GNUNET_free (au); if (NULL == buf) { diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index b59acaead..6807e7563 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1480,8 +1480,8 @@ postgres_get_denomination_info (void *cls, EXITIF (GNUNET_OK != GNUNET_PQ_extract_result (result, - rs, - 0)); + rs, + 0)); } PQclear (result); return GNUNET_OK; @@ -1954,7 +1954,7 @@ postgres_get_reserve_history (void *cls, &bt->wire), GNUNET_PQ_result_spec_end }; - if (GNUNET_YES != + if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, --rows)) { GNUNET_break (0); @@ -2019,7 +2019,7 @@ postgres_get_reserve_history (void *cls, &cbc->withdraw_fee), GNUNET_PQ_result_spec_end }; - if (GNUNET_YES != + if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, --rows)) { GNUNET_break (0); @@ -2285,6 +2285,7 @@ postgres_get_ready_deposit (void *cls, &wire), GNUNET_PQ_result_spec_end }; + if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, 0)) { diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c index 466e450be..e0a3426c2 100644 --- a/src/wire/plugin_wire_sepa.c +++ b/src/wire/plugin_wire_sepa.c @@ -731,20 +731,20 @@ libtaler_plugin_wire_sepa_init (void *cls) sc = GNUNET_new (struct SepaClosure); if (NULL != cfg) + { + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "exchange", + "CURRENCY", + &sc->currency)) { - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "exchange", - "CURRENCY", - &sc->currency)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "exchange", - "CURRENCY"); - GNUNET_free (sc); - return NULL; - } + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "CURRENCY"); + GNUNET_free (sc); + return NULL; } + } plugin = GNUNET_new (struct TALER_WIRE_Plugin); plugin->cls = sc; plugin->amount_round = &sepa_amount_round; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 8c03d155e..357449af6 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -762,6 +762,7 @@ libtaler_plugin_wire_test_init (void *cls) return NULL; } tc->bank = TALER_BANK_init (uri); + GNUNET_free (uri); if (NULL == tc->bank) { GNUNET_break (0); -- cgit v1.2.3 From a96c7177aae60c37041406ff0879992e58ef2f50 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 6 Apr 2016 12:04:51 +0200 Subject: get simple aggregation test to pass --- src/exchange/taler-exchange-aggregator.c | 42 +++++++++++++++++++++++---- src/exchange/test_taler_exchange_aggregator.c | 22 +++++++------- src/wire/plugin_wire_test.c | 2 +- 3 files changed, 50 insertions(+), 16 deletions(-) (limited to 'src/wire') diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 3726d32fa..def6d0be4 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -237,8 +237,9 @@ shutdown_task (void *cls, json_decref (au->wire); au = NULL; GNUNET_free (au); - } + TALER_EXCHANGEDB_plugin_unload (db_plugin); + TALER_WIRE_plugin_unload (wire_plugin); } @@ -366,6 +367,9 @@ deposit_cb (void *cls, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &au->wtid, sizeof (au->wtid)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting aggregation under WTID %s\n", + TALER_B2S (&au->wtid)); if (GNUNET_OK != db_plugin->insert_aggregation_tracking (db_plugin->cls, au->session, @@ -523,8 +527,11 @@ run_aggregation (void *cls, unsigned int i; int ret; + task = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Checking for ready deposits to aggregate\n"); if (NULL == (session = db_plugin->get_session (db_plugin->cls, test_mode))) { @@ -563,6 +570,8 @@ run_aggregation (void *cls, global_ret = GNUNET_SYSERR; return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No more ready deposits, going to sleep\n"); if (GNUNET_YES == test_mode) { /* in test mode, shutdown if we end up being idle */ @@ -578,6 +587,9 @@ run_aggregation (void *cls, return; } /* Now try to find other deposits to aggregate */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Found ready deposit for %s, aggregating\n", + TALER_B2S (&au->merchant_pub)); ret = db_plugin->iterate_matching_deposits (db_plugin->cls, session, &au->h_wire, @@ -608,6 +620,8 @@ run_aggregation (void *cls, if ( (0 == au->total_amount.value) && (0 == au->total_amount.fraction) ) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Aggregate value too low for transfer\n"); /* Rollback ongoing transaction, as we will not use the respective WTID and thus need to remove the tracking data */ db_plugin->rollback (db_plugin->cls, @@ -660,6 +674,15 @@ run_aggregation (void *cls, NULL); return; } + { + char *amount_s; + + amount_s = TALER_amount_to_string (&au->total_amount); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Preparing wire transfer of %s to %s\n", + amount_s, + TALER_B2S (&au->merchant_pub)); + } au->ph = wire_plugin->prepare_wire_transfer (wire_plugin->cls, au->wire, &au->total_amount, @@ -757,7 +780,8 @@ prepare_cb (void *cls, NULL); return; } - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Preparation complete, switching to transfer mode\n"); /* run alternative task: actually do wire transfer! */ task = GNUNET_SCHEDULER_add_now (&run_transfers, NULL); @@ -817,6 +841,8 @@ wire_confirm_cb (void *cls, NULL); return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Wire transfer complete\n"); /* continue with #run_transfers(), just to guard against the unlikely case that there are more. */ task = GNUNET_SCHEDULER_add_now (&run_transfers, @@ -840,6 +866,9 @@ wire_prepare_cb (void *cls, size_t buf_size) { wpd->row_id = rowid; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting wire transfer %llu\n", + rowid); wpd->eh = wire_plugin->execute_wire_transfer (wire_plugin->cls, buf, buf_size, @@ -872,6 +901,9 @@ run_transfers (void *cls, int ret; struct TALER_EXCHANGEDB_Session *session; + task = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Checking for pending wire transfers\n"); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; if (NULL == (session = db_plugin->get_session (db_plugin->cls, @@ -911,6 +943,8 @@ run_transfers (void *cls, if (GNUNET_NO == ret) { /* no more prepared wire transfers, go back to aggregation! */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No more pending wire transfers, starting aggregation\n"); db_plugin->rollback (db_plugin->cls, session); task = GNUNET_SCHEDULER_add_now (&run_aggregation, @@ -934,7 +968,7 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { task = GNUNET_SCHEDULER_add_now (&run_transfers, - cls); + NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, cls); @@ -991,8 +1025,6 @@ main (int argc, global_ret = GNUNET_OK; GNUNET_SCHEDULER_run (&run, NULL); - TALER_EXCHANGEDB_plugin_unload (db_plugin); - TALER_WIRE_plugin_unload (wire_plugin); return (GNUNET_SYSERR == global_ret) ? 1 : 0; } diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 22bc8e277..f34dea837 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -668,25 +668,19 @@ run_test () .label = "run-aggregator-deposit-1" }, - /* The above step is already known to fail (with an error message) - right now, so we skip the rest of the test. */ - { - .opcode = OPCODE_TERMINATE_SKIP, - .label = "testcase-incomplete-terminating-with-skip" - }, - - { .opcode = OPCODE_EXPECT_TRANSACTION, .label = "expect-deposit-1", - .details.expect_transaction.debit_account = 1, + .details.expect_transaction.debit_account = 3, .details.expect_transaction.credit_account = 4, .details.expect_transaction.amount = "EUR:1" }, + { .opcode = OPCODE_EXPECT_TRANSACTIONS_EMPTY, .label = "expect-empty-transactions-on-start" }, + /* test idempotency: run again on transactions already done */ { .opcode = OPCODE_DATABASE_DEPOSIT, @@ -703,6 +697,11 @@ run_test () .label = "expect-empty-transactions-on-start" }, + { + .opcode = OPCODE_TERMINATE_SUCCESS, + .label = "testcase-incomplete-terminating-with-skip" + }, + { .opcode = OPCODE_TERMINATE_SKIP, .label = "testcase-incomplete-terminating-with-skip" @@ -804,7 +803,6 @@ handle_mhd_request (void *cls, GNUNET_break_op (0); return MHD_NO; } - /* FIXME: to be implemented! */ pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, con_cls, upload_data, @@ -848,6 +846,10 @@ handle_mhd_request (void *cls, transactions_tail, t); } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Receiving incoming wire transfer: %llu->%llu\n", + (unsigned long long) t->debit_account, + (unsigned long long) t->credit_account); json_decref (json); resp = MHD_create_response_from_buffer (0, "", MHD_RESPMEM_PERSISTENT); ret = MHD_queue_response (connection, diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 357449af6..9d0667680 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -178,7 +178,7 @@ context_task (void *cls, rs, ws, &context_task, - cls); + tc); GNUNET_NETWORK_fdset_destroy (rs); GNUNET_NETWORK_fdset_destroy (ws); } -- cgit v1.2.3 From 8df75214f459fd39ce43540dc604733c1a47515e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 7 Apr 2016 09:30:58 +0200 Subject: install data and plugins in taler-exchange, not taler --- src/exchangedb/Makefile.am | 2 +- src/util/os_installation.c | 2 +- src/wire/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/wire') diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 416d5688f..b3637346b 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -6,7 +6,7 @@ if USE_COVERAGE XLIB = -lgcov endif -plugindir = $(libdir)/taler +plugindir = $(libdir)/taler-exchange if HAVE_POSTGRESQL plugin_LTLIBRARIES = \ diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 4fce72ee9..22e0133cd 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -33,7 +33,7 @@ */ static const struct GNUNET_OS_ProjectData taler_pd = { .libname = "libtalerutil", - .project_dirname = "taler", + .project_dirname = "taler-exchange", .binary_name = "taler-exchange-httpd", .env_varname = "TALER_PREFIX" }; diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index fd59c8eb7..16ef1ded0 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -6,7 +6,7 @@ if USE_COVERAGE XLIB = -lgcov endif -plugindir = $(libdir)/taler +plugindir = $(libdir)/taler-exchange plugin_LTLIBRARIES = \ libtaler_plugin_wire_sepa.la \ -- cgit v1.2.3 From d986269dae21c52321341e1980a464494a3fe87b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 7 Apr 2016 11:09:30 +0200 Subject: for #4374 --- src/exchange/Makefile.am | 2 +- src/exchangedb/Makefile.am | 2 +- src/util/os_installation.c | 2 +- src/wire/Makefile.am | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/wire') diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index 68689da22..df939d3ee 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -6,7 +6,7 @@ if USE_COVERAGE XLIB = -lgcov endif -pkgcfgdir= $(pkgdatadir)/config.d/ +pkgcfgdir = $(prefix)/share/taler/config.d/ pkgcfg_DATA = \ exchange.conf diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 914153f6f..0a7b0447c 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -6,7 +6,7 @@ if USE_COVERAGE XLIB = -lgcov endif -plugindir = $(libdir)/taler-exchange +plugindir = $(libdir)/taler if HAVE_POSTGRESQL plugin_LTLIBRARIES = \ diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 22e0133cd..4fce72ee9 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -33,7 +33,7 @@ */ static const struct GNUNET_OS_ProjectData taler_pd = { .libname = "libtalerutil", - .project_dirname = "taler-exchange", + .project_dirname = "taler", .binary_name = "taler-exchange-httpd", .env_varname = "TALER_PREFIX" }; diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index 16ef1ded0..fd59c8eb7 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -6,7 +6,7 @@ if USE_COVERAGE XLIB = -lgcov endif -plugindir = $(libdir)/taler-exchange +plugindir = $(libdir)/taler plugin_LTLIBRARIES = \ libtaler_plugin_wire_sepa.la \ -- cgit v1.2.3 From 0dee91e014a51a5b66cd1b0a9a7517ac75813eb6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 10 Apr 2016 00:57:20 +0200 Subject: changing code to meet latest change in GNUNET_SCHEDULER API --- src/bank-lib/test_bank_api.c | 28 +++++++---------------- src/exchange-lib/test_exchange_api.c | 28 +++++++---------------- src/exchange/taler-exchange-aggregator.c | 23 ++++++++----------- src/exchange/test_taler_exchange_aggregator.c | 32 +++++++++------------------ src/exchangedb/test_exchangedb.c | 4 +--- src/wire/plugin_wire_test.c | 8 ++----- 6 files changed, 38 insertions(+), 85 deletions(-) (limited to 'src/wire') diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c index 66f3557b9..cc1086e73 100644 --- a/src/bank-lib/test_bank_api.c +++ b/src/bank-lib/test_bank_api.c @@ -163,11 +163,9 @@ struct InterpreterState * Task that runs the context's event loop with the GNUnet scheduler. * * @param cls unused - * @param tc scheduler context (unused) */ static void -context_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +context_task (void *cls); /** @@ -233,11 +231,9 @@ find_command (const struct InterpreterState *is, * Run the main interpreter loop that performs bank operations. * * @param cls contains the `struct InterpreterState` - * @param tc scheduler context */ static void -interpreter_run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +interpreter_run (void *cls); /** @@ -281,17 +277,17 @@ add_incoming_cb (void *cls, * Run the main interpreter loop that performs bank operations. * * @param cls contains the `struct InterpreterState` - * @param tc scheduler context */ static void -interpreter_run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +interpreter_run (void *cls) { struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; struct TALER_Amount amount; + const struct GNUNET_SCHEDULER_TaskContext *tc; is->task = NULL; + tc = GNUNET_SCHEDULER_get_task_context (); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { fprintf (stderr, @@ -354,11 +350,9 @@ interpreter_run (void *cls, * Cleans up our state. * * @param cls the interpreter state. - * @param tc unused */ static void -do_shutdown (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +do_shutdown (void *cls) { struct InterpreterState *is = cls; struct Command *cmd; @@ -415,11 +409,9 @@ do_shutdown (void *cls, * Task that runs the context's event loop with the GNUnet scheduler. * * @param cls unused - * @param tc scheduler context (unused) */ static void -context_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +context_task (void *cls) { long timeout; int max_fd; @@ -471,13 +463,9 @@ context_task (void *cls, * Main function that will be run by the scheduler. * * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param config configuration */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls) { struct InterpreterState *is; static struct Command commands[] = diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index bfe54d507..c7eb9e314 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -573,11 +573,9 @@ struct InterpreterState * Task that runs the context's event loop with the GNUnet scheduler. * * @param cls unused - * @param tc scheduler context (unused) */ static void -context_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +context_task (void *cls); /** @@ -641,11 +639,9 @@ find_command (const struct InterpreterState *is, * Run the main interpreter loop that performs exchange operations. * * @param cls contains the `struct InterpreterState` - * @param tc scheduler context */ static void -interpreter_run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +interpreter_run (void *cls); /** @@ -1414,11 +1410,9 @@ deposit_wtid_cb (void *cls, * Run the main interpreter loop that performs exchange operations. * * @param cls contains the `struct InterpreterState` - * @param tc scheduler context */ static void -interpreter_run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +interpreter_run (void *cls) { struct InterpreterState *is = cls; struct Command *cmd = &is->commands[is->ip]; @@ -1428,8 +1422,10 @@ interpreter_run (void *cls, struct TALER_Amount amount; struct GNUNET_TIME_Absolute execution_date; json_t *wire; + const struct GNUNET_SCHEDULER_TaskContext *tc; is->task = NULL; + tc = GNUNET_SCHEDULER_get_task_context (); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { fprintf (stderr, @@ -1993,11 +1989,9 @@ interpreter_run (void *cls, * Cleans up our state. * * @param cls the interpreter state. - * @param tc unused */ static void -do_shutdown (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +do_shutdown (void *cls) { struct InterpreterState *is = cls; struct Command *cmd; @@ -2218,11 +2212,9 @@ cert_cb (void *cls, * Task that runs the context's event loop with the GNUnet scheduler. * * @param cls unused - * @param tc scheduler context (unused) */ static void -context_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +context_task (void *cls) { long timeout; int max_fd; @@ -2274,13 +2266,9 @@ context_task (void *cls, * Main function that will be run by the scheduler. * * @param cls closure - * @param args remaining command-line arguments - * @param cfgfile name of the configuration file used (for saving, can be NULL!) - * @param config configuration */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls) { struct InterpreterState *is; static struct MeltDetails melt_coins_1[] = { diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 80d1bbb9f..2ff3c2ca8 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -198,11 +198,9 @@ static unsigned int aggregation_limit = TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT * We're being aborted with CTRL-C (or SIGTERM). Shut down. * * @param cls closure - * @param tc scheduler context */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls) { if (NULL != task) { @@ -517,17 +515,17 @@ prepare_cb (void *cls, * into larger wire transfers. * * @param cls NULL - * @param tc scheduler context */ static void -run_aggregation (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run_aggregation (void *cls) { struct TALER_EXCHANGEDB_Session *session; unsigned int i; int ret; + const struct GNUNET_SCHEDULER_TaskContext *tc; task = NULL; + tc = GNUNET_SCHEDULER_get_task_context (); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -713,11 +711,9 @@ run_aggregation (void *cls, * do. * * @param cls pointer to an `int` which we will return from main() - * @param tc scheduler context */ static void -run_transfers (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +run_transfers (void *cls); /** @@ -895,15 +891,16 @@ wire_prepare_cb (void *cls, * @param tc scheduler context */ static void -run_transfers (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run_transfers (void *cls) { int ret; struct TALER_EXCHANGEDB_Session *session; + const struct GNUNET_SCHEDULER_TaskContext *tc; task = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Checking for pending wire transfers\n"); + tc = GNUNET_SCHEDULER_get_task_context (); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; if (NULL == (session = db_plugin->get_session (db_plugin->cls, @@ -961,11 +958,9 @@ run_transfers (void *cls, * First task. * * @param cls closure, NULL - * @param tc scheduler context */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls) { task = GNUNET_SCHEDULER_add_now (&run_transfers, NULL); diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index f34dea837..3720ce829 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -305,22 +305,18 @@ static struct GNUNET_CRYPTO_RsaPublicKey *coin_pub; * Interprets the commands from the test program. * * @param cls the `struct State` of the interpreter - * @param tc scheduler context */ static void -interpreter (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +interpreter (void *cls); /** * Task triggered whenever we are to shutdown. * * @param cls closure, NULL if we need to self-restart - * @param tc context */ static void -shutdown_action (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_action (void *cls) { shutdown_task = NULL; if (NULL != mhd_task) @@ -355,18 +351,18 @@ shutdown_action (void *cls, * process died). * * @param cls closure, NULL if we need to self-restart - * @param tc context */ static void -maint_child_death (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +maint_child_death (void *cls) { const struct GNUNET_DISK_FileHandle *pr; char c[16]; struct State *state; + const struct GNUNET_SCHEDULER_TaskContext *tc; child_death_task = NULL; pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); + tc = GNUNET_SCHEDULER_get_task_context (); if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) { /* shutdown scheduled us, ignore! */ @@ -384,7 +380,7 @@ maint_child_death (void *cls, aggregator_state->ioff++; state = aggregator_state; aggregator_state = NULL; - interpreter (state, NULL); + interpreter (state); if (NULL == shutdown_task) return; child_death_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, @@ -527,11 +523,9 @@ fail (struct Command *cmd) * Interprets the commands from the test program. * * @param cls the `struct State` of the interpreter - * @param tc scheduler context */ static void -interpreter (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +interpreter (void *cls) { struct State *state = cls; @@ -864,11 +858,9 @@ handle_mhd_request (void *cls, * Task run whenever HTTP server operations are pending. * * @param cls NULL - * @param tc scheduler context */ static void -run_mhd (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +run_mhd (void *cls); /** @@ -934,11 +926,9 @@ schedule_httpd () * Task run whenever HTTP server operations are pending. * * @param cls NULL - * @param tc scheduler context */ static void -run_mhd (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run_mhd (void *cls) { mhd_task = NULL; MHD_run (mhd_bank); @@ -950,11 +940,9 @@ run_mhd (void *cls, * Main function that will be run by the scheduler. * * @param cls closure with configuration - * @param tc unused */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TALER_EXCHANGEDB_DenominationKeyInformationP issue; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 8d06c0072..f2c473fd9 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -615,11 +615,9 @@ deposit_cb (void *cls, * Main function that will be run by the scheduler. * * @param cls closure with config - * @param tc unused */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TALER_EXCHANGEDB_Session *session; diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index 9d0667680..bde3c4442 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -131,11 +131,9 @@ struct TALER_WIRE_ExecuteHandle * scheduler. * * @param cls our `struct TestClosure` - * @param tc scheduler context (unused) */ static void -context_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *sct) +context_task (void *cls) { struct TestClosure *tc = cls; long timeout; @@ -388,11 +386,9 @@ GNUNET_NETWORK_STRUCT_END * callback with the serialized state. * * @param cls the `struct TALER_WIRE_PrepareHandle` - * @param sct unused */ static void -do_prepare (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *sct) +do_prepare (void *cls) { struct TALER_WIRE_PrepareHandle *pth = cls; char *wire_enc; -- cgit v1.2.3 From 30d66bcebc27a1cdcbad39ddbeeaf047da6cc1dd Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 10 Apr 2016 17:10:20 +0200 Subject: fixing #4386: use more sane configuration and data file structure --- .gitignore | 2 + doc/taler.conf.5 | 6 +- src/exchange-lib/Makefile.am | 5 +- .../test-exchange-home/config/exchange-common.conf | 41 --------- .../test-exchange-home/config/exchange-keyup.conf | 86 ------------------- src/exchange-lib/test-exchange-home/master.priv | 1 - src/exchange-lib/test-exchange-home/sepa.json | 9 -- src/exchange-lib/test_exchange_api.c | 8 +- src/exchange-lib/test_exchange_api.conf | 96 ++++++++++++++++++++++ .../test_exchange_api_home/.config/taler/sepa.json | 9 ++ .../share/taler/exchange/offline-keys/master.priv | 1 + src/exchange-tools/Makefile.am | 12 +++ src/exchange-tools/auditor.conf | 12 +++ src/exchange-tools/coins.conf | 25 ++++++ src/exchange-tools/exchange-signkeys.conf | 16 ++++ src/exchange-tools/taler-auditor-sign.c | 47 +++++++++-- src/exchange-tools/taler-exchange-dbinit.c | 46 ++++------- src/exchange-tools/taler-exchange-keycheck.c | 42 ++++++---- src/exchange-tools/taler-exchange-keyup.c | 42 ++++++---- src/exchange-tools/taler-exchange-reservemod.c | 42 ++++++---- src/exchange-tools/taler-exchange-wire.c | 29 ++++++- src/exchange/Makefile.am | 2 + src/exchange/exchange.conf | 33 +++----- src/exchange/taler-exchange-aggregator.c | 73 +++++++--------- src/exchange/taler-exchange-httpd.c | 34 ++++---- src/exchange/taler-exchange-httpd_keystate.c | 6 +- .../test-exchange-home/config/exchange-common.conf | 39 --------- src/exchange/test-exchange-home/master.priv | 1 - src/exchange/test_taler_exchange_aggregator.c | 6 +- src/exchange/test_taler_exchange_httpd.conf | 82 ++++++++++++++++++ src/exchange/test_taler_exchange_httpd.sh | 14 ++-- .../share/taler/exchange/offline-keys/master.priv | 1 + src/exchangedb/Makefile.am | 11 +++ src/exchangedb/exchangedb-postgres.conf | 2 + src/exchangedb/exchangedb.conf | 7 ++ src/exchangedb/exchangedb_keyio.c | 21 ++--- src/include/taler_exchangedb_lib.h | 12 +-- src/include/taler_util.h | 11 --- src/util/Makefile.am | 9 ++ src/util/paths.conf | 29 +++++++ src/util/util.c | 27 ------ src/wire/Makefile.am | 11 +++ src/wire/wire-sepa.conf | 7 ++ src/wire/wire-test.conf | 14 ++++ 44 files changed, 606 insertions(+), 423 deletions(-) delete mode 100644 src/exchange-lib/test-exchange-home/config/exchange-common.conf delete mode 100644 src/exchange-lib/test-exchange-home/config/exchange-keyup.conf delete mode 100644 src/exchange-lib/test-exchange-home/master.priv delete mode 100644 src/exchange-lib/test-exchange-home/sepa.json create mode 100644 src/exchange-lib/test_exchange_api.conf create mode 100644 src/exchange-lib/test_exchange_api_home/.config/taler/sepa.json create mode 100644 src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv create mode 100644 src/exchange-tools/auditor.conf create mode 100644 src/exchange-tools/coins.conf create mode 100644 src/exchange-tools/exchange-signkeys.conf delete mode 100644 src/exchange/test-exchange-home/config/exchange-common.conf delete mode 100644 src/exchange/test-exchange-home/master.priv create mode 100644 src/exchange/test_taler_exchange_httpd.conf create mode 100644 src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv create mode 100644 src/exchangedb/exchangedb-postgres.conf create mode 100644 src/exchangedb/exchangedb.conf create mode 100644 src/util/paths.conf create mode 100644 src/wire/wire-sepa.conf create mode 100644 src/wire/wire-test.conf (limited to 'src/wire') diff --git a/.gitignore b/.gitignore index ce73b4d26..fc31e919e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,8 +31,10 @@ src/lib/test_exchange_api doc/doxygen/doxygen_sqlite3.db src/bank-lib/test_bank_api src/exchange-lib/test_exchange_api +src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/live-keys/ src/exchange/taler-exchange-aggregator src/exchange/test_taler_exchange_aggregator-postgres +src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/live-keys/ src/exchange-tools/taler-auditor-sign src/exchange-tools/taler-exchange-dbinit src/exchange-tools/taler-exchange-keycheck diff --git a/doc/taler.conf.5 b/doc/taler.conf.5 index e4c7083d6..1d03927ea 100644 --- a/doc/taler.conf.5 +++ b/doc/taler.conf.5 @@ -1,14 +1,14 @@ -.TH TALER.CONF 5 "Aug 11, 2015" "GNU Taler" +.TH TALER.CONF 5 "Apr 11, 2016" "GNU Taler" .SH NAME taler.conf \- Taler configuration file. .SH SYNOPSIS -.B DIRNAME/taler.conf +.B taler.conf .SH DESCRIPTION -The basic structure of the configuration file is the following. The file is split into sections. Every section begins with "[SECTIONNAME]" and contains a number of options of the form "OPTION=VALUE". Empty lines and lines beginning with a "#" are treated as comments. +The basic structure of the configuration file is the following. The file is split into sections. Every section begins with "[SECTIONNAME]" and contains a number of options of the form "OPTION=VALUE". Empty lines and lines beginning with a "#" are treated as comments. Files containing default values for many of the options described below are installed under \$TALER\_PREFIX/share/taler/config.d/. The configuration file given with \-c to Taler binaries overrides these defaults. .SH EXCHANGE OPTIONS diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 49cb234a1..58a903342 100644 --- a/src/exchange-lib/Makefile.am +++ b/src/exchange-lib/Makefile.am @@ -61,5 +61,6 @@ test_exchange_api_LDADD = \ -ljansson EXTRA_DIST = \ - test-exchange-home/config/exchange-common.conf \ - test-exchange-home/master.priv + test_taler_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv \ + test_taler_exchange_api_home/.config/taler/sepa.json \ + test_taler_exchange_api.conf diff --git a/src/exchange-lib/test-exchange-home/config/exchange-common.conf b/src/exchange-lib/test-exchange-home/config/exchange-common.conf deleted file mode 100644 index 97947f111..000000000 --- a/src/exchange-lib/test-exchange-home/config/exchange-common.conf +++ /dev/null @@ -1,41 +0,0 @@ -[exchange] -# Currency supported by the exchange (can only be one) -CURRENCY = EUR - -# Wire format supported by the exchange -# We use 'test' for testing of the actual -# coin operations, and 'sepa' to test SEPA-specific routines. -WIREFORMAT = test sepa - -# HTTP port the exchange listens to -PORT = 8081 - -# Master public key used to sign the exchange's various keys -MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG - -# How to access our database -DB = postgres - -# Is this is a testcase, use transient DB actions? -TESTRUN = YES - -[exchangedb-postgres] -DB_CONN_STR = "postgres:///talercheck" - -[wire-incoming-sepa] -SEPA_RESPONSE_FILE = "test-exchange-home/sepa.json" - -[wire-incoming-sepa] -SEPA_RESPONSE_FILE = "test-exchange-home/sepa.json" - -[wire-incoming-test] -# What is the main website of the bank? -BANK_URI = "http://localhost/" -# Into which account at the 'bank' should (incoming) wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 - -[wire-outgoing-test] -# What is the main website of the bank? -BANK_URI = "http://localhost/" -# Into which account at the 'bank' should (incoming) wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 diff --git a/src/exchange-lib/test-exchange-home/config/exchange-keyup.conf b/src/exchange-lib/test-exchange-home/config/exchange-keyup.conf deleted file mode 100644 index 4a80da7e9..000000000 --- a/src/exchange-lib/test-exchange-home/config/exchange-keyup.conf +++ /dev/null @@ -1,86 +0,0 @@ -[exchange_keys] - -# how long is one signkey valid? -signkey_duration = 4 weeks - -# how long are the signatures with the signkey valid? -legal_duration = 2 years - -# how long do we generate denomination and signing keys -# ahead of time? -lookahead_sign = 32 weeks 1 day - -# how long do we provide to clients denomination and signing keys -# ahead of time? -lookahead_provide = 4 weeks 1 day - - -# Coin definitions are detected because the section -# name begins with "coin_". The rest of the -# name is free, but of course following the convention -# of "coin_$CURRENCY[_$SUBUNIT]_$VALUE" make sense. -[coin_eur_ct_1] -value = EUR:0.01 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.00 -fee_deposit = EUR:0.00 -fee_refresh = EUR:0.01 -rsa_keysize = 1024 - -[coin_eur_ct_10] -value = EUR:0.10 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -rsa_keysize = 1024 - -[coin_eur_1] -value = EUR:1 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -rsa_keysize = 1024 - -[coin_eur_5] -value = EUR:5 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -rsa_keysize = 1024 - -[coin_eur_10] -value = EUR:10 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -rsa_keysize = 1024 - -[coin_eur_1000] -value = EUR:1000 -duration_overlap = 5 minutes -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -rsa_keysize = 2048 diff --git a/src/exchange-lib/test-exchange-home/master.priv b/src/exchange-lib/test-exchange-home/master.priv deleted file mode 100644 index 394926938..000000000 --- a/src/exchange-lib/test-exchange-home/master.priv +++ /dev/null @@ -1 +0,0 @@ -p^-33XX!\0qmU_ \ No newline at end of file diff --git a/src/exchange-lib/test-exchange-home/sepa.json b/src/exchange-lib/test-exchange-home/sepa.json deleted file mode 100644 index b435ce86b..000000000 --- a/src/exchange-lib/test-exchange-home/sepa.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "Max Musterman", - "bic": "COBADEFF370", - "type": "sepa", - "sig": "4EVRC2MCJPXQC8MC00831DNWEXMZAP4JQDDE1A7R6KR3MANG24RC1VQ55AX5A2E35S58VW1VSTENFTPHG5MWG9BSN8B8WXSV21KKW20", - "address": "Musterstadt", - "salt": "3KTM1ZRMWGEQPQ254S4R5R4Q8XM0ZYWTCTE01TZ76MVBSQ6RX7A5DR08WXVH1DCHR1R7ACRB7X0EVC2XDW1CBZM9WFSD9TRMZ90BR98", - "iban": "DE89370400440532013000" -} \ No newline at end of file diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index c7eb9e314..68f4852be 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -2539,13 +2539,15 @@ main (int argc, GNUNET_log_setup ("test-exchange-api", "WARNING", NULL); + /* These might get in the way... */ + unsetenv ("XDG_DATA_HOME"); + unsetenv ("XDG_CONFIG_HOME"); proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "taler-exchange-keyup", "taler-exchange-keyup", - "-d", "test-exchange-home", - "-m", "test-exchange-home/master.priv", + "-c", "test_exchange_api.conf", NULL); GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); @@ -2554,7 +2556,7 @@ main (int argc, NULL, NULL, NULL, "taler-exchange-httpd", "taler-exchange-httpd", - "-d", "test-exchange-home", + "-c", "test_exchange_api.conf", NULL); /* give child time to start and bind against the socket */ fprintf (stderr, "Waiting for taler-exchange-httpd to be ready"); diff --git a/src/exchange-lib/test_exchange_api.conf b/src/exchange-lib/test_exchange_api.conf new file mode 100644 index 000000000..e1e916bd2 --- /dev/null +++ b/src/exchange-lib/test_exchange_api.conf @@ -0,0 +1,96 @@ +# This file is in the public domain. +# +[PATHS] +# Persistant data storage for the testcase +TALER_TEST_HOME = test_exchange_api_home/ + +[exchange] +# Currency supported by the exchange (can only be one) +CURRENCY = EUR + +# Wire format supported by the exchange +# We use 'test' for testing of the actual +# coin operations, and 'sepa' to test SEPA-specific routines. +WIREFORMAT = test sepa + +# HTTP port the exchange listens to +PORT = 8081 + +# Master public key used to sign the exchange's various keys +MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG + +# How to access our database +DB = postgres + +# Is this is a testcase, use transient DB actions? +TESTRUN = YES + +[exchangedb-postgres] +DB_CONN_STR = "postgres:///talercheck" + +[wire-incoming-test] +# What is the main website of the bank? +BANK_URI = "http://localhost/" +# Into which account at the 'bank' should (incoming) wire transfers be made? +BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] +# What is the main website of the bank? +BANK_URI = "http://localhost/" +# Into which account at the 'bank' should (incoming) wire transfers be made? +BANK_ACCOUNT_NUMBER = 2 + +[coin_eur_ct_1] +value = EUR:0.01 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.00 +fee_deposit = EUR:0.00 +fee_refresh = EUR:0.01 +rsa_keysize = 1024 + +[coin_eur_ct_10] +value = EUR:0.10 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 + +[coin_eur_1] +value = EUR:1 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 + +[coin_eur_5] +value = EUR:5 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 + +[coin_eur_10] +value = EUR:10 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 diff --git a/src/exchange-lib/test_exchange_api_home/.config/taler/sepa.json b/src/exchange-lib/test_exchange_api_home/.config/taler/sepa.json new file mode 100644 index 000000000..b435ce86b --- /dev/null +++ b/src/exchange-lib/test_exchange_api_home/.config/taler/sepa.json @@ -0,0 +1,9 @@ +{ + "name": "Max Musterman", + "bic": "COBADEFF370", + "type": "sepa", + "sig": "4EVRC2MCJPXQC8MC00831DNWEXMZAP4JQDDE1A7R6KR3MANG24RC1VQ55AX5A2E35S58VW1VSTENFTPHG5MWG9BSN8B8WXSV21KKW20", + "address": "Musterstadt", + "salt": "3KTM1ZRMWGEQPQ254S4R5R4Q8XM0ZYWTCTE01TZ76MVBSQ6RX7A5DR08WXVH1DCHR1R7ACRB7X0EVC2XDW1CBZM9WFSD9TRMZ90BR98", + "iban": "DE89370400440532013000" +} \ No newline at end of file diff --git a/src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv b/src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv new file mode 100644 index 000000000..394926938 --- /dev/null +++ b/src/exchange-lib/test_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv @@ -0,0 +1 @@ +p^-33XX!\0qmU_ \ No newline at end of file diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am index feb3c314f..d283979c8 100644 --- a/src/exchange-tools/Makefile.am +++ b/src/exchange-tools/Makefile.am @@ -1,6 +1,14 @@ # This Makefile.am is in the public domain AM_CPPFLAGS = -I$(top_srcdir)/src/include +pkgcfgdir = $(prefix)/share/taler/config.d/ + +pkgcfg_DATA = \ + auditor.conf \ + exchange-signkeys.conf \ + coins.conf + + if USE_COVERAGE AM_CFLAGS = --coverage -O0 XLIB = -lgcov @@ -81,3 +89,7 @@ taler_exchange_dbinit_CPPFLAGS = \ -I$(top_srcdir)/src/include \ -I$(top_srcdir)/src/pq/ \ $(POSTGRESQL_CPPFLAGS) + + +EXTRA_DIST = \ + auditor.conf diff --git a/src/exchange-tools/auditor.conf b/src/exchange-tools/auditor.conf new file mode 100644 index 000000000..7eb5f8ae9 --- /dev/null +++ b/src/exchange-tools/auditor.conf @@ -0,0 +1,12 @@ +# This configuration file is in the public domain +# +# It cointains options for the auditor. + +[auditor] + +# Where do we store the auditor's private key? +AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv + +# What is the Web site of the auditor (i.e. to file complaints about +# a misbehaving exchange)? +# AUDITOR_URL = https://auditor.taler.net/ diff --git a/src/exchange-tools/coins.conf b/src/exchange-tools/coins.conf new file mode 100644 index 000000000..90bf7064c --- /dev/null +++ b/src/exchange-tools/coins.conf @@ -0,0 +1,25 @@ +# This configuration file is in the public domain +# +# This is a template file for coin definitions. There are no +# reasonable defaults, as legal and business concerns influence each +# value given. +# +# Note that while we only give one section here, you can define +# any number of coins by providing many "coin_" sections. +# +# Coin definitions are detected because the section name begins with +# "coin_". The rest of the name is free, but of course following the +# convention of "coin_$CURRENCY[_$SUBUNIT]_$VALUE" make sense. +# +# [coin_eur_ct_1] + +# All options are mandatory! +# value = EUR:0.01 +# duration_overlap = 60 minutes +# duration_withdraw = 7 days +# duration_spend = 2 years +# duration_legal = 3 years +# fee_withdraw = EUR:0.00 +# fee_deposit = EUR:0.00 +# fee_refresh = EUR:0.01 +# rsa_keysize = 1024 diff --git a/src/exchange-tools/exchange-signkeys.conf b/src/exchange-tools/exchange-signkeys.conf new file mode 100644 index 000000000..3146f09b2 --- /dev/null +++ b/src/exchange-tools/exchange-signkeys.conf @@ -0,0 +1,16 @@ +# General data for signing keys. +[exchange_keys] + +# how long is one signkey valid? +signkey_duration = 4 weeks + +# how long are the signatures with the signkey valid? +legal_duration = 2 years + +# how long do we generate denomination and signing keys +# ahead of time? +lookahead_sign = 32 weeks 1 day + +# how long do we provide to clients denomination and signing keys +# ahead of time? +lookahead_provide = 4 weeks 1 day diff --git a/src/exchange-tools/taler-auditor-sign.c b/src/exchange-tools/taler-auditor-sign.c index 870f889ea..d5a3a9403 100644 --- a/src/exchange-tools/taler-auditor-sign.c +++ b/src/exchange-tools/taler-auditor-sign.c @@ -59,6 +59,11 @@ static char *auditor_url; */ static struct TALER_MasterPublicKeyP master_public_key; +/** + * Our configuration. + */ +static struct GNUNET_CONFIGURATION_Handle *cfg; + /** * Print denomination key details for diagnostics. @@ -131,10 +136,12 @@ int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'a', "auditor-key", "FILE", + char *cfgfile = NULL; + const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'a', "auditor-key", "FILENAME", "file containing the private key of the auditor", 1, &GNUNET_GETOPT_set_filename, &auditor_key_file}, + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), GNUNET_GETOPT_OPTION_HELP ("Private key of the auditor to use for signing"), {'m', "exchange-key", "KEY", "public key of the exchange (Crockford base32 encoded)", 1, @@ -142,10 +149,10 @@ main (int argc, {'u', "auditor-url", "URL", "URL of the auditor (informative link for the user)", 1, &GNUNET_GETOPT_set_string, &auditor_url}, - {'r', "exchange-request", "FILE", + {'r', "exchange-request", "FILENAME", "set of keys the exchange requested the auditor to sign", 1, &GNUNET_GETOPT_set_string, &exchange_request_file}, - {'o', "output", "FILE", + {'o', "output", "FILENAME", "where to write our signature", 1, &GNUNET_GETOPT_set_string, &output_file}, GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), @@ -163,20 +170,41 @@ main (int argc, unsigned int i; GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("taler-exchange-keyup", + GNUNET_log_setup ("taler-auditor-sign", "WARNING", NULL)); - if (GNUNET_GETOPT_run ("taler-exchange-keyup", + if (GNUNET_GETOPT_run ("taler-auditor-sign", options, argc, argv) < 0) return 1; - if (NULL == auditor_key_file) + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, + cfgfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); + return 1; + } + GNUNET_free_non_null (cfgfile); + if ( (NULL == auditor_key_file) && + (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "auditor", + "AUDITOR_PRIV_FILE", + &auditor_key_file)) ) { fprintf (stderr, - "Auditor key file not given\n"); + "Auditor key file not given in neither configuration nor command-line\n"); return 1; } - if (NULL == auditor_url) + if ( (NULL == auditor_url) && + (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "auditor", + "AUDITOR_URL", + &auditor_url)) ) { fprintf (stderr, "Auditor URL not given\n"); @@ -328,6 +356,7 @@ main (int argc, GNUNET_free (dks); return 1; } + GNUNET_free (sigs); GNUNET_free (dks); GNUNET_free (eddsa_priv); diff --git a/src/exchange-tools/taler-exchange-dbinit.c b/src/exchange-tools/taler-exchange-dbinit.c index 43a070228..9f301854f 100644 --- a/src/exchange-tools/taler-exchange-dbinit.c +++ b/src/exchange-tools/taler-exchange-dbinit.c @@ -20,24 +20,8 @@ */ #include "platform.h" #include -#include #include "taler_exchangedb_plugin.h" -/** - * Exchange directory with the keys. - */ -static char *exchange_base_dir; - -/** - * Our configuration. - */ -static struct GNUNET_CONFIGURATION_Handle *cfg; - -/** - * Our DB plugin. - */ -static struct TALER_EXCHANGEDB_Plugin *plugin; - /** * The main function of the database initialization tool. @@ -51,14 +35,15 @@ int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'d', "exchange-dir", "DIR", - "exchange directory", 1, - &GNUNET_GETOPT_set_filename, &exchange_base_dir}, + char *cfgfile = NULL; + const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), GNUNET_GETOPT_OPTION_HELP ("Initialize Taler Exchange database"), GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; + struct GNUNET_CONFIGURATION_Handle *cfg; + struct TALER_EXCHANGEDB_Plugin *plugin; if (GNUNET_GETOPT_run ("taler-exchange-dbinit", options, @@ -69,24 +54,23 @@ main (int argc, GNUNET_log_setup ("taler-exchange-dbinit", "INFO", NULL)); - if (NULL == exchange_base_dir) + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, + cfgfile)) { - fprintf (stderr, - "Exchange base directory not given.\n"); - return 1; - } - cfg = TALER_config_load (exchange_base_dir); - if (NULL == cfg) - { - fprintf (stderr, - "Failed to load exchange configuration.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); return 1; } + GNUNET_free_non_null (cfgfile); if (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg))) { fprintf (stderr, "Failed to initialize database plugin.\n"); + GNUNET_CONFIGURATION_destroy (cfg); return 1; } if (GNUNET_OK != @@ -96,9 +80,11 @@ main (int argc, fprintf (stderr, "Failed to initialize database.\n"); TALER_EXCHANGEDB_plugin_unload (plugin); + GNUNET_CONFIGURATION_destroy (cfg); return 1; } TALER_EXCHANGEDB_plugin_unload (plugin); + GNUNET_CONFIGURATION_destroy (cfg); return 0; } diff --git a/src/exchange-tools/taler-exchange-keycheck.c b/src/exchange-tools/taler-exchange-keycheck.c index d6566cd03..064f2249e 100644 --- a/src/exchange-tools/taler-exchange-keycheck.c +++ b/src/exchange-tools/taler-exchange-keycheck.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. 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 @@ -104,8 +104,8 @@ static int exchange_signkeys_check () { if (0 > TALER_EXCHANGEDB_signing_keys_iterate (exchange_directory, - &signkeys_iter, - NULL)) + &signkeys_iter, + NULL)) return GNUNET_NO; return GNUNET_OK; } @@ -186,8 +186,8 @@ static int exchange_denomkeys_check () { if (0 > TALER_EXCHANGEDB_denomination_keys_iterate (exchange_directory, - &denomkeys_iter, - NULL)) + &denomkeys_iter, + NULL)) return GNUNET_NO; return GNUNET_OK; } @@ -203,11 +203,10 @@ exchange_denomkeys_check () int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { + char *cfgfile; + const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), GNUNET_GETOPT_OPTION_HELP ("gnunet-exchange-keycheck OPTIONS"), - {'d', "directory", "DIRECTORY", - "exchange directory with keys to check", 1, - &GNUNET_GETOPT_set_filename, &exchange_directory}, GNUNET_GETOPT_OPTION_END }; @@ -220,20 +219,29 @@ main (int argc, char *const *argv) options, argc, argv) < 0) return 1; - if (NULL == exchange_directory) + kcfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (kcfg, + cfgfile)) { - fprintf (stderr, - "Exchange directory not given\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); return 1; } - - kcfg = TALER_config_load (exchange_directory); - if (NULL == kcfg) + GNUNET_free_non_null (cfgfile); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "exchange", + "KEYDIR", + &exchange_directory)) { - fprintf (stderr, - "Failed to load exchange configuration\n"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "KEYDIR"); return 1; } + if ( (GNUNET_OK != exchange_signkeys_check ()) || (GNUNET_OK != exchange_denomkeys_check ()) ) { diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c index 3413dfb42..ab2123a15 100644 --- a/src/exchange-tools/taler-exchange-keyup.c +++ b/src/exchange-tools/taler-exchange-keyup.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. 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 @@ -876,10 +876,9 @@ int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'d', "exchange-dir", "DIR", - "exchange directory with keys to update", 1, - &GNUNET_GETOPT_set_filename, &exchange_directory}, + char *cfgfile = NULL; + const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), GNUNET_GETOPT_OPTION_HELP ("Setup signing and denomination keys for a Taler exchange"), {'m', "master-key", "FILE", "master key file (private key)", 1, @@ -905,12 +904,17 @@ main (int argc, options, argc, argv) < 0) return 1; - if (NULL == exchange_directory) + kcfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (kcfg, + cfgfile)) { - fprintf (stderr, - "Exchange directory not given\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); return 1; } + GNUNET_free_non_null (cfgfile); if (NULL != pretend_time_str) { if (GNUNET_OK != @@ -928,18 +932,26 @@ main (int argc, now = GNUNET_TIME_absolute_get (); } GNUNET_TIME_round_abs (&now); - - kcfg = TALER_config_load (exchange_directory); - if (NULL == kcfg) + if ( (NULL == masterkeyfile) && + (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "exchange", + "MASTER_PRIV_FILE", + &masterkeyfile)) ) { fprintf (stderr, - "Failed to load exchange configuration\n"); + "Master key file not given in neither configuration nor command-line\n"); return 1; } - if (NULL == masterkeyfile) + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (kcfg, + "exchange", + "KEYDIR", + &exchange_directory)) { - fprintf (stderr, - "Master key file not given\n"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "KEYDIR"); return 1; } eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile); diff --git a/src/exchange-tools/taler-exchange-reservemod.c b/src/exchange-tools/taler-exchange-reservemod.c index 03a0d17d5..3494e88a0 100644 --- a/src/exchange-tools/taler-exchange-reservemod.c +++ b/src/exchange-tools/taler-exchange-reservemod.c @@ -51,6 +51,7 @@ static struct TALER_EXCHANGEDB_Plugin *plugin; int main (int argc, char *const *argv) { + char *cfgfile = NULL; char *reserve_pub_str = NULL; char *add_str = NULL; struct TALER_Amount add_value; @@ -63,10 +64,8 @@ main (int argc, char *const *argv) {'a', "add", "DENOM", "value to add", 1, &GNUNET_GETOPT_set_string, &add_str}, - {'d', "exchange-dir", "DIR", - "exchange directory with keys to update", 1, - &GNUNET_GETOPT_set_filename, &exchange_directory}, - {'D', "details", "JSON", + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), + {'d', "details", "JSON", "details about the bank transaction which justify why we add this amount", 1, &GNUNET_GETOPT_set_string, &details}, GNUNET_GETOPT_OPTION_HELP ("Deposit funds into a Taler reserve"), @@ -87,10 +86,29 @@ main (int argc, char *const *argv) options, argc, argv) < 0) return 1; - if (NULL == exchange_directory) + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, + cfgfile)) { - fprintf (stderr, - "Exchange directory not given\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); + return 1; + } + GNUNET_free_non_null (cfgfile); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "exchange", + "KEYDIR", + &exchange_directory)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "KEYDIR"); GNUNET_free_non_null (add_str); GNUNET_free_non_null (details); GNUNET_free_non_null (reserve_pub_str); @@ -133,16 +151,6 @@ main (int argc, char *const *argv) return 1; } - cfg = TALER_config_load (exchange_directory); - if (NULL == cfg) - { - fprintf (stderr, - "Failed to load exchange configuration\n"); - GNUNET_free_non_null (add_str); - GNUNET_free_non_null (details); - GNUNET_free_non_null (reserve_pub_str); - return 1; - } ret = 1; if (NULL == (plugin = TALER_EXCHANGEDB_plugin_load (cfg))) diff --git a/src/exchange-tools/taler-exchange-wire.c b/src/exchange-tools/taler-exchange-wire.c index 5bb4835de..930086d39 100644 --- a/src/exchange-tools/taler-exchange-wire.c +++ b/src/exchange-tools/taler-exchange-wire.c @@ -46,6 +46,11 @@ static char *method; */ static char *output_filename; +/** + * Our configuration. + */ +static struct GNUNET_CONFIGURATION_Handle *cfg; + /** * The main function of the taler-exchange-sepa tool. This tool is used @@ -59,7 +64,9 @@ int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { + char *cfgfile = NULL; + const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), {'j', "json", "JSON", "account information in JSON format", 1, &GNUNET_GETOPT_set_string, &json_in}, @@ -95,10 +102,26 @@ main (int argc, options, argc, argv) < 0) return 1; - if (NULL == masterkeyfile) + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, + cfgfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); + return 1; + } + GNUNET_free_non_null (cfgfile); + if ( (NULL == masterkeyfile) && + (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "exchange-master", + "MASTER_PRIV_FILE", + &masterkeyfile)) ) { fprintf (stderr, - "Master key file not given\n"); + "Master key file not given in neither configuration nor command-line\n"); return 1; } eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile); diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am index e815d911b..dc7225b0c 100644 --- a/src/exchange/Makefile.am +++ b/src/exchange/Makefile.am @@ -89,4 +89,6 @@ TESTS = \ EXTRA_DIST = \ test-taler-exchange-aggregator-postgres.conf \ + test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv \ + test_taler_exchange_httpd.conf \ exchange.conf diff --git a/src/exchange/exchange.conf b/src/exchange/exchange.conf index 6a4f03ac1..eab476ccd 100644 --- a/src/exchange/exchange.conf +++ b/src/exchange/exchange.conf @@ -1,13 +1,20 @@ +# This file is in the public domain. +# [exchange] # Currency supported by the exchange (can only be one) # CURRENCY = EUR -# Wire format supported by the exchange We use 'test' for testing of +# Where do we store the private keys the exchange needs at +# runtime? (Denomination and signing keys are then stored +# in respective subdirectories.) +KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/ + +# Wire format supported by the exchange. We use 'test' for testing of # the actual coin operations. -WIREFORMAT = test +# WIREFORMAT = test # HTTP port the exchange listens to -PORT = 8081 +# PORT = 8081 # Master public key used to sign the exchange's various keys # MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG @@ -18,21 +25,5 @@ DB = postgres # Is this is a testcase, use transient DB actions? # TESTRUN = YES -[exchangedb-postgres] -DB_CONN_STR = "postgres:///taler" - - -[wire-incoming-test] -# What is the main website of the bank? -BANK_URI = "http://localhost:8082/" -# Into which account at the 'bank' should incoming -# wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 - -[wire-outgoing-test] -# What is the main website of the bank? -BANK_URI = "http://localhost:8082/" - -# From which account at the 'bank' should outgoing -# wire transfers be made? -BANK_ACCOUNT_NUMBER = 3 +# Where do we store the offline master private key of the exchange? +MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 25ddcf3f6..e4ba975a2 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -134,11 +134,6 @@ static char *exchange_currency_string; */ static char *exchange_wireformat; -/** - * Base directory of the exchange (global) - */ -static char *exchange_directory; - /** * The exchange's configuration (global) */ @@ -238,26 +233,20 @@ shutdown_task (void *cls) } TALER_EXCHANGEDB_plugin_unload (db_plugin); TALER_WIRE_plugin_unload (wire_plugin); + GNUNET_CONFIGURATION_destroy (cfg); + cfg = NULL; } /** - * Load configuration parameters for the exchange - * server into the corresponding global variables. + * Parse configuration parameters for the exchange server into the + * corresponding global variables. * - * @param exchange_directory the exchange's directory * @return #GNUNET_OK on success */ static int -exchange_serve_process_config (const char *exchange_directory) +exchange_serve_process_config () { - cfg = TALER_config_load (exchange_directory); - if (NULL == cfg) - { - fprintf (stderr, - "Failed to load exchange configuration\n"); - return GNUNET_SYSERR; - } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "exchange", @@ -311,7 +300,6 @@ exchange_serve_process_config (const char *exchange_directory) exchange_wireformat); return GNUNET_SYSERR; } - return GNUNET_OK; } @@ -958,10 +946,24 @@ run_transfers (void *cls) * First task. * * @param cls closure, NULL + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration */ static void -run (void *cls) +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) { + cfg = GNUNET_CONFIGURATION_dup (c); + if (GNUNET_OK != exchange_serve_process_config ()) + { + GNUNET_CONFIGURATION_destroy (cfg); + cfg = NULL; + global_ret = 1; + return; + } task = GNUNET_SCHEDULER_add_now (&run_transfers, NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, @@ -982,13 +984,9 @@ main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'d', "exchange-dir", "DIR", - "exchange directory with configuration and keys for operating the exchange", 1, - &GNUNET_GETOPT_set_filename, &exchange_directory}, {'f', "format", "WIREFORMAT", "wireformat to use, overrides WIREFORMAT option in [exchange] section", 1, &GNUNET_GETOPT_set_filename, &exchange_wireformat}, - GNUNET_GETOPT_OPTION_HELP ("background process that aggregates and executes wire transfers to merchants"), {'t', "test", NULL, "run in test mode with temporary tables", 0, &GNUNET_GETOPT_set_one, &test_mode}, @@ -996,30 +994,17 @@ main (int argc, GNUNET_GETOPT_OPTION_END }; - GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("taler-exchange-aggregator", - "INFO", - NULL)); - if (0 >= - GNUNET_GETOPT_run ("taler-exchange-aggregator", - options, - argc, argv)) - return 1; - if (NULL == exchange_directory) - { - fprintf (stderr, - "Exchange directory not specified\n"); - return 1; - } + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, + &argc, &argv)) + return 2; if (GNUNET_OK != - exchange_serve_process_config (exchange_directory)) - { + GNUNET_PROGRAM_run (argc, argv, + "taler-exchange-aggregator", + gettext_noop ("background process that aggregates and executes wire transfers to merchants"), + options, + &run, NULL)) return 1; - } - global_ret = GNUNET_OK; - GNUNET_SCHEDULER_run (&run, NULL); - - return (GNUNET_SYSERR == global_ret) ? 1 : 0; + return global_ret; } /* end of taler-exchange-aggregator.c */ diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 3061443b5..a8e9b3b08 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -360,16 +360,20 @@ handle_mhd_request (void *cls, * @return #GNUNET_OK on success */ static int -exchange_serve_process_config (const char *exchange_directory) +exchange_serve_process_config () { unsigned long long port; char *TMH_master_public_key_str; - cfg = TALER_config_load (exchange_directory); - if (NULL == cfg) + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "exchange", + "KEYDIR", + &TMH_exchange_directory)) { - fprintf (stderr, - "Failed to load exchange configuration\n"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "KEYDIR"); return GNUNET_SYSERR; } if (GNUNET_OK != @@ -615,13 +619,12 @@ int main (int argc, char *const *argv) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { + char *cfgfile = NULL; + const struct GNUNET_GETOPT_CommandLineOption options[] = { {'C', "connection-close", NULL, "force HTTP connections to be closed after each request", 0, &GNUNET_GETOPT_set_one, &TMH_exchange_connection_close}, - {'d', "exchange-dir", "DIR", - "exchange directory with configuration and keys for operating the exchange", 1, - &GNUNET_GETOPT_set_filename, &TMH_exchange_directory}, + GNUNET_GETOPT_OPTION_CFG_FILE (&cfgfile), {'t', "timeout", "SECONDS", "after how long do connections timeout by default (in seconds)", 1, &GNUNET_GETOPT_set_uint, &connection_timeout}, @@ -645,15 +648,18 @@ main (int argc, options, argc, argv)) return 1; - if (NULL == TMH_exchange_directory) + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfgfile)) { - fprintf (stderr, - "Exchange directory not specified\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + cfgfile); + GNUNET_free_non_null (cfgfile); return 1; } - + GNUNET_free_non_null (cfgfile); if (GNUNET_OK != - exchange_serve_process_config (TMH_exchange_directory)) + exchange_serve_process_config ()) return 1; mydaemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index dbb72fab2..c9db50895 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -650,9 +650,9 @@ TMH_KS_acquire_ (const char *location) TALER_EXCHANGEDB_signing_keys_iterate (TMH_exchange_directory, &reload_keys_sign_iter, key_state); - TALER_EXCHANGEDB_auditor_iterate (TMH_exchange_directory, - &reload_auditor_iter, - key_state); + TALER_EXCHANGEDB_auditor_iterate (cfg, + &reload_auditor_iter, + key_state); ks.purpose.size = htonl (sizeof (ks)); ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET); ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time); diff --git a/src/exchange/test-exchange-home/config/exchange-common.conf b/src/exchange/test-exchange-home/config/exchange-common.conf deleted file mode 100644 index 4078cbee5..000000000 --- a/src/exchange/test-exchange-home/config/exchange-common.conf +++ /dev/null @@ -1,39 +0,0 @@ -[exchange] -# Currency supported by the exchange (can only be one) -CURRENCY = EUR - -# Wire format supported by the exchange -# We use 'test' for testing of the actual -# coin operations. -WIREFORMAT = test - -# HTTP port the exchange listens to -PORT = 8081 - -# Master public key used to sign the exchange's various keys -MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG - -# How to access our database -DB = postgres - -# Is this is a testcase, use transient DB actions? -TESTRUN = YES - -[exchangedb-postgres] -DB_CONN_STR = "postgres:///talercheck" - - -[wire-incoming-test] -# What is the main website of the bank? -BANK_URI = "http://localhost:8082/" -# Into which account at the 'bank' should incoming -# wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 - -[wire-outgoing-test] -# What is the main website of the bank? -BANK_URI = "http://localhost:8082/" - -# From which account at the 'bank' should outgoing -# wire transfers be made? -BANK_ACCOUNT_NUMBER = 3 diff --git a/src/exchange/test-exchange-home/master.priv b/src/exchange/test-exchange-home/master.priv deleted file mode 100644 index 394926938..000000000 --- a/src/exchange/test-exchange-home/master.priv +++ /dev/null @@ -1 +0,0 @@ -p^-33XX!\0qmU_ \ No newline at end of file diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 80c14ed67..594f972c1 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -570,8 +570,7 @@ interpreter (void *cls) NULL, NULL, NULL, "taler-exchange-aggregator", "taler-exchange-aggregator", - /* "-c", config_filename, */ - "-d", "test-exchange-home", + "-c", "test_taler_exchange_httpd.conf", "-t", /* enable temporary tables */ NULL); return; @@ -1523,6 +1522,9 @@ main (int argc, "test-taler-exchange-aggregator-%s", plugin_name); (void) GNUNET_asprintf (&config_filename, "%s.conf", testname); + /* these might get in the way */ + unsetenv ("XDG_DATA_HOME"); + unsetenv ("XDG_CONFIG_HOME"); GNUNET_log_setup ("test_taler_exchange_aggregator", "WARNING", NULL); diff --git a/src/exchange/test_taler_exchange_httpd.conf b/src/exchange/test_taler_exchange_httpd.conf new file mode 100644 index 000000000..0ce9dadd2 --- /dev/null +++ b/src/exchange/test_taler_exchange_httpd.conf @@ -0,0 +1,82 @@ +[PATHS] +# Persistant data storage for the testcase +TALER_TEST_HOME = test_taler_exchange_httpd_home/ + + +[exchange] +# Currency supported by the exchange (can only be one) +CURRENCY = EUR + +# Wire format supported by the exchange +# We use 'test' for testing of the actual +# coin operations. +WIREFORMAT = test + +# HTTP port the exchange listens to +PORT = 8081 + +# Master public key used to sign the exchange's various keys +MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG + +# How to access our database +DB = postgres + +# Is this is a testcase, use transient DB actions? +TESTRUN = YES + + + + +[exchangedb-postgres] +DB_CONN_STR = "postgres:///talercheck" + + +[wire-incoming-test] +# What is the main website of the bank? +BANK_URI = "http://localhost:8082/" +# Into which account at the 'bank' should incoming +# wire transfers be made? +BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] +# What is the main website of the bank? +BANK_URI = "http://localhost:8082/" + +# From which account at the 'bank' should outgoing +# wire transfers be made? +BANK_ACCOUNT_NUMBER = 3 + + +# Coins for the tests. +[coin_eur_ct_1] +value = EUR:0.01 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.00 +fee_deposit = EUR:0.00 +fee_refresh = EUR:0.01 +rsa_keysize = 1024 + +[coin_eur_ct_10] +value = EUR:0.10 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 + +[coin_eur_1] +value = EUR:1 +duration_overlap = 5 minutes +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +rsa_keysize = 1024 diff --git a/src/exchange/test_taler_exchange_httpd.sh b/src/exchange/test_taler_exchange_httpd.sh index 727014243..2b55ef5f4 100755 --- a/src/exchange/test_taler_exchange_httpd.sh +++ b/src/exchange/test_taler_exchange_httpd.sh @@ -1,7 +1,7 @@ #!/bin/bash # # This file is part of TALER -# Copyright (C) 2015 GNUnet e.V. +# Copyright (C) 2015, 2016 Inria and GNUnet e.V. # # 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 @@ -19,15 +19,19 @@ # taler-exchange-httpd. Basically, the goal is to make sure that the # HTTP server survives (and produces the 'correct' error code). # -# We read the JSON snippets to POST from test_taler_exchange_httpd.data +# +# Clear environment from variables that override config. +export XDG_DATA_HOME= +export XDG_CONFIG_HOME= # # Setup keys. -taler-exchange-keyup -d test-exchange-home -m test-exchange-home/master.priv +taler-exchange-keyup -c test_taler_exchange_httpd.conf # Run Exchange HTTPD (in background) -taler-exchange-httpd -d test-exchange-home & +taler-exchange-httpd -c test_taler_exchange_httpd.conf & # Give HTTP time to start sleep 5 -# Run test... +# Finally run test... +# We read the JSON snippets to POST from test_taler_exchange_httpd.data cat test_taler_exchange_httpd.data | grep -v ^\# | awk '{ print "curl -d \47" $2 "\47 http://localhost:8081" $1 }' | bash # Stop HTTP server kill -TERM %% diff --git a/src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv b/src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv new file mode 100644 index 000000000..394926938 --- /dev/null +++ b/src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/offline-keys/master.priv @@ -0,0 +1 @@ +p^-33XX!\0qmU_ \ No newline at end of file diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index fff112994..0c6a73138 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -6,6 +6,17 @@ if USE_COVERAGE XLIB = -lgcov endif +pkgcfgdir = $(prefix)/share/taler/config.d/ + +pkgcfg_DATA = \ + exchangedb.conf \ + exchangedb-postgres.conf + +EXTRA_DIST = \ + exchangedb.conf \ + exchangedb-postgres.conf + + plugindir = $(libdir)/taler if HAVE_POSTGRESQL diff --git a/src/exchangedb/exchangedb-postgres.conf b/src/exchangedb/exchangedb-postgres.conf new file mode 100644 index 000000000..3de7474ff --- /dev/null +++ b/src/exchangedb/exchangedb-postgres.conf @@ -0,0 +1,2 @@ +[exchangedb-postgres] +DB_CONN_STR = "postgres:///taler" diff --git a/src/exchangedb/exchangedb.conf b/src/exchangedb/exchangedb.conf new file mode 100644 index 000000000..19277ed23 --- /dev/null +++ b/src/exchangedb/exchangedb.conf @@ -0,0 +1,7 @@ +# This file is in the public domain. +# +# Database-backend independent specification for the exchangedb module. +# +[exchangedb] +# Where do we expect to find information about auditors? +AUDITOR_BASE_DIR = ${TALER_DATA_HOME}/auditors/ diff --git a/src/exchangedb/exchangedb_keyio.c b/src/exchangedb/exchangedb_keyio.c index 4d4f78ed5..9f170f645 100644 --- a/src/exchangedb/exchangedb_keyio.c +++ b/src/exchangedb/exchangedb_keyio.c @@ -502,9 +502,7 @@ auditor_iter (void *cls, /** * Call @a it with information for each auditor found in the @a exchange_base_dir. * - * @param exchange_base_dir base directory for the exchange, - * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS - * subdirectory + * @param cfg configuration to use * @param it function to call with auditor information * @param it_cls closure for @a it * @return -1 on error, 0 if no files were found, otherwise @@ -513,23 +511,26 @@ auditor_iter (void *cls, * as maybe none of the files were well-formed) */ int -TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir, +TALER_EXCHANGEDB_auditor_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, TALER_EXCHANGEDB_AuditorIterator it, void *it_cls) { - char *dir; struct AuditorIterateContext aic; int ret; + char *auditor_base_dir; - GNUNET_asprintf (&dir, - "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_AUDITORS, - exchange_base_dir); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "exchangedb", + "AUDITOR_BASE_DIR", + &auditor_base_dir)) + return -1; aic.it = it; aic.it_cls = it_cls; - ret = GNUNET_DISK_directory_scan (dir, + ret = GNUNET_DISK_directory_scan (auditor_base_dir, &auditor_iter, &aic); - GNUNET_free (dir); + GNUNET_free (auditor_base_dir); return ret; } diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h index e13df2d46..1f6445212 100644 --- a/src/include/taler_exchangedb_lib.h +++ b/src/include/taler_exchangedb_lib.h @@ -37,12 +37,6 @@ */ #define TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS "denomkeys" -/** - * Subdirectory under the exchange's base directory which contains - * the exchange's auditing information. - */ -#define TALER_EXCHANGEDB_DIR_AUDITORS "auditors" - GNUNET_NETWORK_STRUCT_BEGIN @@ -234,9 +228,7 @@ typedef int /** * Call @a it with information for each auditor found in the @a exchange_base_dir. * - * @param exchange_base_dir base directory for the exchange, - * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS - * subdirectory + * @param cfg configuration to use * @param it function to call with auditor information * @param it_cls closure for @a it * @return -1 on error, 0 if no files were found, otherwise @@ -245,7 +237,7 @@ typedef int * as maybe none of the files were well-formed) */ int -TALER_EXCHANGEDB_auditor_iterate (const char *exchange_base_dir, +TALER_EXCHANGEDB_auditor_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, TALER_EXCHANGEDB_AuditorIterator it, void *it_cls); diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 425304152..0b1d40c85 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -95,17 +95,6 @@ TALER_b2s (const void *buf, #define TALER_B2S(obj) TALER_b2s (obj, sizeof (*obj)) -/** - * Load configuration by parsing all configuration - * files in the given directory. - * - * @param base_dir directory with the configuration files - * @return NULL on error, otherwise configuration - */ -struct GNUNET_CONFIGURATION_Handle * -TALER_config_load (const char *base_dir); - - /** * Obtain denomination amount from configuration file. * diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 54f0f0e38..f52bc81c6 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -6,6 +6,15 @@ if USE_COVERAGE XLIB = -lgcov endif + +pkgcfgdir = $(prefix)/share/taler/config.d/ + +pkgcfg_DATA = \ + paths.conf + +EXTRA_DIST = \ + paths.conf + if WALLET_ONLY lib_LTLIBRARIES = \ libtalerutil_wallet.la diff --git a/src/util/paths.conf b/src/util/paths.conf new file mode 100644 index 000000000..03febb0e4 --- /dev/null +++ b/src/util/paths.conf @@ -0,0 +1,29 @@ +# This file is in the public domain. +# +[PATHS] +# The PATHS section is special, as filenames including $-expression are +# expanded using the values from PATHS or the system environment (PATHS +# is checked first). Taler also supports expanding $-expressions using +# defaults with the syntax "${VAR:-default}". Here, "default" can again +# be a $-expression. +# +# We usually want $HOME for $TALER_HOME, but we allow testcases to +# easily override this by setting $TALER_TEST_HOME. +# +TALER_HOME = ${TALER_TEST_HOME:-${HOME:-${USERPROFILE}}} + +# see XDG Base Directory Specification at +# http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +# for how these should be used. + +# Persistant data storage +TALER_DATA_HOME = ${XDG_DATA_HOME:-$TALER_HOME/.local/share}/taler/ + +# Configuration files +TALER_CONFIG_HOME = ${XDG_CONFIG_HOME:-$TALER_HOME/.config}/taler/ + +# Cached data, no big deal if lost +TALER_CACHE_HOME = ${XDG_CACHE_HOME:-$TALER_HOME/.cache}/taler/ + +# Runtime data (always lost on system boot) +TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/taler-system-runtime/ diff --git a/src/util/util.c b/src/util/util.c index 434ce8a9d..d5fa8c05c 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -89,31 +89,4 @@ TALER_config_get_denom (struct GNUNET_CONFIGURATION_Handle *cfg, } -/** - * Load configuration by parsing all configuration - * files in the given directory. - * - * @param base_dir directory with the configuration files - * @return NULL on error, otherwise configuration - */ -struct GNUNET_CONFIGURATION_Handle * -TALER_config_load (const char *base_dir) -{ - struct GNUNET_CONFIGURATION_Handle *cfg; - char *cfg_dir; - int res; - - res = GNUNET_asprintf (&cfg_dir, - "%s" DIR_SEPARATOR_STR "config", - base_dir); - GNUNET_assert (res > 0); - cfg = GNUNET_CONFIGURATION_create (); - res = GNUNET_CONFIGURATION_load_from (cfg, cfg_dir); - GNUNET_free (cfg_dir); - if (GNUNET_OK != res) - return NULL; - return cfg; -} - - /* end of util.c */ diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index fd59c8eb7..0ed5f7be9 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -6,6 +6,17 @@ if USE_COVERAGE XLIB = -lgcov endif +pkgcfgdir = $(prefix)/share/taler/config.d/ + +pkgcfg_DATA = \ + wire-sepa.conf \ + wire-test.conf + + +EXTRA_DIST = \ + wire-sepa.conf \ + wire-test.conf + plugindir = $(libdir)/taler plugin_LTLIBRARIES = \ diff --git a/src/wire/wire-sepa.conf b/src/wire/wire-sepa.conf new file mode 100644 index 000000000..0ee17db30 --- /dev/null +++ b/src/wire/wire-sepa.conf @@ -0,0 +1,7 @@ +# Configuration for SEPA wire plugin. + +[wire-incoming-sepa] +SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json + +[wire-incoming-sepa] +SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json diff --git a/src/wire/wire-test.conf b/src/wire/wire-test.conf new file mode 100644 index 000000000..f2a71e2e4 --- /dev/null +++ b/src/wire/wire-test.conf @@ -0,0 +1,14 @@ +[wire-incoming-test] +# What is the main website of the bank? +# BANK_URI = "http://localhost:8082/" +# Into which account at the 'bank' should incoming +# wire transfers be made? +# BANK_ACCOUNT_NUMBER = 2 + +[wire-outgoing-test] +# What is the main website of the bank? +# BANK_URI = "http://localhost:8082/" + +# From which account at the 'bank' should outgoing +# wire transfers be made? +# BANK_ACCOUNT_NUMBER = 3 -- cgit v1.2.3 From b018d4d5b0798bdad6002cb7bbd246247b3ebd4f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 11 Apr 2016 02:37:56 +0200 Subject: implementing #4357, but test missing --- src/exchange-lib/Makefile.am | 1 + src/exchange-lib/test_exchange_api.c | 18 +- src/exchange-lib/test_exchange_api.conf | 9 +- .../test_exchange_api_home/.config/taler/test.json | 8 + src/exchange/taler-exchange-httpd_admin.c | 3 +- src/exchange/taler-exchange-httpd_deposit.c | 3 +- src/exchange/taler-exchange-httpd_validation.c | 18 +- src/exchange/taler-exchange-httpd_validation.h | 4 +- src/exchange/test_taler_exchange_aggregator.c | 4 +- src/exchange/test_taler_exchange_httpd.conf | 9 +- .../.config/taler/test.json | 8 + src/wire/plugin_wire_test.c | 229 ++++++++++++++------- src/wire/wire-sepa.conf | 7 +- src/wire/wire-test.conf | 22 +- 14 files changed, 223 insertions(+), 120 deletions(-) create mode 100644 src/exchange-lib/test_exchange_api_home/.config/taler/test.json create mode 100644 src/exchange/test_taler_exchange_httpd_home/.config/taler/test.json (limited to 'src/wire') diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am index 58a903342..d953a7a86 100644 --- a/src/exchange-lib/Makefile.am +++ b/src/exchange-lib/Makefile.am @@ -62,5 +62,6 @@ test_exchange_api_LDADD = \ EXTRA_DIST = \ test_taler_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv \ + test_taler_exchange_api_home/.config/taler/test.json \ test_taler_exchange_api_home/.config/taler/sepa.json \ test_taler_exchange_api.conf diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 68f4852be..3659e119e 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -2327,7 +2327,7 @@ run (void *cls) { .oc = OC_ADMIN_ADD_INCOMING, .label = "create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":42 }", + .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2348,7 +2348,7 @@ run (void *cls) .expected_response_code = MHD_HTTP_OK, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 1 }, @@ -2365,7 +2365,7 @@ run (void *cls) .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":43 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":43 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 1 }, /* Try to double-spend the 5 EUR coin at the same merchant (but different @@ -2375,7 +2375,7 @@ run (void *cls) .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }", .details.deposit.transaction_id = 2 }, /* Try to double-spend the 5 EUR coin at the same merchant (but different @@ -2385,7 +2385,7 @@ run (void *cls) .expected_response_code = MHD_HTTP_FORBIDDEN, .details.deposit.amount = "EUR:5", .details.deposit.coin_ref = "withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\":[{ \"name\":\"ice cream\", \"value\":2 } ] }", .details.deposit.transaction_id = 1 }, @@ -2395,7 +2395,7 @@ run (void *cls) { .oc = OC_ADMIN_ADD_INCOMING, .label = "refresh-create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":424 }", + .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":424 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2410,7 +2410,7 @@ run (void *cls) .expected_response_code = MHD_HTTP_OK, .details.deposit.amount = "EUR:1", .details.deposit.coin_ref = "refresh-withdraw-coin-1", - .details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:1\" } ] }", .details.deposit.transaction_id = 42421 }, @@ -2444,7 +2444,7 @@ run (void *cls) .details.deposit.amount = "EUR:1", .details.deposit.coin_ref = "refresh-reveal-1", .details.deposit.coin_idx = 0, - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":3 } ] }", .details.deposit.transaction_id = 2 }, @@ -2456,7 +2456,7 @@ run (void *cls) .details.deposit.amount = "EUR:0.1", .details.deposit.coin_ref = "refresh-reveal-1", .details.deposit.coin_idx = 4, - .details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }", + .details.deposit.wire_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", .details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":3 } ] }", .details.deposit.transaction_id = 2 }, diff --git a/src/exchange-lib/test_exchange_api.conf b/src/exchange-lib/test_exchange_api.conf index e1e916bd2..281ac7361 100644 --- a/src/exchange-lib/test_exchange_api.conf +++ b/src/exchange-lib/test_exchange_api.conf @@ -29,14 +29,13 @@ TESTRUN = YES DB_CONN_STR = "postgres:///talercheck" [wire-incoming-test] -# What is the main website of the bank? -BANK_URI = "http://localhost/" -# Into which account at the 'bank' should (incoming) wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. +TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json [wire-outgoing-test] # What is the main website of the bank? -BANK_URI = "http://localhost/" +BANK_URI = "http://localhost:8082/" # Into which account at the 'bank' should (incoming) wire transfers be made? BANK_ACCOUNT_NUMBER = 2 diff --git a/src/exchange-lib/test_exchange_api_home/.config/taler/test.json b/src/exchange-lib/test_exchange_api_home/.config/taler/test.json new file mode 100644 index 000000000..be5e92c11 --- /dev/null +++ b/src/exchange-lib/test_exchange_api_home/.config/taler/test.json @@ -0,0 +1,8 @@ +{ + "salt": "AZPRFVJ58NM6M7J5CZQPJAH3EW5DYM52AEZ9Y1C1ER3W94QV8D8TQKF6CK8MYQRA9QMSKDQTGZ306ZS9GQ0M6R01CJ20KPP49WFDZK8", + "name": "The exchange", + "account_number": 3, + "bank_uri": "http://localhost:8082/", + "type": "test", + "sig": "RPQXP9S4P8PQP7HEZQNRSZCT0ATNEP8GW0P5TPM34V5RX86FCD670V44R9NETSYDDKB8SZV7TKY9PAJYTY51D3VDWY9XXQ5BPFRXR28" +} \ No newline at end of file diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c index cc0245cd6..29da2d441 100644 --- a/src/exchange/taler-exchange-httpd_admin.c +++ b/src/exchange/taler-exchange-httpd_admin.c @@ -145,7 +145,8 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh, return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } if (GNUNET_YES != - TMH_json_validate_wireformat (wire)) + TMH_json_validate_wireformat (wire, + GNUNET_NO)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 73e6463df..efef3d04e 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -165,7 +165,8 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, return MHD_YES; /* failure */ if (GNUNET_YES != - TMH_json_validate_wireformat (wire)) + TMH_json_validate_wireformat (wire, + GNUNET_NO)) { GNUNET_JSON_parse_free (spec); return TMH_RESPONSE_reply_arg_unknown (connection, diff --git a/src/exchange/taler-exchange-httpd_validation.c b/src/exchange/taler-exchange-httpd_validation.c index 61599fe1f..12244c518 100644 --- a/src/exchange/taler-exchange-httpd_validation.c +++ b/src/exchange/taler-exchange-httpd_validation.c @@ -153,10 +153,12 @@ TMH_VALIDATION_done () * a wire address. * * @param wire the JSON wire format object + * @param ours #GNUNET_YES if the signature should match our master key * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ int -TMH_json_validate_wireformat (const json_t *wire) +TMH_json_validate_wireformat (const json_t *wire, + int ours) { const char *stype; json_error_t error; @@ -175,7 +177,9 @@ TMH_json_validate_wireformat (const json_t *wire) stype)) return p->plugin->wire_validate (p->plugin->cls, wire, - &TMH_master_public_key); + (GNUNET_YES == ours) + ? &TMH_master_public_key + : NULL); return GNUNET_NO; } @@ -227,6 +231,16 @@ TMH_VALIDATION_get_wire_methods (const char *prefix) method = plugin->get_wire_details (plugin->cls, cfg, account_name); + if (GNUNET_YES != + TMH_json_validate_wireformat (method, + GNUNET_YES)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Account details for method `%s' ill-formed. Disabling method\n", + p->type); + json_decref (method); + method = NULL; + } if (NULL != method) json_object_set_new (methods, p->type, diff --git a/src/exchange/taler-exchange-httpd_validation.h b/src/exchange/taler-exchange-httpd_validation.h index a5403edd4..bd04994ef 100644 --- a/src/exchange/taler-exchange-httpd_validation.h +++ b/src/exchange/taler-exchange-httpd_validation.h @@ -47,10 +47,12 @@ TMH_VALIDATION_done (void); * a wire address. * * @param wire the JSON wire format object + * @param ours #GNUNET_YES if the signature should match our master key * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ int -TMH_json_validate_wireformat (const json_t *wire); +TMH_json_validate_wireformat (const json_t *wire, + int ours); /** * Check if we support the given wire method. diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 594f972c1..a799316f3 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -481,9 +481,7 @@ do_deposit (struct Command *cmd) return GNUNET_SYSERR; } fake_coin (&deposit.coin); - /* Build JSON for wire details; - note that this simple method may fail in the future if we implement - and enforce signature checking on test-wire account details */ + /* Build JSON for wire details */ deposit.wire = json_pack ("{s:s, s:s, s:I}", "type", "test", "bank_uri", "http://localhost:8082/", diff --git a/src/exchange/test_taler_exchange_httpd.conf b/src/exchange/test_taler_exchange_httpd.conf index 0ce9dadd2..5b49c0824 100644 --- a/src/exchange/test_taler_exchange_httpd.conf +++ b/src/exchange/test_taler_exchange_httpd.conf @@ -31,20 +31,13 @@ TESTRUN = YES DB_CONN_STR = "postgres:///talercheck" -[wire-incoming-test] -# What is the main website of the bank? -BANK_URI = "http://localhost:8082/" -# Into which account at the 'bank' should incoming -# wire transfers be made? -BANK_ACCOUNT_NUMBER = 2 - [wire-outgoing-test] # What is the main website of the bank? BANK_URI = "http://localhost:8082/" # From which account at the 'bank' should outgoing # wire transfers be made? -BANK_ACCOUNT_NUMBER = 3 +EXCHANGE_ACCOUNT_NUMBER = 3 # Coins for the tests. diff --git a/src/exchange/test_taler_exchange_httpd_home/.config/taler/test.json b/src/exchange/test_taler_exchange_httpd_home/.config/taler/test.json new file mode 100644 index 000000000..be5e92c11 --- /dev/null +++ b/src/exchange/test_taler_exchange_httpd_home/.config/taler/test.json @@ -0,0 +1,8 @@ +{ + "salt": "AZPRFVJ58NM6M7J5CZQPJAH3EW5DYM52AEZ9Y1C1ER3W94QV8D8TQKF6CK8MYQRA9QMSKDQTGZ306ZS9GQ0M6R01CJ20KPP49WFDZK8", + "name": "The exchange", + "account_number": 3, + "bank_uri": "http://localhost:8082/", + "type": "test", + "sig": "RPQXP9S4P8PQP7HEZQNRSZCT0ATNEP8GW0P5TPM34V5RX86FCD670V44R9NETSYDDKB8SZV7TKY9PAJYTY51D3VDWY9XXQ5BPFRXR28" +} \ No newline at end of file diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c index bde3c4442..d467b7bdd 100644 --- a/src/wire/plugin_wire_test.c +++ b/src/wire/plugin_wire_test.c @@ -35,26 +35,31 @@ struct TestClosure { /** - * Handle to the bank for sending funds to the bank. + * Which currency do we support? */ - struct TALER_BANK_Context *bank; + char *currency; /** - * Which currency do we support? + * URI of our bank. */ - char *currency; + char *bank_uri; /** - * Number of the account that the exchange has at the bank for outgoing - * transfers. + * Handle to the bank for sending funds to the bank. */ - unsigned long long exchange_account_outgoing_no; + struct TALER_BANK_Context *bank; /** * Handle to the bank task, or NULL. */ struct GNUNET_SCHEDULER_Task *bt; + /** + * Number of the account that the exchange has at the bank for + * outgoing transfers. + */ + unsigned long long exchange_account_outgoing_no; + }; @@ -216,7 +221,12 @@ test_amount_round (void *cls, uint32_t delta; if (NULL == tc->currency) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "CURRENCY"); return GNUNET_SYSERR; /* not configured with currency */ + } if (0 != strcasecmp (amount->currency, tc->currency)) { @@ -232,58 +242,6 @@ test_amount_round (void *cls, } -/** - * Obtain wire transfer details in the plugin-specific format - * from the configuration. - * - * @param cls closure - * @param cfg configuration with details about wire accounts - * @param account_name which section in the configuration should we parse - * @return NULL if @a cfg fails to have valid wire details for @a account_name - */ -static json_t * -test_get_wire_details (void *cls, - const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *account_name) -{ - json_t *ret; - char *bank_uri; - unsigned long long account_number; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - account_name, - "BANK_URI", - &bank_uri)) - { - /* oopsie, configuration error */ - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - account_name, - "BANK_URI"); - return NULL; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, - account_name, - "BANK_ACCOUNT_NUMBER", - &account_number)) - { - /* oopsie, configuration error */ - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - account_name, - "BANK_ACCOUNT_NUMBER"); - GNUNET_free (bank_uri); - return NULL; - } - ret = json_pack ("{s:s, s:I, s:s}", - "type", "test", - "account_number", (json_int_t) account_number, - "bank_uri", bank_uri); - GNUNET_free (bank_uri); - return ret; -} - - /** * Compute purpose for signing. * @@ -331,17 +289,23 @@ test_wire_validate (void *cls, const json_t *wire, const struct TALER_MasterPublicKeyP *master_pub) { + struct TestClosure *tc = cls; json_error_t error; json_int_t account_no; + const char *bank_uri; + const char *sig_s; + struct TALER_MasterWireDetailsPS wsd; + struct TALER_MasterSignatureP sig; if (0 != json_unpack_ex ((json_t *) wire, &error, 0, - "{s:I}", - "account_number", &account_no)) + "{s:I, s:s}", + "account_number", &account_no, + "bank_uri", &bank_uri)) { - GNUNET_break (0); + GNUNET_break_op (0); return GNUNET_SYSERR; } if ( (account_no < 0) || @@ -350,14 +314,119 @@ test_wire_validate (void *cls, GNUNET_break (0); return GNUNET_SYSERR; } - /* FIXME: should check signature here in the future! - (note: right now the sig is not properly provided - by the exchange due to the way account data is - specified in the configuration) */ + if ( (NULL != tc->bank_uri) && + (0 != strcmp (bank_uri, + tc->bank_uri)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wire specifies bank URI %s, but this exchange only supports %s\n", + bank_uri, + tc->bank_uri); + return GNUNET_NO; + } + if (NULL == master_pub) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Skipping signature check as master public key not given\n"); + return GNUNET_OK; + } + if (0 != + json_unpack_ex ((json_t *) wire, + &error, + 0, + "{s:s}", + "sig", &sig_s)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Signature check required, but signature is missing\n"); + return GNUNET_NO; + } + compute_purpose (account_no, + bank_uri, + &wsd); + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (sig_s, + strlen (sig_s), + &sig, + sizeof (sig))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_TEST_DETAILS, + &wsd.purpose, + &sig.eddsa_signature, + &master_pub->eddsa_pub)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } return GNUNET_YES; } +/** + * Obtain wire transfer details in the plugin-specific format + * from the configuration. + * + * @param cls closure + * @param cfg configuration with details about wire accounts + * @param account_name which section in the configuration should we parse + * @return NULL if @a cfg fails to have valid wire details for @a account_name + */ +static json_t * +test_get_wire_details (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *account_name) +{ + struct TestClosure *tc = cls; + char *test_wire_file; + json_error_t err; + json_t *ret; + + /* Fetch reply */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + account_name, + "TEST_RESPONSE_FILE", + &test_wire_file)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + account_name, + "TEST_RESPONSE_FILE"); + return NULL; + } + ret = json_load_file (test_wire_file, + JSON_REJECT_DUPLICATES, + &err); + if (NULL == ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse JSON in %s: %s (%s:%u)\n", + test_wire_file, + err.text, + err.source, + err.line); + GNUNET_free (test_wire_file); + return NULL; + } + if (GNUNET_YES != test_wire_validate (tc, + ret, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to validate TEST wire data in %s\n", + test_wire_file); + GNUNET_free (test_wire_file); + json_decref (ret); + return NULL; + } + GNUNET_free (test_wire_file); + return ret; +} + + GNUNET_NETWORK_STRUCT_BEGIN /** * Format we used for serialized transaction data. @@ -460,11 +529,11 @@ test_prepare_wire_transfer (void *cls, struct TALER_WIRE_PrepareHandle *pth; if (GNUNET_YES != - test_wire_validate (cls, + test_wire_validate (tc, wire, NULL)) { - GNUNET_break (0); + GNUNET_break_op (0); return NULL; } pth = GNUNET_new (struct TALER_WIRE_PrepareHandle); @@ -624,7 +693,11 @@ test_execute_wire_transfer (void *cls, struct BufFormatP bf; if (NULL == tc->bank) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Bank not initialized, cannot do transfers!\n"); return NULL; /* not initialized with configuration, cannot do transfers */ + } if ( (buf_size <= sizeof (struct BufFormatP)) || ('\0' != buf[buf_size -1]) ) { @@ -645,7 +718,7 @@ test_execute_wire_transfer (void *cls, return NULL; } GNUNET_assert (GNUNET_YES == - test_wire_validate (NULL, + test_wire_validate (tc, wire, NULL)); if (0 != @@ -714,7 +787,6 @@ libtaler_plugin_wire_test_init (void *cls) struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TestClosure *tc; struct TALER_WIRE_Plugin *plugin; - char *uri; tc = GNUNET_new (struct TestClosure); if (NULL != cfg) @@ -723,7 +795,7 @@ libtaler_plugin_wire_test_init (void *cls) GNUNET_CONFIGURATION_get_value_string (cfg, "wire-outgoing-test", "BANK_URI", - &uri)) + &tc->bank_uri)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "wire-outgoing-test", @@ -734,13 +806,13 @@ libtaler_plugin_wire_test_init (void *cls) if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "wire-outgoing-test", - "BANK_ACCOUNT_NUMBER", + "EXCHANGE_ACCOUNT_NUMBER", &tc->exchange_account_outgoing_no)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "wire-incoming-test", - "BANK_ACCOUNT_NUMBER"); - GNUNET_free (uri); + "wire-outgoing-test", + "EXCHANGE_ACCOUNT_NUMBER"); + GNUNET_free (tc->bank_uri); GNUNET_free (tc); return NULL; } @@ -753,16 +825,16 @@ libtaler_plugin_wire_test_init (void *cls) GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "exchange", "CURRENCY"); - GNUNET_free (uri); + GNUNET_free (tc->bank_uri); GNUNET_free (tc); return NULL; } - tc->bank = TALER_BANK_init (uri); - GNUNET_free (uri); + tc->bank = TALER_BANK_init (tc->bank_uri); if (NULL == tc->bank) { GNUNET_break (0); GNUNET_free (tc->currency); + GNUNET_free (tc->bank_uri); GNUNET_free (tc); return NULL; } @@ -804,6 +876,7 @@ libtaler_plugin_wire_test_done (void *cls) tc->bank = NULL; } GNUNET_free_non_null (tc->currency); + GNUNET_free_non_null (tc->bank_uri); GNUNET_free (tc); GNUNET_free (plugin); return NULL; diff --git a/src/wire/wire-sepa.conf b/src/wire/wire-sepa.conf index 0ee17db30..7321a2be6 100644 --- a/src/wire/wire-sepa.conf +++ b/src/wire/wire-sepa.conf @@ -1,7 +1,10 @@ # Configuration for SEPA wire plugin. [wire-incoming-sepa] +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json -[wire-incoming-sepa] -SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json +[wire-outgoing-sepa] +# This section should contain the options required for making outgoing +# SEPA transfers. Not yet supported (need libebics). diff --git a/src/wire/wire-test.conf b/src/wire/wire-test.conf index f2a71e2e4..98e486acb 100644 --- a/src/wire/wire-test.conf +++ b/src/wire/wire-test.conf @@ -1,14 +1,16 @@ +# This file is in the public domain. +# [wire-incoming-test] -# What is the main website of the bank? -# BANK_URI = "http://localhost:8082/" -# Into which account at the 'bank' should incoming -# wire transfers be made? -# BANK_ACCOUNT_NUMBER = 2 +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. +TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json [wire-outgoing-test] -# What is the main website of the bank? -# BANK_URI = "http://localhost:8082/" +# For outgoing transfers, we need to know the exchange's +# account number at the bank. +EXCHANGE_ACCOUNT_NUMBER = 2 -# From which account at the 'bank' should outgoing -# wire transfers be made? -# BANK_ACCOUNT_NUMBER = 3 +# For transfers made by the exchange, we need to know +# the URI of the bank (where the /admin/add/incoming API +# is avaialble). +# BANK_URI = https://bank.demo.taler.net/ -- cgit v1.2.3 From 58373f2a92536be08db1fc7e9c4dc872e382c2c4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 11 Apr 2016 13:16:12 +0200 Subject: adding new test, still failing --- src/wire/Makefile.am | 15 ++++++- src/wire/test_wire_plugin.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/wire/test_wire_plugin.c (limited to 'src/wire') diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index 0ed5f7be9..107ceb379 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -76,10 +76,12 @@ libtalerwire_la_LDFLAGS = \ AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; TESTS = \ - test_sepa_wireformat + test_sepa_wireformat \ + test_wire_plugin check_PROGRAMS= \ - test_sepa_wireformat + test_sepa_wireformat \ + test_wire_plugin @@ -90,3 +92,12 @@ test_sepa_wireformat_LDADD = \ -ljansson \ libtalerwire.la \ $(top_builddir)/src/util/libtalerutil.la + + +test_wire_plugin_SOURCES = \ + test_wire_plugin.c +test_wire_plugin_LDADD = \ + -lgnunetutil \ + -ljansson \ + libtalerwire.la \ + $(top_builddir)/src/util/libtalerutil.la diff --git a/src/wire/test_wire_plugin.c b/src/wire/test_wire_plugin.c new file mode 100644 index 000000000..9f61b21fe --- /dev/null +++ b/src/wire/test_wire_plugin.c @@ -0,0 +1,106 @@ +/* + This file is part of TALER + (C) 2015, 2016 GNUnet e.V. and Inria + + 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, If not, see +*/ +/** + * @file wire/test_wire_plugin.c + * @brief Tests for wire plugins + * @author Christian Grothoff + * @author Sree Harsha Totakura + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_wire_lib.h" +#include "taler_wire_plugin.h" + + +/** + * Definitions for a test with a plugin. + */ +struct TestBlock { + + /** + * Name of the plugin to test. + */ + const char *plugin_name; + + /** + * JSON template expected by the plugin for an account definition. + */ + const char *json_proto; + +}; + + +/** + * List of plugins and (unsigned) JSON account definitions + * to use for the tests. + */ +static struct TestBlock tests[] = { + { "sepa", "{ \"iban\":3 }" }, + { "test", "{ \"bank_uri\":3 }" }, + { NULL, NULL } +}; + + +int +main (int argc, + const char *const argv[]) +{ + json_t *wire; + json_error_t error; + int ret; + struct GNUNET_CONFIGURATION_Handle *cfg; + struct TALER_WIRE_Plugin *plugin; + const struct TestBlock *test; + unsigned int i; + + GNUNET_log_setup ("test-wire-plugin", + "WARNING", + NULL); + cfg = GNUNET_CONFIGURATION_create (); + GNUNET_CONFIGURATION_set_value_string (cfg, + "exchange", + "currency", + "EUR"); + ret = GNUNET_OK; + for (i=0;NULL != (test = &tests[i])->plugin_name;i++) + { + plugin = TALER_WIRE_plugin_load (cfg, + test->plugin_name); + GNUNET_assert (NULL != plugin); + wire = json_loads (test->json_proto, 0, NULL); + GNUNET_assert (NULL != wire); + // FIXME: do test... + json_decref (wire); + TALER_WIRE_plugin_unload (plugin); + if (GNUNET_OK != ret) + { + fprintf (stdout, + "%s FAILED\n", + test->plugin_name); + break; + } + else + { + fprintf (stdout, + "%s PASS\n", + test->plugin_name); + } + } + GNUNET_CONFIGURATION_destroy (cfg); + if (GNUNET_NO == ret) + return 1; + return 0; +} -- cgit v1.2.3 From a7f2496795a80dca6fbbfb5a20f0ee4b7a72650e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 11 Apr 2016 15:59:24 +0200 Subject: adding wire plugin tests, resolving #4357 --- .gitignore | 1 + src/wire/Makefile.am | 4 +- src/wire/plugin_wire_sepa.c | 3 + src/wire/test_wire_plugin.c | 108 +++++++++++++++++++++++++++++++++--- src/wire/test_wire_plugin.conf | 21 +++++++ src/wire/test_wire_plugin_key.priv | 1 + src/wire/test_wire_plugin_sepa.json | 8 +++ src/wire/test_wire_plugin_test.json | 7 +++ 8 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 src/wire/test_wire_plugin.conf create mode 100644 src/wire/test_wire_plugin_key.priv create mode 100644 src/wire/test_wire_plugin_sepa.json create mode 100644 src/wire/test_wire_plugin_test.json (limited to 'src/wire') diff --git a/.gitignore b/.gitignore index fc31e919e..20d4b52c2 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ src/exchange-tools/taler-exchange-wire src/exchangedb/perf-exchangedb src/json/test_json src/wire/test_sepa_wireformat +src/wire/test_wire_plugin src/pq/test_pq src/util/test_amount src/util/test_crypto diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index 107ceb379..debb27828 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -15,7 +15,8 @@ pkgcfg_DATA = \ EXTRA_DIST = \ wire-sepa.conf \ - wire-test.conf + wire-test.conf \ + test_wire_plugin.conf plugindir = $(libdir)/taler @@ -97,6 +98,7 @@ test_sepa_wireformat_LDADD = \ test_wire_plugin_SOURCES = \ test_wire_plugin.c test_wire_plugin_LDADD = \ + -lgnunetjson \ -lgnunetutil \ -ljansson \ libtalerwire.la \ diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c index e0a3426c2..6f01167d9 100644 --- a/src/wire/plugin_wire_sepa.c +++ b/src/wire/plugin_wire_sepa.c @@ -539,6 +539,9 @@ sepa_get_wire_details (void *cls, "SEPA_RESPONSE_FILE", &sepa_wire_file)) { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + account_name, + "SEPA_RESPONSE_FILE"); return NULL; } ret = json_load_file (sepa_wire_file, diff --git a/src/wire/test_wire_plugin.c b/src/wire/test_wire_plugin.c index 9f61b21fe..27b4366c1 100644 --- a/src/wire/test_wire_plugin.c +++ b/src/wire/test_wire_plugin.c @@ -23,6 +23,8 @@ #include "taler_util.h" #include "taler_wire_lib.h" #include "taler_wire_plugin.h" +#include +#include /** @@ -48,32 +50,120 @@ struct TestBlock { * to use for the tests. */ static struct TestBlock tests[] = { - { "sepa", "{ \"iban\":3 }" }, - { "test", "{ \"bank_uri\":3 }" }, + { "sepa", "{ \"type\":\"sepa\", \"iban\":\"DE67830654080004822650\", \"name\":\"GNUnet e.V.\", \"bic\":\"GENODEF1SLR\" }" }, + { "test", "{ \"type\":\"test\", \"bank_uri\":\"http://localhost/\", \"account_number\":42 }" }, { NULL, NULL } }; +/** + * Private key used to sign wire details. + */ +static struct TALER_MasterPrivateKeyP priv_key; + +/** + * Public key matching #priv_key. + */ +static struct TALER_MasterPublicKeyP pub_key; + +/** + * Our configuration. + */ +static struct GNUNET_CONFIGURATION_Handle *cfg; + + +/** + * Run the test. + * + * @param name of the test + * @param plugin plugin to test + * @param wire wire details for testing + * @return #GNUNET_OK on success + */ +static int +run_test (const char *name, + struct TALER_WIRE_Plugin *plugin, + json_t *wire) +{ + struct GNUNET_HashCode salt; + struct TALER_MasterSignatureP sig; + json_t *lwire; + + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &salt, + sizeof (salt)); + if (GNUNET_OK != + plugin->sign_wire_details (plugin->cls, + wire, + &priv_key, + &salt, + &sig)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + json_object_set_new (wire, + "salt", + GNUNET_JSON_from_data (&salt, + sizeof (salt))); + json_object_set_new (wire, + "sig", + GNUNET_JSON_from_data (&sig, + sizeof (sig))); + if (GNUNET_OK != + plugin->wire_validate (plugin->cls, + wire, + &pub_key)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + /* load wire details from file */ + lwire = plugin->get_wire_details (plugin->cls, + cfg, + name); + if (NULL == lwire) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + plugin->wire_validate (plugin->cls, + lwire, + &pub_key)) + { + GNUNET_break (0); + json_decref (lwire); + return GNUNET_SYSERR; + } + json_decref (lwire); + return GNUNET_OK; +} + + int main (int argc, const char *const argv[]) { json_t *wire; - json_error_t error; int ret; - struct GNUNET_CONFIGURATION_Handle *cfg; struct TALER_WIRE_Plugin *plugin; const struct TestBlock *test; unsigned int i; + struct GNUNET_CRYPTO_EddsaPrivateKey *pk; GNUNET_log_setup ("test-wire-plugin", "WARNING", NULL); cfg = GNUNET_CONFIGURATION_create (); - GNUNET_CONFIGURATION_set_value_string (cfg, - "exchange", - "currency", - "EUR"); + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_load (cfg, + "test_wire_plugin.conf")); + pk = GNUNET_CRYPTO_eddsa_key_create_from_file ("test_wire_plugin_key.priv"); + priv_key.eddsa_priv = *pk; + GNUNET_free (pk); + GNUNET_CRYPTO_eddsa_key_get_public (&priv_key.eddsa_priv, + &pub_key.eddsa_pub); ret = GNUNET_OK; for (i=0;NULL != (test = &tests[i])->plugin_name;i++) { @@ -82,7 +172,7 @@ main (int argc, GNUNET_assert (NULL != plugin); wire = json_loads (test->json_proto, 0, NULL); GNUNET_assert (NULL != wire); - // FIXME: do test... + ret = run_test (test->plugin_name, plugin, wire); json_decref (wire); TALER_WIRE_plugin_unload (plugin); if (GNUNET_OK != ret) diff --git a/src/wire/test_wire_plugin.conf b/src/wire/test_wire_plugin.conf new file mode 100644 index 000000000..ece816954 --- /dev/null +++ b/src/wire/test_wire_plugin.conf @@ -0,0 +1,21 @@ +# This file is in the public domain. +# +[test] +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. +TEST_RESPONSE_FILE = test_wire_plugin_test.json + +[sepa] +# This is the response we give out for the /wire request. It provides +# wallets with the bank information for transfers to the exchange. +SEPA_RESPONSE_FILE = test_wire_plugin_sepa.json + + +[wire-outgoing-test] +# For transfers made by the exchange, we need to know +# the URI of the bank (where the /admin/add/incoming API +# is avaialble). +BANK_URI = http://localhost/ + +[exchange] +CURRENCY = "EUR" diff --git a/src/wire/test_wire_plugin_key.priv b/src/wire/test_wire_plugin_key.priv new file mode 100644 index 000000000..26b4f26f6 --- /dev/null +++ b/src/wire/test_wire_plugin_key.priv @@ -0,0 +1 @@ +?Sgb@Js; %aKȉs_Hў \ No newline at end of file diff --git a/src/wire/test_wire_plugin_sepa.json b/src/wire/test_wire_plugin_sepa.json new file mode 100644 index 000000000..175345f0c --- /dev/null +++ b/src/wire/test_wire_plugin_sepa.json @@ -0,0 +1,8 @@ +{ + "salt": "32V01R7K4T02S74PZZMVXRQ1K7FR948RBNB9BJ5Z101HEQFH7CW7J82006GY3BPTGQ4FM775PSSRD3K9MY97HSNVVCGEVBPVSAQ2710", + "type": "sepa", + "iban": "DE67830654080004822650", + "sig": "K48GPPM715ZXX0DC597WESD5ECT3R0B3TAFQMB68SBF4K5CZ5KCE9NESN1JX412SPZ82PSV7JAPVJFXDDTZ63YV4295S5RC28E4221G", + "name": "GNUnet e.V.", + "bic": "GENODEF1SLR" +} \ No newline at end of file diff --git a/src/wire/test_wire_plugin_test.json b/src/wire/test_wire_plugin_test.json new file mode 100644 index 000000000..6fe6b2359 --- /dev/null +++ b/src/wire/test_wire_plugin_test.json @@ -0,0 +1,7 @@ +{ + "type": "test", + "bank_uri": "http://localhost/", + "sig": "KX1CMHNFH1WE10244AEF07AXHJCF9PZDZVNZBC9P4EJEQ1MH1Y3C2TWF08VTQMK4N5TCV0V1VTGWSV0WB8TB9YQRZW87F5A6KCEZ81R", + "account_number": 42, + "salt": "EZV905MQPVAZEMGC6SEZQF2Z75P6ZKTN8TX00JHN11S7J81DQ78G8Z551K6TGR9WHPP0JW1X9J9X9CVRY48JTHBCP6Q4XKJ6R2G18G0" +} \ No newline at end of file -- cgit v1.2.3