Compare commits
23 Commits
ddedf03a81
...
b87d1112ea
Author | SHA1 | Date | |
---|---|---|---|
b87d1112ea | |||
|
421129a32e | ||
|
75733ee00e | ||
|
e2f44ea7b3 | ||
|
fcd3948f3b | ||
|
d25dc8b0ad | ||
|
720783b66a | ||
|
999dae7c5d | ||
|
d4a65faad4 | ||
|
7bb9547599 | ||
|
22d5b9fc3a | ||
|
32d5b90827 | ||
|
ee2471a8c3 | ||
|
ef6496aba5 | ||
|
c512c8b101 | ||
|
f5ce22ddf6 | ||
|
af77a2a178 | ||
|
a37a8d34d5 | ||
|
17789253e9 | ||
|
d6838ed841 | ||
|
35bf856fcb | ||
|
8be960125f | ||
|
9b20c5047e |
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
\section{Deposit}
|
||||
|
||||
\section{Deposit} \label{sec:deposit}
|
||||
|
||||
% FIXME: split up between deposit to merchant
|
||||
% and deposit to customer's (own) bank account!
|
||||
|
||||
\begin{figure}[h!]
|
||||
\begin{sequencediagram}
|
||||
|
@ -49,9 +49,10 @@ if required.
|
||||
|
||||
|
||||
\begin{table}[h!]
|
||||
\caption{Settings for the balance trigger}
|
||||
\caption{Settings for the balance trigger.}
|
||||
\begin{tabular}{l|l|r}
|
||||
{\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline
|
||||
Default AML threshold & Amount & {\em 1000 CHF} \\
|
||||
KYC threshold & Amount & {\em 5000 CHF} \\
|
||||
Default AML threshold & Amount & {\em 5000 CHF} \\
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
@ -61,11 +61,13 @@
|
||||
|
||||
|
||||
\begin{table}[h!]
|
||||
\caption{Settings for the deposit trigger}
|
||||
\caption{Settings for the deposit trigger. Note that the operation
|
||||
must satisfy all of the given rules.}
|
||||
\begin{tabular}{l|l|r}
|
||||
{\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline
|
||||
Allowed bank accounts & RFC 8905 RegEx & {\em CH*} \\ \hline
|
||||
KYC deposit threshold & Amount & {\em 1000 CHF} \\
|
||||
Default AML deposit threshold & Amount & {\em 2500 CHF} \\
|
||||
KYC deposit threshold & Amount/month & {\em 5000 CHF} \\
|
||||
KYC deposit threshold & Amount/year & {\em 15000 CHF} \\
|
||||
Default AML deposit threshold & Amount/month & {\em 2500 CHF} \\
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
@ -68,11 +68,13 @@
|
||||
|
||||
|
||||
\begin{table}[h!]
|
||||
\caption{Settings for the pull payment trigger}
|
||||
\caption{Settings for the pull payment trigger. Note that the operation
|
||||
must satisfy all of the given rules.}
|
||||
\begin{tabular}{l|l|r}
|
||||
{\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline
|
||||
Permitted phone numbers & Dialing prefix & {\em +41} \\
|
||||
P2P KYC threshold & Amount & {\em 100 CHF} \\
|
||||
Default P2P AML threshold & Amount & {\em 1000 CHF} \\
|
||||
P2P KYC threshold & Amount/month & {\em 5000 CHF} \\
|
||||
P2P KYC threshold & Amount/year & {\em 15000 CHF} \\
|
||||
Default P2P AML threshold & Amount/month & {\em 1000 CHF} \\
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
@ -69,11 +69,13 @@
|
||||
|
||||
|
||||
\begin{table}[h!]
|
||||
\caption{Settings for the push payment trigger}
|
||||
\caption{Settings for the push payment trigger. Note that the operation
|
||||
must satisfy all of the given rules.}
|
||||
\begin{tabular}{l|l|r}
|
||||
{\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline
|
||||
Permitted phone numbers & Dialing prefix & {\em +41} \\
|
||||
P2P KYC threshold & Amount & {\em 100 CHF} \\
|
||||
P2P KYC threshold & Amount/month & {\em 5000 CHF} \\
|
||||
P2P KYC threshold & Amount/year & {\em 15000 CHF} \\
|
||||
Default P2P AML threshold & Amount & {\em 1000 CHF} \\
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
@ -30,16 +30,21 @@
|
||||
\end{center}
|
||||
\caption{Regulatory process when withdrawing digital cash from a
|
||||
bank account.
|
||||
When the transfer is denied the money is (eventually) returned to
|
||||
If the transfer is denied or the user fails to withdraw the
|
||||
funds for any other reason, the money is automatically returned
|
||||
after the bounce period (see Table~\ref{table:kyc:withdraw:settings}) to
|
||||
the originating bank account.}
|
||||
\label{fig:kyc:withdraw}
|
||||
\end{figure}
|
||||
|
||||
\begin{table}[h!]
|
||||
\caption{Settings for the withdraw trigger}
|
||||
\caption{Settings for the withdraw trigger. Note that the operation
|
||||
must satisfy all of the given rules.} \label{table:kyc:withdraw:settings}
|
||||
\begin{tabular}{l|l|r}
|
||||
{\bf Setting} & {\bf Type} & {\bf Value} \\ \hline \hline
|
||||
Allowed bank accounts & RFC 8905 RegEx & {\em CH*} \\ \hline
|
||||
Monthly withdraw maximum & Amount & {\em 1000 CHF} \\
|
||||
Withdraw maximum & Amount/month & {\em 5000 CHF} \\
|
||||
Withdraw maximum & Amount/year & {\em 15000 CHF} \\
|
||||
Bounce period & Delay & 1 month \\
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
@ -37,16 +37,48 @@ The main interactions of the system are:
|
||||
\item[shutdown] the Taler payment system operator informs the customers that the system is being shut down for good
|
||||
\end{description}
|
||||
|
||||
Taler has no accounts (this is digital cash) and thus there is no ``opening''
|
||||
or ``closing'' of accounts. The equivalent of ``opening'' an account is thus
|
||||
to withdraw digital cash. The equivalent of ``closing'' an account is to
|
||||
either (1) deposit the funds explicitly into a bank account, or (2) the coins
|
||||
will expire if the wallet was lost (including long-term offline or
|
||||
{\bf Customers} begin their business relationship with us when they withdraw
|
||||
digital cash. Taler has no accounts (this is digital cash) and thus there is
|
||||
no ``opening'' or ``closing'' of accounts for consumers. Given digital cash,
|
||||
the customers can either (1) deposit the funds explicitly into a bank account
|
||||
(see Section~\ref{sec:deposit}), (2) pay a merchant (see
|
||||
Section~\ref{sec:deposit}), (3) pay another customer using a peer-to-peer
|
||||
transfer (see Sections~\ref{sec:push} and~\ref{sec:pull}), or (4) the coins
|
||||
will expire if the wallet was lost (including offline for a long time or
|
||||
uninstalled). Finally, if a wallet remains (occasionally) online but a user
|
||||
does simply not spend the coins will (3) diminish in value from the change
|
||||
does simply not spend the coins will (5) diminish in value from the change
|
||||
fees (see Section~\ref{sec:fees:coin}) that apply to prevent the coins from
|
||||
expiring outright.
|
||||
|
||||
For customers, we will categorically limit of digital cash withdrawn per month
|
||||
to less than CHF 5000 per month and less than CHF 15000 per year, thus
|
||||
ensuring that consumers remain below the thresholds where most regulatory
|
||||
processes become applicable. We will, however, ensure that customers are Swiss
|
||||
(see Section~\ref{sec:proc:domestic}) by requiring them to have a Swiss bank
|
||||
account and/or Swiss phone number (+41-prefix). Furthermore, the wallet will
|
||||
impose an upper limit of CHF 5000 on its balance at any point in time.
|
||||
|
||||
For {\bf merchants}, the Taler equivalent of ``opening'' an account and thus
|
||||
establishing an ongoing business relationship is for a business to receive
|
||||
payments (see Section~\ref{sec:deposit}) exceeding CHF 5000/month or CHF
|
||||
15000/year. We will consider the account ``open'' (and require up-to-date KYB
|
||||
information and check sanction lists) as long as the business has made any
|
||||
transactions within the last 24 months.
|
||||
|
||||
In contrast to normal customers, merchants can in principle {\bf receive}
|
||||
payments without limit. However, these transactions must go into the bank
|
||||
account of the business: when digital coins are deposited at a business in
|
||||
Taler, the business never actually receives usable digital coins but instead
|
||||
the amount is always directly credited to their bank account. Depending on
|
||||
the transacted amounts, the business will be subject to KYB
|
||||
(Section~\ref{sec:proc:kyb}) and AML checks. As we will only transfer money
|
||||
into the existing bank accounts of the merchants to compensate them for sales
|
||||
made using the Taler payment system, we do not need to check the origin of
|
||||
funds for those merchants as they will only receive funds from
|
||||
us.\footnote{Should businesses want to use Taler for expenditures, they will
|
||||
need to withdraw digital coins from their bank account just like customers,
|
||||
and the limits for customers will continue to apply.}
|
||||
|
||||
The following sections describe the respective processes for each of these
|
||||
interactions.
|
||||
|
||||
@ -119,7 +151,8 @@ The three main regulatory processes are:
|
||||
\end{description}
|
||||
|
||||
\include{proc-domestic}
|
||||
\include{proc-kyc}
|
||||
%\include{proc-kyc}
|
||||
\include{proc-kyb}
|
||||
\include{proc-aml}
|
||||
|
||||
\chapter{Fees} \label{chap:fees}
|
||||
|
@ -1,4 +1,4 @@
|
||||
\section{Domestic wallet check}
|
||||
\section{Domestic wallet check} \label{sec:proc:domestic}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\begin{sequencediagram}
|
||||
|
@ -157,6 +157,8 @@ handle_config (struct TAH_RequestHandler *rh,
|
||||
if (NULL == ver)
|
||||
{
|
||||
ver = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("name",
|
||||
"taler-auditor"),
|
||||
GNUNET_JSON_pack_string ("version",
|
||||
AUDITOR_PROTOCOL_VERSION),
|
||||
GNUNET_JSON_pack_string ("currency",
|
||||
|
@ -514,7 +514,7 @@ parallel_benchmark (TALER_TESTING_Main main_cb,
|
||||
|
||||
/* We always wait for the exchange, no matter if it's running locally or
|
||||
remotely */
|
||||
if (0 != TALER_TESTING_wait_exchange_ready (ec.exchange_url))
|
||||
if (0 != TALER_TESTING_wait_httpd_ready (ec.exchange_url))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to detect running exchange at `%s'\n",
|
||||
|
@ -147,6 +147,10 @@ kyc_aml_finished (void *cls,
|
||||
ea,
|
||||
0 != code);
|
||||
GNUNET_free (ea);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Stored encrypted KYC process #%llu attributes: %d\n",
|
||||
(unsigned long long) kat->process_row,
|
||||
qs);
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
|
@ -601,11 +601,12 @@ TEH_handler_kyc_check (
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Suspending HTTP request on timeout (%s) now...\n",
|
||||
GNUNET_TIME_relative2s (GNUNET_TIME_absolute_get_duration (
|
||||
GNUNET_TIME_relative2s (GNUNET_TIME_absolute_get_remaining (
|
||||
kyp->timeout),
|
||||
true));
|
||||
GNUNET_assert (NULL != kyp->eh);
|
||||
kyp->suspended = true;
|
||||
kyp->section_name = NULL;
|
||||
GNUNET_CONTAINER_DLL_insert (kyp_head,
|
||||
kyp_tail,
|
||||
kyp);
|
||||
|
@ -221,6 +221,9 @@ proof_cb (
|
||||
&old_scope);
|
||||
if (TALER_KYCLOGIC_STATUS_SUCCESS == status)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"KYC process #%llu succeeded with KYC provider\n",
|
||||
(unsigned long long) kpc->process_row);
|
||||
kpc->kat = TEH_kyc_finished (&rc->async_scope_id,
|
||||
kpc->process_row,
|
||||
&kpc->h_payto,
|
||||
|
@ -65,7 +65,9 @@ BEGIN
|
||||
,expiration_date=GREATEST(expiration_date,in_expiration_date)
|
||||
,gc_date=GREATEST(gc_date,in_expiration_date)
|
||||
WHERE reserve_pub=in_reserve_pub;
|
||||
PERFORM pg_notify(in_notify, NULL);
|
||||
EXECUTE FORMAT (
|
||||
'NOTIFY %s'
|
||||
,in_notify);
|
||||
ELSE
|
||||
out_duplicate = TRUE;
|
||||
END IF;
|
||||
|
@ -75,8 +75,10 @@ THEN
|
||||
UPDATE SET status=EXCLUDED.status | 1;
|
||||
END IF;
|
||||
|
||||
-- Wake up everyone who might care...
|
||||
PERFORM pg_notify (in_kyc_completed_notify_s, NULL);
|
||||
EXECUTE FORMAT (
|
||||
'NOTIFY %s'
|
||||
,in_kyc_completed_notify_s);
|
||||
|
||||
|
||||
INSERT INTO kyc_alerts
|
||||
(h_payto
|
||||
|
@ -89,6 +89,7 @@ TEH_PG_insert_aml_decision (
|
||||
params,
|
||||
rs);
|
||||
GNUNET_free (notify_s);
|
||||
GNUNET_PQ_event_do_poll (pg->conn);
|
||||
if (NULL != kyc_s)
|
||||
free (kyc_s);
|
||||
return qs;
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "pg_insert_kyc_attributes.h"
|
||||
#include "pg_helper.h"
|
||||
|
||||
void
|
||||
event_do_poll (struct GNUNET_PQ_Context *db);
|
||||
|
||||
|
||||
enum GNUNET_DB_QueryStatus
|
||||
TEH_PG_insert_kyc_attributes (
|
||||
@ -81,6 +84,9 @@ TEH_PG_insert_kyc_attributes (
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Inserting KYC attributes, wake up on %s\n",
|
||||
kyc_completed_notify_s);
|
||||
PREPARE (pg,
|
||||
"insert_kyc_attributes",
|
||||
"SELECT "
|
||||
@ -92,6 +98,8 @@ TEH_PG_insert_kyc_attributes (
|
||||
params,
|
||||
rs);
|
||||
GNUNET_free (kyc_completed_notify_s);
|
||||
GNUNET_PQ_event_do_poll (pg->conn);
|
||||
|
||||
if (qs < 0)
|
||||
return qs;
|
||||
if (! ok)
|
||||
|
@ -611,6 +611,7 @@ TEH_PG_reserves_in_insert (
|
||||
reserves_length,
|
||||
batch_size,
|
||||
results);
|
||||
GNUNET_PQ_event_do_poll (pg->conn);
|
||||
for (unsigned int i = 0; i<reserves_length; i++)
|
||||
GNUNET_free (rrs[i].notify_s);
|
||||
return qs;
|
||||
@ -889,6 +890,7 @@ TEH_PG_reserves_in_insertN (
|
||||
}
|
||||
}
|
||||
finished:
|
||||
GNUNET_PQ_event_do_poll (pg->conn);
|
||||
for (unsigned int i = 0; i<reserves_length; i++)
|
||||
GNUNET_free (rrs[i].notify_s);
|
||||
return qs;
|
||||
|
@ -2,9 +2,9 @@
|
||||
# This file is in the public domain.
|
||||
set -eu
|
||||
echo "Initializing DB"
|
||||
taler-exchange-dbinit -r test-exchange-db-postgres.conf
|
||||
taler-exchange-dbinit -r -c test-exchange-db-postgres.conf
|
||||
echo "Re-initializing DB"
|
||||
taler-exchange-dbinit test-exchange-db-postgres.conf
|
||||
taler-exchange-dbinit -c test-exchange-db-postgres.conf
|
||||
echo "Re-loading procedures"
|
||||
psql talercheck < procedures.sql
|
||||
echo "Test PASSED"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2021 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
@ -28,12 +28,12 @@
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
|
||||
|
||||
/* ********************* /version *********************** */
|
||||
/* ********************* /config *********************** */
|
||||
|
||||
/**
|
||||
* @brief Information we get from the auditor about auditors.
|
||||
* @brief Information we get from the auditor about itself.
|
||||
*/
|
||||
struct TALER_AUDITOR_VersionInformation
|
||||
struct TALER_AUDITOR_ConfigInformation
|
||||
{
|
||||
/**
|
||||
* Public key of the auditing institution. Wallets and merchants
|
||||
@ -146,58 +146,91 @@ struct TALER_AUDITOR_HttpResponse
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to /config request.
|
||||
*/
|
||||
struct TALER_AUDITOR_ConfigResponse
|
||||
{
|
||||
/**
|
||||
* HTTP response.
|
||||
*/
|
||||
struct TALER_AUDITOR_HttpResponse hr;
|
||||
|
||||
/**
|
||||
* Details depending on HTTP status.
|
||||
*/
|
||||
union
|
||||
{
|
||||
|
||||
/**
|
||||
* Details for #MHD_HTTP_OK.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
||||
/**
|
||||
* Protocol compatibility evaluation.
|
||||
*/
|
||||
enum TALER_AUDITOR_VersionCompatibility compat;
|
||||
|
||||
/**
|
||||
* Config data returned by /config.
|
||||
*/
|
||||
struct TALER_AUDITOR_ConfigInformation vi;
|
||||
|
||||
} ok;
|
||||
|
||||
} details;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with information about the auditor.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response data
|
||||
* @param vi basic information about the auditor
|
||||
* @param compat protocol compatibility information
|
||||
* @param vr response data
|
||||
*/
|
||||
// FIXME: bad API!
|
||||
typedef void
|
||||
(*TALER_AUDITOR_VersionCallback) (
|
||||
(*TALER_AUDITOR_ConfigCallback) (
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
const struct TALER_AUDITOR_VersionInformation *vi,
|
||||
enum TALER_AUDITOR_VersionCompatibility compat);
|
||||
const struct TALER_AUDITOR_ConfigResponse *vr);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle to the auditor. This is where we interact with
|
||||
* a particular auditor and keep the per-auditor information.
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle;
|
||||
struct TALER_AUDITOR_GetConfigHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a connection to the auditor. Will connect to the
|
||||
* Obtain meta data about an auditor. Will connect to the
|
||||
* auditor and obtain information about the auditor's master public
|
||||
* key and the auditor's auditor. The respective information will
|
||||
* be passed to the @a version_cb once available, and all future
|
||||
* interactions with the auditor will be checked to be signed
|
||||
* (where appropriate) by the respective master key.
|
||||
* be passed to the @a config_cb once available.
|
||||
*
|
||||
* @param ctx the context
|
||||
* @param ctx the context for CURL requests
|
||||
* @param url HTTP base URL for the auditor
|
||||
* @param version_cb function to call with the auditor's version information
|
||||
* @param version_cb_cls closure for @a version_cb
|
||||
* @param config_cb function to call with the auditor's config information
|
||||
* @param config_cb_cls closure for @a config_cb
|
||||
* @return the auditor handle; NULL upon error
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle *
|
||||
TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
|
||||
struct TALER_AUDITOR_GetConfigHandle *
|
||||
TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_AUDITOR_VersionCallback version_cb,
|
||||
void *version_cb_cls);
|
||||
TALER_AUDITOR_ConfigCallback config_cb,
|
||||
void *config_cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect from the auditor.
|
||||
* Cancel auditor config request.
|
||||
*
|
||||
* @param auditor the auditor handle
|
||||
*/
|
||||
void
|
||||
TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor);
|
||||
TALER_AUDITOR_get_config_cancel (struct
|
||||
TALER_AUDITOR_GetConfigHandle *auditor);
|
||||
|
||||
|
||||
/**
|
||||
@ -206,17 +239,29 @@ TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor);
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Response to /deposit-confirmation request.
|
||||
*/
|
||||
struct TALER_AUDITOR_DepositConfirmationResponse
|
||||
{
|
||||
/**
|
||||
* HTTP response.
|
||||
*/
|
||||
struct TALER_AUDITOR_HttpResponse hr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Signature of functions called with the result from our call to the
|
||||
* auditor's /deposit-confirmation handler.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response data
|
||||
* @param dcr response data
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_AUDITOR_DepositConfirmationResultCallback)(
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr);
|
||||
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr);
|
||||
|
||||
|
||||
/**
|
||||
@ -226,13 +271,13 @@ typedef void
|
||||
* that the response is well-formed. If the auditor's reply is not
|
||||
* well-formed, we return an HTTP status code of zero to @a cb.
|
||||
*
|
||||
* We also verify that the @a exchange_sig is valid for this deposit-confirmation
|
||||
* request, and that the @a master_sig is a valid signature for @a
|
||||
* exchange_pub. Also, the @a auditor must be ready to operate (i.e. have
|
||||
* finished processing the /version reply). If either check fails, we do
|
||||
* NOT initiate the transaction with the auditor and instead return NULL.
|
||||
* We also verify that the @a exchange_sig is valid for this
|
||||
* deposit-confirmation request, and that the @a master_sig is a valid
|
||||
* signature for @a exchange_pub. If the check fails, we do NOT initiate the
|
||||
* transaction with the auditor and instead return NULL.
|
||||
*
|
||||
* @param auditor the auditor handle; the auditor must be ready to operate
|
||||
* @param ctx the context for CURL requests
|
||||
* @param url HTTP base URL for the auditor
|
||||
* @param h_wire hash of merchant wire details
|
||||
* @param h_policy hash over the policy, if any
|
||||
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
|
||||
@ -256,7 +301,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *
|
||||
TALER_AUDITOR_deposit_confirmation (
|
||||
struct TALER_AUDITOR_Handle *auditor,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_MerchantWireHashP *h_wire,
|
||||
const struct TALER_ExtensionPolicyHashP *h_policy,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
@ -313,34 +359,70 @@ struct TALER_AUDITOR_ExchangeInfo
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to GET /exchanges request.
|
||||
*/
|
||||
struct TALER_AUDITOR_ListExchangesResponse
|
||||
{
|
||||
/**
|
||||
* HTTP response.
|
||||
*/
|
||||
struct TALER_AUDITOR_HttpResponse hr;
|
||||
|
||||
/**
|
||||
* Details depending on HTTP status.
|
||||
*/
|
||||
union
|
||||
{
|
||||
|
||||
/**
|
||||
* Details for #MHD_HTTP_OK.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
||||
/**
|
||||
* Length of the @e ei array.
|
||||
*/
|
||||
unsigned int num_exchanges;
|
||||
|
||||
/**
|
||||
* Array with information about exchanges
|
||||
* audited by this auditor.
|
||||
*/
|
||||
const struct TALER_AUDITOR_ExchangeInfo *ei;
|
||||
} ok;
|
||||
} details;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with the result from /exchanges.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response data
|
||||
* @param num_exchanges length of array at @a ei
|
||||
* @param ei information about exchanges returned by the auditor
|
||||
* @param ler response data
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_AUDITOR_ListExchangesResultCallback)(
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
unsigned int num_exchanges,
|
||||
const struct TALER_AUDITOR_ExchangeInfo *ei);
|
||||
const struct TALER_AUDITOR_ListExchangesResponse *ler);
|
||||
|
||||
|
||||
/**
|
||||
* Submit an /exchanges request to the auditor and get the
|
||||
* auditor's response. If the auditor's reply is not
|
||||
* well-formed, we return an HTTP status code of zero to @a cb.
|
||||
*
|
||||
* @param auditor the auditor handle; the auditor must be ready to operate
|
||||
* @param ctx the context for CURL requests
|
||||
* @param url HTTP base URL for the auditor
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
* @param cb_cls closure for the above callback
|
||||
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
||||
* signatures fail to verify). In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_AUDITOR_ListExchangesHandle *
|
||||
TALER_AUDITOR_list_exchanges (struct TALER_AUDITOR_Handle *auditor,
|
||||
TALER_AUDITOR_list_exchanges (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_AUDITOR_ListExchangesResultCallback cb,
|
||||
void *cb_cls);
|
||||
|
||||
|
@ -573,10 +573,30 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange);
|
||||
* @param exchange the exchange handle
|
||||
* @return the exchange's key set
|
||||
*/
|
||||
const struct TALER_EXCHANGE_Keys *
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange);
|
||||
|
||||
|
||||
/**
|
||||
* Increment reference counter for @a keys
|
||||
*
|
||||
* @param[in,out] keys object to increment reference counter for
|
||||
* @return keys, with incremented reference counter
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_EXCHANGE_keys_incref (struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* Deccrement reference counter for @a keys.
|
||||
* Frees @a keys if reference counter becomes zero.
|
||||
*
|
||||
* @param[in,out] keys object to decrement reference counter for
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* Let the user set the last valid denomination time manually.
|
||||
*
|
||||
@ -584,7 +604,8 @@ TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange);
|
||||
* @param last_denom_new new last denomination time.
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_set_last_denom (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_set_last_denom (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_TIME_Timestamp last_denom_new);
|
||||
|
||||
|
||||
@ -633,7 +654,8 @@ enum TALER_EXCHANGE_CheckKeysFlags
|
||||
* @return until when the existing response is current, 0 if we are re-downloading now
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp
|
||||
TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_check_keys_current (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
enum TALER_EXCHANGE_CheckKeysFlags flags,
|
||||
TALER_EXCHANGE_CertificationCallback cb,
|
||||
void *cb_cls);
|
||||
@ -649,6 +671,16 @@ json_t *
|
||||
TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the exchange in the raw JSON format.
|
||||
*
|
||||
* @param keys the keys structure
|
||||
* @return the keys in raw JSON
|
||||
*/
|
||||
json_t *
|
||||
TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* Test if the given @a pub is a the current signing key from the exchange
|
||||
* according to @a keys.
|
||||
@ -1035,7 +1067,8 @@ struct TALER_EXCHANGE_WireHandle;
|
||||
* @return a handle for this request
|
||||
*/
|
||||
struct TALER_EXCHANGE_WireHandle *
|
||||
TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_wire (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_WireCallback wire_cb,
|
||||
void *wire_cb_cls);
|
||||
|
||||
@ -1151,135 +1184,6 @@ struct TALER_EXCHANGE_DepositContractDetail
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief A Deposit Handle
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Structure with information about a deposit
|
||||
* operation's result.
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositResult
|
||||
{
|
||||
/**
|
||||
* HTTP response data
|
||||
*/
|
||||
struct TALER_EXCHANGE_HttpResponse hr;
|
||||
|
||||
union
|
||||
{
|
||||
|
||||
/**
|
||||
* Information returned if the HTTP status is
|
||||
* #MHD_HTTP_OK.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* Time when the exchange generated the deposit confirmation
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp deposit_timestamp;
|
||||
|
||||
/**
|
||||
* signature provided by the exchange
|
||||
*/
|
||||
const struct TALER_ExchangeSignatureP *exchange_sig;
|
||||
|
||||
/**
|
||||
* exchange key used to sign @a exchange_sig.
|
||||
*/
|
||||
const struct TALER_ExchangePublicKeyP *exchange_pub;
|
||||
|
||||
/**
|
||||
* Base URL for looking up wire transfers, or
|
||||
* NULL to use the default base URL.
|
||||
*/
|
||||
const char *transaction_base_url;
|
||||
|
||||
} ok;
|
||||
|
||||
/**
|
||||
* Information returned if the HTTP status is
|
||||
* #MHD_HTTP_CONFLICT.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/* TODO: returning full details is not implemented */
|
||||
} conflict;
|
||||
|
||||
} details;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks of this type are used to serve the result of submitting a
|
||||
* deposit permission request to a exchange.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param dr deposit response details
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_EXCHANGE_DepositResultCallback) (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_DepositResult *dr);
|
||||
|
||||
|
||||
/**
|
||||
* Submit a deposit permission to the exchange and get the exchange's
|
||||
* response. This API is typically used by a merchant. Note that
|
||||
* while we return the response verbatim to the caller for further
|
||||
* processing, we do already verify that the response is well-formed
|
||||
* (i.e. that signatures included in the response are all valid). If
|
||||
* the exchange's reply is not well-formed, we return an HTTP status code
|
||||
* of zero to @a cb.
|
||||
*
|
||||
* We also verify that the @a cdd.coin_sig is valid for this deposit
|
||||
* request, and that the @a cdd.ub_sig is a valid signature for @a
|
||||
* coin_pub. Also, the @a exchange must be ready to operate (i.e. have
|
||||
* finished processing the /keys reply). If either check fails, we do
|
||||
* NOT initiate the transaction with the exchange and instead return NULL.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param dcd details about the contract the deposit is for
|
||||
* @param cdd details about the coin to be deposited
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
* @param cb_cls closure for the above callback
|
||||
* @param[out] ec if NULL is returned, set to the error code explaining why the operation failed
|
||||
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
||||
* signatures fail to verify). In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositHandle *
|
||||
TALER_EXCHANGE_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||
const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
|
||||
TALER_EXCHANGE_DepositResultCallback cb,
|
||||
void *cb_cls,
|
||||
enum TALER_ErrorCode *ec);
|
||||
|
||||
|
||||
/**
|
||||
* Change the chance that our deposit confirmation will be given to the
|
||||
* auditor to 100%.
|
||||
*
|
||||
* @param deposit the deposit permission request handle
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit);
|
||||
|
||||
|
||||
/**
|
||||
* Cancel a deposit permission request. This function cannot be used
|
||||
* on a request handle if a response is already served for it.
|
||||
*
|
||||
* @param deposit the deposit permission request handle
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit);
|
||||
|
||||
|
||||
/**
|
||||
* @brief A Batch Deposit Handle
|
||||
*/
|
||||
@ -1374,7 +1278,9 @@ typedef void
|
||||
* finished processing the /keys reply). If either check fails, we do
|
||||
* NOT initiate the transaction with the exchange and instead return NULL.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param dcd details about the contract the deposit is for
|
||||
* @param num_cdds length of the @a cdds array
|
||||
* @param cdds array with details about the coins to be deposited
|
||||
@ -1386,7 +1292,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *
|
||||
TALER_EXCHANGE_batch_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||
unsigned int num_cdds,
|
||||
const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
|
||||
@ -1482,7 +1390,9 @@ typedef void
|
||||
* finished processing the /keys reply). If this check fails, we do
|
||||
* NOT initiate the transaction with the exchange and instead return NULL.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param amount the amount to be refunded; must be larger than the refund fee
|
||||
* (as that fee is still being subtracted), and smaller than the amount
|
||||
* (with deposit fee) of the original deposit contribution of this coin
|
||||
@ -1500,7 +1410,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_RefundHandle *
|
||||
TALER_EXCHANGE_refund (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
@ -1609,7 +1521,8 @@ struct TALER_EXCHANGE_NonceKey
|
||||
/**
|
||||
* Get a set of CS R values using a /csr-melt request.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param rms master key used for the derivation of the CS values
|
||||
* @param nks_len length of the @a nks array
|
||||
* @param nks array of denominations and nonces
|
||||
@ -1620,7 +1533,9 @@ struct TALER_EXCHANGE_NonceKey
|
||||
* In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_CsRMeltHandle *
|
||||
TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_csr_melt (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
unsigned int nks_len,
|
||||
struct TALER_EXCHANGE_NonceKey *nks,
|
||||
@ -1713,7 +1628,8 @@ typedef void
|
||||
* In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_CsRWithdrawHandle *
|
||||
TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_csr_withdraw (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||
const struct TALER_CsNonce *nonce,
|
||||
TALER_EXCHANGE_CsRWithdrawCallback res_cb,
|
||||
@ -2127,7 +2043,8 @@ typedef void
|
||||
* reply is not well-formed, we return an HTTP status code of zero to
|
||||
* @a cb.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param reserve_pub public key of the reserve to inspect
|
||||
* @param timeout how long to wait for an affirmative reply
|
||||
* (enables long polling if the reserve does not yet exist)
|
||||
@ -2138,7 +2055,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesGetHandle *
|
||||
TALER_EXCHANGE_reserves_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
TALER_EXCHANGE_ReservesGetCallback cb,
|
||||
@ -2235,7 +2153,9 @@ typedef void
|
||||
/**
|
||||
* Submit a request to obtain the reserve status.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param reserve_priv private key of the reserve to inspect
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
* @param cb_cls closure for the above callback
|
||||
@ -2244,7 +2164,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesStatusHandle *
|
||||
TALER_EXCHANGE_reserves_status (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
TALER_EXCHANGE_ReservesStatusCallback cb,
|
||||
void *cb_cls);
|
||||
@ -2353,7 +2275,9 @@ typedef void
|
||||
/**
|
||||
* Submit a request to obtain the reserve history.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param reserve_priv private key of the reserve to inspect
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
* @param cb_cls closure for the above callback
|
||||
@ -2362,7 +2286,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesHistoryHandle *
|
||||
TALER_EXCHANGE_reserves_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
TALER_EXCHANGE_ReservesHistoryCallback cb,
|
||||
void *cb_cls);
|
||||
@ -2752,7 +2678,8 @@ struct TALER_EXCHANGE_Withdraw2Handle;
|
||||
* In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Withdraw2Handle *
|
||||
TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_withdraw2 (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const struct TALER_PlanchetDetail *pd,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
TALER_EXCHANGE_Withdraw2Callback res_cb,
|
||||
@ -3014,7 +2941,9 @@ typedef void
|
||||
* argument @a rd should be committed to persistent storage
|
||||
* prior to calling this function.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param rms the fresh secret that defines the refresh operation
|
||||
* @param rd the refresh data specifying the characteristics of the operation
|
||||
* @param melt_cb the callback to call with the result
|
||||
@ -3023,7 +2952,10 @@ typedef void
|
||||
* In this case, neither callback will be called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_MeltHandle *
|
||||
TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_melt (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||
TALER_EXCHANGE_MeltCallback melt_cb,
|
||||
@ -3147,7 +3079,9 @@ struct TALER_EXCHANGE_RefreshesRevealHandle;
|
||||
* arguments should have been committed to persistent storage
|
||||
* prior to calling this function.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param rms the fresh secret that defines the refresh operation
|
||||
* @param rd the refresh data that characterizes the refresh operation
|
||||
* @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, must match value in @a rd
|
||||
@ -3162,7 +3096,8 @@ struct TALER_EXCHANGE_RefreshesRevealHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_RefreshesRevealHandle *
|
||||
TALER_EXCHANGE_refreshes_reveal (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||
unsigned int num_coins,
|
||||
@ -3284,7 +3219,8 @@ typedef void
|
||||
* This API is typically not used by anyone, it is more a threat against those
|
||||
* trying to receive a funds transfer by abusing the refresh protocol.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param coin_priv private key to request link data for
|
||||
* @param age_commitment_proof age commitment to the corresponding coin, might be NULL
|
||||
* @param link_cb the callback to call with the useful result of the
|
||||
@ -3294,7 +3230,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_LinkHandle *
|
||||
TALER_EXCHANGE_link (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof,
|
||||
TALER_EXCHANGE_LinkCallback link_cb,
|
||||
@ -3412,7 +3349,9 @@ typedef void
|
||||
* Query the exchange about which transactions were combined
|
||||
* to create a wire transfer.
|
||||
*
|
||||
* @param exchange exchange to query
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param wtid raw wire transfer identifier to get information about
|
||||
* @param cb callback to call
|
||||
* @param cb_cls closure for @a cb
|
||||
@ -3420,7 +3359,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_TransfersGetHandle *
|
||||
TALER_EXCHANGE_transfers_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_WireTransferIdentifierRawP *wtid,
|
||||
TALER_EXCHANGE_TransfersGetCallback cb,
|
||||
void *cb_cls);
|
||||
@ -3550,7 +3491,9 @@ typedef void
|
||||
* which aggregate wire transfer the deposit operation identified by @a coin_pub,
|
||||
* @a merchant_priv and @a h_contract_terms contributed to.
|
||||
*
|
||||
* @param exchange the exchange to query
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param merchant_priv the merchant's private key
|
||||
* @param h_wire hash of merchant's wire transfer details
|
||||
* @param h_contract_terms hash of the proposal data
|
||||
@ -3562,7 +3505,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositGetHandle *
|
||||
TALER_EXCHANGE_deposits_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv,
|
||||
const struct TALER_MerchantWireHashP *h_wire,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
@ -3605,7 +3550,7 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
* Parse history given in JSON format and return it in binary
|
||||
* format.
|
||||
*
|
||||
* @param exchange connection to the exchange we can use
|
||||
* @param keys exchange keys
|
||||
* @param history JSON array with the history
|
||||
* @param reserve_pub public key of the reserve to inspect
|
||||
* @param currency currency we expect the balance to be in
|
||||
@ -3620,7 +3565,7 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_EXCHANGE_parse_reserve_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const json_t *history,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
const char *currency,
|
||||
@ -3702,7 +3647,9 @@ typedef void
|
||||
* the emergency recoup protocol for a given denomination. The value
|
||||
* of the coin will be refunded to the original customer (without fees).
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param pk kind of coin to pay back
|
||||
* @param denom_sig signature over the coin by the exchange using @a pk
|
||||
* @param exchange_vals contribution from the exchange on the withdraw
|
||||
@ -3714,7 +3661,10 @@ typedef void
|
||||
* In this case, the callback is not called.
|
||||
*/
|
||||
struct TALER_EXCHANGE_RecoupHandle *
|
||||
TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_recoup (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||
const struct TALER_DenominationSignature *denom_sig,
|
||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||
@ -3793,7 +3743,9 @@ typedef void
|
||||
* revoked coin was refreshed from. The original coin is then
|
||||
* considered a zombie.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param pk kind of coin to pay back
|
||||
* @param denom_sig signature over the coin by the exchange using @a pk
|
||||
* @param exchange_vals contribution from the exchange on the withdraw
|
||||
@ -3808,7 +3760,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_RecoupRefreshHandle *
|
||||
TALER_EXCHANGE_recoup_refresh (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||
const struct TALER_DenominationSignature *denom_sig,
|
||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||
@ -4023,7 +3977,8 @@ struct TALER_EXCHANGE_KycProofHandle;
|
||||
/**
|
||||
* Run interaction with exchange to provide proof of KYC status.
|
||||
*
|
||||
* @param eh exchange handle to use
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param h_payto hash of payto URI identifying the target account
|
||||
* @param logic name of the KYC logic to run
|
||||
* @param args additional args to pass, can be NULL
|
||||
@ -4033,7 +3988,9 @@ struct TALER_EXCHANGE_KycProofHandle;
|
||||
* @return NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_KycProofHandle *
|
||||
TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *eh,
|
||||
TALER_EXCHANGE_kyc_proof (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
const char *logic,
|
||||
const char *args,
|
||||
@ -4116,7 +4073,8 @@ typedef void
|
||||
* Run interaction with exchange to find out the wallet's KYC
|
||||
* identifier.
|
||||
*
|
||||
* @param eh exchange handle to use
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param reserve_priv wallet private key to check
|
||||
* @param balance balance (or balance threshold) crossed by the wallet
|
||||
* @param cb function to call with the result
|
||||
@ -4124,7 +4082,9 @@ typedef void
|
||||
* @return NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_KycWalletHandle *
|
||||
TALER_EXCHANGE_kyc_wallet (struct TALER_EXCHANGE_Handle *eh,
|
||||
TALER_EXCHANGE_kyc_wallet (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_Amount *balance,
|
||||
TALER_EXCHANGE_KycWalletCallback cb,
|
||||
@ -4353,7 +4313,8 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle;
|
||||
* @return the request handle; NULL upon error
|
||||
*/
|
||||
struct TALER_EXCHANGE_ManagementGetKeysHandle *
|
||||
TALER_EXCHANGE_get_management_keys (struct GNUNET_CURL_Context *ctx,
|
||||
TALER_EXCHANGE_get_management_keys (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_EXCHANGE_ManagementGetKeysCallback cb,
|
||||
void *cb_cls);
|
||||
@ -5783,7 +5744,8 @@ struct TALER_EXCHANGE_ContractsGetHandle;
|
||||
/**
|
||||
* Request information about a contract from the exchange.
|
||||
*
|
||||
* @param exchange exchange handle
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param contract_priv private key of the contract
|
||||
* @param cb function to call with the exchange's result
|
||||
* @param cb_cls closure for @a cb
|
||||
@ -5791,7 +5753,8 @@ struct TALER_EXCHANGE_ContractsGetHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_ContractsGetHandle *
|
||||
TALER_EXCHANGE_contract_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||
TALER_EXCHANGE_ContractGetCallback cb,
|
||||
void *cb_cls);
|
||||
@ -5880,7 +5843,9 @@ struct TALER_EXCHANGE_PurseGetHandle;
|
||||
/**
|
||||
* Request information about a purse from the exchange.
|
||||
*
|
||||
* @param exchange exchange handle
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param purse_pub public key of the purse
|
||||
* @param timeout how long to wait for a change to happen
|
||||
* @param wait_for_merge true to wait for a merge event, otherwise wait for a deposit event
|
||||
@ -5890,7 +5855,9 @@ struct TALER_EXCHANGE_PurseGetHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_PurseGetHandle *
|
||||
TALER_EXCHANGE_purse_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
bool wait_for_merge,
|
||||
@ -6004,7 +5971,9 @@ struct TALER_EXCHANGE_PurseDeposit
|
||||
* Inform the exchange that a purse should be created
|
||||
* and coins deposited into it.
|
||||
*
|
||||
* @param exchange the exchange to interact with
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param purse_priv private key of the purse
|
||||
* @param merge_priv the merge credential
|
||||
* @param contract_priv key needed to obtain and decrypt the contract
|
||||
@ -6020,7 +5989,9 @@ struct TALER_EXCHANGE_PurseDeposit
|
||||
*/
|
||||
struct TALER_EXCHANGE_PurseCreateDepositHandle *
|
||||
TALER_EXCHANGE_purse_create_with_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
const struct TALER_PurseMergePrivateKeyP *merge_priv,
|
||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||
@ -6077,7 +6048,8 @@ struct TALER_EXCHANGE_PurseDeleteHandle;
|
||||
* Asks the exchange to delete a purse. Will only succeed if
|
||||
* the purse was not yet merged and did not yet time out.
|
||||
*
|
||||
* @param exchange the exchange to interact with
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param purse_priv private key of the purse
|
||||
* @param cb function to call with the exchange's result
|
||||
* @param cb_cls closure for @a cb
|
||||
@ -6085,7 +6057,8 @@ struct TALER_EXCHANGE_PurseDeleteHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_PurseDeleteHandle *
|
||||
TALER_EXCHANGE_purse_delete (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
TALER_EXCHANGE_PurseDeleteCallback cb,
|
||||
void *cb_cls);
|
||||
@ -6182,7 +6155,9 @@ struct TALER_EXCHANGE_AccountMergeHandle;
|
||||
* Inform the exchange that a purse should be merged
|
||||
* with a reserve.
|
||||
*
|
||||
* @param exchange the exchange hosting the purse
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param reserve_exchange_url base URL of the exchange with the reserve
|
||||
* @param reserve_priv private key of the reserve to merge into
|
||||
* @param purse_pub public key of the purse to merge
|
||||
@ -6198,7 +6173,9 @@ struct TALER_EXCHANGE_AccountMergeHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_AccountMergeHandle *
|
||||
TALER_EXCHANGE_account_merge (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const char *reserve_exchange_url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
@ -6244,7 +6221,7 @@ struct TALER_EXCHANGE_PurseCreateMergeResponse
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Detailed returned on #MHD_HTTP_OK.
|
||||
* Details returned on #MHD_HTTP_OK.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
@ -6290,7 +6267,9 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle;
|
||||
* Inform the exchange that a purse should be created
|
||||
* and merged with a reserve.
|
||||
*
|
||||
* @param exchange the exchange hosting the reserve
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param reserve_priv private key of the reserve
|
||||
* @param purse_priv private key of the purse
|
||||
* @param merge_priv private key of the merge capability
|
||||
@ -6305,7 +6284,9 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_PurseCreateMergeHandle *
|
||||
TALER_EXCHANGE_purse_create_with_merge (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
const struct TALER_PurseMergePrivateKeyP *merge_priv,
|
||||
@ -6397,7 +6378,9 @@ struct TALER_EXCHANGE_PurseDepositHandle;
|
||||
* Inform the exchange that a deposit should be made into
|
||||
* a purse.
|
||||
*
|
||||
* @param exchange the exchange that issued the coins
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param purse_exchange_url base URL of the exchange hosting the purse
|
||||
* @param purse_pub public key of the purse to merge
|
||||
* @param min_age minimum age we need to prove for the purse
|
||||
@ -6409,7 +6392,9 @@ struct TALER_EXCHANGE_PurseDepositHandle;
|
||||
*/
|
||||
struct TALER_EXCHANGE_PurseDepositHandle *
|
||||
TALER_EXCHANGE_purse_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const char *purse_exchange_url,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
uint8_t min_age,
|
||||
@ -6533,7 +6518,9 @@ typedef void
|
||||
/**
|
||||
* Submit a request to open a reserve.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param reserve_priv private key of the reserve to open
|
||||
* @param reserve_contribution amount to pay from the reserve's balance for the operation
|
||||
* @param coin_payments_length length of the @a coin_payments array
|
||||
@ -6547,7 +6534,9 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesOpenHandle *
|
||||
TALER_EXCHANGE_reserves_open (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_Amount *reserve_contribution,
|
||||
unsigned int coin_payments_length,
|
||||
@ -6635,7 +6624,8 @@ typedef void
|
||||
/**
|
||||
* Submit a request to get the list of attestable attributes for a reserve.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param reserve_pub public key of the reserve to get available attributes for
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
* @param cb_cls closure for the above callback
|
||||
@ -6644,7 +6634,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesGetAttestHandle *
|
||||
TALER_EXCHANGE_reserves_get_attestable (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
TALER_EXCHANGE_ReservesGetAttestCallback cb,
|
||||
void *cb_cls);
|
||||
@ -6738,7 +6729,8 @@ typedef void
|
||||
/**
|
||||
* Submit a request to attest attributes about the owner of a reserve.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx CURL context
|
||||
* @param url exchange base URL
|
||||
* @param reserve_priv private key of the reserve to attest
|
||||
* @param attributes_length length of the @a attributes array
|
||||
* @param attributes array of names of attributes to get attestations for
|
||||
@ -6749,7 +6741,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesAttestHandle *
|
||||
TALER_EXCHANGE_reserves_attest (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
unsigned int attributes_length,
|
||||
const char *const*attributes,
|
||||
@ -6847,7 +6840,8 @@ typedef void
|
||||
/**
|
||||
* Submit a request to close a reserve.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param reserve_priv private key of the reserve to close
|
||||
* @param target_payto_uri where to send the payment, NULL to send to reserve origin
|
||||
* @param cb the callback to call when a reply for this request is available
|
||||
@ -6857,7 +6851,8 @@ typedef void
|
||||
*/
|
||||
struct TALER_EXCHANGE_ReservesCloseHandle *
|
||||
TALER_EXCHANGE_reserves_close (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const char *target_payto_uri,
|
||||
TALER_EXCHANGE_ReservesCloseCallback cb,
|
||||
|
@ -514,7 +514,7 @@ typedef void
|
||||
* Iterates over all of the top-level commands of an
|
||||
* interpreter.
|
||||
*
|
||||
* @param[in] interpreter to iterate over
|
||||
* @param[in] is interpreter to iterate over
|
||||
* @param asc true in execution order, false for reverse execution order
|
||||
* @param cb function to call on each command
|
||||
* @param cb_cls closure for cb
|
||||
@ -2692,9 +2692,9 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
||||
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
|
||||
op (claim_token, const struct TALER_ClaimTokenP) \
|
||||
op (relative_time, const struct GNUNET_TIME_Relative) \
|
||||
op (auditor, struct TALER_AUDITOR_Handle) \
|
||||
op (exchange, struct TALER_EXCHANGE_Handle) \
|
||||
op (fakebank, struct TALER_FAKEBANK_Handle) \
|
||||
op (keys, struct TALER_EXCHANGE_Keys) \
|
||||
op (process, struct GNUNET_OS_Process *)
|
||||
|
||||
|
||||
@ -2741,4 +2741,26 @@ struct TALER_EXCHANGE_Handle *
|
||||
TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange URL from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange URL, or NULL on error
|
||||
*/
|
||||
const char *
|
||||
TALER_TESTING_get_exchange_url (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange keys from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange keys, or NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_TESTING_get_keys (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,6 @@ libtalerexchange_la_SOURCES = \
|
||||
exchange_api_csr_melt.c \
|
||||
exchange_api_csr_withdraw.c \
|
||||
exchange_api_handle.c exchange_api_handle.h \
|
||||
exchange_api_deposit.c \
|
||||
exchange_api_deposits_get.c \
|
||||
exchange_api_kyc_check.c \
|
||||
exchange_api_kyc_proof.c \
|
||||
@ -96,7 +95,7 @@ libtalerauditor_la_LDFLAGS = \
|
||||
-no-undefined
|
||||
libtalerauditor_la_SOURCES = \
|
||||
auditor_api_curl_defaults.c auditor_api_curl_defaults.h \
|
||||
auditor_api_handle.c auditor_api_handle.h \
|
||||
auditor_api_get_config.c \
|
||||
auditor_api_deposit_confirmation.c \
|
||||
auditor_api_exchanges.c
|
||||
libtalerauditor_la_LIBADD = \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2021 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -25,9 +25,10 @@
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_json_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_util.h"
|
||||
#include "taler_curl_lib.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_auditor_service.h"
|
||||
#include "auditor_api_handle.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "auditor_api_curl_defaults.h"
|
||||
|
||||
@ -38,11 +39,6 @@
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to auditor this request handle will use
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -87,64 +83,64 @@ handle_deposit_confirmation_finished (void *cls,
|
||||
{
|
||||
const json_t *json = djson;
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *dh = cls;
|
||||
struct TALER_AUDITOR_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_AUDITOR_DepositConfirmationResponse dcr = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
dh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
dcr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
hr.ec = TALER_EC_NONE;
|
||||
dcr.hr.ec = TALER_EC_NONE;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
/* This should never happen, either us or the auditor is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
/* Nothing really to verify, auditor says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
/* Nothing really to verify, auditor says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
dcr.hr.ec = TALER_JSON_get_error_code (json);
|
||||
dcr.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for auditor deposit confirmation\n",
|
||||
(unsigned int) response_code,
|
||||
hr.ec);
|
||||
dcr.hr.ec);
|
||||
break;
|
||||
}
|
||||
dh->cb (dh->cb_cls,
|
||||
&hr);
|
||||
&dcr);
|
||||
TALER_AUDITOR_deposit_confirmation_cancel (dh);
|
||||
}
|
||||
|
||||
@ -237,7 +233,8 @@ verify_signatures (const struct TALER_MerchantWireHashP *h_wire,
|
||||
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *
|
||||
TALER_AUDITOR_deposit_confirmation (
|
||||
struct TALER_AUDITOR_Handle *auditor,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_MerchantWireHashP *h_wire,
|
||||
const struct TALER_ExtensionPolicyHashP *h_policy,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
@ -258,12 +255,9 @@ TALER_AUDITOR_deposit_confirmation (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *dh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *deposit_confirmation_obj;
|
||||
CURL *eh;
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TALER_AUDITOR_handle_is_ready_ (auditor));
|
||||
if (GNUNET_OK !=
|
||||
verify_signatures (h_wire,
|
||||
h_policy,
|
||||
@ -322,18 +316,17 @@ TALER_AUDITOR_deposit_confirmation (
|
||||
GNUNET_JSON_pack_data_auto ("exchange_pub",
|
||||
exchange_pub));
|
||||
dh = GNUNET_new (struct TALER_AUDITOR_DepositConfirmationHandle);
|
||||
dh->auditor = auditor;
|
||||
dh->cb = cb;
|
||||
dh->cb_cls = cb_cls;
|
||||
dh->url = TALER_AUDITOR_path_to_url_ (auditor,
|
||||
"/deposit-confirmation");
|
||||
dh->url = TALER_url_join (url,
|
||||
"deposit-confirmation",
|
||||
NULL);
|
||||
if (NULL == dh->url)
|
||||
{
|
||||
GNUNET_free (dh);
|
||||
return NULL;
|
||||
}
|
||||
eh = TALER_AUDITOR_curl_easy_get_ (dh->url);
|
||||
|
||||
if ( (NULL == eh) ||
|
||||
(CURLE_OK !=
|
||||
curl_easy_setopt (eh,
|
||||
@ -356,7 +349,6 @@ TALER_AUDITOR_deposit_confirmation (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for deposit-confirmation: `%s'\n",
|
||||
dh->url);
|
||||
ctx = TALER_AUDITOR_handle_to_context_ (auditor);
|
||||
dh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
dh->ctx.headers,
|
||||
|
@ -27,7 +27,8 @@
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_auditor_service.h"
|
||||
#include "auditor_api_handle.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_curl_lib.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "auditor_api_curl_defaults.h"
|
||||
|
||||
@ -44,11 +45,6 @@
|
||||
struct TALER_AUDITOR_ListExchangesHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to auditor this request handle will use
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -89,16 +85,16 @@ handle_exchanges_finished (void *cls,
|
||||
const json_t *ja;
|
||||
unsigned int ja_len;
|
||||
struct TALER_AUDITOR_ListExchangesHandle *leh = cls;
|
||||
struct TALER_AUDITOR_HttpResponse hr = {
|
||||
.reply = json,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_AUDITOR_ListExchangesResponse ler = {
|
||||
.hr.reply = json,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
leh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
ler.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
ja = json_object_get (json,
|
||||
@ -107,8 +103,8 @@ handle_exchanges_finished (void *cls,
|
||||
(! json_is_array (ja)) )
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
ler.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -116,20 +112,21 @@ handle_exchanges_finished (void *cls,
|
||||
if (ja_len > MAX_EXCHANGES)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
ler.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
{
|
||||
struct TALER_AUDITOR_ExchangeInfo ei[ja_len];
|
||||
bool ok;
|
||||
struct TALER_AUDITOR_ExchangeInfo ei[GNUNET_NZL (ja_len)];
|
||||
bool ok = true;
|
||||
|
||||
ok = true;
|
||||
for (unsigned int i = 0; i<ja_len; i++)
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("master_pub", &ei[i].master_pub),
|
||||
GNUNET_JSON_spec_string ("exchange_url", &ei[i].exchange_url),
|
||||
GNUNET_JSON_spec_fixed_auto ("master_pub",
|
||||
&ei[i].master_pub),
|
||||
GNUNET_JSON_spec_string ("exchange_url",
|
||||
&ei[i].exchange_url),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -141,76 +138,71 @@ handle_exchanges_finished (void *cls,
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ok = false;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
hr.http_status = 0;
|
||||
ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
ler.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! ok)
|
||||
break;
|
||||
ler.details.ok.ei = ei;
|
||||
ler.details.ok.num_exchanges = ja_len;
|
||||
leh->cb (leh->cb_cls,
|
||||
&hr,
|
||||
ja_len,
|
||||
ei);
|
||||
&ler);
|
||||
TALER_AUDITOR_list_exchanges_cancel (leh);
|
||||
return;
|
||||
}
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the auditor is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
ler.hr.ec = TALER_JSON_get_error_code (json);
|
||||
ler.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
ler.hr.ec = TALER_JSON_get_error_code (json);
|
||||
ler.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
ler.hr.ec = TALER_JSON_get_error_code (json);
|
||||
ler.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
hr.ec = TALER_JSON_get_error_code (json);
|
||||
hr.hint = TALER_JSON_get_error_hint (json);
|
||||
ler.hr.ec = TALER_JSON_get_error_code (json);
|
||||
ler.hr.hint = TALER_JSON_get_error_hint (json);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for auditor list-exchanges request\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) ler.hr.ec);
|
||||
GNUNET_break_op (0);
|
||||
break;
|
||||
}
|
||||
if (NULL != leh->cb)
|
||||
leh->cb (leh->cb_cls,
|
||||
&hr,
|
||||
0,
|
||||
NULL);
|
||||
&ler);
|
||||
TALER_AUDITOR_list_exchanges_cancel (leh);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_AUDITOR_ListExchangesHandle *
|
||||
TALER_AUDITOR_list_exchanges (struct TALER_AUDITOR_Handle *auditor,
|
||||
TALER_AUDITOR_list_exchanges (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_AUDITOR_ListExchangesResultCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_AUDITOR_ListExchangesHandle *leh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TALER_AUDITOR_handle_is_ready_ (auditor));
|
||||
|
||||
leh = GNUNET_new (struct TALER_AUDITOR_ListExchangesHandle);
|
||||
leh->auditor = auditor;
|
||||
leh->cb = cb;
|
||||
leh->cb_cls = cb_cls;
|
||||
leh->url = TALER_AUDITOR_path_to_url_ (auditor,
|
||||
"/exchanges");
|
||||
leh->url = TALER_url_join (url,
|
||||
"exchanges",
|
||||
NULL);
|
||||
if (NULL == leh->url)
|
||||
{
|
||||
GNUNET_free (leh);
|
||||
@ -227,7 +219,6 @@ TALER_AUDITOR_list_exchanges (struct TALER_AUDITOR_Handle *auditor,
|
||||
GNUNET_free (leh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TALER_AUDITOR_handle_to_context_ (auditor);
|
||||
leh->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_exchanges_finished,
|
||||
|
288
src/lib/auditor_api_get_config.c
Normal file
288
src/lib/auditor_api_get_config.c
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see
|
||||
<http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file lib/auditor_api_get_config.c
|
||||
* @brief Implementation of /config for the auditor's HTTP API
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <microhttpd.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_auditor_service.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "auditor_api_curl_defaults.h"
|
||||
|
||||
|
||||
/**
|
||||
* Which revision of the Taler auditor protocol is implemented
|
||||
* by this library? Used to determine compatibility.
|
||||
*/
|
||||
#define TALER_PROTOCOL_CURRENT 0
|
||||
|
||||
/**
|
||||
* How many revisions back are we compatible to?
|
||||
*/
|
||||
#define TALER_PROTOCOL_AGE 0
|
||||
|
||||
|
||||
/**
|
||||
* Log error related to CURL operations.
|
||||
*
|
||||
* @param type log level
|
||||
* @param function which function failed to run
|
||||
* @param code what was the curl error code
|
||||
*/
|
||||
#define CURL_STRERROR(type, function, code) \
|
||||
GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \
|
||||
function, __FILE__, __LINE__, curl_easy_strerror (code));
|
||||
|
||||
|
||||
/**
|
||||
* Handle for the get config request.
|
||||
*/
|
||||
struct TALER_AUDITOR_GetConfigHandle
|
||||
{
|
||||
/**
|
||||
* The context of this handle
|
||||
*/
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* Function to call with the auditor's certification data,
|
||||
* NULL if this has already been done.
|
||||
*/
|
||||
TALER_AUDITOR_ConfigCallback config_cb;
|
||||
|
||||
/**
|
||||
* Closure to pass to @e config_cb.
|
||||
*/
|
||||
void *config_cb_cls;
|
||||
|
||||
/**
|
||||
* Data for the request to get the /config of a auditor,
|
||||
* NULL once we are past stage #MHS_INIT.
|
||||
*/
|
||||
struct GNUNET_CURL_Job *vr;
|
||||
|
||||
/**
|
||||
* The url for the @e vr job.
|
||||
*/
|
||||
char *vr_url;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ***************** Internal /config fetching ************* */
|
||||
|
||||
/**
|
||||
* Decode the JSON in @a resp_obj from the /config response and store the data
|
||||
* in the @a key_data.
|
||||
*
|
||||
* @param[in] resp_obj JSON object to parse
|
||||
* @param[in,out] auditor where to store the results we decoded
|
||||
* @param[out] vc where to store config compatibility data
|
||||
* @return #TALER_EC_NONE on success
|
||||
*/
|
||||
static enum TALER_ErrorCode
|
||||
decode_config_json (const json_t *resp_obj,
|
||||
struct TALER_AUDITOR_ConfigInformation *vi,
|
||||
enum TALER_AUDITOR_VersionCompatibility *vc)
|
||||
{
|
||||
unsigned int age;
|
||||
unsigned int revision;
|
||||
unsigned int current;
|
||||
char dummy;
|
||||
const char *ver;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("version",
|
||||
&ver),
|
||||
GNUNET_JSON_spec_fixed_auto ("auditor_public_key",
|
||||
&vi->auditor_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (JSON_OBJECT != json_typeof (resp_obj))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_JSON_INVALID;
|
||||
}
|
||||
/* check the config */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (resp_obj,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_JSON_INVALID;
|
||||
}
|
||||
if (3 != sscanf (ver,
|
||||
"%u:%u:%u%c",
|
||||
¤t,
|
||||
&revision,
|
||||
&age,
|
||||
&dummy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_VERSION_MALFORMED;
|
||||
}
|
||||
vi->version = ver;
|
||||
*vc = TALER_AUDITOR_VC_MATCH;
|
||||
if (TALER_PROTOCOL_CURRENT < current)
|
||||
{
|
||||
*vc |= TALER_AUDITOR_VC_NEWER;
|
||||
if (TALER_PROTOCOL_CURRENT < current - age)
|
||||
*vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
|
||||
}
|
||||
if (TALER_PROTOCOL_CURRENT > current)
|
||||
{
|
||||
*vc |= TALER_AUDITOR_VC_OLDER;
|
||||
if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
|
||||
*vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
|
||||
}
|
||||
return TALER_EC_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback used when downloading the reply to a /config request
|
||||
* is complete.
|
||||
*
|
||||
* @param cls the `struct TALER_AUDITOR_GetConfigHandle`
|
||||
* @param response_code HTTP response code, 0 on error
|
||||
* @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
|
||||
*/
|
||||
static void
|
||||
config_completed_cb (void *cls,
|
||||
long response_code,
|
||||
const void *gresp_obj)
|
||||
{
|
||||
struct TALER_AUDITOR_GetConfigHandle *auditor = cls;
|
||||
const json_t *resp_obj = gresp_obj;
|
||||
struct TALER_AUDITOR_ConfigResponse vr = {
|
||||
.hr.reply = resp_obj,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
auditor->vr = NULL;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Received config from URL `%s' with status %ld.\n",
|
||||
auditor->vr_url,
|
||||
response_code);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
GNUNET_break_op (0);
|
||||
vr.hr.ec = TALER_EC_INVALID;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
if (NULL == resp_obj)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
vr.hr.http_status = 0;
|
||||
vr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
}
|
||||
vr.hr.ec = decode_config_json (resp_obj,
|
||||
&vr.details.ok.vi,
|
||||
&vr.details.ok.compat);
|
||||
if (TALER_EC_NONE != vr.hr.ec)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
vr.hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
|
||||
vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
|
||||
break;
|
||||
default:
|
||||
vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
|
||||
vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d\n",
|
||||
(unsigned int) response_code,
|
||||
(int) vr.hr.ec);
|
||||
break;
|
||||
}
|
||||
auditor->config_cb (auditor->config_cb_cls,
|
||||
&vr);
|
||||
TALER_AUDITOR_get_config_cancel (auditor);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_AUDITOR_GetConfigHandle *
|
||||
TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_AUDITOR_ConfigCallback config_cb,
|
||||
void *config_cb_cls)
|
||||
{
|
||||
struct TALER_AUDITOR_GetConfigHandle *auditor;
|
||||
CURL *eh;
|
||||
|
||||
auditor = GNUNET_new (struct TALER_AUDITOR_GetConfigHandle);
|
||||
auditor->config_cb = config_cb;
|
||||
auditor->config_cb_cls = config_cb_cls;
|
||||
auditor->ctx = ctx;
|
||||
auditor->vr_url = TALER_url_join (url,
|
||||
"config",
|
||||
NULL);
|
||||
if (NULL == auditor->vr_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_free (auditor->vr_url);
|
||||
GNUNET_free (auditor);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Requesting auditor config with URL `%s'.\n",
|
||||
auditor->vr_url);
|
||||
eh = TALER_AUDITOR_curl_easy_get_ (auditor->vr_url);
|
||||
if (NULL == eh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_AUDITOR_get_config_cancel (auditor);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_break (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_TIMEOUT,
|
||||
(long) 300));
|
||||
auditor->vr = GNUNET_CURL_job_add (auditor->ctx,
|
||||
eh,
|
||||
&config_completed_cb,
|
||||
auditor);
|
||||
return auditor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_AUDITOR_get_config_cancel (struct TALER_AUDITOR_GetConfigHandle *auditor)
|
||||
{
|
||||
if (NULL != auditor->vr)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (auditor->vr);
|
||||
auditor->vr = NULL;
|
||||
}
|
||||
GNUNET_free (auditor->vr_url);
|
||||
GNUNET_free (auditor);
|
||||
}
|
||||
|
||||
|
||||
/* end of auditor_api_get_config.c */
|
@ -1,449 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see
|
||||
<http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file lib/auditor_api_handle.c
|
||||
* @brief Implementation of the "handle" component of the auditor's HTTP API
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <microhttpd.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_auditor_service.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "auditor_api_handle.h"
|
||||
#include "auditor_api_curl_defaults.h"
|
||||
#include "backoff.h"
|
||||
|
||||
/**
|
||||
* Which revision of the Taler auditor protocol is implemented
|
||||
* by this library? Used to determine compatibility.
|
||||
*/
|
||||
#define TALER_PROTOCOL_CURRENT 0
|
||||
|
||||
/**
|
||||
* How many revisions back are we compatible to?
|
||||
*/
|
||||
#define TALER_PROTOCOL_AGE 0
|
||||
|
||||
|
||||
/**
|
||||
* Log error related to CURL operations.
|
||||
*
|
||||
* @param type log level
|
||||
* @param function which function failed to run
|
||||
* @param code what was the curl error code
|
||||
*/
|
||||
#define CURL_STRERROR(type, function, code) \
|
||||
GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \
|
||||
function, __FILE__, __LINE__, curl_easy_strerror (code));
|
||||
|
||||
/**
|
||||
* Stages of initialization for the `struct TALER_AUDITOR_Handle`
|
||||
*/
|
||||
enum AuditorHandleState
|
||||
{
|
||||
/**
|
||||
* Just allocated.
|
||||
*/
|
||||
MHS_INIT = 0,
|
||||
|
||||
/**
|
||||
* Obtained the auditor's versioning data and version.
|
||||
*/
|
||||
MHS_VERSION = 1,
|
||||
|
||||
/**
|
||||
* Failed to initialize (fatal).
|
||||
*/
|
||||
MHS_FAILED = 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle to the auditor
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle
|
||||
{
|
||||
/**
|
||||
* The context of this handle
|
||||
*/
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* The URL of the auditor (i.e. "http://auditor.taler.net/")
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* Function to call with the auditor's certification data,
|
||||
* NULL if this has already been done.
|
||||
*/
|
||||
TALER_AUDITOR_VersionCallback version_cb;
|
||||
|
||||
/**
|
||||
* Closure to pass to @e version_cb.
|
||||
*/
|
||||
void *version_cb_cls;
|
||||
|
||||
/**
|
||||
* Data for the request to get the /config of a auditor,
|
||||
* NULL once we are past stage #MHS_INIT.
|
||||
*/
|
||||
struct GNUNET_CURL_Job *vr;
|
||||
|
||||
/**
|
||||
* The url for the @e vr job.
|
||||
*/
|
||||
char *vr_url;
|
||||
|
||||
/**
|
||||
* Task for retrying /config request.
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *retry_task;
|
||||
|
||||
/**
|
||||
* /config data of the auditor, only valid if
|
||||
* @e handshake_complete is past stage #MHS_VERSION.
|
||||
*/
|
||||
char *version;
|
||||
|
||||
/**
|
||||
* Version information for the callback.
|
||||
*/
|
||||
struct TALER_AUDITOR_VersionInformation vi;
|
||||
|
||||
/**
|
||||
* Retry /config frequency.
|
||||
*/
|
||||
struct GNUNET_TIME_Relative retry_delay;
|
||||
|
||||
/**
|
||||
* Stage of the auditor's initialization routines.
|
||||
*/
|
||||
enum AuditorHandleState state;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ***************** Internal /config fetching ************* */
|
||||
|
||||
/**
|
||||
* Decode the JSON in @a resp_obj from the /config response and store the data
|
||||
* in the @a key_data.
|
||||
*
|
||||
* @param[in] resp_obj JSON object to parse
|
||||
* @param[in,out] auditor where to store the results we decoded
|
||||
* @param[out] vc where to store version compatibility data
|
||||
* @return #TALER_EC_NONE on success
|
||||
*/
|
||||
static enum TALER_ErrorCode
|
||||
decode_version_json (const json_t *resp_obj,
|
||||
struct TALER_AUDITOR_Handle *auditor,
|
||||
enum TALER_AUDITOR_VersionCompatibility *vc)
|
||||
{
|
||||
struct TALER_AUDITOR_VersionInformation *vi = &auditor->vi;
|
||||
unsigned int age;
|
||||
unsigned int revision;
|
||||
unsigned int current;
|
||||
char dummy;
|
||||
const char *ver;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("version",
|
||||
&ver),
|
||||
GNUNET_JSON_spec_fixed_auto ("auditor_public_key",
|
||||
&vi->auditor_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (JSON_OBJECT != json_typeof (resp_obj))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_JSON_INVALID;
|
||||
}
|
||||
/* check the version */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (resp_obj,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_JSON_INVALID;
|
||||
}
|
||||
if (3 != sscanf (ver,
|
||||
"%u:%u:%u%c",
|
||||
¤t,
|
||||
&revision,
|
||||
&age,
|
||||
&dummy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TALER_EC_GENERIC_VERSION_MALFORMED;
|
||||
}
|
||||
GNUNET_free (auditor->version);
|
||||
auditor->version = GNUNET_strdup (ver);
|
||||
vi->version = auditor->version;
|
||||
*vc = TALER_AUDITOR_VC_MATCH;
|
||||
if (TALER_PROTOCOL_CURRENT < current)
|
||||
{
|
||||
*vc |= TALER_AUDITOR_VC_NEWER;
|
||||
if (TALER_PROTOCOL_CURRENT < current - age)
|
||||
*vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
|
||||
}
|
||||
if (TALER_PROTOCOL_CURRENT > current)
|
||||
{
|
||||
*vc |= TALER_AUDITOR_VC_OLDER;
|
||||
if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
|
||||
*vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
|
||||
}
|
||||
return TALER_EC_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initiate download of /config from the auditor.
|
||||
*
|
||||
* @param cls auditor where to download /config from
|
||||
*/
|
||||
static void
|
||||
request_version (void *cls);
|
||||
|
||||
|
||||
/**
|
||||
* Callback used when downloading the reply to a /config request
|
||||
* is complete.
|
||||
*
|
||||
* @param cls the `struct TALER_AUDITOR_Handle`
|
||||
* @param response_code HTTP response code, 0 on error
|
||||
* @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
|
||||
*/
|
||||
static void
|
||||
version_completed_cb (void *cls,
|
||||
long response_code,
|
||||
const void *gresp_obj)
|
||||
{
|
||||
struct TALER_AUDITOR_Handle *auditor = cls;
|
||||
const json_t *resp_obj = gresp_obj;
|
||||
enum TALER_AUDITOR_VersionCompatibility vc;
|
||||
struct TALER_AUDITOR_HttpResponse hr = {
|
||||
.reply = resp_obj,
|
||||
.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
auditor->vr = NULL;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Received version from URL `%s' with status %ld.\n",
|
||||
auditor->url,
|
||||
response_code);
|
||||
vc = TALER_AUDITOR_VC_PROTOCOL_ERROR;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* NOTE: this design is debatable. We MAY want to throw this error at the
|
||||
client. We may then still additionally internally re-try. */
|
||||
GNUNET_assert (NULL == auditor->retry_task);
|
||||
auditor->retry_delay = EXCHANGE_LIB_BACKOFF (auditor->retry_delay);
|
||||
auditor->retry_task = GNUNET_SCHEDULER_add_delayed (auditor->retry_delay,
|
||||
&request_version,
|
||||
auditor);
|
||||
return;
|
||||
case MHD_HTTP_OK:
|
||||
if (NULL == resp_obj)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TALER_LOG_WARNING ("NULL body for a 200-OK /config\n");
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
}
|
||||
hr.ec = decode_version_json (resp_obj,
|
||||
auditor,
|
||||
&vc);
|
||||
if (TALER_EC_NONE != hr.ec)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
hr.http_status = 0;
|
||||
break;
|
||||
}
|
||||
auditor->retry_delay = GNUNET_TIME_UNIT_ZERO; /* restart quickly */
|
||||
break;
|
||||
default:
|
||||
hr.ec = TALER_JSON_get_error_code (resp_obj);
|
||||
hr.hint = TALER_JSON_get_error_hint (resp_obj);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
break;
|
||||
}
|
||||
if (MHD_HTTP_OK != response_code)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"/config failed for auditor %s: %u!\n",
|
||||
auditor->url,
|
||||
(unsigned int) response_code);
|
||||
auditor->state = MHS_FAILED;
|
||||
/* notify application that we failed */
|
||||
auditor->version_cb (auditor->version_cb_cls,
|
||||
&hr,
|
||||
NULL,
|
||||
vc);
|
||||
return;
|
||||
}
|
||||
TALER_LOG_DEBUG ("Switching auditor state to 'version'\n");
|
||||
auditor->state = MHS_VERSION;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Auditor %s is ready!\n",
|
||||
auditor->url);
|
||||
/* notify application about the key information */
|
||||
auditor->version_cb (auditor->version_cb_cls,
|
||||
&hr,
|
||||
&auditor->vi,
|
||||
vc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initiate download of /config from the auditor.
|
||||
*
|
||||
* @param cls auditor where to download /config from
|
||||
*/
|
||||
static void
|
||||
request_version (void *cls)
|
||||
{
|
||||
struct TALER_AUDITOR_Handle *auditor = cls;
|
||||
CURL *eh;
|
||||
|
||||
auditor->retry_task = NULL;
|
||||
GNUNET_assert (NULL == auditor->vr);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Requesting auditor version with URL `%s'.\n",
|
||||
auditor->vr_url);
|
||||
eh = TALER_AUDITOR_curl_easy_get_ (auditor->vr_url);
|
||||
if (NULL == eh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
auditor->retry_delay = EXCHANGE_LIB_BACKOFF (auditor->retry_delay);
|
||||
auditor->retry_task = GNUNET_SCHEDULER_add_delayed (auditor->retry_delay,
|
||||
&request_version,
|
||||
auditor);
|
||||
return;
|
||||
}
|
||||
GNUNET_break (CURLE_OK ==
|
||||
curl_easy_setopt (eh,
|
||||
CURLOPT_TIMEOUT,
|
||||
(long) 300));
|
||||
auditor->vr = GNUNET_CURL_job_add (auditor->ctx,
|
||||
eh,
|
||||
&version_completed_cb,
|
||||
auditor);
|
||||
}
|
||||
|
||||
|
||||
/* ********************* library internal API ********* */
|
||||
|
||||
|
||||
struct GNUNET_CURL_Context *
|
||||
TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h)
|
||||
{
|
||||
return h->ctx;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Checking if auditor at `%s` is now ready: %s\n",
|
||||
h->url,
|
||||
(MHD_VERSION == h->state) ? "yes" : "no");
|
||||
return (MHS_VERSION == h->state) ? GNUNET_YES : GNUNET_NO;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
|
||||
const char *path)
|
||||
{
|
||||
GNUNET_assert ('/' == path[0]);
|
||||
return TALER_url_join (h->url,
|
||||
path + 1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/* ********************* public API ******************* */
|
||||
|
||||
|
||||
struct TALER_AUDITOR_Handle *
|
||||
TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_AUDITOR_VersionCallback version_cb,
|
||||
void *version_cb_cls)
|
||||
{
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
|
||||
auditor = GNUNET_new (struct TALER_AUDITOR_Handle);
|
||||
auditor->version_cb = version_cb;
|
||||
auditor->version_cb_cls = version_cb_cls;
|
||||
auditor->retry_delay = GNUNET_TIME_UNIT_SECONDS; /* start slowly */
|
||||
auditor->ctx = ctx;
|
||||
auditor->url = GNUNET_strdup (url);
|
||||
auditor->vr_url = TALER_AUDITOR_path_to_url_ (auditor,
|
||||
"/config");
|
||||
if (NULL == auditor->vr_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_free (auditor->url);
|
||||
GNUNET_free (auditor);
|
||||
return NULL;
|
||||
}
|
||||
auditor->retry_task = GNUNET_SCHEDULER_add_now (&request_version,
|
||||
auditor);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Connecting to auditor at URL `%s'.\n",
|
||||
url);
|
||||
return auditor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Disconnecting from auditor at URL `%s'.\n",
|
||||
auditor->url);
|
||||
if (NULL != auditor->vr)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (auditor->vr);
|
||||
auditor->vr = NULL;
|
||||
}
|
||||
if (NULL != auditor->retry_task)
|
||||
{
|
||||
GNUNET_SCHEDULER_cancel (auditor->retry_task);
|
||||
auditor->retry_task = NULL;
|
||||
}
|
||||
GNUNET_free (auditor->version);
|
||||
GNUNET_free (auditor->vr_url);
|
||||
GNUNET_free (auditor->url);
|
||||
GNUNET_free (auditor);
|
||||
}
|
||||
|
||||
|
||||
/* end of auditor_api_handle.c */
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014, 2015 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see
|
||||
<http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file lib/auditor_api_handle.h
|
||||
* @brief Internal interface to the handle part of the auditor's HTTP API
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_auditor_service.h"
|
||||
#include "taler_curl_lib.h"
|
||||
|
||||
/**
|
||||
* Get the context of a auditor.
|
||||
*
|
||||
* @param h the auditor handle to query
|
||||
* @return ctx context to execute jobs in
|
||||
*/
|
||||
struct GNUNET_CURL_Context *
|
||||
TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h);
|
||||
|
||||
|
||||
/**
|
||||
* Check if the handle is ready to process requests.
|
||||
*
|
||||
* @param h the auditor handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
int
|
||||
TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the URL to use for an API request.
|
||||
*
|
||||
* @param h the auditor handle to query
|
||||
* @param path Taler API path (i.e. "/deposit-confirmation")
|
||||
* @return the full URL to use with cURL
|
||||
*/
|
||||
char *
|
||||
TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
|
||||
const char *path);
|
||||
|
||||
|
||||
/* end of auditor_api_handle.h */
|
@ -44,6 +44,39 @@
|
||||
*/
|
||||
#define AUDITOR_CHANCE 20
|
||||
|
||||
|
||||
/**
|
||||
* Entry in list of ongoing interactions with an auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry
|
||||
{
|
||||
/**
|
||||
* DLL entry.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *next;
|
||||
|
||||
/**
|
||||
* DLL entry.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *prev;
|
||||
|
||||
/**
|
||||
* URL of our auditor. For logging.
|
||||
*/
|
||||
const char *auditor_url;
|
||||
|
||||
/**
|
||||
* Interaction state.
|
||||
*/
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *dch;
|
||||
|
||||
/**
|
||||
* Batch deposit this is for.
|
||||
*/
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief A Deposit Handle
|
||||
*/
|
||||
@ -51,9 +84,14 @@ struct TALER_EXCHANGE_BatchDepositHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* Context for our curl request(s).
|
||||
*/
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -64,7 +102,7 @@ struct TALER_EXCHANGE_BatchDepositHandle
|
||||
* Context for #TEH_curl_easy_post(). Keeps the data that must
|
||||
* persist for Curl to make the upload.
|
||||
*/
|
||||
struct TALER_CURL_PostContext ctx;
|
||||
struct TALER_CURL_PostContext post_ctx;
|
||||
|
||||
/**
|
||||
* Handle for the request.
|
||||
@ -112,11 +150,31 @@ struct TALER_EXCHANGE_BatchDepositHandle
|
||||
*/
|
||||
struct TALER_ExchangeSignatureP *exchange_sigs;
|
||||
|
||||
/**
|
||||
* Head of DLL of interactions with this auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *ai_head;
|
||||
|
||||
/**
|
||||
* Tail of DLL of interactions with this auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *ai_tail;
|
||||
|
||||
/**
|
||||
* Result to return to the application once @e ai_head is empty.
|
||||
*/
|
||||
struct TALER_EXCHANGE_BatchDepositResult dr;
|
||||
|
||||
/**
|
||||
* Exchange signing public key, set for #auditor_cb.
|
||||
*/
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
|
||||
/**
|
||||
* Response object to free at the end.
|
||||
*/
|
||||
json_t *response;
|
||||
|
||||
/**
|
||||
* Chance that we will inform the auditor about the deposit
|
||||
* is 1:n, where the value of this field is "n".
|
||||
@ -131,22 +189,66 @@ struct TALER_EXCHANGE_BatchDepositHandle
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finish batch deposit operation by calling the callback.
|
||||
*
|
||||
* @param[in] dh handle to finished batch deposit operation
|
||||
*/
|
||||
static void
|
||||
finish_dh (struct TALER_EXCHANGE_BatchDepositHandle *dh)
|
||||
{
|
||||
dh->cb (dh->cb_cls,
|
||||
&dh->dr);
|
||||
TALER_EXCHANGE_batch_deposit_cancel (dh);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called with the result from our call to the
|
||||
* auditor's /deposit-confirmation handler.
|
||||
*
|
||||
* @param cls closure of type `struct TEAH_AuditorInteractionEntry *`
|
||||
* @param dcr response
|
||||
*/
|
||||
static void
|
||||
acc_confirmation_cb (
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr)
|
||||
{
|
||||
struct TEAH_AuditorInteractionEntry *aie = cls;
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh = aie->dh;
|
||||
|
||||
if (MHD_HTTP_OK != dcr->hr.http_status)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to submit deposit confirmation to auditor `%s' with HTTP status %d (EC: %d). This is acceptable if it does not happen often.\n",
|
||||
aie->auditor_url,
|
||||
dcr->hr.http_status,
|
||||
dcr->hr.ec);
|
||||
}
|
||||
GNUNET_CONTAINER_DLL_remove (dh->ai_head,
|
||||
dh->ai_tail,
|
||||
aie);
|
||||
GNUNET_free (aie);
|
||||
if (NULL == dh->ai_head)
|
||||
finish_dh (dh);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called for each auditor to give us a chance to possibly
|
||||
* launch a deposit confirmation interaction.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param ah handle to the auditor
|
||||
* @param auditor_url base URL of the auditor
|
||||
* @param auditor_pub public key of the auditor
|
||||
* @return NULL if no deposit confirmation interaction was launched
|
||||
*/
|
||||
static struct TEAH_AuditorInteractionEntry *
|
||||
static void
|
||||
auditor_cb (void *cls,
|
||||
struct TALER_AUDITOR_Handle *ah,
|
||||
const char *auditor_url,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub)
|
||||
{
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh = cls;
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
const struct TALER_EXCHANGE_SigningPublicKey *spk;
|
||||
struct TEAH_AuditorInteractionEntry *aie;
|
||||
struct TALER_Amount amount_without_fee;
|
||||
@ -159,31 +261,33 @@ auditor_cb (void *cls,
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Not providing deposit confirmation to auditor\n");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
coin = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
dh->num_cdds);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Will provide deposit confirmation to auditor `%s'\n",
|
||||
TALER_B2S (auditor_pub));
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (dh->keys,
|
||||
&dh->cdds[coin].h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
spk = TALER_EXCHANGE_get_signing_key_info (key_state,
|
||||
spk = TALER_EXCHANGE_get_signing_key_info (dh->keys,
|
||||
&dh->exchange_pub);
|
||||
if (NULL == spk)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
GNUNET_assert (0 <=
|
||||
TALER_amount_subtract (&amount_without_fee,
|
||||
&dh->cdds[coin].amount,
|
||||
&dki->fees.deposit));
|
||||
aie = GNUNET_new (struct TEAH_AuditorInteractionEntry);
|
||||
aie->dh = dh;
|
||||
aie->auditor_url = auditor_url;
|
||||
aie->dch = TALER_AUDITOR_deposit_confirmation (
|
||||
ah,
|
||||
dh->ctx,
|
||||
auditor_url,
|
||||
&dh->h_wire,
|
||||
&dh->h_policy,
|
||||
&dh->dcd.h_contract_terms,
|
||||
@ -195,14 +299,16 @@ auditor_cb (void *cls,
|
||||
&dh->dcd.merchant_pub,
|
||||
&dh->exchange_pub,
|
||||
&dh->exchange_sigs[coin],
|
||||
&key_state->master_pub,
|
||||
&dh->keys->master_pub,
|
||||
spk->valid_from,
|
||||
spk->valid_until,
|
||||
spk->valid_legal,
|
||||
&spk->master_sig,
|
||||
&TEAH_acc_confirmation_cb,
|
||||
&acc_confirmation_cb,
|
||||
aie);
|
||||
GNUNET_CONTAINER_DLL_insert (dh->ai_head,
|
||||
dh->ai_tail,
|
||||
aie);
|
||||
return aie;
|
||||
}
|
||||
|
||||
|
||||
@ -221,22 +327,19 @@ handle_deposit_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_BatchDepositResult dr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
struct TALER_EXCHANGE_BatchDepositResult *dr = &dh->dr;
|
||||
|
||||
dh->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dh->response = json_incref ((json_t*) j);
|
||||
dr->hr.reply = dh->response;
|
||||
dr->hr.http_status = (unsigned int) response_code;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
dr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
const json_t *sigs;
|
||||
json_t *sig;
|
||||
unsigned int idx;
|
||||
@ -247,7 +350,7 @@ handle_deposit_finished (void *cls,
|
||||
&dh->exchange_pub),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("transaction_base_url",
|
||||
&dr.details.ok.transaction_base_url),
|
||||
&dr->details.ok.transaction_base_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&dh->exchange_timestamp),
|
||||
@ -260,27 +363,26 @@ handle_deposit_finished (void *cls,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
if (json_array_size (sigs) != dh->num_cdds)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
dh->exchange_sigs = GNUNET_new_array (dh->num_cdds,
|
||||
struct TALER_ExchangeSignatureP);
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (dh->keys,
|
||||
&dh->exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
json_array_foreach (sigs, idx, sig)
|
||||
@ -299,11 +401,11 @@ handle_deposit_finished (void *cls,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (dh->keys,
|
||||
&dh->cdds[idx].
|
||||
h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
@ -327,42 +429,41 @@ handle_deposit_finished (void *cls,
|
||||
&dh->exchange_sigs[idx]))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEAH_get_auditors_for_dc (dh->exchange,
|
||||
TEAH_get_auditors_for_dc (dh->keys,
|
||||
&auditor_cb,
|
||||
dh);
|
||||
}
|
||||
dr.details.ok.exchange_sigs = dh->exchange_sigs;
|
||||
dr.details.ok.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.ok.deposit_timestamp = dh->exchange_timestamp;
|
||||
dr.details.ok.num_signatures = dh->num_cdds;
|
||||
dr->details.ok.exchange_sigs = dh->exchange_sigs;
|
||||
dr->details.ok.exchange_pub = &dh->exchange_pub;
|
||||
dr->details.ok.deposit_timestamp = dh->exchange_timestamp;
|
||||
dr->details.ok.num_signatures = dh->num_cdds;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_pub",
|
||||
@ -378,8 +479,8 @@ handle_deposit_finished (void *cls,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
for (unsigned int i = 0; i<dh->num_cdds; i++)
|
||||
@ -388,14 +489,13 @@ handle_deposit_finished (void *cls,
|
||||
GNUNET_memcmp (&coin_pub,
|
||||
&dh->cdds[i].coin_pub))
|
||||
continue;
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (dh->keys,
|
||||
&dh->cdds[i].
|
||||
h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_coin_conflict_ (
|
||||
keys,
|
||||
dh->keys,
|
||||
j,
|
||||
dki,
|
||||
&dh->cdds[i].coin_pub,
|
||||
@ -403,8 +503,8 @@ handle_deposit_finished (void *cls,
|
||||
&dh->cdds[i].amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
@ -413,12 +513,12 @@ handle_deposit_finished (void *cls,
|
||||
if (! found)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
dr->hr.http_status = 0;
|
||||
dr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
@ -426,35 +526,37 @@ handle_deposit_finished (void *cls,
|
||||
/* Note: one might want to check /keys for revocation
|
||||
signature here, alas tricky in case our /keys
|
||||
is outdated => left to clients */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
dr->hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr->hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange deposit\n",
|
||||
(unsigned int) response_code,
|
||||
dr.hr.ec);
|
||||
dr->hr.ec);
|
||||
GNUNET_break_op (0);
|
||||
break;
|
||||
}
|
||||
dh->cb (dh->cb_cls,
|
||||
&dr);
|
||||
TALER_EXCHANGE_batch_deposit_cancel (dh);
|
||||
if (NULL != dh->ai_head)
|
||||
return;
|
||||
finish_dh (dh);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *
|
||||
TALER_EXCHANGE_batch_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||
unsigned int num_cdds,
|
||||
const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
|
||||
@ -462,16 +564,12 @@ TALER_EXCHANGE_batch_deposit (
|
||||
void *cb_cls,
|
||||
enum TALER_ErrorCode *ec)
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *deposit_obj;
|
||||
json_t *deposits;
|
||||
CURL *eh;
|
||||
struct TALER_Amount amount_without_fee;
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
if (GNUNET_TIME_timestamp_cmp (dcd->refund_deadline,
|
||||
>,
|
||||
dcd->wire_deadline))
|
||||
@ -480,10 +578,8 @@ TALER_EXCHANGE_batch_deposit (
|
||||
*ec = TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE;
|
||||
return NULL;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (exchange);
|
||||
dh = GNUNET_new (struct TALER_EXCHANGE_BatchDepositHandle);
|
||||
dh->auditor_chance = AUDITOR_CHANCE;
|
||||
dh->exchange = exchange;
|
||||
dh->cb = cb;
|
||||
dh->cb_cls = cb_cls;
|
||||
dh->cdds = GNUNET_memdup (cdds,
|
||||
@ -504,7 +600,7 @@ TALER_EXCHANGE_batch_deposit (
|
||||
const struct TALER_EXCHANGE_CoinDepositDetail *cdd = &cdds[i];
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
|
||||
&cdd->h_denom_pub);
|
||||
if (NULL == dki)
|
||||
{
|
||||
@ -563,8 +659,9 @@ TALER_EXCHANGE_batch_deposit (
|
||||
&cdd->coin_sig)
|
||||
)));
|
||||
}
|
||||
dh->url = TEAH_path_to_url (exchange,
|
||||
"/batch-deposit");
|
||||
dh->url = TALER_url_join (url,
|
||||
"batch-deposit",
|
||||
NULL);
|
||||
if (NULL == dh->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -600,7 +697,7 @@ TALER_EXCHANGE_batch_deposit (
|
||||
eh = TALER_EXCHANGE_curl_easy_get_ (dh->url);
|
||||
if ( (NULL == eh) ||
|
||||
(GNUNET_OK !=
|
||||
TALER_curl_easy_post (&dh->ctx,
|
||||
TALER_curl_easy_post (&dh->post_ctx,
|
||||
eh,
|
||||
deposit_obj)) )
|
||||
{
|
||||
@ -618,10 +715,11 @@ TALER_EXCHANGE_batch_deposit (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for deposit: `%s'\n",
|
||||
dh->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
dh->ctx = ctx;
|
||||
dh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
dh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
dh->ctx.headers,
|
||||
dh->post_ctx.headers,
|
||||
&handle_deposit_finished,
|
||||
dh);
|
||||
return dh;
|
||||
@ -640,15 +738,31 @@ void
|
||||
TALER_EXCHANGE_batch_deposit_cancel (
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *deposit)
|
||||
{
|
||||
struct TEAH_AuditorInteractionEntry *aie;
|
||||
|
||||
while (NULL != (aie = deposit->ai_head))
|
||||
{
|
||||
GNUNET_assert (aie->dh == deposit);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Not sending deposit confirmation to auditor `%s' due to cancellation\n",
|
||||
aie->auditor_url);
|
||||
TALER_AUDITOR_deposit_confirmation_cancel (aie->dch);
|
||||
GNUNET_CONTAINER_DLL_remove (deposit->ai_head,
|
||||
deposit->ai_tail,
|
||||
aie);
|
||||
GNUNET_free (aie);
|
||||
}
|
||||
if (NULL != deposit->job)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (deposit->job);
|
||||
deposit->job = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_keys_decref (deposit->keys);
|
||||
GNUNET_free (deposit->url);
|
||||
GNUNET_free (deposit->cdds);
|
||||
GNUNET_free (deposit->exchange_sigs);
|
||||
TALER_curl_easy_post_finished (&deposit->ctx);
|
||||
TALER_curl_easy_post_finished (&deposit->post_ctx);
|
||||
json_decref (deposit->response);
|
||||
GNUNET_free (deposit);
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,8 @@ reserve_batch_withdraw_payment_required (
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_parse_reserve_history (wh->exchange,
|
||||
TALER_EXCHANGE_parse_reserve_history (
|
||||
TALER_EXCHANGE_get_keys (wh->exchange),
|
||||
history,
|
||||
&wh->reserve_pub,
|
||||
balance.currency,
|
||||
|
@ -34,9 +34,9 @@ struct HistoryParseContext
|
||||
{
|
||||
|
||||
/**
|
||||
* Exchange we use.
|
||||
* Keys of the exchange we use.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* Our reserve public key.
|
||||
@ -187,7 +187,7 @@ parse_withdraw (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
|
||||
key_state = TALER_EXCHANGE_get_keys (uc->exchange);
|
||||
key_state = uc->keys;
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
&h_denom_pub);
|
||||
if ( (GNUNET_YES !=
|
||||
@ -275,7 +275,7 @@ parse_recoup (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (uc->exchange);
|
||||
key_state = uc->keys;
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&rh->details.
|
||||
@ -349,7 +349,7 @@ parse_closing (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (uc->exchange);
|
||||
key_state = uc->keys;
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (
|
||||
key_state,
|
||||
@ -647,7 +647,7 @@ parse_close (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_EXCHANGE_parse_reserve_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const json_t *history,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
const char *currency,
|
||||
@ -673,7 +673,7 @@ TALER_EXCHANGE_parse_reserve_history (
|
||||
};
|
||||
struct GNUNET_HashCode uuid[history_length];
|
||||
struct HistoryParseContext uc = {
|
||||
.exchange = exchange,
|
||||
.keys = keys,
|
||||
.reserve_pub = reserve_pub,
|
||||
.uuids = uuid,
|
||||
.total_in = total_in,
|
||||
|
@ -38,11 +38,6 @@
|
||||
struct TALER_EXCHANGE_ContractsGetHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -194,7 +189,8 @@ handle_contract_get_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ContractsGetHandle *
|
||||
TALER_EXCHANGE_contract_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||
TALER_EXCHANGE_ContractGetCallback cb,
|
||||
void *cb_cls)
|
||||
@ -203,14 +199,7 @@ TALER_EXCHANGE_contract_get (
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (cgh->cpub) * 2 + 48];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
cgh = GNUNET_new (struct TALER_EXCHANGE_ContractsGetHandle);
|
||||
cgh->exchange = exchange;
|
||||
cgh->cb = cb;
|
||||
cgh->cb_cls = cb_cls;
|
||||
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
|
||||
@ -226,12 +215,13 @@ TALER_EXCHANGE_contract_get (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/contracts/%s",
|
||||
"contracts/%s",
|
||||
cpub_str);
|
||||
}
|
||||
|
||||
cgh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
cgh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == cgh->url)
|
||||
{
|
||||
GNUNET_free (cgh);
|
||||
@ -247,7 +237,7 @@ TALER_EXCHANGE_contract_get (
|
||||
GNUNET_free (cgh);
|
||||
return NULL;
|
||||
}
|
||||
cgh->job = GNUNET_CURL_job_add (TEAH_handle_to_context (exchange),
|
||||
cgh->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_contract_get_finished,
|
||||
cgh);
|
||||
|
@ -38,10 +38,6 @@
|
||||
*/
|
||||
struct TALER_EXCHANGE_CsRMeltHandle
|
||||
{
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* Function to call with the result.
|
||||
@ -220,7 +216,9 @@ handle_csr_finished (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_CsRMeltHandle *
|
||||
TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_csr_melt (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
unsigned int nks_len,
|
||||
struct TALER_EXCHANGE_NonceKey *nks,
|
||||
@ -242,7 +240,6 @@ TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
return NULL;
|
||||
}
|
||||
csrh = GNUNET_new (struct TALER_EXCHANGE_CsRMeltHandle);
|
||||
csrh->exchange = exchange;
|
||||
csrh->cb = res_cb;
|
||||
csrh->cb_cls = res_cb_cls;
|
||||
csr_arr = json_array ();
|
||||
@ -262,8 +259,9 @@ TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
json_array_append_new (csr_arr,
|
||||
csr_obj));
|
||||
}
|
||||
csrh->url = TEAH_path_to_url (exchange,
|
||||
"/csr-melt");
|
||||
csrh->url = TALER_url_join (url,
|
||||
"csr-melt",
|
||||
NULL);
|
||||
if (NULL == csrh->url)
|
||||
{
|
||||
json_decref (csr_arr);
|
||||
@ -272,7 +270,6 @@ TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
}
|
||||
{
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *req;
|
||||
|
||||
req = GNUNET_JSON_PACK (
|
||||
@ -280,7 +277,6 @@ TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
rms),
|
||||
GNUNET_JSON_pack_array_steal ("nks",
|
||||
csr_arr));
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url);
|
||||
if ( (NULL == eh) ||
|
||||
(GNUNET_OK !=
|
||||
|
@ -1,557 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2021 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see
|
||||
<http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file lib/exchange_api_deposit.c
|
||||
* @brief Implementation of the /deposit request of the exchange's HTTP API
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <jansson.h>
|
||||
#include <microhttpd.h> /* just for HTTP status codes */
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <gnunet/gnunet_json_lib.h>
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_auditor_service.h"
|
||||
#include "taler_exchange_service.h"
|
||||
#include "exchange_api_common.h"
|
||||
#include "exchange_api_handle.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "exchange_api_curl_defaults.h"
|
||||
|
||||
|
||||
/**
|
||||
* 1:#AUDITOR_CHANCE is the probability that we report deposits
|
||||
* to the auditor.
|
||||
*
|
||||
* 20==5% of going to auditor. This is possibly still too high, but set
|
||||
* deliberately this high for testing
|
||||
*/
|
||||
#define AUDITOR_CHANCE 20
|
||||
|
||||
/**
|
||||
* @brief A Deposit Handle
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* Context for #TEH_curl_easy_post(). Keeps the data that must
|
||||
* persist for Curl to make the upload.
|
||||
*/
|
||||
struct TALER_CURL_PostContext ctx;
|
||||
|
||||
/**
|
||||
* Handle for the request.
|
||||
*/
|
||||
struct GNUNET_CURL_Job *job;
|
||||
|
||||
/**
|
||||
* Function to call with the result.
|
||||
*/
|
||||
TALER_EXCHANGE_DepositResultCallback cb;
|
||||
|
||||
/**
|
||||
* Closure for @a cb.
|
||||
*/
|
||||
void *cb_cls;
|
||||
|
||||
/**
|
||||
* Details about the contract.
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositContractDetail dcd;
|
||||
|
||||
/**
|
||||
* Details about the coin.
|
||||
*/
|
||||
struct TALER_EXCHANGE_CoinDepositDetail cdd;
|
||||
|
||||
/**
|
||||
* Hash of the merchant's wire details.
|
||||
*/
|
||||
struct TALER_MerchantWireHashP h_wire;
|
||||
|
||||
/**
|
||||
* Hash over the policy extension, or all zero.
|
||||
*/
|
||||
struct TALER_ExtensionPolicyHashP h_policy;
|
||||
|
||||
/**
|
||||
* Time when this confirmation was generated / when the exchange received
|
||||
* the deposit request.
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp exchange_timestamp;
|
||||
|
||||
/**
|
||||
* Exchange signature, set for #auditor_cb.
|
||||
*/
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
|
||||
/**
|
||||
* Exchange signing public key, set for #auditor_cb.
|
||||
*/
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
|
||||
/**
|
||||
* Chance that we will inform the auditor about the deposit
|
||||
* is 1:n, where the value of this field is "n".
|
||||
*/
|
||||
unsigned int auditor_chance;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called for each auditor to give us a chance to possibly
|
||||
* launch a deposit confirmation interaction.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param ah handle to the auditor
|
||||
* @param auditor_pub public key of the auditor
|
||||
* @return NULL if no deposit confirmation interaction was launched
|
||||
*/
|
||||
static struct TEAH_AuditorInteractionEntry *
|
||||
auditor_cb (void *cls,
|
||||
struct TALER_AUDITOR_Handle *ah,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub)
|
||||
{
|
||||
struct TALER_EXCHANGE_DepositHandle *dh = cls;
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
const struct TALER_EXCHANGE_SigningPublicKey *spk;
|
||||
struct TEAH_AuditorInteractionEntry *aie;
|
||||
struct TALER_Amount amount_without_fee;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
|
||||
if (0 !=
|
||||
GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
dh->auditor_chance))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Not providing deposit confirmation to auditor\n");
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Will provide deposit confirmation to auditor `%s'\n",
|
||||
TALER_B2S (auditor_pub));
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
&dh->cdd.h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
spk = TALER_EXCHANGE_get_signing_key_info (key_state,
|
||||
&dh->exchange_pub);
|
||||
if (NULL == spk)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_assert (0 <=
|
||||
TALER_amount_subtract (&amount_without_fee,
|
||||
&dh->cdd.amount,
|
||||
&dki->fees.deposit));
|
||||
aie = GNUNET_new (struct TEAH_AuditorInteractionEntry);
|
||||
aie->dch = TALER_AUDITOR_deposit_confirmation (
|
||||
ah,
|
||||
&dh->h_wire,
|
||||
&dh->h_policy,
|
||||
&dh->dcd.h_contract_terms,
|
||||
dh->exchange_timestamp,
|
||||
dh->dcd.wire_deadline,
|
||||
dh->dcd.refund_deadline,
|
||||
&amount_without_fee,
|
||||
&dh->cdd.coin_pub,
|
||||
&dh->dcd.merchant_pub,
|
||||
&dh->exchange_pub,
|
||||
&dh->exchange_sig,
|
||||
&key_state->master_pub,
|
||||
spk->valid_from,
|
||||
spk->valid_until,
|
||||
spk->valid_legal,
|
||||
&spk->master_sig,
|
||||
&TEAH_acc_confirmation_cb,
|
||||
aie);
|
||||
return aie;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called when we're done processing the
|
||||
* HTTP /deposit request.
|
||||
*
|
||||
* @param cls the `struct TALER_EXCHANGE_DepositHandle`
|
||||
* @param response_code HTTP response code, 0 on error
|
||||
* @param response parsed JSON result, NULL on error
|
||||
*/
|
||||
static void
|
||||
handle_deposit_finished (void *cls,
|
||||
long response_code,
|
||||
const void *response)
|
||||
{
|
||||
struct TALER_EXCHANGE_DepositHandle *dh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_DepositResult dr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
dh->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&dh->exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&dh->exchange_pub),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_string ("transaction_base_url",
|
||||
&dr.details.ok.transaction_base_url),
|
||||
NULL),
|
||||
GNUNET_JSON_spec_timestamp ("exchange_timestamp",
|
||||
&dh->exchange_timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_Amount amount_without_fee;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
&dh->cdd.h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&dh->exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
GNUNET_assert (0 <=
|
||||
TALER_amount_subtract (&amount_without_fee,
|
||||
&dh->cdd.amount,
|
||||
&dki->fees.deposit));
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_exchange_online_deposit_confirmation_verify (
|
||||
&dh->dcd.h_contract_terms,
|
||||
&dh->h_wire,
|
||||
&dh->h_policy,
|
||||
dh->exchange_timestamp,
|
||||
dh->dcd.wire_deadline,
|
||||
dh->dcd.refund_deadline,
|
||||
&amount_without_fee,
|
||||
&dh->cdd.coin_pub,
|
||||
&dh->dcd.merchant_pub,
|
||||
&dh->exchange_pub,
|
||||
&dh->exchange_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
|
||||
break;
|
||||
}
|
||||
|
||||
TEAH_get_auditors_for_dc (dh->exchange,
|
||||
&auditor_cb,
|
||||
dh);
|
||||
}
|
||||
dr.details.ok.exchange_sig = &dh->exchange_sig;
|
||||
dr.details.ok.exchange_pub = &dh->exchange_pub;
|
||||
dr.details.ok.deposit_timestamp = dh->exchange_timestamp;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_FORBIDDEN:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Nothing really to verify, exchange says one of the signatures is
|
||||
invalid; as we checked them, this should never happen, we
|
||||
should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Nothing really to verify, this should never
|
||||
happen, we should pass the JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
|
||||
key_state = TALER_EXCHANGE_get_keys (dh->exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
&dh->cdd.h_denom_pub);
|
||||
GNUNET_assert (NULL != dki);
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_coin_conflict_ (
|
||||
keys,
|
||||
j,
|
||||
dki,
|
||||
&dh->cdd.coin_pub,
|
||||
&dh->cdd.coin_sig,
|
||||
&dh->cdd.amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
dr.hr.http_status = 0;
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
/* could happen if denomination was revoked */
|
||||
/* Note: one might want to check /keys for revocation
|
||||
signature here, alas tricky in case our /keys
|
||||
is outdated => left to clients */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
dr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
dr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange deposit\n",
|
||||
(unsigned int) response_code,
|
||||
dr.hr.ec);
|
||||
GNUNET_break_op (0);
|
||||
break;
|
||||
}
|
||||
dh->cb (dh->cb_cls,
|
||||
&dr);
|
||||
TALER_EXCHANGE_deposit_cancel (dh);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_DepositHandle *
|
||||
TALER_EXCHANGE_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const struct TALER_EXCHANGE_DepositContractDetail *dcd,
|
||||
const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
|
||||
TALER_EXCHANGE_DepositResultCallback cb,
|
||||
void *cb_cls,
|
||||
enum TALER_ErrorCode *ec)
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct TALER_EXCHANGE_DepositHandle *dh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *deposit_obj;
|
||||
CURL *eh;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dki;
|
||||
struct TALER_Amount amount_without_fee;
|
||||
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
if (GNUNET_TIME_timestamp_cmp (dcd->refund_deadline,
|
||||
>,
|
||||
dcd->wire_deadline))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
*ec = TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE;
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||
char *end;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
&cdd->coin_pub,
|
||||
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/deposit",
|
||||
pub_str);
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (exchange);
|
||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||
&cdd->h_denom_pub);
|
||||
if (NULL == dki)
|
||||
{
|
||||
*ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
|
||||
GNUNET_break_op (0);
|
||||
return NULL;
|
||||
}
|
||||
if (0 >
|
||||
TALER_amount_subtract (&amount_without_fee,
|
||||
&cdd->amount,
|
||||
&dki->fees.deposit))
|
||||
{
|
||||
*ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT;
|
||||
GNUNET_break_op (0);
|
||||
return NULL;
|
||||
}
|
||||
dh = GNUNET_new (struct TALER_EXCHANGE_DepositHandle);
|
||||
dh->auditor_chance = AUDITOR_CHANCE;
|
||||
dh->exchange = exchange;
|
||||
dh->cb = cb;
|
||||
dh->cb_cls = cb_cls;
|
||||
dh->cdd = *cdd;
|
||||
dh->dcd = *dcd;
|
||||
if (NULL != dcd->policy_details)
|
||||
TALER_deposit_policy_hash (dcd->policy_details,
|
||||
&dh->h_policy);
|
||||
TALER_merchant_wire_signature_hash (dcd->merchant_payto_uri,
|
||||
&dcd->wire_salt,
|
||||
&dh->h_wire);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_verify_deposit_signature_ (dcd,
|
||||
&dh->h_policy,
|
||||
&dh->h_wire,
|
||||
cdd,
|
||||
dki))
|
||||
{
|
||||
*ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID;
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_free (dh);
|
||||
return NULL;
|
||||
}
|
||||
dh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
if (NULL == dh->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*ec = TALER_EC_GENERIC_ALLOCATION_FAILURE;
|
||||
GNUNET_free (dh->url);
|
||||
GNUNET_free (dh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
deposit_obj = GNUNET_JSON_PACK (
|
||||
TALER_JSON_pack_amount ("contribution",
|
||||
&cdd->amount),
|
||||
GNUNET_JSON_pack_string ("merchant_payto_uri",
|
||||
dcd->merchant_payto_uri),
|
||||
GNUNET_JSON_pack_data_auto ("wire_salt",
|
||||
&dcd->wire_salt),
|
||||
GNUNET_JSON_pack_data_auto ("h_contract_terms",
|
||||
&dcd->h_contract_terms),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_data_auto ("h_age_commitment",
|
||||
&cdd->h_age_commitment)),
|
||||
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
|
||||
&cdd->h_denom_pub),
|
||||
TALER_JSON_pack_denom_sig ("ub_sig",
|
||||
&cdd->denom_sig),
|
||||
GNUNET_JSON_pack_timestamp ("timestamp",
|
||||
dcd->timestamp),
|
||||
GNUNET_JSON_pack_data_auto ("merchant_pub",
|
||||
&dcd->merchant_pub),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_timestamp ("refund_deadline",
|
||||
dcd->refund_deadline)),
|
||||
GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
|
||||
dcd->wire_deadline),
|
||||
GNUNET_JSON_pack_data_auto ("coin_sig",
|
||||
&cdd->coin_sig));
|
||||
GNUNET_assert (NULL != deposit_obj);
|
||||
eh = TALER_EXCHANGE_curl_easy_get_ (dh->url);
|
||||
if ( (NULL == eh) ||
|
||||
(GNUNET_OK !=
|
||||
TALER_curl_easy_post (&dh->ctx,
|
||||
eh,
|
||||
deposit_obj)) )
|
||||
{
|
||||
*ec = TALER_EC_GENERIC_CURL_ALLOCATION_FAILURE;
|
||||
GNUNET_break (0);
|
||||
if (NULL != eh)
|
||||
curl_easy_cleanup (eh);
|
||||
json_decref (deposit_obj);
|
||||
GNUNET_free (dh->url);
|
||||
GNUNET_free (dh);
|
||||
return NULL;
|
||||
}
|
||||
json_decref (deposit_obj);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for deposit: `%s'\n",
|
||||
dh->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
dh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
dh->ctx.headers,
|
||||
&handle_deposit_finished,
|
||||
dh);
|
||||
return dh;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit)
|
||||
{
|
||||
deposit->auditor_chance = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit)
|
||||
{
|
||||
if (NULL != deposit->job)
|
||||
{
|
||||
GNUNET_CURL_job_cancel (deposit->job);
|
||||
deposit->job = NULL;
|
||||
}
|
||||
GNUNET_free (deposit->url);
|
||||
TALER_curl_easy_post_finished (&deposit->ctx);
|
||||
GNUNET_free (deposit);
|
||||
}
|
||||
|
||||
|
||||
/* end of exchange_api_deposit.c */
|
@ -39,9 +39,9 @@ struct TALER_EXCHANGE_DepositGetHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -131,7 +131,7 @@ handle_deposit_wtid_finished (void *cls,
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
|
||||
key_state = TALER_EXCHANGE_get_keys (dwh->exchange);
|
||||
key_state = dwh->keys;
|
||||
GNUNET_assert (NULL != key_state);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
@ -255,7 +255,9 @@ handle_deposit_wtid_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_DepositGetHandle *
|
||||
TALER_EXCHANGE_deposits_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv,
|
||||
const struct TALER_MerchantWireHashP *h_wire,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
@ -267,7 +269,6 @@ TALER_EXCHANGE_deposits_get (
|
||||
struct TALER_MerchantPublicKeyP merchant;
|
||||
struct TALER_MerchantSignatureP merchant_sig;
|
||||
struct TALER_EXCHANGE_DepositGetHandle *dwh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[(sizeof (struct TALER_CoinSpendPublicKeyP)
|
||||
+ sizeof (struct TALER_MerchantWireHashP)
|
||||
@ -275,12 +276,6 @@ TALER_EXCHANGE_deposits_get (
|
||||
+ sizeof (struct TALER_PrivateContractHashP)
|
||||
+ sizeof (struct TALER_MerchantSignatureP)) * 2 + 48];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv->eddsa_priv,
|
||||
&merchant.eddsa_pub);
|
||||
TALER_merchant_deposit_sign (h_contract_terms,
|
||||
@ -339,7 +334,7 @@ TALER_EXCHANGE_deposits_get (
|
||||
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/deposits/%s/%s/%s/%s?merchant_sig=%s%s%s",
|
||||
"deposits/%s/%s/%s/%s?merchant_sig=%s%s%s",
|
||||
whash_str,
|
||||
mpub_str,
|
||||
chash_str,
|
||||
@ -352,11 +347,11 @@ TALER_EXCHANGE_deposits_get (
|
||||
}
|
||||
|
||||
dwh = GNUNET_new (struct TALER_EXCHANGE_DepositGetHandle);
|
||||
dwh->exchange = exchange;
|
||||
dwh->cb = cb;
|
||||
dwh->cb_cls = cb_cls;
|
||||
dwh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
dwh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == dwh->url)
|
||||
{
|
||||
GNUNET_free (dwh);
|
||||
@ -365,7 +360,6 @@ TALER_EXCHANGE_deposits_get (
|
||||
dwh->h_wire = *h_wire;
|
||||
dwh->h_contract_terms = *h_contract_terms;
|
||||
dwh->coin_pub = *coin_pub;
|
||||
|
||||
eh = TALER_EXCHANGE_curl_easy_get_ (dwh->url);
|
||||
if (NULL == eh)
|
||||
{
|
||||
@ -374,11 +368,11 @@ TALER_EXCHANGE_deposits_get (
|
||||
GNUNET_free (dwh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
dwh->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_deposit_wtid_finished,
|
||||
dwh);
|
||||
dwh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
return dwh;
|
||||
}
|
||||
|
||||
@ -393,6 +387,7 @@ TALER_EXCHANGE_deposits_get_cancel (struct TALER_EXCHANGE_DepositGetHandle *dwh)
|
||||
}
|
||||
GNUNET_free (dwh->url);
|
||||
TALER_curl_easy_post_finished (&dwh->ctx);
|
||||
TALER_EXCHANGE_keys_decref (dwh->keys);
|
||||
GNUNET_free (dwh);
|
||||
}
|
||||
|
||||
|
@ -110,17 +110,7 @@ struct TEAH_AuditorListEntry
|
||||
/**
|
||||
* Handle to the auditor.
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle *ah;
|
||||
|
||||
/**
|
||||
* Head of DLL of interactions with this auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *ai_head;
|
||||
|
||||
/**
|
||||
* Tail of DLL of interactions with this auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *ai_tail;
|
||||
struct TALER_AUDITOR_GetConfigHandle *ah;
|
||||
|
||||
/**
|
||||
* Public key of the auditor.
|
||||
@ -168,57 +158,24 @@ struct KeysRequest
|
||||
|
||||
|
||||
void
|
||||
TEAH_acc_confirmation_cb (void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr)
|
||||
{
|
||||
struct TEAH_AuditorInteractionEntry *aie = cls;
|
||||
struct TEAH_AuditorListEntry *ale = aie->ale;
|
||||
|
||||
if (MHD_HTTP_OK != hr->http_status)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to submit deposit confirmation to auditor `%s' with HTTP status %d (EC: %d). This is acceptable if it does not happen often.\n",
|
||||
ale->auditor_url,
|
||||
hr->http_status,
|
||||
hr->ec);
|
||||
}
|
||||
GNUNET_CONTAINER_DLL_remove (ale->ai_head,
|
||||
ale->ai_tail,
|
||||
aie);
|
||||
GNUNET_free (aie);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Handle *h,
|
||||
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Keys *keys,
|
||||
TEAH_AuditorCallback ac,
|
||||
void *ac_cls)
|
||||
{
|
||||
if (NULL == h->auditors_head)
|
||||
if (0 == keys->num_auditors)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"No auditor available for exchange `%s'. Not submitting deposit confirmations.\n",
|
||||
h->url);
|
||||
"No auditor available. Not submitting deposit confirmations.\n");
|
||||
return;
|
||||
}
|
||||
for (struct TEAH_AuditorListEntry *ale = h->auditors_head;
|
||||
NULL != ale;
|
||||
ale = ale->next)
|
||||
for (unsigned int i = 0; i<keys->num_auditors; i++)
|
||||
{
|
||||
struct TEAH_AuditorInteractionEntry *aie;
|
||||
const struct TALER_EXCHANGE_AuditorInformation *auditor
|
||||
= &keys->auditors[i];
|
||||
|
||||
if (! ale->is_up)
|
||||
continue;
|
||||
aie = ac (ac_cls,
|
||||
ale->ah,
|
||||
&ale->auditor_pub);
|
||||
if (NULL != aie)
|
||||
{
|
||||
aie->ale = ale;
|
||||
GNUNET_CONTAINER_DLL_insert (ale->ai_head,
|
||||
ale->ai_tail,
|
||||
aie);
|
||||
}
|
||||
ac (ac_cls,
|
||||
auditor->auditor_url,
|
||||
&auditor->auditor_pub);
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,21 +536,18 @@ parse_global_fee (struct TALER_EXCHANGE_GlobalFee *gf,
|
||||
* auditor as 'up'.
|
||||
*
|
||||
* @param cls closure, a `struct TEAH_AuditorListEntry *`
|
||||
* @param hr http response from the auditor
|
||||
* @param vi basic information about the auditor
|
||||
* @param compat protocol compatibility information
|
||||
* @param vr response from the auditor
|
||||
*/
|
||||
static void
|
||||
auditor_version_cb (
|
||||
auditor_config_cb (
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
const struct TALER_AUDITOR_VersionInformation *vi,
|
||||
enum TALER_AUDITOR_VersionCompatibility compat)
|
||||
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||
{
|
||||
struct TEAH_AuditorListEntry *ale = cls;
|
||||
enum TALER_AUDITOR_VersionCompatibility compat;
|
||||
|
||||
(void) hr;
|
||||
if (NULL == vi)
|
||||
ale->ah = NULL;
|
||||
if (MHD_HTTP_OK != vr->hr.http_status)
|
||||
{
|
||||
/* In this case, we don't mark the auditor as 'up' */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
@ -601,7 +555,7 @@ auditor_version_cb (
|
||||
ale->auditor_url);
|
||||
return;
|
||||
}
|
||||
|
||||
compat = vr->details.ok.compat;
|
||||
if (0 != (TALER_AUDITOR_VC_INCOMPATIBLE & compat))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
@ -667,9 +621,9 @@ update_auditors (struct TALER_EXCHANGE_Handle *exchange)
|
||||
GNUNET_CONTAINER_DLL_insert (exchange->auditors_head,
|
||||
exchange->auditors_tail,
|
||||
ale);
|
||||
ale->ah = TALER_AUDITOR_connect (exchange->ctx,
|
||||
ale->ah = TALER_AUDITOR_get_config (exchange->ctx,
|
||||
ale->auditor_url,
|
||||
&auditor_version_cb,
|
||||
&auditor_config_cb,
|
||||
ale);
|
||||
}
|
||||
}
|
||||
@ -2123,26 +2077,14 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange)
|
||||
|
||||
while (NULL != (ale = exchange->auditors_head))
|
||||
{
|
||||
struct TEAH_AuditorInteractionEntry *aie;
|
||||
|
||||
while (NULL != (aie = ale->ai_head))
|
||||
{
|
||||
GNUNET_assert (aie->ale == ale);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Not sending deposit confirmation to auditor `%s' due to exchange disconnect\n",
|
||||
ale->auditor_url);
|
||||
TALER_AUDITOR_deposit_confirmation_cancel (aie->dch);
|
||||
GNUNET_CONTAINER_DLL_remove (ale->ai_head,
|
||||
ale->ai_tail,
|
||||
aie);
|
||||
GNUNET_free (aie);
|
||||
}
|
||||
GNUNET_CONTAINER_DLL_remove (exchange->auditors_head,
|
||||
exchange->auditors_tail,
|
||||
ale);
|
||||
TALER_LOG_DEBUG ("Disconnecting the auditor `%s'\n",
|
||||
ale->auditor_url);
|
||||
TALER_AUDITOR_disconnect (ale->ah);
|
||||
if (NULL != ale->ah)
|
||||
{
|
||||
TALER_AUDITOR_get_config_cancel (ale->ah);
|
||||
ale->ah = NULL;
|
||||
}
|
||||
GNUNET_free (ale->auditor_url);
|
||||
GNUNET_free (ale);
|
||||
}
|
||||
@ -2275,7 +2217,7 @@ TALER_EXCHANGE_get_denomination_key_by_hash (
|
||||
}
|
||||
|
||||
|
||||
const struct TALER_EXCHANGE_Keys *
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange)
|
||||
{
|
||||
(void) TALER_EXCHANGE_check_keys_current (exchange,
|
||||
@ -2297,4 +2239,33 @@ TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the exchange in the raw JSON format.
|
||||
*
|
||||
* @param keys the keys structure
|
||||
* @return the keys in raw JSON
|
||||
*/
|
||||
json_t *
|
||||
TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys)
|
||||
{
|
||||
// FIXME!
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_EXCHANGE_keys_incref (struct TALER_EXCHANGE_Keys *keys)
|
||||
{
|
||||
// FIXME
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
/* end of exchange_api_handle.c */
|
||||
|
@ -34,32 +34,6 @@
|
||||
struct TEAH_AuditorListEntry;
|
||||
|
||||
|
||||
/**
|
||||
* Entry in list of ongoing interactions with an auditor.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry
|
||||
{
|
||||
/**
|
||||
* DLL entry.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *next;
|
||||
|
||||
/**
|
||||
* DLL entry.
|
||||
*/
|
||||
struct TEAH_AuditorInteractionEntry *prev;
|
||||
|
||||
/**
|
||||
* Which auditor is this action associated with?
|
||||
*/
|
||||
struct TEAH_AuditorListEntry *ale;
|
||||
|
||||
/**
|
||||
* Interaction state.
|
||||
*/
|
||||
struct TALER_AUDITOR_DepositConfirmationHandle *dch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stages of initialization for the `struct TALER_EXCHANGE_Handle`
|
||||
*/
|
||||
@ -178,39 +152,26 @@ struct TALER_EXCHANGE_Handle
|
||||
* launch a deposit confirmation interaction.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param ah handle to the auditor
|
||||
* @param auditor_url base URL of the auditor
|
||||
* @param auditor_pub public key of the auditor
|
||||
* @return NULL if no deposit confirmation interaction was launched
|
||||
*/
|
||||
typedef struct TEAH_AuditorInteractionEntry *
|
||||
typedef void
|
||||
(*TEAH_AuditorCallback)(void *cls,
|
||||
struct TALER_AUDITOR_Handle *ah,
|
||||
const char *auditor_url,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub);
|
||||
|
||||
|
||||
/**
|
||||
* Signature of functions called with the result from our call to the
|
||||
* auditor's /deposit-confirmation handler.
|
||||
*
|
||||
* @param cls closure of type `struct TEAH_AuditorInteractionEntry *`
|
||||
* @param hr HTTP response
|
||||
*/
|
||||
void
|
||||
TEAH_acc_confirmation_cb (void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr);
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all available auditors for @a h, calling
|
||||
* @a ac and giving it a chance to start a deposit
|
||||
* confirmation interaction.
|
||||
*
|
||||
* @param h exchange to go over auditors for
|
||||
* @param keys the keys to go over auditors for
|
||||
* @param ac function to call per auditor
|
||||
* @param ac_cls closure for @a ac
|
||||
*/
|
||||
void
|
||||
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Handle *h,
|
||||
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Keys *keys,
|
||||
TEAH_AuditorCallback ac,
|
||||
void *ac_cls);
|
||||
|
||||
|
@ -36,11 +36,6 @@
|
||||
struct TALER_EXCHANGE_KycProofHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -140,7 +135,9 @@ handle_kyc_proof_finished (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_KycProofHandle *
|
||||
TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_kyc_proof (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_PaytoHashP *h_payto,
|
||||
const char *logic,
|
||||
const char *args,
|
||||
@ -148,19 +145,12 @@ TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_KycProofHandle *kph;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
char *arg_str;
|
||||
|
||||
if (NULL == args)
|
||||
args = "";
|
||||
else
|
||||
GNUNET_assert (args[0] == '&');
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char hstr[sizeof (struct TALER_PaytoHashP) * 2];
|
||||
char *end;
|
||||
@ -171,17 +161,17 @@ TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
|
||||
sizeof (hstr));
|
||||
*end = '\0';
|
||||
GNUNET_asprintf (&arg_str,
|
||||
"/kyc-proof/%s?state=%s%s",
|
||||
"kyc-proof/%s?state=%s%s",
|
||||
logic,
|
||||
hstr,
|
||||
args);
|
||||
}
|
||||
kph = GNUNET_new (struct TALER_EXCHANGE_KycProofHandle);
|
||||
kph->exchange = exchange;
|
||||
kph->cb = cb;
|
||||
kph->cb_cls = cb_cls;
|
||||
kph->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
kph->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
GNUNET_free (arg_str);
|
||||
if (NULL == kph->url)
|
||||
{
|
||||
@ -202,7 +192,6 @@ TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *exchange,
|
||||
curl_easy_setopt (kph->eh,
|
||||
CURLOPT_FOLLOWLOCATION,
|
||||
0L));
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
kph->job = GNUNET_CURL_job_add_raw (ctx,
|
||||
kph->eh,
|
||||
NULL,
|
||||
|
@ -42,11 +42,6 @@ struct TALER_EXCHANGE_KycWalletHandle
|
||||
*/
|
||||
struct TALER_CURL_PostContext ctx;
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -154,7 +149,9 @@ handle_kyc_wallet_finished (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_KycWalletHandle *
|
||||
TALER_EXCHANGE_kyc_wallet (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_kyc_wallet (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_Amount *balance,
|
||||
TALER_EXCHANGE_KycWalletCallback cb,
|
||||
@ -163,7 +160,6 @@ TALER_EXCHANGE_kyc_wallet (struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct TALER_EXCHANGE_KycWalletHandle *kwh;
|
||||
CURL *eh;
|
||||
json_t *req;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
|
||||
@ -181,18 +177,17 @@ TALER_EXCHANGE_kyc_wallet (struct TALER_EXCHANGE_Handle *exchange,
|
||||
&reserve_sig));
|
||||
GNUNET_assert (NULL != req);
|
||||
kwh = GNUNET_new (struct TALER_EXCHANGE_KycWalletHandle);
|
||||
kwh->exchange = exchange;
|
||||
kwh->cb = cb;
|
||||
kwh->cb_cls = cb_cls;
|
||||
kwh->url = TEAH_path_to_url (exchange,
|
||||
"/kyc-wallet");
|
||||
kwh->url = TALER_url_join (url,
|
||||
"kyc-wallet",
|
||||
NULL);
|
||||
if (NULL == kwh->url)
|
||||
{
|
||||
json_decref (req);
|
||||
GNUNET_free (kwh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
eh = TALER_EXCHANGE_curl_easy_get_ (kwh->url);
|
||||
if ( (NULL == eh) ||
|
||||
(GNUNET_OK !=
|
||||
|
@ -36,11 +36,6 @@
|
||||
struct TALER_EXCHANGE_LinkHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -451,26 +446,19 @@ handle_link_finished (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_LinkHandle *
|
||||
TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_link (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
const struct
|
||||
TALER_AgeCommitmentProof *age_commitment_proof,
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof,
|
||||
TALER_EXCHANGE_LinkCallback link_cb,
|
||||
void *link_cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_LinkHandle *lh;
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
||||
&coin_pub.eddsa_pub);
|
||||
{
|
||||
@ -485,17 +473,17 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/link",
|
||||
"coins/%s/link",
|
||||
pub_str);
|
||||
}
|
||||
lh = GNUNET_new (struct TALER_EXCHANGE_LinkHandle);
|
||||
lh->exchange = exchange;
|
||||
lh->link_cb = link_cb;
|
||||
lh->link_cb_cls = link_cb_cls;
|
||||
lh->coin_priv = *coin_priv;
|
||||
lh->age_commitment_proof = age_commitment_proof;
|
||||
lh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
lh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == lh->url)
|
||||
{
|
||||
GNUNET_free (lh);
|
||||
@ -509,7 +497,6 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_free (lh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
lh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
||||
eh,
|
||||
&handle_link_finished,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2015-2022 Taler Systems SA
|
||||
Copyright (C) 2015-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -41,15 +41,25 @@ struct TALER_EXCHANGE_MeltHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* The exchange base url.
|
||||
*/
|
||||
char *exchange_url;
|
||||
|
||||
/**
|
||||
* Curl context.
|
||||
*/
|
||||
struct GNUNET_CURL_Context *cctx;
|
||||
|
||||
/**
|
||||
* Context for #TEH_curl_easy_post(). Keeps the data that must
|
||||
* persist for Curl to make the upload.
|
||||
@ -159,7 +169,7 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* check that exchange signing key is permitted */
|
||||
key_state = TALER_EXCHANGE_get_keys (mh->exchange);
|
||||
key_state = mh->keys;
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
exchange_pub))
|
||||
@ -211,7 +221,7 @@ handle_melt_finished (void *cls,
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
mh->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (mh->exchange);
|
||||
keys = mh->keys;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -309,7 +319,6 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
json_t *melt_obj;
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
|
||||
struct TALER_DenominationHashP h_denom_pub;
|
||||
struct TALER_ExchangeWithdrawValues alg_values[mh->rd->fresh_pks_len];
|
||||
@ -371,19 +380,19 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/melt",
|
||||
"coins/%s/melt",
|
||||
pub_str);
|
||||
}
|
||||
|
||||
ctx = TEAH_handle_to_context (mh->exchange);
|
||||
key_state = TALER_EXCHANGE_get_keys (mh->exchange);
|
||||
key_state = mh->keys;
|
||||
mh->dki = TALER_EXCHANGE_get_denomination_key (key_state,
|
||||
&mh->md.melted_coin.pub_key);
|
||||
|
||||
/* and now we can at last begin the actual request handling */
|
||||
|
||||
mh->url = TEAH_path_to_url (mh->exchange,
|
||||
arg_str);
|
||||
mh->url = TALER_url_join (mh->exchange_url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == mh->url)
|
||||
{
|
||||
json_decref (melt_obj);
|
||||
@ -403,7 +412,7 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
json_decref (melt_obj);
|
||||
mh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
mh->job = GNUNET_CURL_job_add2 (mh->cctx,
|
||||
eh,
|
||||
mh->ctx.headers,
|
||||
&handle_melt_finished,
|
||||
@ -496,7 +505,10 @@ csr_cb (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_MeltHandle *
|
||||
TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_melt (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||
TALER_EXCHANGE_MeltCallback melt_cb,
|
||||
@ -511,11 +523,10 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle);
|
||||
mh->noreveal_index = TALER_CNC_KAPPA; /* invalid value */
|
||||
mh->exchange = exchange;
|
||||
mh->cctx = ctx;
|
||||
mh->exchange_url = GNUNET_strdup (url);
|
||||
mh->rd = rd;
|
||||
mh->rms = *rms;
|
||||
mh->melt_cb = melt_cb;
|
||||
@ -545,9 +556,11 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
|
||||
break;
|
||||
}
|
||||
}
|
||||
mh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
if (0 != nks_off)
|
||||
{
|
||||
mh->csr = TALER_EXCHANGE_csr_melt (exchange,
|
||||
mh->csr = TALER_EXCHANGE_csr_melt (ctx,
|
||||
url,
|
||||
rms,
|
||||
nks_off,
|
||||
nks,
|
||||
@ -588,7 +601,9 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
TALER_EXCHANGE_free_melt_data_ (&mh->md); /* does not free 'md' itself */
|
||||
GNUNET_free (mh->mbds);
|
||||
GNUNET_free (mh->url);
|
||||
GNUNET_free (mh->exchange_url);
|
||||
TALER_curl_easy_post_finished (&mh->ctx);
|
||||
TALER_EXCHANGE_keys_decref (mh->keys);
|
||||
GNUNET_free (mh);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -73,15 +73,20 @@ struct TALER_EXCHANGE_PurseCreateDepositHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* The base URL of the exchange.
|
||||
*/
|
||||
char *exchange_url;
|
||||
|
||||
/**
|
||||
* Context for #TEH_curl_easy_post(). Keeps the data that must
|
||||
* persist for Curl to make the upload.
|
||||
@ -170,10 +175,9 @@ handle_purse_create_deposit_finished (void *cls,
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_Keys *keys = pch->keys;
|
||||
|
||||
pch->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (pch->exchange);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -181,7 +185,6 @@ handle_purse_create_deposit_finished (void *cls,
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct GNUNET_TIME_Timestamp etime;
|
||||
struct TALER_Amount total_deposited;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
@ -209,9 +212,8 @@ handle_purse_create_deposit_finished (void *cls,
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (pch->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (keys,
|
||||
&exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -387,7 +389,7 @@ handle_purse_create_deposit_finished (void *cls,
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_purse_coin_conflict_ (
|
||||
&pch->purse_pub,
|
||||
pch->exchange->url,
|
||||
pch->exchange_url,
|
||||
j,
|
||||
&h_denom_pub,
|
||||
&phac,
|
||||
@ -496,7 +498,9 @@ handle_purse_create_deposit_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_PurseCreateDepositHandle *
|
||||
TALER_EXCHANGE_purse_create_with_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
const struct TALER_PurseMergePrivateKeyP *merge_priv,
|
||||
const struct TALER_ContractDiffiePrivateP *contract_priv,
|
||||
@ -508,16 +512,13 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_PurseCreateDepositHandle *pch;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *create_obj;
|
||||
json_t *deposit_arr;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (pch->purse_pub) * 2 + 32];
|
||||
char *url;
|
||||
uint32_t min_age = 0;
|
||||
|
||||
pch = GNUNET_new (struct TALER_EXCHANGE_PurseCreateDepositHandle);
|
||||
pch->exchange = exchange;
|
||||
pch->cb = cb;
|
||||
pch->cb_cls = cb_cls;
|
||||
{
|
||||
@ -542,8 +543,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
if (GNUNET_OK !=
|
||||
TALER_JSON_contract_hash (contract_terms,
|
||||
&pch->h_contract_terms))
|
||||
@ -565,13 +564,14 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s/create",
|
||||
"purses/%s/create",
|
||||
pub_str);
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv,
|
||||
&pch->merge_pub.eddsa_pub);
|
||||
pch->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pch->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pch->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -583,8 +583,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
struct Deposit);
|
||||
deposit_arr = json_array ();
|
||||
GNUNET_assert (NULL != deposit_arr);
|
||||
url = TEAH_path_to_url (exchange,
|
||||
"/");
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Signing with URL `%s'\n",
|
||||
url);
|
||||
@ -610,7 +608,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
{
|
||||
GNUNET_break (0);
|
||||
json_decref (deposit_arr);
|
||||
GNUNET_free (url);
|
||||
GNUNET_free (pch);
|
||||
return NULL;
|
||||
}
|
||||
@ -648,7 +645,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
json_array_append_new (deposit_arr,
|
||||
jdeposit));
|
||||
}
|
||||
GNUNET_free (url);
|
||||
TALER_wallet_purse_create_sign (pch->purse_expiration,
|
||||
&pch->h_contract_terms,
|
||||
&pch->merge_pub,
|
||||
@ -714,7 +710,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for purse create with deposit: `%s'\n",
|
||||
pch->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
pch->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
pch->exchange_url = GNUNET_strdup (url);
|
||||
pch->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
pch->ctx.headers,
|
||||
@ -734,8 +731,10 @@ TALER_EXCHANGE_purse_create_with_deposit_cancel (
|
||||
pch->job = NULL;
|
||||
}
|
||||
GNUNET_free (pch->econtract.econtract);
|
||||
GNUNET_free (pch->exchange_url);
|
||||
GNUNET_free (pch->url);
|
||||
GNUNET_free (pch->deposits);
|
||||
TALER_EXCHANGE_keys_decref (pch->keys);
|
||||
TALER_curl_easy_post_finished (&pch->ctx);
|
||||
GNUNET_free (pch);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -41,15 +41,20 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* The exchange base URL.
|
||||
*/
|
||||
char *exchange_url;
|
||||
|
||||
/**
|
||||
* Context for #TEH_curl_easy_post(). Keeps the data that must
|
||||
* persist for Curl to make the upload.
|
||||
@ -157,7 +162,6 @@ handle_purse_create_with_merge_finished (void *cls,
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct GNUNET_TIME_Timestamp etime;
|
||||
struct TALER_Amount total_deposited;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
@ -184,9 +188,8 @@ handle_purse_create_with_merge_finished (void *cls,
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (pcm->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (pcm->keys,
|
||||
&exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -253,7 +256,7 @@ handle_purse_create_with_merge_finished (void *cls,
|
||||
&pcm->merge_sig,
|
||||
&pcm->merge_pub,
|
||||
&pcm->purse_pub,
|
||||
pcm->exchange->url,
|
||||
pcm->exchange_url,
|
||||
j))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -340,7 +343,9 @@ handle_purse_create_with_merge_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_PurseCreateMergeHandle *
|
||||
TALER_EXCHANGE_purse_create_with_merge (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
const struct TALER_PurseMergePrivateKeyP *merge_priv,
|
||||
@ -353,7 +358,6 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_PurseCreateMergeHandle *pcm;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *create_with_merge_obj;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (pcm->reserve_pub) * 2 + 32];
|
||||
@ -362,7 +366,6 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
enum TALER_WalletAccountMergeFlags flags;
|
||||
|
||||
pcm = GNUNET_new (struct TALER_EXCHANGE_PurseCreateMergeHandle);
|
||||
pcm->exchange = exchange;
|
||||
pcm->cb = cb;
|
||||
pcm->cb_cls = cb_cls;
|
||||
if (GNUNET_OK !=
|
||||
@ -409,7 +412,7 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
const struct TALER_EXCHANGE_GlobalFee *gf;
|
||||
|
||||
gf = TALER_EXCHANGE_get_global_fee (
|
||||
TALER_EXCHANGE_get_keys (exchange),
|
||||
keys,
|
||||
GNUNET_TIME_timestamp_get ());
|
||||
purse_fee = gf->fees.purse;
|
||||
flags = TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE;
|
||||
@ -422,8 +425,6 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
flags = TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA;
|
||||
}
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
{
|
||||
char pub_str[sizeof (pcm->reserve_pub) * 2];
|
||||
char *end;
|
||||
@ -436,11 +437,12 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s/purse",
|
||||
"reserves/%s/purse",
|
||||
pub_str);
|
||||
}
|
||||
pcm->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pcm->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pcm->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -457,7 +459,7 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
{
|
||||
char *payto_uri;
|
||||
|
||||
payto_uri = TALER_reserve_make_payto (exchange->url,
|
||||
payto_uri = TALER_reserve_make_payto (url,
|
||||
&pcm->reserve_pub);
|
||||
TALER_wallet_purse_merge_sign (payto_uri,
|
||||
merge_timestamp,
|
||||
@ -546,7 +548,8 @@ TALER_EXCHANGE_purse_create_with_merge (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for purse create_with_merge: `%s'\n",
|
||||
pcm->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
pcm->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
pcm->exchange_url = GNUNET_strdup (url);
|
||||
pcm->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
pcm->ctx.headers,
|
||||
@ -566,7 +569,9 @@ TALER_EXCHANGE_purse_create_with_merge_cancel (
|
||||
pcm->job = NULL;
|
||||
}
|
||||
GNUNET_free (pcm->url);
|
||||
GNUNET_free (pcm->exchange_url);
|
||||
TALER_curl_easy_post_finished (&pcm->ctx);
|
||||
TALER_EXCHANGE_keys_decref (pcm->keys);
|
||||
GNUNET_free (pcm->econtract.econtract);
|
||||
GNUNET_free (pcm);
|
||||
}
|
||||
|
@ -40,11 +40,6 @@
|
||||
struct TALER_EXCHANGE_PurseDeleteHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -148,26 +143,23 @@ handle_purse_delete_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_PurseDeleteHandle *
|
||||
TALER_EXCHANGE_purse_delete (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv,
|
||||
TALER_EXCHANGE_PurseDeleteCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_PurseDeleteHandle *pdh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||
struct TALER_PurseContractSignatureP purse_sig;
|
||||
char arg_str[sizeof (purse_pub) * 2 + 32];
|
||||
|
||||
pdh = GNUNET_new (struct TALER_EXCHANGE_PurseDeleteHandle);
|
||||
pdh->exchange = exchange;
|
||||
pdh->cb = cb;
|
||||
pdh->cb_cls = cb_cls;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&purse_priv->eddsa_priv,
|
||||
&purse_pub.eddsa_pub);
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
{
|
||||
char pub_str[sizeof (purse_pub) * 2];
|
||||
char *end;
|
||||
@ -179,11 +171,12 @@ TALER_EXCHANGE_purse_delete (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s",
|
||||
"purses/%s",
|
||||
pub_str);
|
||||
}
|
||||
pdh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pdh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pdh->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -223,7 +216,6 @@ TALER_EXCHANGE_purse_delete (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for purse delete: `%s'\n",
|
||||
pdh->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
pdh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
pdh->xhdr,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -73,9 +73,9 @@ struct TALER_EXCHANGE_PurseDepositHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -144,10 +144,9 @@ handle_purse_deposit_finished (void *cls,
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_Keys *keys = pch->keys;
|
||||
|
||||
pch->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (pch->exchange);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -447,7 +446,9 @@ handle_purse_deposit_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_PurseDepositHandle *
|
||||
TALER_EXCHANGE_purse_deposit (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const char *purse_exchange_url,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
uint8_t min_age,
|
||||
@ -457,7 +458,6 @@ TALER_EXCHANGE_purse_deposit (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_PurseDepositHandle *pch;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *create_obj;
|
||||
json_t *deposit_arr;
|
||||
CURL *eh;
|
||||
@ -470,11 +470,8 @@ TALER_EXCHANGE_purse_deposit (
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
pch = GNUNET_new (struct TALER_EXCHANGE_PurseDepositHandle);
|
||||
pch->purse_pub = *purse_pub;
|
||||
pch->exchange = exchange;
|
||||
pch->cb = cb;
|
||||
pch->cb_cls = cb_cls;
|
||||
{
|
||||
@ -489,11 +486,12 @@ TALER_EXCHANGE_purse_deposit (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s/deposit",
|
||||
"purses/%s/deposit",
|
||||
pub_str);
|
||||
}
|
||||
pch->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pch->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pch->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -502,8 +500,7 @@ TALER_EXCHANGE_purse_deposit (
|
||||
}
|
||||
deposit_arr = json_array ();
|
||||
GNUNET_assert (NULL != deposit_arr);
|
||||
pch->base_url = TEAH_path_to_url (exchange,
|
||||
"/");
|
||||
pch->base_url = GNUNET_strdup (url);
|
||||
pch->num_deposits = num_deposits;
|
||||
pch->coins = GNUNET_new_array (num_deposits,
|
||||
struct Coin);
|
||||
@ -594,7 +591,7 @@ TALER_EXCHANGE_purse_deposit (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for purse deposit: `%s'\n",
|
||||
pch->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
pch->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
pch->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
pch->ctx.headers,
|
||||
@ -616,6 +613,7 @@ TALER_EXCHANGE_purse_deposit_cancel (
|
||||
GNUNET_free (pch->base_url);
|
||||
GNUNET_free (pch->url);
|
||||
GNUNET_free (pch->coins);
|
||||
TALER_EXCHANGE_keys_decref (pch->keys);
|
||||
TALER_curl_easy_post_finished (&pch->ctx);
|
||||
GNUNET_free (pch);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -41,9 +41,9 @@ struct TALER_EXCHANGE_AccountMergeHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -148,7 +148,6 @@ handle_purse_merge_finished (void *cls,
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct TALER_Amount total_deposited;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
@ -173,9 +172,8 @@ handle_purse_merge_finished (void *cls,
|
||||
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (pch->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (pch->keys,
|
||||
&dr.details.ok.exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -302,7 +300,9 @@ handle_purse_merge_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_AccountMergeHandle *
|
||||
TALER_EXCHANGE_account_merge (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const char *reserve_exchange_url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
@ -316,14 +316,12 @@ TALER_EXCHANGE_account_merge (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_AccountMergeHandle *pch;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *merge_obj;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (pch->purse_pub) * 2 + 32];
|
||||
char *reserve_url;
|
||||
|
||||
pch = GNUNET_new (struct TALER_EXCHANGE_AccountMergeHandle);
|
||||
pch->exchange = exchange;
|
||||
pch->merge_priv = *merge_priv;
|
||||
pch->cb = cb;
|
||||
pch->cb_cls = cb_cls;
|
||||
@ -332,14 +330,12 @@ TALER_EXCHANGE_account_merge (
|
||||
pch->purse_expiration = purse_expiration;
|
||||
pch->purse_value_after_fees = *purse_value_after_fees;
|
||||
if (NULL == reserve_exchange_url)
|
||||
pch->provider_url = GNUNET_strdup (exchange->url);
|
||||
pch->provider_url = GNUNET_strdup (url);
|
||||
else
|
||||
pch->provider_url = GNUNET_strdup (reserve_exchange_url);
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||
&pch->reserve_pub.eddsa_pub);
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
{
|
||||
char pub_str[sizeof (*purse_pub) * 2];
|
||||
char *end;
|
||||
@ -352,7 +348,7 @@ TALER_EXCHANGE_account_merge (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s/merge",
|
||||
"purses/%s/merge",
|
||||
pub_str);
|
||||
}
|
||||
reserve_url = TALER_reserve_make_payto (pch->provider_url,
|
||||
@ -364,8 +360,9 @@ TALER_EXCHANGE_account_merge (
|
||||
GNUNET_free (pch);
|
||||
return NULL;
|
||||
}
|
||||
pch->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pch->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pch->url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -426,7 +423,7 @@ TALER_EXCHANGE_account_merge (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for purse merge: `%s'\n",
|
||||
pch->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
pch->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
pch->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
pch->ctx.headers,
|
||||
@ -448,6 +445,7 @@ TALER_EXCHANGE_account_merge_cancel (
|
||||
GNUNET_free (pch->url);
|
||||
GNUNET_free (pch->provider_url);
|
||||
TALER_curl_easy_post_finished (&pch->ctx);
|
||||
TALER_EXCHANGE_keys_decref (pch->keys);
|
||||
GNUNET_free (pch);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2022 Taler Systems SA
|
||||
Copyright (C) 2022-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,9 +39,9 @@ struct TALER_EXCHANGE_PurseGetHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -117,7 +117,6 @@ handle_purse_get_finished (void *cls,
|
||||
&exchange_sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
@ -130,9 +129,8 @@ handle_purse_get_finished (void *cls,
|
||||
break;
|
||||
}
|
||||
|
||||
key_state = TALER_EXCHANGE_get_keys (pgh->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (pgh->keys,
|
||||
&exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -207,7 +205,9 @@ handle_purse_get_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_PurseGetHandle *
|
||||
TALER_EXCHANGE_purse_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
bool wait_for_merge,
|
||||
@ -218,14 +218,7 @@ TALER_EXCHANGE_purse_get (
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (*purse_pub) * 2 + 64];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
pgh = GNUNET_new (struct TALER_EXCHANGE_PurseGetHandle);
|
||||
pgh->exchange = exchange;
|
||||
pgh->cb = cb;
|
||||
pgh->cb_cls = cb_cls;
|
||||
{
|
||||
@ -247,19 +240,20 @@ TALER_EXCHANGE_purse_get (
|
||||
if (GNUNET_TIME_relative_is_zero (timeout))
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s/%s",
|
||||
"purses/%s/%s",
|
||||
cpub_str,
|
||||
wait_for_merge ? "merge" : "deposit");
|
||||
else
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/purses/%s/%s?timeout_ms=%s",
|
||||
"purses/%s/%s?timeout_ms=%s",
|
||||
cpub_str,
|
||||
wait_for_merge ? "merge" : "deposit",
|
||||
timeout_str);
|
||||
}
|
||||
pgh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
pgh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == pgh->url)
|
||||
{
|
||||
GNUNET_free (pgh);
|
||||
@ -273,10 +267,11 @@ TALER_EXCHANGE_purse_get (
|
||||
GNUNET_free (pgh);
|
||||
return NULL;
|
||||
}
|
||||
pgh->job = GNUNET_CURL_job_add (TEAH_handle_to_context (exchange),
|
||||
pgh->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_purse_get_finished,
|
||||
pgh);
|
||||
pgh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
return pgh;
|
||||
}
|
||||
|
||||
@ -291,6 +286,7 @@ TALER_EXCHANGE_purse_get_cancel (
|
||||
pgh->job = NULL;
|
||||
}
|
||||
GNUNET_free (pgh->url);
|
||||
TALER_EXCHANGE_keys_decref (pgh->keys);
|
||||
GNUNET_free (pgh);
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,9 @@ struct TALER_EXCHANGE_RecoupHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -143,10 +143,8 @@ handle_recoup_finished (void *cls,
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
ph->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (ph->exchange);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -177,7 +175,7 @@ handle_recoup_finished (void *cls,
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_get_min_denomination_ (keys,
|
||||
TALER_EXCHANGE_get_min_denomination_ (ph->keys,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -187,7 +185,7 @@ handle_recoup_finished (void *cls,
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_coin_conflict_ (
|
||||
keys,
|
||||
ph->keys,
|
||||
j,
|
||||
&ph->pk,
|
||||
&ph->coin_pub,
|
||||
@ -244,7 +242,10 @@ handle_recoup_finished (void *cls,
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_RecoupHandle *
|
||||
TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_recoup (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||
const struct TALER_DenominationSignature *denom_sig,
|
||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||
@ -253,7 +254,6 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
void *recoup_cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupHandle *ph;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_DenominationHashP h_denom_pub;
|
||||
json_t *recoup_obj;
|
||||
CURL *eh;
|
||||
@ -261,8 +261,6 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||
union TALER_DenominationBlindingKeyP bks;
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle);
|
||||
TALER_planchet_setup_coin_priv (ps,
|
||||
exchange_vals,
|
||||
@ -319,19 +317,19 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/recoup",
|
||||
"coins/%s/recoup",
|
||||
pub_str);
|
||||
}
|
||||
|
||||
ph->exchange = exchange;
|
||||
ph->pk = *pk;
|
||||
memset (&ph->pk.key,
|
||||
0,
|
||||
sizeof (ph->pk.key)); /* zero out, as lifetime cannot be warranted */
|
||||
ph->cb = recoup_cb;
|
||||
ph->cb_cls = recoup_cb_cls;
|
||||
ph->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
ph->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == ph->url)
|
||||
{
|
||||
json_decref (recoup_obj);
|
||||
@ -357,7 +355,7 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for recoup: `%s'\n",
|
||||
ph->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
ph->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
ph->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
ph->ctx.headers,
|
||||
@ -377,6 +375,7 @@ TALER_EXCHANGE_recoup_cancel (struct TALER_EXCHANGE_RecoupHandle *ph)
|
||||
}
|
||||
GNUNET_free (ph->url);
|
||||
TALER_curl_easy_post_finished (&ph->ctx);
|
||||
TALER_EXCHANGE_keys_decref (ph->keys);
|
||||
GNUNET_free (ph);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2017-2022 Taler Systems SA
|
||||
Copyright (C) 2017-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -40,9 +40,9 @@ struct TALER_EXCHANGE_RecoupRefreshHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -144,10 +144,8 @@ handle_recoup_refresh_finished (void *cls,
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
ph->job = NULL;
|
||||
keys = TALER_EXCHANGE_get_keys (ph->exchange);
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
@ -191,7 +189,7 @@ handle_recoup_refresh_finished (void *cls,
|
||||
rrr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rrr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_get_min_denomination_ (keys,
|
||||
TALER_EXCHANGE_get_min_denomination_ (ph->keys,
|
||||
&min_key))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -201,7 +199,7 @@ handle_recoup_refresh_finished (void *cls,
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_coin_conflict_ (
|
||||
keys,
|
||||
ph->keys,
|
||||
j,
|
||||
&ph->pk,
|
||||
&ph->coin_pub,
|
||||
@ -246,7 +244,9 @@ handle_recoup_refresh_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_RecoupRefreshHandle *
|
||||
TALER_EXCHANGE_recoup_refresh (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||
const struct TALER_DenominationSignature *denom_sig,
|
||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||
@ -257,7 +257,6 @@ TALER_EXCHANGE_recoup_refresh (
|
||||
void *recoup_cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupRefreshHandle *ph;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_DenominationHashP h_denom_pub;
|
||||
json_t *recoup_obj;
|
||||
CURL *eh;
|
||||
@ -266,10 +265,7 @@ TALER_EXCHANGE_recoup_refresh (
|
||||
union TALER_DenominationBlindingKeyP bks;
|
||||
|
||||
GNUNET_assert (NULL != recoup_cb);
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
ph = GNUNET_new (struct TALER_EXCHANGE_RecoupRefreshHandle);
|
||||
ph->exchange = exchange;
|
||||
ph->pk = *pk;
|
||||
memset (&ph->pk.key,
|
||||
0,
|
||||
@ -333,12 +329,13 @@ TALER_EXCHANGE_recoup_refresh (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/recoup-refresh",
|
||||
"coins/%s/recoup-refresh",
|
||||
pub_str);
|
||||
}
|
||||
|
||||
ph->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
ph->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == ph->url)
|
||||
{
|
||||
json_decref (recoup_obj);
|
||||
@ -364,7 +361,7 @@ TALER_EXCHANGE_recoup_refresh (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for recoup-refresh: `%s'\n",
|
||||
ph->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
ph->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
ph->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
ph->ctx.headers,
|
||||
@ -385,6 +382,7 @@ TALER_EXCHANGE_recoup_refresh_cancel (
|
||||
}
|
||||
GNUNET_free (ph->url);
|
||||
TALER_curl_easy_post_finished (&ph->ctx);
|
||||
TALER_EXCHANGE_keys_decref (ph->keys);
|
||||
GNUNET_free (ph);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2015-2022 Taler Systems SA
|
||||
Copyright (C) 2015-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,11 +39,6 @@
|
||||
struct TALER_EXCHANGE_RefreshesRevealHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -310,7 +305,8 @@ handle_refresh_reveal_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_RefreshesRevealHandle *
|
||||
TALER_EXCHANGE_refreshes_reveal (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_RefreshMasterSecretP *rms,
|
||||
const struct TALER_EXCHANGE_RefreshData *rd,
|
||||
unsigned int num_coins,
|
||||
@ -327,7 +323,6 @@ TALER_EXCHANGE_refreshes_reveal (
|
||||
json_t *link_sigs;
|
||||
json_t *old_age_commitment = NULL;
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct MeltData md;
|
||||
char arg_str[sizeof (struct TALER_RefreshCommitmentP) * 2 + 32];
|
||||
bool send_rms = false;
|
||||
@ -342,12 +337,6 @@ TALER_EXCHANGE_refreshes_reveal (
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_get_melt_data_ (rms,
|
||||
rd,
|
||||
@ -467,22 +456,22 @@ TALER_EXCHANGE_refreshes_reveal (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/refreshes/%s/reveal",
|
||||
"refreshes/%s/reveal",
|
||||
pub_str);
|
||||
}
|
||||
/* finally, we can actually issue the request */
|
||||
rrh = GNUNET_new (struct TALER_EXCHANGE_RefreshesRevealHandle);
|
||||
rrh->exchange = exchange;
|
||||
rrh->noreveal_index = noreveal_index;
|
||||
rrh->reveal_cb = reveal_cb;
|
||||
rrh->reveal_cb_cls = reveal_cb_cls;
|
||||
rrh->md = md;
|
||||
rrh->alg_values = GNUNET_memdup (alg_values,
|
||||
rrh->alg_values
|
||||
= GNUNET_memdup (alg_values,
|
||||
md.num_fresh_coins
|
||||
* sizeof (struct
|
||||
TALER_ExchangeWithdrawValues));
|
||||
rrh->url = TEAH_path_to_url (rrh->exchange,
|
||||
arg_str);
|
||||
* sizeof (struct TALER_ExchangeWithdrawValues));
|
||||
rrh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rrh->url)
|
||||
{
|
||||
json_decref (reveal_obj);
|
||||
@ -510,7 +499,6 @@ TALER_EXCHANGE_refreshes_reveal (
|
||||
return NULL;
|
||||
}
|
||||
json_decref (reveal_obj);
|
||||
ctx = TEAH_handle_to_context (rrh->exchange);
|
||||
rrh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rrh->ctx.headers,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,9 +39,9 @@ struct TALER_EXCHANGE_RefundHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -117,7 +117,6 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||
struct TALER_ExchangeSignatureP *exchange_sig)
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
exchange_sig),
|
||||
@ -134,9 +133,8 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
key_state = TALER_EXCHANGE_get_keys (rh->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
TALER_EXCHANGE_test_signing_key (rh->keys,
|
||||
exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -672,7 +670,9 @@ handle_refund_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_RefundHandle *
|
||||
TALER_EXCHANGE_refund (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
@ -684,13 +684,10 @@ TALER_EXCHANGE_refund (
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct TALER_MerchantSignatureP merchant_sig;
|
||||
struct TALER_EXCHANGE_RefundHandle *rh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
json_t *refund_obj;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv->eddsa_priv,
|
||||
&merchant_pub.eddsa_pub);
|
||||
TALER_merchant_refund_sign (coin_pub,
|
||||
@ -711,7 +708,7 @@ TALER_EXCHANGE_refund (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/coins/%s/refund",
|
||||
"coins/%s/refund",
|
||||
pub_str);
|
||||
}
|
||||
refund_obj = GNUNET_JSON_PACK (
|
||||
@ -726,11 +723,11 @@ TALER_EXCHANGE_refund (
|
||||
GNUNET_JSON_pack_data_auto ("merchant_sig",
|
||||
&merchant_sig));
|
||||
rh = GNUNET_new (struct TALER_EXCHANGE_RefundHandle);
|
||||
rh->exchange = exchange;
|
||||
rh->cb = cb;
|
||||
rh->cb_cls = cb_cls;
|
||||
rh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rh->url)
|
||||
{
|
||||
json_decref (refund_obj);
|
||||
@ -761,7 +758,7 @@ TALER_EXCHANGE_refund (
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"URL for refund: `%s'\n",
|
||||
rh->url);
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
rh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rh->ctx.headers,
|
||||
@ -781,6 +778,7 @@ TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund)
|
||||
}
|
||||
GNUNET_free (refund->url);
|
||||
TALER_curl_easy_post_finished (&refund->ctx);
|
||||
TALER_EXCHANGE_keys_decref (refund->keys);
|
||||
GNUNET_free (refund);
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,6 @@
|
||||
struct TALER_EXCHANGE_ReservesAttestHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -131,6 +126,8 @@ handle_reserves_attest_ok (struct TALER_EXCHANGE_ReservesAttestHandle *rsh,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* FIXME: validate exchange_pub is actually
|
||||
a good exchange signing key */
|
||||
rsh->cb (rsh->cb_cls,
|
||||
&rs);
|
||||
rsh->cb = NULL;
|
||||
@ -228,7 +225,8 @@ handle_reserves_attest_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesAttestHandle *
|
||||
TALER_EXCHANGE_reserves_attest (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
unsigned int attributes_length,
|
||||
const char *const*attributes,
|
||||
@ -236,7 +234,6 @@ TALER_EXCHANGE_reserves_attest (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesAttestHandle *rsh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
@ -248,12 +245,6 @@ TALER_EXCHANGE_reserves_attest (
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
details = json_array ();
|
||||
GNUNET_assert (NULL != details);
|
||||
for (unsigned int i = 0; i<attributes_length; i++)
|
||||
@ -263,7 +254,6 @@ TALER_EXCHANGE_reserves_attest (
|
||||
json_string (attributes[i])));
|
||||
}
|
||||
rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesAttestHandle);
|
||||
rsh->exchange = exchange;
|
||||
rsh->cb = cb;
|
||||
rsh->cb_cls = cb_cls;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||
@ -280,11 +270,12 @@ TALER_EXCHANGE_reserves_attest (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves-attest/%s",
|
||||
"reserves-attest/%s",
|
||||
pub_str);
|
||||
}
|
||||
rsh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rsh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rsh->url)
|
||||
{
|
||||
json_decref (details);
|
||||
@ -328,7 +319,6 @@ TALER_EXCHANGE_reserves_attest (
|
||||
}
|
||||
json_decref (attest_obj);
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rsh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rsh->post_ctx.headers,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -38,11 +38,6 @@
|
||||
struct TALER_EXCHANGE_ReservesCloseHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -269,26 +264,19 @@ handle_reserves_close_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesCloseHandle *
|
||||
TALER_EXCHANGE_reserves_close (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const char *target_payto_uri,
|
||||
TALER_EXCHANGE_ReservesCloseCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesCloseHandle *rch;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
struct TALER_PaytoHashP h_payto;
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
rch = GNUNET_new (struct TALER_EXCHANGE_ReservesCloseHandle);
|
||||
rch->exchange = exchange;
|
||||
rch->cb = cb;
|
||||
rch->cb_cls = cb_cls;
|
||||
rch->ts = GNUNET_TIME_timestamp_get ();
|
||||
@ -306,11 +294,12 @@ TALER_EXCHANGE_reserves_close (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s/close",
|
||||
"reserves/%s/close",
|
||||
pub_str);
|
||||
}
|
||||
rch->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rch->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rch->url)
|
||||
{
|
||||
GNUNET_free (rch);
|
||||
@ -357,7 +346,6 @@ TALER_EXCHANGE_reserves_close (
|
||||
}
|
||||
json_decref (close_obj);
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rch->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rch->post_ctx.headers,
|
||||
|
@ -38,11 +38,6 @@
|
||||
struct TALER_EXCHANGE_ReservesGetHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -186,23 +181,17 @@ handle_reserves_get_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesGetHandle *
|
||||
TALER_EXCHANGE_reserves_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
TALER_EXCHANGE_ReservesGetCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesGetHandle *rgh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 16 + 32];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
|
||||
char *end;
|
||||
@ -223,22 +212,22 @@ TALER_EXCHANGE_reserves_get (
|
||||
if (GNUNET_TIME_relative_is_zero (timeout))
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s",
|
||||
"reserves/%s",
|
||||
pub_str);
|
||||
else
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s?timeout_ms=%s",
|
||||
"reserves/%s?timeout_ms=%s",
|
||||
pub_str,
|
||||
timeout_str);
|
||||
}
|
||||
rgh = GNUNET_new (struct TALER_EXCHANGE_ReservesGetHandle);
|
||||
rgh->exchange = exchange;
|
||||
rgh->cb = cb;
|
||||
rgh->cb_cls = cb_cls;
|
||||
rgh->reserve_pub = *reserve_pub;
|
||||
rgh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rgh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rgh->url)
|
||||
{
|
||||
GNUNET_free (rgh);
|
||||
@ -252,7 +241,6 @@ TALER_EXCHANGE_reserves_get (
|
||||
GNUNET_free (rgh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rgh->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_reserves_get_finished,
|
||||
|
@ -38,11 +38,6 @@
|
||||
struct TALER_EXCHANGE_ReservesGetAttestHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
*/
|
||||
@ -211,22 +206,16 @@ handle_reserves_get_attestable_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesGetAttestHandle *
|
||||
TALER_EXCHANGE_reserves_get_attestable (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
TALER_EXCHANGE_ReservesGetAttestCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesGetAttestHandle *rgah;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
|
||||
char *end;
|
||||
@ -239,16 +228,16 @@ TALER_EXCHANGE_reserves_get_attestable (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves-attest/%s",
|
||||
"reserves-attest/%s",
|
||||
pub_str);
|
||||
}
|
||||
rgah = GNUNET_new (struct TALER_EXCHANGE_ReservesGetAttestHandle);
|
||||
rgah->exchange = exchange;
|
||||
rgah->cb = cb;
|
||||
rgah->cb_cls = cb_cls;
|
||||
rgah->reserve_pub = *reserve_pub;
|
||||
rgah->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rgah->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rgah->url)
|
||||
{
|
||||
GNUNET_free (rgah);
|
||||
@ -262,7 +251,6 @@ TALER_EXCHANGE_reserves_get_attestable (
|
||||
GNUNET_free (rgah);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rgah->job = GNUNET_CURL_job_add (ctx,
|
||||
eh,
|
||||
&handle_reserves_get_attestable_finished,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,9 +39,9 @@ struct TALER_EXCHANGE_ReservesHistoryHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -131,7 +131,7 @@ handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
|
||||
rhistory = GNUNET_new_array (len,
|
||||
struct TALER_EXCHANGE_ReserveHistoryEntry);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_parse_reserve_history (rsh->exchange,
|
||||
TALER_EXCHANGE_parse_reserve_history (rsh->keys,
|
||||
history,
|
||||
&rsh->reserve_pub,
|
||||
rs.details.ok.balance.currency,
|
||||
@ -250,26 +250,19 @@ handle_reserves_history_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesHistoryHandle *
|
||||
TALER_EXCHANGE_reserves_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
TALER_EXCHANGE_ReservesHistoryCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesHistoryHandle *rsh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_GlobalFee *gf;
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesHistoryHandle);
|
||||
rsh->exchange = exchange;
|
||||
rsh->cb = cb;
|
||||
rsh->cb_cls = cb_cls;
|
||||
rsh->ts = GNUNET_TIME_timestamp_get ();
|
||||
@ -287,11 +280,12 @@ TALER_EXCHANGE_reserves_history (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s/history",
|
||||
"reserves/%s/history",
|
||||
pub_str);
|
||||
}
|
||||
rsh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rsh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rsh->url)
|
||||
{
|
||||
GNUNET_free (rsh);
|
||||
@ -305,15 +299,6 @@ TALER_EXCHANGE_reserves_history (
|
||||
GNUNET_free (rsh);
|
||||
return NULL;
|
||||
}
|
||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||
if (NULL == keys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
curl_easy_cleanup (eh);
|
||||
GNUNET_free (rsh->url);
|
||||
GNUNET_free (rsh);
|
||||
return NULL;
|
||||
}
|
||||
gf = TALER_EXCHANGE_get_global_fee (keys,
|
||||
rsh->ts);
|
||||
if (NULL == gf)
|
||||
@ -349,7 +334,7 @@ TALER_EXCHANGE_reserves_history (
|
||||
}
|
||||
json_decref (history_obj);
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rsh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
rsh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rsh->post_ctx.headers,
|
||||
@ -370,6 +355,7 @@ TALER_EXCHANGE_reserves_history_cancel (
|
||||
}
|
||||
TALER_curl_easy_post_finished (&rsh->post_ctx);
|
||||
GNUNET_free (rsh->url);
|
||||
TALER_EXCHANGE_keys_decref (rsh->keys);
|
||||
GNUNET_free (rsh);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -67,9 +67,9 @@ struct TALER_EXCHANGE_ReservesOpenHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -321,7 +321,6 @@ handle_reserves_open_finished (void *cls,
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct CoinData *cd = NULL;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dk;
|
||||
@ -331,8 +330,6 @@ handle_reserves_open_finished (void *cls,
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
keys = TALER_EXCHANGE_get_keys (roh->exchange);
|
||||
GNUNET_assert (NULL != keys);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
@ -362,7 +359,7 @@ handle_reserves_open_finished (void *cls,
|
||||
rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
dk = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
|
||||
dk = TALER_EXCHANGE_get_denomination_key_by_hash (roh->keys,
|
||||
&cd->h_denom_pub);
|
||||
if (NULL == dk)
|
||||
{
|
||||
@ -372,7 +369,7 @@ handle_reserves_open_finished (void *cls,
|
||||
break;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_check_coin_conflict_ (keys,
|
||||
TALER_EXCHANGE_check_coin_conflict_ (roh->keys,
|
||||
j,
|
||||
dk,
|
||||
&coin_pub,
|
||||
@ -427,7 +424,9 @@ handle_reserves_open_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesOpenHandle *
|
||||
TALER_EXCHANGE_reserves_open (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
const struct TALER_Amount *reserve_contribution,
|
||||
unsigned int coin_payments_length,
|
||||
@ -438,20 +437,11 @@ TALER_EXCHANGE_reserves_open (
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesOpenHandle *roh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
json_t *cpa;
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
roh = GNUNET_new (struct TALER_EXCHANGE_ReservesOpenHandle);
|
||||
roh->exchange = exchange;
|
||||
roh->cb = cb;
|
||||
roh->cb_cls = cb_cls;
|
||||
roh->ts = GNUNET_TIME_timestamp_get ();
|
||||
@ -469,11 +459,12 @@ TALER_EXCHANGE_reserves_open (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s/open",
|
||||
"reserves/%s/open",
|
||||
pub_str);
|
||||
}
|
||||
roh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
roh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == roh->url)
|
||||
{
|
||||
GNUNET_free (roh);
|
||||
@ -487,15 +478,6 @@ TALER_EXCHANGE_reserves_open (
|
||||
GNUNET_free (roh);
|
||||
return NULL;
|
||||
}
|
||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||
if (NULL == keys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
curl_easy_cleanup (eh);
|
||||
GNUNET_free (roh->url);
|
||||
GNUNET_free (roh);
|
||||
return NULL;
|
||||
}
|
||||
TALER_wallet_reserve_open_sign (reserve_contribution,
|
||||
roh->ts,
|
||||
expiration_time,
|
||||
@ -578,7 +560,7 @@ TALER_EXCHANGE_reserves_open (
|
||||
}
|
||||
json_decref (open_obj);
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
roh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
roh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
roh->post_ctx.headers,
|
||||
@ -600,6 +582,7 @@ TALER_EXCHANGE_reserves_open_cancel (
|
||||
TALER_curl_easy_post_finished (&roh->post_ctx);
|
||||
GNUNET_free (roh->coins);
|
||||
GNUNET_free (roh->url);
|
||||
TALER_EXCHANGE_keys_decref (roh->keys);
|
||||
GNUNET_free (roh);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2022 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,9 +39,9 @@ struct TALER_EXCHANGE_ReservesStatusHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -119,7 +119,7 @@ handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
|
||||
rhistory = GNUNET_new_array (len,
|
||||
struct TALER_EXCHANGE_ReserveHistoryEntry);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_parse_reserve_history (rsh->exchange,
|
||||
TALER_EXCHANGE_parse_reserve_history (rsh->keys,
|
||||
history,
|
||||
&rsh->reserve_pub,
|
||||
rs.details.ok.balance.currency,
|
||||
@ -233,27 +233,21 @@ handle_reserves_status_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_ReservesStatusHandle *
|
||||
TALER_EXCHANGE_reserves_status (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
TALER_EXCHANGE_ReservesStatusCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_ReservesStatusHandle *rsh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
struct GNUNET_TIME_Timestamp ts
|
||||
= GNUNET_TIME_timestamp_get ();
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
rsh = GNUNET_new (struct TALER_EXCHANGE_ReservesStatusHandle);
|
||||
rsh->exchange = exchange;
|
||||
rsh->cb = cb;
|
||||
rsh->cb_cls = cb_cls;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||
@ -270,11 +264,12 @@ TALER_EXCHANGE_reserves_status (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/reserves/%s/status",
|
||||
"reserves/%s/status",
|
||||
pub_str);
|
||||
}
|
||||
rsh->url = TEAH_path_to_url (exchange,
|
||||
arg_str);
|
||||
rsh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == rsh->url)
|
||||
{
|
||||
GNUNET_free (rsh);
|
||||
@ -312,7 +307,7 @@ TALER_EXCHANGE_reserves_status (
|
||||
}
|
||||
json_decref (status_obj);
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
rsh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
rsh->job = GNUNET_CURL_job_add2 (ctx,
|
||||
eh,
|
||||
rsh->post_ctx.headers,
|
||||
@ -333,6 +328,7 @@ TALER_EXCHANGE_reserves_status_cancel (
|
||||
}
|
||||
TALER_curl_easy_post_finished (&rsh->post_ctx);
|
||||
GNUNET_free (rsh->url);
|
||||
TALER_EXCHANGE_keys_decref (rsh->keys);
|
||||
GNUNET_free (rsh);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2021 Taler Systems SA
|
||||
Copyright (C) 2014-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
@ -38,9 +38,9 @@ struct TALER_EXCHANGE_TransfersGetHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection to exchange this request handle will use
|
||||
* The keys of the exchange this request handle will use
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* The url for this request.
|
||||
@ -130,7 +130,7 @@ check_transfers_get_response_ok (
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (
|
||||
TALER_EXCHANGE_get_keys (wdh->exchange),
|
||||
wdh->keys,
|
||||
&td->exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -320,25 +320,18 @@ handle_transfers_get_finished (void *cls,
|
||||
|
||||
struct TALER_EXCHANGE_TransfersGetHandle *
|
||||
TALER_EXCHANGE_transfers_get (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_WireTransferIdentifierRawP *wtid,
|
||||
TALER_EXCHANGE_TransfersGetCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_EXCHANGE_TransfersGetHandle *wdh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
CURL *eh;
|
||||
char arg_str[sizeof (struct TALER_WireTransferIdentifierRawP) * 2 + 32];
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wdh = GNUNET_new (struct TALER_EXCHANGE_TransfersGetHandle);
|
||||
wdh->exchange = exchange;
|
||||
wdh->cb = cb;
|
||||
wdh->cb_cls = cb_cls;
|
||||
|
||||
@ -354,11 +347,12 @@ TALER_EXCHANGE_transfers_get (
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
"/transfers/%s",
|
||||
"transfers/%s",
|
||||
wtid_str);
|
||||
}
|
||||
wdh->url = TEAH_path_to_url (wdh->exchange,
|
||||
arg_str);
|
||||
wdh->url = TALER_url_join (url,
|
||||
arg_str,
|
||||
NULL);
|
||||
if (NULL == wdh->url)
|
||||
{
|
||||
GNUNET_free (wdh);
|
||||
@ -372,7 +366,7 @@ TALER_EXCHANGE_transfers_get (
|
||||
GNUNET_free (wdh);
|
||||
return NULL;
|
||||
}
|
||||
ctx = TEAH_handle_to_context (exchange);
|
||||
wdh->keys = TALER_EXCHANGE_keys_incref (keys);
|
||||
wdh->job = GNUNET_CURL_job_add_with_ct_json (ctx,
|
||||
eh,
|
||||
&handle_transfers_get_finished,
|
||||
@ -397,6 +391,7 @@ TALER_EXCHANGE_transfers_get_cancel (
|
||||
wdh->job = NULL;
|
||||
}
|
||||
GNUNET_free (wdh->url);
|
||||
TALER_EXCHANGE_keys_decref (wdh->keys);
|
||||
GNUNET_free (wdh);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,8 @@ reserve_withdraw_payment_required (
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_parse_reserve_history (wh->exchange,
|
||||
TALER_EXCHANGE_parse_reserve_history (TALER_EXCHANGE_get_keys (
|
||||
wh->exchange),
|
||||
history,
|
||||
&wh->reserve_pub,
|
||||
balance.currency,
|
||||
|
@ -29,19 +29,21 @@ set -eu
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_skip() {
|
||||
echo " SKIP: " "$@"
|
||||
echo " SKIP: " "$@" >&2
|
||||
exit 77
|
||||
}
|
||||
|
||||
# Exit, with error message (hard failure)
|
||||
function exit_fail() {
|
||||
echo " FAIL: " "$@"
|
||||
echo " FAIL: " "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Cleanup to run whenever we exit
|
||||
function cleanup()
|
||||
{
|
||||
echo "Taler unified setup terminating!" >&2
|
||||
|
||||
for n in $(jobs -p)
|
||||
do
|
||||
kill $n 2> /dev/null || true
|
||||
@ -53,6 +55,7 @@ function cleanup()
|
||||
# Install cleanup handler (except for kill -9)
|
||||
trap cleanup EXIT
|
||||
|
||||
WAIT_FOR_SIGNAL=0
|
||||
START_AUDITOR=0
|
||||
START_BACKUP=0
|
||||
START_EXCHANGE=0
|
||||
@ -71,7 +74,7 @@ LOGLEVEL="DEBUG"
|
||||
DEFAULT_SLEEP="0.2"
|
||||
|
||||
# Parse command-line options
|
||||
while getopts ':abc:d:efghl:mnr:stu:vw' OPTION; do
|
||||
while getopts ':abc:d:efghl:mnr:stu:vwW' OPTION; do
|
||||
case "$OPTION" in
|
||||
a)
|
||||
START_AUDITOR="1"
|
||||
@ -82,7 +85,7 @@ while getopts ':abc:d:efghl:mnr:stu:vw' OPTION; do
|
||||
c)
|
||||
CONF_ORIG="$OPTARG"
|
||||
;;
|
||||
c)
|
||||
d)
|
||||
WIRE_DOMAIN="$OPTARG"
|
||||
;;
|
||||
e)
|
||||
@ -142,6 +145,9 @@ while getopts ':abc:d:efghl:mnr:stu:vw' OPTION; do
|
||||
w)
|
||||
START_WIREWATCH="1"
|
||||
;;
|
||||
W)
|
||||
WAIT_FOR_SIGNAL="1"
|
||||
;;
|
||||
?)
|
||||
exit_fail "Unrecognized command line option"
|
||||
;;
|
||||
@ -201,14 +207,25 @@ register_sandbox_account() {
|
||||
demobank \
|
||||
delete \
|
||||
--bank-account "$1" &> /dev/null || true
|
||||
|
||||
MAYBE_IBAN="${4:-}"
|
||||
if test -n "$MAYBE_IBAN"; then
|
||||
libeufin-cli sandbox \
|
||||
demobank \
|
||||
register --name "$3" --iban "$MAYBE_IBAN"
|
||||
else
|
||||
libeufin-cli sandbox \
|
||||
demobank \
|
||||
register --name "$3"
|
||||
fi
|
||||
|
||||
unset LIBEUFIN_SANDBOX_USERNAME
|
||||
unset LIBEUFIN_SANDBOX_PASSWORD
|
||||
}
|
||||
|
||||
|
||||
if [[ "1" = "$START_NEXUS" || "1" = "$START_FAKEBANK" ]]
|
||||
then
|
||||
BANK_PORT=$(taler-config -c "$CONF" -s "BANK" -o "HTTP_PORT")
|
||||
if [ "1" = "$START_NEXUS" ]
|
||||
then
|
||||
@ -218,6 +235,13 @@ else
|
||||
NEXUS_PORT="0"
|
||||
SANDBOX_PORT="1$BANK_PORT"
|
||||
fi
|
||||
else
|
||||
if [ "1" = "$START_SANDBOX" ]
|
||||
then
|
||||
BANK_PORT=$(taler-config -c "$CONF" -s "BANK" -o "HTTP_PORT")
|
||||
SANDBOX_PORT="$BANK_PORT"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "1" = "$START_SANDBOX" ]
|
||||
then
|
||||
@ -256,7 +280,11 @@ then
|
||||
fi
|
||||
echo "OK"
|
||||
echo -n "Register Sandbox users ..."
|
||||
register_sandbox_account fortytwo x "Forty Two"
|
||||
# The specified IBAN and name must match the ones hard-coded into
|
||||
# the C helper for the add-incoming call. Without this value,
|
||||
# Sandbox won't find the target account to debit along a /add-incoming
|
||||
# call.
|
||||
register_sandbox_account fortytwo x "User42" FR7630006000011234567890189
|
||||
register_sandbox_account fortythree x "Forty Three"
|
||||
register_sandbox_account exchange x "Exchange Company"
|
||||
register_sandbox_account tor x "Tor Project"
|
||||
@ -610,7 +638,7 @@ then
|
||||
if [ "1" != "$OK" ]
|
||||
then
|
||||
cat "$LAST_RESPONSE"
|
||||
exit_skip "Failed to setup exchange keys, check secmod logs"
|
||||
exit_fail "Failed to setup exchange keys, check secmod logs"
|
||||
fi
|
||||
rm "$LAST_RESPONSE"
|
||||
echo " OK"
|
||||
@ -662,7 +690,7 @@ then
|
||||
if [ "1" != "$OK" ]
|
||||
then
|
||||
cat "$LAST_RESPONSE"
|
||||
exit_skip " Failed to setup keys"
|
||||
exit_fail " Failed to setup keys"
|
||||
fi
|
||||
rm "$LAST_RESPONSE"
|
||||
echo " OK"
|
||||
@ -681,7 +709,17 @@ fi
|
||||
# Signal caller that we are ready.
|
||||
echo "<<READY>>"
|
||||
|
||||
if [ "1" = "$WAIT_FOR_SIGNAL" ]
|
||||
then
|
||||
while true
|
||||
do
|
||||
sleep 0.1
|
||||
done
|
||||
else
|
||||
# Wait until caller stops us.
|
||||
read
|
||||
fi
|
||||
|
||||
echo "Taler unified setup terminating!" >&2
|
||||
|
||||
exit 0
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
#define CONFIG_FILE "test_auditor_api-rsa.conf"
|
||||
|
||||
static struct TALER_AUDITOR_Handle *ah;
|
||||
static struct TALER_AUDITOR_GetConfigHandle *ah;
|
||||
|
||||
static struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
@ -62,7 +62,11 @@ do_shutdown (void *cls)
|
||||
GNUNET_SCHEDULER_cancel (tt);
|
||||
tt = NULL;
|
||||
}
|
||||
TALER_AUDITOR_disconnect (ah);
|
||||
if (NULL != ah)
|
||||
{
|
||||
TALER_AUDITOR_get_config_cancel (ah);
|
||||
ah = NULL;
|
||||
}
|
||||
GNUNET_CURL_fini (ctx);
|
||||
GNUNET_CURL_gnunet_rc_destroy (rc);
|
||||
}
|
||||
@ -82,20 +86,16 @@ do_timeout (void *cls)
|
||||
* Function called with information about the auditor.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr http response details
|
||||
* @param vi basic information about the auditor
|
||||
* @param compat protocol compatibility information
|
||||
* @param vr response details
|
||||
*/
|
||||
static void
|
||||
version_cb (void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
const struct TALER_AUDITOR_VersionInformation *vi,
|
||||
enum TALER_AUDITOR_VersionCompatibility compat)
|
||||
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||
{
|
||||
(void) cls;
|
||||
(void) hr;
|
||||
if ( (NULL != vi) &&
|
||||
(TALER_AUDITOR_VC_MATCH == compat) )
|
||||
ah = NULL;
|
||||
if ( (MHD_HTTP_OK == vr->hr.http_status) &&
|
||||
(TALER_AUDITOR_VC_MATCH == vr->details.ok.compat) )
|
||||
global_ret = 0;
|
||||
else
|
||||
global_ret = 2;
|
||||
@ -118,7 +118,7 @@ run (void *cls)
|
||||
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||
&rc);
|
||||
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
||||
ah = TALER_AUDITOR_connect (ctx,
|
||||
ah = TALER_AUDITOR_get_config (ctx,
|
||||
auditor_url,
|
||||
&version_cb,
|
||||
NULL);
|
||||
|
@ -142,8 +142,8 @@ run (void *cls,
|
||||
"fetch-transactions-at-nexus",
|
||||
"exchange", /* from taler-nexus-prepare */
|
||||
"x", /* from taler-nexus-prepare */
|
||||
"http://localhost:5001",
|
||||
"my-bank-account") /* from taler-nexus-prepare */
|
||||
"http://localhost:8082",
|
||||
"exchange-nexus") /* from taler-nexus-prepare */
|
||||
: TALER_TESTING_cmd_sleep ("nop",
|
||||
0),
|
||||
TALER_TESTING_cmd_bank_debits ("history-2b",
|
||||
|
@ -11,7 +11,7 @@ CURRENCY_ROUND_UNIT = EUR:0.01
|
||||
[auditor]
|
||||
BASE_URL = "http://localhost:8083/"
|
||||
PORT = 8083
|
||||
PUBLIC_KEY = SA7JVMCW3MMN7SYAWJ9AB0BGJDX6MP3PNN2JWQ3T8233MDSQC7Z0
|
||||
PUBLIC_KEY = T0XJ9QZ59YDN7QG3RE40SB2HY7W0ASR1EKF4WZDGZ1G159RSQC80
|
||||
TINY_AMOUNT = EUR:0.01
|
||||
|
||||
[auditordb-postgres]
|
||||
|
@ -0,0 +1 @@
|
||||
<EFBFBD>G,U<><55><EFBFBD>{<7B>~#r<>-<11><>H<11><0B><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2018, 2021 Taler Systems SA
|
||||
Copyright (C) 2018-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
@ -132,13 +132,15 @@ do_retry (void *cls)
|
||||
* to check if the response code is acceptable.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param dcr response details
|
||||
*/
|
||||
static void
|
||||
deposit_confirmation_cb (void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr)
|
||||
deposit_confirmation_cb (
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr)
|
||||
{
|
||||
struct DepositConfirmationState *dcs = cls;
|
||||
const struct TALER_AUDITOR_HttpResponse *hr = &dcr->hr;
|
||||
|
||||
dcs->dc = NULL;
|
||||
if (dcs->expected_response_code != hr->http_status)
|
||||
@ -208,7 +210,7 @@ deposit_confirmation_run (void *cls,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv;
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_SigningPublicKey *spk;
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
const char *auditor_url;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
@ -229,9 +231,14 @@ deposit_confirmation_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_TESTING_get_trait_auditor (auditor_cmd,
|
||||
&auditor));
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_auditor_url (auditor_cmd,
|
||||
&auditor_url))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
deposit_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
@ -317,7 +324,9 @@ deposit_confirmation_run (void *cls,
|
||||
if (GNUNET_TIME_absolute_is_zero (refund_deadline.abs_time))
|
||||
refund_deadline = timestamp;
|
||||
}
|
||||
dcs->dc = TALER_AUDITOR_deposit_confirmation (auditor,
|
||||
dcs->dc = TALER_AUDITOR_deposit_confirmation (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
auditor_url,
|
||||
&h_wire,
|
||||
&no_h_policy,
|
||||
&h_contract_terms,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2018 Taler Systems SA
|
||||
Copyright (C) 2018-2023 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
@ -127,11 +127,10 @@ do_retry (void *cls)
|
||||
*/
|
||||
static void
|
||||
exchanges_cb (void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
unsigned int num_exchanges,
|
||||
const struct TALER_AUDITOR_ExchangeInfo *ei)
|
||||
const struct TALER_AUDITOR_ListExchangesResponse *ler)
|
||||
{
|
||||
struct ExchangesState *es = cls;
|
||||
const struct TALER_AUDITOR_HttpResponse *hr = &ler->hr;
|
||||
|
||||
es->leh = NULL;
|
||||
if (es->expected_response_code != hr->http_status)
|
||||
@ -164,24 +163,30 @@ exchanges_cb (void *cls,
|
||||
hr->http_status);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_interpreter_next (es->is);
|
||||
return;
|
||||
}
|
||||
if (NULL != es->exchange_url)
|
||||
{
|
||||
unsigned int found = GNUNET_NO;
|
||||
bool found = false;
|
||||
unsigned int num_exchanges = ler->details.ok.num_exchanges;
|
||||
const struct TALER_AUDITOR_ExchangeInfo *ei = ler->details.ok.ei;
|
||||
|
||||
for (unsigned int i = 0;
|
||||
i<num_exchanges;
|
||||
i++)
|
||||
if (0 == strcmp (es->exchange_url,
|
||||
ei[i].exchange_url))
|
||||
found = GNUNET_YES;
|
||||
if (GNUNET_NO == found)
|
||||
found = true;
|
||||
if (! found)
|
||||
{
|
||||
TALER_LOG_ERROR ("Exchange '%s' doesn't exist at this auditor\n",
|
||||
es->exchange_url);
|
||||
TALER_TESTING_interpreter_fail (es->is);
|
||||
return;
|
||||
}
|
||||
|
||||
TALER_LOG_DEBUG ("Exchange '%s' exists at this auditor!\n",
|
||||
es->exchange_url);
|
||||
}
|
||||
@ -203,7 +208,7 @@ exchanges_run (void *cls,
|
||||
{
|
||||
struct ExchangesState *es = cls;
|
||||
const struct TALER_TESTING_Command *auditor_cmd;
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
const char *auditor_url;
|
||||
|
||||
(void) cmd;
|
||||
auditor_cmd = TALER_TESTING_interpreter_get_command (is,
|
||||
@ -214,15 +219,20 @@ exchanges_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_TESTING_get_trait_auditor (auditor_cmd,
|
||||
&auditor));
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_auditor_url (auditor_cmd,
|
||||
&auditor_url))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
es->is = is;
|
||||
es->leh = TALER_AUDITOR_list_exchanges (auditor,
|
||||
es->leh = TALER_AUDITOR_list_exchanges (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
auditor_url,
|
||||
&exchanges_cb,
|
||||
es);
|
||||
|
||||
if (NULL == es->leh)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -287,14 +297,6 @@ exchanges_traits (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a "list exchanges" command.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param auditor auditor connection.
|
||||
* @param expected_response_code expected HTTP response code.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exchanges (const char *label,
|
||||
unsigned int expected_response_code)
|
||||
@ -318,16 +320,6 @@ TALER_TESTING_cmd_exchanges (const char *label,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a "list exchanges" command and check whether
|
||||
* a particular exchange belongs to the returned bundle.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param expected_response_code expected HTTP response code.
|
||||
* @param exchange_url URL of the exchange supposed to
|
||||
* be included in the response.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exchanges_with_url (const char *label,
|
||||
unsigned int expected_response_code,
|
||||
|
@ -288,8 +288,7 @@ command_cb (void *cls,
|
||||
* to be allocated, and the second to actually populate every
|
||||
* element.
|
||||
*
|
||||
* @param is interpreter state (supposedly having the
|
||||
* current CMD pointing at a "history" CMD).
|
||||
* @param hs history state
|
||||
* @param[out] rh history array to initialize.
|
||||
* @return number of entries in @a rh.
|
||||
*/
|
||||
|
@ -251,12 +251,15 @@ batch_deposit_run (void *cls,
|
||||
&wire_salt),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url
|
||||
= TALER_TESTING_get_exchange_url (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
memset (cdds,
|
||||
0,
|
||||
sizeof (cdds));
|
||||
@ -383,7 +386,10 @@ batch_deposit_run (void *cls,
|
||||
.refund_deadline = ds->refund_deadline
|
||||
};
|
||||
|
||||
ds->dh = TALER_EXCHANGE_batch_deposit (exchange,
|
||||
ds->dh = TALER_EXCHANGE_batch_deposit (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
TALER_TESTING_get_keys (is),
|
||||
&dcd,
|
||||
ds->num_coins,
|
||||
cdds,
|
||||
|
@ -190,13 +190,16 @@ get_run (void *cls,
|
||||
struct ContractGetState *ds = cls;
|
||||
const struct TALER_ContractDiffiePrivateP *contract_priv;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ds->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
ref = TALER_TESTING_interpreter_lookup_command (ds->is,
|
||||
ds->contract_ref);
|
||||
GNUNET_assert (NULL != ref);
|
||||
@ -210,7 +213,8 @@ get_run (void *cls,
|
||||
}
|
||||
ds->contract_priv = *contract_priv;
|
||||
ds->dh = TALER_EXCHANGE_contract_get (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
contract_priv,
|
||||
&get_cb,
|
||||
ds);
|
||||
|
@ -98,7 +98,7 @@ struct DepositState
|
||||
/**
|
||||
* Deposit handle while operation is running.
|
||||
*/
|
||||
struct TALER_EXCHANGE_DepositHandle *dh;
|
||||
struct TALER_EXCHANGE_BatchDepositHandle *dh;
|
||||
|
||||
/**
|
||||
* Timestamp of the /deposit operation in the wallet (contract signing time).
|
||||
@ -215,7 +215,7 @@ do_retry (void *cls)
|
||||
*/
|
||||
static void
|
||||
deposit_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_DepositResult *dr)
|
||||
const struct TALER_EXCHANGE_BatchDepositResult *dr)
|
||||
{
|
||||
struct DepositState *ds = cls;
|
||||
|
||||
@ -254,10 +254,11 @@ deposit_cb (void *cls,
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
{
|
||||
GNUNET_assert (1 == dr->details.ok.num_signatures);
|
||||
ds->deposit_succeeded = GNUNET_YES;
|
||||
ds->exchange_timestamp = dr->details.ok.deposit_timestamp;
|
||||
ds->exchange_pub = *dr->details.ok.exchange_pub;
|
||||
ds->exchange_sig = *dr->details.ok.exchange_sig;
|
||||
ds->exchange_sig = dr->details.ok.exchange_sigs[0];
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
}
|
||||
@ -296,12 +297,15 @@ deposit_run (void *cls,
|
||||
&wire_salt),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url
|
||||
= TALER_TESTING_get_exchange_url (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
ds->is = is;
|
||||
if (NULL != ds->deposit_reference)
|
||||
{
|
||||
@ -469,8 +473,12 @@ deposit_run (void *cls,
|
||||
.refund_deadline = ds->refund_deadline
|
||||
};
|
||||
|
||||
ds->dh = TALER_EXCHANGE_deposit (exchange,
|
||||
ds->dh = TALER_EXCHANGE_batch_deposit (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
TALER_TESTING_get_keys (is),
|
||||
&dcd,
|
||||
1,
|
||||
&cdd,
|
||||
&deposit_cb,
|
||||
ds,
|
||||
@ -505,7 +513,7 @@ deposit_cleanup (void *cls,
|
||||
{
|
||||
TALER_TESTING_command_incomplete (ds->is,
|
||||
cmd->label);
|
||||
TALER_EXCHANGE_deposit_cancel (ds->dh);
|
||||
TALER_EXCHANGE_batch_deposit_cancel (ds->dh);
|
||||
ds->dh = NULL;
|
||||
}
|
||||
if (NULL != ds->retry_task)
|
||||
|
@ -198,12 +198,8 @@ track_transaction_run (void *cls,
|
||||
struct TALER_MerchantWireHashP h_wire_details;
|
||||
struct TALER_PrivateContractHashP h_contract_terms;
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
tts->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
tts->is = is;
|
||||
transaction_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (tts->is,
|
||||
@ -275,7 +271,10 @@ track_transaction_run (void *cls,
|
||||
return;
|
||||
}
|
||||
|
||||
tts->tth = TALER_EXCHANGE_deposits_get (exchange,
|
||||
tts->tth = TALER_EXCHANGE_deposits_get (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
merchant_priv,
|
||||
&h_wire_details,
|
||||
&h_contract_terms,
|
||||
|
@ -49,9 +49,9 @@ struct GetAuditorState
|
||||
struct TALER_TESTING_Interpreter *is;
|
||||
|
||||
/**
|
||||
* Auditor handle we produced.
|
||||
* Auditor handle used to get the configuration.
|
||||
*/
|
||||
struct TALER_AUDITOR_Handle *auditor;
|
||||
struct TALER_AUDITOR_GetConfigHandle *auditor;
|
||||
|
||||
/**
|
||||
* URL of the auditor.
|
||||
@ -70,23 +70,28 @@ struct GetAuditorState
|
||||
* Function called with information about the auditor.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response data
|
||||
* @param vi basic information about the auditor
|
||||
* @param compat protocol compatibility information
|
||||
* @param vr response data
|
||||
*/
|
||||
static void
|
||||
version_cb (
|
||||
void *cls,
|
||||
const struct TALER_AUDITOR_HttpResponse *hr,
|
||||
const struct TALER_AUDITOR_VersionInformation *vi,
|
||||
enum TALER_AUDITOR_VersionCompatibility compat)
|
||||
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||
{
|
||||
struct GetAuditorState *gas = cls;
|
||||
|
||||
if (MHD_HTTP_OK != hr->http_status)
|
||||
gas->auditor = NULL;
|
||||
if (MHD_HTTP_OK != vr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (gas->is,
|
||||
hr->http_status);
|
||||
vr->hr.http_status);
|
||||
return;
|
||||
}
|
||||
if ( (NULL != gas->priv_file) &&
|
||||
(0 != GNUNET_memcmp (&gas->auditor_pub,
|
||||
&vr->details.ok.vi.auditor_pub)) )
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (gas->is);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (gas->is);
|
||||
@ -130,7 +135,7 @@ get_auditor_run (void *cls,
|
||||
}
|
||||
gas->is = is;
|
||||
gas->auditor
|
||||
= TALER_AUDITOR_connect (TALER_TESTING_interpreter_get_context (is),
|
||||
= TALER_AUDITOR_get_config (TALER_TESTING_interpreter_get_context (is),
|
||||
gas->auditor_url,
|
||||
&version_cb,
|
||||
gas);
|
||||
@ -157,7 +162,8 @@ get_auditor_cleanup (void *cls,
|
||||
|
||||
if (NULL != gas->auditor)
|
||||
{
|
||||
TALER_AUDITOR_disconnect (gas->auditor);
|
||||
GNUNET_break (0);
|
||||
TALER_AUDITOR_get_config_cancel (gas->auditor);
|
||||
gas->auditor = NULL;
|
||||
}
|
||||
GNUNET_free (gas->priv_file);
|
||||
@ -186,7 +192,6 @@ get_auditor_traits (void *cls,
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv),
|
||||
TALER_TESTING_make_trait_auditor_pub (&gas->auditor_pub),
|
||||
TALER_TESTING_make_trait_auditor (gas->auditor),
|
||||
TALER_TESTING_make_trait_auditor_url (gas->auditor_url),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
@ -189,7 +189,7 @@ get_exchange_traits (void *cls,
|
||||
{
|
||||
struct GetExchangeState *ges = cls;
|
||||
unsigned int off = (NULL == ges->master_priv_file) ? 1 : 0;
|
||||
const struct TALER_EXCHANGE_Keys *keys
|
||||
struct TALER_EXCHANGE_Keys *keys
|
||||
= TALER_EXCHANGE_get_keys (ges->exchange);
|
||||
|
||||
if (NULL != keys)
|
||||
@ -198,6 +198,7 @@ get_exchange_traits (void *cls,
|
||||
TALER_TESTING_make_trait_master_priv (&ges->master_priv),
|
||||
TALER_TESTING_make_trait_master_pub (&keys->master_pub),
|
||||
TALER_TESTING_make_trait_exchange (ges->exchange),
|
||||
TALER_TESTING_make_trait_keys (keys),
|
||||
TALER_TESTING_make_trait_exchange_url (ges->exchange_url),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
@ -127,13 +127,16 @@ proof_kyc_run (void *cls,
|
||||
const struct TALER_TESTING_Command *res_cmd;
|
||||
const struct TALER_PaytoHashP *h_payto;
|
||||
char *uargs;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
kps->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
res_cmd = TALER_TESTING_interpreter_lookup_command (
|
||||
kps->is,
|
||||
kps->payment_target_reference);
|
||||
@ -157,7 +160,9 @@ proof_kyc_run (void *cls,
|
||||
GNUNET_asprintf (&uargs,
|
||||
"&code=%s",
|
||||
kps->code);
|
||||
kps->kph = TALER_EXCHANGE_kyc_proof (exchange,
|
||||
kps->kph = TALER_EXCHANGE_kyc_proof (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
h_payto,
|
||||
kps->logic,
|
||||
uargs,
|
||||
|
@ -147,13 +147,16 @@ wallet_kyc_run (void *cls,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct KycWalletGetState *kwg = cls;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
kwg->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
kwg->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
if (NULL != kwg->reserve_reference)
|
||||
{
|
||||
const struct TALER_TESTING_Command *res_cmd;
|
||||
@ -185,9 +188,11 @@ wallet_kyc_run (void *cls,
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&kwg->reserve_priv.eddsa_priv,
|
||||
&kwg->reserve_pub.eddsa_pub);
|
||||
kwg->reserve_payto_uri
|
||||
= TALER_reserve_make_payto (TALER_EXCHANGE_get_base_url (exchange),
|
||||
= TALER_reserve_make_payto (exchange_url,
|
||||
&kwg->reserve_pub);
|
||||
kwg->kwh = TALER_EXCHANGE_kyc_wallet (exchange,
|
||||
kwg->kwh = TALER_EXCHANGE_kyc_wallet (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
&kwg->reserve_priv,
|
||||
&kwg->balance,
|
||||
&wallet_kyc_cb,
|
||||
|
@ -189,12 +189,8 @@ deposit_run (void *cls,
|
||||
{
|
||||
struct PurseCreateDepositState *ds = cls;
|
||||
struct TALER_EXCHANGE_PurseDeposit deposits[ds->num_coin_references];
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ds->is = is;
|
||||
for (unsigned int i = 0; i<ds->num_coin_references; i++)
|
||||
{
|
||||
@ -259,7 +255,9 @@ deposit_run (void *cls,
|
||||
"pay_deadline",
|
||||
GNUNET_JSON_from_timestamp (ds->purse_expiration)));
|
||||
ds->dh = TALER_EXCHANGE_purse_create_with_deposit (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
&ds->purse_priv,
|
||||
&ds->merge_priv,
|
||||
&ds->contract_priv,
|
||||
|
@ -97,12 +97,15 @@ purse_delete_run (void *cls,
|
||||
struct PurseDeleteState *pds = cls;
|
||||
const struct TALER_PurseContractPrivateKeyP *purse_priv;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
ref = TALER_TESTING_interpreter_lookup_command (is,
|
||||
pds->purse_cmd);
|
||||
if (NULL == ref)
|
||||
@ -121,7 +124,8 @@ purse_delete_run (void *cls,
|
||||
}
|
||||
pds->is = is;
|
||||
pds->pdh = TALER_EXCHANGE_purse_delete (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
purse_priv,
|
||||
&purse_delete_cb,
|
||||
pds);
|
||||
|
@ -259,11 +259,7 @@ deposit_run (void *cls,
|
||||
struct TALER_EXCHANGE_PurseDeposit deposits[ds->num_coin_references];
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub;
|
||||
const struct TALER_TESTING_Command *purse_cmd;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
(void) cmd;
|
||||
ds->is = is;
|
||||
purse_cmd = TALER_TESTING_interpreter_lookup_command (is,
|
||||
@ -321,7 +317,9 @@ deposit_run (void *cls,
|
||||
}
|
||||
|
||||
ds->dh = TALER_EXCHANGE_purse_deposit (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
NULL, /* FIXME #7271: WADs support: purse exchange URL */
|
||||
&ds->purse_pub,
|
||||
ds->min_age,
|
||||
|
@ -183,11 +183,7 @@ status_run (void *cls,
|
||||
{
|
||||
struct StatusState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_purse;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
create_purse
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
@ -202,7 +198,10 @@ status_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
ss->pgh = TALER_EXCHANGE_purse_get (exchange,
|
||||
ss->pgh = TALER_EXCHANGE_purse_get (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
ss->purse_pub,
|
||||
ss->timeout,
|
||||
ss->wait_for_merge,
|
||||
|
@ -201,12 +201,8 @@ merge_run (void *cls,
|
||||
const struct TALER_PurseMergePrivateKeyP *merge_priv;
|
||||
const json_t *ct;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ds->is = is;
|
||||
ref = TALER_TESTING_interpreter_lookup_command (ds->is,
|
||||
ds->merge_ref);
|
||||
@ -322,7 +318,9 @@ merge_run (void *cls,
|
||||
&ds->merge_pub.eddsa_pub);
|
||||
ds->merge_timestamp = GNUNET_TIME_timestamp_get ();
|
||||
ds->dh = TALER_EXCHANGE_account_merge (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
NULL, /* no wad */
|
||||
&ds->reserve_priv,
|
||||
&ds->purse_pub,
|
||||
|
@ -182,11 +182,7 @@ recoup_run (void *cls,
|
||||
char *cref;
|
||||
unsigned int idx;
|
||||
const struct TALER_ExchangeWithdrawValues *ewv;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ps->is = is;
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_parse_coin_reference (
|
||||
@ -259,7 +255,10 @@ recoup_run (void *cls,
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Trying to recoup denomination '%s'\n",
|
||||
TALER_B2S (&denom_pub->h_key));
|
||||
ps->ph = TALER_EXCHANGE_recoup (exchange,
|
||||
ps->ph = TALER_EXCHANGE_recoup (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
denom_pub,
|
||||
coin_sig,
|
||||
ewv,
|
||||
|
@ -184,11 +184,7 @@ recoup_refresh_run (void *cls,
|
||||
const struct TALER_ExchangeWithdrawValues *ewv;
|
||||
char *cref;
|
||||
unsigned int idx;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
rrs->is = is;
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_parse_coin_reference (
|
||||
@ -273,7 +269,10 @@ recoup_refresh_run (void *cls,
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Trying to recoup_refresh denomination '%s'\n",
|
||||
TALER_B2S (&denom_pub->h_key));
|
||||
rrs->ph = TALER_EXCHANGE_recoup_refresh (exchange,
|
||||
rrs->ph = TALER_EXCHANGE_recoup_refresh (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
denom_pub,
|
||||
coin_sig,
|
||||
ewv,
|
||||
|
@ -496,12 +496,8 @@ refresh_reveal_run (void *cls,
|
||||
struct RefreshRevealState *rrs = cls;
|
||||
struct RefreshMeltState *rms;
|
||||
const struct TALER_TESTING_Command *melt_cmd;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
rrs->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
rrs->is = is;
|
||||
melt_cmd = TALER_TESTING_interpreter_lookup_command (is,
|
||||
rrs->melt_reference);
|
||||
@ -518,7 +514,9 @@ refresh_reveal_run (void *cls,
|
||||
|
||||
for (unsigned int i = 0; i<rms->num_fresh_coins; i++)
|
||||
alg_values[i] = rms->mbds[i].alg_value;
|
||||
rrs->rrh = TALER_EXCHANGE_refreshes_reveal (exchange,
|
||||
rrs->rrh = TALER_EXCHANGE_refreshes_reveal (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
&rms->rms,
|
||||
&rms->refresh_data,
|
||||
rms->num_fresh_coins,
|
||||
@ -783,13 +781,16 @@ refresh_link_run (void *cls,
|
||||
const struct TALER_TESTING_Command *reveal_cmd;
|
||||
const struct TALER_TESTING_Command *melt_cmd;
|
||||
const struct TALER_TESTING_Command *coin_cmd;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
rls->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
rls->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
reveal_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
|
||||
rls->reveal_reference);
|
||||
if (NULL == reveal_cmd)
|
||||
@ -832,7 +833,9 @@ refresh_link_run (void *cls,
|
||||
}
|
||||
|
||||
/* finally, use private key from withdraw sign command */
|
||||
rls->rlh = TALER_EXCHANGE_link (exchange,
|
||||
rls->rlh = TALER_EXCHANGE_link (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
coin_priv,
|
||||
rms->refresh_data.melt_age_commitment_proof,
|
||||
&link_cb,
|
||||
@ -908,12 +911,8 @@ melt_cb (void *cls,
|
||||
{
|
||||
struct RefreshMeltState *rms = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &mr->hr;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (rms->is);
|
||||
|
||||
rms->rmh = NULL;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
if (rms->expected_response_code != hr->http_status)
|
||||
{
|
||||
if (0 != rms->do_retry)
|
||||
@ -973,7 +972,10 @@ melt_cb (void *cls,
|
||||
{
|
||||
TALER_LOG_DEBUG ("Doubling the melt (%s)\n",
|
||||
rms->cmd->label);
|
||||
rms->rmh = TALER_EXCHANGE_melt (exchange,
|
||||
rms->rmh = TALER_EXCHANGE_melt (
|
||||
TALER_TESTING_interpreter_get_context (rms->is),
|
||||
TALER_TESTING_get_exchange_url (rms->is),
|
||||
TALER_TESTING_get_keys (rms->is),
|
||||
&rms->rms,
|
||||
&rms->refresh_data,
|
||||
&melt_cb,
|
||||
@ -1149,7 +1151,10 @@ melt_run (void *cls,
|
||||
GNUNET_assert (age_restricted ==
|
||||
(NULL != age_commitment_proof));
|
||||
|
||||
rms->rmh = TALER_EXCHANGE_melt (exchange,
|
||||
rms->rmh = TALER_EXCHANGE_melt (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
&rms->rms,
|
||||
&rms->refresh_data,
|
||||
&melt_cb,
|
||||
|
@ -53,11 +53,6 @@ struct RefundState
|
||||
*/
|
||||
uint64_t refund_transaction_id;
|
||||
|
||||
/**
|
||||
* Connection to the exchange.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
/**
|
||||
* Handle to the refund operation.
|
||||
*/
|
||||
@ -116,9 +111,6 @@ refund_run (void *cls,
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv;
|
||||
const struct TALER_TESTING_Command *coin_cmd;
|
||||
|
||||
rs->exchange = TALER_TESTING_get_exchange (is);
|
||||
if (NULL == rs->exchange)
|
||||
return;
|
||||
rs->is = is;
|
||||
if (GNUNET_OK !=
|
||||
TALER_string_to_amount (rs->refund_amount,
|
||||
@ -172,7 +164,10 @@ refund_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
rs->rh = TALER_EXCHANGE_refund (rs->exchange,
|
||||
rs->rh = TALER_EXCHANGE_refund (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
&refund_amount,
|
||||
&h_contract_terms,
|
||||
&coin,
|
||||
|
@ -152,12 +152,15 @@ attest_run (void *cls,
|
||||
{
|
||||
struct AttestState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
ss->reserve_reference);
|
||||
@ -179,7 +182,9 @@ attest_run (void *cls,
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
|
||||
&ss->reserve_pub.eddsa_pub);
|
||||
ss->rsh = TALER_EXCHANGE_reserves_attest (exchange,
|
||||
ss->rsh = TALER_EXCHANGE_reserves_attest (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
ss->reserve_priv,
|
||||
ss->attrs_len,
|
||||
ss->attrs,
|
||||
|
@ -142,11 +142,7 @@ close_run (void *cls,
|
||||
{
|
||||
struct CloseState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
@ -169,7 +165,9 @@ close_run (void *cls,
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
|
||||
&ss->reserve_pub.eddsa_pub);
|
||||
ss->rsh = TALER_EXCHANGE_reserves_close (exchange,
|
||||
ss->rsh = TALER_EXCHANGE_reserves_close (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
ss->reserve_priv,
|
||||
ss->target_account,
|
||||
&reserve_close_cb,
|
||||
|
@ -178,12 +178,15 @@ status_run (void *cls,
|
||||
{
|
||||
struct StatusState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
ss->reserve_reference);
|
||||
@ -197,7 +200,9 @@ status_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
ss->rsh = TALER_EXCHANGE_reserves_get (exchange,
|
||||
ss->rsh = TALER_EXCHANGE_reserves_get (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
ss->reserve_pubp,
|
||||
ss->timeout,
|
||||
&reserve_status_cb,
|
||||
|
@ -125,12 +125,15 @@ get_attestable_run (void *cls,
|
||||
const struct TALER_TESTING_Command *ref_reserve;
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv;
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
const char *exchange_url;
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
exchange_url = TALER_TESTING_get_exchange_url (is);
|
||||
if (NULL == exchange_url)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
}
|
||||
ref_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
ss->reserve_reference);
|
||||
@ -162,7 +165,9 @@ get_attestable_run (void *cls,
|
||||
}
|
||||
ss->reserve_pub = *reserve_pub;
|
||||
}
|
||||
ss->rgah = TALER_EXCHANGE_reserves_get_attestable (exchange,
|
||||
ss->rgah = TALER_EXCHANGE_reserves_get_attestable (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
&ss->reserve_pub,
|
||||
&reserve_get_attestable_cb,
|
||||
ss);
|
||||
|
@ -369,7 +369,10 @@ history_run (void *cls,
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
|
||||
&ss->reserve_pub.eddsa_pub);
|
||||
ss->rsh = TALER_EXCHANGE_reserves_history (exchange,
|
||||
ss->rsh = TALER_EXCHANGE_reserves_history (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
ss->reserve_priv,
|
||||
&reserve_history_cb,
|
||||
ss);
|
||||
|
@ -256,7 +256,9 @@ open_run (void *cls,
|
||||
cpi->h_denom_pub = denom_pub->h_key;
|
||||
}
|
||||
ss->rsh = TALER_EXCHANGE_reserves_open (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
ss->reserve_priv,
|
||||
&ss->reserve_pay,
|
||||
ss->cpl,
|
||||
|
@ -245,7 +245,9 @@ purse_run (void *cls,
|
||||
GNUNET_JSON_from_timestamp (ds->purse_expiration)));
|
||||
ds->merge_timestamp = GNUNET_TIME_timestamp_get ();
|
||||
ds->dh = TALER_EXCHANGE_purse_create_with_merge (
|
||||
exchange,
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
&ds->reserve_priv,
|
||||
&ds->purse_priv,
|
||||
&ds->merge_priv,
|
||||
|
@ -341,7 +341,10 @@ status_run (void *cls,
|
||||
}
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
|
||||
&ss->reserve_pub.eddsa_pub);
|
||||
ss->rsh = TALER_EXCHANGE_reserves_status (exchange,
|
||||
ss->rsh = TALER_EXCHANGE_reserves_status (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
ss->reserve_priv,
|
||||
&reserve_status_cb,
|
||||
ss);
|
||||
|
@ -345,7 +345,10 @@ track_transfer_run (void *cls,
|
||||
}
|
||||
GNUNET_assert (NULL != wtid_ptr);
|
||||
}
|
||||
tts->tth = TALER_EXCHANGE_transfers_get (exchange,
|
||||
tts->tth = TALER_EXCHANGE_transfers_get (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
TALER_TESTING_get_exchange_url (is),
|
||||
TALER_TESTING_get_keys (is),
|
||||
wtid_ptr,
|
||||
&track_transfer_cb,
|
||||
tts);
|
||||
|
@ -1,796 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2018-2020 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 3, or
|
||||
(at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with TALER; see the file COPYING. If not, see
|
||||
<http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file testing/testing_api_helpers_exchange.c
|
||||
* @brief helper functions
|
||||
* @author Christian Grothoff
|
||||
* @author Marcello Stanisci
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_extensions.h"
|
||||
#include "taler_testing_lib.h"
|
||||
|
||||
/**
|
||||
* Run multiple taler-exchange-httpd processes in
|
||||
* parallel using GNU parallel?
|
||||
*/
|
||||
#define GNU_PARALLEL 0
|
||||
|
||||
|
||||
void
|
||||
TALER_TESTING_cleanup_files (const char *config_name)
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_parse_and_run (config_name,
|
||||
&TALER_TESTING_cleanup_files_cfg,
|
||||
NULL))
|
||||
exit (77);
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_run_auditor_exchange (const char *config_filename,
|
||||
const char *exchange_master_pub,
|
||||
const char *exchange_base_url,
|
||||
int do_remove)
|
||||
{
|
||||
struct GNUNET_OS_Process *proc;
|
||||
enum GNUNET_OS_ProcessStatusType type;
|
||||
unsigned long code;
|
||||
|
||||
TALER_LOG_DEBUG ("Add exchange (%s,%s) to the auditor\n",
|
||||
exchange_base_url,
|
||||
exchange_master_pub);
|
||||
|
||||
proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
"taler-auditor-exchange",
|
||||
"taler-auditor-exchange",
|
||||
"-c", config_filename,
|
||||
"-u", exchange_base_url,
|
||||
"-m", exchange_master_pub,
|
||||
(GNUNET_YES == do_remove)
|
||||
? "-r"
|
||||
: NULL,
|
||||
NULL);
|
||||
if (NULL == proc)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to run `taler-auditor-exchange`, is your PATH correct?\n");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait_status (proc,
|
||||
&type,
|
||||
&code));
|
||||
GNUNET_OS_process_destroy (proc);
|
||||
if ( (0 != code) ||
|
||||
(GNUNET_OS_PROCESS_EXITED != type) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"taler-auditor-exchange terminated with error (%d/%d)\n",
|
||||
(int) type,
|
||||
(int) code);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_exchange_db_reset (const char *config_filename)
|
||||
{
|
||||
struct GNUNET_OS_Process *proc;
|
||||
enum GNUNET_OS_ProcessStatusType type;
|
||||
unsigned long code;
|
||||
|
||||
proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
"taler-exchange-dbinit",
|
||||
"taler-exchange-dbinit",
|
||||
"-c", config_filename,
|
||||
"-L", "WARNING",
|
||||
"-r",
|
||||
NULL);
|
||||
if (NULL == proc)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to run `taler-exchange-dbinit`, is your PATH correct?\n");
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if (GNUNET_SYSERR ==
|
||||
GNUNET_OS_process_wait_status (proc,
|
||||
&type,
|
||||
&code))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_OS_process_destroy (proc);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_OS_process_destroy (proc);
|
||||
if ( (type == GNUNET_OS_PROCESS_EXITED) &&
|
||||
(0 != code) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to setup (exchange) database, exit code %d\n",
|
||||
(int) code);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if ( (type != GNUNET_OS_PROCESS_EXITED) ||
|
||||
(0 != code) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected error (%d/%d) running `taler-exchange-dbinit'!\n",
|
||||
(int) type,
|
||||
(int) code);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_auditor_db_reset (const char *config_filename)
|
||||
{
|
||||
struct GNUNET_OS_Process *proc;
|
||||
enum GNUNET_OS_ProcessStatusType type;
|
||||
unsigned long code;
|
||||
|
||||
proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
"taler-auditor-dbinit",
|
||||
"taler-auditor-dbinit",
|
||||
"-c", config_filename,
|
||||
"-R",
|
||||
NULL);
|
||||
if (NULL == proc)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to run `taler-auditor-dbinit`, is your PATH correct?\n");
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if (GNUNET_SYSERR ==
|
||||
GNUNET_OS_process_wait_status (proc,
|
||||
&type,
|
||||
&code))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_OS_process_destroy (proc);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_OS_process_destroy (proc);
|
||||
if ( (type == GNUNET_OS_PROCESS_EXITED) &&
|
||||
(0 != code) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to setup (auditor) database, exit code %d\n",
|
||||
(int) code);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if ( (type != GNUNET_OS_PROCESS_EXITED) ||
|
||||
(0 != code) )
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected error (%d/%d) running `taler-auditor-dbinit'!\n",
|
||||
(int) type,
|
||||
(int) code);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Type of closure for
|
||||
* #sign_keys_for_exchange.
|
||||
*/
|
||||
struct SignInfo
|
||||
{
|
||||
/**
|
||||
* Members will be set to the exchange configuration.
|
||||
*/
|
||||
struct TALER_TESTING_ExchangeConfiguration *ec;
|
||||
|
||||
/**
|
||||
* Name of the configuration file to use.
|
||||
*/
|
||||
const char *config_filename;
|
||||
|
||||
/**
|
||||
* Did we reset the database?
|
||||
*/
|
||||
int db_reset;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sign the keys for an exchange given configuration @a cfg.
|
||||
* The information to be signed must be in a file "auditor.in".
|
||||
*
|
||||
* @param[in,out] cls a `struct SignInfo` with further parameters
|
||||
* @param cfg configuration to use
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
sign_keys_for_exchange (void *cls,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||
{
|
||||
struct SignInfo *si = cls;
|
||||
char *exchange_master_pub;
|
||||
int ret;
|
||||
|
||||
/* Load the extensions */
|
||||
if (GNUNET_OK != TALER_extensions_init (cfg))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"couldn't load extensions");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"exchange",
|
||||
"BASE_URL",
|
||||
&si->ec->exchange_url))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
|
||||
"exchange",
|
||||
"BASE_URL");
|
||||
si->ec->exchange_url = NULL;
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"auditor",
|
||||
"BASE_URL",
|
||||
&si->ec->auditor_url))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
|
||||
"auditor",
|
||||
"BASE_URL");
|
||||
GNUNET_free (si->ec->exchange_url);
|
||||
si->ec->exchange_url = NULL;
|
||||
si->ec->auditor_url = NULL;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"exchange",
|
||||
"MASTER_PUBLIC_KEY",
|
||||
&exchange_master_pub))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"MASTER_PUBLIC_KEY");
|
||||
ret = GNUNET_SYSERR;
|
||||
goto fail;
|
||||
}
|
||||
if ( (GNUNET_OK !=
|
||||
TALER_TESTING_run_auditor_exchange (si->config_filename,
|
||||
exchange_master_pub,
|
||||
si->ec->exchange_url,
|
||||
GNUNET_NO)) &&
|
||||
(GNUNET_YES == si->db_reset) )
|
||||
{
|
||||
ret = GNUNET_NO;
|
||||
goto fail;
|
||||
}
|
||||
GNUNET_free (exchange_master_pub);
|
||||
return GNUNET_OK;
|
||||
fail:
|
||||
GNUNET_free (si->ec->exchange_url);
|
||||
GNUNET_free (si->ec->auditor_url);
|
||||
si->ec->exchange_url = NULL;
|
||||
si->ec->auditor_url = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_prepare_exchange (const char *config_filename,
|
||||
int reset_db,
|
||||
struct TALER_TESTING_ExchangeConfiguration *ec)
|
||||
{
|
||||
struct SignInfo si = {
|
||||
.config_filename = config_filename,
|
||||
.ec = ec,
|
||||
.db_reset = reset_db
|
||||
};
|
||||
|
||||
if (GNUNET_YES == reset_db)
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_exchange_db_reset (config_filename))
|
||||
return GNUNET_NO;
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_auditor_db_reset (config_filename))
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_parse_and_run (config_filename,
|
||||
&sign_keys_for_exchange,
|
||||
&si))
|
||||
return GNUNET_NO;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
TALER_TESTING_wait_exchange_ready (const char *base_url)
|
||||
{
|
||||
char *wget_cmd;
|
||||
unsigned int iter;
|
||||
|
||||
GNUNET_asprintf (&wget_cmd,
|
||||
"wget -q -t 1 -T 1 %sseed -o /dev/null -O /dev/null",
|
||||
base_url); // make sure ends with '/'
|
||||
/* give child time to start and bind against the socket */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Waiting for `taler-exchange-httpd` service to be ready (check with: %s)\n",
|
||||
wget_cmd);
|
||||
iter = 0;
|
||||
do
|
||||
{
|
||||
if (10 == iter)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to launch `taler-exchange-httpd` service (or `wget')\n");
|
||||
GNUNET_free (wget_cmd);
|
||||
return 77;
|
||||
}
|
||||
sleep (1);
|
||||
iter++;
|
||||
}
|
||||
while (0 != system (wget_cmd));
|
||||
GNUNET_free (wget_cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wait for the auditor to have started. Waits for at
|
||||
* most 10s, after that returns 77 to indicate an error.
|
||||
*
|
||||
* @param base_url what URL should we expect the auditor
|
||||
* to be running at
|
||||
* @return 0 on success
|
||||
*/
|
||||
int
|
||||
TALER_TESTING_wait_auditor_ready (const char *base_url)
|
||||
{
|
||||
char *wget_cmd;
|
||||
unsigned int iter;
|
||||
|
||||
GNUNET_asprintf (&wget_cmd,
|
||||
"wget -q -t 1 -T 1 %sversion -o /dev/null -O /dev/null",
|
||||
base_url); // make sure ends with '/'
|
||||
/* give child time to start and bind against the socket */
|
||||
fprintf (stderr,
|
||||
"Waiting for `taler-auditor-httpd' to be ready at %s\n",
|
||||
base_url);
|
||||
iter = 0;
|
||||
do
|
||||
{
|
||||
if (10 == iter)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to launch `taler-auditor-httpd' (or `wget')\n");
|
||||
GNUNET_free (wget_cmd);
|
||||
return 77;
|
||||
}
|
||||
fprintf (stderr, ".\n");
|
||||
sleep (1);
|
||||
iter++;
|
||||
}
|
||||
while (0 != system (wget_cmd));
|
||||
GNUNET_free (wget_cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_setup_with_exchange (TALER_TESTING_Main main_cb,
|
||||
void *main_cb_cls,
|
||||
const char *config_file)
|
||||
{
|
||||
struct TALER_TESTING_SetupContext setup_ctx = {
|
||||
.config_filename = config_file,
|
||||
.main_cb = main_cb,
|
||||
.main_cb_cls = main_cb_cls
|
||||
};
|
||||
enum GNUNET_GenericReturnValue result;
|
||||
|
||||
result =
|
||||
GNUNET_CONFIGURATION_parse_and_run (config_file,
|
||||
&TALER_TESTING_setup_with_exchange_cfg,
|
||||
&setup_ctx);
|
||||
if (GNUNET_OK != result)
|
||||
return result;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop taler-exchange-crypto helpers.
|
||||
*
|
||||
* @param[in] helpers the process handles.
|
||||
*/
|
||||
static void
|
||||
stop_helpers (struct GNUNET_OS_Process *helpers[3])
|
||||
{
|
||||
for (unsigned int i = 0; i<3; i++)
|
||||
{
|
||||
if (NULL == helpers[i])
|
||||
continue;
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (helpers[i],
|
||||
SIGTERM));
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait (helpers[i]));
|
||||
GNUNET_OS_process_destroy (helpers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start taler-exchange-crypto helpers.
|
||||
*
|
||||
* @param config_filename configuration file to use
|
||||
* @param[out] helpers where to store the process handles.
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
start_helpers (const char *config_filename,
|
||||
struct GNUNET_OS_Process *helpers[3])
|
||||
{
|
||||
char *dir;
|
||||
const struct GNUNET_OS_ProjectData *pd;
|
||||
|
||||
pd = GNUNET_OS_project_data_get ();
|
||||
GNUNET_OS_init (TALER_project_data_default ());
|
||||
dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR);
|
||||
GNUNET_OS_init (pd);
|
||||
if (NULL == dir)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
{
|
||||
char *fn;
|
||||
|
||||
GNUNET_asprintf (&fn,
|
||||
"%s/%s",
|
||||
dir,
|
||||
"taler-exchange-secmod-eddsa");
|
||||
helpers[0] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
fn,
|
||||
"taler-exchange-secmod-eddsa",
|
||||
"-c", config_filename,
|
||||
"-L", "INFO",
|
||||
NULL);
|
||||
GNUNET_free (fn);
|
||||
}
|
||||
{
|
||||
char *fn;
|
||||
|
||||
GNUNET_asprintf (&fn,
|
||||
"%s/%s",
|
||||
dir,
|
||||
"taler-exchange-secmod-rsa");
|
||||
helpers[1] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
fn,
|
||||
"taler-exchange-secmod-rsa",
|
||||
"-c", config_filename,
|
||||
"-L", "INFO",
|
||||
NULL);
|
||||
GNUNET_free (fn);
|
||||
}
|
||||
{
|
||||
char *fn;
|
||||
|
||||
GNUNET_asprintf (&fn,
|
||||
"%s/%s",
|
||||
dir,
|
||||
"taler-exchange-secmod-cs");
|
||||
helpers[2] = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
fn,
|
||||
"taler-exchange-secmod-cs",
|
||||
"-c", config_filename,
|
||||
"-L", "INFO",
|
||||
NULL);
|
||||
GNUNET_free (fn);
|
||||
}
|
||||
GNUNET_free (dir);
|
||||
if ( (NULL == helpers[0]) ||
|
||||
(NULL == helpers[1]) ||
|
||||
(NULL == helpers[2]) )
|
||||
{
|
||||
stop_helpers (helpers);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_setup_with_exchange_cfg (
|
||||
void *cls,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||
{
|
||||
const struct TALER_TESTING_SetupContext *setup_ctx = cls;
|
||||
struct GNUNET_OS_Process *exchanged;
|
||||
struct GNUNET_OS_Process *helpers[3];
|
||||
unsigned long long port;
|
||||
char *serve;
|
||||
char *base_url;
|
||||
int result;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"exchange",
|
||||
"SERVE",
|
||||
&serve))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"SERVE");
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (0 == strcmp ("tcp",
|
||||
serve))
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_number (cfg,
|
||||
"exchange",
|
||||
"PORT",
|
||||
&port))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"PORT");
|
||||
GNUNET_free (serve);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
|
||||
(uint16_t) port))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Required port %llu not available, skipping.\n",
|
||||
port);
|
||||
GNUNET_free (serve);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
}
|
||||
GNUNET_free (serve);
|
||||
if (GNUNET_OK !=
|
||||
start_helpers (setup_ctx->config_filename,
|
||||
helpers))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return 77;
|
||||
}
|
||||
exchanged = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
#if GNU_PARALLEL
|
||||
"parallel",
|
||||
#endif
|
||||
"taler-exchange-httpd",
|
||||
"taler-exchange-httpd",
|
||||
"-L", "INFO",
|
||||
"-a", /* some tests may need timetravel */
|
||||
"-c", setup_ctx->config_filename,
|
||||
#if GNU_PARALLEL
|
||||
"-r",
|
||||
":::",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
#endif
|
||||
NULL);
|
||||
if (NULL == exchanged)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
stop_helpers (helpers);
|
||||
return 77;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"exchange",
|
||||
"BASE_URL",
|
||||
&base_url))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"exchange",
|
||||
"BASE_URL");
|
||||
stop_helpers (helpers);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (0 != TALER_TESTING_wait_exchange_ready (base_url))
|
||||
{
|
||||
GNUNET_free (base_url);
|
||||
stop_helpers (helpers);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (exchanged,
|
||||
SIGTERM));
|
||||
#if GNU_PARALLEL
|
||||
/* GNU Parallel kills on 2nd SIGTERM, need to give it a
|
||||
chance to process the 1st signal first... */
|
||||
sleep (1);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (exchanged,
|
||||
SIGTERM));
|
||||
#endif
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait (exchanged));
|
||||
GNUNET_OS_process_destroy (exchanged);
|
||||
return 77;
|
||||
}
|
||||
GNUNET_free (base_url);
|
||||
|
||||
/* NOTE: this call blocks. */
|
||||
result = TALER_TESTING_setup (setup_ctx->main_cb,
|
||||
setup_ctx->main_cb_cls,
|
||||
cfg,
|
||||
exchanged,
|
||||
GNUNET_YES);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (exchanged,
|
||||
SIGTERM));
|
||||
#if GNU_PARALLEL
|
||||
/* GNU Parallel kills on 2nd SIGTERM, need to give it a
|
||||
chance to process the 1st signal first... */
|
||||
sleep (1);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (exchanged,
|
||||
SIGTERM));
|
||||
#endif
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait (exchanged));
|
||||
GNUNET_OS_process_destroy (exchanged);
|
||||
stop_helpers (helpers);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_setup_with_auditor_and_exchange_cfg (
|
||||
void *cls,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||
{
|
||||
const struct TALER_TESTING_SetupContext *setup_ctx = cls;
|
||||
struct GNUNET_OS_Process *auditord;
|
||||
unsigned long long port;
|
||||
char *serve;
|
||||
char *base_url;
|
||||
int result;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"auditor",
|
||||
"SERVE",
|
||||
&serve))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"auditor",
|
||||
"SERVE");
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (0 == strcmp ("tcp", serve))
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_number (cfg,
|
||||
"auditor",
|
||||
"PORT",
|
||||
&port))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"auditor",
|
||||
"PORT");
|
||||
GNUNET_free (serve);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
|
||||
(uint16_t) port))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Required port %llu not available, skipping.\n",
|
||||
port);
|
||||
GNUNET_free (serve);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
}
|
||||
GNUNET_free (serve);
|
||||
auditord = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
"taler-auditor-httpd",
|
||||
"taler-auditor-httpd",
|
||||
"-c", setup_ctx->config_filename,
|
||||
NULL);
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||
"auditor",
|
||||
"BASE_URL",
|
||||
&base_url))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||
"auditor",
|
||||
"BASE_URL");
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
if (0 != TALER_TESTING_wait_auditor_ready (base_url))
|
||||
{
|
||||
GNUNET_free (base_url);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (auditord,
|
||||
SIGTERM));
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait (auditord));
|
||||
GNUNET_OS_process_destroy (auditord);
|
||||
return 77;
|
||||
}
|
||||
GNUNET_free (base_url);
|
||||
|
||||
/* NOTE: this call blocks. */
|
||||
result = TALER_TESTING_setup_with_exchange_cfg ((void *) setup_ctx,
|
||||
cfg);
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (auditord,
|
||||
SIGTERM));
|
||||
GNUNET_break (GNUNET_OK ==
|
||||
GNUNET_OS_process_wait (auditord));
|
||||
GNUNET_OS_process_destroy (auditord);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_TESTING_setup_with_auditor_and_exchange (TALER_TESTING_Main main_cb,
|
||||
void *main_cb_cls,
|
||||
const char *config_file)
|
||||
{
|
||||
struct TALER_TESTING_SetupContext setup_ctx = {
|
||||
.config_filename = config_file,
|
||||
.main_cb = main_cb,
|
||||
.main_cb_cls = main_cb_cls
|
||||
};
|
||||
|
||||
return GNUNET_CONFIGURATION_parse_and_run (
|
||||
config_file,
|
||||
&TALER_TESTING_setup_with_auditor_and_exchange_cfg,
|
||||
&setup_ctx);
|
||||
}
|
||||
|
||||
|
||||
/* end of testing_api_helpers_exchange.c */
|
@ -385,7 +385,7 @@ do_timeout (void *cls)
|
||||
*
|
||||
* @param cls the `struct TALER_TESTING_Interpreter *`
|
||||
* @param type type of the process
|
||||
* @param exit_code status code of the process
|
||||
* @param code status code of the process
|
||||
*/
|
||||
static void
|
||||
maint_child_death (void *cls,
|
||||
|
@ -102,4 +102,59 @@ TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is)
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
TALER_TESTING_get_exchange_url (struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
const char *exchange_url;
|
||||
const struct TALER_TESTING_Command *exchange_cmd;
|
||||
|
||||
exchange_cmd
|
||||
= TALER_TESTING_interpreter_get_command (is,
|
||||
"exchange");
|
||||
if (NULL == exchange_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_exchange_url (exchange_cmd,
|
||||
&exchange_url))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
return exchange_url;
|
||||
}
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_TESTING_get_keys (
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_TESTING_Command *exchange_cmd;
|
||||
|
||||
exchange_cmd
|
||||
= TALER_TESTING_interpreter_get_command (is,
|
||||
"exchange");
|
||||
if (NULL == exchange_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_keys (exchange_cmd,
|
||||
&keys))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
/* end of testing_api_traits.c */
|
||||
|
Loading…
Reference in New Issue
Block a user