From 4d6ef1da29e5c1bf4c2216d9fe0c14dcab0f04cd Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 13 Jan 2020 18:16:01 +0100 Subject: eliminate libtalerwire --- src/Makefile.am | 2 +- src/auditor/Makefile.am | 2 +- src/auditor/taler-auditor.c | 6 +- src/auditor/taler-wire-auditor.c | 4 +- src/bank-lib/Makefile.am | 1 + src/bank-lib/bank_api_parse.c | 4 +- src/bank-lib/bank_api_payto.c | 509 ++++++++++++++++++++++++ src/benchmark/taler-exchange-benchmark.c | 2 +- src/exchange/taler-exchange-aggregator.c | 12 +- src/exchange/taler-exchange-httpd_validation.c | 2 +- src/exchange/taler-exchange-wirewatch.c | 2 +- src/exchangedb/plugin_exchangedb_postgres.c | 2 +- src/include/Makefile.am | 1 - src/include/taler_amount_lib.h | 12 + src/include/taler_bank_service.h | 100 +++++ src/include/taler_crypto_lib.h | 8 +- src/include/taler_util.h | 10 + src/include/taler_wire_lib.h | 124 +----- src/json/Makefile.am | 1 - src/json/json_wire.c | 2 +- src/lib/Makefile.am | 1 - src/lib/exchange_api_wire.c | 2 +- src/lib/testing_api_cmd_wire.c | 2 +- src/lib/testing_api_helpers_bank.c | 33 +- src/lib/testing_api_helpers_exchange.c | 4 +- src/util/amount.c | 21 + src/util/util.c | 32 ++ src/wire/.gitignore | 3 - src/wire/Makefile.am | 22 -- src/wire/payto.c | 510 ------------------------- src/wire/wire_helper.c | 83 ---- 31 files changed, 738 insertions(+), 781 deletions(-) create mode 100644 src/bank-lib/bank_api_payto.c delete mode 100644 src/wire/.gitignore delete mode 100644 src/wire/Makefile.am delete mode 100644 src/wire/payto.c delete mode 100644 src/wire/wire_helper.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index cc749e275..0e1698d00 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,7 @@ pkgcfg_DATA = \ EXTRA_DIST = \ taler.conf -SUBDIRS = include util wire json curl $(PQ_DIR) mhd $(BANK_LIB) exchangedb exchange exchange-tools auditordb auditor +SUBDIRS = include util json curl $(PQ_DIR) mhd $(BANK_LIB) exchangedb exchange exchange-tools auditordb auditor if HAVE_LIBCURL SUBDIRS += lib benchmark else diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am index d5d7669bc..b2219e357 100644 --- a/src/auditor/Makefile.am +++ b/src/auditor/Makefile.am @@ -40,7 +40,7 @@ taler_auditor_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/json/libtalerjson.la \ - $(top_builddir)/src/wire/libtalerwire.la \ + $(top_builddir)/src/bank-lib/libtalerbank.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \ $(top_builddir)/src/auditordb/libtalerauditordb.la \ -ljansson \ diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index bb769fd6c..76285d554 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -41,7 +41,7 @@ #include "taler_auditordb_plugin.h" #include "taler_exchangedb_plugin.h" #include "taler_json_lib.h" -#include "taler_wire_lib.h" +#include "taler_bank_service.h" #include "taler_signatures.h" @@ -1459,7 +1459,7 @@ get_closing_fee (const char *receiver_account, struct TALER_Amount wire_fee; char *method; - method = TALER_WIRE_payto_get_method (receiver_account); + method = TALER_payto_get_method (receiver_account); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Method is `%s'\n", method); @@ -2894,7 +2894,7 @@ check_wire_out_cb } /* Round down to amount supported by wire method */ - GNUNET_break (TALER_WIRE_amount_round (&final_amount)); + GNUNET_break (TALER_amount_round (&final_amount)); /* Calculate the exchange's gain as the fees plus rounding differences! */ if (GNUNET_OK != diff --git a/src/auditor/taler-wire-auditor.c b/src/auditor/taler-wire-auditor.c index bd9617466..4c1d6ac3b 100644 --- a/src/auditor/taler-wire-auditor.c +++ b/src/auditor/taler-wire-auditor.c @@ -652,7 +652,7 @@ do_shutdown (void *cls) wa_tail, wa); TALER_BANK_auth_free (&wa->auth); - TALER_WIRE_account_free (&wa->account); + TALER_BANK_account_free (&wa->account); GNUNET_free (wa->section_name); GNUNET_free (wa); } @@ -2082,7 +2082,7 @@ process_account_cb (void *cls, if (TALER_PAC_X_TALER_BANK != wa->account.type) { GNUNET_break (0); - TALER_WIRE_account_free (&wa->account); + TALER_BANK_account_free (&wa->account); TALER_BANK_auth_free (&wa->auth); GNUNET_free (wa->section_name); GNUNET_free (wa); diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am index 35af78262..a428f5ffd 100644 --- a/src/bank-lib/Makefile.am +++ b/src/bank-lib/Makefile.am @@ -41,6 +41,7 @@ libtalerbank_la_SOURCES = \ bank_api_credit.c \ bank_api_debit.c \ bank_api_transfer.c \ + bank_api_payto.c \ bank_api_parse.c libtalerbank_la_LIBADD = \ $(top_builddir)/src/json/libtalerjson.la \ diff --git a/src/bank-lib/bank_api_parse.c b/src/bank-lib/bank_api_parse.c index 86288802d..1d6b2efbc 100644 --- a/src/bank-lib/bank_api_parse.c +++ b/src/bank-lib/bank_api_parse.c @@ -50,7 +50,7 @@ TALER_BANK_account_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_SYSERR; } if (TALER_EC_NONE != - TALER_WIRE_payto_to_account (account_url, + TALER_BANK_payto_to_account (account_url, acc)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, @@ -67,7 +67,7 @@ TALER_BANK_account_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, "URL", "Malformed payto:// URL for x-taler-bank method"); GNUNET_free (account_url); - TALER_WIRE_account_free (acc); + TALER_BANK_account_free (acc); return GNUNET_SYSERR; } GNUNET_free (account_url); diff --git a/src/bank-lib/bank_api_payto.c b/src/bank-lib/bank_api_payto.c new file mode 100644 index 000000000..5f87eb796 --- /dev/null +++ b/src/bank-lib/bank_api_payto.c @@ -0,0 +1,509 @@ +/* + This file is part of TALER + (C) 2015--2020 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see +*/ +/** + * @file bank-lib/bank_api_payto.c + * @brief Functions for parsing payto:// URIs + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_util.h" +#include "taler_bank_service.h" + +/** + * Maximum legal 'value' for an account number, based on IEEE double (for JavaScript compatibility). + */ +#define MAX_ACCOUNT_NO (1LLU << 52) + + +/** + * Release memory allocated in @a acc. + * + * @param acc account to free, the pointer itself is NOT free'd. + */ +void +TALER_BANK_account_free (struct TALER_Account *acc) +{ + switch (acc->type) + { + case TALER_PAC_NONE: + return; + case TALER_PAC_X_TALER_BANK: + GNUNET_free (acc->details.x_taler_bank.hostname); + acc->details.x_taler_bank.hostname = NULL; + GNUNET_free (acc->details.x_taler_bank.account_base_url); + acc->details.x_taler_bank.account_base_url = NULL; + break; + case TALER_PAC_IBAN: + GNUNET_free (acc->details.iban.number); + acc->details.iban.number = NULL; + break; + } + acc->type = TALER_PAC_NONE; +} + + +/* Taken from GNU gettext */ + +/** + * Entry in the country table. + */ +struct CountryTableEntry +{ + /** + * 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 CountryTableEntry 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 CountryTableEntry *cc1 = ptr1; + const struct CountryTableEntry *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 CountryTableEntry cc_entry; + unsigned int len; + char *nbuf; + unsigned long long dividend; + unsigned long long remainder; + int nread; + int ret; + unsigned int i; + unsigned int j; + + len = strlen (iban); + if (len > 34) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "IBAN number too long to be valid\n"); + 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 CountryTableEntry), + sizeof (struct CountryTableEntry), + &cmp_country_code)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Country code `%c%c' not supported\n", + cc[0], + cc[1]); + return GNUNET_NO; + } + nbuf = GNUNET_malloc ((len * 2) + 1); + for (i = 0, j = 0; i < len; i++) + { + if (isalpha ((unsigned char) ibancpy[i])) + { + if (2 != snprintf (&nbuf[j], + 3, + "%2u", + (ibancpy[i] - 'A' + 10))) + { + GNUNET_free (nbuf); + return GNUNET_NO; + } + j += 2; + continue; + } + nbuf[j] = ibancpy[i]; + j++; + } + for (j = 0; '\0' != nbuf[j]; j++) + GNUNET_assert (isdigit ( (unsigned char) nbuf[j])); + GNUNET_assert (sizeof(dividend) >= 8); + remainder = 0; + for (unsigned int i = 0; itype = TALER_PAC_IBAN; + account->details.iban.number = result; + } + else + { + GNUNET_free (result); + } + return TALER_EC_NONE; +} + + +/** + * Parse payto://x-taler-bank/ account URL (only account information, + * wire subject and amount are ignored). + * + * @param account_url URL to parse + * @param account[out] set to information, can be NULL + * @return #TALER_EC_NONE if @a account_url is well-formed + */ +static enum TALER_ErrorCode +parse_payto_x_taler_bank (const char *account_url, + struct TALER_Account *r_account) +{ + const char *hostname; + const char *account; + const char *q; + unsigned int port; + char *p; + +#define PREFIX "payto://x-taler-bank/" + if (0 != strncasecmp (account_url, + PREFIX, + strlen (PREFIX))) + return TALER_EC_PAYTO_WRONG_METHOD; + hostname = &account_url[strlen (PREFIX)]; + if (NULL == (account = strchr (hostname, + (unsigned char) '/'))) + return TALER_EC_PAYTO_MALFORMED; + account++; + if (NULL == r_account) + return TALER_EC_NONE; + q = strchr (account, + (unsigned char) '?'); + if (0 == q) + q = account + strlen (account); + r_account->details.x_taler_bank.hostname + = GNUNET_strndup (hostname, + account - hostname); + port = 443; /* if non given, equals 443. */ + if (NULL != (p = strchr (r_account->details.x_taler_bank.hostname, + (unsigned char) ':'))) + { + p++; + if (1 != sscanf (p, + "%u", + &port)) + { + GNUNET_break (0); + TALER_LOG_ERROR ("Malformed host from payto:// URI\n"); + GNUNET_free (r_account->details.x_taler_bank.hostname); + r_account->details.x_taler_bank.hostname = NULL; + return TALER_EC_PAYTO_MALFORMED; + } + } + if (443 != port) + { + GNUNET_assert + (GNUNET_SYSERR != GNUNET_asprintf + (&r_account->details.x_taler_bank.account_base_url, + "http://%s/%.*s", + r_account->details.x_taler_bank.hostname, + (int) (q - account), + account)); + } + else + { + GNUNET_assert + (GNUNET_SYSERR != GNUNET_asprintf + (&r_account->details.x_taler_bank.account_base_url, + "https://%s/%.*s", + r_account->details.x_taler_bank.hostname, + (int) (q - account), + account)); + } + r_account->type = TALER_PAC_X_TALER_BANK; + return TALER_EC_NONE; +} + + +typedef enum TALER_ErrorCode +(*Parser)(const char *account_url, + struct TALER_Account *r_account); + +/** + * Parse @a payto_url and store the result in @a acc + * + * @param payto_url URL to parse + * @param acc[in,out] account to initialize, free using #TALER_BANK_account_free() later + * @return #TALER_EC_NONE if @a payto_url is well-formed + */ +enum TALER_ErrorCode +TALER_BANK_payto_to_account (const char *payto_url, + struct TALER_Account *acc) +{ + Parser parsers[] = { + &parse_payto_x_taler_bank, + &parse_payto_iban, + NULL + }; + + for (unsigned int i = 0; NULL != parsers[i]; i++) + { + enum TALER_ErrorCode ec = parsers[i](payto_url, + acc); + if (TALER_EC_PAYTO_WRONG_METHOD == ec) + continue; + return ec; + } + return TALER_EC_PAYTO_WRONG_METHOD; +} + + +/* end of payto.c */ diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index cc350942a..ca3b1a767 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -858,7 +858,7 @@ main (int argc, } if (TALER_EC_NONE != - TALER_WIRE_payto_to_account (exchange_payto_url, + TALER_BANK_payto_to_account (exchange_payto_url, &exchange_bank_account)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 2704f5910..161d35b2f 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -172,7 +172,7 @@ struct AggregationUnit /** * Wire preparation handle. */ - struct TALER_WIRE_PrepareHandle *ph; + struct TALER_BANK_PrepareHandle *ph; /** * Array of #aggregation_limit row_ids from the @@ -416,7 +416,7 @@ find_account_by_url (const char *url) char *method; struct WireAccount *wa; - method = TALER_WIRE_payto_get_method (url); + method = TALER_payto_get_method (url); if (NULL == method) { fprintf (stderr, @@ -573,7 +573,7 @@ shutdown_task (void *cls) GNUNET_CONTAINER_DLL_remove (wa_head, wa_tail, wa); - TALER_WIRE_account_free (&wa->account); + TALER_BANK_account_free (&wa->account); TALER_BANK_auth_free (&wa->auth); TALER_EXCHANGEDB_fees_free (wa->af); GNUNET_free (wa->section_name); @@ -1117,7 +1117,7 @@ expired_reserve_cb (void *cls, } /* round down to enable transfer */ if (GNUNET_SYSERR == - TALER_WIRE_amount_round (&amount_without_fee)) + TALER_amount_round (&amount_without_fee)) { GNUNET_break (0); global_ret = GNUNET_SYSERR; @@ -1182,7 +1182,7 @@ expired_reserve_cb (void *cls, ctc = GNUNET_new (struct CloseTransferContext); ctc->wa = wa; ctc->session = session; - ctc->method = TALER_WIRE_payto_get_method (account_details); + ctc->method = TALER_payto_get_method (account_details); TALER_BANK_prepare_wire_transfer (account_details, &amount_without_fee, exchange_base_url, @@ -1449,7 +1449,7 @@ run_aggregation (void *cls) &au->total_amount, &au->wire_fee)) || (GNUNET_SYSERR == - TALER_WIRE_amount_round (&au->final_amount)) || + TALER_amount_round (&au->final_amount)) || ( (0 == au->final_amount.value) && (0 == au->final_amount.fraction) ) ) { diff --git a/src/exchange/taler-exchange-httpd_validation.c b/src/exchange/taler-exchange-httpd_validation.c index d0371e930..f9bfb0a07 100644 --- a/src/exchange/taler-exchange-httpd_validation.c +++ b/src/exchange/taler-exchange-httpd_validation.c @@ -146,7 +146,7 @@ load_account (void *cls, *ret = GNUNET_SYSERR; return; } - method = TALER_WIRE_payto_get_method (ai->payto_url); + method = TALER_payto_get_method (ai->payto_url); if (GNUNET_OK == load_fee (method)) { diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c index 091f4ba20..5720a6d0b 100644 --- a/src/exchange/taler-exchange-wirewatch.c +++ b/src/exchange/taler-exchange-wirewatch.c @@ -213,7 +213,7 @@ shutdown_task (void *cls) GNUNET_CONTAINER_DLL_remove (wa_head, wa_tail, wa); - TALER_WIRE_account_free (&wa->account); + TALER_BANK_account_free (&wa->account); TALER_BANK_auth_free (&wa->auth); GNUNET_free (wa->section_name); GNUNET_free (wa); diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 5f2c67161..e4caec2d5 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -422,7 +422,7 @@ postgres_create_tables (void *cls) "(wireout_uuid BIGSERIAL PRIMARY KEY" ",execution_date INT8 NOT NULL" ",wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=" - TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR ")" + TALER_BANK_TRANSFER_IDENTIFIER_LEN_STR ")" ",wire_target TEXT NOT NULL" ",exchange_account_section TEXT NOT NULL" ",amount_val INT8 NOT NULL" diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 39e2c3f58..b1068d5d7 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -27,7 +27,6 @@ talerinclude_HEADERS = \ taler_json_lib.h \ taler_testing_auditor_lib.h \ taler_testing_lib.h \ - taler_wire_lib.h \ taler_util.h \ taler_mhd_lib.h \ taler_pq_lib.h \ diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index ef323f83b..37f42bd99 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -309,6 +309,18 @@ const char * TALER_amount2s (const struct TALER_Amount *amount); +/** + * Round the amount to something that can be + * transferred on the wire. + * + * @param[in,out] amount amount to round down + * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, + * #GNUNET_SYSERR if the amount or currency was invalid + */ +int +TALER_amount_round (struct TALER_Amount *amount); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h index 08b29ed11..f52d095d4 100644 --- a/src/include/taler_bank_service.h +++ b/src/include/taler_bank_service.h @@ -85,6 +85,83 @@ struct TALER_BANK_AuthenticationData }; +/** + * Different account types supported by payto://. + */ +enum TALER_PaytoAccountType +{ + + /** + * Used to indicate an uninitialized struct. + */ + TALER_PAC_NONE = 0, + + /** + * Account type of a bank running the x-taler-bank protocol. + */ + TALER_PAC_X_TALER_BANK, + + /** + * Account identified by IBAN number. + */ + TALER_PAC_IBAN +}; + + +/** + * Information about an account extracted from a payto://-URL. + */ +struct TALER_Account +{ + + /** + * How this the account represented. + */ + enum TALER_PaytoAccountType type; + + /** + * Internals depending on @e type. + */ + union + { + + /** + * Taler bank address from x-taler-bank. Set if + * @e type is #TALER_AC_X_TALER_BANK. + */ + struct + { + + /** + * Bank account base URL. + */ + char *account_base_url; + + /** + * Only the hostname of the bank. + */ + char *hostname; + + } x_taler_bank; + + /** + * Taler bank address from iban. Set if + * @e type is #TALER_AC_IBAN. + */ + struct + { + + /** + * IBAN number. + */ + char *number; + + } iban; + + } details; +}; + + /* ********************* /admin/add/incoming *********************** */ @@ -447,6 +524,8 @@ void TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh); +/* ******************** Convenience functions **************** */ + /** * Convenience method for parsing configuration section with bank account data. * @@ -460,6 +539,26 @@ TALER_BANK_account_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, struct TALER_Account *acc); +/** + * Release memory allocated in @a acc. + * + * @param acc account to free, the pointer itself is NOT free'd. + */ +void +TALER_BANK_account_free (struct TALER_Account *acc); + + +/** + * Parse @a payto_url and store the result in @a acc + * + * @param payto_url URL to parse + * @param acc[in,out] account to initialize, free using #TALER_BANK_account_free() later + * @return #TALER_EC_NONE if @a payto_url is well-formed + */ +enum TALER_ErrorCode +TALER_BANK_payto_to_account (const char *payto_url, + struct TALER_Account *acc); + /** * Convenience method for parsing configuration section with bank @@ -486,4 +585,5 @@ TALER_BANK_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, void TALER_BANK_auth_free (struct TALER_BANK_AuthenticationData *auth); + #endif /* _TALER_BANK_SERVICE_H */ diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 81ea0bb95..f8dc1e665 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -510,12 +510,12 @@ struct TALER_TransferSecretP * Length of the raw value in the Taler wire transfer identifier * (in binary representation). */ -#define TALER_WIRE_TRANSFER_IDENTIFIER_LEN 32 +#define TALER_BANK_TRANSFER_IDENTIFIER_LEN 32 /** - * #TALER_WIRE_TRANSFER_IDENTIFIER_LEN as a string. + * #TALER_BANK_TRANSFER_IDENTIFIER_LEN as a string. */ -#define TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR "32" +#define TALER_BANK_TRANSFER_IDENTIFIER_LEN_STR "32" /** @@ -536,7 +536,7 @@ struct TALER_WireTransferIdentifierRawP * encode the actual value (i.e. a 256-bit / 32-byte public key or * a hash code), and the last byte for a minimalistic checksum. */ - uint8_t raw[TALER_WIRE_TRANSFER_IDENTIFIER_LEN]; + uint8_t raw[TALER_BANK_TRANSFER_IDENTIFIER_LEN]; }; diff --git a/src/include/taler_util.h b/src/include/taler_util.h index e1b42f134..105dba61a 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -381,4 +381,14 @@ TALER_url_absolute_mhd (struct MHD_Connection *connection, ...); +/** + * Obtain the payment method from a @a payto_url + * + * @param payto_url the URL to parse + * @return NULL on error (malformed @a payto_url) + */ +char * +TALER_payto_get_method (const char *payto_url); + + #endif diff --git a/src/include/taler_wire_lib.h b/src/include/taler_wire_lib.h index c7d9f78d8..02a3d91c9 100644 --- a/src/include/taler_wire_lib.h +++ b/src/include/taler_wire_lib.h @@ -18,130 +18,10 @@ * @brief Interface for loading and unloading wire plugins * @author Christian Grothoff */ -#ifndef TALER_WIRE_H -#define TALER_WIRE_H +#ifndef TALER_BANK_H +#define TALER_BANK_H #include -/** - * Different account types supported by payto://. - */ -enum TALER_PaytoAccountType -{ - - /** - * Used to indicate an uninitialized struct. - */ - TALER_PAC_NONE = 0, - - /** - * Account type of a bank running the x-taler-bank protocol. - */ - TALER_PAC_X_TALER_BANK, - - /** - * Account identified by IBAN number. - */ - TALER_PAC_IBAN -}; - - -/** - * Information about an account extracted from a payto://-URL. - */ -struct TALER_Account -{ - - /** - * How this the account represented. - */ - enum TALER_PaytoAccountType type; - - /** - * Internals depending on @e type. - */ - union - { - - /** - * Taler bank address from x-taler-bank. Set if - * @e type is #TALER_AC_X_TALER_BANK. - */ - struct - { - - /** - * Bank account base URL. - */ - char *account_base_url; - - /** - * Only the hostname of the bank. - */ - char *hostname; - - } x_taler_bank; - - /** - * Taler bank address from iban. Set if - * @e type is #TALER_AC_IBAN. - */ - struct - { - - /** - * IBAN number. - */ - char *number; - - } iban; - - } details; -}; - - -/** - * Release memory allocated in @a acc. - * - * @param acc account to free, the pointer itself is NOT free'd. - */ -void -TALER_WIRE_account_free (struct TALER_Account *acc); - - -/** - * Round the amount to something that can be - * transferred on the wire. - * - * @param[in,out] amount amount to round down - * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, - * #GNUNET_SYSERR if the amount or currency was invalid - */ -int -TALER_WIRE_amount_round (struct TALER_Amount *amount); - - -/** - * Parse @a payto_url and store the result in @a acc - * - * @param payto_url URL to parse - * @param acc[in,out] account to initialize, free using #TALER_WIRE_account_free() later - * @return #TALER_EC_NONE if @a payto_url is well-formed - */ -enum TALER_ErrorCode -TALER_WIRE_payto_to_account (const char *payto_url, - struct TALER_Account *acc); - - -/** - * Obtain the payment method from a @a payto_url - * - * @param payto_url the URL to parse - * @return NULL on error (malformed @a payto_url) - */ -char * -TALER_WIRE_payto_get_method (const char *payto_url); - - #endif diff --git a/src/json/Makefile.am b/src/json/Makefile.am index 2ac5df44b..2910d0773 100644 --- a/src/json/Makefile.am +++ b/src/json/Makefile.am @@ -18,7 +18,6 @@ libtalerjson_la_LDFLAGS = \ -export-dynamic -no-undefined libtalerjson_la_LIBADD = \ -lgnunetjson \ - $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil \ -ljansson \ diff --git a/src/json/json_wire.c b/src/json/json_wire.c index 515cd9b63..368508fcc 100644 --- a/src/json/json_wire.c +++ b/src/json/json_wire.c @@ -197,7 +197,7 @@ TALER_JSON_wire_to_method (const json_t *wire_s) "Fatally malformed wire record encountered: lacks payto://-url\n"); return NULL; } - return TALER_WIRE_payto_get_method (payto_str); + return TALER_payto_get_method (payto_str); } diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 0325df009..9b76073f0 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -133,7 +133,6 @@ libtalertesting_la_SOURCES = \ testing_api_trait_wtid.c libtalertesting_la_LIBADD = \ libtalerexchange.la \ - $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/bank-lib/libtalerbank.la \ diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c index 787797abe..aff933ba5 100644 --- a/src/lib/exchange_api_wire.c +++ b/src/lib/exchange_api_wire.c @@ -301,7 +301,7 @@ handle_wire_finished (void *cls, ec = TALER_EC_SERVER_JSON_INVALID; break; } - if (NULL == (method = TALER_WIRE_payto_get_method (wa->url))) + if (NULL == (method = TALER_payto_get_method (wa->url))) { /* bogus reply */ GNUNET_break_op (0); diff --git a/src/lib/testing_api_cmd_wire.c b/src/lib/testing_api_cmd_wire.c index 950ed62f7..387cda5dc 100644 --- a/src/lib/testing_api_cmd_wire.c +++ b/src/lib/testing_api_cmd_wire.c @@ -109,7 +109,7 @@ wire_cb (void *cls, { char *method; - method = TALER_WIRE_payto_get_method (accounts[i].url); + method = TALER_payto_get_method (accounts[i].url); if (0 == strcmp (ws->expected_method, method)) { diff --git a/src/lib/testing_api_helpers_bank.c b/src/lib/testing_api_helpers_bank.c index 52227f7b7..1f0617992 100644 --- a/src/lib/testing_api_helpers_bank.c +++ b/src/lib/testing_api_helpers_bank.c @@ -17,15 +17,17 @@ */ /** - * @file bank-lib/testing_api_helpers.c - * @brief convenience functions for bank-lib tests. + * @file lib/testing_api_helpers_bank.c + * @brief convenience functions for bank tests. * @author Marcello Stanisci + * @author Christian Grothoff */ #include "platform.h" #include #include "taler_testing_lib.h" #include "taler_fakebank_lib.h" +#define EXCHANGE_ACCOUNT_NAME "2" #define BANK_FAIL() \ do {GNUNET_break (0); return NULL; } while (0) @@ -332,14 +334,23 @@ TALER_TESTING_prepare_bank (const char *config_filename, return GNUNET_SYSERR; } GNUNET_OS_process_destroy (dbreset_proc); - + if (GNUNET_OK != + TALER_BANK_auth_parse_cfg (cfg, + "account-" EXCHANGE_ACCOUNT_NAME, + &bc->exchange_auth)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } GNUNET_asprintf (&bc->bank_url, "http://localhost:%llu/", port); - // FIXME: initialize rest of 'bc': - bc->exchange_account_url = NULL; // FIXME - bc->exchange_auth; // FIXME - bc->exchange_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "2"); + GNUNET_asprintf (&bc->exchange_account_url, + "%s%s", + bc->bank_url, + EXCHANGE_ACCOUNT_NAME); + bc->exchange_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, + EXCHANGE_ACCOUNT_NAME); bc->user42_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "42"); bc->user43_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "43"); return GNUNET_OK; @@ -412,9 +423,11 @@ TALER_TESTING_prepare_fakebank (const char *config_filename, return GNUNET_SYSERR; } bc->bank_url = fakebank_url; - // FIXME: initialize rest of 'bc': - bc->exchange_account_url = NULL; // FIXME - bc->exchange_auth; // FIXME + GNUNET_asprintf (&bc->exchange_account_url, + "%s%s", + bc->bank_url, + EXCHANGE_ACCOUNT_NAME); + bc->exchange_auth.method = TALER_BANK_AUTH_NONE; bc->exchange_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "2"); bc->user42_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "42"); bc->user43_payto = TALER_TESTING_make_xtalerbank_payto (bc->bank_url, "43"); diff --git a/src/lib/testing_api_helpers_exchange.c b/src/lib/testing_api_helpers_exchange.c index 1fed38d1b..8f7c75035 100644 --- a/src/lib/testing_api_helpers_exchange.c +++ b/src/lib/testing_api_helpers_exchange.c @@ -18,7 +18,7 @@ */ /** - * @file exchange-lib/testing_api_helpers.c + * @file lib/testing_api_helpers_exchange.c * @brief helper functions * @author Christian Grothoff * @author Marcello Stanisci @@ -958,4 +958,4 @@ TALER_TESTING_url_port_free (const char *url) } -/* end of testing_api_helpers.c */ +/* end of testing_api_helpers_exchange.c */ diff --git a/src/util/amount.c b/src/util/amount.c index 21410c769..edb9dc060 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -672,4 +672,25 @@ TALER_amount_divide (struct TALER_Amount *result, } +/** + * Round the amount to something that can be + * transferred on the wire. + * + * @param[in,out] amount amount to round down + * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, + * #GNUNET_SYSERR if the amount or currency was invalid + */ +int +TALER_amount_round (struct TALER_Amount *amount) +{ + uint32_t delta; + + delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / 100); + if (0 == delta) + return GNUNET_NO; + amount->fraction -= delta; + return GNUNET_OK; +} + + /* end of amount.c */ diff --git a/src/util/util.c b/src/util/util.c index fa65fc238..e312e345b 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -744,4 +744,36 @@ TALER_buffer_write_vfstr (struct TALER_Buffer *buf, } +/** + * Prefix of PAYTO URLs. + */ +#define PAYTO "payto://" + + +/** + * Obtain the payment method from a @a payto_url + * + * @param payto_url the URL to parse + * @return NULL on error (malformed @a payto_url) + */ +char * +TALER_payto_get_method (const char *payto_url) +{ + const char *start; + const char *end; + + if (0 != strncmp (payto_url, + PAYTO, + strlen (PAYTO))) + return NULL; + start = &payto_url[strlen (PAYTO)]; + end = strchr (start, + (unsigned char) '/'); + if (NULL == end) + return NULL; + return GNUNET_strndup (start, + end - start); +} + + /* end of util.c */ diff --git a/src/wire/.gitignore b/src/wire/.gitignore deleted file mode 100644 index be0231d74..000000000 --- a/src/wire/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -test_wire_plugin -test_wire_plugin_transactions_test -test_sepa_wireformat diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am deleted file mode 100644 index 2a82282a3..000000000 --- a/src/wire/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# 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 - -pkgcfgdir = $(prefix)/share/taler/config.d/ - -lib_LTLIBRARIES = \ - libtalerwire.la - -libtalerwire_la_SOURCES = \ - payto.c \ - wire_helper.c -libtalerwire_la_LIBADD = \ - -lgnunetutil \ - $(XLIB) -libtalerwire_la_LDFLAGS = \ - -version-info 1:0:0 \ - -export-dynamic -no-undefined diff --git a/src/wire/payto.c b/src/wire/payto.c deleted file mode 100644 index 0c3fce957..000000000 --- a/src/wire/payto.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - This file is part of TALER - (C) 2015--2019 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, see -*/ -/** - * @file wire/payto.c - * @brief Functions for parsing payto:// URIs - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_util.h" -#include "taler_bank_service.h" -#include "taler_wire_lib.h" - -/** - * Maximum legal 'value' for an account number, based on IEEE double (for JavaScript compatibility). - */ -#define MAX_ACCOUNT_NO (1LLU << 52) - - -/** - * Release memory allocated in @a acc. - * - * @param acc account to free, the pointer itself is NOT free'd. - */ -void -TALER_WIRE_account_free (struct TALER_Account *acc) -{ - switch (acc->type) - { - case TALER_PAC_NONE: - return; - case TALER_PAC_X_TALER_BANK: - GNUNET_free (acc->details.x_taler_bank.hostname); - acc->details.x_taler_bank.hostname = NULL; - GNUNET_free (acc->details.x_taler_bank.account_base_url); - acc->details.x_taler_bank.account_base_url = NULL; - break; - case TALER_PAC_IBAN: - GNUNET_free (acc->details.iban.number); - acc->details.iban.number = NULL; - break; - } - acc->type = TALER_PAC_NONE; -} - - -/* Taken from GNU gettext */ - -/** - * Entry in the country table. - */ -struct CountryTableEntry -{ - /** - * 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 CountryTableEntry 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 CountryTableEntry *cc1 = ptr1; - const struct CountryTableEntry *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 CountryTableEntry cc_entry; - unsigned int len; - char *nbuf; - unsigned long long dividend; - unsigned long long remainder; - int nread; - int ret; - unsigned int i; - unsigned int j; - - len = strlen (iban); - if (len > 34) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "IBAN number too long to be valid\n"); - 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 CountryTableEntry), - sizeof (struct CountryTableEntry), - &cmp_country_code)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Country code `%c%c' not supported\n", - cc[0], - cc[1]); - return GNUNET_NO; - } - nbuf = GNUNET_malloc ((len * 2) + 1); - for (i = 0, j = 0; i < len; i++) - { - if (isalpha ((unsigned char) ibancpy[i])) - { - if (2 != snprintf (&nbuf[j], - 3, - "%2u", - (ibancpy[i] - 'A' + 10))) - { - GNUNET_free (nbuf); - return GNUNET_NO; - } - j += 2; - continue; - } - nbuf[j] = ibancpy[i]; - j++; - } - for (j = 0; '\0' != nbuf[j]; j++) - GNUNET_assert (isdigit ( (unsigned char) nbuf[j])); - GNUNET_assert (sizeof(dividend) >= 8); - remainder = 0; - for (unsigned int i = 0; itype = TALER_PAC_IBAN; - account->details.iban.number = result; - } - else - { - GNUNET_free (result); - } - return TALER_EC_NONE; -} - - -/** - * Parse payto://x-taler-bank/ account URL (only account information, - * wire subject and amount are ignored). - * - * @param account_url URL to parse - * @param account[out] set to information, can be NULL - * @return #TALER_EC_NONE if @a account_url is well-formed - */ -static enum TALER_ErrorCode -parse_payto_x_taler_bank (const char *account_url, - struct TALER_Account *r_account) -{ - const char *hostname; - const char *account; - const char *q; - unsigned int port; - char *p; - -#define PREFIX "payto://x-taler-bank/" - if (0 != strncasecmp (account_url, - PREFIX, - strlen (PREFIX))) - return TALER_EC_PAYTO_WRONG_METHOD; - hostname = &account_url[strlen (PREFIX)]; - if (NULL == (account = strchr (hostname, - (unsigned char) '/'))) - return TALER_EC_PAYTO_MALFORMED; - account++; - if (NULL == r_account) - return TALER_EC_NONE; - q = strchr (account, - (unsigned char) '?'); - if (0 == q) - q = account + strlen (account); - r_account->details.x_taler_bank.hostname - = GNUNET_strndup (hostname, - account - hostname); - port = 443; /* if non given, equals 443. */ - if (NULL != (p = strchr (r_account->details.x_taler_bank.hostname, - (unsigned char) ':'))) - { - p++; - if (1 != sscanf (p, - "%u", - &port)) - { - GNUNET_break (0); - TALER_LOG_ERROR ("Malformed host from payto:// URI\n"); - GNUNET_free (r_account->details.x_taler_bank.hostname); - r_account->details.x_taler_bank.hostname = NULL; - return TALER_EC_PAYTO_MALFORMED; - } - } - if (443 != port) - { - GNUNET_assert - (GNUNET_SYSERR != GNUNET_asprintf - (&r_account->details.x_taler_bank.account_base_url, - "http://%s/%.*s", - r_account->details.x_taler_bank.hostname, - (int) (q - account), - account)); - } - else - { - GNUNET_assert - (GNUNET_SYSERR != GNUNET_asprintf - (&r_account->details.x_taler_bank.account_base_url, - "https://%s/%.*s", - r_account->details.x_taler_bank.hostname, - (int) (q - account), - account)); - } - r_account->type = TALER_PAC_X_TALER_BANK; - return TALER_EC_NONE; -} - - -typedef enum TALER_ErrorCode -(*Parser)(const char *account_url, - struct TALER_Account *r_account); - -/** - * Parse @a payto_url and store the result in @a acc - * - * @param payto_url URL to parse - * @param acc[in,out] account to initialize, free using #TALER_WIRE_account_free() later - * @return #TALER_EC_NONE if @a payto_url is well-formed - */ -enum TALER_ErrorCode -TALER_WIRE_payto_to_account (const char *payto_url, - struct TALER_Account *acc) -{ - Parser parsers[] = { - &parse_payto_x_taler_bank, - &parse_payto_iban, - NULL - }; - - for (unsigned int i = 0; NULL != parsers[i]; i++) - { - enum TALER_ErrorCode ec = parsers[i](payto_url, - acc); - if (TALER_EC_PAYTO_WRONG_METHOD == ec) - continue; - return ec; - } - return TALER_EC_PAYTO_WRONG_METHOD; -} - - -/* end of payto.c */ diff --git a/src/wire/wire_helper.c b/src/wire/wire_helper.c deleted file mode 100644 index 4b7f092a2..000000000 --- a/src/wire/wire_helper.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - This file is part of TALER - (C) 2018 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, see - -*/ - -/** - * @file wire/wire_helper.c - * @brief Helper functions for dealing with wire formats - - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_util.h" -#include "taler_wire_lib.h" - -/** - * Prefix of PAYTO URLs. - */ -#define PAYTO "payto://" - - -/** - * Obtain the payment method from a @a payto_url - * - * @param payto_url the URL to parse - * @return NULL on error (malformed @a payto_url) - */ -char * -TALER_WIRE_payto_get_method (const char *payto_url) -{ - const char *start; - const char *end; - - if (0 != strncmp (payto_url, - PAYTO, - strlen (PAYTO))) - return NULL; - start = &payto_url[strlen (PAYTO)]; - end = strchr (start, - (unsigned char) '/'); - if (NULL == end) - return NULL; - return GNUNET_strndup (start, - end - start); -} - - -/** - * Round the amount to something that can be - * transferred on the wire. - * - * @param[in,out] amount amount to round down - * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, - * #GNUNET_SYSERR if the amount or currency was invalid - */ -int -TALER_WIRE_amount_round (struct TALER_Amount *amount) -{ - uint32_t delta; - - delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / 100); - if (0 == delta) - return GNUNET_NO; - amount->fraction -= delta; - return GNUNET_OK; -} - - -/* end of wire_helper.c */ -- cgit v1.2.3