merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit f0e4549b6e3ecf44778d4e5154b7dceb536e0c21
parent d3d5f0ff045b34ce3745fbd18aea63605ccb2087
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date:   Thu,  7 Apr 2016 13:42:03 +0200

Merge branch 'master' of ssh://taler.net/var/git/merchant

Conflicts:
	src/tests/merchant.conf

Diffstat:
Msrc/backend/Makefile.am | 5+++++
Asrc/backend/merchant.conf | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/backend/taler-merchant-httpd.c | 170++++++++++++-------------------------------------------------------------------
Msrc/backenddb/plugin_merchantdb_postgres.c | 4++--
4 files changed, 78 insertions(+), 147 deletions(-)

diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am @@ -1,6 +1,11 @@ # This Makefile.am is in the public domain AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/backend-lib/ +pkgcfgdir = $(prefix)/share/taler/config.d/ + +pkgcfg_DATA = \ + merchant.conf + bin_PROGRAMS = \ taler-merchant-httpd diff --git a/src/backend/merchant.conf b/src/backend/merchant.conf @@ -0,0 +1,46 @@ +# This file is in the public domain. + +# These are default/sample settings for a merchant backend. + + +# General settings for the backend. +[merchant] +# Which HTTP port does the backend listen on? +PORT = 9966 + +# Where does the backend store the merchant's private key? +KEYFILE = merchant.priv + +# Which database backend do we use? +DB = postgres + +# Which wireformat does this merchant use? (test/sepa/etc.) +# WIREFORMAT = "test" +# Must match the specification given in [merchant-wireformat] + + +[exchange-taler] +# FIXME: should use URI, need https! Avoid PORT (other than as part of URI)! +# FIXME: is this used? +HOSTNAME = exchange.demo.taler.net +PORT = 80 +PUBKEY = Q1WVGRGC1F4W7RYC6M23AEGFEXQEHQ730K3GG0B67VPHQSRR75H0 + + +# Configuration for postgres database. +[merchantdb-postgres] +CONFIG = postgres:///talermerchant + + +# Configuration of our bank account details +[merchant-wireformat] +# The values in this section must match the "WIREFORMAT" given in [merchant]: +# * for SEPA: +# IBAN = DE67830654080004822650 +# NAME = GNUNET E.V +# BIC = GENODEF1SRL +# +# * for TEST: +# ACCOUNT_NUMBER = 123456 +# BANK_URI = http:// +# diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -39,7 +39,6 @@ #include "taler-merchant-httpd_util.h" - /** * Our wire format details in JSON format (with salt). */ @@ -61,11 +60,6 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *privkey; struct TALER_MerchantPublicKeyP pubkey; /** - * Our hostname - */ -static char *hostname; - -/** * The port we are running on */ static long long unsigned port; @@ -236,7 +230,8 @@ url_handler (void *cls, * @param tc scheduler task context */ static void -do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { if (NULL != mhd_task) { @@ -257,6 +252,11 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) TMH_AUDITORS_done (); if (NULL != keyfile) GNUNET_free (privkey); + if (NULL != j_wire) + { + json_decref (j_wire); + j_wire = NULL; + } } @@ -327,124 +327,18 @@ TMH_trigger_daemon () run_daemon (NULL, NULL); } -/** - * Parse the TEST wireformat information from the configuration. - * If any of the required fields is missing return an error. - * - * @param cfg the configuration - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -static int -parse_wireformat_test (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - unsigned long long account_number; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number(cfg, - "wire-test", - "ACCOUNT_NUMBER", - &account_number)) - return GNUNET_SYSERR; - j_wire = json_pack("{s:s, s:I}", - "type", "TEST", - "account_number", (json_int_t) account_number); - if (NULL == j_wire) - return GNUNET_SYSERR; - return GNUNET_OK; -} - - -/** - * Parse the SEPA information from the configuration. If any of the - * required fields is missing return an error. - * - * @param cfg the configuration - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -static int -parse_wireformat_sepa (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - unsigned long long salt; - char *iban; - char *name; - char *address; - char *bic; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, - "wire-sepa", - "SALT", - &salt)) - { - salt = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, - UINT64_MAX); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "No SALT option given in `wire-sepa`, using %llu\n", - (unsigned long long) salt); - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-sepa", - "IBAN", - &iban)) - return GNUNET_SYSERR; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-sepa", - "NAME", - &name)) - { - GNUNET_free (iban); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-sepa", - "ADDRESS", - &address)) - { - GNUNET_free (iban); - GNUNET_free (name); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "wire-sepa", - "BIC", - &bic)) - { - GNUNET_free (iban); - GNUNET_free (name); - GNUNET_free (bic); - GNUNET_free (address); - return GNUNET_SYSERR; - } - j_wire = json_pack ("{s:s, s:s, s:s, s:s, s:o, s:s}", - "type", "SEPA", - "IBAN", iban, - "name", name, - "bic", bic, - "r", json_integer (salt), - "address", address); - GNUNET_free (iban); - GNUNET_free (name); - GNUNET_free (address); - GNUNET_free (bic); - if (NULL == j_wire) - return GNUNET_SYSERR; - return GNUNET_OK; -} - /** * Verify that #j_wire contains a well-formed wire format, and * update #h_wire to match it (if successful). * + * @param cfg configuration to use * @param allowed which wire format is allowed/expected? * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int -validate_and_hash_wireformat (const char *allowed) +validate_and_hash_wireformat (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *allowed) { struct TALER_WIRE_Plugin *plugin; char *lib_name; @@ -464,9 +358,15 @@ validate_and_hash_wireformat (const char *allowed) return GNUNET_NO; } plugin->library_name = lib_name; - ret = plugin->wire_validate (plugin->cls, - j_wire, - NULL); + j_wire = plugin->get_wire_details (plugin->cls, + cfg, + "merchant-wireformat"); + if (NULL == j_wire) + ret = GNUNET_SYSERR; + else + ret = plugin->wire_validate (plugin->cls, + j_wire, + NULL); GNUNET_PLUGIN_unload (lib_name, plugin); GNUNET_free (lib_name); @@ -554,7 +454,7 @@ prepare_daemon () * NULL!) * @param config configuration */ -void +static void run (void *cls, char *const *args, const char *cfgfile, @@ -572,28 +472,14 @@ run (void *cls, TMH_EXCHANGES_init (config)); EXITIF (GNUNET_SYSERR == TMH_AUDITORS_init (config)); - /* FIXME: for now, we just support SEPA here: */ EXITIF (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (config, "merchant", "WIREFORMAT", &wireformat)); - - if (0 == strcmp("SEPA", wireformat)) - { - EXITIF (GNUNET_OK != - parse_wireformat_sepa (config)); - EXITIF (GNUNET_OK != - validate_and_hash_wireformat ("SEPA")); - } - else if (0 == strcmp("TEST", wireformat)) - { - EXITIF (GNUNET_OK != - parse_wireformat_test (config)); - EXITIF (GNUNET_OK != - validate_and_hash_wireformat ("TEST")); - } - + EXITIF (GNUNET_OK != + validate_and_hash_wireformat (config, + wireformat)); GNUNET_free (wireformat); EXITIF (GNUNET_OK != @@ -618,11 +504,6 @@ run (void *cls, EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (config, "merchant", - "HOSTNAME", - &hostname)); - EXITIF (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_string (config, - "merchant", "CURRENCY", &TMH_merchant_currency_string)); @@ -638,6 +519,8 @@ run (void *cls, &url_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, NULL, + MHD_OPTION_CONNECTION_TIMEOUT, + (unsigned int) 10 /* 10s */, MHD_OPTION_END); EXITIF (NULL == mhd); result = GNUNET_OK; @@ -646,9 +529,6 @@ run (void *cls, EXITIF_exit: if (GNUNET_OK != result) GNUNET_SCHEDULER_shutdown (); - - if (GNUNET_OK != result) - GNUNET_SCHEDULER_shutdown (); } diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c @@ -42,7 +42,7 @@ struct PostgresClosure #define PQSQL_strerror(kind, cmd, res) \ - GNUNET_log_from (kind, "merchant-db", \ + GNUNET_log_from (kind, "merchantdb-postgres", \ "SQL %s failed at %s:%u with error: %s", \ cmd, __FILE__, __LINE__, PQresultErrorMessage (res)); @@ -231,7 +231,7 @@ postgres_check_payment(void *cls, res = GNUNET_PQ_exec_prepared (pg->conn, "check_payment", params); - + status = PQresultStatus (res); if (PGRES_TUPLES_OK != status) {