exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-unified-setup.sh (30935B)


      1 #!/usr/bin/env bash
      2 #
      3 # This file is part of TALER
      4 # Copyright (C) 2023, 2024 Taler Systems SA
      5 #
      6 # TALER is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as
      8 # published by the Free Software Foundation; either version 3, or
      9 # (at your option) any later version.
     10 #
     11 # TALER is distributed in the hope that it will be useful, but
     12 # WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public
     17 # License along with TALER; see the file COPYING.  If not, see
     18 # <http://www.gnu.org/licenses/>
     19 #
     20 # Author: Christian Grothoff
     21 #
     22 # This script configures and launches various GNU Taler services.
     23 # Which ones depend on command-line options. Use "-h" to find out.
     24 # Prints "<<READY>>" on a separate line once all requested services
     25 # are running. Close STDIN (or input 'NEWLINE') to stop all started
     26 # services again.
     27 #
     28 # shellcheck disable=SC2317
     29 
     30 set -eu
     31 
     32 if [[ ${TALER_TEST_VERBOSE:-0} -ge 1 ]]; then
     33   set -x
     34 fi
     35 
     36 # These break TALER_HOME control via TALER_TEST_HOME...
     37 unset XDG_DATA_HOME
     38 unset XDG_CONFIG_HOME
     39 unset XDG_CACHE_HOME
     40 
     41 EXIT_STATUS=2
     42 
     43 # Exit, with status code "skip" (no 'real' failure)
     44 function exit_skip() {
     45     echo " SKIP: " "$@" >&2
     46     EXIT_STATUS=77
     47     exit "$EXIT_STATUS"
     48 }
     49 
     50 # Exit, with error message (hard failure)
     51 function exit_fail() {
     52     echo " FAIL: " "$@" >&2
     53     EXIT_STATUS=1
     54     exit "$EXIT_STATUS"
     55 }
     56 
     57 # Cleanup to run whenever we exit
     58 function cleanup()
     59 {
     60     echo "Taler unified setup terminating at $STAGE!" >&2
     61 
     62     for n in $(jobs -p)
     63     do
     64         kill "$n" 2> /dev/null || true
     65     done
     66     wait
     67     rm -f libeufin-nexus.pid libeufin-sandbox.pid
     68     exit "$EXIT_STATUS"
     69 }
     70 
     71 STAGE="boot"
     72 
     73 # Install cleanup handler (except for kill -9)
     74 trap cleanup EXIT
     75 
     76 WAIT_FOR_SIGNAL=0
     77 START_AUDITOR=0
     78 START_BACKUP=0
     79 START_EXCHANGE=0
     80 START_FAKEBANK=0
     81 START_DONAU=0
     82 START_CHALLENGER=0
     83 START_AGGREGATOR=0
     84 START_MERCHANT=0
     85 START_NEXUS=0
     86 START_BANK=0
     87 START_TRANSFER=0
     88 START_WIREWATCH=0
     89 START_DEPOSITCHECK=0
     90 START_MERCHANT_EXCHANGE=0
     91 START_MERCHANT_WIREWATCH=0
     92 START_MERCHANT_DONAUKEYUPDATE=0
     93 USE_ACCOUNT="exchange-account-1"
     94 USE_VALGRIND=""
     95 WIRE_DOMAIN="x-taler-bank"
     96 CONF_ORIG="$HOME/.config/taler.conf"
     97 LOGLEVEL="DEBUG"
     98 DEFAULT_SLEEP="0.5"
     99 
    100 # Parse command-line options
    101 while getopts ':abc:d:DeEfghkL:mMnr:stu:vwWzZ' OPTION; do
    102     case "$OPTION" in
    103         a)
    104             START_AUDITOR="1"
    105             ;;
    106         b)
    107             START_BANK="1"
    108             ;;
    109         c)
    110             CONF_ORIG="$OPTARG"
    111             ;;
    112         d)
    113             WIRE_DOMAIN="$OPTARG"
    114             ;;
    115         D)
    116             START_DONAU="1"
    117             ;;
    118         e)
    119             START_EXCHANGE="1"
    120             ;;
    121         E)
    122             START_MERCHANT_EXCHANGE="1"
    123             ;;
    124         f)
    125             START_FAKEBANK="1"
    126             ;;
    127         h)
    128             echo 'Supported options:'
    129             echo '  -a           -- start auditor'
    130             echo '  -b           -- start bank'
    131             # shellcheck disable=SC2016
    132             echo '  -c $CONF     -- set configuration'
    133             # shellcheck disable=SC2016
    134             echo '  -d $METHOD   -- use wire method (default: x-taler-bank)'
    135             echo '  -D           -- start donau'
    136             echo '  -e           -- start exchange'
    137             echo '  -E           -- start taler-merchant-exchange'
    138             echo '  -f           -- start fakebank'
    139             echo '  -g           -- start taler-exchange-aggregator'
    140             echo '  -h           -- print this help'
    141             echo '  -k           -- start challenger (KYC service)'
    142             # shellcheck disable=SC2016
    143             echo '  -L $LOGLEVEL -- set log level'
    144             echo '  -m           -- start taler-merchant'
    145             echo '  -M           -- start taler-merchant-depositcheck'
    146             echo '  -n           -- start nexus'
    147             # shellcheck disable=SC2016
    148             echo '  -r $MEX      -- which exchange to use at the merchant (optional)'
    149             echo '  -s           -- start backup/sync'
    150             echo '  -S $SLEEP    -- set default sleep time between retries'
    151             echo '  -t           -- start taler-exchange-transfer'
    152             # shellcheck disable=SC2016
    153             echo '  -u $SECTION  -- exchange account to use'
    154             echo '  -v           -- use valgrind'
    155             echo '  -w           -- start taler-exchange-wirewatch'
    156             echo '  -W           -- wait for signal'
    157             echo '  -z           -- start taler-merchant-wirewatch'
    158             echo '  -Z           -- start taler-merchant-donaukeyupdate'
    159             exit 0
    160             ;;
    161         g)
    162             START_AGGREGATOR="1"
    163             ;;
    164         k)
    165             START_CHALLENGER="1"
    166             ;;
    167         L)
    168             LOGLEVEL="$OPTARG"
    169             ;;
    170         m)
    171             START_MERCHANT="1"
    172             ;;
    173         M)
    174             START_DEPOSITCHECK="1"
    175             ;;
    176         n)
    177             START_NEXUS="1"
    178             ;;
    179         r)
    180             USE_MERCHANT_EXCHANGE="$OPTARG"
    181             ;;
    182         s)
    183             START_BACKUP="1"
    184             ;;
    185         S)
    186             DEFAULT_SLEEP="$OPTARG"
    187             ;;
    188         t)
    189             START_TRANSFER="1"
    190             ;;
    191         u)
    192             USE_ACCOUNT="$OPTARG"
    193             ;;
    194         v)
    195             USE_VALGRIND="valgrind --leak-check=yes"
    196             DEFAULT_SLEEP="2"
    197             ;;
    198         w)
    199             START_WIREWATCH="1"
    200             ;;
    201         W)
    202             WAIT_FOR_SIGNAL="1"
    203             ;;
    204         z)
    205             START_MERCHANT_WIREWATCH="1"
    206             ;;
    207         Z)
    208             START_MERCHANT_DONAUKEYUPDATE="1"
    209             ;;
    210         ?)
    211         exit_fail "Unrecognized command line option"
    212         ;;
    213     esac
    214 done
    215 
    216 STAGE="init"
    217 
    218 echo "Starting with configuration file at: $CONF_ORIG" >&2
    219 CONF="$CONF_ORIG.edited"
    220 cp "${CONF_ORIG}" "${CONF}"
    221 
    222 STAGE="checks"
    223 
    224 echo -n "Testing for jq" >&2
    225 jq -h > /dev/null || exit_skip " jq required"
    226 echo " FOUND"
    227 
    228 echo -n "Testing for wget" >&2
    229 wget --help > /dev/null || exit_skip " wget required" >&2
    230 echo " FOUND"
    231 
    232 if [ "1" = "$START_EXCHANGE" ]
    233 then
    234     echo -n "Testing for Taler exchange" >&2
    235     taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange-httpd required"
    236     echo " FOUND"
    237 fi
    238 
    239 if [ "1" = "$START_DONAU" ]
    240 then
    241     echo -n "Testing for Donau" >&2
    242     donau-httpd -h > /dev/null || exit_skip " donau-httpd required"
    243     echo " FOUND"
    244 fi
    245 
    246 if [ "1" = "$START_MERCHANT" ]
    247 then
    248     echo -n "Testing for Taler merchant" >&2
    249     taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant-httpd required"
    250     echo " FOUND"
    251 fi
    252 
    253 if [ "1" = "$START_CHALLENGER" ]
    254 then
    255     echo -n "Testing for Taler challenger" >&2
    256     challenger-httpd -h > /dev/null || exit_skip " challenger-httpd required"
    257     echo " FOUND"
    258 fi
    259 
    260 if [ "1" = "$START_BACKUP" ]
    261 then
    262     echo -n "Testing for sync-httpd" >&2
    263     sync-httpd -h > /dev/null || exit_skip " sync-httpd required"
    264     echo " FOUND" >&2
    265 fi
    266 
    267 if [ "1" = "$START_NEXUS" ]
    268 then
    269     echo -n "Testing for libeufin-nexus" >&2
    270     libeufin-nexus --help >/dev/null </dev/null || exit_skip " MISSING"
    271     echo " FOUND" >&2
    272 fi
    273 
    274 if [ "1" = "$START_BANK" ]
    275 then
    276     echo -n "Testing for libeufin-bank" >&2
    277     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
    278     echo " FOUND" >&2
    279 fi
    280 
    281 STAGE="config"
    282 
    283 if [ "1" = "$START_EXCHANGE" ]
    284 then
    285     CURRENCY=$(taler-exchange-config -c "$CONF" -s "EXCHANGE" -o "CURRENCY")
    286 else
    287     if [ "1" = "$START_DONAU" ]
    288     then
    289         CURRENCY=$(donau-config -c "$CONF" -s "DONAU" -o "CURRENCY")
    290     else
    291         if [ "1" = "$START_BANK" ]
    292         then
    293             # Note: would be nice to have libeufin-config in the future...
    294             CURRENCY=$(taler-exchange-config -c "$CONF" -s "libeufin-bank" -o "CURRENCY")
    295         else
    296             CURRENCY="UNKNOWN"
    297         fi
    298     fi
    299 fi
    300 
    301 echo "Setting up for $CURRENCY" >&2
    302 
    303 register_bank_account() {
    304     wget \
    305         --http-user="$AUSER" \
    306         --http-password="$APASS" \
    307         --method=DELETE \
    308         -o /dev/null \
    309         -O /dev/null \
    310         -a wget-delete-account.log \
    311         "http://localhost:${BANK_PORT}/accounts/$1" \
    312         || true # deletion may fail, that's OK!
    313     if [ "$1" = "exchange" ] || [ "$1" = "Exchange" ]
    314     then
    315         IS_EXCHANGE="true"
    316     else
    317         IS_EXCHANGE="false"
    318     fi
    319     MAYBE_IBAN="${4:-}"
    320     if [ -n "$MAYBE_IBAN" ]
    321     then
    322         # shellcheck disable=SC2001
    323         ENAME=$(echo "$3" | sed -e "s/ /+/g")
    324         if [ "$WIRE_DOMAIN" = "x-taler-bank" ]
    325         then
    326             # hostname
    327             OPERATOR="localhost"
    328             MAYBE_IBAN="$1"
    329         else
    330             # BIC
    331             OPERATOR="SANDBOXX"
    332         fi
    333         PAYTO="payto://${WIRE_DOMAIN}/${OPERATOR}/${MAYBE_IBAN}?receiver-name=$ENAME"
    334         BODY='{"username":"'"$1"'","password":"'"$2"'","is_taler_exchange":'"$IS_EXCHANGE"',"name":"'"$3"'","payto_uri":"'"$PAYTO"'"}'
    335     else
    336         BODY='{"username":"'"$1"'","password":"'"$2"'","is_taler_exchange":'"$IS_EXCHANGE"',"name":"'"$3"'"}'
    337     fi
    338     wget \
    339         --http-user="$AUSER" \
    340         --http-password="$APASS" \
    341         --method=POST \
    342         --header='Content-type: application/json' \
    343         --body-data="${BODY}" \
    344         -o /dev/null \
    345         -O /dev/null \
    346         -a wget-register-account.log \
    347         "http://localhost:${BANK_PORT}/accounts"
    348 }
    349 
    350 register_fakebank_account() {
    351     if [ "$1" = "exchange" ] || [ "$1" = "Exchange" ]
    352     then
    353         IS_EXCHANGE="true"
    354     else
    355         IS_EXCHANGE="false"
    356     fi
    357     BODY='{"username":"'"$1"'","password":"'"$2"'","name":"'"$1"'","is_taler_exchange":'"$IS_EXCHANGE"'}'
    358     wget \
    359         --post-data="$BODY" \
    360         --header='Content-type: application/json' \
    361         --tries=3 \
    362         --waitretry=1 \
    363         --timeout=30 \
    364         "http://localhost:$BANK_PORT/accounts" \
    365         -a wget-register-account.log \
    366         -o /dev/null \
    367         -O /dev/null \
    368         >/dev/null
    369 }
    370 
    371 
    372 if [[ "1" = "$START_BANK" ]]
    373 then
    374     BANK_PORT=$(taler-exchange-config -c "$CONF" -s "libeufin-bank" -o "PORT")
    375     BANK_URL="http://localhost:${BANK_PORT}/"
    376 fi
    377 
    378 if [[ "1" = "$START_FAKEBANK" ]]
    379 then
    380     BANK_PORT=$(taler-exchange-config -c "$CONF" -s "BANK" -o "HTTP_PORT")
    381     BANK_URL="http://localhost:${BANK_PORT}/"
    382 fi
    383 
    384 STAGE="bank"
    385 
    386 if [ "1" = "$START_BANK" ]
    387 then
    388     echo -n "Setting up bank database ... " >&2
    389     libeufin-bank dbinit \
    390         -r \
    391         -c "$CONF" \
    392         -L "$LOGLEVEL" \
    393         &> libeufin-bank-reset.log
    394     echo "DONE" >&2
    395     echo -n "Launching bank ... " >&2
    396     libeufin-bank serve \
    397       -c "$CONF" \
    398       -L "$LOGLEVEL" \
    399       > libeufin-bank-stdout.log \
    400       2> libeufin-bank-stderr.log &
    401     echo $! > libeufin-bank.pid
    402     echo "DONE" >&2
    403     echo -n "Waiting for Bank ..." >&2
    404     OK="0"
    405     for n in $(seq 1 100); do
    406         echo -n "." >&2
    407         sleep "$DEFAULT_SLEEP"
    408         wget --timeout=1 \
    409              --tries=3 \
    410              --waitretry=0 \
    411              -a wget-bank-check.log \
    412              -o /dev/null \
    413              -O /dev/null \
    414              "${BANK_URL}config" || continue
    415         OK="1"
    416         break
    417     done
    418     if [ "1" != "$OK" ]
    419     then
    420         exit_skip "Failed to launch services (bank)" >&2
    421     fi
    422     echo "OK" >&2
    423     echo -n "Set admin password..." >&2
    424     AUSER="admin"
    425     APASS="secret-password"
    426     libeufin-bank \
    427       passwd \
    428       -c "$CONF" \
    429       -L "$LOGLEVEL" \
    430       "$AUSER" "$APASS" \
    431       &> libeufin-bank-passwd.log
    432     libeufin-bank \
    433       edit-account \
    434       -c "$CONF" \
    435       -L "$LOGLEVEL" \
    436       --debit_threshold="$CURRENCY:1000000" \
    437       "$AUSER" \
    438       &> libeufin-bank-debit-threshold.log
    439     echo " OK" >&2
    440 fi
    441 
    442 if [ "1" = "$START_NEXUS" ]
    443 then
    444     echo "Nexus currently not supported ..." >&2
    445 fi
    446 
    447 if [ "1" = "$START_FAKEBANK" ]
    448 then
    449     echo -n "Setting up fakebank ..." >&2
    450     $USE_VALGRIND taler-fakebank-run \
    451                   -c "$CONF" \
    452                   -L "$LOGLEVEL" \
    453                   -n 4 \
    454                   2> taler-fakebank-run.log &
    455     echo " OK" >&2
    456 fi
    457 
    458 if [[ "1" = "$START_BANK" || "1" = "$START_FAKEBANK" ]]
    459 then
    460     echo -n "Waiting for the bank" >&2
    461     # Wait for bank to be available (usually the slowest)
    462     OK="0"
    463     for n in $(seq 1 300)
    464     do
    465         echo -n "." >&2
    466         sleep "$DEFAULT_SLEEP"
    467         # bank
    468         wget --tries=1 \
    469              --waitretry=0 \
    470              --timeout=1 \
    471              --user admin \
    472              --password secret \
    473              -a wget-bank-check.log \
    474              -o /dev/null \
    475              -O /dev/null \
    476              "http://localhost:${BANK_PORT}/" || continue
    477         OK="1"
    478         break
    479     done
    480     if [ "1" != "$OK" ]
    481     then
    482         exit_skip "Failed to launch services (bank)"
    483     fi
    484     echo " OK" >&2
    485 fi
    486 
    487 STAGE="accounts"
    488 
    489 if [ "1" = "$START_FAKEBANK" ]
    490 then
    491     echo -n "Register Fakebank users ..." >&2
    492     register_fakebank_account fortytwo password
    493     register_fakebank_account fortythree password
    494     register_fakebank_account exchange password
    495     register_fakebank_account tor password
    496     register_fakebank_account gnunet password
    497     register_fakebank_account tutorial password
    498     register_fakebank_account survey password
    499     echo " DONE" >&2
    500 fi
    501 
    502 if [ "1" = "$START_BANK" ]
    503 then
    504     echo -n "Register bank users ..." >&2
    505     # The specified IBAN and name must match the ones hard-coded into
    506     # the C helper for the add-incoming call.  Without this value,
    507     # libeufin-bank  won't find the target account to debit along a /add-incoming
    508     # call.
    509     register_bank_account fortytwo password "User42" FR7630006000011234567890189
    510     register_bank_account fortythree password "Forty Three"
    511     register_bank_account exchange password "Exchange Company" DE989651
    512     register_bank_account tor password "Tor Project"
    513     register_bank_account gnunet password "GNUnet"
    514     register_bank_account tutorial password "Tutorial"
    515     register_bank_account survey password "Survey"
    516     echo " DONE" >&2
    517 fi
    518 
    519 STAGE="exchange"
    520 
    521 if [ "1" = "$START_EXCHANGE" ]
    522 then
    523     echo -n "Starting exchange ..." >&2
    524     EXCHANGE_PORT=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o PORT)
    525     SERVE=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o SERVE)
    526     if [ "${SERVE}" = "unix" ]
    527     then
    528         EXCHANGE_URL=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o BASE_URL)
    529     else
    530         EXCHANGE_URL="http://localhost:${EXCHANGE_PORT}/"
    531     fi
    532     MASTER_PRIV_FILE=$(taler-exchange-config -f -c "${CONF}" -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE")
    533     MASTER_PRIV_DIR=$(dirname "$MASTER_PRIV_FILE")
    534     mkdir -p "${MASTER_PRIV_DIR}"
    535     if [ ! -e "$MASTER_PRIV_FILE" ]
    536     then
    537         gnunet-ecc -g1 "$MASTER_PRIV_FILE" > /dev/null 2> /dev/null
    538         echo -n "." >&2
    539     fi
    540     MASTER_PUB=$(gnunet-ecc -p "${MASTER_PRIV_FILE}")
    541     MPUB=$(taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY)
    542     if [ "$MPUB" != "$MASTER_PUB" ]
    543     then
    544         echo -n " patching master_pub ($MASTER_PUB from ${MASTER_PRIV_FILE})..." >&2
    545         taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY -V "$MASTER_PUB"
    546     fi
    547     taler-exchange-dbinit \
    548         -c "$CONF" \
    549         --reset
    550     $USE_VALGRIND taler-exchange-secmod-eddsa \
    551                   -c "$CONF" \
    552                   -L "$LOGLEVEL" \
    553                   2> taler-exchange-secmod-eddsa.log &
    554     $USE_VALGRIND taler-exchange-secmod-rsa \
    555                   -c "$CONF" \
    556                   -L "$LOGLEVEL" \
    557                   2> taler-exchange-secmod-rsa.log &
    558     $USE_VALGRIND taler-exchange-secmod-cs \
    559                   -c "$CONF" \
    560                   -L "$LOGLEVEL" \
    561                   2> taler-exchange-secmod-cs.log &
    562     $USE_VALGRIND taler-exchange-httpd \
    563                   -c "$CONF" \
    564                   -L "$LOGLEVEL" 2> taler-exchange-httpd.log &
    565     echo " DONE" >&2
    566 fi
    567 
    568 STAGE="donau"
    569 
    570 if [ "1" = "$START_DONAU" ]
    571 then
    572     echo -n "Starting Donau ..." >&2
    573     DONAU_PORT=$(donau-config -c "$CONF" -s DONAU -o PORT)
    574     SERVE=$(donau-config -c "$CONF" -s DONAU -o SERVE)
    575     if [ "${SERVE}" = "unix" ]
    576     then
    577         DONAU_URL=$(donau-config -c "$CONF" -s DONAU -o BASE_URL)
    578     else
    579         DONAU_URL="http://localhost:${DONAU_PORT}/"
    580     fi
    581     donau-dbinit -c "$CONF" --reset
    582     $USE_VALGRIND donau-secmod-eddsa -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-eddsa.log &
    583     $USE_VALGRIND donau-secmod-rsa -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-rsa.log &
    584     $USE_VALGRIND donau-secmod-cs -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-cs.log &
    585     $USE_VALGRIND donau-httpd -c "$CONF" -L "$LOGLEVEL" 2> donau-httpd.log &
    586     echo " DONE" >&2
    587 fi
    588 
    589 STAGE="wirewatch"
    590 
    591 if [ "1" = "$START_WIREWATCH" ]
    592 then
    593     echo -n "Starting wirewatch ..." >&2
    594     $USE_VALGRIND taler-exchange-wirewatch \
    595                   --account="$USE_ACCOUNT" \
    596                   -c "$CONF" \
    597                   -L "$LOGLEVEL" \
    598                   --longpoll-timeout="60 s" \
    599                   2> taler-exchange-wirewatch.log &
    600     echo " DONE" >&2
    601 fi
    602 
    603 STAGE="aggregator"
    604 
    605 if [ "1" = "$START_AGGREGATOR" ]
    606 then
    607     echo -n "Starting aggregator ..." >&2
    608     $USE_VALGRIND taler-exchange-aggregator \
    609                   -c "$CONF" \
    610                   -L "$LOGLEVEL" \
    611                   2> taler-exchange-aggregator.log &
    612     echo " DONE" >&2
    613 fi
    614 
    615 STAGE="transfer"
    616 
    617 if [ "1" = "$START_TRANSFER" ]
    618 then
    619     echo -n "Starting transfer ..." >&2
    620     $USE_VALGRIND taler-exchange-transfer \
    621                   -c "$CONF" \
    622                   -L "$LOGLEVEL" \
    623                   2> taler-exchange-transfer.log &
    624     echo " DONE" >&2
    625 fi
    626 
    627 STAGE="merchant"
    628 
    629 if [ -n "${USE_MERCHANT_EXCHANGE+x}" ]
    630 then
    631     MEPUB=$(taler-merchant-config -c "$CONF" -s "${USE_MERCHANT_EXCHANGE}" -o MASTER_KEY)
    632     MXPUB=${MASTER_PUB:-$(taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY)}
    633     if [ "$MEPUB" != "$MXPUB" ]
    634     then
    635         echo -n " patching master_pub ($MXPUB)..." >&2
    636         taler-merchant-config -c "$CONF" -s "${USE_MERCHANT_EXCHANGE}" -o MASTER_KEY -V "$MXPUB"
    637     else
    638         echo -n " with exchange $MXPUB ..." >&2
    639     fi
    640 fi
    641 
    642 if [ "1" = "$START_MERCHANT" ]
    643 then
    644     echo -n "Starting merchant ..." >&2
    645     MERCHANT_TYPE=$(taler-merchant-config -c "$CONF" -s MERCHANT -o SERVE)
    646     if [ "unix" = "$MERCHANT_TYPE" ]
    647     then
    648         MERCHANT_URL="$(taler-merchant-config -c "$CONF" -s MERCHANT -o BASE_URL)"
    649     else
    650         MERCHANT_PORT="$(taler-merchant-config -c "$CONF" -s MERCHANT -o PORT)"
    651         MERCHANT_URL="http://localhost:${MERCHANT_PORT}/"
    652     fi
    653     taler-merchant-dbinit \
    654         -c "$CONF" \
    655         --reset &> taler-merchant-dbinit.log
    656     $USE_VALGRIND taler-merchant-exchangekeyupdate \
    657                   -c "$CONF" \
    658                   -L "$LOGLEVEL" 2> taler-merchant-exchangekeyupdate.log &
    659     $USE_VALGRIND taler-merchant-kyccheck \
    660                   -c "$CONF" \
    661                   -L "$LOGLEVEL" 2> taler-merchant-kyccheck.log &
    662     $USE_VALGRIND taler-merchant-httpd \
    663                   -c "$CONF" \
    664                   -L "$LOGLEVEL" 2> taler-merchant-httpd.log &
    665     $USE_VALGRIND taler-merchant-webhook \
    666                   -c "$CONF" \
    667                   -L "$LOGLEVEL" 2> taler-merchant-webhook.log &
    668     echo " DONE" >&2
    669     if [ "1" = "$START_MERCHANT_WIREWATCH" ]
    670     then
    671        echo -n "Starting taler-merchant-wirewatch ..." >&2
    672        $USE_VALGRIND taler-merchant-wirewatch \
    673                      -c "$CONF" \
    674                      -L "$LOGLEVEL" \
    675                      --persist \
    676                      2> taler-merchant-wirewatch.log &
    677        echo " DONE" >&2
    678     fi
    679     if [ "1" = "$START_MERCHANT_EXCHANGE" ]
    680     then
    681         echo -n "Starting taler-merchant-exchange ..." >&2
    682         $USE_VALGRIND taler-merchant-exchange \
    683                   -c "$CONF" \
    684                   -L "$LOGLEVEL" 2> taler-merchant-exchange.log &
    685         echo " DONE" >&2
    686     fi
    687     if [ "1" = "$START_DEPOSITCHECK" ]
    688     then
    689         echo -n "Starting taler-merchant-depositcheck ..." >&2
    690         $USE_VALGRIND taler-merchant-depositcheck \
    691                       -c "$CONF" \
    692                       -L "$LOGLEVEL" 2> taler-merchant-depositcheck.log &
    693         echo " DONE" >&2
    694     fi
    695     if [ "1" = "$START_MERCHANT_DONAUKEYUPDATE" ]
    696     then
    697         echo -n "Starting taler-merchant-donaukeyupdate..." >&2
    698         $USE_VALGRIND taler-merchant-donaukeyupdate \
    699                       -c "$CONF" \
    700                       -L "$LOGLEVEL" 2> taler-merchant-donaukeyupdate.log &
    701         echo " DONE" >&2
    702     fi
    703 fi
    704 
    705 STAGE="sync"
    706 
    707 if [ "1" = "$START_BACKUP" ]
    708 then
    709     echo -n "Starting sync ..." >&2
    710     SYNC_PORT=$(sync-config -c "$CONF" -s SYNC -o PORT)
    711     SERVE=$(sync-config -c "$CONF" -s SYNC -o SERVE)
    712     if [ "${SERVE}" = "unix" ]
    713     then
    714         SYNC_URL=$(sync-config -c "$CONF" -s SYNC -o BASE_URL)
    715     else
    716         SYNC_URL="http://localhost:${SYNC_PORT}/"
    717     fi
    718     sync-dbinit -c "$CONF" --reset
    719     $USE_VALGRIND sync-httpd \
    720                   -c "$CONF" \
    721                   -L "$LOGLEVEL" \
    722                   2> sync-httpd.log &
    723     echo " DONE" >&2
    724 fi
    725 
    726 STAGE="challenger"
    727 
    728 if [ "1" = "$START_CHALLENGER" ]
    729 then
    730     echo -n "Starting challenger ..." >&2
    731     CHALLENGER_PORT=$(challenger-config -c "$CONF" -s CHALLENGER -o PORT)
    732     SERVE=$(challenger-config -c "$CONF" -s CHALLENGER -o SERVE)
    733     if [ "${SERVE}" = "unix" ]
    734     then
    735         CHALLENGER_URL=$(challenger-config -c "$CONF" -s CHALLENGER -o BASE_URL)
    736     else
    737         CHALLENGER_URL="http://localhost:${CHALLENGER_PORT}/"
    738     fi
    739     challenger-dbinit \
    740         -c "$CONF" \
    741         --reset
    742     $USE_VALGRIND challenger-httpd \
    743                   -c "$CONF" \
    744                   -L "$LOGLEVEL" \
    745                   2> challenger-httpd.log &
    746     echo " DONE" >&2
    747     for SECTION in $(taler-exchange-config -c "$CONF" -S | grep kyc-provider)
    748     do
    749         LOGIC=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "LOGIC")
    750         if [ "${LOGIC}" = "oauth2" ]
    751         then
    752             INFO=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_INFO_URL")
    753             if [ "${CHALLENGER_URL}info" = "$INFO" ]
    754             then
    755                 echo -n "Enabling Challenger client for $SECTION" >&2
    756                 CLIENT_SECRET=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_CLIENT_SECRET")
    757                 RFC_8959_PREFIX="secret-token:"
    758                 if ! echo "${CLIENT_SECRET}" | grep ^${RFC_8959_PREFIX} > /dev/null
    759                 then
    760                     exit_fail "Client secret does not begin with '${RFC_8959_PREFIX}'"
    761                 fi
    762                 REDIRECT_URI="${EXCHANGE_URL}kyc-proof/kyc-provider-example-challeger"
    763                 CLIENT_ID=$(challenger-admin --add="${CLIENT_SECRET}" --quiet "${REDIRECT_URI}")
    764                 taler-exchange-config -c "$CONF" -s "$SECTION" -o KYC_OAUTH2_CLIENT_ID -V "$CLIENT_ID"
    765                 echo " DONE" >&2
    766             fi
    767         fi
    768     done
    769 fi
    770 
    771 STAGE="auditor"
    772 
    773 if [ "1" = "$START_AUDITOR" ]
    774 then
    775     echo -n "Starting auditor ..." >&2
    776 
    777     export TALER_AUDITOR_SALT=$(taler-auditor-config -c "$CONF" -s AUDITOR -o TALER_AUDITOR_SALT)
    778 
    779     AUDITOR_URL=$(taler-auditor-config -c "$CONF" -s AUDITOR -o BASE_URL)
    780     AUDITOR_PRIV_FILE=$(taler-auditor-config -f -c "$CONF" -s AUDITOR -o AUDITOR_PRIV_FILE)
    781     AUDITOR_PRIV_DIR=$(dirname "$AUDITOR_PRIV_FILE")
    782     mkdir -p "$AUDITOR_PRIV_DIR"
    783     if [ ! -e "$AUDITOR_PRIV_FILE" ]
    784     then
    785         gnunet-ecc -g1 "$AUDITOR_PRIV_FILE" > /dev/null 2> /dev/null
    786         echo -n "." >&2
    787     fi
    788     AUDITOR_PUB=$(gnunet-ecc -p "${AUDITOR_PRIV_FILE}")
    789     APUB=$(taler-exchange-config -c "$CONF" -s auditor -o PUBLIC_KEY)
    790     if [ "$APUB" != "$AUDITOR_PUB" ]
    791     then
    792         echo -n " patching auditor public key ..." >&2
    793         # Using taler-exchange-config is correct here, we don't want to
    794         # suddenly use the auditor-defaults while editing...
    795         taler-exchange-config -c "$CONF" -s auditor -o PUBLIC_KEY -V "$AUDITOR_PUB"
    796     fi
    797 
    798     taler-auditor-dbinit \
    799         -c "$CONF" \
    800         --reset
    801     echo "Launching auditor using $CONF" > taler-auditor-httpd.log >&2
    802     echo "Launching auditor using $AUDITOR_PUB from $AUDITOR_PRIV_FILE" \
    803          >> taler-auditor-httpd.log
    804     $USE_VALGRIND taler-auditor-httpd \
    805                   -L "$LOGLEVEL" \
    806                   -c "$CONF" 2>> taler-auditor-httpd.log &
    807     echo " DONE" >&2
    808 fi
    809 
    810 STAGE="wait"
    811 
    812 echo -n "Waiting for Taler services ..." >&2
    813 # Wait for all other taler services to be available
    814 E_DONE=0
    815 D_DONE=0
    816 M_DONE=0
    817 S_DONE=0
    818 K_DONE=0
    819 A_DONE=0
    820 for n in $(seq 1 30)
    821 do
    822     sleep "$DEFAULT_SLEEP"
    823     OK="0"
    824     if [ "0" = "$E_DONE" ] && [ "1" = "$START_EXCHANGE" ]
    825     then
    826         echo -n "E" >&2
    827         wget \
    828             --tries=1 \
    829             --timeout=1 \
    830             "${EXCHANGE_URL}config" \
    831             -o /dev/null \
    832             -O /dev/null >/dev/null || continue
    833         E_DONE=1
    834     fi
    835    if [ "0" = "$D_DONE" ] && [ "1" = "$START_DONAU" ]
    836     then
    837         echo -n "D" >&2
    838         wget \
    839             --tries=1 \
    840             --timeout=1 \
    841             "${DONAU_URL}config" \
    842             -o /dev/null \
    843             -O /dev/null >/dev/null || continue
    844         D_DONE=1
    845     fi
    846     if [ "0" = "$M_DONE" ] && [ "1" = "$START_MERCHANT" ]
    847     then
    848         echo -n "M" >&2
    849         wget \
    850             --tries=1 \
    851             --timeout=1 \
    852             "${MERCHANT_URL}config" \
    853             -o /dev/null \
    854             -O /dev/null >/dev/null || continue
    855         M_DONE=1
    856     fi
    857     if [ "0" = "$S_DONE" ] && [ "1" = "$START_BACKUP" ]
    858     then
    859         echo -n "S" >&2
    860         wget \
    861             --tries=1 \
    862             --timeout=1 \
    863             "${SYNC_URL}config" \
    864             -o /dev/null \
    865             -O /dev/null >/dev/null || continue
    866         S_DONE=1
    867     fi
    868     if [ "0" = "$K_DONE" ] && [ "1" = "$START_CHALLENGER" ]
    869     then
    870         echo -n "K" >&2
    871         wget \
    872             --tries=1 \
    873             --timeout=1 \
    874             "${CHALLENGER_URL}config" \
    875             -o /dev/null \
    876             -O /dev/null >/dev/null || continue
    877         K_DONE=1
    878     fi
    879     if [ "0" = "$A_DONE" ] && [ "1" = "$START_AUDITOR" ]
    880     then
    881         echo -n "A" >&2
    882         wget \
    883             --tries=1 \
    884             --timeout=1 \
    885             "${AUDITOR_URL}config" \
    886             -o /dev/null \
    887             -O /dev/null >/dev/null || continue
    888         A_DONE=1
    889     fi
    890     OK="1"
    891     break
    892 done
    893 if [ 1 != "$OK" ]
    894 then
    895     exit_skip "Failed to launch (some) Taler services (E: $E_DONE, M: $M_DONE, S: $S_DONE, K: $K_DONE, A: $A_DONE, D: $D_DONE)"
    896 fi
    897 echo " OK" >&2
    898 
    899 if [ "1" = "$START_EXCHANGE" ]
    900 then
    901     echo -n "Wait for exchange /management/keys to be ready " >&2
    902     OK="0"
    903     LAST_RESPONSE=$(mktemp tmp-last-response.XXXXXXXX)
    904     for n in $(seq 1 10)
    905     do
    906         echo -n "." >&2
    907         sleep "$DEFAULT_SLEEP"
    908         # exchange
    909         wget \
    910             --tries=3 \
    911             --waitretry=0 \
    912             --timeout=30 \
    913             "${EXCHANGE_URL}management/keys"\
    914             -o /dev/null \
    915             -O "$LAST_RESPONSE" \
    916             >/dev/null || continue
    917         OK="1"
    918         break;
    919     done
    920     if [ "1" != "$OK" ]
    921     then
    922         cat "$LAST_RESPONSE"
    923         exit_fail "Failed to setup exchange keys, check secmod logs"
    924     fi
    925     rm "$LAST_RESPONSE"
    926     echo " OK" >&2
    927 
    928     echo -n "Setting up exchange keys ..." >&2
    929     rm -f test_exchange_api_home/.local/share/taler-exchange/offline/secm_tofus.pub
    930     NEXT_YEAR=$(expr 1 + $(date +%Y))
    931     taler-exchange-offline -c "$CONF" \
    932       download \
    933       sign \
    934       wire-fee now "$WIRE_DOMAIN" "$CURRENCY:0.01" "$CURRENCY:0.01" \
    935       wire-fee "$NEXT_YEAR" "$WIRE_DOMAIN" "$CURRENCY:0.01" "$CURRENCY:0.01" \
    936       global-fee now "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.0" 1h 1year 5 \
    937       global-fee "$NEXT_YEAR" "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.0" 1h 1year 5 \
    938       upload &> taler-exchange-offline.log
    939     echo "OK" >&2
    940     ENABLED=$(taler-exchange-config -c "$CONF" -s "$USE_ACCOUNT" -o "ENABLE_CREDIT")
    941     if [ "YES" = "$ENABLED" ]
    942     then
    943         echo -n "Configuring bank account $USE_ACCOUNT ..." >&2
    944         EXCHANGE_PAYTO_URI=$(taler-exchange-config -c "$CONF" -s "$USE_ACCOUNT" -o "PAYTO_URI")
    945         taler-exchange-offline -c "$CONF" \
    946           enable-account "$EXCHANGE_PAYTO_URI" \
    947           upload &> "taler-exchange-offline-account.log"
    948         echo " OK" >&2
    949     else
    950         echo "WARNING: Account ${USE_ACCOUNT} not enabled (set to: '$ENABLED')" >&2
    951     fi
    952     if [ "1" = "$START_AUDITOR" ]
    953     then
    954         echo -n "Enabling auditor ..." >&2
    955         taler-exchange-offline -c "$CONF" \
    956           enable-auditor "$AUDITOR_PUB" "$AUDITOR_URL" "$CURRENCY Auditor" \
    957           upload &> taler-exchange-offline-auditor.log
    958         echo "OK" >&2
    959     fi
    960 
    961     echo -n "Checking /keys " >&2
    962     OK="0"
    963     LAST_RESPONSE=$(mktemp tmp-last-response.XXXXXXXX)
    964     for n in $(seq 1 10)
    965     do
    966         echo -n "." >&2
    967         sleep "$DEFAULT_SLEEP"
    968         wget \
    969             --tries=1 \
    970             --timeout=5 \
    971             "${EXCHANGE_URL}keys" \
    972             -a wget-keys-check.log \
    973             -o /dev/null \
    974             -O "$LAST_RESPONSE" \
    975             >/dev/null || continue
    976         OK="1"
    977         break
    978     done
    979     if [ "1" != "$OK" ]
    980     then
    981         cat "$LAST_RESPONSE"
    982         exit_fail " Failed to fetch ${EXCHANGE_URL}keys"
    983     fi
    984     rm "$LAST_RESPONSE"
    985     echo " OK" >&2
    986 fi
    987 
    988 if [ "1" = "$START_AUDITOR" ]
    989 then
    990     echo -n "Setting up auditor signatures ..." >&2
    991     timeout 15 taler-auditor-offline -c "$CONF" \
    992       download \
    993       sign \
    994       upload &> taler-auditor-offline.log
    995     echo " OK" >&2
    996 
    997     echo -n "Starting helpers " >&2
    998 
    999     $USE_VALGRIND taler-helper-auditor-coins \
   1000                         -L "$LOGLEVEL" \
   1001                         -c "$CONF" 2> taler-helper-auditor.log &
   1002     echo -n "." >&2
   1003 
   1004     $USE_VALGRIND taler-helper-auditor-reserves \
   1005                         -L "$LOGLEVEL" \
   1006                         -c "$CONF" 2> taler-helper-auditor.log &
   1007     echo -n "." >&2
   1008 
   1009     $USE_VALGRIND taler-helper-auditor-purses \
   1010                         -L "$LOGLEVEL" \
   1011                         -c "$CONF" 2> taler-helper-auditor.log &
   1012     echo -n "." >&2
   1013 
   1014     $USE_VALGRIND taler-helper-auditor-aggregation \
   1015                         -L "$LOGLEVEL" \
   1016                         -c "$CONF" 2> taler-helper-auditor.log &
   1017     echo -n "." >&2
   1018 
   1019     $USE_VALGRIND taler-helper-auditor-deposits \
   1020                             -L "$LOGLEVEL" \
   1021                             -c "$CONF" 2> taler-helper-auditor.log &
   1022     echo -n "." >&2
   1023 
   1024     echo " OK" >&2
   1025 
   1026 fi
   1027 
   1028 STAGE="ready"
   1029 
   1030 # Signal caller that we are ready.
   1031 echo "<<READY>>"
   1032 
   1033 if [ "1" = "$WAIT_FOR_SIGNAL" ]
   1034 then
   1035     while true
   1036     do
   1037         sleep 0.1
   1038     done
   1039 else
   1040     # Wait until caller stops us.
   1041     # shellcheck disable=SC2162
   1042     read
   1043 fi
   1044 
   1045 
   1046 
   1047 STAGE="exiting"
   1048 
   1049 echo "Taler unified setup terminating!" >&2
   1050 EXIT_STATUS=0
   1051 exit "$EXIT_STATUS"