diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2024-01-13 18:34:41 +0100 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2024-01-13 18:34:41 +0100 |
commit | c51675e17d691fda680682f041240057256aa9b3 (patch) | |
tree | 1b1114078832729f8626115cf770ffeb99afb8d4 | |
parent | db1da821ae6f540f46276779876b417f0c431d6c (diff) | |
parent | 9c3fd5dff7e3ce23b72d748fb566786432c7d4cf (diff) | |
download | exchange-c51675e17d691fda680682f041240057256aa9b3.tar.xz |
Merge branch 'master' of git+ssh://git.taler.net/exchange
116 files changed, 1878 insertions, 1551 deletions
diff --git a/configure.ac b/configure.ac index 5f211c4b2..8c7769a83 100644 --- a/configure.ac +++ b/configure.ac @@ -310,11 +310,11 @@ AS_CASE([$with_gnunet], CPPFLAGS="-I$with_gnunet/include ${CPPFLAGS}"]) CPPFLAGS="${CPPFLAGS} ${POSTGRESQL_CPPFLAGS}" AC_CHECK_HEADERS([gnunet/gnunet_pq_lib.h], - [AC_CHECK_LIB([gnunetpq], [GNUNET_PQ_result_spec_array_string], libgnunetpq=1)]) + [AC_CHECK_LIB([gnunetpq], [GNUNET_PQ_get_event_notify_channel], libgnunetpq=1)]) AS_IF([test $libgnunetpq != 1], [AC_MSG_ERROR([[ *** -*** You need libgnunetpq version >= 4.0.0 to build this program. +*** You need libgnunetpq version >= 5:0:0 to build this program. *** Make sure you have Postgres installed while *** building GNUnet (and that your GNUnet version *** is recent!) diff --git a/contrib/gana b/contrib/gana -Subproject 6c45f89a6434e7a10ef90503153aa487be9a3de +Subproject 0ff4edfe76be77a59d4ebff5031feb50f3ba07d diff --git a/contrib/taler-terms-generator b/contrib/taler-terms-generator index 38ccd6cc1..4f348ae7b 100755 --- a/contrib/taler-terms-generator +++ b/contrib/taler-terms-generator @@ -26,14 +26,7 @@ set -eu # Call with target language as first argument. function make_config() { - XLOC=$(echo "$LOCALE_DIR" | sed -e "s/\//\\\\\\//g") - sed -e "s/%VERSION%/$VERSION/g" \ - -e "s/%TITLE%/$TITLE/g" \ - -e "s/%AUTHOR%/$AUTHOR/g" \ - -e "s/%LOCALE_DIR%/$XLOC/g" \ - -e "s/%COPYRIGHT%/$COPYRIGHT/g" \ - -e "s/%LANGUAGE%/$1/g" \ - > "${BUILDDIR}/conf.py" <<EOF + cat > "${BUILDDIR}/conf.py" <<EOF import sys import os sys.path.append(os.path.abspath('_exts')) @@ -47,14 +40,14 @@ templates_path = ['_templates'] source_suffix = { '.rst': 'restructuredtext', } -master_doc = '%VERSION%' -project = u'%VERSION%' -copyright = u'%COPYRIGHT%' -version = '%VERSION%' -release = '%VERSION%' -language = "%LANGUAGE%" +master_doc = '$VERSION_BASENAME' +project = u'$VERSION_BASENAME' +copyright = u'$COPYRIGHT' +version = '$VERSION_BASENAME' +release = '$VERSION_BASENAME' +language = "$LANGUAGE" exclude_patterns = ['_build', '_exts', 'cf', 'prebuilt'] -locale_dirs = ['%LOCALE_DIR%/'] +locale_dirs = ['$LOCALE_DIR/'] gettext_compact = False pygments_style = 'sphinx' html_theme = 'epub' @@ -64,8 +57,8 @@ html_theme_options = { "relbar1": "false", "footer": "false", } -html_title = "%TITLE%" -html_short_title = "%TITLE%" +html_title = "$TITLE" +html_short_title = "$TITLE" html_use_index = True html_show_sphinx = False latex_elements = { @@ -79,11 +72,11 @@ latex_elements = { #'preamble': '', } latex_documents = [ - ('%VERSION%', '%VERSION%.tex', - '%TITLE%', '%AUTHOR%', 'manual'), + ('$VERSION_BASENAME', '$VERSION_BASENAME.tex', + '$VERSION_BASENAME', '$VERSION_BASENAME', 'manual'), ] -epub_basename = "%VERSION%" -epub_title = "%TITLE%" +epub_basename = "$VERSION_BASENAME" +epub_title = "$TITLE" EOF } @@ -98,13 +91,14 @@ function failcat () # defaults AUTHOR="GNU Taler team" VERSION="exchange-tos-v0" -LOCALE_DIR=$(taler-config -s "LOCALEDIR" -f) -OUTPUT=$(taler-config -s "TERMS_DIR" -f) +LOCALE_DIR=$(taler-config -s "PATHS" -o "LOCALEDIR" -f) +OUTPUT=$(taler-config -s "EXCHANGE" -o "TERMS_DIR" -f) PAPER="a4" COPYRIGHT="2014-2023 Taler Systems SA (GPLv3+ or GFDL 1.3+)" +INCREMENTAL=0 # Parse command-line options -while getopts ':a:C:hi:l:L:o:p:t:' OPTION; do +while getopts ':a:C:hKi:l:L:o:p:t:' OPTION; do case "$OPTION" in a) AUTHOR="$OPTARG" @@ -117,6 +111,7 @@ while getopts ':a:C:hi:l:L:o:p:t:' OPTION; do echo ' -a AUTHOR -- set author header' "(default: $AUTHOR)" echo ' -C COPYRIGHT -- set copyright header' "(default: $COPYRIGHT)" echo ' -h -- print this help' + echo ' -K -- rebuild only if input is older than output' echo ' -i INPUT -- input file to convert' "(default: $VERSION)" echo ' -l LANGUAGE -- target language to add' echo ' -L LOCALE_DIR -- directory with resources for translation' "(default: $LOCALE_DIR)" @@ -151,6 +146,9 @@ while getopts ':a:C:hi:l:L:o:p:t:' OPTION; do t) TITLE="$OPTARG" ;; + K) + INCREMENTAL=1 + ;; ?) echo "Unrecognized command line option" 1>&2 exit 1 @@ -170,6 +168,12 @@ then exit 1 fi +if ! which make > /dev/null +then + echo "Command 'make' not found, but required. Please install make." 1>&2 + exit 1 +fi + # We append ".rst" if needed, remove if given on command-line # shellcheck disable=SC2001 VERSION=$(echo "${VERSION}" | sed -e "s/\.rst$//") @@ -227,6 +231,17 @@ then exit 0 fi +# As a heuristic for incremental builds, we only check the text output file. +if [[ "$INCREMENTAL" -eq 1 ]] +then + if [[ "$VERSION" -ot "${OUTPUT}/buildstamp" ]]; + then + echo "Not rebuilding, input file $VERSION is older than $OUTPUT/buildstamp." + exit 0 + fi +fi + + # shellcheck disable=SC2086 for d in en $(ls -d ${LOCALE_DIR}/?? | grep -v "en" 2> /dev/null || true) do @@ -313,5 +328,10 @@ do mv "${BUILDDIR}/pdf/${VERSION_BASENAME}.pdf" "${OUTPUT}/${LANGUAGE}/${VERSION_BASENAME}.pdf" done +if [[ "$INCREMENTAL" -eq 1 ]] +then + touch "${OUTPUT}/buildstamp"; +fi + echo "Done" 1>&2 exit 0 diff --git a/contrib/wallet-core b/contrib/wallet-core -Subproject 0c211082e0b8372f8fa1cef8102e477c7363d9b +Subproject 496bfdc3aecbea61922bb2e0c281f5d35f934a3 diff --git a/debian/rules b/debian/rules index aef4bf5f8..b957c81ac 100755 --- a/debian/rules +++ b/debian/rules @@ -38,6 +38,7 @@ override_dh_installsystemd: # and dh_installsystemd by default only looks for "<package>.service". dh_installsystemd -ptaler-exchange --name=taler-exchange-httpd --no-start --no-enable dh_installsystemd -ptaler-exchange --name=taler-exchange-aggregator --no-start --no-enable + dh_installsystemd -ptaler-exchange --name=taler-exchange-expire --no-start --no-enable dh_installsystemd -ptaler-exchange --name=taler-exchange-transfer --no-start --no-enable dh_installsystemd -ptaler-exchange --name=taler-exchange-wirewatch --no-start --no-enable dh_installsystemd -ptaler-exchange --name=taler-exchange-secmod-cs --no-start --no-enable diff --git a/debian/taler-auditor.taler-auditor-httpd.service b/debian/taler-auditor.taler-auditor-httpd.service index 9aefab641..e65afd9c7 100644 --- a/debian/taler-auditor.taler-auditor-httpd.service +++ b/debian/taler-auditor.taler-auditor-httpd.service @@ -6,6 +6,7 @@ After=postgres.service network.target User=taler-auditor-httpd Type=simple Restart=on-failure +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-auditor-httpd -c /etc/taler/taler.conf [Install] diff --git a/debian/taler-exchange.postinst b/debian/taler-exchange.postinst index 6278dac1f..7509a7749 100644 --- a/debian/taler-exchange.postinst +++ b/debian/taler-exchange.postinst @@ -13,6 +13,7 @@ _CSECUSERNAME=taler-exchange-secmod-cs _RSECUSERNAME=taler-exchange-secmod-rsa _ESECUSERNAME=taler-exchange-secmod-eddsa _AGGRUSERNAME=taler-exchange-aggregator +_EXPIUSERNAME=taler-exchange-expire _WIREUSERNAME=taler-exchange-wire case "${1}" in @@ -53,6 +54,10 @@ configure) adduser --quiet --system --no-create-home --home ${TALER_HOME} ${_AGGRUSERNAME} adduser --quiet ${_AGGRUSERNAME} ${_DBGROUPNAME} fi + if ! getent passwd ${_EXPIUSERNAME} >/dev/null; then + adduser --quiet --system --no-create-home --home ${TALER_HOME} ${_EXPIUSERNAME} + adduser --quiet ${_EXPIUSERNAME} ${_DBGROUPNAME} + fi if ! dpkg-statoverride --list /etc/taler/secrets/exchange-accountcredentials-1.secret.conf >/dev/null 2>&1; then dpkg-statoverride --add --update \ diff --git a/debian/taler-exchange.postrm b/debian/taler-exchange.postrm index 9edf548a5..fcde84b58 100644 --- a/debian/taler-exchange.postrm +++ b/debian/taler-exchange.postrm @@ -10,6 +10,7 @@ _CSECUSERNAME=taler-exchange-secmod-cs _RSECUSERNAME=taler-exchange-secmod-rsa _ESECUSERNAME=taler-exchange-secmod-eddsa _AGGRUSERNAME=taler-exchange-aggregator +_EXPIUSERNAME=taler-exchange-expire _WIREUSERNAME=taler-exchange-wire @@ -28,6 +29,7 @@ purge) deluser --quiet --system ${_RSECUSERNAME} || true deluser --quiet --system ${_ESECUSERNAME} || true deluser --quiet --system ${_AGGRUSERNAME} || true + deluser --quiet --system ${_EXPIUSERNAME} || true deluser --quiet --system ${_WIREUSERNAME} || true deluser --quiet --system ${_CLOSERUSERNAME} || true deluser --quiet --system ${_EUSERNAME} || true diff --git a/debian/taler-exchange.taler-exchange-aggregator.service b/debian/taler-exchange.taler-exchange-aggregator.service index 246cad5c1..095945981 100644 --- a/debian/taler-exchange.taler-exchange-aggregator.service +++ b/debian/taler-exchange.taler-exchange-aggregator.service @@ -8,6 +8,7 @@ User=taler-exchange-aggregator Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-aggregator -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-aggregator@.service b/debian/taler-exchange.taler-exchange-aggregator@.service index bfc44a9a9..170501715 100644 --- a/debian/taler-exchange.taler-exchange-aggregator@.service +++ b/debian/taler-exchange.taler-exchange-aggregator@.service @@ -1,3 +1,9 @@ +# This is a systemd service template to instantiate +# the service multiple times for parallelism. +# We currently don't ship it with the package, +# but might use it for future high-performance +# deployments. + [Unit] Description=GNU Taler payment system exchange aggregator service PartOf=taler-exchange.target @@ -7,6 +13,7 @@ User=taler-exchange-aggregator Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-aggregator -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-closer.service b/debian/taler-exchange.taler-exchange-closer.service index 97a385c13..ab9c6d98f 100644 --- a/debian/taler-exchange.taler-exchange-closer.service +++ b/debian/taler-exchange.taler-exchange-closer.service @@ -8,6 +8,7 @@ User=taler-exchange-closer Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-closer -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-expire.service b/debian/taler-exchange.taler-exchange-expire.service index 250f210fe..a34cdccb7 100644 --- a/debian/taler-exchange.taler-exchange-expire.service +++ b/debian/taler-exchange.taler-exchange-expire.service @@ -8,6 +8,7 @@ User=taler-exchange-expire Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-expire -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-httpd.service b/debian/taler-exchange.taler-exchange-httpd.service index 3671bdc7d..2a4cf72e4 100644 --- a/debian/taler-exchange.taler-exchange-httpd.service +++ b/debian/taler-exchange.taler-exchange-httpd.service @@ -13,6 +13,7 @@ Type=simple # needs to be restarted. Thus no significant delay on restarts. Restart=always RestartSec=1ms +RestartPreventExitStatus=9 # Disable the service if more than 5 restarts are encountered within 5s. # These are usually the systemd defaults, but can be overwritten, thus we set diff --git a/debian/taler-exchange.taler-exchange-httpd@.service b/debian/taler-exchange.taler-exchange-httpd@.service index e0246899c..5a19323f6 100644 --- a/debian/taler-exchange.taler-exchange-httpd@.service +++ b/debian/taler-exchange.taler-exchange-httpd@.service @@ -1,4 +1,9 @@ -% This is a systemd service template. +# This is a systemd service template to instantiate +# the service multiple times for parallelism. +# We currently don't ship it with the package, +# but might use it for future high-performance +# deployments. + [Unit] Description=GNU Taler payment system exchange REST API at %I AssertPathExists=/run/taler/exchange-httpd @@ -14,6 +19,7 @@ Type=simple Restart=always # Do not dally on restarts. RestartSec=1ms +RestartPreventExitStatus=9 EnvironmentFile=/etc/environment ExecStart=/usr/bin/taler-exchange-httpd -c /etc/taler/taler.conf StandardOutput=journal diff --git a/debian/taler-exchange.taler-exchange-secmod-cs.service b/debian/taler-exchange.taler-exchange-secmod-cs.service index 3b5e0745d..edbebac0f 100644 --- a/debian/taler-exchange.taler-exchange-secmod-cs.service +++ b/debian/taler-exchange.taler-exchange-secmod-cs.service @@ -8,6 +8,7 @@ User=taler-exchange-secmod-cs Type=simple Restart=always RestartSec=100ms +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-secmod-cs -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-secmod-eddsa.service b/debian/taler-exchange.taler-exchange-secmod-eddsa.service index e8fba1736..223eec9e2 100644 --- a/debian/taler-exchange.taler-exchange-secmod-eddsa.service +++ b/debian/taler-exchange.taler-exchange-secmod-eddsa.service @@ -8,6 +8,7 @@ User=taler-exchange-secmod-eddsa Type=simple Restart=always RestartSec=100ms +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-secmod-eddsa -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal @@ -16,4 +17,3 @@ PrivateDevices=yes ProtectSystem=full IPAddressDeny=any Slice=taler-exchange.slice - diff --git a/debian/taler-exchange.taler-exchange-secmod-rsa.service b/debian/taler-exchange.taler-exchange-secmod-rsa.service index 10a9585a7..7bfe46006 100644 --- a/debian/taler-exchange.taler-exchange-secmod-rsa.service +++ b/debian/taler-exchange.taler-exchange-secmod-rsa.service @@ -8,6 +8,7 @@ User=taler-exchange-secmod-rsa Type=simple Restart=always RestartSec=100ms +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-secmod-rsa -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-transfer.service b/debian/taler-exchange.taler-exchange-transfer.service index e26af20d0..40d47b09c 100644 --- a/debian/taler-exchange.taler-exchange-transfer.service +++ b/debian/taler-exchange.taler-exchange-transfer.service @@ -8,6 +8,7 @@ User=taler-exchange-wire Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-transfer -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/debian/taler-exchange.taler-exchange-wirewatch.service b/debian/taler-exchange.taler-exchange-wirewatch.service index 7b74737b7..14023c12b 100644 --- a/debian/taler-exchange.taler-exchange-wirewatch.service +++ b/debian/taler-exchange.taler-exchange-wirewatch.service @@ -8,6 +8,7 @@ User=taler-exchange-wire Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 RuntimeMaxSec=3600s ExecStart=/usr/bin/taler-exchange-wirewatch -c /etc/taler/taler.conf StandardOutput=journal diff --git a/debian/taler-exchange.taler-exchange-wirewatch@.service b/debian/taler-exchange.taler-exchange-wirewatch@.service index 85bb9268b..1d11ab0cf 100644 --- a/debian/taler-exchange.taler-exchange-wirewatch@.service +++ b/debian/taler-exchange.taler-exchange-wirewatch@.service @@ -1,3 +1,9 @@ +# This is a systemd service template to instantiate +# the service multiple times for parallelism. +# We currently don't ship it with the package, +# but might use it for future high-performance +# deployments. + [Unit] Description=GNU Taler payment system exchange wirewatch service After=network.target @@ -8,6 +14,7 @@ User=taler-exchange-wire Type=simple Restart=always RestartSec=1s +RestartPreventExitStatus=9 ExecStart=/usr/bin/taler-exchange-wirewatch -c /etc/taler/taler.conf StandardOutput=journal StandardError=journal diff --git a/doc/prebuilt b/doc/prebuilt -Subproject 5e47a72e8a2b5086dfdae4078f695155f5ed7af +Subproject 5e7026c5cef101c90b6dc58096e0a0946ef11b0 diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am index 2a51ed27a..c3deedba1 100644 --- a/src/auditor/Makefile.am +++ b/src/auditor/Makefile.am @@ -163,7 +163,6 @@ taler_helper_auditor_wire_LDADD = \ taler_auditor_httpd_SOURCES = \ taler-auditor-httpd.c taler-auditor-httpd.h \ taler-auditor-httpd_deposit-confirmation.c taler-auditor-httpd_deposit-confirmation.h \ - taler-auditor-httpd_exchanges.c taler-auditor-httpd_exchanges.h \ taler-auditor-httpd_mhd.c taler-auditor-httpd_mhd.h taler_auditor_httpd_LDADD = \ $(LIBGCRYPT_LIBS) \ diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c index a59ce3de0..0bb9c77d9 100644 --- a/src/auditor/taler-auditor-httpd.c +++ b/src/auditor/taler-auditor-httpd.c @@ -31,7 +31,6 @@ #include "taler_auditordb_lib.h" #include "taler_exchangedb_lib.h" #include "taler-auditor-httpd_deposit-confirmation.h" -#include "taler-auditor-httpd_exchanges.h" #include "taler-auditor-httpd_mhd.h" #include "taler-auditor-httpd.h" @@ -206,9 +205,12 @@ handle_mhd_request (void *cls, { "/deposit-confirmation", MHD_HTTP_METHOD_PUT, "application/json", NULL, 0, &TAH_DEPOSIT_CONFIRMATION_handler, MHD_HTTP_OK }, - { "/exchanges", MHD_HTTP_METHOD_GET, "application/json", + { "/deposit-confirmation", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, - &TAH_EXCHANGES_handler, MHD_HTTP_OK }, + &TAH_DEPOSIT_CONFIRMATION_get, MHD_HTTP_OK }, +// { "/deposit-confirmation", MHD_HTTP_METHOD_DELETE, "application/json", +// NULL, 0, +// &TAH_DEPOSIT_CONFIRMATION_delete, MHD_HTTP_OK }, { "/config", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, &handle_config, MHD_HTTP_OK }, diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 020d43d56..2631c6f58 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -31,7 +31,6 @@ #include "taler-auditor-httpd.h" #include "taler-auditor-httpd_deposit-confirmation.h" - GNUNET_NETWORK_STRUCT_BEGIN /** @@ -118,11 +117,11 @@ verify_and_execute_deposit_confirmation ( const struct TALER_CoinSpendSignatureP *coin_sigps[ GNUNET_NZL (dc->num_coins)]; - for (unsigned int i = 0; i<dc->num_coins; i++) + for (unsigned int i = 0; i < dc->num_coins; i++) coin_sigps[i] = &dc->coin_sigs[i]; if (GNUNET_TIME_absolute_is_future (es->ep_start.abs_time) || - GNUNET_TIME_absolute_is_past (es->ep_expire.abs_time) ) + GNUNET_TIME_absolute_is_past (es->ep_expire.abs_time)) { /* Signing key expired */ TALER_LOG_WARNING ("Expired exchange signing key\n"); @@ -134,7 +133,7 @@ verify_and_execute_deposit_confirmation ( /* check our cache */ GNUNET_CRYPTO_hash (&skv, - sizeof (skv), + sizeof(skv), &h); GNUNET_assert (0 == pthread_mutex_lock (&lock)); cached = GNUNET_CONTAINER_multihashmap_get (cache, @@ -341,8 +340,8 @@ TAH_DEPOSIT_CONFIRMATION_handler ( &json); if (GNUNET_SYSERR == res) return MHD_NO; - if ( (GNUNET_NO == res) || - (NULL == json) ) + if ((GNUNET_NO == res) || + (NULL == json)) return MHD_YES; res = TALER_MHD_parse_json_data (connection, json, @@ -350,12 +349,12 @@ TAH_DEPOSIT_CONFIRMATION_handler ( if (GNUNET_SYSERR == res) { json_decref (json); - return MHD_NO; /* hard failure */ + return MHD_NO; /* hard failure */ } if (GNUNET_NO == res) { json_decref (json); - return MHD_YES; /* failure */ + return MHD_YES; /* failure */ } } num_coins = json_array_size (jcoin_sigs); @@ -382,7 +381,7 @@ TAH_DEPOSIT_CONFIRMATION_handler ( struct TALER_CoinSpendSignatureP coin_sigs[num_coins]; MHD_RESULT res; - for (unsigned int i = 0; i<num_coins; i++) + for (unsigned int i = 0; i < num_coins; i++) { json_t *jpub = json_array_get (jcoin_pubs, i); @@ -391,12 +390,12 @@ TAH_DEPOSIT_CONFIRMATION_handler ( const char *ps = json_string_value (jpub); const char *ss = json_string_value (jsig); - if ( (NULL == ps) || - (GNUNET_OK != - GNUNET_STRINGS_string_to_data (ps, - strlen (ps), - &coin_pubs[i], - sizeof (coin_pubs[i]))) ) + if ((NULL == ps) || + (GNUNET_OK != + GNUNET_STRINGS_string_to_data (ps, + strlen (ps), + &coin_pubs[i], + sizeof(coin_pubs[i])))) { GNUNET_break_op (0); json_decref (json); @@ -405,12 +404,12 @@ TAH_DEPOSIT_CONFIRMATION_handler ( TALER_EC_GENERIC_PARAMETER_MALFORMED, "coin_pub[] malformed"); } - if ( (NULL == ss) || - (GNUNET_OK != - GNUNET_STRINGS_string_to_data (ss, - strlen (ss), - &coin_sigs[i], - sizeof (coin_sigs[i]))) ) + if ((NULL == ss) || + (GNUNET_OK != + GNUNET_STRINGS_string_to_data (ss, + strlen (ss), + &coin_sigs[i], + sizeof(coin_sigs[i])))) { GNUNET_break_op (0); json_decref (json); @@ -423,7 +422,7 @@ TAH_DEPOSIT_CONFIRMATION_handler ( dc.num_coins = num_coins; dc.coin_pubs = coin_pubs; dc.coin_sigs = coin_sigs; - es.exchange_pub = dc.exchange_pub; /* used twice! */ + es.exchange_pub = dc.exchange_pub; /* used twice! */ dc.master_public_key = es.master_public_key; res = verify_and_execute_deposit_confirmation (connection, &dc, @@ -456,4 +455,99 @@ TEAH_DEPOSIT_CONFIRMATION_done (void) } +/** + * Add deposit confirmation to the list. + * + * @param[in,out] cls a `json_t *` array to extend + * @param serial_id location of the @a dc in the database + * @param dc struct of deposit confirmation + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating + */ +static enum GNUNET_GenericReturnValue +add_deposit_confirmation (void *cls, + uint64_t serial_id, + const struct TALER_AUDITORDB_DepositConfirmation *dc) +{ + json_t *list = cls; + json_t *obj; + + obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("dc", + dc)); + GNUNET_break (0 == + json_array_append_new (list, + obj)); + return GNUNET_OK; +} + + +/** + * + * @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 + */ +MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_get (struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + json_t *ja; + enum GNUNET_DB_QueryStatus qs; + + (void) rh; + (void) connection_cls; + (void) upload_data; + (void) upload_data_size; + if (GNUNET_SYSERR == + TAH_plugin->preflight (TAH_plugin->cls)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_SETUP_FAILED, + NULL); + } + ja = json_array (); + GNUNET_break (NULL != ja); + // TODO correct below + struct TALER_AUDITORDB_ProgressPointDepositConfirmation ppdc = { 0 }; // FIXME: initialize... + + qs = TAH_plugin->get_deposit_confirmations ( + TAH_plugin->cls, + NULL, /* FIXME: master-public key to be removed! */ + ppdc.last_deposit_confirmation_serial_id, + &add_deposit_confirmation, + ja); + + if (0 > qs) + { + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + json_decref (ja); + TALER_LOG_WARNING ( + "Failed to handle GET /deposit-confirmation in database\n"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "deposit-confirmation"); + } + return TALER_MHD_REPLY_JSON_PACK ( + connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_array_steal ("deposit-confirmation", + ja)); +} + + +/*MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_delete(struct TEH_RequestContext *rc, + const char *const args[1]) { +}*/ + + /* end of taler-auditor-httpd_deposit-confirmation.c */ diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.h b/src/auditor/taler-auditor-httpd_deposit-confirmation.h index a7c331916..ff42e4aa3 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.h +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.h @@ -56,4 +56,34 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size); +/** + * Handle a "/deposit-confirmation" 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 + */ +MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_get (struct TAH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + +/** + * Handle a DELETE "/deposit-confirmation/$dc" request. + * + * @param rc request details about the request to handle + * @param args argument with the dc primary key + * @return MHD result code + */ +/*MHD_RESULT +TAH_DEPOSIT_CONFIRMATION_delete ( + struct TEH_RequestContext *rc, + const char *const args[1]);*/ + + #endif diff --git a/src/auditor/taler-auditor-httpd_exchanges.c b/src/auditor/taler-auditor-httpd_exchanges.c deleted file mode 100644 index f9a9e9e60..000000000 --- a/src/auditor/taler-auditor-httpd_exchanges.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - 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, see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-auditor-httpd_exchanges.c - * @brief Handle /exchanges requests; returns list of exchanges we audit - * @author Christian Grothoff - */ -#include "platform.h" -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <jansson.h> -#include <microhttpd.h> -#include <pthread.h> -#include "taler_json_lib.h" -#include "taler_mhd_lib.h" -#include "taler-auditor-httpd.h" -#include "taler-auditor-httpd_exchanges.h" - - -/** - * Add exchange information to the list. - * - * @param[in,out] cls a `json_t *` array to extend - * @param master_pub master public key of an exchange - * @param exchange_url base URL of an exchange - */ -static void -add_exchange (void *cls, - const struct TALER_MasterPublicKeyP *master_pub, - const char *exchange_url) -{ - json_t *list = cls; - json_t *obj; - - obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("master_pub", - master_pub), - GNUNET_JSON_pack_string ("exchange_url", - exchange_url)); - GNUNET_break (0 == - json_array_append_new (list, - obj)); - -} - - -/** - * Handle a "/exchanges" 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 - */ -MHD_RESULT -TAH_EXCHANGES_handler (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - json_t *ja; - enum GNUNET_DB_QueryStatus qs; - - (void) rh; - (void) connection_cls; - (void) upload_data; - (void) upload_data_size; - if (GNUNET_SYSERR == - TAH_plugin->preflight (TAH_plugin->cls)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_SETUP_FAILED, - NULL); - } - ja = json_array (); - GNUNET_break (NULL != ja); - qs = TAH_plugin->list_exchanges (TAH_plugin->cls, - &add_exchange, - ja); - if (0 > qs) - { - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - json_decref (ja); - TALER_LOG_WARNING ("Failed to handle /exchanges in database\n"); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "exchanges"); - } - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_array_steal ("exchanges", - ja)); -} - - -/* end of taler-auditor-httpd_exchanges.c */ diff --git a/src/auditor/taler-auditor-httpd_exchanges.h b/src/auditor/taler-auditor-httpd_exchanges.h deleted file mode 100644 index c7d8dd5fd..000000000 --- a/src/auditor/taler-auditor-httpd_exchanges.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2018 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free Software - 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, see <http://www.gnu.org/licenses/> -*/ -/** - * @file taler-auditor-httpd_exchanges.h - * @brief Handle /exchanges requests - * @author Christian Grothoff - */ -#ifndef TALER_AUDITOR_HTTPD_EXCHANGES_H -#define TALER_AUDITOR_HTTPD_EXCHANGES_H - -#include <gnunet/gnunet_util_lib.h> -#include <microhttpd.h> -#include "taler-auditor-httpd.h" - - -/** - * Handle a "/exchanges" 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 - */ -MHD_RESULT -TAH_EXCHANGES_handler (struct TAH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - -#endif diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index 8ec2b223e..520fc2f47 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -29,6 +29,8 @@ #include "taler_bank_service.h" #include "taler_signatures.h" #include "report-lib.h" +#include "taler_dbevents.h" +#include <jansson.h> /* -- @@ -51,6 +53,10 @@ -- AND NOT ancient; */ +/** + * Next task to run, if any. + */ +static struct GNUNET_SCHEDULER_Task *task; /** * Return value from main(). @@ -77,6 +83,13 @@ static struct TALER_Amount total_missed_deposit_confirmations; */ static int internal_checks; +static struct GNUNET_DB_EventHandler *eh; + +/** + * Our database plugin. + */ +static struct TALER_AUDITORDB_Plugin *db_plugin; + /** * Closure for #test_dc. */ @@ -289,6 +302,29 @@ analyze_deposit_confirmations (void *cls) /** + * Function called on events received from Postgres. + * + * @param cls closure, NULL + * @param extra additional event data provided + * @param extra_size number of bytes in @a extra + */ +static void +db_notify (void *cls, + const void *extra, + size_t extra_size) +{ + (void) cls; + (void) extra; + (void) extra_size; + + GNUNET_assert (NULL != task); + GNUNET_SCHEDULER_cancel (task); + task = GNUNET_SCHEDULER_add_now (&analyze_deposit_confirmations, + NULL); +} + + +/** * Main function that will be run. * * @param cls closure @@ -313,6 +349,39 @@ run (void *cls, global_ret = EXIT_FAILURE; return; } + + /*if (NULL == + (db_plugin = TALER_AUDITORDB_plugin_load (cfg))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to initialize DB subsystem\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_OK != + db_plugin->connect (db_plugin->cls)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to connect to database\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + { + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_AUDITOR_NEW_DEPOSIT_CONFIRMATIONS) + }; + + eh = db_plugin->event_listen (db_plugin->cls, + &es, + GNUNET_TIME_UNIT_FOREVER_REL, + &db_notify, + NULL); + } + GNUNET_assert (NULL == task); + task = GNUNET_SCHEDULER_add_now (&select_work, + NULL);*/ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting deposit audit\n"); GNUNET_assert (NULL != diff --git a/src/auditor/taler-helper-auditor-purses.c b/src/auditor/taler-helper-auditor-purses.c index e728df0ee..81291f97d 100644 --- a/src/auditor/taler-helper-auditor-purses.c +++ b/src/auditor/taler-helper-auditor-purses.c @@ -316,6 +316,11 @@ struct PurseSummary */ bool purse_deleted; + /** + * Was the purse refunded? FIXME: Not yet handled (do we need to?) + */ + bool purse_refunded; + }; @@ -416,7 +421,8 @@ setup_purse (struct PurseContext *pc, &ps->exchange_balance, &ps->h_contract_terms, &ps->merge_timestamp, - &ps->purse_deleted); + &ps->purse_deleted, + &ps->purse_refunded); if (0 >= qs) { GNUNET_free (ps); diff --git a/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql b/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql new file mode 100644 index 000000000..712561ccc --- /dev/null +++ b/src/auditordb/0002-auditor_amount_arithmetic_inconsistency.sql @@ -0,0 +1,27 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_amount_arithmetic_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ operation BYTEA,
+ exchange_amount taler_amount,
+ auditor_amount taler_amount,
+ profitable BOOLEAN
+);
+COMMENT ON TABLE auditor_amount_arithmetic_inconsistency
+ IS 'Report a (serious) inconsistency in the exchange''s database with respect to calculations involving amounts';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_bad_sig_losses.sql b/src/auditordb/0002-auditor_bad_sig_losses.sql new file mode 100644 index 000000000..ac17a5120 --- /dev/null +++ b/src/auditordb/0002-auditor_bad_sig_losses.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_bad_sig_losses
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ operation BYTEA,
+ loss taler_amount,
+ operation_specific_pub BYTEA
+);
+COMMENT ON TABLE auditor_bad_sig_losses
+ IS 'Report a (serious) inconsistency with losses due to bad signatures';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_closure_lags.sql b/src/auditordb/0002-auditor_closure_lags.sql new file mode 100644 index 000000000..8473b25f9 --- /dev/null +++ b/src/auditordb/0002-auditor_closure_lags.sql @@ -0,0 +1,27 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_closure_lags
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ amount taler_amount,
+ deadline BIGINT,
+ wtid integer,
+ account BYTEA
+);
+COMMENT ON TABLE auditor_closure_lags
+ IS 'Report closure lags.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_coin_inconsistency.sql b/src/auditordb/0002-auditor_coin_inconsistency.sql new file mode 100644 index 000000000..91f954a68 --- /dev/null +++ b/src/auditordb/0002-auditor_coin_inconsistency.sql @@ -0,0 +1,28 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_coin_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ operation BYTEA,
+ exchange_amount taler_amount,
+ auditor_amount taler_amount,
+ coin_pub BYTEA,
+ profitable BOOLEAN
+);
+COMMENT ON TABLE auditor_coin_inconsistency
+ IS 'Report a (serious) inconsistency in the exchange''s database with respect to calculations involving amounts';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql b/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql new file mode 100644 index 000000000..fd18f35fb --- /dev/null +++ b/src/auditordb/0002-auditor_denomination_key_validity_withdraw_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_denomination_key_validity_withdraw_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ execution_date BIGINT,
+ reserve_pub BYTEA,
+ denompub_h BYTEA
+);
+COMMENT ON TABLE auditor_denomination_key_validity_withdraw_inconsistency
+ IS 'Report a (serious) denomination key validity withdraw inconsistency in the exchange''s database';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_denominations_without_sigs.sql b/src/auditordb/0002-auditor_denominations_without_sigs.sql new file mode 100644 index 000000000..86c83e94f --- /dev/null +++ b/src/auditordb/0002-auditor_denominations_without_sigs.sql @@ -0,0 +1,27 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_denominations_without_sigs
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ denompub_h BYTEA,
+ value taler_amount,
+ start_time BIGINT,
+ end_time BIGINT
+);
+COMMENT ON TABLE auditor_denominations_without_sigs
+ IS 'Report encountered denomination that auditor is not auditing.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_deposit_confirmations.sql b/src/auditordb/0002-auditor_deposit_confirmations.sql index a0725925c..dd85c0a62 100644 --- a/src/auditordb/0002-auditor_deposit_confirmations.sql +++ b/src/auditordb/0002-auditor_deposit_confirmations.sql @@ -41,4 +41,20 @@ COMMENT ON TABLE auditor_deposit_confirmations CREATE INDEX IF NOT EXISTS auditor_deposit_confirmations_not_ancient ON auditor_deposit_confirmations (exchange_timestamp ASC) - WHERE NOT ancient;
\ No newline at end of file + WHERE NOT ancient; + +CREATE OR REPLACE FUNCTION auditor_new_transactions_trigger() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + NOTIFY XX81AFHF88YGN6ESNH39KR5VQE9MHD7GSSNMTCXB82SZ6T99ARHE0; + RETURN NEW; +END $$; +COMMENT ON FUNCTION auditor_new_transactions_trigger() + IS 'Call auditor_call_db_notify on new entry'; + +CREATE TRIGGER auditor_notify_helper_deposits + AFTER INSERT + ON auditor.deposit_confirmations +EXECUTE PROCEDURE auditor_new_transactions_trigger();
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_emergency.sql b/src/auditordb/0002-auditor_emergency.sql new file mode 100644 index 000000000..2bb13d7e5 --- /dev/null +++ b/src/auditordb/0002-auditor_emergency.sql @@ -0,0 +1,29 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_emergency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ denompub_h BYTEA,
+ denom_risk taler_amount,
+ denom_loss taler_amount,
+ deposit_start BIGINT,
+ deposit_end BIGINT,
+ value taler_amount
+);
+COMMENT ON TABLE auditor_emergency
+ IS 'Report an emergency denomination.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_emergency_by_count.sql b/src/auditordb/0002-auditor_emergency_by_count.sql new file mode 100644 index 000000000..4daa994a7 --- /dev/null +++ b/src/auditordb/0002-auditor_emergency_by_count.sql @@ -0,0 +1,30 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_emergency_by_count
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ denompub_h BYTEA,
+ num_issued integer,
+ num_known integer,
+ risk taler_amount,
+ start BIGINT,
+ deposit_end BIGINT,
+ value taler_amount
+);
+COMMENT ON TABLE auditor_emergency_by_count
+ IS 'Report an emergency denomination.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_exchange_signkeys.sql b/src/auditordb/0002-auditor_exchange_signkeys.sql index 127365e64..345870252 100644 --- a/src/auditordb/0002-auditor_exchange_signkeys.sql +++ b/src/auditordb/0002-auditor_exchange_signkeys.sql @@ -1,4 +1,4 @@ --- + -- -- This file is part of TALER -- Copyright (C) 2014--2022 Taler Systems SA -- diff --git a/src/auditordb/0002-auditor_fee_time_inconsistency.sql b/src/auditordb/0002-auditor_fee_time_inconsistency.sql new file mode 100644 index 000000000..b89cc59c7 --- /dev/null +++ b/src/auditordb/0002-auditor_fee_time_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_fee_time_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ type BYTEA,
+ time BIGINT,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_fee_time_inconsistency
+ IS 'Report a (serious) fee time inconsistency in the exchange''s database';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql b/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql new file mode 100644 index 000000000..f786d0fdf --- /dev/null +++ b/src/auditordb/0002-auditor_misattribution_in_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_misattribution_in_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ amount taler_amount,
+ bank_row BIGINT,
+ reserve_pub BYTEA
+);
+COMMENT ON TABLE auditor_misattribution_in_inconsistency
+ IS 'Report wire transfer that was smaller than it should have been.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql b/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql new file mode 100644 index 000000000..5ffb6e85a --- /dev/null +++ b/src/auditordb/0002-auditor_purse_not_closed_inconsistencies.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_purse_not_closed_inconsistencies
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ purse_pub BYTEA,
+ amount taler_amount,
+ expiration_date BIGINT
+);
+COMMENT ON TABLE auditor_purse_not_closed_inconsistencies
+ IS 'Report expired purses';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_refreshes_hanging.sql b/src/auditordb/0002-auditor_refreshes_hanging.sql new file mode 100644 index 000000000..5544bc0d8 --- /dev/null +++ b/src/auditordb/0002-auditor_refreshes_hanging.sql @@ -0,0 +1,25 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_refreshes_hanging
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ amount taler_amount,
+ coin_pub BYTEA
+);
+COMMENT ON TABLE auditor_refreshes_hanging
+ IS 'Report a hanging refresh.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql b/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql new file mode 100644 index 000000000..bbc0c8118 --- /dev/null +++ b/src/auditordb/0002-auditor_reserve_balance_insufficient_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_reserve_balance_insufficient_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ reserve_pub BYTEA,
+ inconsistency_gain BOOLEAN,
+ inconsistency_amount taler_amount
+);
+COMMENT ON TABLE auditor_reserve_balance_insufficient_inconsistency
+ IS 'Report a (serious) balance insufficiency in the exchange''s database';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql b/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql new file mode 100644 index 000000000..26d872132 --- /dev/null +++ b/src/auditordb/0002-auditor_reserve_balance_summary_wrong_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_reserve_balance_summary_wrong_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ reserve_pub BYTEA,
+ exchange_amount taler_amount,
+ auditor_amount taler_amount
+);
+COMMENT ON TABLE auditor_reserve_balance_summary_wrong_inconsistency
+ IS 'Report a (serious) reserve balance insufficiency.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_reserve_in_inconsistency.sql b/src/auditordb/0002-auditor_reserve_in_inconsistency.sql new file mode 100644 index 000000000..bb90c4018 --- /dev/null +++ b/src/auditordb/0002-auditor_reserve_in_inconsistency.sql @@ -0,0 +1,29 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_reserve_in_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ amount_exchange_expected taler_amount,
+ amount_wired taler_amount,
+ reserve_pub BYTEA,
+ timestamp BIGINT,
+ account BYTEA,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_reserve_in_inconsistency
+ IS 'Report an incoming wire transfer claimed by exchange not found.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql b/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql new file mode 100644 index 000000000..1147b4ae8 --- /dev/null +++ b/src/auditordb/0002-auditor_reserve_not_closed_inconsistency.sql @@ -0,0 +1,27 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_reserve_not_closed_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ reserve_pub BYTEA,
+ balance taler_amount,
+ expiration_time BIGINT,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_reserve_not_closed_inconsistency
+ IS 'Report a (serious) reserve balance insufficiency.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_row_inconsistency.sql b/src/auditordb/0002-auditor_row_inconsistency.sql new file mode 100644 index 000000000..ece2e5661 --- /dev/null +++ b/src/auditordb/0002-auditor_row_inconsistency.sql @@ -0,0 +1,25 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_row_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ table BYTEA,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_row_inconsistency
+ IS 'Report a (serious) row inconsistency in the exchange''s database';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_row_minor_inconsistencies.sql b/src/auditordb/0002-auditor_row_minor_inconsistencies.sql new file mode 100644 index 000000000..7836037c7 --- /dev/null +++ b/src/auditordb/0002-auditor_row_minor_inconsistencies.sql @@ -0,0 +1,25 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_row_minor_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ table BYTEA,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_row_minor_inconsistency
+ IS 'Report a (serious) row inconsistency in the exchange''s database.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_wire_format_inconsistency.sql b/src/auditordb/0002-auditor_wire_format_inconsistency.sql new file mode 100644 index 000000000..1bc9af89d --- /dev/null +++ b/src/auditordb/0002-auditor_wire_format_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_wire_format_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ amount taler_amount,
+ wire_offset BIGINT,
+ diagnostic BYTEA
+);
+COMMENT ON TABLE auditor_wire_format_inconsistency
+ IS 'Report a (serious) format inconsistency.';
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_wire_out_inconsistency.sql b/src/auditordb/0002-auditor_wire_out_inconsistency.sql new file mode 100644 index 000000000..6a49c24a0 --- /dev/null +++ b/src/auditordb/0002-auditor_wire_out_inconsistency.sql @@ -0,0 +1,26 @@ +--
+-- This file is part of TALER
+-- Copyright (C) 2014--2024 Taler Systems SA
+--
+-- TALER is free software; you can redistribute it and/or modify it under the
+-- terms of the GNU General Public License as published by the Free Software
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+SET search_path TO auditor;
+CREATE TABLE IF NOT EXISTS auditor_wire_out_inconsistency
+(
+ row_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE PRIMARY KEY,
+ destination_account BYTEA,
+ expected taler_amount,
+ claimed taler_amount
+);
+COMMENT ON TABLE auditor_wire_out_inconsistency
+ IS 'Report a (serious) wire inconsistency in the exchange''s database';
\ No newline at end of file diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am index dbbd4d1cc..573b1b980 100644 --- a/src/auditordb/Makefile.am +++ b/src/auditordb/Makefile.am @@ -108,16 +108,15 @@ libtaler_plugin_auditordb_postgres_la_SOURCES = \ pg_insert_purse_summary.h pg_insert_purse_summary.c \ pg_update_purse_summary.h pg_update_purse_summary.c \ pg_get_deposit_confirmations.h pg_get_deposit_confirmations.c -libtaler_plugin_auditordb_postgres_la_LIBADD = \ - $(LTLIBINTL) libtaler_plugin_auditordb_postgres_la_LDFLAGS = \ - $(TALER_PLUGIN_LDFLAGS) \ + $(TALER_PLUGIN_LDFLAGS) +libtaler_plugin_auditordb_postgres_la_LIBADD = \ + $(LTLIBINTL) \ $(top_builddir)/src/pq/libtalerpq.la \ $(top_builddir)/src/util/libtalerutil.la \ - -lpq \ -lgnunetpq \ -lgnunetutil \ - -lpthread \ + -lpq \ $(XLIB) lib_LTLIBRARIES = \ diff --git a/src/auditordb/pg_delete_deposit_confirmations.c b/src/auditordb/pg_delete_deposit_confirmations.c new file mode 100644 index 000000000..553e97121 --- /dev/null +++ b/src/auditordb/pg_delete_deposit_confirmations.c @@ -0,0 +1,62 @@ +/*
+ This file is part of TALER
+ Copyright (C) 2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file auditordb/pg_delete_deposit_confirmations.c
+ * @brief Implementation of the delete_deposit_confirmations function for Postgres
+ * @author Nicola Eigel
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_delete_deposit_confirmations.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+TAH_PG_delete_deposit_confirmations (
+ void *cls,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+ GNUNET_PQ_query_param_auto_from_type (h_wire),
+ GNUNET_PQ_query_param_auto_from_type (merchant_pub),
+ GNUNET_PQ_query_param_auto_from_type (exchange_sig),
+ GNUNET_PQ_query_param_auto_from_type (exchange_pub),
+ GNUNET_PQ_query_param_auto_from_type (master_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "auditor_delete_deposit_confirmations",
+ "DELETE"
+ " FROM deposit_confirmations"
+ " WHERE h_contract_terms=$1"
+ " AND h_wire=$2"
+ " AND merchant_pub=$3"
+ " AND exchange_sig=$4"
+ " AND exchange_pub=$5"
+ " AND master_sig=$6;");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "auditor_delete_deposit_confirmations",
+ params);
+}
diff --git a/src/auditordb/pg_delete_deposit_confirmations.h b/src/auditordb/pg_delete_deposit_confirmations.h new file mode 100644 index 000000000..f0339fd3d --- /dev/null +++ b/src/auditordb/pg_delete_deposit_confirmations.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2024 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file auditordb/pg_delete_deposit_confirmations.h + * @brief implementation of the delete_deposit_confirmations function for Postgres + * @author Nicola Eigel + */ +#ifndef PG_DELETE_DEPOSIT_CONFIRMATIONS_H +#define PG_DELETE_DEPOSIT_CONFIRMATIONS_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_auditordb_plugin.h" + +/** + * Delete a row from the deposit confirmations table. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param h_contract_terms private contract hash + * @param h_wire merchant wire hash + * @param merchant_pub master key of the merchant + * @param exchange_sig signature of the exchange + * @param exchange_pub master key of the exchange + * @param master_sig master signature of the exchange + * @return + */ +enum GNUNET_DB_QueryStatus +TAH_PG_delete_deposit_confirmations ( + void *cls, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_ExchangeSignatureP *exchange_sig, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterSignatureP *master_sig); + + +#endif diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 2b722a5ea..dc66990ba 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -77,6 +77,7 @@ #include "pg_insert_exchange_signkey.h" #include "pg_insert_deposit_confirmation.h" #include "pg_get_deposit_confirmations.h" +#include "pg_delete_deposit_confirmations.h" #include "pg_insert_auditor_progress_coin.h" #include "pg_update_auditor_progress_coin.h" #include "pg_get_auditor_progress_coin.h" diff --git a/src/curl/curl.c b/src/curl/curl.c index caa0052f7..483c9b671 100644 --- a/src/curl/curl.c +++ b/src/curl/curl.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2019-2021 Taler Systems SA + Copyright (C) 2019-2024 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 @@ -30,6 +30,58 @@ #endif +void +TALER_curl_set_secure_redirect_policy (CURL *eh, + const char *url) +{ + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_FOLLOWLOCATION, + 1L)); + GNUNET_assert ( (0 == strncasecmp (url, + "https://", + strlen ("https://"))) || + (0 == strncasecmp (url, + "http://", + strlen ("http://"))) ); +#ifdef CURLOPT_REDIR_PROTOCOLS_STR + if (0 == strncasecmp (url, + "https://", + strlen ("https://"))) + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_REDIR_PROTOCOLS_STR, + "https")); + else + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_REDIR_PROTOCOLS_STR, + "http,https")); +#else +#ifdef CURLOPT_REDIR_PROTOCOLS + if (0 == strncasecmp (url, + "https://", + strlen ("https://"))) + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_REDIR_PROTOCOLS, + CURLPROTO_HTTPS)); + else + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_REDIR_PROTOCOLS, + CURLPROTO_HTTP | CURLPROTO_HTTPS)); +#endif +#endif + /* limit MAXREDIRS to 5 as a simple security measure against + a potential infinite loop caused by a malicious target */ + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_MAXREDIRS, + 5L)); +} + + enum GNUNET_GenericReturnValue TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx, CURL *eh, diff --git a/src/exchange/taler-exchange-expire.c b/src/exchange/taler-exchange-expire.c index d99c430e0..c7132fcb2 100644 --- a/src/exchange/taler-exchange-expire.c +++ b/src/exchange/taler-exchange-expire.c @@ -74,11 +74,6 @@ static struct TALER_EXCHANGEDB_Plugin *db_plugin; static struct GNUNET_SCHEDULER_Task *task; /** - * How long should we sleep when idle before trying to find more work? - */ -static struct GNUNET_TIME_Relative expire_idle_sleep_interval; - -/** * How big are the shards we are processing? Is an inclusive offset, so every * shard ranges from [X,X+shard_size) exclusive. So a shard covers * shard_size slots. @@ -141,17 +136,6 @@ shutdown_task (void *cls) static enum GNUNET_GenericReturnValue parse_expire_config (void) { - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, - "exchange", - "EXPIRE_IDLE_SLEEP_INTERVAL", - &expire_idle_sleep_interval)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "exchange", - "EXPIRE_IDLE_SLEEP_INTERVAL"); - return GNUNET_SYSERR; - } if (NULL == (db_plugin = TALER_EXCHANGEDB_plugin_load (cfg))) { @@ -223,7 +207,12 @@ release_shard (struct Shard *s) if ( (0 == wc) && (test_mode) && (! jump_mode) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "In test-mode without work. Terminating.\n"); GNUNET_SCHEDULER_shutdown (); + return; + } } @@ -395,6 +384,13 @@ run_shard (void *cls) if (GNUNET_TIME_absolute_is_future (s->shard_end)) { abort_shard (s); + if (test_mode) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "In test-mode without work. Terminating.\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } GNUNET_assert (NULL == task); task = GNUNET_SCHEDULER_add_at (s->shard_end, &run_shard, diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c b/src/exchange/taler-exchange-httpd_age-withdraw.c index 939e0f76d..9276fb191 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw.c @@ -225,7 +225,6 @@ parse_age_withdraw_json ( * the commitment along the way. */ { unsigned int kappa = 0; - enum GNUNET_GenericReturnValue ret; json_array_foreach (j_kappa_coin_evs, kappa, value) { struct GNUNET_JSON_Specification spec[] = { @@ -253,10 +252,9 @@ parse_age_withdraw_json ( { struct TALER_BlindedCoinHashP bch; - ret = TALER_coin_ev_hash (&awc->coin_evs[idx][kappa], - &awc->denom_hs[idx], - &bch); - GNUNET_assert (GNUNET_OK == ret); + TALER_coin_ev_hash (&awc->coin_evs[idx][kappa], + &awc->denom_hs[idx], + &bch); GNUNET_CRYPTO_hash_context_read (hash_context, &bch, sizeof(bch)); diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c index 632368ded..c9aca8e99 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c @@ -357,11 +357,10 @@ calculate_blinded_hash ( return ret; } - ret = TALER_coin_ev_hash (&detail.blinded_planchet, - &denom_key->h_denom_pub, - bch); + TALER_coin_ev_hash (&detail.blinded_planchet, + &denom_key->h_denom_pub, + bch); TALER_blinded_planchet_free (&detail.blinded_planchet); - GNUNET_assert (GNUNET_OK == ret); } return ret; @@ -594,7 +593,7 @@ TEH_handler_age_withdraw_reveal ( result = reply_age_withdraw_reveal_success (rc->connection, &actx.commitment); - } while(0); + } while (0); GNUNET_JSON_parse_free (spec); if (NULL != actx.commitment.denom_sigs) diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c b/src/exchange/taler-exchange-httpd_batch-withdraw.c index e296f31f8..2b80c2fc4 100644 --- a/src/exchange/taler-exchange-httpd_batch-withdraw.c +++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c @@ -838,17 +838,10 @@ parse_planchets (const struct TEH_RequestContext *rc, NULL); } - if (GNUNET_OK != - TALER_coin_ev_hash (&pc->blinded_planchet, - &pc->collectable.denom_pub_hash, - &pc->collectable.h_coin_envelope)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL); - } + TALER_coin_ev_hash (&pc->blinded_planchet, + &pc->collectable.denom_pub_hash, + &pc->collectable.h_coin_envelope); + TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != TALER_wallet_withdraw_verify (&pc->collectable.denom_pub_hash, diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 913cd7343..4d6decf35 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -1630,6 +1630,7 @@ setup_key_helpers (struct HelperState *hs) = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_NO /* MUST BE NO! */); hs->rsadh = TALER_CRYPTO_helper_rsa_connect (TEH_cfg, + "taler", &helper_rsa_cb, hs); if (NULL == hs->rsadh) @@ -1638,6 +1639,7 @@ setup_key_helpers (struct HelperState *hs) return GNUNET_SYSERR; } hs->csdh = TALER_CRYPTO_helper_cs_connect (TEH_cfg, + "taler", &helper_cs_cb, hs); if (NULL == hs->csdh) @@ -1646,6 +1648,7 @@ setup_key_helpers (struct HelperState *hs) return GNUNET_SYSERR; } hs->esh = TALER_CRYPTO_helper_esign_connect (TEH_cfg, + "taler", &helper_esign_cb, hs); if (NULL == hs->esh) @@ -3500,64 +3503,6 @@ TEH_keys_denomination_by_hash_from_state ( enum TALER_ErrorCode -TEH_keys_denomination_sign ( - const struct TEH_CoinSignData *csd, - bool for_melt, - struct TALER_BlindedDenominationSignature *bs) -{ - struct TEH_KeyStateHandle *ksh; - struct HelperDenomination *hd; - const struct TALER_DenominationHashP *h_denom_pub = csd->h_denom_pub; - const struct TALER_BlindedPlanchet *bp = csd->bp; - - ksh = TEH_keys_get_state (); - if (NULL == ksh) - return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; - hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys, - &h_denom_pub->hash); - if (NULL == hd) - return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; - if (bp->blinded_message->cipher != - hd->denom_pub.bsign_pub_key->cipher) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - switch (hd->denom_pub.bsign_pub_key->cipher) - { - case GNUNET_CRYPTO_BSA_INVALID: - break; - case GNUNET_CRYPTO_BSA_RSA: - TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_RSA]++; - { - struct TALER_CRYPTO_RsaSignRequest rsr = { - .h_rsa = &hd->h_details.h_rsa, - .msg = bp->blinded_message->details.rsa_blinded_message.blinded_msg, - .msg_size = - bp->blinded_message->details.rsa_blinded_message.blinded_msg_size - }; - - return TALER_CRYPTO_helper_rsa_sign ( - ksh->helpers->rsadh, - &rsr, - bs); - } - case GNUNET_CRYPTO_BSA_CS: - TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_CS]++; - { - struct TALER_CRYPTO_CsSignRequest csr; - - csr.h_cs = &hd->h_details.h_cs; - csr.blinded_planchet = &bp->blinded_message->details.cs_blinded_message; - return TALER_CRYPTO_helper_cs_sign ( - ksh->helpers->csdh, - &csr, - for_melt, - bs); - } - } - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; -} - - -enum TALER_ErrorCode TEH_keys_denomination_batch_sign ( unsigned int csds_length, const struct TEH_CoinSignData csds[static csds_length], diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 5e19ac2ff..e526385ff 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -300,22 +300,7 @@ struct TEH_CoinSignData /** - * Request to sign @a csd for melting. - * - * @param csd identifies data to blindly sign and key to sign with - * @param for_melt true if this is for a melt operation - * @param[out] bs set to the blind signature on success - * @return #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TEH_keys_denomination_sign ( - const struct TEH_CoinSignData *csd, - bool for_melt, - struct TALER_BlindedDenominationSignature *bs); - - -/** - * Request to sign @a csds for melting. + * Request to sign @a csds. * * @param csds array with data to blindly sign (and keys to sign with) * @param csds_length length of @a csds array diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c b/src/exchange/taler-exchange-httpd_purses_deposit.c index 973dfccf1..8e4d5e41a 100644 --- a/src/exchange/taler-exchange-httpd_purses_deposit.c +++ b/src/exchange/taler-exchange-httpd_purses_deposit.c @@ -374,6 +374,7 @@ TEH_handler_purses_deposit ( struct GNUNET_TIME_Timestamp create_timestamp; struct GNUNET_TIME_Timestamp merge_timestamp; bool was_deleted; + bool was_refunded; qs = TEH_plugin->select_purse ( TEH_plugin->cls, @@ -384,7 +385,8 @@ TEH_handler_purses_deposit ( &pcc.deposit_total, &pcc.h_contract_terms, &merge_timestamp, - &was_deleted); + &was_deleted, + &was_refunded); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -407,7 +409,7 @@ TEH_handler_purses_deposit ( case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; /* handled below */ } - if (GNUNET_TIME_absolute_is_past (pcc.purse_expiration.abs_time) || + if (was_refunded || was_deleted) { return TALER_MHD_reply_with_error ( diff --git a/src/exchange/taler-exchange-httpd_purses_get.c b/src/exchange/taler-exchange-httpd_purses_get.c index 0701fc452..22328fe09 100644 --- a/src/exchange/taler-exchange-httpd_purses_get.c +++ b/src/exchange/taler-exchange-httpd_purses_get.c @@ -57,6 +57,12 @@ struct GetContext struct GNUNET_DB_EventHandler *eh; /** + * Subscription for refund event we are + * waiting for. + */ + struct GNUNET_DB_EventHandler *ehr; + + /** * Public key of our purse. */ struct TALER_PurseContractPublicKeyP purse_pub; @@ -153,6 +159,12 @@ gc_cleanup (struct TEH_RequestContext *rc) gc->eh); gc->eh = NULL; } + if (NULL != gc->ehr) + { + TEH_plugin->event_listen_cancel (TEH_plugin->cls, + gc->ehr); + gc->ehr = NULL; + } GNUNET_free (gc); } @@ -208,6 +220,7 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, { struct GetContext *gc = rc->rh_ctx; bool purse_deleted; + bool purse_refunded; MHD_RESULT res; if (NULL == gc) @@ -271,6 +284,20 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, GNUNET_break (0); gc->timeout = GNUNET_TIME_UNIT_ZERO_ABS; } + else + { + struct GNUNET_DB_EventHeaderP repr = { + .size = htons (sizeof (repr)), + .type = htons (TALER_DBEVENT_EXCHANGE_PURSE_REFUNDED), + }; + + gc->ehr = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (gc->timeout), + &repr, + &db_event_cb, + rc); + } } } /* end first-time initialization */ @@ -286,7 +313,8 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &gc->deposited, &gc->h_contract, &gc->merge_timestamp, - &purse_deleted); + &purse_deleted, + &purse_refunded); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -309,41 +337,12 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; /* handled below */ } - if (GNUNET_TIME_absolute_cmp (gc->timeout, - >, - gc->purse_expiration.abs_time)) - { - /* Timeout too high, need to replace event handler */ - struct TALER_PurseEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons ( - gc->wait_for_merge - ? TALER_DBEVENT_EXCHANGE_PURSE_MERGED - : TALER_DBEVENT_EXCHANGE_PURSE_DEPOSITED), - .purse_pub = gc->purse_pub - }; - struct GNUNET_DB_EventHandler *eh2; - - gc->timeout = gc->purse_expiration.abs_time; - eh2 = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (gc->timeout), - &rep.header, - &db_event_cb, - rc); - if (NULL == eh2) - { - GNUNET_break (0); - gc->timeout = GNUNET_TIME_UNIT_ZERO_ABS; - } - TEH_plugin->event_listen_cancel (TEH_plugin->cls, - gc->eh); - gc->eh = eh2; - } } - if (GNUNET_TIME_absolute_is_past (gc->purse_expiration.abs_time) || + if (purse_refunded || purse_deleted) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Purse refunded or deleted\n"); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_GONE, purse_deleted @@ -397,9 +396,11 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &gc->deposited, &exchange_pub, &exchange_sig))) + { res = TALER_MHD_reply_with_ec (rc->connection, ec, NULL); + } else { /* Make sure merge_timestamp is omitted if not yet merged */ diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index 6173ca6c9..afbbd7474 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -284,17 +284,9 @@ verify_and_execute_recoup ( TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED, NULL); } - if (GNUNET_OK != - TALER_coin_ev_hash (&blinded_planchet, - &coin->denom_pub_hash, - &pc.h_coin_ev)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL); - } + TALER_coin_ev_hash (&blinded_planchet, + &coin->denom_pub_hash, + &pc.h_coin_ev); TALER_blinded_planchet_free (&blinded_planchet); } diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c index be9723bfb..34235eb94 100644 --- a/src/exchange/taler-exchange-wirewatch.c +++ b/src/exchange/taler-exchange-wirewatch.c @@ -490,7 +490,7 @@ transaction_completed (void) latency); if (! (test_mode || GNUNET_TIME_relative_is_zero (left)) ) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, // WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Server did not respect long-polling, enforcing client-side by sleeping for %s\n", GNUNET_TIME_relative2s (left, true)); diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 89e6d9c9a..4febbfb17 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -254,18 +254,16 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_select_account_merges_above_serial_id.h pg_select_account_merges_above_serial_id.c \ pg_select_all_purse_decisions_above_serial_id.h pg_select_all_purse_decisions_above_serial_id.c \ pg_select_reserve_open_above_serial_id.c pg_select_reserve_open_above_serial_id.h -libtaler_plugin_exchangedb_postgres_la_LIBADD = \ - $(LTLIBINTL) libtaler_plugin_exchangedb_postgres_la_LDFLAGS = \ - $(TALER_PLUGIN_LDFLAGS) \ + $(TALER_PLUGIN_LDFLAGS) +libtaler_plugin_exchangedb_postgres_la_LIBADD = \ + $(LTLIBINTL) \ $(top_builddir)/src/pq/libtalerpq.la \ - $(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/util/libtalerutil.la \ - -lpq \ - -lpthread \ -lgnunetpq \ -lgnunetutil \ -ljansson \ + -lpq \ $(XLIB) lib_LTLIBRARIES = \ diff --git a/src/exchangedb/exchange_do_amount_specific.sql b/src/exchangedb/exchange_do_amount_specific.sql index e8f60f40d..9b305a3ec 100644 --- a/src/exchangedb/exchange_do_amount_specific.sql +++ b/src/exchangedb/exchange_do_amount_specific.sql @@ -1,3 +1,19 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2014--2022 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +-- + -------------------------------------------------------------- -- Taler amounts and helper functions ------------------------------------------------------------- @@ -74,5 +90,3 @@ END $$; COMMENT ON FUNCTION amount_left_minus_right IS 'Subtracts the right amount from the left and returns the difference and TRUE, if the left amount is larger than the right, or an invalid amount and FALSE otherwise.'; - - diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql index 1156c7de5..c89e9e470 100644 --- a/src/exchangedb/exchange_do_deposit.sql +++ b/src/exchangedb/exchange_do_deposit.sql @@ -42,7 +42,6 @@ AS $$ DECLARE wtsi INT8; -- wire target serial id bdsi INT8; -- batch_deposits serial id - curs REFCURSOR; i INT4; ini_amount_with_fee taler_amount; ini_coin_pub BYTEA; diff --git a/src/exchangedb/exchange_do_expire_purse.sql b/src/exchangedb/exchange_do_expire_purse.sql index 1a17869ad..ee9757f03 100644 --- a/src/exchangedb/exchange_do_expire_purse.sql +++ b/src/exchangedb/exchange_do_expire_purse.sql @@ -56,6 +56,9 @@ VALUES ,in_now ,TRUE); +-- Code for 'TALER_DBEVENT_EXCHANGE_PURSE_REFUNDED' +NOTIFY X8DJSPNYJMNZDAP7GN6YQ4EZVSQXMF3HRP4VAR347WP9SZYP1C200; + IF (my_in_reserve_quota) THEN UPDATE reserves diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql b/src/exchangedb/exchange_do_reserves_in_insert.sql index d2347bde8..1be06f063 100644 --- a/src/exchangedb/exchange_do_reserves_in_insert.sql +++ b/src/exchangedb/exchange_do_reserves_in_insert.sql @@ -30,7 +30,6 @@ RETURNS SETOF exchange_do_array_reserve_insert_return_type LANGUAGE plpgsql AS $$ DECLARE - curs REFCURSOR; conflict BOOL; dup BOOL; uuid INT8; diff --git a/src/exchangedb/perf_deposits_get_ready.c b/src/exchangedb/perf_deposits_get_ready.c index cba751e15..005ea6843 100644 --- a/src/exchangedb/perf_deposits_get_ready.c +++ b/src/exchangedb/perf_deposits_get_ready.c @@ -33,24 +33,25 @@ static int result; * Report line of error if @a cond is true, and jump to label "drop". */ #define FAILIF(cond) \ - do { \ - if (! (cond)) {break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) + do { \ + if (! (cond)) {break;} \ + GNUNET_break (0); \ + goto drop; \ + } while (0) /** * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \ + sizeof (*ptr)) /** * Initializes @a ptr with zeros. */ #define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) + memset (ptr, 0, sizeof (*ptr)) /** * Currency we use. Must match test-exchange-db-*.conf. @@ -300,10 +301,9 @@ run (void *cls) &new_dkp[cnt]->priv, true, bp)); - GNUNET_assert (GNUNET_OK == - TALER_coin_ev_hash (bp, - &cbc.denom_pub_hash, - &cbc.h_coin_envelope)); + TALER_coin_ev_hash (bp, + &cbc.denom_pub_hash, + &cbc.h_coin_envelope); GNUNET_assert ( GNUNET_OK == TALER_denom_sign_blinded ( diff --git a/src/exchangedb/perf_select_refunds_by_coin.c b/src/exchangedb/perf_select_refunds_by_coin.c index 8f2946fb8..84825d6d7 100644 --- a/src/exchangedb/perf_select_refunds_by_coin.c +++ b/src/exchangedb/perf_select_refunds_by_coin.c @@ -33,23 +33,24 @@ static int result; * Report line of error if @a cond is true, and jump to label "drop". */ #define FAILIF(cond) \ - do { \ - if (! (cond)) {break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) + do { \ + if (! (cond)) {break;} \ + GNUNET_break (0); \ + goto drop; \ + } while (0) /** * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \ + sizeof (*ptr)) /** * Initializes @a ptr with zeros. */ #define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) + memset (ptr, 0, sizeof (*ptr)) /** * Currency we use. Must match test-exchange-db-*.conf. @@ -325,10 +326,9 @@ run (void *cls) &new_dkp[cnt]->priv, true, bp)); - GNUNET_assert (GNUNET_OK == - TALER_coin_ev_hash (bp, - &cbc.denom_pub_hash, - &cbc.h_coin_envelope)); + TALER_coin_ev_hash (bp, + &cbc.denom_pub_hash, + &cbc.h_coin_envelope); GNUNET_assert ( GNUNET_OK == TALER_denom_sign_blinded ( diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c index a3653824c..39419be59 100644 --- a/src/exchangedb/pg_insert_aml_decision.c +++ b/src/exchangedb/pg_insert_aml_decision.c @@ -49,7 +49,7 @@ TEH_PG_insert_aml_decision ( .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), .h_payto = *h_payto }; - char *notify_s = GNUNET_PG_get_event_notify_channel (&rep.header); + char *notify_s = GNUNET_PQ_get_event_notify_channel (&rep.header); char *kyc_s = (NULL != kyc_requirements) ? json_dumps (kyc_requirements, JSON_COMPACT) : NULL; diff --git a/src/exchangedb/pg_insert_kyc_attributes.c b/src/exchangedb/pg_insert_kyc_attributes.c index 8b3cf84c6..3c94abb85 100644 --- a/src/exchangedb/pg_insert_kyc_attributes.c +++ b/src/exchangedb/pg_insert_kyc_attributes.c @@ -53,7 +53,7 @@ TEH_PG_insert_kyc_attributes ( .h_payto = *h_payto }; char *kyc_completed_notify_s - = GNUNET_PG_get_event_notify_channel (&rep.header); + = GNUNET_PQ_get_event_notify_channel (&rep.header); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&process_row), GNUNET_PQ_query_param_auto_from_type (h_payto), diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c index 17cb496bf..21734942a 100644 --- a/src/exchangedb/pg_reserves_in_insert.c +++ b/src/exchangedb/pg_reserves_in_insert.c @@ -51,7 +51,7 @@ compute_notify_on_reserve (const struct TALER_ReservePublicKeyP *reserve_pub) .reserve_pub = *reserve_pub }; - return GNUNET_PG_get_event_notify_channel (&rep.header); + return GNUNET_PQ_get_event_notify_channel (&rep.header); } diff --git a/src/exchangedb/pg_select_purse.c b/src/exchangedb/pg_select_purse.c index 7c0a638ac..ffccb905c 100644 --- a/src/exchangedb/pg_select_purse.c +++ b/src/exchangedb/pg_select_purse.c @@ -36,7 +36,8 @@ TEH_PG_select_purse ( struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, struct GNUNET_TIME_Timestamp *merge_timestamp, - bool *purse_deleted) + bool *purse_deleted, + bool *purse_refunded) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -60,6 +61,10 @@ TEH_PG_select_purse ( NULL), GNUNET_PQ_result_spec_bool ("purse_deleted", purse_deleted), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_bool ("purse_refunded", + purse_refunded), + NULL), GNUNET_PQ_result_spec_end }; @@ -74,11 +79,14 @@ TEH_PG_select_purse ( ",pr.balance" ",pm.merge_timestamp" ",pd.purse_sig IS NOT NULL AS purse_deleted" + ",pc.refunded AS purse_refunded" " FROM purse_requests pr" " LEFT JOIN purse_merges pm ON (pm.purse_pub = pr.purse_pub)" + " LEFT JOIN purse_decision pc ON (pc.purse_pub = pr.purse_pub)" " LEFT JOIN purse_deletion pd ON (pd.purse_pub = pr.purse_pub)" " WHERE pr.purse_pub=$1;"); *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS; + *purse_refunded = false; return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "select_purse", params, diff --git a/src/exchangedb/pg_select_purse.h b/src/exchangedb/pg_select_purse.h index db63f0c90..8f88c5cf7 100644 --- a/src/exchangedb/pg_select_purse.h +++ b/src/exchangedb/pg_select_purse.h @@ -38,6 +38,7 @@ * @param[out] h_contract_terms set to hash of the contract for the purse * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not * @param[out] purse_deleted set to true if purse was deleted + * @param[out] purse_refunded set to true if purse was refunded * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -50,7 +51,7 @@ TEH_PG_select_purse ( struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, struct GNUNET_TIME_Timestamp *merge_timestamp, - bool *purse_deleted); - + bool *purse_deleted, + bool *purse_refunded); #endif diff --git a/src/exchangedb/pg_select_purse_merge.c b/src/exchangedb/pg_select_purse_merge.c index d58e8892f..ecc047cc5 100644 --- a/src/exchangedb/pg_select_purse_merge.c +++ b/src/exchangedb/pg_select_purse_merge.c @@ -41,7 +41,6 @@ TEH_PG_select_purse_merge ( GNUNET_PQ_query_param_auto_from_type (purse_pub), GNUNET_PQ_query_param_end }; - bool is_null; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("merge_sig", merge_sig), @@ -52,7 +51,7 @@ TEH_PG_select_purse_merge ( GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("partner_base_url", partner_url), - &is_null), + NULL), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_bool ("refunded", refunded), @@ -61,19 +60,19 @@ TEH_PG_select_purse_merge ( }; *partner_url = NULL; - *refunded = true; + *refunded = false; PREPARE (pg, "select_purse_merge", "SELECT " - " reserve_pub" - ",merge_sig" - ",merge_timestamp" - ",partner_base_url" - ",refunded" - " FROM purse_merges" - " LEFT JOIN purse_decision USING (purse_pub)" - " LEFT JOIN partners USING (partner_serial_id)" - " WHERE purse_pub=$1;"); + " pm.reserve_pub" + ",pm.merge_sig" + ",pm.merge_timestamp" + ",pr.partner_base_url" + ",pd.refunded" + " FROM purse_merges pm" + " LEFT JOIN purse_decision pd USING (purse_pub)" + " LEFT JOIN partners pr USING (partner_serial_id)" + " WHERE pm.purse_pub=$1;"); return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "select_purse_merge", params, diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 489f40ed1..f96e81da7 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -34,24 +34,25 @@ static int result; * Report line of error if @a cond is true, and jump to label "drop". */ #define FAILIF(cond) \ - do { \ - if (! (cond)) { break;} \ - GNUNET_break (0); \ - goto drop; \ - } while (0) + do { \ + if (! (cond)) { break;} \ + GNUNET_break (0); \ + goto drop; \ + } while (0) /** * Initializes @a ptr with random data. */ #define RND_BLK(ptr) \ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr)) + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, \ + sizeof (*ptr)) /** * Initializes @a ptr with zeros. */ #define ZR_BLK(ptr) \ - memset (ptr, 0, sizeof (*ptr)) + memset (ptr, 0, sizeof (*ptr)) /** @@ -1383,10 +1384,9 @@ run (void *cls) alg_values, &c_hash, &pd.blinded_planchet)); - GNUNET_assert (GNUNET_OK == - TALER_coin_ev_hash (&pd.blinded_planchet, - &cbc.denom_pub_hash, - &cbc.h_coin_envelope)); + TALER_coin_ev_hash (&pd.blinded_planchet, + &cbc.denom_pub_hash, + &cbc.h_coin_envelope); if (i != 0) TALER_blinded_denom_sig_free (&cbc.sig); GNUNET_assert ( diff --git a/src/include/platform.h b/src/include/platform.h index efce84eeb..f27ee38b7 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -254,6 +254,11 @@ atoll (const char *nptr); #define EXIT_NOTRUNNING 7 #endif +#ifndef EXIT_NO_RESTART +#define EXIT_NO_RESTART 9 +#endif + + /** * clang et al do not have such an attribute */ diff --git a/src/include/taler_auditor_service.h b/src/include/taler_auditor_service.h index 409faca7d..75c3d0e25 100644 --- a/src/include/taler_auditor_service.h +++ b/src/include/taler_auditor_service.h @@ -338,108 +338,4 @@ TALER_AUDITOR_deposit_confirmation_cancel ( struct TALER_AUDITOR_DepositConfirmationHandle *deposit_confirmation); -/** - * Handle for /exchanges API returned by - * #TALER_AUDITOR_list_exchanges() so that the operation can be - * cancelled with #TALER_AUDITOR_list_exchanges_cancel() - */ -struct TALER_AUDITOR_ListExchangesHandle; - - -/** - * Information about an exchange kept by the auditor. - */ -struct TALER_AUDITOR_ExchangeInfo -{ - /** - * Master public key of the exchange. - */ - struct TALER_MasterPublicKeyP master_pub; - - /** - * Base URL of the exchange's API. - */ - const char *exchange_url; -}; - - -/** - * Response to GET /exchanges request. - */ -struct TALER_AUDITOR_ListExchangesResponse -{ - /** - * HTTP response. - */ - struct TALER_AUDITOR_HttpResponse hr; - - /** - * Details depending on HTTP status. - */ - union - { - - /** - * Details for #MHD_HTTP_OK. - */ - struct - { - - /** - * Length of the @e ei array. - */ - unsigned int num_exchanges; - - /** - * Array with information about exchanges - * audited by this auditor. - */ - const struct TALER_AUDITOR_ExchangeInfo *ei; - } ok; - } details; -}; - - -/** - * Function called with the result from /exchanges. - * - * @param cls closure - * @param ler response data - */ -typedef void -(*TALER_AUDITOR_ListExchangesResultCallback)( - void *cls, - const struct TALER_AUDITOR_ListExchangesResponse *ler); - - -/** - * Submit an /exchanges request to the auditor and get the - * auditor's response. If the auditor's reply is not - * well-formed, we return an HTTP status code of zero to @a cb. - * - * @param ctx the context for CURL requests - * @param url HTTP base URL for the auditor - * @param cb the callback to call when a reply for this request is available - * @param cb_cls closure for the above callback - * @return a handle for this request; NULL if the inputs are invalid (i.e. - * signatures fail to verify). In this case, the callback is not called. - */ -struct TALER_AUDITOR_ListExchangesHandle * -TALER_AUDITOR_list_exchanges (struct GNUNET_CURL_Context *ctx, - const char *url, - TALER_AUDITOR_ListExchangesResultCallback cb, - void *cb_cls); - - -/** - * Cancel a list exchanges request. This function cannot be used - * on a request handle if a response is already served for it. - * - * @param leh the list exchanges request handle - */ -void -TALER_AUDITOR_list_exchanges_cancel ( - struct TALER_AUDITOR_ListExchangesHandle *leh); - - #endif /* _TALER_AUDITOR_SERVICE_H */ diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index fb9e32a21..9e074a0c4 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1719,9 +1719,8 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, * @param blinded_planchet blinded planchet * @param denom_hash hash of the denomination public key * @param[out] bch where to write the hash - * @return #GNUNET_OK when successful, #GNUNET_SYSERR if an internal error occurred */ -enum GNUNET_GenericReturnValue +void TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, const struct TALER_DenominationHashP *denom_hash, struct TALER_BlindedCoinHashP *bch); @@ -2345,6 +2344,7 @@ typedef void * Initiate connection to an denomination key helper. * * @param cfg configuration to use + * @param section configuration section prefix to use, usually 'taler' or 'donau' * @param dkc function to call with key information * @param dkc_cls closure for @a dkc * @return NULL on error (such as bad @a cfg). @@ -2352,6 +2352,7 @@ typedef void struct TALER_CRYPTO_RsaDenominationHelper * TALER_CRYPTO_helper_rsa_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_RsaDenominationKeyStatusCallback dkc, void *dkc_cls); @@ -2514,6 +2515,7 @@ typedef void * Initiate connection to an denomination key helper. * * @param cfg configuration to use + * @param section configuration section prefix to use, usually 'taler' or 'donau' * @param dkc function to call with key information * @param dkc_cls closure for @a dkc * @return NULL on error (such as bad @a cfg). @@ -2521,6 +2523,7 @@ typedef void struct TALER_CRYPTO_CsDenominationHelper * TALER_CRYPTO_helper_cs_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_CsDenominationKeyStatusCallback dkc, void *dkc_cls); @@ -2734,6 +2737,7 @@ typedef void * Initiate connection to an online signing key helper. * * @param cfg configuration to use + * @param section configuration section prefix to use, usually 'taler' or 'donau' * @param ekc function to call with key information * @param ekc_cls closure for @a ekc * @return NULL on error (such as bad @a cfg). @@ -2741,6 +2745,7 @@ typedef void struct TALER_CRYPTO_ExchangeSignHelper * TALER_CRYPTO_helper_esign_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_ExchangeKeyStatusCallback ekc, void *ekc_cls); @@ -2799,15 +2804,15 @@ TALER_CRYPTO_helper_esign_sign_ ( * @return the error code (or #TALER_EC_NONE on success) */ #define TALER_CRYPTO_helper_esign_sign(esh,ps,epub,esig) ( \ - /* check size is set correctly */ \ - GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)), \ - /* check 'ps' begins with the purpose */ \ - GNUNET_static_assert (((void*) (ps)) == \ - ((void*) &(ps)->purpose)), \ - TALER_CRYPTO_helper_esign_sign_ (esh, \ - &(ps)->purpose, \ - epub, \ - esig) ) + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)), \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)), \ + TALER_CRYPTO_helper_esign_sign_ (esh, \ + &(ps)->purpose, \ + epub, \ + esig) ) /** diff --git a/src/include/taler_curl_lib.h b/src/include/taler_curl_lib.h index 04dc20b9e..f108e6158 100644 --- a/src/include/taler_curl_lib.h +++ b/src/include/taler_curl_lib.h @@ -79,4 +79,17 @@ void TALER_curl_easy_post_finished (struct TALER_CURL_PostContext *ctx); +/** + * Set a secure redirection policy, allowing a limited + * number of redirects and only going from HTTP to HTTPS + * but not from HTTPS to HTTP. + * + * @param[in,out] eh easy handle to modify + * @param url URL to base the redirect policy on; + * must start with "http://" or "https://" + */ +void +TALER_curl_set_secure_redirect_policy (CURL *eh, + const char *url); + #endif diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 3fe2efd1a..33546e008 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -6335,6 +6335,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] h_contract_terms set to hash of the contract for the purse * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not * @param[out] purse_deleted set to true if purse was deleted + * @param[out] purse_refunded set to true if purse was refunded (after expiration) * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -6347,7 +6348,8 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, struct GNUNET_TIME_Timestamp *merge_timestamp, - bool *purse_deleted); + bool *purse_deleted, + bool *purse_refunded); /** diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index a529b4302..cf9f7c02f 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -177,8 +177,9 @@ TALER_PQ_query_param_array_hash_code ( const struct GNUNET_HashCode *hashes, struct GNUNET_PQ_Context *db); + /** - * Generate query parameter for an array of mounts + * Generate query parameter for an array of amounts * * @param num of elements in @e amounts * @param amounts continuous array of amounts @@ -192,6 +193,20 @@ TALER_PQ_query_param_array_amount ( /** + * Generate query parameter for an array of amounts + * + * @param num of elements in @e amounts + * @param amounts continuous array of amounts + * @param db context for db-connection, needed for OID-lookup + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_array_amount_with_currency ( + size_t num, + const struct TALER_Amount *amounts, + struct GNUNET_PQ_Context *db); + + +/** * Generate query parameter for a blind sign public key of variable size. * * @param public_key pointer to the query parameter to pass diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 1e8ae9d8f..43923fea7 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -43,12 +43,12 @@ * quite any time after the command "run" method has been called. */ #define TALER_TESTING_FAIL(is) \ - do \ - { \ - GNUNET_break (0); \ - TALER_TESTING_interpreter_fail (is); \ - return; \ - } while (0) + do \ + { \ + GNUNET_break (0); \ + TALER_TESTING_interpreter_fail (is); \ + return; \ + } while (0) /** @@ -60,16 +60,16 @@ * @param expected expected HTTP status code */ #define TALER_TESTING_unexpected_status(is,status,expected) \ - do { \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ - "Unexpected response code %u (expected: %u) to command %s in %s:%u\n", \ - status, \ - expected, \ - TALER_TESTING_interpreter_get_current_label (is), \ - __FILE__, \ - __LINE__); \ - TALER_TESTING_interpreter_fail (is); \ - } while (0) + do { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + "Unexpected response code %u (expected: %u) to command %s in %s:%u\n", \ + status, \ + expected, \ + TALER_TESTING_interpreter_get_current_label (is), \ + __FILE__, \ + __LINE__); \ + TALER_TESTING_interpreter_fail (is); \ + } while (0) /** * Log an error message about us receiving an unexpected HTTP @@ -82,18 +82,18 @@ * @param body received JSON-reply */ #define TALER_TESTING_unexpected_status_with_body(is,status,expected,body) \ - do { \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ - "Unexpected response code %u (expected: %u) to " \ - "command %s in %s:%u\nwith body:\n>>%s<<\n", \ - status, \ - expected, \ - TALER_TESTING_interpreter_get_current_label (is), \ - __FILE__, \ - __LINE__, \ - json_dumps (body, JSON_INDENT (2))); \ - TALER_TESTING_interpreter_fail (is); \ - } while (0) + do { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + "Unexpected response code %u (expected: %u) to " \ + "command %s in %s:%u\nwith body:\n>>%s<<\n", \ + status, \ + expected, \ + TALER_TESTING_interpreter_get_current_label (is), \ + __FILE__, \ + __LINE__, \ + json_dumps (body, JSON_INDENT (2))); \ + TALER_TESTING_interpreter_fail (is); \ + } while (0) /** @@ -104,14 +104,14 @@ * @param label command label of the incomplete command */ #define TALER_TESTING_command_incomplete(is,label) \ - do { \ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ - "Command %s (%s:%u) did not complete (at %s)\n", \ - label, \ - __FILE__, \ - __LINE__, \ - TALER_TESTING_interpreter_get_current_label (is)); \ - } while (0) + do { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + "Command %s (%s:%u) did not complete (at %s)\n", \ + label, \ + __FILE__, \ + __LINE__, \ + TALER_TESTING_interpreter_get_current_label (is)); \ + } while (0) /** @@ -311,10 +311,10 @@ struct TALER_TESTING_Command * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue - (*traits)(void *cls, - const void **ret, - const char *trait, - unsigned int index); + (*traits)(void *cls, + const void **ret, + const char *trait, + unsigned int index); /** * When did the execution of this command start? @@ -831,44 +831,6 @@ TALER_TESTING_cmd_deposit_confirmation_with_retry ( /** - * Create a "list exchanges" command. - * - * @param label command label. - * @param expected_response_code expected HTTP response code. - * @return the command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges (const char *label, - unsigned int expected_response_code); - - -/** - * Create a "list exchanges" command and check whether - * a particular exchange belongs to the returned bundle. - * - * @param label command label. - * @param expected_response_code expected HTTP response code. - * @param exchange_url URL of the exchange supposed to - * be included in the response. - * @return the command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges_with_url (const char *label, - unsigned int expected_response_code, - const char *exchange_url); - -/** - * Modify an exchanges command to enable retries when we get - * transient errors from the auditor. - * - * @param cmd a deposit confirmation command - * @return the command with retries enabled - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges_with_retry (struct TALER_TESTING_Command cmd); - - -/** * Create /admin/add-incoming command. * * @param label command label. @@ -1130,14 +1092,14 @@ TALER_TESTING_cmd_batch_withdraw_with_conflict ( expected_response_code, \ amount, \ ...) \ - TALER_TESTING_cmd_batch_withdraw_with_conflict ( \ - (label), \ - (reserve_reference), \ - false, \ - (age), \ - (expected_response_code), \ - (amount), \ - __VA_ARGS__) + TALER_TESTING_cmd_batch_withdraw_with_conflict ( \ + (label), \ + (reserve_reference), \ + false, \ + (age), \ + (expected_response_code), \ + (amount), \ + __VA_ARGS__) /** * Create an age-withdraw command, letting the caller specify @@ -2267,7 +2229,7 @@ TALER_TESTING_cmd_oauth_with_birthdate (const char *label, * @param port the TCP port to listen on */ #define TALER_TESTING_cmd_oauth(label, port) \ - TALER_TESTING_cmd_oauth_with_birthdate ((label), NULL, (port)) + TALER_TESTING_cmd_oauth_with_birthdate ((label), NULL, (port)) /* ****************** P2P payment commands ****************** */ @@ -2596,13 +2558,13 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, * statically allocated data of type @a type. */ #define TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT(name,type) \ - enum GNUNET_GenericReturnValue \ - TALER_TESTING_get_trait_ ## name ( \ - const struct TALER_TESTING_Command *cmd, \ - type **ret); \ - struct TALER_TESTING_Trait \ - TALER_TESTING_make_trait_ ## name ( \ - type * value); + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + type **ret); \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + type * value); /** @@ -2610,27 +2572,27 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, * allocated data of type @a type. */ #define TALER_TESTING_MAKE_IMPL_SIMPLE_TRAIT(name,type) \ - enum GNUNET_GenericReturnValue \ - TALER_TESTING_get_trait_ ## name ( \ - const struct TALER_TESTING_Command *cmd, \ - type * *ret) \ - { \ - if (NULL == cmd->traits) return GNUNET_SYSERR; \ - return cmd->traits (cmd->cls, \ - (const void **) ret, \ - TALER_S (name), \ - 0); \ - } \ - struct TALER_TESTING_Trait \ - TALER_TESTING_make_trait_ ## name ( \ - type * value) \ - { \ - struct TALER_TESTING_Trait ret = { \ - .trait_name = TALER_S (name), \ - .ptr = (const void *) value \ - }; \ - return ret; \ - } + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + type **ret) \ + { \ + if (NULL == cmd->traits) return GNUNET_SYSERR; \ + return cmd->traits (cmd->cls, \ + (const void **) ret, \ + TALER_S (name), \ + 0); \ + } \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + type * value) \ + { \ + struct TALER_TESTING_Trait ret = { \ + .trait_name = TALER_S (name), \ + .ptr = (const void *) value \ + }; \ + return ret; \ + } /** @@ -2638,15 +2600,15 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, * statically allocated data of type @a type. */ #define TALER_TESTING_MAKE_DECL_INDEXED_TRAIT(name,type) \ - enum GNUNET_GenericReturnValue \ - TALER_TESTING_get_trait_ ## name ( \ - const struct TALER_TESTING_Command *cmd, \ - unsigned int index, \ - type **ret); \ - struct TALER_TESTING_Trait \ - TALER_TESTING_make_trait_ ## name ( \ - unsigned int index, \ - type *value); + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + unsigned int index, \ + type **ret); \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + unsigned int index, \ + type * value); /** @@ -2654,116 +2616,116 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, * allocated data of type @a type. */ #define TALER_TESTING_MAKE_IMPL_INDEXED_TRAIT(name,type) \ - enum GNUNET_GenericReturnValue \ - TALER_TESTING_get_trait_ ## name ( \ - const struct TALER_TESTING_Command *cmd, \ - unsigned int index, \ - type * *ret) \ - { \ - if (NULL == cmd->traits) return GNUNET_SYSERR; \ - return cmd->traits (cmd->cls, \ - (const void **) ret, \ - TALER_S (name), \ - index); \ - } \ - struct TALER_TESTING_Trait \ - TALER_TESTING_make_trait_ ## name ( \ - unsigned int index, \ - type * value) \ - { \ - struct TALER_TESTING_Trait ret = { \ - .index = index, \ - .trait_name = TALER_S (name), \ - .ptr = (const void *) value \ - }; \ - return ret; \ - } + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + unsigned int index, \ + type **ret) \ + { \ + if (NULL == cmd->traits) return GNUNET_SYSERR; \ + return cmd->traits (cmd->cls, \ + (const void **) ret, \ + TALER_S (name), \ + index); \ + } \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + unsigned int index, \ + type * value) \ + { \ + struct TALER_TESTING_Trait ret = { \ + .index = index, \ + .trait_name = TALER_S (name), \ + .ptr = (const void *) value \ + }; \ + return ret; \ + } /** * Call #op on all simple traits. */ #define TALER_TESTING_SIMPLE_TRAITS(op) \ - op (bank_row, const uint64_t) \ - op (officer_pub, const struct TALER_AmlOfficerPublicKeyP) \ - op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP) \ - op (officer_name, const char) \ - op (aml_decision, enum TALER_AmlDecisionState) \ - op (aml_justification, const char) \ - op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \ - op (auditor_pub, const struct TALER_AuditorPublicKeyP) \ - op (master_priv, const struct TALER_MasterPrivateKeyP) \ - op (master_pub, const struct TALER_MasterPublicKeyP) \ - op (purse_priv, const struct TALER_PurseContractPrivateKeyP) \ - op (purse_pub, const struct TALER_PurseContractPublicKeyP) \ - op (merge_priv, const struct TALER_PurseMergePrivateKeyP) \ - op (merge_pub, const struct TALER_PurseMergePublicKeyP) \ - op (contract_priv, const struct TALER_ContractDiffiePrivateP) \ - op (reserve_priv, const struct TALER_ReservePrivateKeyP) \ - op (reserve_sig, const struct TALER_ReserveSignatureP) \ - op (h_payto, const struct TALER_PaytoHashP) \ - op (planchet_secret, const struct TALER_PlanchetMasterSecretP) \ - op (refresh_secret, const struct TALER_RefreshMasterSecretP) \ - op (reserve_pub, const struct TALER_ReservePublicKeyP) \ - op (merchant_priv, const struct TALER_MerchantPrivateKeyP) \ - op (merchant_pub, const struct TALER_MerchantPublicKeyP) \ - op (merchant_sig, const struct TALER_MerchantSignatureP) \ - op (wtid, const struct TALER_WireTransferIdentifierRawP) \ - op (bank_auth_data, const struct TALER_BANK_AuthenticationData) \ - op (contract_terms, const json_t) \ - op (wire_details, const json_t) \ - op (exchange_url, const char) \ - op (auditor_url, const char) \ - op (exchange_bank_account_url, const char) \ - op (taler_uri, const char) \ - op (payto_uri, const char) \ - op (kyc_url, const char) \ - op (web_url, const char) \ - op (row, const uint64_t) \ - op (legi_requirement_row, const uint64_t) \ - op (array_length, const unsigned int) \ - op (credit_payto_uri, const char) \ - op (debit_payto_uri, const char) \ - op (order_id, const char) \ - op (amount, const struct TALER_Amount) \ - op (amount_with_fee, const struct TALER_Amount) \ - op (batch_cmds, struct TALER_TESTING_Command) \ - op (uuid, const struct GNUNET_Uuid) \ - op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \ - op (claim_token, const struct TALER_ClaimTokenP) \ - op (relative_time, const struct GNUNET_TIME_Relative) \ - op (fakebank, struct TALER_FAKEBANK_Handle) \ - op (keys, struct TALER_EXCHANGE_Keys) \ - op (process, struct GNUNET_OS_Process *) + op (bank_row, const uint64_t) \ + op (officer_pub, const struct TALER_AmlOfficerPublicKeyP) \ + op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP) \ + op (officer_name, const char) \ + op (aml_decision, enum TALER_AmlDecisionState) \ + op (aml_justification, const char) \ + op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \ + op (auditor_pub, const struct TALER_AuditorPublicKeyP) \ + op (master_priv, const struct TALER_MasterPrivateKeyP) \ + op (master_pub, const struct TALER_MasterPublicKeyP) \ + op (purse_priv, const struct TALER_PurseContractPrivateKeyP) \ + op (purse_pub, const struct TALER_PurseContractPublicKeyP) \ + op (merge_priv, const struct TALER_PurseMergePrivateKeyP) \ + op (merge_pub, const struct TALER_PurseMergePublicKeyP) \ + op (contract_priv, const struct TALER_ContractDiffiePrivateP) \ + op (reserve_priv, const struct TALER_ReservePrivateKeyP) \ + op (reserve_sig, const struct TALER_ReserveSignatureP) \ + op (h_payto, const struct TALER_PaytoHashP) \ + op (planchet_secret, const struct TALER_PlanchetMasterSecretP) \ + op (refresh_secret, const struct TALER_RefreshMasterSecretP) \ + op (reserve_pub, const struct TALER_ReservePublicKeyP) \ + op (merchant_priv, const struct TALER_MerchantPrivateKeyP) \ + op (merchant_pub, const struct TALER_MerchantPublicKeyP) \ + op (merchant_sig, const struct TALER_MerchantSignatureP) \ + op (wtid, const struct TALER_WireTransferIdentifierRawP) \ + op (bank_auth_data, const struct TALER_BANK_AuthenticationData) \ + op (contract_terms, const json_t) \ + op (wire_details, const json_t) \ + op (exchange_url, const char) \ + op (auditor_url, const char) \ + op (exchange_bank_account_url, const char) \ + op (taler_uri, const char) \ + op (payto_uri, const char) \ + op (kyc_url, const char) \ + op (web_url, const char) \ + op (row, const uint64_t) \ + op (legi_requirement_row, const uint64_t) \ + op (array_length, const unsigned int) \ + op (credit_payto_uri, const char) \ + op (debit_payto_uri, const char) \ + op (order_id, const char) \ + op (amount, const struct TALER_Amount) \ + op (amount_with_fee, const struct TALER_Amount) \ + op (batch_cmds, struct TALER_TESTING_Command) \ + op (uuid, const struct GNUNET_Uuid) \ + op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \ + op (claim_token, const struct TALER_ClaimTokenP) \ + op (relative_time, const struct GNUNET_TIME_Relative) \ + op (fakebank, struct TALER_FAKEBANK_Handle) \ + op (keys, struct TALER_EXCHANGE_Keys) \ + op (process, struct GNUNET_OS_Process *) /** * Call #op on all indexed traits. */ #define TALER_TESTING_INDEXED_TRAITS(op) \ - op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \ - op (denom_sig, const struct TALER_DenominationSignature) \ - op (amounts, const struct TALER_Amount) \ - op (deposit_amount, const struct TALER_Amount) \ - op (deposit_fee_amount, const struct TALER_Amount) \ - op (age_commitment, const struct TALER_AgeCommitment) \ - op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \ - op (h_age_commitment, const struct TALER_AgeCommitmentHash) \ - op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \ - op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \ - op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ - op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \ - op (coin_priv, const struct TALER_CoinSpendPrivateKeyP) \ - op (coin_pub, const struct TALER_CoinSpendPublicKeyP) \ - op (coin_sig, const struct TALER_CoinSpendSignatureP) \ - op (absolute_time, const struct GNUNET_TIME_Absolute) \ - op (timestamp, const struct GNUNET_TIME_Timestamp) \ - op (wire_deadline, const struct GNUNET_TIME_Timestamp) \ - op (refund_deadline, const struct GNUNET_TIME_Timestamp) \ - op (exchange_pub, const struct TALER_ExchangePublicKeyP) \ - op (exchange_sig, const struct TALER_ExchangeSignatureP) \ - op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP) \ - op (h_blinded_coin, const struct TALER_BlindedCoinHashP) + op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \ + op (denom_sig, const struct TALER_DenominationSignature) \ + op (amounts, const struct TALER_Amount) \ + op (deposit_amount, const struct TALER_Amount) \ + op (deposit_fee_amount, const struct TALER_Amount) \ + op (age_commitment, const struct TALER_AgeCommitment) \ + op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \ + op (h_age_commitment, const struct TALER_AgeCommitmentHash) \ + op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \ + op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \ + op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ + op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \ + op (coin_priv, const struct TALER_CoinSpendPrivateKeyP) \ + op (coin_pub, const struct TALER_CoinSpendPublicKeyP) \ + op (coin_sig, const struct TALER_CoinSpendSignatureP) \ + op (absolute_time, const struct GNUNET_TIME_Absolute) \ + op (timestamp, const struct GNUNET_TIME_Timestamp) \ + op (wire_deadline, const struct GNUNET_TIME_Timestamp) \ + op (refund_deadline, const struct GNUNET_TIME_Timestamp) \ + op (exchange_pub, const struct TALER_ExchangePublicKeyP) \ + op (exchange_sig, const struct TALER_ExchangeSignatureP) \ + op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP) \ + op (h_blinded_coin, const struct TALER_BlindedCoinHashP) TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT) diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c index d7fddab4b..6c8ced55d 100644 --- a/src/kyclogic/plugin_kyclogic_kycaid.c +++ b/src/kyclogic/plugin_kyclogic_kycaid.c @@ -1205,7 +1205,7 @@ kycaid_webhook (void *cls, CURL *eh; const char *request_id; const char *type; - const char *verification_id; + const char *verification_id; /* = provider_legitimization_id */ const char *applicant_id; const char *form_id; const char *status = NULL; @@ -1304,7 +1304,7 @@ kycaid_webhook (void *cls, if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Received webhook for unknown verification ID `%s' and section %s\n", + "Received webhook for unknown verification ID `%s' and section `%s'\n", verification_id, pd->section); wh->resp = TALER_MHD_make_error ( diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c index 7c57b5ae1..53b03e1eb 100644 --- a/src/kyclogic/plugin_kyclogic_oauth2.c +++ b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -1060,6 +1060,15 @@ handle_curl_proof_finished (void *cls, ph->job = NULL; switch (response_code) { + case 0: + ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; + ph->response + = TALER_MHD_make_error ( + TALER_EC_EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE, + "No response from KYC gateway"); + ph->http_status + = MHD_HTTP_BAD_GATEWAY; + break; case MHD_HTTP_OK: parse_proof_success_reply (ph, j); @@ -1304,13 +1313,19 @@ oauth2_proof (void *cls, ph); return ph; } - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Requesting OAuth 2.0 data via HTTP POST `%s'\n", + pd->token_url); GNUNET_assert (CURLE_OK == curl_easy_setopt (ph->eh, CURLOPT_URL, pd->token_url)); GNUNET_assert (CURLE_OK == curl_easy_setopt (ph->eh, + CURLOPT_VERBOSE, + 1)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (ph->eh, CURLOPT_POST, 1)); { diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 1291fd3a4..5d4f54b53 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -75,7 +75,7 @@ libtalerexchange_la_SOURCES = \ exchange_api_reserves_history.c \ exchange_api_reserves_open.c \ exchange_api_stefan.c \ - exchange_api_transfers_get.c + exchange_api_transfers_get.c libtalerexchange_la_LIBADD = \ libtalerauditor.la \ $(top_builddir)/src/json/libtalerjson.la \ @@ -97,8 +97,7 @@ libtalerauditor_la_LDFLAGS = \ libtalerauditor_la_SOURCES = \ auditor_api_curl_defaults.c auditor_api_curl_defaults.h \ auditor_api_get_config.c \ - auditor_api_deposit_confirmation.c \ - auditor_api_exchanges.c + auditor_api_deposit_confirmation.c libtalerauditor_la_LIBADD = \ $(top_builddir)/src/curl/libtalercurl.la \ $(top_builddir)/src/json/libtalerjson.la \ diff --git a/src/lib/auditor_api_curl_defaults.c b/src/lib/auditor_api_curl_defaults.c index 81fcd7bac..972f28ca6 100644 --- a/src/lib/auditor_api_curl_defaults.c +++ b/src/lib/auditor_api_curl_defaults.c @@ -19,6 +19,8 @@ * @brief curl easy handle defaults * @author Florian Dold */ +#include "platform.h" +#include "taler_curl_lib.h" #include "auditor_api_curl_defaults.h" @@ -37,22 +39,14 @@ TALER_AUDITOR_curl_easy_get_ (const char *url) curl_easy_setopt (eh, CURLOPT_URL, url)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_FOLLOWLOCATION, - 1L)); + TALER_curl_set_secure_redirect_policy (eh, + url); /* Enable compression (using whatever curl likes), see https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */ GNUNET_break (CURLE_OK == curl_easy_setopt (eh, CURLOPT_ACCEPT_ENCODING, "")); - /* limit MAXREDIRS to 5 as a simple security measure against - a potential infinite loop caused by a malicious target */ - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_MAXREDIRS, - 5L)); GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TCP_FASTOPEN, diff --git a/src/lib/auditor_api_exchanges.c b/src/lib/auditor_api_exchanges.c deleted file mode 100644 index 1988c2faf..000000000 --- a/src/lib/auditor_api_exchanges.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-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 - <http://www.gnu.org/licenses/> -*/ -/** - * @file lib/auditor_api_exchanges.c - * @brief Implementation of the /exchanges request of the auditor's HTTP API - * @author Christian Grothoff - */ -#include "platform.h" -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_json_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include "taler_json_lib.h" -#include "taler_auditor_service.h" -#include "taler_util.h" -#include "taler_curl_lib.h" -#include "taler_signatures.h" -#include "auditor_api_curl_defaults.h" - -/** - * How many exchanges do we allow a single auditor to - * audit at most? - */ -#define MAX_EXCHANGES 1024 - - -/** - * @brief A ListExchanges Handle - */ -struct TALER_AUDITOR_ListExchangesHandle -{ - - /** - * The url for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_AUDITOR_ListExchangesResultCallback cb; - - /** - * Closure for @a cb. - */ - void *cb_cls; - -}; - - -/** - * Function called when we're done processing the - * HTTP /exchanges request. - * - * @param cls the `struct TALER_AUDITOR_ListExchangesHandle` - * @param response_code HTTP response code, 0 on error - * @param djson parsed JSON result, NULL on error - */ -static void -handle_exchanges_finished (void *cls, - long response_code, - const void *djson) -{ - const json_t *json = djson; - const json_t *ja; - unsigned int ja_len; - struct TALER_AUDITOR_ListExchangesHandle *leh = cls; - struct TALER_AUDITOR_ListExchangesResponse ler = { - .hr.reply = json, - .hr.http_status = (unsigned int) response_code - }; - - leh->job = NULL; - switch (response_code) - { - case 0: - ler.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - ja = json_object_get (json, - "exchanges"); - if ( (NULL == ja) || - (! json_is_array (ja)) ) - { - GNUNET_break (0); - ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - ler.hr.http_status = 0; - break; - } - - ja_len = json_array_size (ja); - if (ja_len > MAX_EXCHANGES) - { - GNUNET_break (0); - ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - ler.hr.http_status = 0; - break; - } - { - struct TALER_AUDITOR_ExchangeInfo ei[GNUNET_NZL (ja_len)]; - bool ok = true; - - for (unsigned int i = 0; i<ja_len; i++) - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("master_pub", - &ei[i].master_pub), - TALER_JSON_spec_web_url ("exchange_url", - &ei[i].exchange_url), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (ja, - i), - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - ok = false; - ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - ler.hr.http_status = 0; - break; - } - } - if (! ok) - break; - ler.details.ok.ei = ei; - ler.details.ok.num_exchanges = ja_len; - leh->cb (leh->cb_cls, - &ler); - TALER_AUDITOR_list_exchanges_cancel (leh); - return; - } - case MHD_HTTP_BAD_REQUEST: - /* This should never happen, either us or the auditor is buggy - (or API version conflict); just pass JSON reply to the application */ - ler.hr.ec = TALER_JSON_get_error_code (json); - ler.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the application */ - ler.hr.ec = TALER_JSON_get_error_code (json); - ler.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ - ler.hr.ec = TALER_JSON_get_error_code (json); - ler.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - /* unexpected response code */ - ler.hr.ec = TALER_JSON_get_error_code (json); - ler.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for auditor list-exchanges request\n", - (unsigned int) response_code, - (int) ler.hr.ec); - GNUNET_break_op (0); - break; - } - if (NULL != leh->cb) - leh->cb (leh->cb_cls, - &ler); - TALER_AUDITOR_list_exchanges_cancel (leh); -} - - -struct TALER_AUDITOR_ListExchangesHandle * -TALER_AUDITOR_list_exchanges (struct GNUNET_CURL_Context *ctx, - const char *url, - TALER_AUDITOR_ListExchangesResultCallback cb, - void *cb_cls) -{ - struct TALER_AUDITOR_ListExchangesHandle *leh; - CURL *eh; - - leh = GNUNET_new (struct TALER_AUDITOR_ListExchangesHandle); - leh->cb = cb; - leh->cb_cls = cb_cls; - leh->url = TALER_url_join (url, - "exchanges", - NULL); - if (NULL == leh->url) - { - GNUNET_free (leh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "URL for list-exchanges: `%s'\n", - leh->url); - eh = TALER_AUDITOR_curl_easy_get_ (leh->url); - if (NULL == eh) - { - GNUNET_break (0); - GNUNET_free (leh->url); - GNUNET_free (leh); - return NULL; - } - leh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_exchanges_finished, - leh); - return leh; -} - - -void -TALER_AUDITOR_list_exchanges_cancel ( - struct TALER_AUDITOR_ListExchangesHandle *leh) -{ - if (NULL != leh->job) - { - GNUNET_CURL_job_cancel (leh->job); - leh->job = NULL; - } - GNUNET_free (leh->url); - GNUNET_free (leh); -} - - -/* end of auditor_api_exchanges.c */ diff --git a/src/lib/auditor_api_get_config.c b/src/lib/auditor_api_get_config.c index 5d0b4db81..8f865a608 100644 --- a/src/lib/auditor_api_get_config.c +++ b/src/lib/auditor_api_get_config.c @@ -235,7 +235,6 @@ TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx, if (NULL == auditor->vr_url) { GNUNET_break (0); - GNUNET_free (auditor->vr_url); GNUNET_free (auditor); return NULL; } diff --git a/src/lib/exchange_api_age_withdraw.c b/src/lib/exchange_api_age_withdraw.c index e319332d1..8f8d2b2b0 100644 --- a/src/lib/exchange_api_age_withdraw.c +++ b/src/lib/exchange_api_age_withdraw.c @@ -500,15 +500,15 @@ perform_protocol ( struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh) { #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto ERROR; \ - } \ - } while(0) - - struct GNUNET_HashContext *coins_hctx; + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto ERROR; \ + } \ + } while (0) + + struct GNUNET_HashContext *coins_hctx = NULL; json_t *j_denoms = NULL; json_t *j_array_candidates = NULL; json_t *j_request_body = NULL; @@ -567,7 +567,7 @@ perform_protocol ( GNUNET_JSON_pack_data_auto (NULL, denom_h)); FAIL_IF (NULL == jdenom); - FAIL_IF (0 < json_array_append_new (j_denoms, + FAIL_IF (0 > json_array_append_new (j_denoms, jdenom)); /* Build the candidate array */ @@ -586,7 +586,7 @@ perform_protocol ( &planchet->blinded_planchet)); FAIL_IF (NULL == jc); - FAIL_IF (0 < json_array_append_new (j_can, + FAIL_IF (0 > json_array_append_new (j_can, jc)); TALER_coin_ev_hash (&planchet->blinded_planchet, @@ -598,7 +598,7 @@ perform_protocol ( sizeof(bch)); } - FAIL_IF (0 < json_array_append_new (j_array_candidates, + FAIL_IF (0 > json_array_append_new (j_array_candidates, j_can)); } } @@ -607,6 +607,7 @@ perform_protocol ( /* Build the hash of the commitment */ GNUNET_CRYPTO_hash_context_finish (coins_hctx, &awbh->h_commitment.hash); + coins_hctx = NULL; /* Sign the request */ TALER_wallet_age_withdraw_sign (&awbh->h_commitment, @@ -653,6 +654,8 @@ ERROR: json_decref (j_request_body); if (NULL != curlh) curl_easy_cleanup (curlh); + if (NULL != coins_hctx) + GNUNET_CRYPTO_hash_context_abort (coins_hctx); TALER_EXCHANGE_age_withdraw_blinded_cancel (awbh); return; #undef FAIL_IF @@ -685,12 +688,8 @@ copy_results ( .num_coins = awh->num_coins, .coin_details = details, .blinded_coin_hs = blinded_coin_hs - } - - - } - - + }, + }, }; for (size_t n = 0; n< awh->num_coins; n++) @@ -838,21 +837,14 @@ csr_withdraw_done ( planchet)) { GNUNET_break (0); - TALER_EXCHANGE_age_withdraw_cancel (awh); break; } - if (GNUNET_OK != - TALER_coin_ev_hash (&planchet->blinded_planchet, - &planchet->denom_pub_hash, - &can->blinded_coin_h)) - { - GNUNET_break (0); - TALER_EXCHANGE_age_withdraw_cancel (awh); - break; - } + TALER_coin_ev_hash (&planchet->blinded_planchet, + &planchet->denom_pub_hash, + &can->blinded_coin_h); success = true; - } while(0); + } while (0); awh->csr.pending--; @@ -890,13 +882,13 @@ prepare_coins ( static num_coins]) { #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto ERROR; \ - } \ - } while(0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto ERROR; \ + } \ + } while (0) GNUNET_assert (0 < num_coins); awh->age_mask = coin_inputs[0].denom_pub->key.age_mask; @@ -952,10 +944,9 @@ prepare_coins ( &can->details.h_age_commitment, &can->details.h_coin_pub, planchet)); - FAIL_IF (GNUNET_OK != - TALER_coin_ev_hash (&planchet->blinded_planchet, - &planchet->denom_pub_hash, - &can->blinded_coin_h)); + TALER_coin_ev_hash (&planchet->blinded_planchet, + &planchet->denom_pub_hash, + &can->blinded_coin_h); break; case GNUNET_CRYPTO_BSA_CS: { @@ -1025,7 +1016,10 @@ TALER_EXCHANGE_age_withdraw ( if (GNUNET_OK != prepare_coins (awh, num_coins, coin_inputs)) + { + GNUNET_free (awh); return NULL; + } /* If there were no CS denominations, we can now perform the actual * age-withdraw protocol. Otherwise, there are calls to /csr-withdraw diff --git a/src/lib/exchange_api_age_withdraw_reveal.c b/src/lib/exchange_api_age_withdraw_reveal.c index a448d109d..cade528d2 100644 --- a/src/lib/exchange_api_age_withdraw_reveal.c +++ b/src/lib/exchange_api_age_withdraw_reveal.c @@ -57,7 +57,7 @@ struct TALER_EXCHANGE_AgeWithdrawRevealHandle const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coins_input; /* The url for the reveal request */ - const char *request_url; + char *request_url; /** * CURL handle for the request job. @@ -146,6 +146,9 @@ age_withdraw_reveal_ok ( &response); /* Make sure the callback isn't called again */ awrh->callback = NULL; + /* Free resources */ + for (size_t i = 0; i < awrh->num_coins; i++) + TALER_blinded_denom_sig_free (&denom_sigs[i]); } return GNUNET_OK; @@ -340,13 +343,13 @@ perform_protocol ( json_t *j_sec = NULL; #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto ERROR; \ - } \ - } while(0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto ERROR; \ + } \ + } while (0) j_array_of_secrets = json_array (); FAIL_IF (NULL == j_array_of_secrets); @@ -463,7 +466,10 @@ TALER_EXCHANGE_age_withdraw_reveal_cancel ( awrh->job = NULL; } TALER_curl_easy_post_finished (&awrh->post_ctx); - /* FIXME[oec]: anything else left to cleanup!? */ + + if (NULL != awrh->request_url) + GNUNET_free (awrh->request_url); + GNUNET_free (awrh); } diff --git a/src/lib/exchange_api_batch_withdraw2.c b/src/lib/exchange_api_batch_withdraw2.c index b6f773197..453d8a0ab 100644 --- a/src/lib/exchange_api_batch_withdraw2.c +++ b/src/lib/exchange_api_batch_withdraw2.c @@ -373,16 +373,9 @@ TALER_EXCHANGE_batch_withdraw2 ( json_decref (jc); return NULL; } - if (GNUNET_OK != - TALER_coin_ev_hash (&pd->blinded_planchet, - &pd->denom_pub_hash, - &bch)) - { - GNUNET_break (0); - TALER_EXCHANGE_batch_withdraw2_cancel (wh); - json_decref (jc); - return NULL; - } + TALER_coin_ev_hash (&pd->blinded_planchet, + &pd->denom_pub_hash, + &bch); TALER_wallet_withdraw_sign (&pd->denom_pub_hash, &coin_total, &bch, diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c index 9627db9ff..85a32189b 100644 --- a/src/lib/exchange_api_curl_defaults.c +++ b/src/lib/exchange_api_curl_defaults.c @@ -19,7 +19,8 @@ * @brief curl easy handle defaults * @author Florian Dold */ - +#include "platform.h" +#include "taler_curl_lib.h" #include "exchange_api_curl_defaults.h" @@ -38,22 +39,14 @@ TALER_EXCHANGE_curl_easy_get_ (const char *url) curl_easy_setopt (eh, CURLOPT_URL, url)); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_FOLLOWLOCATION, - 1L)); + TALER_curl_set_secure_redirect_policy (eh, + url); /* Enable compression (using whatever curl likes), see https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */ GNUNET_break (CURLE_OK == curl_easy_setopt (eh, CURLOPT_ACCEPT_ENCODING, "")); - /* limit MAXREDIRS to 5 as a simple security measure against - a potential infinite loop caused by a malicious target */ - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_MAXREDIRS, - 5L)); GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TCP_FASTOPEN, diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h index 735528ae1..1562646ff 100644 --- a/src/pq/pq_common.h +++ b/src/pq/pq_common.h @@ -45,13 +45,20 @@ enum TALER_PQ_ArrayType TALER_PQ_array_of_blinded_coin_hash, TALER_PQ_array_of_denom_hash, TALER_PQ_array_of_hash_code, + /** * Amounts *without* currency. */ TALER_PQ_array_of_amount, + + /** + * Amounts *with* currency. + */ + TALER_PQ_array_of_amount_currency, TALER_PQ_array_of_MAX, /* must be last */ }; + /** * Memory representation of an taler amount record for Postgres. * diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index d8655db08..d25b3223e 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -846,14 +846,14 @@ qconv_array ( same_sized = (0 != meta->same_size); #define RETURN_UNLESS(cond) \ - do { \ - if (! (cond)) \ - { \ - GNUNET_break ((cond)); \ - noerror = false; \ - goto DONE; \ - } \ - } while (0) + do { \ + if (! (cond)) \ + { \ + GNUNET_break ((cond)); \ + noerror = false; \ + goto DONE; \ + } \ + } while (0) /* Calculate sizes and check bounds */ { @@ -881,6 +881,46 @@ qconv_array ( { switch (meta->typ) { + case TALER_PQ_array_of_amount_currency: + { + const struct TALER_Amount *amounts = data; + Oid oid_v; + Oid oid_f; + Oid oid_c; + + buffer_lengths = GNUNET_new_array (num, size_t); + /* hoist out of loop? */ + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "int8", + &oid_v)); + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "int4", + &oid_f)); + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "varchar", + &oid_c)); + for (size_t i = 0; i<num; i++) + { + struct TALER_PQ_AmountCurrencyP am; + size_t len; + + len = TALER_PQ_make_taler_pq_amount_currency_ ( + &amounts[i], + oid_v, + oid_f, + oid_c, + &am); + buffer_lengths[i] = len; + y = total_size; + total_size += len; + RETURN_UNLESS (total_size >= y); + } + sizes = buffer_lengths; + break; + } case TALER_PQ_array_of_blinded_denom_sig: { const struct TALER_BlindedDenominationSignature *denom_sigs = data; @@ -963,6 +1003,7 @@ qconv_array ( Oid oid_v; Oid oid_f; + /* hoist out of loop? */ GNUNET_assert (GNUNET_OK == GNUNET_PQ_get_oid_by_name (meta->db, "int8", @@ -984,6 +1025,42 @@ qconv_array ( } break; } + case TALER_PQ_array_of_amount_currency: + { + const struct TALER_Amount *amounts = data; + Oid oid_v; + Oid oid_f; + Oid oid_c; + + /* hoist out of loop? */ + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "int8", + &oid_v)); + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "int4", + &oid_f)); + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (meta->db, + "varchar", + &oid_c)); + { + struct TALER_PQ_AmountCurrencyP am; + size_t len; + + len = TALER_PQ_make_taler_pq_amount_currency_ ( + &amounts[i], + oid_v, + oid_f, + oid_c, + &am); + GNUNET_memcpy (out, + &am, + len); + } + break; + } case TALER_PQ_array_of_blinded_denom_sig: { const struct TALER_BlindedDenominationSignature *denom_sigs = data; @@ -1099,6 +1176,7 @@ query_param_array_generic ( struct GNUNET_PQ_Context *db) { struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls); + meta->typ = typ; meta->oid = oid; meta->sizes = sizes; @@ -1106,16 +1184,18 @@ query_param_array_generic ( meta->continuous = continuous; meta->db = db; - struct GNUNET_PQ_QueryParam res = { - .conv = qconv_array, - .conv_cls = meta, - .conv_cls_cleanup = qconv_array_cls_cleanup, - .data = elements, - .size = num, - .num_params = 1, - }; + { + struct GNUNET_PQ_QueryParam res = { + .conv = qconv_array, + .conv_cls = meta, + .conv_cls_cleanup = qconv_array_cls_cleanup, + .data = elements, + .size = num, + .num_params = 1, + }; - return res; + return res; + } } @@ -1126,8 +1206,11 @@ TALER_PQ_query_param_array_blinded_denom_sig ( struct GNUNET_PQ_Context *db) { Oid oid; + GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "bytea", &oid)); + GNUNET_PQ_get_oid_by_name (db, + "bytea", + &oid)); return query_param_array_generic (num, true, denom_sigs, @@ -1146,8 +1229,11 @@ TALER_PQ_query_param_array_blinded_coin_hash ( struct GNUNET_PQ_Context *db) { Oid oid; + GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "bytea", &oid)); + GNUNET_PQ_get_oid_by_name (db, + "bytea", + &oid)); return query_param_array_generic (num, true, coin_hs, @@ -1166,8 +1252,11 @@ TALER_PQ_query_param_array_denom_hash ( struct GNUNET_PQ_Context *db) { Oid oid; + GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "bytea", &oid)); + GNUNET_PQ_get_oid_by_name (db, + "bytea", + &oid)); return query_param_array_generic (num, true, denom_hs, @@ -1206,8 +1295,11 @@ TALER_PQ_query_param_array_amount ( struct GNUNET_PQ_Context *db) { Oid oid; + GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "taler_amount", &oid)); + GNUNET_PQ_get_oid_by_name (db, + "taler_amount", + &oid)); return query_param_array_generic ( num, true, @@ -1220,6 +1312,30 @@ TALER_PQ_query_param_array_amount ( } +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_array_amount_with_currency ( + size_t num, + const struct TALER_Amount *amounts, + struct GNUNET_PQ_Context *db) +{ + Oid oid; + + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (db, + "taler_amount_currency", + &oid)); + return query_param_array_generic ( + num, + true, + amounts, + NULL, + 0, /* currency is technically variable length */ + TALER_PQ_array_of_amount_currency, + oid, + db); +} + + /** * Function called to convert input argument into SQL parameters. * @@ -1300,6 +1416,7 @@ qconv_blind_sign_pub (void *cls, return 1; } + /** * Generate query parameter for a blind sign public key of variable size. * diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index ae713ab67..f1e7f1cce 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -45,7 +45,6 @@ libtalertesting_la_SOURCES = \ testing_api_cmd_auditor_add.c \ testing_api_cmd_auditor_del.c \ testing_api_cmd_auditor_deposit_confirmation.c \ - testing_api_cmd_auditor_exchanges.c \ testing_api_cmd_auditor_exec_auditor.c \ testing_api_cmd_auditor_exec_auditor_dbinit.c \ testing_api_cmd_bank_admin_add_incoming.c \ diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh index 833357ccb..ca58d9835 100755 --- a/src/testing/taler-unified-setup.sh +++ b/src/testing/taler-unified-setup.sh @@ -1,7 +1,7 @@ #!/bin/bash # # This file is part of TALER -# Copyright (C) 2023 Taler Systems SA +# Copyright (C) 2023, 2024 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 @@ -67,6 +67,7 @@ START_AUDITOR=0 START_BACKUP=0 START_EXCHANGE=0 START_FAKEBANK=0 +START_DONAU=0 START_CHALLENGER=0 START_AGGREGATOR=0 START_MERCHANT=0 @@ -74,6 +75,8 @@ START_NEXUS=0 START_BANK=0 START_TRANSFER=0 START_WIREWATCH=0 +START_DEPOSITCHECK=0 +START_MERCHANT_EXCHANGE=0 USE_ACCOUNT="exchange-account-1" USE_VALGRIND="" WIRE_DOMAIN="x-taler-bank" @@ -82,7 +85,7 @@ LOGLEVEL="DEBUG" DEFAULT_SLEEP="0.2" # Parse command-line options -while getopts ':abc:d:efghkL:mnr:stu:vwW' OPTION; do +while getopts ':abc:d:DeEfghkL:mMnr:stu:vwW' OPTION; do case "$OPTION" in a) START_AUDITOR="1" @@ -96,9 +99,15 @@ while getopts ':abc:d:efghkL:mnr:stu:vwW' OPTION; do d) WIRE_DOMAIN="$OPTARG" ;; + D) + START_DONAU="1" + ;; e) START_EXCHANGE="1" ;; + E) + START_MERCHANT_EXCHANGE="1" + ;; f) START_FAKEBANK="1" ;; @@ -110,22 +119,26 @@ while getopts ':abc:d:efghkL:mnr:stu:vwW' OPTION; do echo ' -c $CONF -- set configuration' # shellcheck disable=SC2016 echo ' -d $METHOD -- use wire method (default: x-taler-bank)' + echo ' -D -- start donau' echo ' -e -- start exchange' + echo ' -E -- start taler-merchant-exchange' echo ' -f -- start fakebank' - echo ' -g -- start aggregator' + echo ' -g -- start taler-exchange-aggregator' echo ' -h -- print this help' # shellcheck disable=SC2016 echo ' -L $LOGLEVEL -- set log level' - echo ' -m -- start merchant' + echo ' -m -- start taler-merchant' + echo ' -M -- start taler-merchant-depositcheck' echo ' -n -- start nexus' # shellcheck disable=SC2016 echo ' -r $MEX -- which exchange to use at the merchant (optional)' echo ' -s -- start backup/sync' - echo ' -t -- start transfer' + echo ' -t -- start taler-exchange-transfer' # shellcheck disable=SC2016 echo ' -u $SECTION -- exchange account to use' echo ' -v -- use valgrind' - echo ' -w -- start wirewatch' + echo ' -w -- start taler-exchange-wirewatch' + echo ' -W -- wait for signal' exit 0 ;; g) @@ -140,6 +153,9 @@ while getopts ':abc:d:efghkL:mnr:stu:vwW' OPTION; do m) START_MERCHANT="1" ;; + M) + START_DEPOSITCHECK="1" + ;; n) START_NEXUS="1" ;; @@ -186,6 +202,13 @@ then echo " FOUND" fi +if [ "1" = "$START_DONAU" ] +then + echo -n "Testing for Donau" + donau-httpd -h > /dev/null || exit_skip " donau-httpd required" + echo " FOUND" +fi + if [ "1" = "$START_MERCHANT" ] then echo -n "Testing for Taler merchant" @@ -446,10 +469,40 @@ then taler-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY -V "$MASTER_PUB" fi taler-exchange-dbinit -c "$CONF" --reset - $USE_VALGRIND taler-exchange-secmod-eddsa -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-secmod-eddsa.log & - $USE_VALGRIND taler-exchange-secmod-rsa -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-secmod-rsa.log & - $USE_VALGRIND taler-exchange-secmod-cs -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-secmod-cs.log & - $USE_VALGRIND taler-exchange-httpd -c "$CONF" -L "$LOGLEVEL" 2> taler-exchange-httpd.log & + $USE_VALGRIND taler-exchange-secmod-eddsa \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> taler-exchange-secmod-eddsa.log & + $USE_VALGRIND taler-exchange-secmod-rsa \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> taler-exchange-secmod-rsa.log & + $USE_VALGRIND taler-exchange-secmod-cs \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> taler-exchange-secmod-cs.log & + $USE_VALGRIND taler-exchange-httpd \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-exchange-httpd.log & + echo " DONE" +fi + +if [ "1" = "$START_DONAU" ] +then + echo -n "Starting Donau ..." + DONAU_PORT=$(donau-config -c "$CONF" -s DONAU -o PORT) + SERVE=$(donau-config -c "$CONF" -s DONAU -o SERVE) + if [ "${SERVE}" = "unix" ] + then + DONAU_URL=$(donau-config -c "$CONF" -s DONAU -o BASE_URL) + else + DONAU_URL="http://localhost:${DONAU_PORT}/" + fi + donau-dbinit -c "$CONF" --reset + $USE_VALGRIND taler-secmod-eddsa -c "$CONF" -L "$LOGLEVEL" -s donau 2> donau-secmod-eddsa.log & + $USE_VALGRIND taler-secmod-rsa -c "$CONF" -L "$LOGLEVEL" -s donau 2> donau-secmod-rsa.log & + $USE_VALGRIND taler-secmod-cs -c "$CONF" -L "$LOGLEVEL" -s donau 2> donau-secmod-cs.log & + $USE_VALGRIND donau-httpd -c "$CONF" -L "$LOGLEVEL" 2> donau-httpd.log & echo " DONE" fi @@ -459,6 +512,7 @@ then $USE_VALGRIND taler-exchange-wirewatch \ --account="$USE_ACCOUNT" \ -c "$CONF" \ + -L "$LOGLEVEL" \ --longpoll-timeout="1 s" \ 2> taler-exchange-wirewatch.log & echo " DONE" @@ -467,14 +521,20 @@ fi if [ "1" = "$START_AGGREGATOR" ] then echo -n "Starting aggregator ..." - $USE_VALGRIND taler-exchange-aggregator -c "$CONF" 2> taler-exchange-aggregator.log & + $USE_VALGRIND taler-exchange-aggregator \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> taler-exchange-aggregator.log & echo " DONE" fi if [ "1" = "$START_TRANSFER" ] then echo -n "Starting transfer ..." - $USE_VALGRIND taler-exchange-transfer -c "$CONF" 2> taler-exchange-transfer.log & + $USE_VALGRIND taler-exchange-transfer \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> taler-exchange-transfer.log & echo " DONE" fi @@ -499,12 +559,31 @@ then MERCHANT_PORT="$(taler-config -c "$CONF" -s MERCHANT -o PORT)" MERCHANT_URL="http://localhost:${MERCHANT_PORT}/" fi - taler-merchant-dbinit -c "$CONF" -L "$LOGLEVEL" --reset &> taler-merchant-dbinit.log - $USE_VALGRIND taler-merchant-httpd -c "$CONF" -L "$LOGLEVEL" 2> taler-merchant-httpd.log & - $USE_VALGRIND taler-merchant-webhook -c "$CONF" -L "$LOGLEVEL" 2> taler-merchant-webhook.log & + taler-merchant-dbinit \ + -c "$CONF" \ + --reset &> taler-merchant-dbinit.log + $USE_VALGRIND taler-merchant-httpd \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-httpd.log & + $USE_VALGRIND taler-merchant-webhook \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-webhook.log & + if [ "1" = "$START_MERCHANT_EXCHANGE" ] + then + $USE_VALGRIND taler-merchant-exchange \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-exchange.log & + fi + if [ "1" = "$START_DEPOSITCHECK" ] + then + $USE_VALGRIND taler-merchant-depositcheck \ + -c "$CONF" \ + -L "$LOGLEVEL" 2> taler-merchant-depositcheck.log & + fi echo " DONE" fi + if [ "1" = "$START_BACKUP" ] then echo -n "Starting sync ..." @@ -517,7 +596,10 @@ then SYNC_URL="http://localhost:${SYNC_PORT}/" fi sync-dbinit -c "$CONF" --reset - $USE_VALGRIND sync-httpd -c "$CONF" -L "$LOGLEVEL" 2> sync-httpd.log & + $USE_VALGRIND sync-httpd \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> sync-httpd.log & echo " DONE" fi @@ -532,8 +614,13 @@ then else CHALLENGER_URL="http://localhost:${CHALLENGER_PORT}/" fi - challenger-dbinit -c "$CONF" --reset - $USE_VALGRIND challenger-httpd -c "$CONF" -L "$LOGLEVEL" 2> challenger-httpd.log & + challenger-dbinit \ + -c "$CONF" \ + --reset + $USE_VALGRIND challenger-httpd \ + -c "$CONF" \ + -L "$LOGLEVEL" \ + 2> challenger-httpd.log & echo " DONE" for SECTION in $(taler-config -c "$CONF" -S | grep kyc-provider) do @@ -574,9 +661,16 @@ then fi AUDITOR_PUB=$(gnunet-ecc -p "${AUDITOR_PRIV_FILE}") MAPUB=${MASTER_PUB:-$(taler-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY)} - taler-auditor-dbinit -c "$CONF" --reset - taler-auditor-exchange -c "$CONF" -m "$MAPUB" -u "$EXCHANGE_URL" - $USE_VALGRIND taler-auditor-httpd -L "$LOGLEVEL" -c "$CONF" 2> taler-auditor-httpd.log & + taler-auditor-dbinit \ + -c "$CONF" \ + --reset + taler-auditor-exchange \ + -c "$CONF" \ + -m "$MAPUB" \ + -u "$EXCHANGE_URL" + $USE_VALGRIND taler-auditor-httpd \ + -L "$LOGLEVEL" \ + -c "$CONF" 2> taler-auditor-httpd.log & echo " DONE" fi @@ -690,7 +784,7 @@ then download \ sign \ wire-fee now "$WIRE_DOMAIN" "$CURRENCY:0.01" "$CURRENCY:0.01" \ - global-fee now "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.01" 1h 1year 5 \ + global-fee now "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.0" 1h 1year 5 \ upload &> taler-exchange-offline.log echo "OK" ENABLED=$(taler-config -c "$CONF" -s "$USE_ACCOUNT" -o "ENABLE_CREDIT") diff --git a/src/testing/test_auditor_api.c b/src/testing/test_auditor_api.c index ac147d931..3810c601e 100644 --- a/src/testing/test_auditor_api.c +++ b/src/testing/test_auditor_api.c @@ -663,9 +663,6 @@ run (void *cls, TALER_TESTING_cmd_exec_auditor_offline ("auditor-offline", config_file), CMD_RUN_AUDITOR ("virgin-auditor"), - TALER_TESTING_cmd_exchanges_with_url ("check-exchange", - MHD_HTTP_OK, - "http://localhost:8081/"), TALER_TESTING_cmd_batch ("massive-deposit-confirms", massive_deposit_confirms), TALER_TESTING_cmd_batch ("withdraw", diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c index 0c4fb48ec..093730ff2 100644 --- a/src/testing/test_exchange_p2p.c +++ b/src/testing/test_exchange_p2p.c @@ -254,12 +254,12 @@ run (void *cls, TALER_TESTING_cmd_status ( "pull-check-post-merge-reserve-balance-get", "create-reserve-1", - "EUR:2.01", + "EUR:2.02", MHD_HTTP_OK), TALER_TESTING_cmd_reserve_history ( "push-check-post-merge-reserve-balance-post", "create-reserve-1", - "EUR:2.01", + "EUR:2.02", MHD_HTTP_OK), TALER_TESTING_cmd_purse_deposit_coins ( "purse-deposit-coins-idempotent", diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c index b7b28985c..a0178db06 100644 --- a/src/testing/test_kyc_api.c +++ b/src/testing/test_kyc_api.c @@ -403,14 +403,14 @@ run (void *cls, 5), "pull-poll-purse-before-deposit"), TALER_TESTING_cmd_status ( - "pull-check-post-merge-reserve-balance-get", + "pull-check-post-merge-reserve-balance-get-2", "p2p_create-reserve-3", - "EUR:1.02", + "EUR:1.03", MHD_HTTP_OK), TALER_TESTING_cmd_reserve_history ( - "push-check-post-merge-reserve-balance-post", + "push-check-post-merge-reserve-balance-post-2", "p2p_create-reserve-3", - "EUR:1.02", + "EUR:1.03", MHD_HTTP_OK), TALER_TESTING_cmd_end () }; diff --git a/src/testing/testing_api_cmd_age_withdraw.c b/src/testing/testing_api_cmd_age_withdraw.c index 30f409f4a..6ad22809e 100644 --- a/src/testing/testing_api_cmd_age_withdraw.c +++ b/src/testing/testing_api_cmd_age_withdraw.c @@ -585,6 +585,7 @@ age_withdraw_reveal_cb ( awrs->denom_sigs = GNUNET_new_array (awrs->num_coins, struct TALER_DenominationSignature); for (size_t n = 0; n < awrs->num_coins; n++) + { GNUNET_assert (GNUNET_OK == TALER_denom_sig_unblind ( &awrs->denom_sigs[n], @@ -593,8 +594,12 @@ age_withdraw_reveal_cb ( &aws->coin_outputs[n].details.h_coin_pub, &aws->coin_outputs[n].details.alg_values, &aws->coin_inputs[n].denom_pub->key)); + TALER_denom_sig_free (&awrs->denom_sigs[n]); + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "age-withdraw reveal success!\n"); + GNUNET_free (awrs->denom_sigs); } break; case MHD_HTTP_NOT_FOUND: diff --git a/src/testing/testing_api_cmd_auditor_exchanges.c b/src/testing/testing_api_cmd_auditor_exchanges.c deleted file mode 100644 index c554e5b84..000000000 --- a/src/testing/testing_api_cmd_auditor_exchanges.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2018-2023 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your - option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file testing/testing_api_cmd_auditor_exchanges.c - * @brief command for testing /exchanges of the auditor - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler_json_lib.h" -#include <gnunet/gnunet_curl_lib.h> -#include "taler_auditor_service.h" -#include "taler_testing_lib.h" -#include "taler_signatures.h" -#include "backoff.h" - -/** - * How long do we wait AT MOST when retrying? - */ -#define MAX_BACKOFF GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 100) - - -/** - * How often do we retry before giving up? - */ -#define NUM_RETRIES 5 - - -/** - * State for a "deposit confirmation" CMD. - */ -struct ExchangesState -{ - - /** - * Exchanges handle while operation is running. - */ - struct TALER_AUDITOR_ListExchangesHandle *leh; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Task scheduled to try later. - */ - struct GNUNET_SCHEDULER_Task *retry_task; - - /** - * How long do we wait until we retry? - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Expected HTTP response code. - */ - unsigned int expected_response_code; - - /** - * URL of the exchange expected to be included in the response. - */ - const char *exchange_url; - - /** - * How often should we retry on (transient) failures? - */ - unsigned int do_retry; - -}; - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -exchanges_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is); - - -/** - * Task scheduled to re-try #exchanges_run. - * - * @param cls a `struct ExchangesState` - */ -static void -do_retry (void *cls) -{ - struct ExchangesState *es = cls; - - es->retry_task = NULL; - TALER_TESTING_touch_cmd (es->is); - exchanges_run (es, - NULL, - es->is); -} - - -/** - * Callback to analyze the /exchanges response. - * - * @param cls closure of type struct ExchangesState* - * @param ler Response to the GET /exchanges request - */ -static void -exchanges_cb (void *cls, - const struct TALER_AUDITOR_ListExchangesResponse *ler) -{ - struct ExchangesState *es = cls; - const struct TALER_AUDITOR_HttpResponse *hr = &ler->hr; - - es->leh = NULL; - if (es->expected_response_code != hr->http_status) - { - if (0 != es->do_retry) - { - es->do_retry--; - if ( (0 == hr->http_status) || - (TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec) || - (MHD_HTTP_INTERNAL_SERVER_ERROR == hr->http_status) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Retrying list exchanges failed with %u/%d\n", - hr->http_status, - (int) hr->ec); - /* on DB conflicts, do not use backoff */ - if (TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec) - es->backoff = GNUNET_TIME_UNIT_ZERO; - else - es->backoff = GNUNET_TIME_randomized_backoff (es->backoff, - MAX_BACKOFF); - TALER_TESTING_inc_tries (es->is); - es->retry_task = GNUNET_SCHEDULER_add_delayed (es->backoff, - &do_retry, - es); - return; - } - } - TALER_TESTING_unexpected_status (es->is, - hr->http_status, - es->expected_response_code); - return; - } - if (MHD_HTTP_OK != hr->http_status) - { - TALER_TESTING_interpreter_next (es->is); - return; - } - if (NULL != es->exchange_url) - { - bool found = false; - unsigned int num_exchanges = ler->details.ok.num_exchanges; - const struct TALER_AUDITOR_ExchangeInfo *ei = ler->details.ok.ei; - - for (unsigned int i = 0; - i<num_exchanges; - i++) - if (0 == strcmp (es->exchange_url, - ei[i].exchange_url)) - found = true; - if (! found) - { - TALER_LOG_ERROR ("Exchange '%s' doesn't exist at this auditor\n", - es->exchange_url); - TALER_TESTING_interpreter_fail (es->is); - return; - } - TALER_LOG_DEBUG ("Exchange '%s' exists at this auditor!\n", - es->exchange_url); - } - TALER_TESTING_interpreter_next (es->is); -} - - -/** - * Run the command. - * - * @param cls closure. - * @param cmd the command to execute. - * @param is the interpreter state. - */ -static void -exchanges_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct ExchangesState *es = cls; - const struct TALER_TESTING_Command *auditor_cmd; - const char *auditor_url; - - (void) cmd; - auditor_cmd = TALER_TESTING_interpreter_get_command (is, - "auditor"); - if (NULL == auditor_cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - if (GNUNET_OK != - TALER_TESTING_get_trait_auditor_url (auditor_cmd, - &auditor_url)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - es->is = is; - es->leh = TALER_AUDITOR_list_exchanges ( - TALER_TESTING_interpreter_get_context (is), - auditor_url, - &exchanges_cb, - es); - if (NULL == es->leh) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (is); - return; - } - return; -} - - -/** - * Free the state of a "exchanges" CMD, and possibly cancel a - * pending operation thereof. - * - * @param cls closure, a `struct ExchangesState` - * @param cmd the command which is being cleaned up. - */ -static void -exchanges_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct ExchangesState *es = cls; - - if (NULL != es->leh) - { - TALER_TESTING_command_incomplete (es->is, - cmd->label); - TALER_AUDITOR_list_exchanges_cancel (es->leh); - es->leh = NULL; - } - if (NULL != es->retry_task) - { - GNUNET_SCHEDULER_cancel (es->retry_task); - es->retry_task = NULL; - } - GNUNET_free (es); -} - - -/** - * Offer internal data to other commands. - * - * @param cls closure. - * @param[out] ret set to the wanted data. - * @param trait name of the trait. - * @param index index number of the traits to be returned. - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -exchanges_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - (void) cls; - (void) ret; - (void) trait; - (void) index; - /* Must define this function because some callbacks - * look for certain traits on _all_ the commands. */ - return GNUNET_SYSERR; -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges (const char *label, - unsigned int expected_response_code) -{ - struct ExchangesState *es; - - es = GNUNET_new (struct ExchangesState); - es->expected_response_code = expected_response_code; - - { - struct TALER_TESTING_Command cmd = { - .cls = es, - .label = label, - .run = &exchanges_run, - .cleanup = &exchanges_cleanup, - .traits = &exchanges_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges_with_url (const char *label, - unsigned int expected_response_code, - const char *exchange_url) -{ - struct ExchangesState *es; - - es = GNUNET_new (struct ExchangesState); - es->expected_response_code = expected_response_code; - es->exchange_url = exchange_url; - { - struct TALER_TESTING_Command cmd = { - .cls = es, - .label = label, - .run = &exchanges_run, - .cleanup = &exchanges_cleanup, - .traits = &exchanges_traits - }; - - return cmd; - } -} - - -/** - * Modify an exchanges command to enable retries when we get - * transient errors from the auditor. - * - * @param cmd a deposit confirmation command - * @return the command with retries enabled - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_exchanges_with_retry (struct TALER_TESTING_Command cmd) -{ - struct ExchangesState *es; - - GNUNET_assert (&exchanges_run == cmd.run); - es = cmd.cls; - es->do_retry = NUM_RETRIES; - return cmd; -} - - -/* end of testing_auditor_api_cmd_exchanges.c */ diff --git a/src/util/crypto.c b/src/util/crypto.c index d8c6d7912..4735af3b0 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -473,7 +473,7 @@ TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub, } -enum GNUNET_GenericReturnValue +void TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, const struct TALER_DenominationHashP *denom_hash, struct TALER_BlindedCoinHashP *bch) @@ -488,7 +488,6 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, hash_context); GNUNET_CRYPTO_hash_context_finish (hash_context, &bch->hash); - return GNUNET_OK; } diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c index dae0b6fc6..ac41f52c6 100644 --- a/src/util/crypto_helper_cs.c +++ b/src/util/crypto_helper_cs.c @@ -113,21 +113,27 @@ try_connect (struct TALER_CRYPTO_CsDenominationHelper *dh) struct TALER_CRYPTO_CsDenominationHelper * TALER_CRYPTO_helper_cs_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_CsDenominationKeyStatusCallback dkc, void *dkc_cls) { struct TALER_CRYPTO_CsDenominationHelper *dh; char *unixpath; + char *secname; + GNUNET_asprintf (&secname, + "%s-exchange-secmod-cs", + section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-cs", + secname, "UNIXPATH", &unixpath)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-cs", + secname, "UNIXPATH"); + GNUNET_free (secname); return NULL; } /* we use >= here because we want the sun_path to always @@ -135,12 +141,14 @@ TALER_CRYPTO_helper_cs_connect ( if (strlen (unixpath) >= sizeof (dh->sa.sun_path)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-cs", + secname, "UNIXPATH", "path too long"); GNUNET_free (unixpath); + GNUNET_free (secname); return NULL; } + GNUNET_free (secname); dh = GNUNET_new (struct TALER_CRYPTO_CsDenominationHelper); dh->dkc = dkc; dh->dkc_cls = dkc_cls; diff --git a/src/util/crypto_helper_esign.c b/src/util/crypto_helper_esign.c index 5b04d0ead..4901937f5 100644 --- a/src/util/crypto_helper_esign.c +++ b/src/util/crypto_helper_esign.c @@ -111,21 +111,28 @@ try_connect (struct TALER_CRYPTO_ExchangeSignHelper *esh) struct TALER_CRYPTO_ExchangeSignHelper * TALER_CRYPTO_helper_esign_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_ExchangeKeyStatusCallback ekc, void *ekc_cls) { struct TALER_CRYPTO_ExchangeSignHelper *esh; char *unixpath; + char *secname; + + GNUNET_asprintf (&secname, + "%s-exchange-secmod-eddsa", + section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-eddsa", + secname, "UNIXPATH", &unixpath)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-eddsa", + secname, "UNIXPATH"); + GNUNET_free (secname); return NULL; } /* we use >= here because we want the sun_path to always @@ -133,12 +140,14 @@ TALER_CRYPTO_helper_esign_connect ( if (strlen (unixpath) >= sizeof (esh->sa.sun_path)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-eddsa", + secname, "UNIXPATH", "path too long"); GNUNET_free (unixpath); + GNUNET_free (secname); return NULL; } + GNUNET_free (secname); esh = GNUNET_new (struct TALER_CRYPTO_ExchangeSignHelper); esh->ekc = ekc; esh->ekc_cls = ekc_cls; diff --git a/src/util/crypto_helper_rsa.c b/src/util/crypto_helper_rsa.c index 58ed5a375..d5b7ccf2f 100644 --- a/src/util/crypto_helper_rsa.c +++ b/src/util/crypto_helper_rsa.c @@ -113,21 +113,28 @@ try_connect (struct TALER_CRYPTO_RsaDenominationHelper *dh) struct TALER_CRYPTO_RsaDenominationHelper * TALER_CRYPTO_helper_rsa_connect ( const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, TALER_CRYPTO_RsaDenominationKeyStatusCallback dkc, void *dkc_cls) { struct TALER_CRYPTO_RsaDenominationHelper *dh; char *unixpath; + char *secname; + + GNUNET_asprintf (&secname, + "%s-exchange-secmod-rsa", + section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-rsa", + secname, "UNIXPATH", &unixpath)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-rsa", + secname, "UNIXPATH"); + GNUNET_free (secname); return NULL; } /* we use >= here because we want the sun_path to always @@ -139,8 +146,10 @@ TALER_CRYPTO_helper_rsa_connect ( "UNIXPATH", "path too long"); GNUNET_free (unixpath); + GNUNET_free (secname); return NULL; } + GNUNET_free (secname); dh = GNUNET_new (struct TALER_CRYPTO_RsaDenominationHelper); dh->dkc = dkc; dh->dkc_cls = dkc_cls; diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c index a9696ee84..fbd5aa258 100644 --- a/src/util/taler-exchange-secmod-cs.c +++ b/src/util/taler-exchange-secmod-cs.c @@ -341,6 +341,13 @@ static struct GNUNET_TIME_Timestamp now_tmp; static char *keydir; /** + * Name of the configuration section prefix to use. Usually either "taler" or + * "donau". The actual configuration section will then be + * "$SECTION-exchange-secmod-cs". + */ +static char *section; + +/** * How much should coin creation (@e duration_withdraw) duration overlap * with the next denomination? Basically, the starting time of two * denominations is always @e duration_withdraw - #overlap_duration apart. @@ -2157,6 +2164,7 @@ run (void *cls, .updater = &cs_update_client_keys, .init = &cs_client_init }; + char *secname; (void) cls; (void) args; @@ -2171,18 +2179,23 @@ run (void *cls, /* get current time again, we may be timetraveling! */ now = GNUNET_TIME_timestamp_get (); } + GNUNET_asprintf (&secname, + "%s-exchange-secmod-cs", + section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-cs", + secname, "KEY_DIR", &keydir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-cs", + secname, "KEY_DIR"); + GNUNET_free (secname); global_ret = EXIT_NOTCONFIGURED; return; } + GNUNET_free (secname); if (GNUNET_OK != load_durations (cfg)) { @@ -2264,6 +2277,11 @@ main (int argc, char **argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('s', + "section", + "SECTION", + "name of the configuration section prefix to use, default is 'taler'", + §ion), GNUNET_GETOPT_option_timetravel ('T', "timetravel"), GNUNET_GETOPT_option_timestamp ('t', @@ -2282,7 +2300,7 @@ main (int argc, /* Restrict permissions for the key files that we create. */ (void) umask (S_IWGRP | S_IROTH | S_IWOTH | S_IXOTH); - + section = GNUNET_strdup ("taler"); /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ diff --git a/src/util/taler-exchange-secmod-eddsa.c b/src/util/taler-exchange-secmod-eddsa.c index f7a9702e6..1be4f7b49 100644 --- a/src/util/taler-exchange-secmod-eddsa.c +++ b/src/util/taler-exchange-secmod-eddsa.c @@ -137,6 +137,13 @@ static struct GNUNET_TIME_Timestamp now_tmp; static char *keydir; /** + * Name of the configuration section prefix to use. Usually either "taler" or + * "donau". The actual configuration section will then be + * "$SECTION-exchange-secmod-cs". + */ +static char *section; + +/** * How much should coin creation duration overlap * with the next key? Basically, the starting time of two * keys is always #duration - #overlap_duration apart. @@ -1065,6 +1072,7 @@ run (void *cls, .updater = eddsa_update_client_keys, .init = eddsa_client_init }; + char *secname; (void) cls; (void) args; @@ -1079,6 +1087,9 @@ run (void *cls, /* get current time again, we may be timetraveling! */ now = GNUNET_TIME_timestamp_get (); } + GNUNET_asprintf (&secname, + "%s-exchange-secmod-eddsa", + section); if (GNUNET_OK != load_durations (cfg)) { @@ -1087,16 +1098,18 @@ run (void *cls, } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-eddsa", + secname, "KEY_DIR", &keydir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-eddsa", + secname, "KEY_DIR"); + GNUNET_free (secname); global_ret = EXIT_NOTCONFIGURED; return; } + GNUNET_free (secname); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); global_ret = TES_listen_start (cfg, @@ -1144,6 +1157,11 @@ main (int argc, char **argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('s', + "section", + "SECTION", + "name of the configuration section prefix to use, default is 'taler'", + §ion), GNUNET_GETOPT_option_timetravel ('T', "timetravel"), GNUNET_GETOPT_option_timestamp ('t', @@ -1157,7 +1175,7 @@ main (int argc, /* Restrict permissions for the key files that we create. */ (void) umask (S_IWGRP | S_IROTH | S_IWOTH | S_IXOTH); - + section = GNUNET_strdup ("taler"); /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ diff --git a/src/util/taler-exchange-secmod-rsa.c b/src/util/taler-exchange-secmod-rsa.c index b10e7c637..57bf69d04 100644 --- a/src/util/taler-exchange-secmod-rsa.c +++ b/src/util/taler-exchange-secmod-rsa.c @@ -308,6 +308,13 @@ static struct GNUNET_TIME_Timestamp now_tmp; static char *keydir; /** + * Name of the configuration section prefix to use. Usually either "taler" or + * "donau". The actual configuration section will then be + * "$SECTION-exchange-secmod-cs". + */ +static char *section; + +/** * How much should coin creation (@e duration_withdraw) duration overlap * with the next denomination? Basically, the starting time of two * denominations is always @e duration_withdraw - #overlap_duration apart. @@ -1943,6 +1950,7 @@ run (void *cls, .updater = rsa_update_client_keys, .init = rsa_client_init }; + char *secname; (void) cls; (void) args; @@ -1957,18 +1965,23 @@ run (void *cls, /* get current time again, we may be timetraveling! */ now = GNUNET_TIME_timestamp_get (); } + GNUNET_asprintf (&secname, + "%s-exchange-secmod-rsa", + section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, - "taler-exchange-secmod-rsa", + secname, "KEY_DIR", &keydir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "taler-exchange-secmod-rsa", + secname, "KEY_DIR"); + GNUNET_free (secname); global_ret = EXIT_NOTCONFIGURED; return; } + GNUNET_free (secname); if (GNUNET_OK != load_durations (cfg)) { @@ -2051,6 +2064,11 @@ main (int argc, char **argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('s', + "section", + "SECTION", + "name of the configuration section prefix to use, default is 'taler'", + §ion), GNUNET_GETOPT_option_timetravel ('T', "timetravel"), GNUNET_GETOPT_option_timestamp ('t', @@ -2069,7 +2087,7 @@ main (int argc, /* Restrict permissions for the key files that we create. */ (void) umask (S_IWGRP | S_IROTH | S_IWOTH | S_IXOTH); - + section = GNUNET_strdup ("taler"); /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c index 2292cbfd1..07e9907b4 100644 --- a/src/util/test_helper_cs.c +++ b/src/util/test_helper_cs.c @@ -970,6 +970,7 @@ par_signing (struct GNUNET_CONFIGURATION_Handle *cfg) int ret; dh = TALER_CRYPTO_helper_cs_connect (cfg, + "taler", &key_cb, NULL); GNUNET_assert (NULL != dh); @@ -1027,6 +1028,7 @@ run_test (void) nanosleep (&req, NULL); dh = TALER_CRYPTO_helper_cs_connect (cfg, + "taler", &key_cb, NULL); if (NULL != dh) diff --git a/src/util/test_helper_eddsa.c b/src/util/test_helper_eddsa.c index da1c51b46..4f1f95893 100644 --- a/src/util/test_helper_eddsa.c +++ b/src/util/test_helper_eddsa.c @@ -365,6 +365,7 @@ par_signing (struct GNUNET_CONFIGURATION_Handle *cfg) int ret; esh = TALER_CRYPTO_helper_esign_connect (cfg, + "taler", &key_cb, NULL); if (NULL == esh) @@ -427,6 +428,7 @@ run_test (void) nanosleep (&req, NULL); esh = TALER_CRYPTO_helper_esign_connect (cfg, + "taler", &key_cb, NULL); if (NULL != esh) diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c index 028e23c74..2ea166330 100644 --- a/src/util/test_helper_rsa.c +++ b/src/util/test_helper_rsa.c @@ -797,6 +797,7 @@ par_signing (struct GNUNET_CONFIGURATION_Handle *cfg) int ret; dh = TALER_CRYPTO_helper_rsa_connect (cfg, + "taler", &key_cb, NULL); GNUNET_assert (NULL != dh); @@ -855,6 +856,7 @@ run_test (void) nanosleep (&req, NULL); dh = TALER_CRYPTO_helper_rsa_connect (cfg, + "taler", &key_cb, NULL); if (NULL != dh) |