diff options
Diffstat (limited to 'src')
67 files changed, 1911 insertions, 1967 deletions
diff --git a/src/authorization/Makefile.am b/src/authorization/Makefile.am index c6a7af1..5d2854d 100644 --- a/src/authorization/Makefile.am +++ b/src/authorization/Makefile.am @@ -35,7 +35,9 @@ bin_PROGRAMS = \ anastasis-helper-authorization-iban bin_SCRIPTS = \ - anastasis-authorization-email.sh + anastasis-authorization-email.sh \ + anastasis-authorization-sms.sh \ + anastasis-authorization-post.sh anastasis_helper_authorization_iban_SOURCES = \ anastasis-helper-authorization-iban.c diff --git a/src/authorization/anastasis-authorization-email.sh b/src/authorization/anastasis-authorization-email.sh index ae3ecf7..738aaf0 100755 --- a/src/authorization/anastasis-authorization-email.sh +++ b/src/authorization/anastasis-authorization-email.sh @@ -1,2 +1,3 @@ #!/bin/sh +# This file is in the public domain. exec mail -s "Anastasis" -r noreply "$1" diff --git a/src/authorization/anastasis-authorization-post.sh b/src/authorization/anastasis-authorization-post.sh new file mode 100755 index 0000000..66255ea --- /dev/null +++ b/src/authorization/anastasis-authorization-post.sh @@ -0,0 +1,196 @@ +#!/bin/bash +# This file is in the public domain. +set -eu + +# Check shared secrets +if [ -x "$PINGEN_CLIENT_ID" ] +then + echo "PINGEN_CLIENT_ID not sent in environment" + exit 1 +fi +if [ -x "$PINGEN_CLIENT_SECRET" ] +then + echo "PINGEN_CLIENT_SECRET not sent in environment" + exit 1 +fi +if [ -x "$PINGEN_ORG_ID" ] +then + echo "PINGEN_ORG_ID not sent in environment" + exit 1 +fi + +ENDPOINT="https://api.pingen.com" +LOGS="$PWD/authorization-post.log" + +MESSAGE=$(cat -) +DATE=$(date +%F) +ADDR="$1" +NAME=$(echo $ADDR | jq -r .full_name) +STREET=$(echo $ADDR | jq -r .street) + +LNUMBER=$(echo $STREET | awk '{print $NF}') +FNUMBER=$(echo $STREET | awk '{print $1}') +case $LNUMBER in + ''|*[!0-9]*) + case $FNUMBER in + ''|*[!0-9]*) + NUMBER=0 + ;; + *) + NUMBER=$FNUMBER + ;; + esac + ;; + *) + NUMBER=$LNUMBER + ;; +esac + + +CITY=$(echo $ADDR | jq -r .city) +POSTCODE=$(echo $ADDR | jq -r .postcode) +COUNTRY=$(echo $ADDR | jq -r .country) + +MYDIR=$(mktemp -d /tmp/authorization-post-XXXXXX) +cd "$MYDIR" +cat - | sed -e "s/%NAME%/$NAME/g" \ + -e "s/%STREET%/$STREET/g" \ + -e "s/%POSTCODE%/$POSTCODE/g" \ + -e "s/%CITY%/$CITY/g" \ + -e "s/%COUNTRY%/$COUNTRY/g" \ + -e "s/%MESSAGE%/$MESSAGE/g" > input.tex <<EOF +\NeedsTeXFormat{LaTeX2e} +\documentclass[fontsize=11pt,a4paper]{scrlttr2} +\makeatletter +\KOMAoptions{foldmarks=off} +%\@setplength{toaddrvpos}{30mm} +%\@setplength{toaddrhpos}{130mm} +%\@setplength{sigbeforevskip}{10mm} +\makeatother +\setkomavar{subject}{Anastasis Recovery} +%\setkomavar{fromname}{Anastasis SARL} +\setkomavar{signature}{Anastasis SARL} +\date{\today} +%\address{Anastasis SARL \\\\ 7 rue de Mondorf \\\\ 5431 Erpeldange} +%\signature{Anastasis SARL} +\begin{document} +\begin{letter}{\ \ %NAME% \\\\ \ \ %STREET% \\\\ \ \ %POSTCODE% %CITY% \\\\ \ \ %COUNTRY% } +\opening{To whom it may concern,} +%MESSAGE% +\closing{Best regards} +\end{letter} +\end{document} +EOF +pdflatex input.tex > /dev/null 2> /dev/null + +REPLY=$(curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" \ + --data-urlencode "grant_type=client_credentials" \ + --data-urlencode "client_id=$PINGEN_CLIENT_ID" \ + --data-urlencode "client_secret=$PINGEN_CLIENT_SECRET" \ + --data-urlencode "scope=letter" \ + https://identity.pingen.com/auth/access-tokens) + +ACCESS_TOKEN=$(echo $REPLY | jq -r .access_token) + +REPLY=$(curl -s \ + -X GET "$ENDPOINT/file-upload" \ + -H "Authorization: Bearer $ACCESS_TOKEN") +ATTRS=$(echo $REPLY | jq .data.attributes) +UPLOAD_URL=$(echo $ATTRS | jq -r .url) +URL_SIG=$(echo $ATTRS | jq -r .url_signature) + +curl -s -X PUT -T input.pdf "$UPLOAD_URL" + + +RECIPIENT="$(jq -n ' + { + name: $NAME, + street: $STREET, + number: $NUMBER, + city: $CITY, + zip: $POSTCODE, + country: $COUNTRY, + }' \ + --arg NAME "$NAME" \ + --arg STREET "$STREET" \ + --arg NUMBER "$NUMBER" \ + --arg CITY "$CITY" \ + --arg POSTCODE "$POSTCODE" \ + --arg COUNTRY "$COUNTRY" \ + )" + +SENDER="$(jq -n ' + { + name: "Anastasis SARL", + street: "Rue de Mondorf", + number: "7", + zip: "5421", + city: "Erpeldange", + country: "LU" + }' + )" + +REQUEST="$(jq -n ' + { data: { + type: "letters", + attributes: { + file_original_name: "input.pdf", + file_url: $UPLOAD_URL, + file_url_signature: $URL_SIG, + address_position: "left", + delivery_product: "cheap", + print_mode: "duplex", + auto_send: true, + print_spectrum: "grayscale" + } } + }' \ + --argjson RECIPIENT "$RECIPIENT" \ + --argjson SENDER "$SENDER" \ + --arg UPLOAD_URL "$UPLOAD_URL" \ + --arg URL_SIG "$URL_SIG" \ + )" + +STATUS=$(curl -s --request POST \ + --url "$ENDPOINT/organisations/${PINGEN_ORG_ID}/letters" \ + --header 'Content-Type: application/vnd.api+json' \ + --header "Authorization: Bearer $ACCESS_TOKEN" \ + -d "$REQUEST" \ + -o "$MYDIR/final-reply.txt" \ + -w "%{http_code}" -s) +cat "$MYDIR/final-reply.txt" >> "$LOGS" +case $STATUS in + 201) + ;; + *) + echo "Failed to add letter: $STATUS" >> "$LOGS" + echo "$REPLY" + exit 1; + ;; +esac +LETTER_ID=$(cat "$MYDIR/final-reply.txt" | jq -r .data.id) +REPLY=$MYDIR/delete-reply.txt +STATUS=409 +sleep 1; +while test "$STATUS" = 409; +do + STATUS=$(curl -s --request DELETE \ + --url "$ENDPOINT/organisations/$PINGEN_ORG_ID/letters/$LETTER_ID" \ + --header "Authorization: Bearer $ACCESS_TOKEN" \ + -o "$REPLY" \ + -w "%{http_code}" -s) + case $STATUS in + 204) + cat "$REPLY" >> "$LOGS" + ;; + 409) + # Happens, likely still in processing... + ;; + *) + echo "Failed to delete letter: $STATUS" >> "$LOGS" + ;; + esac +done + +rm -r "$MYDIR" + +exit 0 diff --git a/src/authorization/anastasis-authorization-sms.sh b/src/authorization/anastasis-authorization-sms.sh new file mode 100755 index 0000000..1e38661 --- /dev/null +++ b/src/authorization/anastasis-authorization-sms.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# This file is in the public domain. +set -eu + +# Check shared secrets +if [ -x "$TELESIGN_AUTH_TOKEN" ] +then + echo "TELESIGN_AUTH_TOKEN not sent in environment" + exit 1 +fi + +MESSAGE=$(cat -) +TMPFILE=$(mktemp /tmp/sms-loggingXXXXXX) +STATUS=$(curl --request POST \ + --url https://rest-api.telesign.com/v1/messaging \ + --header 'authorization: Basic $TELESIGN_AUTH_TOKEN' \ + --header 'content-type: application/x-www-form-urlencoded' \ + --data account_livecycle_event=transact \ + --data "message=$MESSAGE" \ + --data message_type=OTP \ + --data "phone_number=$1" \ + -w "%{http_code}" -s -o $TMPFILE) +echo `cat $TMPFILE` >> /var/log/sms.log +rm -f $TMPFILE +case $STATUS in + 200|203|250|290|291|295) + exit 0; + ;; + *) + exit 1; + ;; +esac +exit 1 diff --git a/src/authorization/anastasis_authorization_plugin_email.c b/src/authorization/anastasis_authorization_plugin_email.c index 62b50b8..7fc97e7 100644 --- a/src/authorization/anastasis_authorization_plugin_email.c +++ b/src/authorization/anastasis_authorization_plugin_email.c @@ -296,8 +296,12 @@ email_done_cb (void *cls, { struct ANASTASIS_AUTHORIZATION_State *as = cls; - as->child = NULL; as->cwh = NULL; + if (NULL != as->child) + { + GNUNET_OS_process_destroy (as->child); + as->child = NULL; + } as->pst = type; as->exit_code = exit_code; MHD_resume_connection (as->connection); diff --git a/src/authorization/anastasis_authorization_plugin_post.c b/src/authorization/anastasis_authorization_plugin_post.c index 1863279..9410b58 100644 --- a/src/authorization/anastasis_authorization_plugin_post.c +++ b/src/authorization/anastasis_authorization_plugin_post.c @@ -334,8 +334,12 @@ post_done_cb (void *cls, { struct ANASTASIS_AUTHORIZATION_State *as = cls; - as->child = NULL; as->cwh = NULL; + if (NULL != as->child) + { + GNUNET_OS_process_destroy (as->child); + as->child = NULL; + } as->pst = type; as->exit_code = exit_code; MHD_resume_connection (as->connection); diff --git a/src/authorization/anastasis_authorization_plugin_sms.c b/src/authorization/anastasis_authorization_plugin_sms.c index 47439eb..51457b6 100644 --- a/src/authorization/anastasis_authorization_plugin_sms.c +++ b/src/authorization/anastasis_authorization_plugin_sms.c @@ -295,8 +295,12 @@ sms_done_cb (void *cls, { struct ANASTASIS_AUTHORIZATION_State *as = cls; - as->child = NULL; as->cwh = NULL; + if (NULL != as->child) + { + GNUNET_OS_process_destroy (as->child); + as->child = NULL; + } as->pst = type; as->exit_code = exit_code; MHD_resume_connection (as->connection); diff --git a/src/authorization/anastasis_authorization_plugin_totp.c b/src/authorization/anastasis_authorization_plugin_totp.c index e1c104a..c127e38 100644 --- a/src/authorization/anastasis_authorization_plugin_totp.c +++ b/src/authorization/anastasis_authorization_plugin_totp.c @@ -188,7 +188,7 @@ compute_totp (int time_off, offset = hmac[sizeof (hmac) - 1] & 0x0f; for (int count = 0; count < 4; count++) - code |= hmac[offset + 3 - count] << (8 * count); + code |= ((uint32_t) hmac[offset + 3 - count]) << (8 * count); code &= 0x7fffffff; /* always use 8 digits (maximum) */ code = code % 100000000; diff --git a/src/authorization/test-post.sh b/src/authorization/test-post.sh new file mode 100755 index 0000000..fd3a8d8 --- /dev/null +++ b/src/authorization/test-post.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# This file is in the public domain. +set -eu +ADDR=`jq -n '{ + full_name: "John Doe", + street: "Bar street 3", + city: "Wuppertal", + postcode: 42289, + country: "DE", + }'` + +echo "Your recovery code is 1234" | ./anastasis-authorization-post.sh "$ADDR" diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index db37478..10edef5 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -41,7 +41,6 @@ anastasis_httpd_LDADD = \ -lgnunetjson \ -lgnunetutil \ -lmicrohttpd \ - -luuid \ $(XLIB) EXTRA_DIST = \ diff --git a/src/backend/anastasis-httpd_config.c b/src/backend/anastasis-httpd_config.c index 015fd01..677c5dc 100644 --- a/src/backend/anastasis-httpd_config.c +++ b/src/backend/anastasis-httpd_config.c @@ -103,7 +103,9 @@ AH_handler_config (struct AH_RequestHandler *rh, GNUNET_JSON_pack_string ("name", "anastasis"), GNUNET_JSON_pack_string ("version", - "0:0:0"), + "0:1:0"), + GNUNET_JSON_pack_string ("implementation", + "urn:net:taler:specs:anastasis:c-reference"), GNUNET_JSON_pack_string ("business_name", AH_business_name), GNUNET_JSON_pack_array_steal ("methods", diff --git a/src/backend/anastasis-httpd_policy-upload.c b/src/backend/anastasis-httpd_policy-upload.c index 8670483..83e8117 100644 --- a/src/backend/anastasis-httpd_policy-upload.c +++ b/src/backend/anastasis-httpd_policy-upload.c @@ -425,8 +425,8 @@ check_payment_cb (void *cls, GNUNET_assert (MHD_HTTP_OK == hr->http_status); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Payment status checked: %d\n", - osr->details.success.status); - switch (osr->details.success.status) + osr->details.ok.status); + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -441,7 +441,7 @@ check_payment_cb (void *cls, GNUNET_JSON_spec_end () }; - contract = osr->details.success.details.paid.contract_terms; + contract = osr->details.ok.details.paid.contract_terms; if (GNUNET_OK != GNUNET_JSON_parse (contract, cspec, @@ -537,7 +537,6 @@ await_payment (struct PolicyUploadContext *puc) AH_backend_url, order_id, NULL /* our payments are NOT session-bound */, - false, timeout, &check_payment_cb, puc); @@ -558,6 +557,7 @@ await_payment (struct PolicyUploadContext *puc) static MHD_RESULT begin_payment (struct PolicyUploadContext *puc) { + static const char *no_uuids[1] = { NULL }; json_t *order; GNUNET_CONTAINER_DLL_insert (puc_head, @@ -608,7 +608,7 @@ begin_payment (struct PolicyUploadContext *puc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, puc); @@ -662,34 +662,10 @@ AH_handler_policy_post ( hc->cc = &cleanup_ctx; puc->con = connection; - { - const char *pay_id; - - pay_id = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER); - if (NULL != pay_id) - { - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data ( - pay_id, - strlen (pay_id), - &puc->payment_identifier, - sizeof (struct ANASTASIS_PaymentSecretP))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER - " header must be a base32-encoded Payment-Secret"); - } - puc->payment_identifier_provided = true; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Policy upload started with payment identifier `%s'\n", - pay_id); - } - } + TALER_MHD_parse_request_header_auto (connection, + ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER, + &puc->payment_identifier, + puc->payment_identifier_provided); puc->account = *account_pub; /* check for meta-data */ @@ -768,28 +744,10 @@ AH_handler_policy_post ( } puc->upload_size = (size_t) len; } - { - /* Check if header contains Anastasis-Policy-Signature */ - const char *sig_s; - sig_s = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE); - if ( (NULL == sig_s) || - (GNUNET_OK != - GNUNET_STRINGS_string_to_data (sig_s, - strlen (sig_s), - &puc->account_sig, - sizeof (puc->account_sig))) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_ANASTASIS_POLICY_BAD_SIGNATURE, - ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE - " header must include a base32-encoded EdDSA signature"); - } - } + TALER_MHD_parse_request_header_auto_t (connection, + ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE, + &puc->account_sig); { /* Check if header contains an ETAG */ const char *etag; @@ -798,9 +756,12 @@ AH_handler_policy_post ( MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_NONE_MATCH); if ( (NULL == etag) || + (2 >= strlen (etag)) || + ('"' != etag[0]) || + ('"' != etag[strlen (etag) - 1]) || (GNUNET_OK != - GNUNET_STRINGS_string_to_data (etag, - strlen (etag), + GNUNET_STRINGS_string_to_data (etag + 1, + strlen (etag) - 2, &puc->new_policy_upload_hash, sizeof (puc->new_policy_upload_hash))) ) { @@ -834,39 +795,10 @@ AH_handler_policy_post ( } } - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - puc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - } - else - { - puc->timeout = GNUNET_TIME_relative_to_absolute ( - CHECK_PAYMENT_GENERIC_TIMEOUT); - } - } + puc->timeout = GNUNET_TIME_relative_to_absolute ( + CHECK_PAYMENT_GENERIC_TIMEOUT); + TALER_MHD_parse_request_timeout (connection, + &puc->timeout); /* check if the client insists on paying */ { diff --git a/src/backend/anastasis-httpd_policy.c b/src/backend/anastasis-httpd_policy.c index a26d11e..177cc06 100644 --- a/src/backend/anastasis-httpd_policy.c +++ b/src/backend/anastasis-httpd_policy.c @@ -122,25 +122,30 @@ return_policy (struct MHD_Connection *connection, { char *sig_s; char *etag; + char *etagq; sig_s = GNUNET_STRINGS_data_to_string_alloc (&account_sig, sizeof (account_sig)); - etag = GNUNET_STRINGS_data_to_string_alloc (&recovery_data_hash, - sizeof (recovery_data_hash)); GNUNET_break (MHD_YES == MHD_add_response_header (resp, ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE, sig_s)); + GNUNET_free (sig_s); GNUNET_break (MHD_YES == MHD_add_response_header (resp, ANASTASIS_HTTP_HEADER_POLICY_VERSION, version_s)); + etag = GNUNET_STRINGS_data_to_string_alloc (&recovery_data_hash, + sizeof (recovery_data_hash)); + GNUNET_asprintf (&etagq, + "\"%s\"", + etag); + GNUNET_free (etag); GNUNET_break (MHD_YES == MHD_add_response_header (resp, MHD_HTTP_HEADER_ETAG, - etag)); - GNUNET_free (etag); - GNUNET_free (sig_s); + etagq)); + GNUNET_free (etagq); } { MHD_RESULT ret; @@ -203,13 +208,16 @@ AH_policy_get (struct MHD_Connection *connection, inm = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_NONE_MATCH); - if (NULL != inm) + if ( (NULL != inm) && + (2 < strlen (inm)) && + ('"' == inm[0]) && + ('"' == inm[strlen (inm) - 1]) ) { struct GNUNET_HashCode inm_h; if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (inm, - strlen (inm), + GNUNET_STRINGS_string_to_data (inm + 1, + strlen (inm) - 2, &inm_h, sizeof (inm_h))) { diff --git a/src/backend/anastasis-httpd_truth-challenge.c b/src/backend/anastasis-httpd_truth-challenge.c index 9f7f123..a7d138f 100644 --- a/src/backend/anastasis-httpd_truth-challenge.c +++ b/src/backend/anastasis-httpd_truth-challenge.c @@ -360,22 +360,17 @@ AH_truth_challenge_shutdown (void) * Callback to process a POST /orders/ID/refund request * * @param cls closure with a `struct RefundEntry *` - * @param hr HTTP response details - * @param taler_refund_uri the refund uri offered to the wallet - * @param h_contract hash of the contract a Browser may need to authorize - * obtaining the HTTP response. + * @param rr response details */ static void refund_cb ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *taler_refund_uri, - const struct TALER_PrivateContractHashP *h_contract) + const struct TALER_MERCHANT_RefundResponse *rr) { struct RefundEntry *re = cls; re->ro = NULL; - switch (hr->http_status) + switch (rr->hr.http_status) { case MHD_HTTP_OK: { @@ -407,9 +402,9 @@ refund_cb ( GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Refund `%s' failed with HTTP status %u: %s (#%u)\n", re->order_id, - hr->http_status, - hr->hint, - (unsigned int) hr->ec); + rr->hr.http_status, + rr->hr.hint, + (unsigned int) rr->hr.ec); break; } GNUNET_CONTAINER_DLL_remove (re_head, @@ -713,7 +708,7 @@ check_payment_cb (void *cls, } GNUNET_assert (MHD_HTTP_OK == hr->http_status); - switch (osr->details.success.status) + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -796,7 +791,6 @@ begin_payment (struct ChallengeContext *gc) AH_backend_url, order_id, NULL /* NOT session-bound */, - false, timeout, &check_payment_cb, gc); @@ -804,6 +798,7 @@ begin_payment (struct ChallengeContext *gc) else { /* Create a fresh order */ + static const char *no_uuids[1] = { NULL }; json_t *order; struct GNUNET_TIME_Timestamp pay_deadline; @@ -837,7 +832,7 @@ begin_payment (struct ChallengeContext *gc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, gc); diff --git a/src/backend/anastasis-httpd_truth-solve.c b/src/backend/anastasis-httpd_truth-solve.c index 957d924..eb09dc7 100644 --- a/src/backend/anastasis-httpd_truth-solve.c +++ b/src/backend/anastasis-httpd_truth-solve.c @@ -555,7 +555,7 @@ check_payment_cb (void *cls, } GNUNET_assert (MHD_HTTP_OK == hr->http_status); - switch (osr->details.success.status) + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -638,7 +638,6 @@ begin_payment (struct SolveContext *gc) AH_backend_url, order_id, NULL /* NOT session-bound */, - false, timeout, &check_payment_cb, gc); @@ -646,6 +645,7 @@ begin_payment (struct SolveContext *gc) else { /* Create a fresh order */ + static const char *no_uuids[1] = { NULL }; json_t *order; struct GNUNET_TIME_Timestamp pay_deadline; @@ -679,7 +679,7 @@ begin_payment (struct SolveContext *gc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, gc); @@ -1140,40 +1140,10 @@ AH_handler_truth_solve ( gc->connection = connection; gc->truth_uuid = *truth_uuid; gc->hc->cc = &request_done; - - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - gc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - } - else - { - gc->timeout = GNUNET_TIME_relative_to_absolute ( - GNUNET_TIME_UNIT_SECONDS); - } - } + gc->timeout = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_SECONDS); + TALER_MHD_parse_request_timeout (connection, + &gc->timeout); } /* end of first-time initialization (if NULL == gc) */ else { diff --git a/src/backend/anastasis-httpd_truth-upload.c b/src/backend/anastasis-httpd_truth-upload.c index b8d2a84..1c2a58d 100644 --- a/src/backend/anastasis-httpd_truth-upload.c +++ b/src/backend/anastasis-httpd_truth-upload.c @@ -310,7 +310,7 @@ check_payment_cb (void *cls, NULL); break; case MHD_HTTP_OK: - switch (osr->details.success.status) + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -325,7 +325,7 @@ check_payment_cb (void *cls, GNUNET_JSON_spec_end () }; - contract = osr->details.success.details.paid.contract_terms; + contract = osr->details.ok.details.paid.contract_terms; if (GNUNET_OK != GNUNET_JSON_parse (contract, cspec, @@ -354,7 +354,7 @@ check_payment_cb (void *cls, qs = db->record_truth_upload_payment ( db->cls, &tuc->truth_uuid, - &osr->details.success.details.paid.deposit_total, + &osr->details.ok.details.paid.deposit_total, paid_until); if (qs <= 0) { @@ -396,6 +396,7 @@ check_payment_cb (void *cls, case MHD_HTTP_NOT_FOUND: /* Setup fresh order */ { + static const char *no_uuids[1] = { NULL }; char *order_id; json_t *order; @@ -415,7 +416,6 @@ check_payment_cb (void *cls, "description", "challenge storage fee", "quantity", (json_int_t) tuc->years_to_pay, "unit", "years", - "order_id", order_id); GNUNET_free (order_id); @@ -427,7 +427,7 @@ check_payment_cb (void *cls, 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, tuc); @@ -485,7 +485,6 @@ begin_payment (struct TruthUploadContext *tuc) AH_backend_url, order_id, NULL /* our payments are NOT session-bound */, - false, timeout, &check_payment_cb, tuc); @@ -550,78 +549,12 @@ AH_handler_truth_post ( tuc->truth_uuid = *truth_uuid; hc->ctx = tuc; hc->cc = &cleanup_truth_post; - - /* check for excessive upload */ - { - const char *lens; - unsigned long len; - char dummy; - - lens = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_CONTENT_LENGTH); - if ( (NULL == lens) || - (1 != sscanf (lens, - "%lu%c", - &len, - &dummy)) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - (NULL == lens) - ? TALER_EC_ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH - : TALER_EC_ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH, - NULL); - } - if (len / 1024 / 1024 >= AH_upload_limit_mb) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_PAYLOAD_TOO_LARGE, - TALER_EC_SYNC_MALFORMED_CONTENT_LENGTH, - "Content-length value not acceptable"); - } - } - - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - tuc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Long polling for %u ms enabled\n", - timeout); - } - else - { - tuc->timeout = GNUNET_TIME_relative_to_absolute ( - GNUNET_TIME_UNIT_SECONDS); - } - } - + TALER_MHD_check_content_length (connection, + AH_upload_limit_mb * 1024LLU * 1024LLU); + tuc->timeout = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_SECONDS); + TALER_MHD_parse_request_timeout (connection, + &tuc->timeout); } /* end 'if (NULL == tuc)' */ if (NULL != tuc->resp) diff --git a/src/cli/.gitignore b/src/cli/.gitignore index 72921e1..111e321 100644 --- a/src/cli/.gitignore +++ b/src/cli/.gitignore @@ -1,7 +1,13 @@ *.log +*.err +*.out anastasis-reducer test_reducer_home *.trs taler-bank.err wallet.err anastasis-discover +talercheck +test_reducer.conf.edited +wallet-withdraw.out +libeufin-transfer-initiate.out diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am index 44cad27..8b2a9a0 100644 --- a/src/cli/Makefile.am +++ b/src/cli/Makefile.am @@ -21,8 +21,10 @@ check_SCRIPTS = \ test_anastasis_reducer_enter_secret.sh \ test_anastasis_reducer_recovery_enter_user_attributes.sh \ test_anastasis_reducer_recovery_no_pay.sh \ - test_anastasis_reducer_recovery_hanging.sh \ - test_iban.sh + test_anastasis_reducer_recovery_hanging.sh + +# Removed for now, libeufin is not yet working OK for this. +# test_iban.sh AM_TESTS_ENVIRONMENT=export ANASTASIS_PREFIX=$${ANASTASIS_PREFIX:-@libdir@};export PATH=$${ANASTASIS_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; @@ -32,6 +34,8 @@ TESTS = \ EXTRA_DIST = \ $(check_SCRIPTS) \ + setup.sh \ + test_reducer_home/.local/share/taler/exchange-offline/master.priv \ test_reducer.conf \ test_reducer_free.conf \ test_free_reducer.conf \ diff --git a/src/cli/setup.sh b/src/cli/setup.sh new file mode 100755 index 0000000..6d26168 --- /dev/null +++ b/src/cli/setup.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# This file is in the public domain + +# Script to be inlined into the main test scripts. Defines function 'setup()' +# which wraps around 'taler-unified-setup.sh' to launch GNU Taler services. +# Call setup() with the arguments to pass to 'taler-unified-setup'. setup() +# will then launch GNU Taler, wait for the process to be complete before +# returning. The script will also install an exit handler to ensure the GNU +# Taler processes are stopped when the shell exits. + +set -eu + +# Cleanup to run whenever we exit +function exit_cleanup() +{ + if [ ! -z ${SETUP_PID+x} ] + then + echo "Killing taler-unified-setup ($SETUP_PID)" >&2 + kill -TERM "$SETUP_PID" 2> /dev/null || true + wait "$SETUP_PID" 2> /dev/null || true + fi +} + +# Install cleanup handler (except for kill -9) +trap exit_cleanup EXIT + +function setup() +{ + echo "Starting test system ..." >&2 + # Create a named pipe in a temp directory we own. + FIFO_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d fifo-XXXXXX) + FIFO_OUT=$(echo "$FIFO_DIR/out") + mkfifo "$FIFO_OUT" + # Open pipe as FD 3 (RW) and FD 4 (RO) + exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT" + rm -rf "$FIFO_DIR" + # We require '-W' for our termination logic to work. + taler-unified-setup.sh -W "$@" >&3 & + SETUP_PID=$! + # Close FD3 + exec 3>&- + sed -u '/<<READY>>/ q' <&4 + # Close FD4 + exec 4>&- + echo "Test system ready" >&2 +} + +# Exit, with status code "skip" (no 'real' failure) +function exit_fail() { + echo "$@" >&2 + exit 1 +} + +# Exit, with status code "skip" (no 'real' failure) +function exit_skip() { + echo "SKIPPING: $1" + exit 77 +} + +function get_payto_uri() { + export LIBEUFIN_SANDBOX_USERNAME="$1" + export LIBEUFIN_SANDBOX_PASSWORD="$2" + export LIBEUFIN_SANDBOX_URL="http://localhost:18082" + libeufin-cli sandbox demobank info --bank-account "$1" | jq --raw-output '.paytoUri' +} + +function get_bankaccount_transactions() { + export LIBEUFIN_SANDBOX_USERNAME=$1 + export LIBEUFIN_SANDBOX_PASSWORD=$2 + export LIBEUFIN_SANDBOX_URL="http://localhost:18082" + libeufin-cli sandbox demobank list-transactions --bank-account $1 +} diff --git a/src/cli/test_anastasis_reducer_done_authentication.sh b/src/cli/test_anastasis_reducer_done_authentication.sh index 87c738c..545c733 100755 --- a/src/cli/test_anastasis_reducer_done_authentication.sh +++ b/src/cli/test_anastasis_reducer_done_authentication.sh @@ -46,9 +46,9 @@ echo " OK" echo -n "Test done authentication (next) ..." -anastasis-reducer next resources/04-backup.json $TFILE +anastasis-reducer next resources/04-backup.json "$TFILE" -STATE=`jq -r -e .backup_state < $TFILE` +STATE=$(jq -r -e .backup_state < "$TFILE") if test "$STATE" != "POLICIES_REVIEWING" then exit_fail "Expected new state to be AUTHENTICATIONS_EDITING, got $STATE" diff --git a/src/cli/test_anastasis_reducer_enter_secret.sh b/src/cli/test_anastasis_reducer_enter_secret.sh index cfba181..3b25537 100755 --- a/src/cli/test_anastasis_reducer_enter_secret.sh +++ b/src/cli/test_anastasis_reducer_enter_secret.sh @@ -1,6 +1,7 @@ #!/bin/bash # This file is in the public domain. +# shellcheck disable=SC2317 ## Coloring style Text shell script COLOR='\033[0;35m' NOCOLOR='\033[0m' @@ -8,48 +9,23 @@ BOLD="$(tput bold)" NORM="$(tput sgr0)" set -eu -set -x -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo " SKIP: $1" - exit 77 -} - -# Exit, with error message (hard failure) -function exit_fail() { - echo " FAIL: $1" - exit 1 -} - -# Cleanup to run whenever we exit -function cleanup() -{ - for n in `jobs -p` - do - kill $n 2> /dev/null || true - done - rm -rf $CONF $WALLET_DB $TFILE $UFILE $TMP_DIR - wait -} - -CONF_1="test_anastasis_reducer_1.conf" -CONF_2="test_anastasis_reducer_2.conf" -CONF_3="test_anastasis_reducer_3.conf" -CONF_4="test_anastasis_reducer_4.conf" - -# Exchange configuration file will be edited, so we create one -# from the template. -CONF=`mktemp test_reducerXXXXXX.conf` -cp test_reducer.conf $CONF - -TMP_DIR=`mktemp -d keys-tmp-XXXXXX` -WALLET_DB=`mktemp test_reducer_walletXXXXXX.json` -TFILE=`mktemp test_reducer_statePPXXXXXX` -UFILE=`mktemp test_reducer_stateBFXXXXXX` - -# Install cleanup handler (except for kill -9) -trap cleanup EXIT +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + MERCHANT_PAYTO="payto://x-taler-bank/localhost/anastasis?receiver-name=anastasis" +else + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + MERCHANT_PAYTO="payto://iban/SANDBOXX/DE648226?receiver-name=anastasis" +fi # Check we can actually run echo -n "Testing for jq" @@ -64,9 +40,6 @@ taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" echo " FOUND" -echo -n "Testing for taler-bank-manage" -taler-bank-manage --help >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" echo -n "Testing for taler-wallet-cli" taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING" echo " FOUND" @@ -75,88 +48,65 @@ echo -n "Testing for anastasis-httpd" anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING" echo " FOUND" -echo -n "Initialize anastasis database ..." -# Name of the Postgres database we will use for the script. -# Will be dropped, do NOT use anything that might be used -# elsewhere -TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` - -dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1" -anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log -dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2" -anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log -dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3" -anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log -dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4" -anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log +. setup.sh +# Launch exchange, merchant and bank. +# shellcheck disable=SC2086 +setup -c "test_reducer.conf" \ + -aemw \ + $BANK_FLAGS -echo " OK" -echo -n "Generating Taler auditor, exchange and merchant configurations ..." - -DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME` -rm -rf $DATA_DIR - -# obtain key configuration data -MASTER_PRIV_FILE=`taler-config -f -c $CONF -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE"` -MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE` -mkdir -p $MASTER_PRIV_DIR -gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null -MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE` -EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL` -MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT` -MERCHANT_URL=http://localhost:${MERCHANT_PORT}/ -BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT` -BANK_URL=http://localhost:${BANK_PORT}/ -AUDITOR_URL=http://localhost:8083/ -AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE` -AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE` -mkdir -p $AUDITOR_PRIV_DIR -gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null -AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE` - -# patch configuration -TALER_DB=talercheck -taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB -taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB -taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s bank -o database -V postgres:///$TALER_DB -taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/" -taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/" +# Cleanup to run whenever we exit +function cleanup() +{ + exit_cleanup + for n in $(jobs -p) + do + kill "$n" 2> /dev/null || true + done + rm -rf "$CONF" "$WALLET_DB" "$TFILE" "$UFILE" "$TMP_DIR" + wait +} -echo " OK" +CONF_1="test_anastasis_reducer_1.conf" +CONF_2="test_anastasis_reducer_2.conf" +CONF_3="test_anastasis_reducer_3.conf" +CONF_4="test_anastasis_reducer_4.conf" + +# Exchange configuration file will be edited, so we create one +# from the template. +CONF="test_reducer.conf.edited" -echo -n "Setting up exchange ..." +TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d keys-tmp-XXXXXX) +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_walletXXXXXX.json) +TFILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_statePPXXXXXX) +UFILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateBFXXXXXX) -# reset database -dropdb $TALER_DB >/dev/null 2>/dev/null || true -createdb $TALER_DB || exit_skip "Could not create database $TALER_DB" -taler-exchange-dbinit -c $CONF -taler-merchant-dbinit -c $CONF -taler-auditor-dbinit -c $CONF -taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL +# Install cleanup handler (except for kill -9) +trap cleanup EXIT -echo " OK" -# Launch services -echo -n "Launching taler services ..." -taler-bank-manage-testing $CONF postgres:///$TALER_DB serve > taler-bank.log 2> taler-bank.err & -taler-exchange-secmod-eddsa -c $CONF 2> taler-exchange-secmod-eddsa.log & -taler-exchange-secmod-rsa -c $CONF 2> taler-exchange-secmod-rsa.log & -taler-exchange-secmod-cs -c $CONF 2> taler-exchange-secmod-cs.log & -taler-exchange-httpd -c $CONF 2> taler-exchange-httpd.log & -taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log & -taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log & -taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log & +echo -n "Initialize anastasis databases ..." +# Name of the Postgres database we will use for the script. +# Will be dropped, do NOT use anything that might be used +# elsewhere +TARGET_DB_1=$(anastasis-config -c "$CONF_1" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_2=$(anastasis-config -c "$CONF_2" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_3=$(anastasis-config -c "$CONF_3" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_4=$(anastasis-config -c "$CONF_4" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") + +dropdb "$TARGET_DB_1" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_1" || exit_skip "Could not create database $TARGET_DB_1" +anastasis-dbinit -c "$CONF_1" 2> anastasis-dbinit_1.log +dropdb "$TARGET_DB_2" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_2" || exit_skip "Could not create database $TARGET_DB_2" +anastasis-dbinit -c "$CONF_2" 2> anastasis-dbinit_2.log +dropdb "$TARGET_DB_3" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_3" || exit_skip "Could not create database $TARGET_DB_3" +anastasis-dbinit -c "$CONF_3" 2> anastasis-dbinit_3.log +dropdb "$TARGET_DB_4" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_4" || exit_skip "Could not create database $TARGET_DB_4" +anastasis-dbinit -c "$CONF_4" 2> anastasis-dbinit_4.log echo " OK" @@ -167,82 +117,9 @@ $PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log & $PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log & $PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log & -# Wait for bank to be available (usually the slowest) -for n in `seq 1 50` -do - echo -n "." - sleep 0.2 - OK=0 - # bank - wget --tries=1 --timeout=1 http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch services (bank)" -fi - -# Wait for all other taler services to be available -for n in `seq 1 50` -do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue - # merchant - wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue - # auditor - wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch taler services" -fi - -echo "OK" - -echo -n "Setting up keys ..." -taler-exchange-offline -c $CONF \ - download \ - sign \ - enable-account payto://x-taler-bank/localhost/Exchange \ - enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \ - wire-fee now x-taler-bank TESTKUDOS:0.01 TESTKUDOS:0.01 TESTKUDOS:0.01 \ - upload &> taler-exchange-offline.log - -echo -n "." - -for n in `seq 1 3` -do - echo -n "." - OK=0 - wget --tries=1 --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to setup keys" -fi - -echo " OK" - -echo -n "Setting up auditor signatures ..." -taler-auditor-offline -c $CONF \ - download sign upload &> taler-auditor-offline.log -echo " OK" - echo -n "Waiting for anastasis services ..." - # Wait for anastasis services to be available -for n in `seq 1 50` +for n in $(seq 1 50) do echo -n "." sleep 0.1 @@ -259,7 +136,7 @@ do break done -if [ 1 != $OK ] +if [ 1 != "$OK" ] then exit_skip "Failed to launch anastasis services" fi @@ -268,70 +145,74 @@ echo "OK" echo -n "Configuring merchant instance ..." # Setup merchant -curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_ms" : 3600000},"default_pay_delay":{"d_ms": 3600000}}' http://localhost:9966/management/instances +curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances + + +curl -H "Content-Type: application/json" -X POST -d '{"payto_uri":"'"$MERCHANT_PAYTO"'"}' http://localhost:9966/private/accounts + echo " DONE" -echo -en $COLOR$BOLD"Test enter secret in a backup state ..."$NORM$NOCOLOR +echo -en "${COLOR}${BOLD}Test enter secret in a backup state ...${NORM}${NOCOLOR}" $PREFIX anastasis-reducer -a \ '{"secret": { "value" : "veryhardtoguesssecret", "mime" : "text/plain" } }' \ - enter_secret resources/06-backup.json $TFILE + enter_secret resources/06-backup.json "$TFILE" -STATE=`jq -r -e .backup_state < $TFILE` -if test "$STATE" != "SECRET_EDITING" +STATE=$(jq -r -e .backup_state < "$TFILE") +if [ "$STATE" != "SECRET_EDITING" ] then - jq -e . $TFILE + jq -e . "$TFILE" exit_fail "Expected new state to be 'SECRET_EDITING', got '$STATE'" fi echo " DONE" -echo -en $COLOR$BOLD"Test expiration change ..."$NORM$NOCOLOR +echo -en "${COLOR}${BOLD}Test expiration change ...${NORM}${NOCOLOR}" -MILLIS=`date '+%s'`000 +SECS=$(date '+%s') # Use 156 days into the future to get 1 year -MILLIS=`expr $MILLIS + 13478400000` +SECS=$(( SECS + 13478400 )) $PREFIX anastasis-reducer -a \ "$(jq -n ' - {"expiration": { "t_ms" : $MSEC } }' \ - --argjson MSEC $MILLIS + {"expiration": { "t_s" : $SEC } }' \ + --argjson SEC "$SECS" )" \ - update_expiration $TFILE $UFILE + update_expiration "$TFILE" "$UFILE" -STATE=`jq -r -e .backup_state < $UFILE` +STATE=$(jq -r -e .backup_state < "$UFILE") if test "$STATE" != "SECRET_EDITING" then - jq -e . $UFILE + jq -e . "$UFILE" exit_fail "Expected new state to be 'SECRET_EDITING', got '$STATE'" fi -FEES=`jq -r -e '.upload_fees[0].fee' < $UFILE` +FEES=$(jq -r -e '.upload_fees[0].fee' < "$UFILE") # 4x 4.99 for annual fees, plus 4x0.01 for truth uploads -if test "$FEES" != "TESTKUDOS:20" +if [ "$FEES" != "TESTKUDOS:20" ] then - jq -e . $UFILE + jq -e . "$UFILE" exit_fail "Expected upload fees to be 'TESTKUDOS:20', got '$FEES'" fi echo " DONE" -echo -en $COLOR$BOLD"Test advance to payment ..."$NORM$NOCOLOR +echo -en "${COLOR}${BOLD}Test advance to payment ...${NORM}${NOCOLOR}" -$PREFIX anastasis-reducer next $UFILE $TFILE +$PREFIX anastasis-reducer next "$UFILE" "$TFILE" -STATE=`jq -r -e .backup_state < $TFILE` -if test "$STATE" != "TRUTHS_PAYING" +STATE=$(jq -r -e .backup_state < "$TFILE") +if [ "$STATE" != "TRUTHS_PAYING" ] then - jq -e . $TFILE + jq -e . "$TFILE" exit_fail "Expected new state to be 'TRUTHS_PAYING', got '$STATE'" fi # FIXME: this test is specific to how the # C reducer stores state (redundantly!), should converge eventually! -#TMETHOD=`jq -r -e '.policies[0].methods[0].truth.type' < $TFILE` +#TMETHOD=$(jq -r -e '.policies[0].methods[0].truth.type' < $TFILE) #if test $TMETHOD != "question" #then # exit_fail "Expected method to be >='question', got $TMETHOD" @@ -342,85 +223,115 @@ fi #Pay -echo -en $COLOR$BOLD"Withdrawing amount to wallet ..."$NORM$NOCOLOR +echo -en "${COLOR}${BOLD}Withdrawing amount to wallet ...${NORM}${NOCOLOR}" + +EXCHANGE_URL="$(taler-config -c "$CONF" -s exchange -o BASE_URL)" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'withdrawTestBalance' \ +rm "$WALLET_DB" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:40", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL" \ - --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2>wallet.err >wallet.log -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet.err >wallet.log + --arg BANK_URL "${BANK_URL}" \ + --arg EXCHANGE_URL "${EXCHANGE_URL}" + )" 2>wallet-withdraw.err \ + >wallet-withdraw.log +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish.err \ + >wallet-withdraw-finish.log echo " OK" -echo -en $COLOR$BOLD"Making payments for truth uploads ... "$NORM$NOCOLOR -OBJECT_SIZE=`jq -r -e '.payments | length' < $TFILE` -for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++)) +echo -en "${COLOR}${BOLD}Making payments for truth uploads ... ${NORM}${NOCOLOR}" +OBJECT_SIZE=$(jq -r -e '.payments | length' < "$TFILE") +for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) do - PAY_URI=`jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < $TFILE` + PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < "$TFILE") # run wallet CLI echo -n "$INDEX" - taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>wallet.err >wallet.log + taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URI}" \ + -y \ + 2>wallet-pay1.err \ + >wallet-pay1.log echo -n "," done echo " OK" -echo -e $COLOR$BOLD"Running wallet run-pending..."$NORM$NOCOLOR -taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>wallet.err >wallet.log -echo -e $COLOR$BOLD"Payments done"$NORM$NOCOLOR - - -echo -en $COLOR$BOLD"Try to upload again ..."$NORM$NOCOLOR -$PREFIX anastasis-reducer pay $TFILE $UFILE -mv $UFILE $TFILE +echo -e "${COLOR}${BOLD}Running wallet run-until-done...${NORM}${NOCOLOR}" +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-pay-finish.err \ + >wallet-pay-finish.log +echo -e "${COLOR}${BOLD}Payments done${NORM}${NOCOLOR}" + + +echo -en "${COLOR}${BOLD}Try to upload again ...${NORM}${NOCOLOR}" +$PREFIX anastasis-reducer pay "$TFILE" "$UFILE" +mv "$UFILE" "$TFILE" echo " OK" -STATE=`jq -r -e .backup_state < $TFILE` -if test "$STATE" != "POLICIES_PAYING" +STATE="$(jq -r -e .backup_state < "$TFILE")" +if [ "$STATE" != "POLICIES_PAYING" ] then exit_fail "Expected new state to be 'POLICIES_PAYING', got '$STATE'" fi -export TFILE -export UFILE - -echo -en $COLOR$BOLD"Making payments for policy uploads ... "$NORM$NOCOLOR -OBJECT_SIZE=`jq -r -e '.policy_payment_requests | length' < $TFILE` -for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++)) +echo -en "${COLOR}${BOLD}Making payments for policy uploads ... ${NORM}${NOCOLOR}" +OBJECT_SIZE="$(jq -r -e '.policy_payment_requests | length' < "$TFILE")" +for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) do - PAY_URI=`jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < $TFILE` + PAY_URI="$(jq --argjson INDEX "$INDEX" -r -e '.policy_payment_requests[$INDEX].payto' < "$TFILE")" # run wallet CLI export PAY_URI echo -n "$INDEX" - taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>wallet.err >wallet.log + taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + handle-uri "$PAY_URI" \ + -y \ + 2>"wallet-pay2-$INDEX.err" \ + >"wallet-pay2-$INDEX.log" echo -n "," done echo " OK" -echo -e $COLOR$BOLD"Running wallet run-pending..."$NORM$NOCOLOR -taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>wallet.err >wallet.log -echo -e $COLOR$BOLD"Payments done"$NORM$NOCOLOR +echo -e "${COLOR}${BOLD}Running wallet run-until-done...${NORM}${NOCOLOR}" +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-pay2-finish.err \ + >wallet-pay2-finish.log +echo -e "${COLOR}${BOLD}Payments done${NORM}${NOCOLOR}" -echo -en $COLOR$BOLD"Try to upload again ..."$NORM$NOCOLOR -$PREFIX anastasis-reducer pay $TFILE $UFILE +echo -en "${COLOR}${BOLD}Try to upload again ...${NORM}${NOCOLOR}" +$PREFIX anastasis-reducer pay "$TFILE" "$UFILE" echo " OK" echo -n "Final checks ..." -STATE=`jq -r -e .backup_state < $UFILE` -if test "$STATE" != "BACKUP_FINISHED" +STATE=$(jq -r -e .backup_state < "$UFILE") +if [ "$STATE" != "BACKUP_FINISHED" ] then exit_fail "Expected new state to be BACKUP_FINISHED, got $STATE" fi -jq -r -e .core_secret < $UFILE > /dev/null && exit_fail "'core_secret' was not cleared upon success" +jq -r -e .core_secret \ + < "$UFILE" \ + > /dev/null \ + && exit_fail "'core_secret' was not cleared upon success" echo " OK" - exit 0 diff --git a/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh b/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh index 49814cd..551ab36 100755 --- a/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh +++ b/src/cli/test_anastasis_reducer_recovery_enter_user_attributes.sh @@ -1,28 +1,64 @@ #!/bin/bash # This file is in the public domain. +# shellcheck disable=SC2317 + set -eu -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo " SKIP: $1" - exit 77 -} +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + MERCHANT_PAYTO="payto://x-taler-bank/localhost/anastasis?receiver-name=anastasis" +else + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + MERCHANT_PAYTO="payto://iban/SANDBOXX/DE648226?receiver-name=anastasis" +fi -# Exit, with error message (hard failure) -function exit_fail() { - echo " FAIL: $1" - exit 1 -} +# Check we can actually run +echo -n "Testing for jq" +jq -h > /dev/null || exit_skip "jq required" +echo " FOUND" +echo -n "Testing for anastasis-reducer ..." +anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required" +echo " FOUND" + +echo -n "Testing for taler" +taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" +taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" +echo " FOUND" + +echo -n "Testing for taler-wallet-cli" +taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + +echo -n "Testing for anastasis-httpd" +anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + +. setup.sh +# Launch exchange, merchant and bank. +# shellcheck disable=SC2086 +setup -c "test_reducer.conf" \ + -aemw \ + $BANK_FLAGS # Cleanup to run whenever we exit function cleanup() { - for n in `jobs -p` + exit_cleanup + for n in $(jobs -p) do - kill $n 2> /dev/null || true + kill "$n" 2> /dev/null || true done - rm -rf $CONF $WALLET_DB $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR + rm -rf "$CONF" "$WALLET_DB" "$R1FILE" "$R2FILE" "$B1FILE" "$B2FILE" "$TMP_DIR" wait } @@ -33,25 +69,28 @@ function sync_providers() { # Sync with providers (up to 3 providers aren't synced here) for x in 1 2 3; do echo "Synchronizing providers (round $x)" - anastasis-reducer sync_providers < $infile > $outfile 2> /dev/null || true - CODE=$(jq -r -e ".code // 0" < $outfile) + anastasis-reducer sync_providers < "$infile" > "$outfile" 2> /dev/null || true + CODE=$(jq -r -e ".code // 0" < "$outfile") # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED # FIXME: Temporary workaround for C reducer. See #7227. - if test "$CODE" = "8420"; then + if [ "$CODE" = "8420" ] + then # restore previous non-error state - cat $infile > $outfile + cat "$infile" > "$outfile" break fi # ANASTASIS_REDUCER_ACTION_INVALID - if test "$CODE" = "8400"; then + if [ "$CODE" = "8400" ] + then # restore previous non-error state - cat $infile > $outfile + cat "$infile" > "$outfile" break fi - if test "$CODE" != "0"; then + if [ "$CODE" != "0" ] + then exit_fail "Expected no error or 8420/8400, got $CODE" fi - cat $outfile > $infile + cat "$outfile" > "$infile" done echo "Providers synced." } @@ -65,211 +104,56 @@ CONF_4="test_anastasis_reducer_4.conf" # Configuration file will be edited, so we create one # from the template. -CONF=`mktemp test_reducerXXXXXX.conf` -cp test_reducer.conf $CONF +CONF="$(mktemp -p "${TMPDIR:-/tmp}" test_reducerXXXXXX.conf)" +cp test_reducer.conf "$CONF" -TMP_DIR=`mktemp -d keys-tmp-XXXXXX` -WALLET_DB=`mktemp test_reducer_walletXXXXXX.json` -B1FILE=`mktemp test_reducer_stateB1XXXXXX` -B2FILE=`mktemp test_reducer_stateB2XXXXXX` -R1FILE=`mktemp test_reducer_stateR1XXXXXX` -R2FILE=`mktemp test_reducer_stateR2XXXXXX` +TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d keys-tmp-XXXXXX) +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_walletXXXXXX.json) +B1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB1XXXXXX) +B2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateB2XXXXXX) +R1FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR1XXXXXX) +R2FILE=$(mktemp -p "${TMPDIR:-/tmp}" test_reducer_stateR2XXXXXX) # Install cleanup handler (except for kill -9) trap cleanup EXIT -# Check we can actually run -echo -n "Testing for jq" -jq -h > /dev/null || exit_skip "jq required" -echo " FOUND" -echo -n "Testing for anastasis-reducer ..." -anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required" -echo " FOUND" - -echo -n "Testing for taler" -taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" -taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" -echo " FOUND" - -echo -n "Testing for taler-bank-manage" -taler-bank-manage --help >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" -echo -n "Testing for taler-wallet-cli" -taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" - -echo -n "Testing for anastasis-httpd" -anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" - echo -n "Initialize anastasis database ..." # Name of the Postgres database we will use for the script. # Will be dropped, do NOT use anything that might be used # elsewhere -TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` -TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` - -dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1" -anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log -dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2" -anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log -dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3" -anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log -dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true -createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4" -anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log - -echo " OK" - -echo -n "Generating Taler auditor, exchange and merchant configurations ..." - -DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME` -rm -rf $DATA_DIR - -# obtain key configuration data -MASTER_PRIV_FILE=`taler-config -f -c $CONF -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE"` -MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE` -mkdir -p $MASTER_PRIV_DIR -gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null -MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE` -EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL` -MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT` -MERCHANT_URL=http://localhost:${MERCHANT_PORT}/ -BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT` -BANK_URL=http://localhost:${BANK_PORT}/ -AUDITOR_URL=http://localhost:8083/ -AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE` -AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE` -mkdir -p $AUDITOR_PRIV_DIR -gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null -AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE` - -# patch configuration -TALER_DB=talercheck -taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB -taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB -taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s bank -o database -V postgres:///$TALER_DB -taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/" -taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/" - -echo " OK" - -echo -n "Setting up exchange ..." - -# reset database -dropdb $TALER_DB >/dev/null 2>/dev/null || true -createdb $TALER_DB || exit_skip "Could not create database $TALER_DB" -taler-exchange-dbinit -c $CONF -taler-merchant-dbinit -c $CONF -taler-auditor-dbinit -c $CONF -taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL - -echo " OK" - -# Launch services -echo -n "Launching taler services ..." -taler-bank-manage-testing $CONF postgres:///$TALER_DB serve > taler-bank.log 2> taler-bank.err & -taler-exchange-secmod-eddsa -c $CONF 2> taler-exchange-secmod-eddsa.log & -taler-exchange-secmod-rsa -c $CONF 2> taler-exchange-secmod-rsa.log & -taler-exchange-secmod-cs -c $CONF 2> taler-exchange-secmod-cs.log & -taler-exchange-httpd -c $CONF 2> taler-exchange-httpd.log & -taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log & -taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log & -taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log & +TARGET_DB_1=$(anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_2=$(anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_3=$(anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") +TARGET_DB_4=$(anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") + +dropdb "$TARGET_DB_1" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_1" || exit_skip "Could not create database $TARGET_DB_1" +anastasis-dbinit -c "$CONF_1" 2> anastasis-dbinit_1.log +dropdb "$TARGET_DB_2" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_2" || exit_skip "Could not create database $TARGET_DB_2" +anastasis-dbinit -c "$CONF_2" 2> anastasis-dbinit_2.log +dropdb "$TARGET_DB_3" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_3" || exit_skip "Could not create database $TARGET_DB_3" +anastasis-dbinit -c "$CONF_3" 2> anastasis-dbinit_3.log +dropdb "$TARGET_DB_4" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB_4" || exit_skip "Could not create database $TARGET_DB_4" +anastasis-dbinit -c "$CONF_4" 2> anastasis-dbinit_4.log echo " OK" echo -n "Launching anastasis services ..." PREFIX="" #valgrind -$PREFIX anastasis-httpd -c $CONF_1 2> anastasis-httpd_1.log & -$PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log & -$PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log & -$PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log & - -# Wait for bank to be available (usually the slowest) -for n in `seq 1 50` -do - echo -n "." - sleep 0.2 - OK=0 - # bank - wget --tries=1 --timeout=1 http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch services (bank)" -fi - -# Wait for all other taler services to be available -for n in `seq 1 50` -do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue - # merchant - wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue - # auditor - wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch taler services" -fi +$PREFIX anastasis-httpd -c "$CONF_1" 2> anastasis-httpd_1.log & +$PREFIX anastasis-httpd -c "$CONF_2" 2> anastasis-httpd_2.log & +$PREFIX anastasis-httpd -c "$CONF_3" 2> anastasis-httpd_3.log & +$PREFIX anastasis-httpd -c "$CONF_4" 2> anastasis-httpd_4.log & echo "OK" -echo -n "Setting up keys ..." -taler-exchange-offline -c $CONF \ - download \ - sign \ - enable-account payto://x-taler-bank/localhost/Exchange \ - enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \ - wire-fee now x-taler-bank TESTKUDOS:0.01 TESTKUDOS:0.01 TESTKUDOS:0.01 \ - upload &> taler-exchange-offline.log - -echo -n "." - -for n in `seq 1 3` -do - echo -n "." - OK=0 - wget --tries=1 --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to setup keys" -fi - -echo " OK" - -echo -n "Setting up auditor signatures ..." -taler-auditor-offline -c $CONF \ - download sign upload &> taler-auditor-offline.log -echo " OK" - echo -n "Waiting for anastasis services ..." # Wait for anastasis services to be available -for n in `seq 1 50` +for n in $(seq 1 50) do echo -n "." sleep 0.1 @@ -286,7 +170,7 @@ do break done -if [ 1 != $OK ] +if [ 1 != "$OK" ] then exit_skip "Failed to launch anastasis services" fi @@ -295,31 +179,32 @@ echo "OK" echo -n "Configuring merchant instance ..." # Setup merchant -curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_ms" : 3600000},"default_pay_delay":{"d_ms": 3600000}}' http://localhost:9966/management/instances +curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances +curl -H "Content-Type: application/json" -X POST -d '{"payto_uri":"'"$MERCHANT_PAYTO"'"}' http://localhost:9966/private/accounts echo " DONE" echo -n "Running backup logic ...," -anastasis-reducer -b > $B1FILE +anastasis-reducer -b > "$B1FILE" echo -n "." anastasis-reducer -a \ '{"continent": "Demoworld"}' \ - select_continent < $B1FILE > $B2FILE + select_continent < "$B1FILE" > "$B2FILE" echo -n "." anastasis-reducer -a \ '{"country_code": "xx"}' \ - select_country < $B2FILE > $B1FILE + select_country < "$B2FILE" > "$B1FILE" echo -n "." anastasis-reducer -a \ '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01"}}' \ - enter_user_attributes < $B1FILE > $B2FILE -cat $B2FILE > $B1FILE + enter_user_attributes < "$B1FILE" > "$B2FILE" +cat "$B2FILE" > "$B1FILE" echo -n "," -sync_providers $B1FILE $B2FILE +sync_providers "$B1FILE" "$B2FILE" echo -n "," # "91GPWWR" encodes "Hans" anastasis-reducer -a \ @@ -328,7 +213,7 @@ anastasis-reducer -a \ "instructions": "What is your name?", "challenge": "91GPWWR" } }' \ - add_authentication < $B2FILE > $B1FILE + add_authentication < "$B2FILE" > "$B1FILE" echo -n "." # "64S36" encodes "123" anastasis-reducer -a \ @@ -337,7 +222,7 @@ anastasis-reducer -a \ "instructions": "How old are you?", "challenge": "64S36" } }' \ - add_authentication < $B1FILE > $B2FILE + add_authentication < "$B1FILE" > "$B2FILE" echo -n "." # "9NGQ4WR" encodes "Mars" anastasis-reducer -a \ @@ -346,155 +231,177 @@ anastasis-reducer -a \ "instructions": "Where do you live?", "challenge": "9NGQ4WR" } }' \ - add_authentication < $B2FILE > $B1FILE + add_authentication < "$B2FILE" > "$B1FILE" echo -n "." # Finished adding authentication methods anastasis-reducer \ - next < $B1FILE > $B2FILE + next < "$B1FILE" > "$B2FILE" echo -n "," # Finished policy review anastasis-reducer \ - next < $B2FILE > $B1FILE + next < "$B2FILE" > "$B1FILE" echo -n "." # Note: 'secret' must here be a Crockford base32-encoded value anastasis-reducer -a \ '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \ - enter_secret < $B1FILE > $B2FILE -mv $B2FILE $B1FILE -anastasis-reducer next $B1FILE $B2FILE + enter_secret < "$B1FILE" > "$B2FILE" +mv "$B2FILE" "$B1FILE" +anastasis-reducer next "$B1FILE" "$B2FILE" echo " OK" echo -n "Preparing wallet" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'withdrawTestBalance' \ + +EXCHANGE_URL="$(taler-config -c "$CONF" -s exchange -o BASE_URL)" + +rm -f "$WALLET_DB" +taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" api --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:100", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL" \ + --arg BANK_URL "${BANK_URL}" \ --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2> /dev/null >/dev/null -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>/dev/null >/dev/null + )" 2> wallet-withdraw.err > wallet-withdraw.out +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish.err \ + >wallet-withdraw-finish.out echo " OK" echo -en "Making payments for truth uploads ... " -OBJECT_SIZE=`jq -r -e '.payments | length' < $B2FILE` -for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++)) +OBJECT_SIZE=$(jq -r -e '.payments | length' < "$B2FILE") +for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) do - PAY_URI=`jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < $B2FILE` + PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.payments[$INDEX]' < "$B2FILE") # run wallet CLI echo -n "$INDEX" - taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>/dev/null >/dev/null + taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + handle-uri "$PAY_URI" \ + -y \ + 2>"wallet-pay-truth-$INDEX.err" \ + >"wallet-pay-truth-$INDEX.out" echo -n ", " done echo "OK" -echo -e "Running wallet run-pending..." -taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>/dev/null >/dev/null +echo -e "Running wallet run-until-done..." +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>"wallet-pay-truth-finish-$INDEX.err" \ + >"wallet-pay-truth-finish-$INDEX.out" echo -e "Payments done" -export B2FILE -export B1FILE - echo -en "Try to upload again ..." -$PREFIX anastasis-reducer pay $B2FILE $B1FILE -mv $B1FILE $B2FILE +$PREFIX anastasis-reducer pay "$B2FILE" "$B1FILE" +mv "$B1FILE" "$B2FILE" echo " OK" echo -en "Making payments for policy uploads ... " -OBJECT_SIZE=`jq -r -e '.policy_payment_requests | length' < $B2FILE` -for ((INDEX=0; INDEX < $OBJECT_SIZE; INDEX++)) +OBJECT_SIZE=$(jq -r -e '.policy_payment_requests | length' < "$B2FILE") +for ((INDEX=0; INDEX < "$OBJECT_SIZE"; INDEX++)) do - PAY_URI=`jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < $B2FILE` + PAY_URI=$(jq --argjson INDEX $INDEX -r -e '.policy_payment_requests[$INDEX].payto' < "$B2FILE") # run wallet CLI echo -n "$INDEX" - taler-wallet-cli --wallet-db=$WALLET_DB handle-uri $PAY_URI -y 2>/dev/null >/dev/null + taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + handle-uri "$PAY_URI" \ + -y \ + 2>"wallet-pay-policy-$INDEX.err" \ + >"wallet-pay-policy-$INDEX.out" echo -n ", " done echo " OK" -echo -en "Running wallet run-pending..." -taler-wallet-cli --wallet-db=$WALLET_DB run-pending 2>/dev/null >/dev/null +echo -en "Running wallet run-until-done..." +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-pay-policy-finish.err \ + >wallet-pay-policy-finish.out echo -e " payments DONE" echo -en "Try to upload again ..." anastasis-reducer \ - pay < $B2FILE > $B1FILE + pay < "$B2FILE" > "$B1FILE" echo " OK: Backup finished" echo -n "Final backup checks ..." -STATE=`jq -r -e .backup_state < $B1FILE` -if test "$STATE" != "BACKUP_FINISHED" +STATE=$(jq -r -e .backup_state < "$B1FILE") +if [ "$STATE" != "BACKUP_FINISHED" ] then exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'" fi -jq -r -e .core_secret < $B1FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success" +jq -r -e .core_secret < "$B1FILE" > /dev/null && exit_fail "'core_secret' was not cleared upon success" echo " OK" echo -n "Running recovery basic logic ..." -anastasis-reducer -r > $R1FILE +anastasis-reducer -r > "$R1FILE" anastasis-reducer -a \ '{"continent": "Demoworld"}' \ - select_continent < $R1FILE > $R2FILE + select_continent < "$R1FILE" > "$R2FILE" anastasis-reducer -a \ '{"country_code": "xx"}' \ - select_country < $R2FILE > $R1FILE -anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE + select_country < "$R2FILE" > "$R1FILE" +anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < "$R1FILE" > "$R2FILE" -STATE=`jq -r -e .recovery_state < $R2FILE` -if test "$STATE" != "SECRET_SELECTING" +STATE=$(jq -r -e .recovery_state < "$R2FILE") +if [ "$STATE" != "SECRET_SELECTING" ] then exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'" fi echo " OK" echo -n "Adding provider (to ensure it is loaded)" -anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < $R2FILE > $R1FILE +anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < "$R2FILE" > "$R1FILE" echo " OK" echo -n "Selecting secret to recover" -anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < $R1FILE > $R2FILE +anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < "$R1FILE" > "$R2FILE" -STATE=`jq -r -e .recovery_state < $R2FILE` -if test "$STATE" != "CHALLENGE_SELECTING" +STATE=$(jq -r -e .recovery_state < "$R2FILE") +if [ "$STATE" != "CHALLENGE_SELECTING" ] then exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'" fi echo " OK" -cat $R2FILE > $R1FILE +cat "$R2FILE" > "$R1FILE" -sync_providers $R1FILE $R2FILE +sync_providers "$R1FILE" "$R2FILE" echo -n "Running challenge logic ..." -UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE` -UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE` -UUID2=`jq -r -e .recovery_information.challenges[2].uuid < $R2FILE` -UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE` -UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE` -UUID2Q=`jq -r -e .recovery_information.challenges[2].instructions < $R2FILE` +UUID0=$(jq -r -e .recovery_information.challenges[0].uuid < "$R2FILE") +UUID1=$(jq -r -e .recovery_information.challenges[1].uuid < "$R2FILE") +UUID2=$(jq -r -e .recovery_information.challenges[2].uuid < "$R2FILE") +#UUID0Q=$(jq -r -e .recovery_information.challenges[0].instructions < "$R2FILE") +UUID1Q=$(jq -r -e .recovery_information.challenges[1].instructions < "$R2FILE") +UUID2Q=$(jq -r -e .recovery_information.challenges[2].instructions < "$R2FILE") -if test "$UUID2Q" = 'How old are you?' +if [ "$UUID2Q" = 'How old are you?' ] then AGE_UUID=$UUID2 -elif test "$UUID1Q" = 'How old are you?' +elif [ "$UUID1Q" = 'How old are you?' ] then AGE_UUID=$UUID1 else AGE_UUID=$UUID0 fi -if test "$UUID2Q" = 'What is your name?' +if [ "$UUID2Q" = 'What is your name?' ] then NAME_UUID=$UUID2 -elif test "$UUID1Q" = 'What is your name?' +elif [ "$UUID1Q" = 'What is your name?' ] then NAME_UUID=$UUID1 else @@ -508,10 +415,10 @@ anastasis-reducer -a \ }' \ --arg UUID "$NAME_UUID" )" \ - select_challenge < $R2FILE > $R1FILE + select_challenge < "$R2FILE" > "$R1FILE" anastasis-reducer -a '{"answer": "Hans"}' \ - solve_challenge < $R1FILE > $R2FILE + solve_challenge < "$R1FILE" > "$R2FILE" anastasis-reducer -a \ "$(jq -n ' @@ -520,34 +427,34 @@ anastasis-reducer -a \ }' \ --arg UUID "$AGE_UUID" )" \ - select_challenge < $R2FILE > $R1FILE + select_challenge < "$R2FILE" > "$R1FILE" anastasis-reducer -a '{"answer": "123"}' \ - solve_challenge < $R1FILE > $R2FILE + solve_challenge < "$R1FILE" > "$R2FILE" echo " OK" echo -n "Checking recovered secret ..." # finally: check here that we recovered the secret... -STATE=`jq -r -e .recovery_state < $R2FILE` -if test "$STATE" != "RECOVERY_FINISHED" +STATE=$(jq -r -e .recovery_state < "$R2FILE") +if [ "$STATE" != "RECOVERY_FINISHED" ] then - jq -e . $R2FILE + jq -e . "$R2FILE" exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'" fi -SECRET=`jq -r -e .core_secret.value < $R2FILE` -if test "$SECRET" != "VERYHARDT0GVESSSECRET" +SECRET=$(jq -r -e .core_secret.value < "$R2FILE") +if [ "$SECRET" != "VERYHARDT0GVESSSECRET" ] then - jq -e . $R2FILE + jq -e . "$R2FILE" exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'" fi -MIME=`jq -r -e .core_secret.mime < $R2FILE` -if test "$MIME" != "text/plain" +MIME=$(jq -r -e .core_secret.mime < "$R2FILE") +if [ "$MIME" != "text/plain" ] then - jq -e . $R2FILE + jq -e . "$R2FILE" exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'" fi diff --git a/src/cli/test_anastasis_reducer_recovery_no_pay.sh b/src/cli/test_anastasis_reducer_recovery_no_pay.sh index 12ac7e9..42f5b0c 100755 --- a/src/cli/test_anastasis_reducer_recovery_no_pay.sh +++ b/src/cli/test_anastasis_reducer_recovery_no_pay.sh @@ -67,8 +67,8 @@ CONF_4="test_anastasis_reducer_free_4.conf" # Configuration file will be edited, so we create one # from the template. -CONF=`mktemp test_reducerXXXXXX.conf` -cp test_reducer.conf $CONF +CONF=$(mktemp test_reducerXXXXXX.conf) +cp test_reducer.conf "$CONF" TMP_DIR=`mktemp -d keys-tmp-XXXXXX` B1FILE=`mktemp test_reducer_stateB1XXXXXX` @@ -121,10 +121,10 @@ echo " OK" echo -n "Launching anastasis services ..." PREFIX="" #valgrind -$PREFIX anastasis-httpd -c $CONF_1 2> anastasis-httpd_1.log & -$PREFIX anastasis-httpd -c $CONF_2 2> anastasis-httpd_2.log & -$PREFIX anastasis-httpd -c $CONF_3 2> anastasis-httpd_3.log & -$PREFIX anastasis-httpd -c $CONF_4 2> anastasis-httpd_4.log & +$PREFIX anastasis-httpd -L DEBUG -c $CONF_1 2> anastasis-httpd_1.log & +$PREFIX anastasis-httpd -L DEBUG -c $CONF_2 2> anastasis-httpd_2.log & +$PREFIX anastasis-httpd -L DEBUG -c $CONF_3 2> anastasis-httpd_3.log & +$PREFIX anastasis-httpd -L DEBUG -c $CONF_4 2> anastasis-httpd_4.log & echo -n "Waiting for anastasis services ..." @@ -180,7 +180,7 @@ anastasis-reducer -a \ "instructions": "What is your name?", "challenge": "91GPWWR" } }' \ - add_authentication < $B2FILE > $B1FILE + add_authentication < $B2FILE > $B1FILE echo -n "." # "64S36" encodes "123" anastasis-reducer -a \ diff --git a/src/cli/test_iban.sh b/src/cli/test_iban.sh index 8278961..207d2d5 100755 --- a/src/cli/test_iban.sh +++ b/src/cli/test_iban.sh @@ -1,4 +1,5 @@ #!/bin/bash +# This file is in the public domain. set -eu #set -x @@ -18,65 +19,64 @@ function exit_fail() { # Cleanup to run whenever we exit function cleanup() { - for n in `jobs -p` + for n in $(jobs -p) do - kill $n 2> /dev/null || true + kill "$n" 2> /dev/null || true done - rm -rf $CONF $R1FILE $R2FILE $B1FILE $B2FILE + rm -rf "$CONF" "$R1FILE" "$R2FILE" "$B1FILE" "$B2FILE" wait } # $1=ebics username, $2=ebics partner name, $3=person name, $4=sandbox bank account name, $5=iban function prepare_sandbox_account() { - echo -n "Activating ebics subscriber $1 at the sandbox ..." - libeufin-cli \ - sandbox --sandbox-url=$SANDBOX_URL \ - ebicssubscriber create \ - --host-id=$EBICS_HOST \ - --partner-id=$2 \ - --user-id=$1 + echo -n "Registering $4 to the Sandbox..." + export LIBEUFIN_SANDBOX_USERNAME="$4" + export LIBEUFIN_SANDBOX_PASSWORD=unused + libeufin-cli sandbox --sandbox-url="$SANDBOX_URL" \ + demobank register --name "$3" --iban "$5" echo " OK" - echo -n "Giving a bank account ($4) to $1 ..." - libeufin-cli \ - sandbox --sandbox-url=$SANDBOX_URL \ - ebicsbankaccount create \ - --iban=$5 \ - --bic="BCMAESM1XXX"\ - --person-name="$3" \ - --account-name=$4 \ - --ebics-user-id=$1 \ - --ebics-host-id=$EBICS_HOST \ - --ebics-partner-id=$2 + echo -n "Associating a EBICS subscriber to $4..." + export LIBEUFIN_SANDBOX_USERNAME=admin + libeufin-cli sandbox --sandbox-url="$SANDBOX_URL" demobank new-ebicssubscriber \ + --host-id "$EBICS_HOST" \ + --user-id "$1" --partner-id "$2" \ + --bank-account "$4" # that's a username _and_ a bank account name echo " OK" + + unset LIBEUFIN_SANDBOX_USERNAME + unset LIBEUFIN_SANDBOX_PASSWORD } function sync_providers() { - infile=$1 - outfile=$2 + infile="$1" + outfile="$2" echo "Synchronizing providers" # Sync with providers (up to 3 providers aren't synced here) for x in 1 2 3; do echo "Synchronizing providers (round $x)" - anastasis-reducer sync_providers < $infile > $outfile 2> /dev/null || true + anastasis-reducer sync_providers < "$infile" > "$outfile" 2> /dev/null || true CODE=$(jq -r -e ".code // 0" < $outfile) # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED # FIXME: Temporary workaround for C reducer. See #7227. - if test "$CODE" = "8420"; then + if [ "$CODE" = "8420" ] + then # restore previous non-error state - cat $infile > $outfile + cp "$infile" "$outfile" break fi # ANASTASIS_REDUCER_ACTION_INVALID - if test "$CODE" = "8400"; then + if [ "$CODE" = "8400" ] + then # restore previous non-error state - cat $infile > $outfile + cp "$infile" "$outfile" break fi - if test "$CODE" != "0"; then + if [ "$CODE" != "0" ] + then exit_fail "Expected no error or 8420/8400, got $CODE" fi - cat $outfile > $infile + cp "$outfile" "$infile" done echo "Providers synced." } @@ -91,13 +91,19 @@ trap cleanup EXIT # to pass through the Nexus+Ebics layer to issue the payment # $1 = amount ($CURRENCY:X.Y), $2 = subject. function wire_transfer_to_anastasis() { + echo -n "Initiating wire transfer ..." libeufin-sandbox make-transaction \ --debit-account=sandbox-account-debit \ - --credit-account=sandbox-account-credit "$1" "$2" - # Sync nexus with sandbox - export LIBEUFIN_NEXUS_USERNAME=$CREDIT_USERNAME - export LIBEUFIN_NEXUS_PASSWORD=$CREDIT_PASSWORD - libeufin-cli accounts fetch-transactions nexus-bankaccount-credit > /dev/null + --credit-account=sandbox-account-credit "$1" "$2" &> libeufin-transfer-initiate.out + echo " OK" + # FIXME-MS: the following command reports that it did not + # sync any transactions, even though presumably we just + # made one in the one above (which succeeded...) + echo -n "Syncing nexus with sandbox ..." + export LIBEUFIN_NEXUS_USERNAME="$CREDIT_USERNAME" + export LIBEUFIN_NEXUS_PASSWORD="$CREDIT_PASSWORD" + libeufin-cli accounts fetch-transactions nexus-bankaccount-credit &> libeufin-transfer-fetch.out + echo " OK" } # $1 = facade base URL. Merely a debug utility. @@ -112,43 +118,33 @@ function prepare_nexus_account() { echo -n "Making bank connection $3 ..." libeufin-cli connections new-ebics-connection \ --ebics-url="${SANDBOX_URL}ebicsweb" \ - --host-id=$EBICS_HOST \ - --partner-id=$2 \ - --ebics-user-id=$1 \ + --host-id="$EBICS_HOST" \ + --partner-id="$2" \ + --ebics-user-id="$1" \ $3 > /dev/null echo " OK" echo -n "Connecting $3 ..." - libeufin-cli connections connect $3 > /dev/null + libeufin-cli connections connect "$3" > /dev/null echo " OK" echo -n "Importing Sandbox bank account ($5) to Nexus ($4) ..." - libeufin-cli connections download-bank-accounts $3 > /dev/null + libeufin-cli connections download-bank-accounts "$3" > /dev/null libeufin-cli connections import-bank-account \ - --offered-account-id=$5 --nexus-bank-account-id=$4 $3 > /dev/null + --offered-account-id="$5" --nexus-bank-account-id="$4" "$3" > /dev/null echo " OK" } -# $1 = facade name, $2 = bank connection to use, $3 = bank account name -# local to Nexus -function prepare_anastasis_facade() { - echo -n "Creating facade ..." - libeufin-cli facades new-anastasis-facade \ - --currency=$CURRENCY \ - --facade-name=$1 \ - $2 $3 - echo " OK" - # No need to setup facade permissions, as the anastasis client - # is superuser at Nexus. -} # Configuration file will be edited, so we create one # from the template. -CONF=`mktemp test_free_reducerXXXXXX.conf` -cp test_free_reducer.conf $CONF +CONF=$(mktemp test_free_reducerXXXXXX.conf) +cp test_free_reducer.conf "$CONF" + + -B1FILE=`mktemp test_reducer_stateB1XXXXXX` -B2FILE=`mktemp test_reducer_stateB2XXXXXX` -R1FILE=`mktemp test_reducer_stateR1XXXXXX` -R2FILE=`mktemp test_reducer_stateR2XXXXXX` +B1FILE=$(mktemp test_reducer_stateB1XXXXXX) +B2FILE=$(mktemp test_reducer_stateB2XXXXXX) +R1FILE=$(mktemp test_reducer_stateR1XXXXXX) +R2FILE=$(mktemp test_reducer_stateR2XXXXXX) export CONF export B2FILE @@ -176,23 +172,40 @@ echo -n "Testing for anastasis-reducer ..." anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required" echo " FOUND" -export LIBEUFIN_NEXUS_DB_CONNECTION="jdbc:sqlite:$(mktemp -u /tmp/nexus-db-XXXXXX.sqlite)" -export LIBEUFIN_SANDBOX_DB_CONNECTION="jdbc:sqlite:$(mktemp -u /tmp/sandbox-db-XXXXXX.sqlite)" +echo -n "Initialize Anastasis database ..." +# Name of the Postgres database we will use for the script. +# Will be dropped, do NOT use anything that might be used +# elsewhere + +TARGET_DB=$(anastasis-config -c "$CONF" -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///") + +dropdb "$TARGET_DB" >/dev/null 2>/dev/null || true +createdb "$TARGET_DB" || exit_skip "Could not create database $TARGET_DB" +anastasis-dbinit -c "$CONF" 2> anastasis-dbinit.log + +echo " OK" + + +export LIBEUFIN_NEXUS_DB_CONNECTION="postgres:///anastasischeck" +export LIBEUFIN_SANDBOX_DB_CONNECTION="postgres:///anastasischeck" NEXUS_URL="http://localhost:5001/" SANDBOX_URL="http://localhost:5000/" echo -n "Starting Nexus ..." libeufin-nexus serve &> nexus.log & nexus_pid=$! -if ! curl -s --retry 5 --retry-connrefused $NEXUS_URL > /dev/null; then +if ! curl -s --retry 5 --retry-connrefused "$NEXUS_URL" > /dev/null; then exit_skip "Could not launch Nexus" fi echo " OK" +echo -n "Configuring Sandbox..." +libeufin-sandbox config default &> sandbox-config.log +echo " OK" echo -n "Starting Sandbox ..." -libeufin-sandbox serve --no-auth &> sandbox.log & +libeufin-sandbox serve --no-auth &> sandbox-serve.log & sandbox_pid=$! -if ! curl -s --retry 5 --retry-connrefused $SANDBOX_URL > /dev/null; then +if ! curl -s --retry 5 --retry-connrefused "$SANDBOX_URL" > /dev/null; then exit_skip "Could not launch Sandbox" fi echo " OK" @@ -204,11 +217,11 @@ EBICS_HOST="ebicstesthost" export IBAN_CREDIT="DE89370400440532013000" export IBAN_DEBIT="FR1420041010050500013M02606" -echo -n "Preparing Sandbox ..." +echo -n "Preparing Sandbox (creating the EBICS host) ..." libeufin-cli \ - sandbox --sandbox-url=$SANDBOX_URL \ + sandbox --sandbox-url="$SANDBOX_URL" \ ebicshost create \ - --host-id=$EBICS_HOST + --host-id="$EBICS_HOST" echo " OK" PERSON_CREDIT_NAME="Person Credit" @@ -219,32 +232,32 @@ prepare_sandbox_account \ ebicspartnerCredit \ "${PERSON_CREDIT_NAME}" \ sandbox-account-credit \ - $IBAN_CREDIT + "$IBAN_CREDIT" prepare_sandbox_account \ ebicsuserDebit \ ebicspartnerDebit \ "Person Debit" \ sandbox-account-debit \ - $IBAN_DEBIT + "$IBAN_DEBIT" echo "Sandbox preparation done" echo -n "Preparing Nexus ..." -export LIBEUFIN_NEXUS_URL=$NEXUS_URL +export LIBEUFIN_NEXUS_URL="$NEXUS_URL" # Make debit user, will buy Anastasis services. DEBIT_USERNAME=anastasis-debit-user DEBIT_PASSWORD=anastasis-debit-password -libeufin-nexus superuser $DEBIT_USERNAME --password=$DEBIT_PASSWORD +libeufin-nexus superuser "$DEBIT_USERNAME" --password="$DEBIT_PASSWORD" echo " OK" -export LIBEUFIN_NEXUS_USERNAME=$DEBIT_USERNAME -export LIBEUFIN_NEXUS_PASSWORD=$DEBIT_PASSWORD +export LIBEUFIN_NEXUS_USERNAME="$DEBIT_USERNAME" +export LIBEUFIN_NEXUS_PASSWORD="$DEBIT_PASSWORD" # Make credit user, will be Anastasis client. CREDIT_USERNAME=anastasis-credit-user CREDIT_PASSWORD=anastasis-credit-password echo -n "Create credit user (for anastasis) at Nexus ..." -libeufin-nexus superuser $CREDIT_USERNAME --password=$CREDIT_PASSWORD +libeufin-nexus superuser "$CREDIT_USERNAME" --password="$CREDIT_PASSWORD" echo " OK" -export LIBEUFIN_NEXUS_USERNAME=$CREDIT_USERNAME -export LIBEUFIN_NEXUS_PASSWORD=$CREDIT_PASSWORD +export LIBEUFIN_NEXUS_USERNAME="$CREDIT_USERNAME" +export LIBEUFIN_NEXUS_PASSWORD="$CREDIT_PASSWORD" prepare_nexus_account \ ebicsuserCredit \ @@ -255,7 +268,7 @@ prepare_nexus_account \ echo -n "Create facade ..." libeufin-cli facades new-anastasis-facade \ - --currency=$CURRENCY \ + --currency="$CURRENCY" \ --facade-name=facade-credit \ bankconnection-credit nexus-bankaccount-credit echo " OK" @@ -263,41 +276,29 @@ FACADE_URL=$(libeufin-cli facades list | jq .facades[0].baseUrl | tr -d \") ## Reach facade with: $FACADE_URL + $CREDIT_USERNAME + $CREDIT_PASSWORD -echo -n "Initialize Anastasis database ..." -# Name of the Postgres database we will use for the script. -# Will be dropped, do NOT use anything that might be used -# elsewhere - -TARGET_DB=`anastasis-config -c $CONF -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` - -dropdb $TARGET_DB >/dev/null 2>/dev/null || true -createdb $TARGET_DB || exit_skip "Could not create database $TARGET_DB" -anastasis-dbinit -c $CONF 2> anastasis-dbinit.log - -echo " OK" echo -n "Configuring Anastasis IBAN account ..." -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o CREDIT_IBAN \ -V "${IBAN_CREDIT}" -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o BUSINESS_NAME \ -V "${PERSON_CREDIT_NAME}" -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o WIRE_GATEWAY_URL \ -V "${FACADE_URL}" -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o WIRE_GATEWAY_AUTH_METHOD \ -V "basic" -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o USERNAME \ -V "${LIBEUFIN_NEXUS_USERNAME}" -anastasis-config -c $CONF \ +anastasis-config -c "$CONF" \ -s authorization-iban \ -o PASSWORD \ -V "${LIBEUFIN_NEXUS_PASSWORD}" @@ -305,12 +306,12 @@ echo " OK" echo -n "Launching Anastasis service ..." PREFIX="" #valgrind -$PREFIX anastasis-httpd -c $CONF -L INFO 2> anastasis-httpd_1.log & +$PREFIX anastasis-httpd -c "$CONF" -L INFO 2> anastasis-httpd_1.log & echo " OK" echo -n "Waiting for Anastasis service ..." # Wait for Anastasis service to be available -for n in `seq 1 50` +for n in $(seq 1 50) do echo -n "." sleep 0.1 @@ -327,15 +328,15 @@ fi echo "OK" echo -n "Running backup logic ...," -anastasis-reducer -b > $B1FILE +anastasis-reducer -b > "$B1FILE" echo -n "." anastasis-reducer -a \ '{"continent": "Demoworld"}' \ - select_continent < $B1FILE > $B2FILE + select_continent < "$B1FILE" > "$B2FILE" echo -n "." anastasis-reducer -a \ '{"country_code": "xx" }' \ - select_country < $B2FILE > $B1FILE 2>> test_reducer.err + select_country < "$B2FILE" > "$B1FILE" 2>> test_reducer.err echo -n "." anastasis-reducer -a \ @@ -343,12 +344,12 @@ anastasis-reducer -a \ "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01"}}' \ - enter_user_attributes < $B1FILE > $B2FILE 2>> test_reducer.err + enter_user_attributes < "$B1FILE" > "$B2FILE" 2>> test_reducer.err echo -n "," -cat $B2FILE > $B1FILE -sync_providers $B1FILE $B2FILE +cat "$B2FILE" > "$B1FILE" +sync_providers "$B1FILE" "$B2FILE" echo -n "," -BASEIBAN=`echo -n $IBAN_DEBIT | gnunet-base32` +BASEIBAN=$(echo -n $IBAN_DEBIT | gnunet-base32) anastasis-reducer -a \ "$(jq -n '{ authentication_method: { type: "iban", @@ -357,7 +358,7 @@ anastasis-reducer -a \ } }' \ --arg CHALLENGE "$BASEIBAN" )" \ - add_authentication < $B2FILE > $B1FILE 2>> test_reducer.err + add_authentication < "$B2FILE" > "$B1FILE" 2>> test_reducer.err echo -n "." # "91GPWWR" encodes "Hans" @@ -367,82 +368,82 @@ anastasis-reducer -a \ "instructions": "What is your name?", "challenge": "91GPWWR" } }' \ - add_authentication < $B1FILE > $B2FILE 2>> test_reducer.err + add_authentication < "$B1FILE" > "$B2FILE" 2>> test_reducer.err echo -n "." -mv $B2FILE $B1FILE +mv "$B2FILE" "$B1FILE" # Finished adding authentication methods anastasis-reducer \ - next < $B1FILE > $B2FILE 2>> test_reducer.err + next < "$B1FILE" > "$B2FILE" 2>> test_reducer.err echo -n "," # Finished policy review anastasis-reducer \ - next < $B2FILE > $B1FILE 2>> test_reducer.err + next < "$B2FILE" > "$B1FILE" 2>> test_reducer.err echo -n "." # Note: 'secret' must here be a Crockford base32-encoded value anastasis-reducer -a \ '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \ - enter_secret < $B1FILE > $B2FILE 2>> test_reducer.err -mv $B2FILE $B1FILE -anastasis-reducer next < $B1FILE > $B2FILE 2>> test_reducer.err + enter_secret < "$B1FILE" > "$B2FILE" 2>> test_reducer.err +mv "$B2FILE" "$B1FILE" +anastasis-reducer next < "$B1FILE" > "$B2FILE" 2>> test_reducer.err echo " OK" echo -n "Final backup checks ..." -STATE=`jq -r -e .backup_state < $B2FILE` -if test "$STATE" != "BACKUP_FINISHED" +STATE=$(jq -r -e .backup_state < "$B2FILE") +if [ "$STATE" != "BACKUP_FINISHED" ] then exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'" fi -jq -r -e .core_secret < $B2FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success" +jq -r -e .core_secret < "$B2FILE" > /dev/null && exit_fail "'core_secret' was not cleared upon success" echo " OK" echo -n "Running recovery basic logic ..." -anastasis-reducer -r > $R1FILE +anastasis-reducer -r > "$R1FILE" anastasis-reducer -a \ '{"continent": "Demoworld"}' \ - select_continent < $R1FILE > $R2FILE + select_continent < "$R1FILE" > "$R2FILE" anastasis-reducer -a \ '{"country_code": "xx", "currencies":["TESTKUDOS"]}' \ - select_country < $R2FILE > $R1FILE 2>> test_reducer.err -anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE 2>> test_reducer.err + select_country < "$R2FILE" > "$R1FILE" 2>> test_reducer.err +anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < "$R1FILE" > "$R2FILE" 2>> test_reducer.err -STATE=`jq -r -e .recovery_state < $R2FILE` -if test "$STATE" != "SECRET_SELECTING" +STATE=$(jq -r -e .recovery_state < "$R2FILE") +if [ "$STATE" != "SECRET_SELECTING" ] then exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'" fi echo " OK" echo -n "Adding provider (to ensure it is loaded)" -anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < $R2FILE > $R1FILE +anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < "$R2FILE" > "$R1FILE" echo " OK" echo -n "Selecting secret to recover" anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' \ - select_version < $R1FILE > $R2FILE 2>> test_reducer.err + select_version < "$R1FILE" > "$R2FILE" 2>> test_reducer.err -STATE=`jq -r -e .recovery_state < $R2FILE` -if test "$STATE" != "CHALLENGE_SELECTING" +STATE=$(jq -r -e .recovery_state < "$R2FILE") +if [ "$STATE" != "CHALLENGE_SELECTING" ] then exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'" fi echo " OK" -cat $R2FILE > $R1FILE -sync_providers $R1FILE $R2FILE +cp "$R2FILE" "$R1FILE" +sync_providers "$R1FILE" "$R2FILE" echo -n "Running challenge selection logic ..." -UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE` -UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE` -UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE` -UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE` +UUID0=$(jq -r -e .recovery_information.challenges[0].uuid < "$R2FILE") +UUID1=$(jq -r -e .recovery_information.challenges[1].uuid < "$R2FILE") +UUID0Q=$(jq -r -e .recovery_information.challenges[0].instructions < "$R2FILE") +UUID1Q=$(jq -r -e .recovery_information.challenges[1].instructions < "$R2FILE") -if test "$UUID1Q" = 'What is your name?' +if [ "$UUID1Q" = 'What is your name?' ] then NAME_UUID=$UUID1 IBAN_UUID=$UUID0 @@ -460,10 +461,10 @@ anastasis-reducer -a \ }' \ --arg UUID "$NAME_UUID" )" \ - select_challenge < $R2FILE > $R1FILE 2>> test_reducer.err + select_challenge < "$R2FILE" > "$R1FILE" 2>> test_reducer.err anastasis-reducer -a '{"answer": "Hans"}' \ - solve_challenge < $R1FILE > $R2FILE + solve_challenge < "$R1FILE" > "$R2FILE" echo "OK" echo -n "Solving IBAN challenge ..." @@ -475,28 +476,28 @@ anastasis-reducer -a \ }' \ --arg UUID "$IBAN_UUID" )" \ - select_challenge < $R2FILE > $R1FILE 2>> test_reducer.err + select_challenge < "$R2FILE" > "$R1FILE" 2>> test_reducer.err echo "OK" -METHOD=`jq -r -e .challenge_feedback.\"$IBAN_UUID\".state < $R1FILE` -if test "$METHOD" != "iban-instructions" +METHOD=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".state < "$R1FILE") +if [ "$METHOD" != "iban-instructions" ] then exit_fail "Expected method to be 'iban-instructions', got ${METHOD}" fi -ACC=`jq -r -e .challenge_feedback.\"$IBAN_UUID\".target_iban < $R1FILE` -if test "$ACC" != ${IBAN_CREDIT} +ACC=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".target_iban < "$R1FILE") +if [ "$ACC" != "${IBAN_CREDIT}" ] then exit_fail "Expected account to be ${IBAN_CREDIT}, got ${ACC}" fi anastasis-reducer \ - back < $R1FILE > $R2FILE 2>> test_reducer.err + back < "$R1FILE" > "$R2FILE" 2>> test_reducer.err -AMOUNT=`jq -r -e .challenge_feedback.\"$IBAN_UUID\".challenge_amount < $R1FILE` -SUBJECT=`jq -r -e .challenge_feedback.\"$IBAN_UUID\".wire_transfer_subject < $R1FILE` +AMOUNT=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".challenge_amount < "$R1FILE") +SUBJECT=$(jq -r -e .challenge_feedback.\"$IBAN_UUID\".wire_transfer_subject < "$R1FILE") echo -n "Performing authorization wire transfer ${SUBJECT} ..." wire_transfer_to_anastasis "${AMOUNT}" "${SUBJECT}" @@ -504,35 +505,35 @@ wire_transfer_to_anastasis "${AMOUNT}" "${SUBJECT}" echo " OK" echo -n "Triggering inbound check ..." -anastasis-helper-authorization-iban -c $CONF -t +anastasis-helper-authorization-iban -c "$CONF" -t -L INFO echo " OK" # Now we should get the secret... echo -n "Polling for recovery ..." -anastasis-reducer poll -L INFO < $R2FILE > $R1FILE +anastasis-reducer poll -L INFO < "$R2FILE" > "$R1FILE" echo " OK" echo -n "Checking recovered secret ..." # finally: check here that we recovered the secret... -STATE=`jq -r -e .recovery_state < $R1FILE` -if test "$STATE" != "RECOVERY_FINISHED" +STATE=$(jq -r -e .recovery_state < "$R1FILE") +if [ "$STATE" != "RECOVERY_FINISHED" ] then - jq -e . $R1FILE + jq -e . "$R1FILE" exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'" fi -SECRET=`jq -r -e .core_secret.value < $R1FILE` -if test "$SECRET" != "VERYHARDT0GVESSSECRET" +SECRET=$(jq -r -e .core_secret.value < "$R1FILE") +if [ "$SECRET" != "VERYHARDT0GVESSSECRET" ] then - jq -e . $R1FILE + jq -e . "$R1FILE" exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'" fi -MIME=`jq -r -e .core_secret.mime < $R1FILE` -if test "$MIME" != "text/plain" +MIME=$(jq -r -e .core_secret.mime < "$R1FILE") +if [ "$MIME" != "text/plain" ] then - jq -e . $R1FILE + jq -e . "$R1FILE" exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'" fi diff --git a/src/cli/test_reducer.conf b/src/cli/test_reducer.conf index e87313b..4f26a79 100644 --- a/src/cli/test_reducer.conf +++ b/src/cli/test_reducer.conf @@ -26,9 +26,10 @@ COST = TESTKUDOS:0.0 [exchange] +MASTER_PUBLIC_KEY = 3NX5DJDBD8XVGZYHV3PBF8C3Z4GK48XD59YY5GF3CZE8AJM04WSG +AML_THRESHOLD = TESTKUDOS:1000000 MAX_KEYS_CACHING = forever DB = postgres -MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv SERVE = tcp UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http UNIXPATH_MODE = 660 @@ -39,26 +40,40 @@ SIGNKEY_LEGAL_DURATION = 2 years LEGAL_DURATION = 2 years LOOKAHEAD_SIGN = 3 weeks 1 day LOOKAHEAD_PROVIDE = 2 weeks 1 day -KEYDIR = ${TALER_DATA_HOME}/exchange/live-keys/ -REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/ TERMS_ETAG = 0 PRIVACY_ETAG = 0 +STEFAN_ABS = "TESTKUDOS:5" + +# Account of the EXCHANGE +[exchange-account-1] +# What is the exchange's bank account (with the "Taler Bank" demo system)? +PAYTO_URI = payto://iban/SANDBOXX/DE989651?receiver-name=Exchange+Company +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES + +[exchange-accountcredentials-1] +WIRE_GATEWAY_URL = http://localhost:18082/accounts/exchange/taler-wire-gateway/ +WIRE_GATEWAY_AUTH_METHOD = basic +USERNAME = exchange +PASSWORD = x + + +[exchange-account-2] +PAYTO_URI = "payto://x-taler-bank/localhost/exchange?receiver-name=exchange" +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES + +[exchange-accountcredentials-2] +WIRE_GATEWAY_AUTH_METHOD = none +WIRE_GATEWAY_URL = "http://localhost:18082/accounts/exchange/taler-wire-gateway/" [merchant] SERVE = tcp PORT = 9966 UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http UNIXPATH_MODE = 660 -DEFAULT_WIRE_FEE_AMORTIZATION = 1 DB = postgres -WIREFORMAT = default -# Set very low, so we can be sure that the database generated -# will contain wire transfers "ready" for the aggregator. -WIRE_TRANSFER_DELAY = 1 minute -DEFAULT_PAY_DEADLINE = 1 day -DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1 KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv -DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10 # Ensure that merchant reports EVERY deposit confirmation to auditor FORCE_AUDIT = YES @@ -79,30 +94,41 @@ BASE_URL = "http://localhost:8083/" DATABASE = postgres:///taler-auditor-basedb MAX_DEBT = TESTKUDOS:50.0 MAX_DEBT_BANK = TESTKUDOS:100000.0 -HTTP_PORT = 8082 +HTTP_PORT = 18082 SUGGESTED_EXCHANGE = http://localhost:8081/ SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2 ALLOW_REGISTRATIONS = YES SERVE = http +[libeufin-bank] +CURRENCY = TESTKUDOS +WIRE_TYPE = iban +IBAN_PAYTO_BIC = SANDBOXX +DEFAULT_CUSTOMER_DEBT_LIMIT = TESTKUDOS:200 +DEFAULT_ADMIN_DEBT_LIMIT = TESTKUDOS:2000 +REGISTRATION_BONUS_ENABLED = yes +REGISTRATION_BONUS = TESTKUDOS:100 +SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ +SERVE = tcp +PORT = 18082 + [exchangedb] IDLE_RESERVE_EXPIRATION_TIME = 4 weeks LEGAL_RESERVE_EXPIRATION_TIME = 7 years -[exchange-account-1] -PAYTO_URI = payto://x-taler-bank/localhost/Exchange -enable_debit = yes -enable_credit = yes +[auditordb-postgres] +CONFIG = "postgres:///talercheck" -[exchange-accountcredentials-1] -WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/" -WIRE_GATEWAY_AUTH_METHOD = basic -USERNAME = Exchange -PASSWORD = x +[exchangedb-postgres] +CONFIG = "postgres:///talercheck" + +[merchantdb-postgres] +CONFIG = "postgres:///talercheck" [merchant-exchange-default] EXCHANGE_BASE_URL = http://localhost:8081/ CURRENCY = TESTKUDOS +MASTER_KEY = 3NX5DJDBD8XVGZYHV3PBF8C3Z4GK48XD59YY5GF3CZE8AJM04WSG [payments-generator] currency = TESTKUDOS diff --git a/src/cli/test_reducer_free.conf b/src/cli/test_reducer_free.conf index 1c7da88..4e46929 100644 --- a/src/cli/test_reducer_free.conf +++ b/src/cli/test_reducer_free.conf @@ -95,7 +95,7 @@ enable_debit = yes enable_credit = yes [exchange-accountcredentials-1] -WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/" +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/Exchange/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange PASSWORD = x diff --git a/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv b/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv new file mode 100644 index 0000000..d990a05 --- /dev/null +++ b/src/cli/test_reducer_home/.local/share/taler/exchange-offline/master.priv @@ -0,0 +1 @@ +>en͙[z3pwTj?cn21
\ No newline at end of file diff --git a/src/include/anastasis_crypto_lib.h b/src/include/anastasis_crypto_lib.h index 648a8eb..8cbc954 100644 --- a/src/include/anastasis_crypto_lib.h +++ b/src/include/anastasis_crypto_lib.h @@ -21,7 +21,7 @@ * @author Dennis Neufeld */ #include <jansson.h> -#include <gnunet/gnunet_crypto_lib.h> +#include <gnunet/gnunet_util_lib.h> /** diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h index ba55314..2f30a8b 100644 --- a/src/include/anastasis_service.h +++ b/src/include/anastasis_service.h @@ -51,51 +51,82 @@ struct ANASTASIS_AuthorizationMethodConfig */ struct ANASTASIS_Config { - /** - * Protocol version supported by the server. - */ - const char *version; /** - * Business name of the anastasis provider. + * HTTP status returned. */ - const char *business_name; + unsigned int http_status; /** - * Array of authorization methods supported by the server. + * Taler-specific error code, #TALER_EC_NONE on success. */ - const struct ANASTASIS_AuthorizationMethodConfig *methods; + enum TALER_ErrorCode ec; /** - * Length of the @e methods array. + * Full response in JSON, if provided. */ - unsigned int methods_length; + const json_t *response; /** - * Maximum size of an upload in megabytes. + * Details depending on @e http_status. */ - uint32_t storage_limit_in_megabytes; + union + { - /** - * Annual fee for an account / policy upload. - */ - struct TALER_Amount annual_fee; + /** + * Details on #MHD_HTTP_OK. + */ + struct + { - /** - * Fee for a truth upload. - */ - struct TALER_Amount truth_upload_fee; + /** + * Protocol version supported by the server. + */ + const char *version; - /** - * Maximum legal liability for data loss covered by the - * provider. - */ - struct TALER_Amount liability_limit; + /** + * Business name of the anastasis provider. + */ + const char *business_name; - /** - * Provider salt. - */ - struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; + /** + * Array of authorization methods supported by the server. + */ + const struct ANASTASIS_AuthorizationMethodConfig *methods; + + /** + * Length of the @e methods array. + */ + unsigned int methods_length; + + /** + * Maximum size of an upload in megabytes. + */ + uint32_t storage_limit_in_megabytes; + + /** + * Annual fee for an account / policy upload. + */ + struct TALER_Amount annual_fee; + + /** + * Fee for a truth upload. + */ + struct TALER_Amount truth_upload_fee; + + /** + * Maximum legal liability for data loss covered by the + * provider. + */ + struct TALER_Amount liability_limit; + + /** + * Provider salt. + */ + struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; + } ok; + + } details; }; @@ -107,12 +138,10 @@ struct ANASTASIS_Config * the server provided an acceptable response. * * @param cls closure - * @param http_status the HTTP status * @param acfg configuration obtained, NULL if we could not parse it */ typedef void (*ANASTASIS_ConfigCallback)(void *cls, - unsigned int http_status, const struct ANASTASIS_Config *acfg); @@ -185,15 +214,45 @@ struct ANASTASIS_MetaDownloadDetails { /** - * Version-sorted array of meta data we downloaded. + * HTTP status returned. + */ + unsigned int http_status; + + /** + * Taler-specific error code, #TALER_EC_NONE on success. + */ + enum TALER_ErrorCode ec; + + /** + * Full response in JSON, if provided. */ - const struct ANASTASIS_MetaDataEntry *metas; + const json_t *response; /** - * Number of entries in @e metas. + * Details depending on @e http_status. */ - size_t metas_length; + union + { + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * Version-sorted array of meta data we downloaded. + */ + const struct ANASTASIS_MetaDataEntry *metas; + + /** + * Number of entries in @e metas. + */ + size_t metas_length; + + } ok; + + } details; }; @@ -201,13 +260,11 @@ struct ANASTASIS_MetaDownloadDetails * Callback to process a GET /policy/$POL/meta request * * @param cls closure - * @param http_status HTTP status code for this request * @param dd the response details */ typedef void (*ANASTASIS_PolicyMetaLookupCallback) ( void *cls, - unsigned int http_status, const struct ANASTASIS_MetaDownloadDetails *dd); @@ -247,30 +304,57 @@ ANASTASIS_policy_meta_lookup_cancel ( */ struct ANASTASIS_DownloadDetails { - /** - * Signature (already verified). - */ - struct ANASTASIS_AccountSignatureP sig; /** - * Hash over @e policy and @e policy_size. + * HTTP status returned. */ - struct GNUNET_HashCode curr_policy_hash; + unsigned int http_status; /** - * The backup we downloaded. + * Taler-specific error code, #TALER_EC_NONE on success. */ - const void *policy; + enum TALER_ErrorCode ec; /** - * Number of bytes in @e backup. + * Details depending on @e http_status. */ - size_t policy_size; + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * Signature (already verified). + */ + struct ANASTASIS_AccountSignatureP sig; + + /** + * Hash over @e policy and @e policy_size. + */ + struct GNUNET_HashCode curr_policy_hash; + + /** + * The backup we downloaded. + */ + const void *policy; + + /** + * Number of bytes in @e backup. + */ + size_t policy_size; + + /** + * Policy version returned by the service. + */ + uint32_t version; + } ok; + + } details; - /** - * Policy version returned by the service. - */ - uint32_t version; }; @@ -284,12 +368,10 @@ struct ANASTASIS_PolicyLookupOperation; * Callback to process a GET /policy request * * @param cls closure - * @param http_status HTTP status code for this request * @param dd the response details */ typedef void (*ANASTASIS_PolicyLookupCallback) (void *cls, - unsigned int http_status, const struct ANASTASIS_DownloadDetails *dd); diff --git a/src/include/anastasis_testing_lib.h b/src/include/anastasis_testing_lib.h index b5036ff..62cde06 100644 --- a/src/include/anastasis_testing_lib.h +++ b/src/include/anastasis_testing_lib.h @@ -130,15 +130,15 @@ op (truth, const struct ANASTASIS_Truth *) \ op (policy, const struct ANASTASIS_Policy *) \ op (provider_salt, const struct ANASTASIS_CRYPTO_ProviderSaltP) \ - op (core_secret, const void *) \ + op (core_secret, const void) \ op (truth_key, const struct ANASTASIS_CRYPTO_TruthKeyP) \ op (account_pub, const struct ANASTASIS_CRYPTO_AccountPublicKeyP) \ op (account_priv, const struct ANASTASIS_CRYPTO_AccountPrivateKeyP) \ op (payment_secret, const struct ANASTASIS_PaymentSecretP) \ op (truth_uuid, const struct ANASTASIS_CRYPTO_TruthUUIDP) \ op (eks, const struct ANASTASIS_CRYPTO_EncryptedKeyShareP) \ - op (code, const char *) \ - op (filename, const char *) + op (code, const char) \ + op (filename, const char) /** @@ -552,7 +552,7 @@ enum ANASTASIS_TESTING_SecretShareOption * @param id_data ID data to generate user identifier * @param core_secret core secret to backup/recover * @param core_secret_size size of @a core_secret - * @param http_status expected HTTP status. + * @param want_status expected status. * @param sso secret share options * @param ... NULL-terminated list of policy create commands * @return the command @@ -566,7 +566,7 @@ ANASTASIS_TESTING_cmd_secret_share ( const json_t *id_data, const void *core_secret, size_t core_secret_size, - unsigned int http_status, + enum ANASTASIS_ShareStatus want_status, enum ANASTASIS_TESTING_SecretShareOption sso, ...); diff --git a/src/include/platform.h b/src/include/platform.h index 7667460..0fd6672 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -26,10 +26,10 @@ /* Include our configuration header */ #ifndef HAVE_USED_CONFIG_H -# define HAVE_USED_CONFIG_H -# ifdef HAVE_CONFIG_H -# include "anastasis_config.h" -# endif +#define HAVE_USED_CONFIG_H +#ifdef HAVE_CONFIG_H +#include "anastasis_config.h" +#endif #endif @@ -69,8 +69,210 @@ /* Include the features available for GNU source */ #define _GNU_SOURCE -/* Include GNUnet's platform file */ -#include <gnunet/platform.h> + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef __clang__ +#undef HAVE_STATIC_ASSERT +#endif + +/** + * These may be expensive, but good for debugging... + */ +#define ALLOW_EXTRA_CHECKS GNUNET_YES + +/** + * For strptime (glibc2 needs this). + */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 499 +#endif + +#ifndef _REENTRANT +#define _REENTRANT +#endif + +/* configuration options */ + +#define VERBOSE_STATS 0 + +#include <netdb.h> +#include <sys/socket.h> +#include <sys/un.h> +#if HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#if HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif +#if HAVE_NETINET_IP_H +#include <netinet/ip.h> /* superset of previous */ +#endif +#include <arpa/inet.h> +#include <netinet/tcp.h> +#include <pwd.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <grp.h> + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdbool.h> +#include <errno.h> +#include <signal.h> +#include <libgen.h> +#ifdef HAVE_MALLOC_H +#include <malloc.h> /* for mallinfo on GNU */ +#endif +#include <unistd.h> /* KLB_FIX */ +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> /* KLB_FIX */ +#include <fcntl.h> +#include <math.h> +#if HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#if HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <time.h> +#ifdef BSD +#include <net/if.h> +#endif +#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__) +#include <semaphore.h> +#endif +#ifdef DARWIN +#include <dlfcn.h> +#include <semaphore.h> +#include <net/if.h> +#endif +#if defined(__linux__) || defined(GNU) +#include <net/if.h> +#endif +#ifdef SOLARIS +#include <sys/sockio.h> +#include <sys/filio.h> +#include <sys/loadavg.h> +#include <semaphore.h> +#endif +#if HAVE_UCRED_H +#include <ucred.h> +#endif +#if HAVE_SYS_UCRED_H +#include <sys/ucred.h> +#endif +#if HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif +#include <errno.h> +#include <limits.h> + +#if HAVE_VFORK_H +#include <vfork.h> +#endif + +#include <ctype.h> +#if HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + +#if HAVE_ENDIAN_H +#include <endian.h> +#endif +#if HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif + +#define DIR_SEPARATOR '/' +#define DIR_SEPARATOR_STR "/" +#define PATH_SEPARATOR ':' +#define PATH_SEPARATOR_STR ":" +#define NEWLINE "\n" + +#include <locale.h> +#include "gettext.h" +/** + * GNU gettext support macro. + */ +#define _(String) dgettext (PACKAGE, String) +#define LIBEXTRACTOR_GETTEXT_DOMAIN "libextractor" + +#include <sys/mman.h> + +/* FreeBSD_kernel is not defined on the now discontinued kFreeBSD */ +#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__) +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#endif + +#ifdef DARWIN +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +/* not available on darwin, override configure */ +#undef HAVE_STAT64 +#undef HAVE_MREMAP +#endif + +#if ! HAVE_ATOLL +long long +atoll (const char *nptr); + +#endif + +#if ENABLE_NLS +#include "langinfo.h" +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t) (-1)) +#endif + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +/** + * AI_NUMERICSERV not defined in windows. Then we just do without. + */ +#ifndef AI_NUMERICSERV +#define AI_NUMERICSERV 0 +#endif + + +#if defined(__sparc__) +#define MAKE_UNALIGNED(val) ({ __typeof__((val)) __tmp; memmove (&__tmp, &(val), \ + sizeof((val))); \ + __tmp; }) +#else +#define MAKE_UNALIGNED(val) val +#endif + +/** + * The termination signal + */ +#define GNUNET_TERM_SIG SIGTERM + + +#ifndef PATH_MAX +/** + * Assumed maximum path length. + */ +#define PATH_MAX 4096 +#endif + +#if HAVE_THREAD_LOCAL_GCC +#define ANASTASIS_THREAD_LOCAL __thread +#else +#define ANASTASIS_THREAD_LOCAL +#endif + /* Do not use shortcuts for gcrypt mpi */ #define GCRYPT_NO_MPI_MACROS 1 diff --git a/src/lib/anastasis_meta.c b/src/lib/anastasis_meta.c index 7812f6b..ae20db5 100644 --- a/src/lib/anastasis_meta.c +++ b/src/lib/anastasis_meta.c @@ -55,20 +55,17 @@ struct ANASTASIS_VersionCheck * Function called with results from a GET /policy/$POL/meta request * * @param cls closure with the `struct ANASTASIS_VersionCheck *` - * @param http_status HTTP status code for this request * @param dd the response details */ static void meta_cb ( void *cls, - unsigned int http_status, const struct ANASTASIS_MetaDownloadDetails *dd) { struct ANASTASIS_VersionCheck *vc = cls; vc->plm = NULL; - if ( (MHD_HTTP_OK != http_status) || - (NULL == dd) ) + if (MHD_HTTP_OK != dd->http_status) { vc->mpc (vc->mpc_cls, 0, @@ -78,9 +75,10 @@ meta_cb ( ANASTASIS_recovery_get_versions_cancel (vc); return; } - for (size_t i = 0; i<dd->metas_length; i++) + for (size_t i = 0; i<dd->details.ok.metas_length; i++) { - const struct ANASTASIS_MetaDataEntry *meta = &dd->metas[i]; + const struct ANASTASIS_MetaDataEntry *meta + = &dd->details.ok.metas[i]; const char *secret_name = NULL; const struct GNUNET_HashCode *eph; void *dec; diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c index c9f8c0e..f164c93 100644 --- a/src/lib/anastasis_recovery.c +++ b/src/lib/anastasis_recovery.c @@ -612,23 +612,22 @@ ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c) * Function called with the results of a #ANASTASIS_policy_lookup() * * @param cls closure - * @param http_status HTTp status code. * @param dd details about the lookup operation */ static void policy_lookup_cb (void *cls, - unsigned int http_status, const struct ANASTASIS_DownloadDetails *dd) { struct ANASTASIS_Recovery *r = cls; void *plaintext; size_t size_plaintext; json_error_t json_error; - json_t *dec_policies; - json_t *esc_methods; + const json_t *dec_policies; + const json_t *esc_methods; + json_t *recovery_document; r->plo = NULL; - switch (http_status) + switch (dd->http_status) { case MHD_HTTP_OK: break; @@ -660,7 +659,7 @@ policy_lookup_cb (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u in %s:%u\n", - http_status, + dd->http_status, __FILE__, __LINE__); r->csc (r->csc_cls, @@ -670,7 +669,7 @@ policy_lookup_cb (void *cls, ANASTASIS_recovery_abort (r); return; } - if (NULL == dd->policy) + if (NULL == dd->details.ok.policy) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No recovery data available"); @@ -682,8 +681,8 @@ policy_lookup_cb (void *cls, return; } ANASTASIS_CRYPTO_recovery_document_decrypt (&r->id, - dd->policy, - dd->policy_size, + dd->details.ok.policy, + dd->details.ok.policy_size, &plaintext, &size_plaintext); if (size_plaintext < sizeof (uint32_t)) @@ -698,7 +697,6 @@ policy_lookup_cb (void *cls, return; } { - json_t *recovery_document; uint32_t be_size; uLongf pt_size; char *pt; @@ -761,10 +759,10 @@ policy_lookup_cb (void *cls, { const char *secret_name = NULL; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("policies", - &dec_policies), - GNUNET_JSON_spec_json ("escrow_methods", - &esc_methods), + GNUNET_JSON_spec_array_const ("policies", + &dec_policies), + GNUNET_JSON_spec_array_const ("escrow_methods", + &esc_methods), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("secret_name", &secret_name), @@ -799,10 +797,9 @@ policy_lookup_cb (void *cls, r->ri.secret_name = r->secret_name; } } - json_decref (recovery_document); } - r->ri.version = dd->version; + r->ri.version = dd->details.ok.version; r->ri.cs_len = json_array_size (esc_methods); r->ri.dps_len = json_array_size (dec_policies); r->ri.dps = GNUNET_new_array (r->ri.dps_len, @@ -824,7 +821,7 @@ policy_lookup_cb (void *cls, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("uuid", &cs->ci.uuid), - GNUNET_JSON_spec_string ("url", + TALER_JSON_spec_web_url ("url", &url), GNUNET_JSON_spec_string ("instructions", &instructions), @@ -848,13 +845,12 @@ policy_lookup_cb (void *cls, NULL, NULL)) { GNUNET_break_op (0); - json_decref (esc_methods); - json_decref (dec_policies); r->csc (r->csc_cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); ANASTASIS_recovery_abort (r); + json_decref (recovery_document); return; } cs->url = GNUNET_strdup (url); @@ -864,13 +860,11 @@ policy_lookup_cb (void *cls, cs->instructions = GNUNET_strdup (instructions); cs->ci.instructions = cs->instructions; } - json_decref (esc_methods); for (unsigned int j = 0; j < r->ri.dps_len; j++) { struct DecryptionPolicy *dp = &r->dps[j]; - - json_t *uuids = NULL; + const json_t *uuids; json_t *uuid; size_t n_index; struct GNUNET_JSON_Specification spec[] = { @@ -879,27 +873,25 @@ policy_lookup_cb (void *cls, &dp->emk_size), GNUNET_JSON_spec_fixed_auto ("master_salt", &dp->master_salt), - GNUNET_JSON_spec_json ("uuids", - &uuids), + GNUNET_JSON_spec_array_const ("uuids", + &uuids), GNUNET_JSON_spec_end () }; r->ri.dps[j] = &r->dps[j].pub_details; - if ( (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (dec_policies, - j), - spec, - NULL, NULL)) || - (! json_is_array (uuids)) ) + if (GNUNET_OK != + GNUNET_JSON_parse (json_array_get (dec_policies, + j), + spec, + NULL, NULL)) { GNUNET_break_op (0); - json_decref (uuids); - json_decref (dec_policies); r->csc (r->csc_cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); ANASTASIS_recovery_abort (r); + json_decref (recovery_document); return; } @@ -925,13 +917,12 @@ policy_lookup_cb (void *cls, sizeof (uuid))) ) { GNUNET_break_op (0); - json_decref (dec_policies); - json_decref (uuids); r->csc (r->csc_cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); ANASTASIS_recovery_abort (r); + json_decref (recovery_document); return; } for (unsigned int i = 0; i<r->ri.cs_len; i++) @@ -947,21 +938,19 @@ policy_lookup_cb (void *cls, if (! found) { GNUNET_break_op (0); - json_decref (dec_policies); - json_decref (uuids); r->csc (r->csc_cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); ANASTASIS_recovery_abort (r); + json_decref (recovery_document); return; } } - json_decref (uuids); } - json_decref (dec_policies); r->pc (r->pc_cls, &r->ri); + json_decref (recovery_document); } @@ -1134,7 +1123,7 @@ ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r) */ static enum GNUNET_GenericReturnValue parse_cs_array (struct ANASTASIS_Recovery *r, - json_t *cs_arr) + const json_t *cs_arr) { json_t *cs; unsigned int n_index; @@ -1161,7 +1150,7 @@ parse_cs_array (struct ANASTASIS_Recovery *r, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("uuid", &c->ci.uuid), - GNUNET_JSON_spec_string ("url", + TALER_JSON_spec_web_url ("url", &url), GNUNET_JSON_spec_string ("instructions", &instructions), @@ -1220,7 +1209,7 @@ parse_cs_array (struct ANASTASIS_Recovery *r, */ static enum GNUNET_GenericReturnValue parse_dps_array (struct ANASTASIS_Recovery *r, - json_t *dps_arr) + const json_t *dps_arr) { json_t *dps; unsigned int n_index; @@ -1239,15 +1228,15 @@ parse_dps_array (struct ANASTASIS_Recovery *r, json_array_foreach (dps_arr, n_index, dps) { struct DecryptionPolicy *dp = &r->dps[n_index]; - json_t *challenges; + const json_t *challenges; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_varsize ("encrypted_master_key", &dp->emk, &dp->emk_size), GNUNET_JSON_spec_fixed_auto ("master_salt", &dp->master_salt), - GNUNET_JSON_spec_json ("challenges", - &challenges), + GNUNET_JSON_spec_array_const ("challenges", + &challenges), GNUNET_JSON_spec_end () }; const char *err_json_name; @@ -1270,12 +1259,6 @@ parse_dps_array (struct ANASTASIS_Recovery *r, } GNUNET_assert (NULL != dp->emk); GNUNET_assert (dp->emk_size > 0); - if (! json_is_array (challenges)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } dp->pub_details.challenges_length = json_array_size (challenges); dp->pub_details.challenges = GNUNET_new_array ( dp->pub_details.challenges_length, @@ -1320,8 +1303,7 @@ parse_dps_array (struct ANASTASIS_Recovery *r, } } } - /* We don't free the spec, since we're still using dp->ems. */ - json_decref (challenges); + /* Do NOT free the spec: we are still using dp->ems. */ } return GNUNET_OK; } @@ -1363,9 +1345,9 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx, const char *err_json_name; unsigned int err_line; uint32_t version; - json_t *dps_arr; - json_t *cs_arr; - json_t *id_data; + const json_t *dps_arr; + const json_t *cs_arr; + const json_t *id_data; const char *provider_url; const char *secret_name; void *ecs; @@ -1373,7 +1355,7 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("id", &r->id), - GNUNET_JSON_spec_string ("provider_url", + TALER_JSON_spec_web_url ("provider_url", &provider_url), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("secret_name", @@ -1381,12 +1363,12 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx, NULL), GNUNET_JSON_spec_uint32 ("version", &version), - GNUNET_JSON_spec_json ("decryption_policies", - &dps_arr), - GNUNET_JSON_spec_json ("challenges", - &cs_arr), - GNUNET_JSON_spec_json ("id_data", - &id_data), + GNUNET_JSON_spec_array_const ("decryption_policies", + &dps_arr), + GNUNET_JSON_spec_array_const ("challenges", + &cs_arr), + GNUNET_JSON_spec_object_const ("id_data", + &id_data), GNUNET_JSON_spec_varsize ("encrypted_core_secret", &ecs, &ecs_size), @@ -1420,7 +1402,7 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx, GNUNET_JSON_parse_free (spec); return NULL; } - r->id_data = json_incref (id_data); + r->id_data = json_incref ((json_t *) id_data); r->provider_url = GNUNET_strdup (provider_url); if (NULL != secret_name) r->secret_name = GNUNET_strdup (secret_name); diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c index abd7c70..13b1dd6 100644 --- a/src/reducer/anastasis_api_backup_redux.c +++ b/src/reducer/anastasis_api_backup_redux.c @@ -1,6 +1,6 @@ /* This file is part of Anastasis - Copyright (C) 2020, 2021 Anastasis SARL + Copyright (C) 2020-2023 Anastasis SARL Anastasis 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 @@ -353,7 +353,7 @@ add_authentication (json_t *state, json_object_foreach (auth_providers, url, details) { - json_t *methods = NULL; + const json_t *methods = NULL; json_t *method; size_t index; uint32_t size_limit_in_mb = 0; @@ -371,8 +371,8 @@ add_authentication (json_t *state, &http_status), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("methods", - &methods), + GNUNET_JSON_spec_array_const ("methods", + &methods), NULL), GNUNET_JSON_spec_end () }; @@ -411,7 +411,6 @@ add_authentication (json_t *state, break; } } - GNUNET_JSON_parse_free (ispec); if (! challenge_size_ok (size_limit_in_mb, challenge_size)) { @@ -767,17 +766,20 @@ free_costs (struct Costs *costs) * Check if providers @a p1 and @a p2 have equivalent * methods and cost structures. * + * @param pb policy builder with list of providers + * @param p1 name of provider to compare + * @param p2 name of provider to compare * @return true if the providers are fully equivalent */ static bool -equiv_provider (struct PolicyBuilder *pb, +equiv_provider (const struct PolicyBuilder *pb, const char *p1, const char *p2) { - json_t *j1; - json_t *j2; - json_t *m1; - json_t *m2; + const json_t *j1; + const json_t *j2; + const json_t *m1; + const json_t *m2; struct TALER_Amount uc1; struct TALER_Amount uc2; @@ -794,8 +796,8 @@ equiv_provider (struct PolicyBuilder *pb, { struct GNUNET_JSON_Specification s1[] = { - GNUNET_JSON_spec_json ("methods", - &m1), + GNUNET_JSON_spec_array_const ("methods", + &m1), TALER_JSON_spec_amount_any ("truth_upload_fee", &uc1), GNUNET_JSON_spec_end () @@ -813,8 +815,8 @@ equiv_provider (struct PolicyBuilder *pb, { struct GNUNET_JSON_Specification s2[] = { - GNUNET_JSON_spec_json ("methods", - &m2), + GNUNET_JSON_spec_array_const ("methods", + &m2), TALER_JSON_spec_amount_any ("truth_upload_fee", &uc2), GNUNET_JSON_spec_end () @@ -933,7 +935,7 @@ eval_provider_selection (struct PolicyBuilder *pb, pb->m_idx[i]); const json_t *provider_cfg = json_object_get (pb->providers, prov_sel[i]); - json_t *provider_methods; + const json_t *provider_methods; const char *method_type; json_t *md; size_t index; @@ -943,8 +945,8 @@ eval_provider_selection (struct PolicyBuilder *pb, struct GNUNET_JSON_Specification pspec[] = { GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes", &size_limit_in_mb), - GNUNET_JSON_spec_json ("methods", - &provider_methods), + GNUNET_JSON_spec_array_const ("methods", + &provider_methods), TALER_JSON_spec_amount_any ("truth_upload_fee", &upload_cost), GNUNET_JSON_spec_end () @@ -1016,7 +1018,6 @@ eval_provider_selection (struct PolicyBuilder *pb, GNUNET_break (0); pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID; pb->hint = "'methods' of provider"; - GNUNET_JSON_parse_free (pspec); for (unsigned int i = 0; i<pb->req_methods; i++) free_costs (policy_ent[i].usage_fee); return; @@ -1038,14 +1039,12 @@ eval_provider_selection (struct PolicyBuilder *pb, { /* Provider does not OFFER this method, combination not possible. Cost is basically 'infinite', but we simply then skip this. */ - GNUNET_JSON_parse_free (pspec); GNUNET_JSON_parse_free (mspec); for (unsigned int i = 0; i<pb->req_methods; i++) free_costs (policy_ent[i].usage_fee); return; } GNUNET_JSON_parse_free (mspec); - GNUNET_JSON_parse_free (pspec); } /* calculate provider diversity by counting number of different @@ -1945,7 +1944,7 @@ add_policy (json_t *state, const char *provider_url; uint32_t method_idx; const char *method_type; - json_t *prov_methods; + const json_t *prov_methods; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("provider", &provider_url), @@ -1982,8 +1981,8 @@ add_policy (json_t *state, NULL), GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes", &limit), - GNUNET_JSON_spec_json ("methods", - &prov_methods), + GNUNET_JSON_spec_array_const ("methods", + &prov_methods), GNUNET_JSON_spec_end () }; @@ -2016,17 +2015,6 @@ add_policy (json_t *state, json_decref (methods); continue; } - if (! json_is_array (prov_methods)) - { - GNUNET_break (0); - json_decref (methods); - json_decref (prov_methods); - ANASTASIS_redux_fail_ (cb, - cb_cls, - TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID, - "provider lacks authentication methods"); - return NULL; - } } { @@ -2038,7 +2026,6 @@ add_policy (json_t *state, { GNUNET_break (0); json_decref (methods); - json_decref (prov_methods); ANASTASIS_redux_fail_ (cb, cb_cls, TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID, @@ -2051,7 +2038,6 @@ add_policy (json_t *state, { GNUNET_break (0); json_decref (methods); - json_decref (prov_methods); ANASTASIS_redux_fail_ (cb, cb_cls, TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID, @@ -2083,7 +2069,6 @@ add_policy (json_t *state, { GNUNET_break (0); json_decref (methods); - json_decref (prov_methods); ANASTASIS_redux_fail_ (cb, cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, @@ -2100,7 +2085,6 @@ add_policy (json_t *state, { GNUNET_break (0); json_decref (methods); - json_decref (prov_methods); ANASTASIS_redux_fail_ (cb, cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, @@ -2111,7 +2095,6 @@ add_policy (json_t *state, GNUNET_assert (0 == json_array_append (methods, method)); - json_decref (prov_methods); } /* end of json_array_foreach (arg_array, index, method) */ } @@ -3130,23 +3113,25 @@ secret_share_result_cb (void *cls, static void share_secret (struct UploadContext *uc) { - json_t *user_id; - json_t *core_secret; - json_t *jpolicies; - json_t *providers = NULL; + const json_t *user_id; + const json_t *core_secret; + const json_t *jpolicies; + const json_t *providers = NULL; size_t policies_len; const char *secret_name = NULL; unsigned int pds_len; struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_ZERO; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("identity_attributes", - &user_id), - GNUNET_JSON_spec_json ("policies", - &jpolicies), - GNUNET_JSON_spec_json ("policy_providers", - &providers), - GNUNET_JSON_spec_json ("core_secret", - &core_secret), + GNUNET_JSON_spec_object_const ("identity_attributes", + &user_id), + GNUNET_JSON_spec_array_const ("policies", + &jpolicies), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_array_const ("policy_providers", + &providers), + NULL), + GNUNET_JSON_spec_object_const ("core_secret", + &core_secret), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("secret_name", &secret_name), @@ -3198,40 +3183,32 @@ share_secret (struct UploadContext *uc) } } - if ( (! json_is_object (user_id)) || - (! json_is_array (jpolicies)) || - (0 == json_array_size (jpolicies)) || - ( (NULL != providers) && - (! json_is_array (providers)) ) ) + policies_len = json_array_size (jpolicies); + if (0 == policies_len) { ANASTASIS_redux_fail_ (uc->cb, uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "State parsing failed checks when preparing to share secret"); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } - policies_len = json_array_size (jpolicies); pds_len = json_array_size (providers); - if (0 == pds_len) { ANASTASIS_redux_fail_ (uc->cb, uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "no workable providers in state"); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } - { struct ANASTASIS_Policy *vpolicies[policies_len]; const struct ANASTASIS_Policy *policies[policies_len]; - struct ANASTASIS_ProviderDetails pds[GNUNET_NZL (pds_len)]; + struct ANASTASIS_ProviderDetails pds[pds_len]; /* initialize policies/vpolicies arrays */ memset (pds, @@ -3253,7 +3230,6 @@ share_secret (struct UploadContext *uc) uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "'methods' must be an array"); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } @@ -3267,13 +3243,13 @@ share_secret (struct UploadContext *uc) { const json_t *jmethod = json_array_get (jmethods, j); - json_t *jtruth = NULL; + const json_t *jtruth = NULL; uint32_t truth_index; const char *provider_url; struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("truth", - &jtruth), + GNUNET_JSON_spec_object_const ("truth", + &jtruth), NULL), GNUNET_JSON_spec_string ("provider", &provider_url), @@ -3295,7 +3271,6 @@ share_secret (struct UploadContext *uc) uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "'truth' failed to decode"); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } @@ -3312,8 +3287,6 @@ share_secret (struct UploadContext *uc) uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "'truth' failed to decode"); - GNUNET_JSON_parse_free (ispec); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } @@ -3351,13 +3324,10 @@ share_secret (struct UploadContext *uc) uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, "'truth' failed to decode"); - GNUNET_JSON_parse_free (ispec); - GNUNET_JSON_parse_free (spec); upload_cancel_cb (uc); return; } } - GNUNET_JSON_parse_free (ispec); ctruths[j] = truths[j]; } p = ANASTASIS_policy_create (ctruths, @@ -3401,7 +3371,6 @@ share_secret (struct UploadContext *uc) for (unsigned int i = 0; i<policies_len; i++) ANASTASIS_policy_destroy (vpolicies[i]); upload_cancel_cb (uc); - GNUNET_JSON_parse_free (spec); return; } } @@ -3432,7 +3401,6 @@ share_secret (struct UploadContext *uc) for (unsigned int i = 0; i<policies_len; i++) ANASTASIS_policy_destroy (vpolicies[i]); } - GNUNET_JSON_parse_free (spec); if (NULL == uc->ss) { GNUNET_break (0); diff --git a/src/reducer/anastasis_api_recovery_redux.c b/src/reducer/anastasis_api_recovery_redux.c index 93884bb..e795c55 100644 --- a/src/reducer/anastasis_api_recovery_redux.c +++ b/src/reducer/anastasis_api_recovery_redux.c @@ -2308,12 +2308,12 @@ done_secret_selecting (json_t *state, void *cb_cls) { uint32_t mask; - json_t *pa; + const json_t *pa; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_uint32 ("attribute_mask", &mask), - GNUNET_JSON_spec_json ("providers", - &pa), + GNUNET_JSON_spec_array_const ("providers", + &pa), GNUNET_JSON_spec_end () }; struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; @@ -2448,7 +2448,6 @@ done_secret_selecting (json_t *state, pd->ra.cleanup_cls = pd; return &pd->ra; } - } } diff --git a/src/reducer/anastasis_api_redux.c b/src/reducer/anastasis_api_redux.c index 0535883..4b5ad7b 100644 --- a/src/reducer/anastasis_api_redux.c +++ b/src/reducer/anastasis_api_redux.c @@ -599,12 +599,10 @@ retry_config (void *cls); * Function called with the results of a #ANASTASIS_get_config(). * * @param cls closure - * @param http_status HTTP status of the request * @param acfg anastasis configuration */ static void config_cb (void *cls, - unsigned int http_status, const struct ANASTASIS_Config *acfg) { struct ConfigRequest *cr = cls; @@ -615,23 +613,23 @@ config_cb (void *cls, GNUNET_SCHEDULER_cancel (cr->tt); cr->tt = NULL; } - cr->http_status = http_status; - if (MHD_HTTP_OK != http_status) + cr->http_status = acfg->http_status; + if (MHD_HTTP_OK != acfg->http_status) { - if (0 == http_status) + if (0 == acfg->http_status) cr->ec = TALER_EC_ANASTASIS_GENERIC_PROVIDER_UNREACHABLE; else cr->ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED; } - if ( (MHD_HTTP_OK == http_status) && + if ( (MHD_HTTP_OK == acfg->http_status) && (NULL == acfg) ) { cr->http_status = MHD_HTTP_NOT_FOUND; cr->ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED; } - else if (NULL != acfg) + else { - if (0 == acfg->storage_limit_in_megabytes) + if (0 == acfg->details.ok.storage_limit_in_megabytes) { cr->http_status = 0; cr->ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG; @@ -640,27 +638,28 @@ config_cb (void *cls, { cr->ec = TALER_EC_NONE; GNUNET_free (cr->business_name); - cr->business_name = GNUNET_strdup (acfg->business_name); + cr->business_name = GNUNET_strdup (acfg->details.ok.business_name); for (unsigned int i = 0; i<cr->methods_length; i++) GNUNET_free (cr->methods[i].type); GNUNET_free (cr->methods); - cr->methods = GNUNET_new_array (acfg->methods_length, + cr->methods = GNUNET_new_array (acfg->details.ok.methods_length, struct AuthorizationMethodConfig); - for (unsigned int i = 0; i<acfg->methods_length; i++) + for (unsigned int i = 0; i<acfg->details.ok.methods_length; i++) { - cr->methods[i].type = GNUNET_strdup (acfg->methods[i].type); - cr->methods[i].usage_fee = acfg->methods[i].usage_fee; + cr->methods[i].type = GNUNET_strdup (acfg->details.ok.methods[i].type); + cr->methods[i].usage_fee = acfg->details.ok.methods[i].usage_fee; } - cr->methods_length = acfg->methods_length; - cr->storage_limit_in_megabytes = acfg->storage_limit_in_megabytes; - cr->annual_fee = acfg->annual_fee; - cr->truth_upload_fee = acfg->truth_upload_fee; - cr->liability_limit = acfg->liability_limit; - cr->provider_salt = acfg->provider_salt; + cr->methods_length = acfg->details.ok.methods_length; + cr->storage_limit_in_megabytes = + acfg->details.ok.storage_limit_in_megabytes; + cr->annual_fee = acfg->details.ok.annual_fee; + cr->truth_upload_fee = acfg->details.ok.truth_upload_fee; + cr->liability_limit = acfg->details.ok.liability_limit; + cr->provider_salt = acfg->details.ok.provider_salt; } } notify_waiting (cr); - if (MHD_HTTP_OK != http_status) + if (MHD_HTTP_OK != acfg->http_status) { cr->backoff = GNUNET_TIME_STD_BACKOFF (cr->backoff); GNUNET_assert (NULL == cr->tt); @@ -879,6 +878,9 @@ begin_provider_config_check (const char *cc, cc)) ) { /* skip */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Skipping provider restricted to country `%s'\n", + restricted); continue; } if ( (NULL == restricted) && diff --git a/src/restclient/anastasis_api_config.c b/src/restclient/anastasis_api_config.c index 5dcc7ec..fff4774 100644 --- a/src/restclient/anastasis_api_config.c +++ b/src/restclient/anastasis_api_config.c @@ -86,6 +86,10 @@ handle_config_finished (void *cls, { struct ANASTASIS_ConfigOperation *co = cls; const json_t *json = response; + struct ANASTASIS_Config acfg = { + .http_status = response_code, + .response = json + }; co->job = NULL; switch (response_code) @@ -99,27 +103,29 @@ handle_config_finished (void *cls, case MHD_HTTP_OK: { const char *name; - struct ANASTASIS_Config acfg; - json_t *methods; + const json_t *methods; + struct TALER_JSON_ProtocolVersion pv; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("name", &name), GNUNET_JSON_spec_string ("business_name", - &acfg.business_name), + &acfg.details.ok.business_name), GNUNET_JSON_spec_string ("version", - &acfg.version), - GNUNET_JSON_spec_json ("methods", - &methods), + &acfg.details.ok.version), + TALER_JSON_spec_version ("version", + &pv), + GNUNET_JSON_spec_array_const ("methods", + &methods), GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes", - &acfg.storage_limit_in_megabytes), + &acfg.details.ok.storage_limit_in_megabytes), TALER_JSON_spec_amount_any ("annual_fee", - &acfg.annual_fee), + &acfg.details.ok.annual_fee), TALER_JSON_spec_amount_any ("truth_upload_fee", - &acfg.truth_upload_fee), + &acfg.details.ok.truth_upload_fee), TALER_JSON_spec_amount_any ("liability_limit", - &acfg.liability_limit), + &acfg.details.ok.liability_limit), GNUNET_JSON_spec_fixed_auto ("provider_salt", - &acfg.provider_salt), + &acfg.details.ok.provider_salt), GNUNET_JSON_spec_end () }; @@ -132,67 +138,44 @@ handle_config_finished (void *cls, json_dumpf (json, stderr, JSON_INDENT (2)); - response_code = 0; + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } if (0 != strcmp (name, "anastasis")) { GNUNET_JSON_parse_free (spec); - response_code = 0; + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } + if ( (ANASTASIS_PROTOCOL_CURRENT < pv.current) && + (ANASTASIS_PROTOCOL_CURRENT < pv.current - pv.age) ) { - unsigned int age; - unsigned int revision; - unsigned int current; - char dummy; - - if (3 != sscanf (acfg.version, - "%u:%u:%u%c", - ¤t, - &revision, - &age, - &dummy)) - { - GNUNET_break_op (0); - response_code = 0; - GNUNET_JSON_parse_free (spec); - break; - } - if ( (ANASTASIS_PROTOCOL_CURRENT < current) && - (ANASTASIS_PROTOCOL_CURRENT < current - age) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Provider protocol version too new\n"); - response_code = 0; - GNUNET_JSON_parse_free (spec); - break; - } - if ( (ANASTASIS_PROTOCOL_CURRENT > current) && - (ANASTASIS_PROTOCOL_CURRENT - ANASTASIS_PROTOCOL_AGE > current) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Provider protocol version too old\n"); - GNUNET_break_op (0); - response_code = 0; - GNUNET_JSON_parse_free (spec); - break; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Provider protocol version too new\n"); + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_VERSION_MALFORMED; + break; } - if (! json_is_array (methods)) + if ( (ANASTASIS_PROTOCOL_CURRENT > pv.current) && + (ANASTASIS_PROTOCOL_CURRENT - ANASTASIS_PROTOCOL_AGE > pv.current) ) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Provider protocol version too old\n"); GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - response_code = 0; + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_VERSION_MALFORMED; break; } - acfg.methods_length = json_array_size (methods); + acfg.details.ok.methods_length = json_array_size (methods); { struct ANASTASIS_AuthorizationMethodConfig mcfg[GNUNET_NZL ( - acfg.methods_length)]; + acfg.details.ok. + methods_length)]; - for (unsigned int i = 0; i<acfg.methods_length; i++) + for (unsigned int i = 0; i<acfg.details.ok.methods_length; i++) { struct ANASTASIS_AuthorizationMethodConfig *m = &mcfg[i]; struct GNUNET_JSON_Specification spec[] = { @@ -210,19 +193,17 @@ handle_config_finished (void *cls, NULL, NULL)) ) { GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - response_code = 0; + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_REPLY_MALFORMED; goto end; } } - acfg.methods = mcfg; + acfg.details.ok.methods = mcfg; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Good backend found at `%s'\n", co->url); co->cb (co->cb_cls, - MHD_HTTP_OK, &acfg); - GNUNET_JSON_parse_free (spec); ANASTASIS_config_cancel (co); return; } @@ -248,8 +229,7 @@ handle_config_finished (void *cls, } end: co->cb (co->cb_cls, - response_code, - NULL); + &acfg); ANASTASIS_config_cancel (co); } diff --git a/src/restclient/anastasis_api_curl_defaults.c b/src/restclient/anastasis_api_curl_defaults.c index 33665e0..f64347b 100644 --- a/src/restclient/anastasis_api_curl_defaults.c +++ b/src/restclient/anastasis_api_curl_defaults.c @@ -20,6 +20,7 @@ * @author Florian Dold */ #include "platform.h" +#include <taler/taler_curl_lib.h> #include "anastasis_api_curl_defaults.h" CURL * @@ -34,20 +35,12 @@ ANASTASIS_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); GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_TCP_FASTOPEN, 1L)); - /* 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)); /* Enable compression (using whatever curl likes), see https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */ GNUNET_break (CURLE_OK == diff --git a/src/restclient/anastasis_api_policy_lookup.c b/src/restclient/anastasis_api_policy_lookup.c index 42db90d..b3132ef 100644 --- a/src/restclient/anastasis_api_policy_lookup.c +++ b/src/restclient/anastasis_api_policy_lookup.c @@ -106,6 +106,9 @@ handle_policy_lookup_finished (void *cls, size_t data_size) { struct ANASTASIS_PolicyLookupOperation *plo = cls; + struct ANASTASIS_DownloadDetails dd = { + .http_status = response_code + }; plo->job = NULL; switch (response_code) @@ -117,7 +120,6 @@ handle_policy_lookup_finished (void *cls, break; case MHD_HTTP_OK: { - struct ANASTASIS_DownloadDetails dd; struct ANASTASIS_UploadSignaturePS usp = { .purpose.purpose = htonl (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD), .purpose.size = htonl (sizeof (usp)), @@ -133,18 +135,17 @@ handle_policy_lookup_finished (void *cls, &plo->account_pub.pub)) { GNUNET_break_op (0); - response_code = 0; + dd.http_status = 0; + dd.ec = -1; // FIXME: needs new code in Gana! break; } /* Success, call callback with all details! */ - memset (&dd, 0, sizeof (dd)); - dd.sig = plo->account_sig; - dd.curr_policy_hash = usp.new_recovery_data_hash; - dd.policy = data; - dd.policy_size = data_size; - dd.version = plo->version; + dd.details.ok.sig = plo->account_sig; + dd.details.ok.curr_policy_hash = usp.new_recovery_data_hash; + dd.details.ok.policy = data; + dd.details.ok.policy_size = data_size; + dd.details.ok.version = plo->version; plo->cb (plo->cb_cls, - response_code, &dd); plo->cb = NULL; ANASTASIS_policy_lookup_cancel (plo); @@ -167,12 +168,10 @@ handle_policy_lookup_finished (void *cls, "Unexpected response code %u\n", (unsigned int) response_code); GNUNET_break (0); - response_code = 0; break; } plo->cb (plo->cb_cls, - response_code, - NULL); + &dd); plo->cb = NULL; ANASTASIS_policy_lookup_cancel (plo); } diff --git a/src/restclient/anastasis_api_policy_meta_lookup.c b/src/restclient/anastasis_api_policy_meta_lookup.c index 3d1482f..cf381fd 100644 --- a/src/restclient/anastasis_api_policy_meta_lookup.c +++ b/src/restclient/anastasis_api_policy_meta_lookup.c @@ -90,6 +90,10 @@ handle_policy_meta_lookup_finished (void *cls, { struct ANASTASIS_PolicyMetaLookupOperation *plo = cls; const json_t *json = response; + struct ANASTASIS_MetaDownloadDetails mdd = { + .http_status = response_code, + .response = json + }; plo->job = NULL; switch (response_code) @@ -116,10 +120,6 @@ handle_policy_meta_lookup_finished (void *cls, { struct ANASTASIS_MetaDataEntry metas[GNUNET_NZL (mlen)]; void *md[GNUNET_NZL (mlen)]; - struct ANASTASIS_MetaDownloadDetails mdd = { - .metas = metas, - .metas_length = mlen - }; size_t off = 0; const char *label; const json_t *val; @@ -127,6 +127,8 @@ handle_policy_meta_lookup_finished (void *cls, memset (md, 0, sizeof (md)); + mdd.details.ok.metas = metas; + mdd.details.ok.metas_length = mlen; json_object_foreach ((json_t *) json, label, val) @@ -148,6 +150,8 @@ handle_policy_meta_lookup_finished (void *cls, &dummy)) { GNUNET_break (0); + mdd.http_status = 0; + mdd.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } if (GNUNET_OK != @@ -156,6 +160,8 @@ handle_policy_meta_lookup_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); + mdd.http_status = 0; + mdd.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } metas[off].version = (uint32_t) ver; @@ -165,13 +171,13 @@ handle_policy_meta_lookup_finished (void *cls, if (off < mlen) { GNUNET_break (0); - response_code = 0; + mdd.http_status = 0; + mdd.ec = TALER_EC_GENERIC_REPLY_MALFORMED; for (size_t i = 0; i<off; i++) GNUNET_free (md[i]); break; } plo->cb (plo->cb_cls, - response_code, &mdd); for (size_t i = 0; i<off; i++) GNUNET_free (md[i]); @@ -197,15 +203,13 @@ handle_policy_meta_lookup_finished (void *cls, "Unexpected response code %u\n", (unsigned int) response_code); GNUNET_break (0); - response_code = 0; break; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "HTTP status for policy meta lookup is %u\n", (unsigned int) response_code); plo->cb (plo->cb_cls, - response_code, - NULL); + &mdd); plo->cb = NULL; ANASTASIS_policy_meta_lookup_cancel (plo); } diff --git a/src/restclient/anastasis_api_policy_store.c b/src/restclient/anastasis_api_policy_store.c index 5cfcfcb..3afee7d 100644 --- a/src/restclient/anastasis_api_policy_store.c +++ b/src/restclient/anastasis_api_policy_store.c @@ -417,7 +417,7 @@ ANASTASIS_policy_store ( val = GNUNET_STRINGS_data_to_string_alloc (&usp.new_recovery_data_hash, sizeof (struct GNUNET_HashCode)); GNUNET_asprintf (&hdr, - "%s: %s", + "%s: \"%s\"", MHD_HTTP_HEADER_IF_NONE_MATCH, val); GNUNET_free (val); diff --git a/src/restclient/anastasis_api_truth_challenge.c b/src/restclient/anastasis_api_truth_challenge.c index aa9119c..7a39db5 100644 --- a/src/restclient/anastasis_api_truth_challenge.c +++ b/src/restclient/anastasis_api_truth_challenge.c @@ -124,7 +124,7 @@ handle_truth_challenge_finished (void *cls, const char *ct; const char *tan_hint = NULL; const char *filename = NULL; - json_t *wire_details = NULL; + const json_t *wire_details = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ( "challenge_type", @@ -138,8 +138,8 @@ handle_truth_challenge_finished (void *cls, &filename), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("wire_details", - &wire_details), + GNUNET_JSON_spec_object_const ("wire_details", + &wire_details), NULL), GNUNET_JSON_spec_end () }; @@ -204,7 +204,6 @@ handle_truth_challenge_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); tcd.http_status = 0; tcd.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; @@ -212,7 +211,6 @@ handle_truth_challenge_finished (void *cls, tcd.details.success.cs = ANASTASIS_CS_WIRE_FUNDS; tco->cb (tco->cb_cls, &tcd); - GNUNET_JSON_parse_free (spec); ANASTASIS_truth_challenge_cancel (tco); return; } diff --git a/src/restclient/anastasis_api_truth_store.c b/src/restclient/anastasis_api_truth_store.c index c1cf634..855ad5a 100644 --- a/src/restclient/anastasis_api_truth_store.c +++ b/src/restclient/anastasis_api_truth_store.c @@ -169,10 +169,18 @@ handle_truth_store_finished (void *cls, ud.ec = TALER_JSON_get_error_code2 (data, data_size); break; + case MHD_HTTP_BAD_GATEWAY: + ud.ec = TALER_JSON_get_error_code2 (data, + data_size); + break; default: - GNUNET_break (0); ud.ec = TALER_JSON_get_error_code2 (data, data_size); + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected HTTP status code %u/%d\n", + (unsigned int) response_code, + ud.ec); break; } tso->cb (tso->cb_cls, diff --git a/src/stasis/Makefile.am b/src/stasis/Makefile.am index d1a0b39..0197f0e 100644 --- a/src/stasis/Makefile.am +++ b/src/stasis/Makefile.am @@ -59,16 +59,16 @@ libanastasisdb_la_LDFLAGS = \ libanastasis_plugin_db_postgres_la_SOURCES = \ plugin_anastasis_postgres.c -libanastasis_plugin_db_postgres_la_LIBADD = \ - $(LTLIBINTL) libanastasis_plugin_db_postgres_la_LDFLAGS = \ + $(ANASTASIS_PLUGIN_LDFLAGS) +libanastasis_plugin_db_postgres_la_LIBADD = \ + $(LTLIBINTL) \ $(top_builddir)/src/util/libanastasisutil.la \ - $(ANASTASIS_PLUGIN_LDFLAGS) \ - -lgnunetpq \ - -lpq \ -ltalerpq \ -ltalerutil \ + -lgnunetpq \ -lgnunetutil \ + -lpq \ $(XLIB) check_PROGRAMS = \ @@ -83,7 +83,6 @@ test_anastasis_db_postgres_LDFLAGS = \ -lgnunetpq \ -ltalerutil \ -ltalerpq \ - -luuid \ $(XLIB) AM_TESTS_ENVIRONMENT=export ANASTASIS_PREFIX=$${ANASTASIS_PREFIX:-@libdir@};export PATH=$${ANASTASIS_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; diff --git a/src/stasis/drop.sql b/src/stasis/drop.sql index 67aa4a1..357fa9d 100644 --- a/src/stasis/drop.sql +++ b/src/stasis/drop.sql @@ -17,8 +17,14 @@ -- Everything in one big transaction BEGIN; --- Unregister patch (0001.sql) -SELECT _v.unregister_patch('stasis-0001'); +WITH xpatches AS ( + SELECT patch_name + FROM _v.patches + WHERE starts_with(patch_name,'stasis-') +) + SELECT _v.unregister_patch(xpatches.patch_name) + FROM xpatches; + DROP SCHEMA anastasis CASCADE; -- And we're out of here... diff --git a/src/stasis/plugin_anastasis_postgres.c b/src/stasis/plugin_anastasis_postgres.c index 566b81a..9f4b969 100644 --- a/src/stasis/plugin_anastasis_postgres.c +++ b/src/stasis/plugin_anastasis_postgres.c @@ -143,54 +143,44 @@ prepare_statements (void *cls) "(user_id" ",expiration_date" ") VALUES " - "($1, $2);", - 2), + "($1, $2);"), GNUNET_PQ_make_prepare ("do_commit", - "COMMIT", - 0), + "COMMIT"), GNUNET_PQ_make_prepare ("user_select", "SELECT" " expiration_date " "FROM anastasis_user" " WHERE user_id=$1" - " FOR UPDATE;", - 1), + " FOR UPDATE;"), GNUNET_PQ_make_prepare ("user_update", "UPDATE anastasis_user" " SET " " expiration_date=$1" - " WHERE user_id=$2;", - 2), + " WHERE user_id=$2;"), GNUNET_PQ_make_prepare ("recdoc_payment_insert", "INSERT INTO anastasis_recdoc_payment " "(user_id" ",post_counter" - ",amount_val" - ",amount_frac" + ",amount" ",payment_identifier" ",creation_date" ") VALUES " - "($1, $2, $3, $4, $5, $6);", - 6), + "($1, $2, $3, $4, $5);"), GNUNET_PQ_make_prepare ("challenge_payment_insert", "INSERT INTO anastasis_challenge_payment " "(truth_uuid" - ",amount_val" - ",amount_frac" + ",amount" ",payment_identifier" ",creation_date" ") VALUES " - "($1, $2, $3, $4, $5);", - 5), + "($1, $2, $3, $4);"), GNUNET_PQ_make_prepare ("truth_payment_insert", "INSERT INTO anastasis_truth_payment " "(truth_uuid" - ",amount_val" - ",amount_frac" + ",amount" ",expiration" ") VALUES " - "($1, $2, $3, $4);", - 4), + "($1, $2, $3);"), GNUNET_PQ_make_prepare ("recdoc_payment_done", "UPDATE anastasis_recdoc_payment " "SET" @@ -200,8 +190,7 @@ prepare_statements (void *cls) " AND" " user_id=$2" " AND" - " paid=FALSE;", - 2), + " paid=FALSE;"), GNUNET_PQ_make_prepare ("challenge_refund_update", "UPDATE anastasis_challenge_payment " "SET" @@ -211,8 +200,7 @@ prepare_statements (void *cls) " AND" " paid=TRUE" " AND" - " truth_uuid=$2;", - 2), + " truth_uuid=$2;"), GNUNET_PQ_make_prepare ("challenge_payment_done", "UPDATE anastasis_challenge_payment " "SET" @@ -224,43 +212,36 @@ prepare_statements (void *cls) " AND" " truth_uuid=$2" " AND" - " paid=FALSE;", - 2), + " paid=FALSE;"), GNUNET_PQ_make_prepare ("recdoc_payment_select", "SELECT" " creation_date" ",post_counter" - ",amount_val" - ",amount_frac" + ",amount" ",paid" " FROM anastasis_recdoc_payment" - " WHERE payment_identifier=$1;", - 1), + " WHERE payment_identifier=$1;"), GNUNET_PQ_make_prepare ("truth_payment_select", "SELECT" " expiration" " FROM anastasis_truth_payment" " WHERE truth_uuid=$1" - " AND expiration>$2;", - 2), + " AND expiration>$2;"), GNUNET_PQ_make_prepare ("challenge_payment_select", "SELECT" " creation_date" - ",amount_val" - ",amount_frac" + ",amount" ",paid" " FROM anastasis_challenge_payment" " WHERE payment_identifier=$1" " AND truth_uuid=$2" " AND refunded=FALSE" - " AND counter>0;", - 1), + " AND counter>0;"), GNUNET_PQ_make_prepare ("challenge_pending_payment_select", "SELECT" " creation_date" ",payment_identifier" - ",amount_val" - ",amount_frac" + ",amount" " FROM anastasis_challenge_payment" " WHERE" " paid=FALSE" @@ -269,29 +250,24 @@ prepare_statements (void *cls) " AND" " truth_uuid=$1" " AND" - " creation_date > $2;", - 1), + " creation_date > $2;"), GNUNET_PQ_make_prepare ("recdoc_payments_select", "SELECT" " user_id" ",payment_identifier" - ",amount_val" - ",amount_frac" + ",amount" " FROM anastasis_recdoc_payment" - " WHERE paid=FALSE;", - 0), + " WHERE paid=FALSE;"), GNUNET_PQ_make_prepare ("gc_accounts", "DELETE FROM anastasis_user " "WHERE" - " expiration_date < $1;", - 1), + " expiration_date < $1;"), GNUNET_PQ_make_prepare ("gc_recdoc_pending_payments", "DELETE FROM anastasis_recdoc_payment " "WHERE" " paid=FALSE" " AND" - " creation_date < $1;", - 1), + " creation_date < $1;"), GNUNET_PQ_make_prepare ("gc_challenge_pending_payments", "DELETE FROM anastasis_challenge_payment " "WHERE" @@ -299,8 +275,7 @@ prepare_statements (void *cls) " OR" " refunded=TRUE)" " AND" - " creation_date < $1;", - 1), + " creation_date < $1;"), GNUNET_PQ_make_prepare ("truth_insert", "INSERT INTO anastasis_truth " "(truth_uuid" @@ -310,29 +285,24 @@ prepare_statements (void *cls) ",truth_mime" ",expiration" ") VALUES " - "($1, $2, $3, $4, $5, $6);", - 6), + "($1, $2, $3, $4, $5, $6);"), GNUNET_PQ_make_prepare ("test_auth_iban_payment", "SELECT" - " credit_val" - ",credit_frac" + " credit" ",wire_subject" " FROM anastasis_auth_iban_in" " WHERE debit_account_details=$1" - " AND execution_date>=$2;", - 2), + " AND execution_date>=$2;"), GNUNET_PQ_make_prepare ("store_auth_iban_payment_details", "INSERT INTO anastasis_auth_iban_in " "(wire_reference" ",wire_subject" - ",credit_val" - ",credit_frac" + ",credit" ",debit_account_details" ",credit_account_details" ",execution_date" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7);", - 7), + "($1, $2, $3, $4, $5, $6);"), GNUNET_PQ_make_prepare ("recovery_document_insert", "INSERT INTO anastasis_recoverydocument " "(user_id" @@ -343,16 +313,14 @@ prepare_statements (void *cls) ",recovery_meta_data" ",creation_date" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7);", - 7), + "($1, $2, $3, $4, $5, $6, $7);"), GNUNET_PQ_make_prepare ("truth_select", "SELECT " " method_name" ",encrypted_truth" ",truth_mime" " FROM anastasis_truth" - " WHERE truth_uuid=$1;", - 1), + " WHERE truth_uuid=$1;"), GNUNET_PQ_make_prepare ("recoverydocument_select_meta", "SELECT " " version" @@ -362,8 +330,7 @@ prepare_statements (void *cls) " WHERE user_id=$1" " AND version < $2" " ORDER BY version DESC" - " LIMIT 1000;", - 2), + " LIMIT 1000;"), GNUNET_PQ_make_prepare ("latest_recoverydocument_select", "SELECT " " version" @@ -373,8 +340,7 @@ prepare_statements (void *cls) " FROM anastasis_recoverydocument" " WHERE user_id=$1" " ORDER BY version DESC" - " LIMIT 1;", - 1), + " LIMIT 1;"), GNUNET_PQ_make_prepare ("latest_recovery_version_select", "SELECT" " version" @@ -384,8 +350,7 @@ prepare_statements (void *cls) " JOIN anastasis_user USING (user_id)" " WHERE user_id=$1" " ORDER BY version DESC" - " LIMIT 1;", - 1), + " LIMIT 1;"), GNUNET_PQ_make_prepare ("recoverydocument_select", "SELECT " " account_sig" @@ -393,30 +358,26 @@ prepare_statements (void *cls) ",recovery_data" " FROM anastasis_recoverydocument" " WHERE user_id=$1" - " AND version=$2;", - 2), + " AND version=$2;"), GNUNET_PQ_make_prepare ("postcounter_select", "SELECT" " post_counter" " FROM anastasis_recdoc_payment" " WHERE user_id=$1" - " AND payment_identifier=$2;", - 2), + " AND payment_identifier=$2;"), GNUNET_PQ_make_prepare ("postcounter_update", "UPDATE" " anastasis_recdoc_payment" " SET" " post_counter=$1" " WHERE user_id =$2" - " AND payment_identifier=$3;", - 3), + " AND payment_identifier=$3;"), GNUNET_PQ_make_prepare ("key_share_select", "SELECT " "key_share_data " "FROM " "anastasis_truth " - "WHERE truth_uuid =$1;", - 1), + "WHERE truth_uuid =$1;"), GNUNET_PQ_make_prepare ("challengecode_insert", "INSERT INTO anastasis_challengecode " "(truth_uuid" @@ -425,8 +386,7 @@ prepare_statements (void *cls) ",expiration_date" ",retry_counter" ") VALUES " - "($1, $2, $3, $4, $5);", - 5), + "($1, $2, $3, $4, $5);"), GNUNET_PQ_make_prepare ("challengecode_select", "SELECT " " code" @@ -434,8 +394,7 @@ prepare_statements (void *cls) " FROM anastasis_challengecode" " WHERE truth_uuid=$1" " AND expiration_date > $2" - " AND retry_counter != 0;", - 2), + " AND retry_counter != 0;"), GNUNET_PQ_make_prepare ("challengecode_set_satisfied", "UPDATE anastasis_challengecode" " SET satisfied=TRUE" @@ -447,16 +406,14 @@ prepare_statements (void *cls) " WHERE truth_uuid=$1" " AND code=$2" " ORDER BY creation_date DESC" - " LIMIT 1);", - 2), + " LIMIT 1);"), GNUNET_PQ_make_prepare ("challengecode_test_satisfied", "SELECT 1 FROM anastasis_challengecode" " WHERE truth_uuid=$1" " AND satisfied=TRUE" " AND code=$2" " AND creation_date >= $3" - " LIMIT 1;", - 3), + " LIMIT 1;"), GNUNET_PQ_make_prepare ("challengecode_select_meta", "SELECT " " code" @@ -467,22 +424,19 @@ prepare_statements (void *cls) " AND expiration_date > $2" " AND creation_date > $3" " ORDER BY creation_date DESC" - " LIMIT 1;", - 2), + " LIMIT 1;"), GNUNET_PQ_make_prepare ("challengecode_update_retry", "UPDATE anastasis_challengecode" " SET retry_counter=retry_counter - 1" " WHERE truth_uuid=$1" " AND code=$2" - " AND retry_counter != 0;", - 1), + " AND retry_counter != 0;"), GNUNET_PQ_make_prepare ("challengepayment_dec_counter", "UPDATE anastasis_challenge_payment" " SET counter=counter - 1" " WHERE truth_uuid=$1" " AND payment_identifier=$2" - " AND counter > 0;", - 2), + " AND counter > 0;"), GNUNET_PQ_make_prepare ("challengecode_mark_sent", "UPDATE anastasis_challengecode" " SET retransmission_date=$3" @@ -494,21 +448,18 @@ prepare_statements (void *cls) " WHERE truth_uuid=$1" " AND code=$2" " ORDER BY creation_date DESC" - " LIMIT 1);", - 3), + " LIMIT 1);"), GNUNET_PQ_make_prepare ("get_last_auth_iban_payment", "SELECT " " wire_reference" " FROM anastasis_auth_iban_in" " WHERE credit_account_details=$1" " ORDER BY wire_reference DESC" - " LIMIT 1;", - 1), + " LIMIT 1;"), GNUNET_PQ_make_prepare ("gc_challengecodes", "DELETE FROM anastasis_challengecode " "WHERE " - "expiration_date < $1;", - 1), + "expiration_date < $1;"), GNUNET_PQ_PREPARED_STATEMENT_END }; @@ -1443,7 +1394,8 @@ postgres_record_recdoc_payment ( struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (account_pub), GNUNET_PQ_query_param_uint32 (&post_counter), - TALER_PQ_query_param_amount (amount), + TALER_PQ_query_param_amount (pg->conn, + amount), GNUNET_PQ_query_param_auto_from_type (payment_secret), GNUNET_PQ_query_param_timestamp (&now), GNUNET_PQ_query_param_end @@ -1546,7 +1498,8 @@ postgres_record_truth_upload_payment ( duration); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (uuid), - TALER_PQ_query_param_amount (amount), + TALER_PQ_query_param_amount (pg->conn, + amount), GNUNET_PQ_query_param_timestamp (&exp), GNUNET_PQ_query_param_end }; @@ -1613,7 +1566,8 @@ postgres_record_challenge_payment ( struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get (); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (truth_uuid), - TALER_PQ_query_param_amount (amount), + TALER_PQ_query_param_amount (pg->conn, + amount), GNUNET_PQ_query_param_auto_from_type (payment_secret), GNUNET_PQ_query_param_timestamp (&now), GNUNET_PQ_query_param_end @@ -1680,7 +1634,8 @@ postgres_record_auth_iban_payment ( struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&wire_reference), GNUNET_PQ_query_param_string (wire_subject), - TALER_PQ_query_param_amount (amount), + TALER_PQ_query_param_amount (pg->conn, + amount), GNUNET_PQ_query_param_string (debit_account), GNUNET_PQ_query_param_string (credit_account), GNUNET_PQ_query_param_timestamp (&execution_date), diff --git a/src/stasis/stasis-0001.sql b/src/stasis/stasis-0001.sql index cca8245..fe08cdc 100644 --- a/src/stasis/stasis-0001.sql +++ b/src/stasis/stasis-0001.sql @@ -1,6 +1,6 @@ -- -- This file is part of Anastasis --- Copyright (C) 2020, 2021, 2022 Anastasis SARL SA +-- Copyright (C) 2020, 2021, 2022, 2023 Anastasis SARL SA -- -- ANASTASIS 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 @@ -26,19 +26,25 @@ COMMENT ON SCHEMA anastasis IS 'anastasis backend data'; SET search_path TO anastasis; +CREATE TYPE taler_amount + AS + (val INT8 + ,frac INT4 + ); +COMMENT ON TYPE taler_amount + IS 'Stores an amount, fraction is in units of 1/100000000 of the base value'; + + CREATE TABLE IF NOT EXISTS anastasis_truth_payment (truth_uuid BYTEA PRIMARY KEY CHECK(LENGTH(truth_uuid)=32), - amount_val INT8 NOT NULL, - amount_frac INT4 NOT NULL, + amount taler_amount NOT NULL, expiration INT8 NOT NULL); COMMENT ON TABLE anastasis_truth_payment IS 'Records about payments for truth uploads'; COMMENT ON COLUMN anastasis_truth_payment.truth_uuid IS 'Identifier of the truth'; -COMMENT ON COLUMN anastasis_truth_payment.amount_val +COMMENT ON COLUMN anastasis_truth_payment.amount IS 'Amount we were paid'; -COMMENT ON COLUMN anastasis_truth_payment.amount_frac - IS 'Amount we were paid fraction'; COMMENT ON COLUMN anastasis_truth_payment.expiration IS 'At which date will the truth payment expire'; @@ -46,9 +52,9 @@ COMMENT ON COLUMN anastasis_truth_payment.expiration CREATE TABLE IF NOT EXISTS anastasis_truth (truth_uuid BYTEA PRIMARY KEY CHECK(LENGTH(truth_uuid)=32), key_share_data BYTEA CHECK(LENGTH(key_share_data)=72) NOT NULL, - method_name VARCHAR NOT NULL, + method_name TEXT NOT NULL, encrypted_truth BYTEA NOT NULL, - truth_mime VARCHAR NOT NULL, + truth_mime TEXT NOT NULL, expiration INT8 NOT NULL); COMMENT ON TABLE anastasis_truth IS 'Truth data is needed to authenticate clients during recovery'; @@ -81,8 +87,7 @@ CREATE TABLE IF NOT EXISTS anastasis_recdoc_payment (payment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, user_id BYTEA NOT NULL REFERENCES anastasis_user(user_id), post_counter INT4 NOT NULL DEFAULT 0 CHECK(post_counter >= 0), - amount_val INT8 NOT NULL, - amount_frac INT4 NOT NULL, + amount taler_amount NOT NULL, payment_identifier BYTEA NOT NULL CHECK(LENGTH(payment_identifier)=32), creation_date INT8 NOT NULL, paid BOOLEAN NOT NULL DEFAULT FALSE); @@ -94,10 +99,8 @@ COMMENT ON COLUMN anastasis_recdoc_payment.user_id IS 'Link to the corresponding user who paid'; COMMENT ON COLUMN anastasis_recdoc_payment.post_counter IS 'For how many posts does the user pay'; -COMMENT ON COLUMN anastasis_recdoc_payment.amount_val +COMMENT ON COLUMN anastasis_recdoc_payment.amount IS 'Amount we were paid'; -COMMENT ON COLUMN anastasis_recdoc_payment.amount_frac - IS 'Amount we were paid fraction'; COMMENT ON COLUMN anastasis_recdoc_payment.payment_identifier IS 'Payment identifier which the user has to provide'; COMMENT ON COLUMN anastasis_recdoc_payment.creation_date @@ -109,8 +112,7 @@ COMMENT ON COLUMN anastasis_recdoc_payment.paid CREATE TABLE IF NOT EXISTS anastasis_challenge_payment (payment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, truth_uuid BYTEA CHECK(LENGTH(truth_uuid)=32) NOT NULL, - amount_val INT8 NOT NULL, - amount_frac INT4 NOT NULL, + amount taler_amount NOT NULL, payment_identifier BYTEA NOT NULL CHECK(LENGTH(payment_identifier)=32), creation_date INT8 NOT NULL, counter INT4 NOT NULL DEFAULT 3, @@ -123,10 +125,8 @@ COMMENT ON COLUMN anastasis_challenge_payment.payment_id IS 'Serial number which identifies the payment'; COMMENT ON COLUMN anastasis_challenge_payment.truth_uuid IS 'Link to the corresponding challenge which is paid'; -COMMENT ON COLUMN anastasis_challenge_payment.amount_val +COMMENT ON COLUMN anastasis_challenge_payment.amount IS 'Amount we were paid'; -COMMENT ON COLUMN anastasis_challenge_payment.amount_frac - IS 'Amount we were paid fraction'; COMMENT ON COLUMN anastasis_challenge_payment.payment_identifier IS 'Payment identifier which the user has to provide'; COMMENT ON COLUMN anastasis_challenge_payment.counter @@ -208,8 +208,7 @@ CREATE TABLE IF NOT EXISTS anastasis_auth_iban_in (auth_in_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,wire_reference INT8 NOT NULL PRIMARY KEY ,wire_subject TEXT NOT NULL - ,credit_val INT8 NOT NULL - ,credit_frac INT4 NOT NULL + ,credit taler_amount NOT NULL ,debit_account_details TEXT NOT NULL ,credit_account_details TEXT NOT NULL ,execution_date INT8 NOT NULL @@ -220,6 +219,8 @@ COMMENT ON COLUMN anastasis_auth_iban_in.wire_reference IS 'Unique number identifying the wire transfer in LibEuFin/Nexus'; COMMENT ON COLUMN anastasis_auth_iban_in.wire_subject IS 'For authentication, this contains the code, but also additional text'; +COMMENT ON COLUMN anastasis_auth_iban_in.credit + IS 'Amount we were credited'; COMMENT ON COLUMN anastasis_auth_iban_in.execution_date IS 'Used both for (theoretical) garbage collection and to see if the transfer happened on time'; COMMENT ON COLUMN anastasis_auth_iban_in.credit_account_details diff --git a/src/stasis/versioning.sql b/src/stasis/versioning.sql index 116f409..444cf95 100644 --- a/src/stasis/versioning.sql +++ b/src/stasis/versioning.sql @@ -146,12 +146,13 @@ BEGIN; + -- This file adds versioning support to database it will be loaded to. -- It requires that PL/pgSQL is already loaded - will raise exception otherwise. -- All versioning "stuff" (tables, functions) is in "_v" schema. -- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literally nothing (0 rows). --- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling. +-- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling CREATE SCHEMA IF NOT EXISTS _v; COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.'; diff --git a/src/testing/.gitignore b/src/testing/.gitignore index a6eb294..9ac5ba4 100644 --- a/src/testing/.gitignore +++ b/src/testing/.gitignore @@ -1,3 +1,6 @@ test_anastasis test_anastasisrest_api -test_anastasis_api_home/.local/share/taler/crypto-* +test_anastasis_api_home/taler/exchange-secmod-* +test_anastasis_api_home/taler/auditor/ +test_anastasis_api_home/taler/exchange/offline-keys/secm_tofus.pub +test_anastasis_api.conf.edited diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index fec971a..22162d3 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -38,7 +38,6 @@ libanastasistesting_la_LIBADD = \ -lgnunetjson \ -lgnunetutil \ -ljansson \ - -luuid \ -ltalertesting \ $(XLIB) @@ -72,9 +71,8 @@ test_anastasis_LDADD = \ EXTRA_DIST = \ test_anastasis_api.conf \ - test_anastasis_api_home/.config/taler/exchange/account-2.json \ - test_anastasis_api_home/.local/share/taler/exchange/offline-keys/master.priv \ + test_anastasis_api_home/taler/exchange/offline-keys/master.priv \ sms_authentication.sh MOSTLYCLEANFILES = \ - test_anastasis_api_home/.local/share/taler/exchange/offline-keys/secm_tofus.pub + test_anastasis_api_home/taler/exchange/offline-keys/secm_tofus.pub diff --git a/src/testing/test_anastasis.c b/src/testing/test_anastasis.c index 4fa3fb9..f28d9a9 100644 --- a/src/testing/test_anastasis.c +++ b/src/testing/test_anastasis.c @@ -1,6 +1,6 @@ /* This file is part of Anastasis - Copyright (C) 2020, 2021 Anastasis SARL + Copyright (C) 2020-2023 Anastasis SARL Anastasis 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 @@ -52,34 +52,29 @@ #define MERCHANT_ACCOUNT_NAME "3" /** - * Configuration of the bank. + * Credentials for the test. */ -static struct TALER_TESTING_BankConfiguration bc; - -/** - * Configuration of the exchange. - */ -static struct TALER_TESTING_ExchangeConfiguration ec; +static struct TALER_TESTING_Credentials cred; /** * Payto URI of the customer (payer). */ -static char *payer_payto; +static const char *payer_payto; /** * Payto URI of the exchange (escrow account). */ -static char *exchange_payto; +static const char *exchange_payto; /** * Payto URI of the merchant (receiver). */ -static char *merchant_payto; +static const char *merchant_payto; /** * Merchant base URL. */ -static char *merchant_url; +static const char *merchant_url; /** * Anastasis base URL. @@ -92,11 +87,6 @@ static char *anastasis_url; static char *file_secret; /** - * Merchant process. - */ -static struct GNUNET_OS_Process *merchantd; - -/** * Anastasis process. */ static struct GNUNET_OS_Process *anastasisd; @@ -135,7 +125,7 @@ cmd_transfer_to_exchange (const char *label, { return TALER_TESTING_cmd_admin_add_incoming (label, amount, - &bc.exchange_auth, + &cred.ba, payer_payto); } @@ -328,28 +318,29 @@ run (void *cls, struct TALER_TESTING_Command commands[] = { /* general setup */ - TALER_TESTING_cmd_auditor_add ("add-auditor-OK", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_wire_add ("add-wire-account", - "payto://x-taler-bank/localhost/2", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys", - CONFIG_FILE), - TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees", - CONFIG_FILE, - "EUR:0.01", - "EUR:0.01", - "EUR:0.01"), - TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", - 1), + TALER_TESTING_cmd_run_fakebank ("run-fakebank", + cred.cfg, + "exchange-account-exchange"), + TALER_TESTING_cmd_system_start ("start-taler", + CONFIG_FILE, + "-em", + "-u", "exchange-account-exchange", + NULL), + TALER_TESTING_cmd_get_exchange ("get-exchange", + cred.cfg, + NULL, + true, + true), TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", merchant_url, "default", - merchant_payto, - "EUR", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + merchant_url, + merchant_payto, + NULL, NULL, + MHD_HTTP_OK), TALER_TESTING_cmd_batch ("pay", pay), TALER_TESTING_cmd_batch ("anastasis", @@ -357,9 +348,8 @@ run (void *cls, TALER_TESTING_cmd_end () }; - TALER_TESTING_run_with_fakebank (is, - commands, - bc.exchange_auth.wire_gateway_url); + TALER_TESTING_run (is, + commands); } @@ -367,19 +357,7 @@ int main (int argc, char *const *argv) { - unsigned int ret; - /* These environment variables get in the way... */ - unsetenv ("XDG_DATA_HOME"); - unsetenv ("XDG_CONFIG_HOME"); - - GNUNET_log_setup ("test-anastasis", - "DEBUG", - NULL); - if (GNUNET_OK != - TALER_TESTING_prepare_fakebank (CONFIG_FILE, - "exchange-account-exchange", - &bc)) - return 77; + int ret; { char dir[] = "/tmp/test-anastasis-file-XXXXXX"; @@ -394,73 +372,42 @@ main (int argc, "%s/.secret", dir); } - id_data = ANASTASIS_TESTING_make_id_data_example ( - "MaxMuster123456789"); - payer_payto = ("payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME); - exchange_payto = ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME); - merchant_payto = ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME); - if (NULL == - (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) - return 77; - TALER_TESTING_cleanup_files (CONFIG_FILE); + id_data = ANASTASIS_TESTING_make_id_data_example ("MaxMuster123456789"); + payer_payto = + "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME + "?receiver-name=62"; + exchange_payto = + "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME + "?receiver-name=exchange"; + merchant_payto = + "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME + "?receiver-name=merchant"; + merchant_url = "http://localhost:8080/"; if (NULL == (anastasis_url = ANASTASIS_TESTING_prepare_anastasis (CONFIG_FILE))) return 77; - TALER_TESTING_cleanup_files (CONFIG_FILE); - - switch (TALER_TESTING_prepare_exchange (CONFIG_FILE, - GNUNET_YES, - &ec)) + if (NULL == (anastasisd = + ANASTASIS_TESTING_run_anastasis (CONFIG_FILE, + anastasis_url))) { - case GNUNET_SYSERR: - GNUNET_break (0); - return 1; - case GNUNET_NO: - return 77; - case GNUNET_OK: - if (NULL == (merchantd = - TALER_TESTING_run_merchant (CONFIG_FILE, - merchant_url))) - { - GNUNET_break (0); - return 1; - } - if (NULL == (anastasisd = - ANASTASIS_TESTING_run_anastasis (CONFIG_FILE, - anastasis_url))) - { - GNUNET_break (0); - GNUNET_OS_process_kill (merchantd, - SIGTERM); - GNUNET_OS_process_wait (merchantd); - GNUNET_OS_process_destroy (merchantd); - - return 1; - } - ret = TALER_TESTING_setup_with_exchange (&run, - NULL, - CONFIG_FILE); - - GNUNET_OS_process_kill (merchantd, - SIGTERM); - GNUNET_OS_process_kill (anastasisd, - SIGTERM); - GNUNET_OS_process_wait (merchantd); - GNUNET_OS_process_wait (anastasisd); - GNUNET_OS_process_destroy (merchantd); - GNUNET_OS_process_destroy (anastasisd); - GNUNET_free (merchant_url); - GNUNET_free (anastasis_url); - - if (GNUNET_OK != ret) - return 1; - break; - default: GNUNET_break (0); return 1; } - return 0; + ret = TALER_TESTING_main (argv, + "INFO", + CONFIG_FILE, + "exchange-account-exchange", + TALER_TESTING_BS_FAKEBANK, + &cred, + &run, + NULL); + GNUNET_OS_process_kill (anastasisd, + SIGTERM); + GNUNET_OS_process_wait (anastasisd); + GNUNET_OS_process_destroy (anastasisd); + GNUNET_free (anastasis_url); + return ret; } diff --git a/src/testing/test_anastasis_api.c b/src/testing/test_anastasis_api.c index 4d85fed..7d7e2ac 100644 --- a/src/testing/test_anastasis_api.c +++ b/src/testing/test_anastasis_api.c @@ -52,34 +52,29 @@ #define MERCHANT_ACCOUNT_NAME "3" /** - * Configuration of the bank. + * Test credentials. */ -static struct TALER_TESTING_BankConfiguration bc; - -/** - * Configuration of the exchange. - */ -static struct TALER_TESTING_ExchangeConfiguration ec; +static struct TALER_TESTING_Credentials cred; /** * Payto URI of the customer (payer). */ -static char *payer_payto; +static const char *payer_payto; /** * Payto URI of the exchange (escrow account). */ -static char *exchange_payto; +static const char *exchange_payto; /** * Payto URI of the merchant (receiver). */ -static char *merchant_payto; +static const char *merchant_payto; /** * Merchant base URL. */ -static char *merchant_url; +static const char *merchant_url; /** * Anastasis base URL. @@ -87,11 +82,6 @@ static char *merchant_url; static char *anastasis_url; /** - * Merchant process. - */ -static struct GNUNET_OS_Process *merchantd; - -/** * Anastasis process. */ static struct GNUNET_OS_Process *anastasisd; @@ -129,7 +119,7 @@ cmd_transfer_to_exchange (const char *label, { return TALER_TESTING_cmd_admin_add_incoming (label, amount, - &bc.exchange_auth, + &cred.ba, payer_payto); } @@ -276,28 +266,29 @@ run (void *cls, struct TALER_TESTING_Command commands[] = { /* general setup */ - TALER_TESTING_cmd_auditor_add ("add-auditor-OK", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_wire_add ("add-wire-account", - "payto://x-taler-bank/localhost/2", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys", - CONFIG_FILE), - TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees", - CONFIG_FILE, - "EUR:0.01", - "EUR:0.01", - "EUR:0.01"), - TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", - 1), + TALER_TESTING_cmd_run_fakebank ("run-fakebank", + cred.cfg, + "exchange-account-exchange"), + TALER_TESTING_cmd_system_start ("start-taler", + CONFIG_FILE, + "-em", + "-u", "exchange-account-exchange", + NULL), + TALER_TESTING_cmd_get_exchange ("get-exchange", + cred.cfg, + NULL, + true, + true), TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", merchant_url, "default", - merchant_payto, - "EUR", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + merchant_url, + merchant_payto, + NULL, NULL, + MHD_HTTP_OK), ANASTASIS_TESTING_cmd_config ("salt-request-1", anastasis_url, MHD_HTTP_OK), @@ -310,9 +301,8 @@ run (void *cls, TALER_TESTING_cmd_end () }; - TALER_TESTING_run_with_fakebank (is, - commands, - bc.exchange_auth.wire_gateway_url); + TALER_TESTING_run (is, + commands); } @@ -322,17 +312,6 @@ main (int argc, { int ret; - /* These environment variables get in the way... */ - unsetenv ("XDG_DATA_HOME"); - unsetenv ("XDG_CONFIG_HOME"); - GNUNET_log_setup ("test-anastasis-api", - "DEBUG", - NULL); - if (GNUNET_OK != - TALER_TESTING_prepare_fakebank (CONFIG_FILE, - "exchange-account-exchange", - &bc)) - return 77; { char dir[] = "/tmp/test-anastasis-file-XXXXXX"; @@ -347,73 +326,41 @@ main (int argc, "%s/.secret", dir); } - payer_payto = ("payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME); - exchange_payto = ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME); - merchant_payto = ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME); - if (NULL == - (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) - return 77; - TALER_TESTING_cleanup_files (CONFIG_FILE); + payer_payto = + "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME + "?receiver-name=62"; + exchange_payto = + "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME + "?receiver-name=exchange"; + merchant_payto = + "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME + "?receiver-name=merchant"; + merchant_url = "http://localhost:8080/"; if (NULL == (anastasis_url = ANASTASIS_TESTING_prepare_anastasis (CONFIG_FILE))) return 77; - TALER_TESTING_cleanup_files (CONFIG_FILE); - - switch (TALER_TESTING_prepare_exchange (CONFIG_FILE, - GNUNET_YES, - &ec)) + if (NULL == (anastasisd = + ANASTASIS_TESTING_run_anastasis (CONFIG_FILE, + anastasis_url))) { - case GNUNET_SYSERR: - GNUNET_break (0); - return 1; - case GNUNET_NO: - return 77; - case GNUNET_OK: - if (NULL == (merchantd = - TALER_TESTING_run_merchant (CONFIG_FILE, - merchant_url))) - { - GNUNET_break (0); - return 1; - } - if (NULL == (anastasisd = - ANASTASIS_TESTING_run_anastasis (CONFIG_FILE, - anastasis_url))) - { - GNUNET_break (0); - GNUNET_OS_process_kill (merchantd, - SIGTERM); - GNUNET_OS_process_wait (merchantd); - GNUNET_OS_process_destroy (merchantd); - return 1; - } - ret = TALER_TESTING_setup_with_exchange (&run, - NULL, - CONFIG_FILE); - GNUNET_OS_process_kill (merchantd, - SIGTERM); - GNUNET_OS_process_kill (anastasisd, - SIGTERM); - GNUNET_OS_process_wait (merchantd); - GNUNET_OS_process_wait (anastasisd); - GNUNET_OS_process_destroy (merchantd); - GNUNET_OS_process_destroy (anastasisd); - GNUNET_free (merchant_url); - GNUNET_free (anastasis_url); - - if (GNUNET_OK != ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Test failed in interpreter\n"); - return 1; - } - break; - default: GNUNET_break (0); return 1; } - return 0; + ret = TALER_TESTING_main (argv, + "INFO", + CONFIG_FILE, + "exchange-account-exchange", + TALER_TESTING_BS_FAKEBANK, + &cred, + &run, + NULL); + GNUNET_OS_process_kill (anastasisd, + SIGTERM); + GNUNET_OS_process_wait (anastasisd); + GNUNET_OS_process_destroy (anastasisd); + GNUNET_free (anastasis_url); + return ret; } diff --git a/src/testing/test_anastasis_api.conf b/src/testing/test_anastasis_api.conf index 3dfc6ba..53801d4 100644 --- a/src/testing/test_anastasis_api.conf +++ b/src/testing/test_anastasis_api.conf @@ -1,231 +1,125 @@ # This file is in the public domain. # [PATHS] -# Persistent data storage for the testcase TALER_TEST_HOME = test_anastasis_api_home/ -TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/ - -# Persistent data storage -TALER_DATA_HOME = $TALER_TEST_HOME/.local/share/taler/ - -# Configuration files -TALER_CONFIG_HOME = $TALER_TEST_HOME/.config/taler/ - -# Cached data, no big deal if lost -TALER_CACHE_HOME = $TALER_TEST_HOME/.cache/taler/ +TALER_HOME = ${TALER_TEST_HOME:-${HOME:-${USERPROFILE}}} +TALER_DATA_HOME = ${TALER_TEST_HOME:-${XDG_DATA_HOME:-${TALER_HOME}/.local/share/}/.local/share/}taler/ +TALER_CONFIG_HOME = ${TALER_TEST_HOME:-${XDG_CONFIG_HOME:-${TALER_HOME}/.config/}/.config/}taler/ +TALER_CACHE_HOME = ${TALER_TEST_HOME:-${XDG_CACHE_HOME:-${TALER_HOME}/.cache/}/.cache/}taler/ +TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/taler-system-runtime/ [taler] -# What currency do we use? -#currency = EUR -currency = EUR -#CURRENCY_ROUND_UNIT = EUR:0.01 -#CURRENCY_ROUND_UNIT = EUR:0.01 +CURRENCY = EUR +CURRENCY_ROUND_UNIT = EUR:0.01 [taler-helper-crypto-rsa] -# Reduce from 1 year to speed up test LOOKAHEAD_SIGN = 12 days [taler-helper-crypto-eddsa] -# Reduce from 1 year to speed up test LOOKAHEAD_SIGN = 12 days -# Reduce from 12 weeks to ensure we have multiple DURATION = 7 days - [bank] HTTP_PORT = 8082 -#BASE_URL = https://bank.test.taler.net/ +BASE_URL = http://localhost:8082/ -########################################## -# Configuration for Anastasis # -########################################## +[libeufin-bank] +CURRENCY = EUR +WIRE_TYPE = iban +IBAN_PAYTO_BIC = SANDBOXX +DEFAULT_CUSTOMER_DEBT_LIMIT = EUR:200 +DEFAULT_ADMIN_DEBT_LIMIT = EUR:2000 +REGISTRATION_BONUS_ENABLED = yes +REGISTRATION_BONUS = EUR:100 +SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ +SERVE = tcp +PORT = 8082 [anastasis] PORT = 8086 - DB = postgres - BUSINESS_NAME = "Checker's Test Inc." - -# Upload limit UPLOAD_LIMIT_MB = 1 - ANNUAL_POLICY_UPLOAD_LIMIT = 64 - INSURANCE = EUR:0 - PROVIDER_SALT = salty - - -# Annual fee we charge. -#ANNUAL_FEE = EUR:4.99 ANNUAL_FEE = EUR:4.99 - TRUTH_UPLOAD_FEE = EUR:0.0 - -# Base URL of anastasis. -# BASE_URL = http://localhost:8086/ +BASE_URL = http://localhost:8086/ [anastasis-merchant-backend] -# Where does our payment backend run? Must match PORT under [merchant] PAYMENT_BACKEND_URL = http://localhost:8080/ -# Authentication costs [authorization-question] -# Cost of authentication by question COST = EUR:0 [authorization-file] -# Cost of authentication by file (only for testing purposes) COST = EUR:1 [authorization-email] -# Cost of authentication by E-Mail COST = EUR:0 [authorization-sms] -# Cost of authentication by SMS COST = EUR:0 - -# Command which is executed for the sms authentication COMMAND = ./sms_authentication.sh - - - -# This specifies which database the postgres backend uses. [stasis-postgres] CONFIG = postgres:///anastasischeck -########################################## -# Configuration for the merchant backend # -########################################## - [merchant] - -# Which port do we run the backend on? (HTTP server) PORT = 8080 - -# How quickly do we want the exchange to send us our money? -# Used only if the frontend does not specify a value. WIRE_TRANSFER_DELAY = 0 s - -# Which plugin (backend) do we use for the DB. DB = postgres -# Default choice for maximum wire fee. -DEFAULT_MAX_WIRE_FEE = EUR:0.10 - -# Default choice for maximum deposit fee. -DEFAULT_MAX_DEPOSIT_FEE = EUR:0.10 - - -# This specifies which database the postgres backend uses. [merchantdb-postgres] CONFIG = postgres:///talercheck -# Sections starting with "exchange-" specify trusted exchanges -# (by the merchant) [merchant-exchange-default] MASTER_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG EXCHANGE_BASE_URL = http://localhost:8081/ -#MASTER_KEY = DY95EXAHQ2BKM2WK9YHZHYG1R7PPMMJPY14FNGP662DAKE35AKQG -#EXCHANGE_BASE_URL = https://exchange.test.taler.net/ -#CURRENCY = EUR CURRENCY = EUR -# only fixes skips. [auditor] -BASE_URL = http://the.auditor/ -#BASE_URL = https://auditor.test.taler.net/ -#AUDITOR_KEY = DSDASDXAMDAARMNAD53ZA4AFAHA2QADAMAHHASWDAWXN84SDAA11 -# If currency does not match [TALER] section, the auditor -# will be ignored! -CURRENCY = EUR - -# Where do we store the auditor's private key? -AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv - -# Auditors must be in sections "auditor-", the rest of the section -# name could be anything. -[auditor-ezb] -# Informal name of the auditor. Just for the user. -NAME = European Central Bank - -# URL of the auditor (especially for in the future, when the -# auditor offers an automated issue reporting system). -# Not really used today. -URL = http://taler.ezb.eu/ - -# This is the important bit: the signing key of the auditor. -PUBLIC_KEY = 9QXF7XY7E9VPV47B5Z806NDFSX2VJ79SVHHD29QEQ3BG31ANHZ60 - -# Which currency is this auditor trusted for? -CURRENCY = EUR - - -################################################### -# Configuration for the exchange for the testcase # -################################################### +PORT = 8083 +BASE_URL = "http://localhost:8083/" [exchange] -# How to access our database +AML_THRESHOLD = EUR:1000000 DB = postgres - -# HTTP port the exchange listens to PORT = 8081 - -# how long are the signatures with the signkey valid? SIGNKEY_LEGAL_DURATION = 2 years - -# Our public key MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG - -# Base URL of the exchange. BASE_URL = "http://localhost:8081/" -#BASE_URL = https://exchange.test.taler.net/ - -# Network configuration for the normal API/service HTTP server -# serve via tcp socket (on PORT) SERVE = tcp +STEFAN_ABS = "EUR:5" [exchange-offline] - -# Where do we store the offline master private key of the exchange? MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv -# Where do we store the TOFU key material? SECM_TOFU_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/secm_tofus.pub - [taler-exchange-secmod-eddsa] -# Where do we store the generated private keys. KEY_DIR = ${TALER_DATA_HOME}/exchange-secmod-eddsa/keys [taler-exchange-secmod-rsa] -# Where do we store the generated private keys. KEY_DIR = ${TALER_DATA_HOME}/exchange-secmod-rsa/keys +[taler-exchange-secmod-cs] +KEY_DIR = ${TALER_DATA_HOME}/exchange-secmod-cs/keys -[exchangedb-postgres] -CONFIG = "postgres:///talercheck" -[auditordb-postgres] +[exchangedb-postgres] CONFIG = "postgres:///talercheck" -# Account of the EXCHANGE [exchange-account-exchange] -# What is the exchange's bank account (with the "Taler Bank" demo system)? -PAYTO_URI = "payto://x-taler-bank/localhost:8082/2" +PAYTO_URI = "payto://x-taler-bank/localhost:8082/2?receiver-name=exchange" ENABLE_DEBIT = YES ENABLE_CREDIT = YES [exchange-accountcredentials-exchange] -WIRE_GATEWAY_URL = "http://localhost:8082/2/" +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = NONE - - [coin_eur_ct_1] value = EUR:0.01 duration_withdraw = 7 days diff --git a/src/testing/test_anastasis_api_home/.config/taler/exchange/account-2.json b/src/testing/test_anastasis_api_home/.config/taler/exchange/account-2.json deleted file mode 100644 index f798275..0000000 --- a/src/testing/test_anastasis_api_home/.config/taler/exchange/account-2.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "payto_uri": "payto://x-taler-bank/localhost:8082/2", - "master_sig": "AM32QB4RYMWK548PE63PJXJMWSA001TFFWTZZPSSD8HQ8JE4D5V5X8WTSYSX59ANF4YRTRMF5Q4Q12CE2KTA8KQ03CM11YDTK75SJ20"} diff --git a/src/testing/test_anastasis_api_home/.local/share/taler/exchange/offline-keys/master.priv b/src/testing/test_anastasis_api_home/taler/exchange-offline/master.priv index c20942d..c20942d 100644 --- a/src/testing/test_anastasis_api_home/.local/share/taler/exchange/offline-keys/master.priv +++ b/src/testing/test_anastasis_api_home/taler/exchange-offline/master.priv diff --git a/src/testing/test_anastasis_api_home/taler/exchange/offline-keys/master.priv b/src/testing/test_anastasis_api_home/taler/exchange/offline-keys/master.priv new file mode 100644 index 0000000..c20942d --- /dev/null +++ b/src/testing/test_anastasis_api_home/taler/exchange/offline-keys/master.priv @@ -0,0 +1 @@ +k;d_U}A.w"!Gv_m"_
\ No newline at end of file diff --git a/src/testing/testing_api_cmd_config.c b/src/testing/testing_api_cmd_config.c index 92a8ae1..542e140 100644 --- a/src/testing/testing_api_cmd_config.c +++ b/src/testing/testing_api_cmd_config.c @@ -61,39 +61,26 @@ struct ConfigState * Function called with the results of a #ANASTASIS_get_config(). * * @param cls closure - * @param http_status HTTP status of the request * @param config config from the server */ static void config_cb (void *cls, - unsigned int http_status, const struct ANASTASIS_Config *config) { struct ConfigState *ss = cls; ss->so = NULL; - if (http_status != ss->http_status) + if (config->http_status != ss->http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - http_status, - ss->is->commands[ss->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (ss->is); + TALER_TESTING_unexpected_status (ss->is, + config->http_status, + ss->http_status); return; } - if (NULL == config) + if (GNUNET_OK == config->http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Config is NULL, command %s in %s:%u\n", - ss->is->commands[ss->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (ss->is); - return; + ss->provider_salt = config->details.ok.provider_salt; } - ss->provider_salt = config->provider_salt; TALER_TESTING_interpreter_next (ss->is); } @@ -113,10 +100,11 @@ config_run (void *cls, struct ConfigState *ss = cls; ss->is = is; - ss->so = ANASTASIS_get_config (is->ctx, - ss->anastasis_url, - &config_cb, - ss); + ss->so = ANASTASIS_get_config ( + TALER_TESTING_interpreter_get_context (is), + ss->anastasis_url, + &config_cb, + ss); if (NULL == ss->so) { GNUNET_break (0); diff --git a/src/testing/testing_api_cmd_policy_lookup.c b/src/testing/testing_api_cmd_policy_lookup.c index 1f59b12..2d854c5 100644 --- a/src/testing/testing_api_cmd_policy_lookup.c +++ b/src/testing/testing_api_cmd_policy_lookup.c @@ -72,32 +72,26 @@ struct PolicyLookupState * Function called with the results of a #ANASTASIS_policy_lookup(). * * @param cls closure - * @param http_status HTTP status of the request * @param dd details about the lookup operation */ static void policy_lookup_cb (void *cls, - unsigned int http_status, const struct ANASTASIS_DownloadDetails *dd) { struct PolicyLookupState *pls = cls; pls->plo = NULL; - if (http_status != pls->http_status) + if (dd->http_status != pls->http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - http_status, - pls->is->commands[pls->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (pls->is); + TALER_TESTING_unexpected_status (pls->is, + dd->http_status, + pls->http_status); return; } if (NULL != pls->upload_reference) { - if ( (MHD_HTTP_OK == http_status) && - (0 != GNUNET_memcmp (&dd->curr_policy_hash, + if ( (MHD_HTTP_OK == dd->http_status) && + (0 != GNUNET_memcmp (&dd->details.ok.curr_policy_hash, pls->upload_hash)) ) { GNUNET_break (0); @@ -156,11 +150,12 @@ policy_lookup_run (void *cls, } pls->anastasis_pub = *anastasis_pub; } - pls->plo = ANASTASIS_policy_lookup (is->ctx, - pls->anastasis_url, - &pls->anastasis_pub, - &policy_lookup_cb, - pls); + pls->plo = ANASTASIS_policy_lookup ( + TALER_TESTING_interpreter_get_context (is), + pls->anastasis_url, + &pls->anastasis_pub, + &policy_lookup_cb, + pls); if (NULL == pls->plo) { GNUNET_break (0); diff --git a/src/testing/testing_api_cmd_policy_store.c b/src/testing/testing_api_cmd_policy_store.c index f23489d..edc753d 100644 --- a/src/testing/testing_api_cmd_policy_store.c +++ b/src/testing/testing_api_cmd_policy_store.c @@ -139,13 +139,9 @@ policy_store_cb (void *cls, pss->pso = NULL; if (ud->http_status != pss->http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - ud->http_status, - pss->is->commands[pss->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (pss->is); + TALER_TESTING_unexpected_status (pss->is, + ud->http_status, + pss->http_status); return; } switch (ud->us) @@ -276,7 +272,7 @@ policy_store_run (void *cls, pss->recovery_data_size, &pss->curr_hash); pss->pso = ANASTASIS_policy_store ( - is->ctx, + TALER_TESTING_interpreter_get_context (is), pss->anastasis_url, &pss->anastasis_priv, pss->recovery_data, @@ -340,8 +336,7 @@ policy_store_traits (void *cls, struct PolicyStoreState *pss = cls; struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_claim_token (&pss->claim_token), - TALER_TESTING_make_trait_order_id ( - (const char **) &pss->order_id), + TALER_TESTING_make_trait_order_id (pss->order_id), ANASTASIS_TESTING_make_trait_hash (&pss->curr_hash), ANASTASIS_TESTING_make_trait_account_pub (&pss->anastasis_pub), ANASTASIS_TESTING_make_trait_account_priv (&pss->anastasis_priv), diff --git a/src/testing/testing_api_cmd_truth_challenge.c b/src/testing/testing_api_cmd_truth_challenge.c index f1384c4..c399345 100644 --- a/src/testing/testing_api_cmd_truth_challenge.c +++ b/src/testing/testing_api_cmd_truth_challenge.c @@ -100,13 +100,9 @@ truth_challenge_cb (void *cls, ksls->tco = NULL; if (tcd->http_status != ksls->expected_http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - tcd->http_status, - ksls->is->commands[ksls->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (ksls->is); + TALER_TESTING_unexpected_status (ksls->is, + tcd->http_status, + ksls->expected_http_status); return; } switch (tcd->http_status) @@ -268,13 +264,14 @@ truth_challenge_run (void *cls, payment_secret = NULL; } - ksls->tco = ANASTASIS_truth_challenge (is->ctx, - ksls->anastasis_url, - truth_uuid, - truth_key, - payment_secret, - &truth_challenge_cb, - ksls); + ksls->tco = ANASTASIS_truth_challenge ( + TALER_TESTING_interpreter_get_context (is), + ksls->anastasis_url, + truth_uuid, + truth_key, + payment_secret, + &truth_challenge_cb, + ksls); if (NULL == ksls->tco) { GNUNET_break (0); @@ -325,12 +322,9 @@ truth_challenge_traits (void *cls, struct TALER_TESTING_Trait traits[] = { ANASTASIS_TESTING_make_trait_payment_secret ( &ksls->payment_secret_response), - TALER_TESTING_make_trait_payto_uri ( - (const char **) ksls->pay_uri), - TALER_TESTING_make_trait_order_id ( - (const char **) &ksls->order_id), - ANASTASIS_TESTING_make_trait_code ( - (const char **) &ksls->code), + TALER_TESTING_make_trait_payto_uri (ksls->pay_uri), + TALER_TESTING_make_trait_order_id (ksls->order_id), + ANASTASIS_TESTING_make_trait_code (ksls->code), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_truth_solve.c b/src/testing/testing_api_cmd_truth_solve.c index 5c12b3f..29157ed 100644 --- a/src/testing/testing_api_cmd_truth_solve.c +++ b/src/testing/testing_api_cmd_truth_solve.c @@ -127,13 +127,9 @@ truth_solve_cb (void *cls, ksls->tso = NULL; if (tsr->http_status != ksls->expected_http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - tsr->http_status, - ksls->is->commands[ksls->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (ksls->is); + TALER_TESTING_unexpected_status (ksls->is, + tsr->http_status, + ksls->expected_http_status); return; } switch (tsr->http_status) @@ -163,7 +159,7 @@ truth_solve_run (void *cls, const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key; const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid; const struct ANASTASIS_PaymentSecretP *payment_secret; - const char **answerp; + const char *answer; ksls->is = is; if (NULL == ksls->upload_reference) @@ -185,7 +181,7 @@ truth_solve_run (void *cls, return; } { - const char **fn; + const char *fn; if (GNUNET_OK != ANASTASIS_TESTING_get_trait_filename (upload_cmd, @@ -195,8 +191,8 @@ truth_solve_run (void *cls, TALER_TESTING_interpreter_fail (ksls->is); return; } - if (NULL != *fn) - ksls->filename = GNUNET_strdup (*fn); + if (NULL != fn) + ksls->filename = GNUNET_strdup (fn); } if (GNUNET_OK != ANASTASIS_TESTING_get_trait_truth_uuid (upload_cmd, @@ -242,13 +238,13 @@ truth_solve_run (void *cls, } if (GNUNET_OK != ANASTASIS_TESTING_get_trait_code (download_cmd, - &answerp)) + &answer)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (ksls->is); return; } - if (NULL == *answerp) + if (NULL == answer) { GNUNET_break (0); TALER_TESTING_interpreter_fail (ksls->is); @@ -258,9 +254,9 @@ truth_solve_run (void *cls, else { /* answer is the answer */ - answerp = &ksls->answer; + answer = ksls->answer; } - if (NULL == answerp) + if (NULL == answer) { GNUNET_break (0); TALER_TESTING_interpreter_fail (ksls->is); @@ -291,18 +287,19 @@ truth_solve_run (void *cls, { struct GNUNET_HashCode h_answer; - GNUNET_CRYPTO_hash (*answerp, - strlen (*answerp), + GNUNET_CRYPTO_hash (answer, + strlen (answer), &h_answer); - ksls->tso = ANASTASIS_truth_solve (is->ctx, - ksls->anastasis_url, - truth_uuid, - truth_key, - payment_secret, - GNUNET_TIME_UNIT_ZERO, - &h_answer, - &truth_solve_cb, - ksls); + ksls->tso = ANASTASIS_truth_solve ( + TALER_TESTING_interpreter_get_context (is), + ksls->anastasis_url, + truth_uuid, + truth_key, + payment_secret, + GNUNET_TIME_UNIT_ZERO, + &h_answer, + &truth_solve_cb, + ksls); } if (NULL == ksls->tso) { @@ -356,12 +353,9 @@ truth_solve_traits (void *cls, struct TALER_TESTING_Trait traits[] = { ANASTASIS_TESTING_make_trait_payment_secret ( &ksls->payment_secret_response), - TALER_TESTING_make_trait_payto_uri ( - (const char **) ksls->pay_uri), - TALER_TESTING_make_trait_order_id ( - (const char **) &ksls->order_id), - ANASTASIS_TESTING_make_trait_code ( - (const char **) &ksls->code), + TALER_TESTING_make_trait_payto_uri (ksls->pay_uri), + TALER_TESTING_make_trait_order_id (ksls->order_id), + ANASTASIS_TESTING_make_trait_code (ksls->code), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_truth_store.c b/src/testing/testing_api_cmd_truth_store.c index 0972210..f7a6ece 100644 --- a/src/testing/testing_api_cmd_truth_store.c +++ b/src/testing/testing_api_cmd_truth_store.c @@ -125,16 +125,11 @@ truth_store_cb (void *cls, struct TruthStoreState *tss = cls; tss->tso = NULL; - if ( (NULL == ud) || - (ud->http_status != tss->http_status) ) + if (ud->http_status != tss->http_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - (NULL != ud) ? ud->http_status : 0, - tss->is->commands[tss->is->ip].label, - __FILE__, - __LINE__); - TALER_TESTING_interpreter_fail (tss->is); + TALER_TESTING_unexpected_status (tss->is, + ud->http_status, + tss->http_status); return; } switch (ud->us) @@ -273,7 +268,7 @@ truth_store_run (void *cls, GNUNET_free (t); } tss->tso = ANASTASIS_truth_store ( - is->ctx, + TALER_TESTING_interpreter_get_context (is), tss->anastasis_url, &tss->uuid, tss->method, @@ -345,10 +340,8 @@ truth_store_traits (void *cls, ANASTASIS_TESTING_make_trait_truth_key (&tss->key), ANASTASIS_TESTING_make_trait_eks (&tss->encrypted_keyshare), ANASTASIS_TESTING_make_trait_payment_secret (&tss->payment_secret_response), - TALER_TESTING_make_trait_payto_uri ( - (const char **) &tss->pay_uri), - ANASTASIS_TESTING_make_trait_filename ( - (const char **) &tss->filename), + TALER_TESTING_make_trait_payto_uri (tss->pay_uri), + ANASTASIS_TESTING_make_trait_filename (tss->filename), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_cmd_challenge_answer.c b/src/testing/testing_cmd_challenge_answer.c index 8e5e2d8..ad24861 100644 --- a/src/testing/testing_cmd_challenge_answer.c +++ b/src/testing/testing_cmd_challenge_answer.c @@ -249,7 +249,7 @@ challenge_answer_run (void *cls, if (1 == cs->mode) { const struct TALER_TESTING_Command *ref; - const char **answer; + const char *answer; unsigned long long code; char dummy; @@ -270,7 +270,7 @@ challenge_answer_run (void *cls, return; } if (1 != - sscanf (*answer, + sscanf (answer, "%llu%c", &code, &dummy)) @@ -544,14 +544,11 @@ challenge_create_traits (void *cls, { struct ChallengeState *cs = cls; struct TALER_TESTING_Trait traits[] = { - ANASTASIS_TESTING_make_trait_code ( - (const char **) &cs->code), + ANASTASIS_TESTING_make_trait_code (cs->code), ANASTASIS_TESTING_make_trait_payment_secret ( &cs->payment_order_req), - TALER_TESTING_make_trait_payto_uri ( - (const char **) cs->payment_uri), - TALER_TESTING_make_trait_order_id ( - (const char **) &cs->order_id), + TALER_TESTING_make_trait_payto_uri (cs->payment_uri), + TALER_TESTING_make_trait_order_id (cs->order_id), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_cmd_recover_secret.c b/src/testing/testing_cmd_recover_secret.c index 3b12012..1f3e832 100644 --- a/src/testing/testing_cmd_recover_secret.c +++ b/src/testing/testing_cmd_recover_secret.c @@ -74,7 +74,7 @@ struct RecoverSecretState /** * Coresecret to check if decryption worked */ - const void **core_secret; + const void *core_secret; /** * Task scheduled to wait for recovery to complete. @@ -108,13 +108,19 @@ policy_lookup_cb (void *cls, { struct RecoverSecretState *rss = cls; - rss->ri = (struct ANASTASIS_RecoveryInformation *) ri; if (NULL == ri) { GNUNET_break (0); TALER_TESTING_interpreter_fail (rss->is); return; } + if (0 == ri->cs_len) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (rss->is); + return; + } + rss->ri = (struct ANASTASIS_RecoveryInformation *) ri; TALER_TESTING_interpreter_next (rss->is); } @@ -146,7 +152,7 @@ core_secret_cb (void *cls, return; } if (0 != memcmp (secret, - *rss->core_secret, + rss->core_secret, secret_size)) { GNUNET_break (0); @@ -188,9 +194,9 @@ recover_secret_run (void *cls, if (NULL != rss->download_reference) { - ref = TALER_TESTING_interpreter_lookup_command - (is, - rss->download_reference); + ref = TALER_TESTING_interpreter_lookup_command ( + is, + rss->download_reference); if (NULL == ref) { GNUNET_break (0); @@ -220,22 +226,23 @@ recover_secret_run (void *cls, if (GNUNET_OK != ANASTASIS_TESTING_get_trait_core_secret ( ref, - (const void ***) &rss->core_secret)) + &rss->core_secret)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (rss->is); return; } } - rss->recovery = ANASTASIS_recovery_begin (is->ctx, - rss->id_data, - rss->version, - rss->anastasis_url, - provider_salt, - &policy_lookup_cb, - rss, - &core_secret_cb, - rss); + rss->recovery = ANASTASIS_recovery_begin ( + TALER_TESTING_interpreter_get_context (is), + rss->id_data, + rss->version, + rss->anastasis_url, + provider_salt, + &policy_lookup_cb, + rss, + &core_secret_cb, + rss); if (NULL == rss->recovery) { GNUNET_break (0); @@ -301,7 +308,7 @@ recover_secret_cleanup (void *cls, * @param index index number of the object to extract. * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue recover_secret_traits (void *cls, const void **ret, const char *trait, diff --git a/src/testing/testing_cmd_secret_share.c b/src/testing/testing_cmd_secret_share.c index 26a237d..3c401d2 100644 --- a/src/testing/testing_cmd_secret_share.c +++ b/src/testing/testing_cmd_secret_share.c @@ -135,14 +135,7 @@ secret_share_result_cb (void *cls, sss->sso = NULL; if (sr->ss != sss->want_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u to command %s in %s:%u\n", - sr->ss, - sss->is->commands[sss->is->ip].label, - __FILE__, - __LINE__); TALER_TESTING_interpreter_fail (sss->is); - return; } switch (sr->ss) { @@ -225,7 +218,7 @@ secret_share_run (void *cls, if (NULL != sss->prev_secret_share) { const struct TALER_TESTING_Command *ref; - const char **order_id; + const char *order_id; ref = TALER_TESTING_interpreter_lookup_command (is, sss->prev_secret_share); @@ -243,8 +236,7 @@ secret_share_run (void *cls, TALER_TESTING_interpreter_fail (sss->is); return; } - sss->payment_order_id = (char *) *order_id; - + sss->payment_order_id = GNUNET_strdup (order_id); if (NULL == sss->payment_order_id) { GNUNET_break (0); @@ -296,19 +288,20 @@ secret_share_run (void *cls, pds.provider_salt = *provider_salt; } - sss->sso = ANASTASIS_secret_share (is->ctx, - sss->id_data, - &pds, - 1, - policies, - sss->cmd_label_array_length, - false, - GNUNET_TIME_UNIT_ZERO, - &secret_share_result_cb, - sss, - "test-case", - sss->core_secret, - sss->core_secret_size); + sss->sso = ANASTASIS_secret_share ( + TALER_TESTING_interpreter_get_context (is), + sss->id_data, + &pds, + 1, + policies, + sss->cmd_label_array_length, + false, + GNUNET_TIME_UNIT_ZERO, + &secret_share_result_cb, + sss, + "test-case", + sss->core_secret, + sss->core_secret_size); if (NULL == sss->sso) { GNUNET_break (0); @@ -366,9 +359,8 @@ secret_share_traits (void *cls, struct SecretShareState *sss = cls; struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_claim_token (&sss->token), - ANASTASIS_TESTING_make_trait_core_secret (&sss->core_secret), - TALER_TESTING_make_trait_order_id ( - (const char **) &sss->payment_order_id), + ANASTASIS_TESTING_make_trait_core_secret (sss->core_secret), + TALER_TESTING_make_trait_order_id (sss->payment_order_id), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_cmd_truth_upload.c b/src/testing/testing_cmd_truth_upload.c index 89ba790..2e3523b 100644 --- a/src/testing/testing_cmd_truth_upload.c +++ b/src/testing/testing_cmd_truth_upload.c @@ -208,19 +208,20 @@ truth_upload_run (void *cls, ANASTASIS_CRYPTO_user_identifier_derive (tus->id_data, provider_salt, &user_id); - tus->tuo = ANASTASIS_truth_upload (is->ctx, - &user_id, - tus->anastasis_url, - tus->method, - tus->instructions, - tus->mime_type, - provider_salt, - tus->truth_data, - tus->truth_data_size, - false, /* force payment */ - GNUNET_TIME_UNIT_ZERO, - &truth_upload_cb, - tus); + tus->tuo = ANASTASIS_truth_upload ( + TALER_TESTING_interpreter_get_context (is), + &user_id, + tus->anastasis_url, + tus->method, + tus->instructions, + tus->mime_type, + provider_salt, + tus->truth_data, + tus->truth_data_size, + false, /* force payment */ + GNUNET_TIME_UNIT_ZERO, + &truth_upload_cb, + tus); if (NULL == tus->tuo) { GNUNET_break (0); diff --git a/src/util/anastasis-config.in b/src/util/anastasis-config.in index 0e94921..6657540 100644 --- a/src/util/anastasis-config.in +++ b/src/util/anastasis-config.in @@ -7,6 +7,7 @@ if ! type gnunet-config >/dev/null; then exit 1 fi -GC=`which gnunet-config` -export LD_PRELOAD=${LD_PRELOAD:-}:%libdir%/libanastasisutil.so +GC=$(which gnunet-config) +SO=$(ls %libdir%/libanastasisutil.so.* | sort -n | tail -n1) +export LD_PRELOAD=${LD_PRELOAD:-}:${SO} exec gnunet-config "$@" |