#!/bin/bash # This file is in the public domain. # # This script configure and launches the Taler exchange. # # The environment must provide the following variables: # # - BANK_EXCHANGE_PASSWORD (exchange password for libeufin-bank) # - EXCHANGE_WIRE_GATEWAY_URL (where is the exchange wire gateway / libeufin-nexus) # - EXCHANGE_PAYTO (exchange account PAYTO) # - ENABLE_TLS (http or https?) # - DOMAIN_NAME: DNS domain name to use for the setup # set -eu notify_exit() { [[ $1 == 0 ]] || echo Script "$0" failed, exit code "$1" } notify_err() { echo "errexit on line $(caller)" >&2 } trap '(exit 130)' INT trap '(exit 143)' TERM trap notify_err ERR # shellcheck disable=SC2154 trap 'rc=$?; notify_exit $rc; exit $rc' EXIT # End of error handling setup source functions.sh source config/user.conf source config/internal.conf EXCHANGE_DB="taler-exchange" say "Beginning Exchange setup" if test -z "${BANK_EXCHANGE_PASSWORD:-}"; then say "Failure: BANK_EXCHANGE_PASSWORD not set" exit 1 fi if test -z "${EXCHANGE_PAYTO:-}"; then say "Failure: EXCHANGE_PAYTO not set" exit 1 fi function die() { say "$1" exit 1 } # Just try if sudo works for diagnostics sudo -i -u taler-exchange-offline id >/dev/null || die "Error: Unable to switch to taler-exchange-offline user" # Create master key as taler-exchange-offline *unless* user already # set the MASTER_PUBLIC_KEY to some value we can use. export MASTER_PRIV_DIR=.local/share/taler/exchange/offline-keys export MASTER_PRIV_FILE=${MASTER_PRIV_DIR}/master.priv export SECMOD_TOFU_FILE=${MASTER_PRIV_DIR}/secm_tofus.pub if test -z "${MASTER_PUBLIC_KEY:-}"; then if test "${DO_OFFLINE:-y}" == n; then say "Error: No MASTER_PUBLIC_KEY but DO_OFFLINE set to NO" exit 1 fi say "Setting up offline key" echo -e "[exchange-offline]\n"\ "MASTER_PRIV_FILE=\$HOME/${MASTER_PRIV_FILE}\n"\ "SECM_TOFU_FILE=\$HOME/${SECMOD_TOFU_FILE}\n"\ >/etc/taler/conf.d/offline-setup.conf MASTER_PUBLIC_KEY=$(sudo -i -u taler-exchange-offline taler-exchange-offline -c /etc/taler/taler.conf -LDEBUG setup 2>> setup.log) echo "MASTER_PUBLIC_KEY=\"${MASTER_PUBLIC_KEY}\"" >>config/user.conf if test -z "${DO_OFFLINE:-}"; then # Set 'DO_OFFLINE' DO_OFFLINE=y echo "DO_OFFLINE=y" >>config/user.conf fi else say "Master public key is $MASTER_PUBLIC_KEY" if test ${DO_OFFLINE:-y} == y; then MASTER_PUBLIC_KEY2=$(sudo -i -u taler-exchange-offline taler-exchange-offline -c /etc/taler/taler.conf setup 2>> setup.log) if test "${MASTER_PUBLIC_KEY2}" != "${MASTER_PUBLIC_KEY}"; then say "Error: master public key missmatch ${MASTER_PUBLIC_KEY2} does not match ${MASTER_PUBLIC_KEY}" exit 1 fi fi fi say "Stopping running exchange before reconfiguration" systemctl stop taler-exchange.target &>> setup.log say "Configuring exchange" # Generate terms of service (ToS) TERMS_ETAG= if test ${DO_EXCHANGE_TERMS} == y; then if test -z "${EXCHANGE_TERMS_FILE:-}"; then say "Error: No EXCHANGE_TERMS_FILE set but DO_EXCHANGE_TERMS set to YES" exit 1 fi TERMS_ETAG="$(basename "$EXCHANGE_TERMS_FILE" .rst)" say "Setting up terms of service (ToS)" taler-terms-generator -i "${EXCHANGE_TERMS_FILE}" &>> setup.log fi # Generate privacy policy PRIVACY_ETAG= if test ${DO_EXCHANGE_PRIVACY} == y; then if test -z "${EXCHANGE_PRIVACY_FILE:-}"; then say "Error: No EXCHANGE_PRIVACY_FILE set but DO_EXCHANGE_PRIVACY set to YES" exit 1 fi PRIVACY_ETAG="$(basename "$EXCHANGE_PRIVACY_FILE" .rst)" say "Setting up the privacy policy" taler-terms-generator -i "${EXCHANGE_PRIVACY_FILE}" &>> setup.log fi export EXCHANGE_BASE_URL="$PROTO://exchange.${DOMAIN_NAME}/" cat << EOF > /etc/taler/conf.d/setup.conf [taler] CURRENCY=${CURRENCY} CURRENCY_ROUND_UNIT=${CURRENCY}:0.01 [exchange] AML_THRESHOLD=${CURRENCY}:1000000 MASTER_PUBLIC_KEY=${MASTER_PUBLIC_KEY} BASE_URL=${EXCHANGE_BASE_URL} STEFAN_ABS=${CURRENCY}:0 STEFAN_LOG=${CURRENCY}:0 STEFAN_LIN=0 TERMS_ETAG=${TERMS_ETAG} PRIVACY_ETAG=${PRIVACY_ETAG} [merchant-exchange-${DOMAIN_NAME}] MASTER_KEY=${MASTER_PUBLIC_KEY} CURRENCY=${CURRENCY} EXCHANGE_BASE_URL=${EXCHANGE_BASE_URL} [exchange-account-default] PAYTO_URI=${EXCHANGE_PAYTO} ENABLE_DEBIT=YES ENABLE_CREDIT=YES @inline-secret@ exchange-accountcredentials-default ../secrets/exchange-accountcredentials-default.secret.conf EOF cat << EOF > /etc/taler/secrets/exchange-db.secret.conf [exchangedb-postgres] CONFIG=postgres:///exchange EOF chmod 440 /etc/taler/secrets/exchange-db.secret.conf chown root:taler-exchange-db /etc/taler/secrets/exchange-db.secret.conf cat << EOF > /etc/taler/secrets/exchange-accountcredentials-default.secret.conf [exchange-accountcredentials-default] WIRE_GATEWAY_URL=${PROTO}://bank.$DOMAIN_NAME/accounts/exchange/taler-wire-gateway/ WIRE_GATEWAY_AUTH_METHOD=basic USERNAME=exchange PASSWORD=${BANK_EXCHANGE_PASSWORD} EOF chmod 400 /etc/taler/secrets/exchange-accountcredentials-default.secret.conf chown taler-exchange-wire:taler-exchange-db /etc/taler/secrets/exchange-accountcredentials-default.secret.conf taler-harness deployment gen-coin-config \ --min-amount "${CURRENCY}":0.01 \ --max-amount "${CURRENCY}":100 | sed -e "s/FEE_DEPOSIT = ${CURRENCY}:0.01/FEE_DEPOSIT = ${CURRENCY}:0/" \ >/etc/taler/conf.d/"${CURRENCY}"-coins.conf say "Initializing exchange database" taler-exchange-dbconfig -c /etc/taler/taler.conf &>> setup.log say "Launching exchange" systemctl enable taler-exchange.target &>> setup.log systemctl restart taler-exchange.target &>> setup.log say "Waiting for exchange HTTP service (/config)..." curl -sS --max-time 2 \ --retry-all-errors \ --retry-delay 2 \ --retry 10 \ "${EXCHANGE_BASE_URL}"config &>> setup.log say "Waiting for exchange management keys (this may take a while)..." curl -sS --max-time 30 \ --retry-delay 2 \ --retry 60 \ "${EXCHANGE_BASE_URL}"management/keys &>> setup.log if test ${DO_OFFLINE} == y; then say "Offline interaction..." sudo -i -u taler-exchange-offline \ taler-exchange-offline \ -c /etc/taler/taler.conf \ download \ sign \ upload &>> setup.log say "Exchange account setup..." sudo -i -u taler-exchange-offline \ taler-exchange-offline \ enable-account "${EXCHANGE_PAYTO}" \ display-hint 0 "${CURRENCY} Exchange" \ wire-fee now x-taler-bank "${CURRENCY}":0 "${CURRENCY}":0 \ global-fee now "${CURRENCY}":0 "${CURRENCY}":0 "${CURRENCY}":0 1h 6a 0 \ upload &>> setup.log say "Enabling timer to automate renewals..." systemctl enable taler-exchange-offline.timer &>> setup.log systemctl restart taler-exchange-offline.timer &>> setup.log if test ${DO_CONVERSION} == y; then say "Conversion account setup (restricted to CH-only)..." sudo -i -u taler-exchange-offline taler-exchange-offline \ enable-account "${CONVERSION_PAYTO}" \ display-hint 10 "${FIAT_BANK_NAME}" \ conversion-url "${PROTO}://bank.$DOMAIN_NAME/conversion-info/" \ debit-restriction deny \ wire-fee now iban "${CURRENCY}":0 "${CURRENCY}":0 \ upload &>> setup.log fi fi say "Waiting for exchange /keys..." curl -sS --max-time 2 \ --retry-connrefused \ --retry-delay 2 \ --retry 10 \ "${EXCHANGE_BASE_URL}"keys &>> setup.log say "Exchange setup finished"