(start to) remove logic no longer needed with new key management
This commit is contained in:
parent
b5d88fc2d1
commit
04f2e9a4d5
@ -83,8 +83,8 @@ taler_exchange_httpd_SOURCES = \
|
||||
taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \
|
||||
taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \
|
||||
taler-exchange-httpd_keys.c taler-exchange-httpd_keys.h \
|
||||
taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \
|
||||
taler-exchange-httpd_link.c taler-exchange-httpd_link.h \
|
||||
taler-exchange-httpd_loop.c taler-exchange-httpd_loop.h \
|
||||
taler-exchange-httpd_management.h \
|
||||
taler-exchange-httpd_management_auditors.c \
|
||||
taler-exchange-httpd_management_auditors_AP_disable.c \
|
||||
@ -103,7 +103,7 @@ taler_exchange_httpd_SOURCES = \
|
||||
taler-exchange-httpd_responses.c taler-exchange-httpd_responses.h \
|
||||
taler-exchange-httpd_terms.c taler-exchange-httpd_terms.h \
|
||||
taler-exchange-httpd_transfers_get.c taler-exchange-httpd_transfers_get.h \
|
||||
taler-exchange-httpd_wire.c taler-exchange-httpd_wire.h \
|
||||
taler-exchange-httpd_wire2.c taler-exchange-httpd_wire.h \
|
||||
taler-exchange-httpd_withdraw.c taler-exchange-httpd_withdraw.h
|
||||
|
||||
# taler-exchange-httpd_management_post_keys.c
|
||||
|
@ -31,9 +31,9 @@
|
||||
#include "taler-exchange-httpd_auditors.h"
|
||||
#include "taler-exchange-httpd_deposit.h"
|
||||
#include "taler-exchange-httpd_deposits_get.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
#include "taler-exchange-httpd_link.h"
|
||||
#include "taler-exchange-httpd_loop.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_melt.h"
|
||||
#include "taler-exchange-httpd_mhd.h"
|
||||
@ -45,6 +45,7 @@
|
||||
#include "taler-exchange-httpd_transfers_get.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
#include "taler-exchange-httpd_withdraw.h"
|
||||
#include "taler_exchangedb_lib.h"
|
||||
#include "taler_exchangedb_plugin.h"
|
||||
#include <gnunet/gnunet_mhd_compat.h>
|
||||
|
||||
@ -1158,21 +1159,11 @@ exchange_serve_process_config (void)
|
||||
"Launching exchange with public key `%s'...\n",
|
||||
GNUNET_p2s (&TEH_master_public_key.eddsa_pub));
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TEH_WIRE_init (TEH_cfg))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to setup wire subsystem\n");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
|
||||
if (NULL ==
|
||||
(TEH_plugin = TALER_EXCHANGEDB_plugin_load (TEH_cfg)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to initialize DB subsystem\n");
|
||||
TEH_WIRE_done ();
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
@ -1185,7 +1176,6 @@ exchange_serve_process_config (void)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to setup HTTPd subsystem\n");
|
||||
TEH_WIRE_done ();
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
@ -1489,8 +1479,8 @@ run_main_loop (int fh,
|
||||
ret = TEH_keys_init ();
|
||||
if (GNUNET_OK == ret)
|
||||
{
|
||||
ret = TEH_KS_loop ();
|
||||
TEH_keys_done ();
|
||||
ret = TEH_loop_run ();
|
||||
TEH_loop_done ();
|
||||
}
|
||||
switch (ret)
|
||||
{
|
||||
@ -1703,7 +1693,10 @@ main (int argc,
|
||||
}
|
||||
|
||||
/* initialize #internal_key_state with an RC of 1 */
|
||||
ret = TEH_KS_init ();
|
||||
if (GNUNET_OK !=
|
||||
TEH_WIRE_init ())
|
||||
return 42;
|
||||
ret = TEH_loop_init ();
|
||||
if (GNUNET_OK == ret)
|
||||
{
|
||||
#if HAVE_DEVELOPER
|
||||
@ -1726,8 +1719,8 @@ main (int argc,
|
||||
ret = run_main_loop (fh,
|
||||
argv);
|
||||
}
|
||||
/* release #internal_key_state */
|
||||
TEH_KS_free ();
|
||||
/* release signal handlers */
|
||||
TEH_loop_done ();
|
||||
}
|
||||
TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
|
||||
TEH_WIRE_done ();
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
|
||||
/**
|
||||
* How often should we retry a transaction before giving up
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_deposit.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler_exchangedb_lib.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
@ -430,29 +430,17 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
(void) GNUNET_TIME_round_abs (&dc.exchange_timestamp);
|
||||
/* check denomination exists and is valid */
|
||||
{
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
struct TEH_DenominationKey *dk;
|
||||
enum TALER_ErrorCode ec;
|
||||
unsigned int hc;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
|
||||
key_state = TEH_KS_acquire (dc.exchange_timestamp);
|
||||
if (NULL == key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
|
||||
"no keys");
|
||||
}
|
||||
dk = TEH_keys_denomination_by_hash (&deposit.coin.denom_pub_hash,
|
||||
&ec,
|
||||
&hc);
|
||||
if (NULL == dk)
|
||||
{
|
||||
TALER_LOG_DEBUG ("Unknown denomination key in /deposit request\n");
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
hc,
|
||||
@ -463,7 +451,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
|
||||
{
|
||||
/* This denomination is past the expiration time for deposits */
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -474,7 +461,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us < dk->meta.start.abs_value_us)
|
||||
{
|
||||
/* This denomination is not yet valid */
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -485,7 +471,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
if (dk->recoup_possible)
|
||||
{
|
||||
/* This denomination has been revoked */
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -500,7 +485,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
&deposit.deposit_fee) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
@ -513,7 +497,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
&dk->denom_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
|
||||
TEH_KS_release (key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_UNAUTHORIZED,
|
||||
@ -521,7 +504,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
NULL);
|
||||
}
|
||||
dc.value = dk->meta.value;
|
||||
TEH_KS_release (key_state);
|
||||
}
|
||||
if (0 < TALER_amount_cmp (&deposit.deposit_fee,
|
||||
&deposit.amount_with_fee))
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
#include "taler-exchange-httpd_deposits_get.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,229 +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 Affero General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file exchange/taler-exchange-httpd_keystate.h
|
||||
* @brief management of our private signing keys (denomination keys)
|
||||
* @author Florian Dold
|
||||
* @author Benedikt Mueller
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#ifndef TALER_EXCHANGE_HTTPD_KEYSTATE_H
|
||||
#define TALER_EXCHANGE_HTTPD_KEYSTATE_H
|
||||
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <microhttpd.h>
|
||||
#include "taler-exchange-httpd.h"
|
||||
#include "taler_error_codes.h"
|
||||
#include "taler_exchangedb_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* Snapshot of the (coin and signing)
|
||||
* keys (including private keys) of the exchange.
|
||||
*/
|
||||
struct TEH_KS_StateHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Acquire the key state of the exchange. Updates keys if necessary.
|
||||
* For every call to #TEH_KS_acquire(), a matching call
|
||||
* to #TEH_KS_release() must be made.
|
||||
*
|
||||
* @param now for what timestamp should we acquire the key state
|
||||
* @param location name of the function in which the lock is acquired
|
||||
* @return the key state, NULL on error (usually pretty fatal)
|
||||
*/
|
||||
struct TEH_KS_StateHandle *
|
||||
TEH_KS_acquire_ (struct GNUNET_TIME_Absolute now,
|
||||
const char *location);
|
||||
|
||||
|
||||
/**
|
||||
* Release key state, free if necessary (if reference count gets to zero).
|
||||
*
|
||||
* @param location name of the function in which the lock is acquired
|
||||
* @param key_state the key state to release
|
||||
*/
|
||||
void
|
||||
TEH_KS_release_ (const char *location,
|
||||
struct TEH_KS_StateHandle *key_state);
|
||||
|
||||
|
||||
/**
|
||||
* Acquire the key state of the exchange. Updates keys if necessary.
|
||||
* For every call to #TEH_KS_acquire(), a matching call
|
||||
* to #TEH_KS_release() must be made.
|
||||
*
|
||||
* @param now current time snapshot; either true, or given by the
|
||||
* client via the "now" URL parameter of "/keys".
|
||||
* @return the key state
|
||||
*/
|
||||
#define TEH_KS_acquire(now) TEH_KS_acquire_ (now, __FUNCTION__)
|
||||
|
||||
|
||||
/**
|
||||
* Release key state, free if necessary (if reference count gets to zero).
|
||||
*
|
||||
* @param key_state the key state to release
|
||||
*/
|
||||
#define TEH_KS_release(key_state) TEH_KS_release_ (__FUNCTION__, key_state)
|
||||
|
||||
|
||||
/**
|
||||
* Setup initial #internal_key_state and our signal handlers.
|
||||
*
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
int
|
||||
TEH_KS_init (void);
|
||||
|
||||
|
||||
/**
|
||||
* Finally, release #internal_key_state and our signal handlers.
|
||||
*/
|
||||
void
|
||||
TEH_KS_free (void);
|
||||
|
||||
|
||||
/**
|
||||
* Denomination key lookups can be for signing of fresh coins
|
||||
* or to validate signatures on existing coins. As the validity
|
||||
* periods for a key differ, the caller must specify which
|
||||
* use is relevant for the current operation.
|
||||
*/
|
||||
enum TEH_KS_DenominationKeyUse
|
||||
{
|
||||
|
||||
/**
|
||||
* The denomination key is to be used for a withdraw or reveal operation.
|
||||
*/
|
||||
TEH_KS_DKU_WITHDRAW,
|
||||
|
||||
/**
|
||||
* The denomination key is to be used for a deposit or melt operation.
|
||||
*/
|
||||
TEH_KS_DKU_DEPOSIT,
|
||||
|
||||
/**
|
||||
* The denomination key is to be used for a recoup operation, or to
|
||||
* melt a coin that was deposited (or melted) before the revocation.
|
||||
*/
|
||||
TEH_KS_DKU_RECOUP,
|
||||
|
||||
/**
|
||||
* The key is to be used for a refresh + recoup operation,
|
||||
* i.e. it is an old coin that regained value from a
|
||||
* recoup on a new coin derived from the old coin.
|
||||
*/
|
||||
TEH_KS_DKU_ZOMBIE
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Look up the issue for a denom public key. Note that the result
|
||||
* is only valid while the @a key_state is not released!
|
||||
*
|
||||
* @param key_state state to look in
|
||||
* @param denom_pub_hash hash of denomination public key
|
||||
* @param use purpose for which the key is being located
|
||||
* @param[out] ec set to the error code, in case the operation failed
|
||||
* @param[out] hc set to the HTTP status code to use
|
||||
* @return the denomination key issue,
|
||||
* or NULL if denom_pub could not be found (or is not valid at this time for the given @a use)
|
||||
*/
|
||||
struct TALER_EXCHANGEDB_DenominationKey *
|
||||
TEH_KS_denomination_key_lookup_by_hash (
|
||||
const struct TEH_KS_StateHandle *key_state,
|
||||
const struct GNUNET_HashCode *denom_pub_hash,
|
||||
enum TEH_KS_DenominationKeyUse use,
|
||||
enum TALER_ErrorCode *ec,
|
||||
unsigned int *hc);
|
||||
|
||||
|
||||
/**
|
||||
* Read signals from a pipe in a loop, and reload keys from disk if
|
||||
* SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
|
||||
* restart if SIGHUP is received.
|
||||
*
|
||||
* @return #GNUNET_SYSERR on errors,
|
||||
* #GNUNET_OK to terminate normally
|
||||
* #GNUNET_NO to restart an update version of the binary
|
||||
*/
|
||||
int
|
||||
TEH_KS_loop (void);
|
||||
|
||||
|
||||
/**
|
||||
* Sign the message in @a purpose with the exchange's signing
|
||||
* key.
|
||||
*
|
||||
* The @a purpose data is the beginning of the data of which the signature is
|
||||
* to be created. The `size` field in @a purpose must correctly indicate the
|
||||
* number of bytes of the data structure, including its header. Use
|
||||
* #TEH_KS_sign() instead of calling this function directly!
|
||||
*
|
||||
* @param purpose the message to sign
|
||||
* @param[out] pub set to the current public signing key of the exchange
|
||||
* @param[out] sig signature over purpose using current signing key
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR if we lack key material
|
||||
*/
|
||||
int
|
||||
TEH_KS_sign_ (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
|
||||
struct TALER_ExchangePublicKeyP *pub,
|
||||
struct TALER_ExchangeSignatureP *sig);
|
||||
|
||||
/**
|
||||
* @ingroup crypto
|
||||
* @brief EdDSA sign a given block.
|
||||
*
|
||||
* The @a ps data must be a fixed-size struct for which the signature is to be
|
||||
* created. The `size` field in @a ps->purpose must correctly indicate the
|
||||
* number of bytes of the data structure, including its header.
|
||||
*
|
||||
* @param ps packed struct with what to sign, MUST begin with a purpose
|
||||
* @param[out] pub where to store the public key to use for the signing
|
||||
* @param[out] sig where to write the signature
|
||||
*/
|
||||
#define TEH_KS_sign(ps,pub,sig) \
|
||||
({ \
|
||||
/* check size is set correctly */ \
|
||||
GNUNET_assert (htonl ((ps)->purpose.size) == \
|
||||
sizeof (*ps)); \
|
||||
/* check 'ps' begins with the purpose */ \
|
||||
GNUNET_static_assert (((void*) (ps)) == \
|
||||
((void*) &(ps)->purpose)); \
|
||||
TEH_KS_sign_ (&(ps)->purpose, \
|
||||
pub, \
|
||||
sig); \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* Handle a "/keys" request
|
||||
*
|
||||
* @param rh context of the handler
|
||||
* @param connection the MHD connection to handle
|
||||
* @param args array of additional options (must be empty for this function)
|
||||
* @return MHD result code
|
||||
*/
|
||||
MHD_RESULT
|
||||
TEH_handler_keys (const struct TEH_RequestHandler *rh,
|
||||
struct MHD_Connection *connection,
|
||||
const char *const args[]);
|
||||
|
||||
|
||||
#endif
|
@ -28,7 +28,6 @@
|
||||
#include "taler-exchange-httpd_mhd.h"
|
||||
#include "taler-exchange-httpd_link.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
|
||||
/**
|
||||
|
209
src/exchange/taler-exchange-httpd_loop.c
Normal file
209
src/exchange/taler-exchange-httpd_loop.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014--2020 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file taler-exchange-httpd_loop.c
|
||||
* @brief management of our main loop
|
||||
* @author Florian Dold
|
||||
* @author Benedikt Mueller
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <pthread.h>
|
||||
#include "taler-exchange-httpd_loop.h"
|
||||
|
||||
|
||||
/* ************************* Signal logic ************************** */
|
||||
|
||||
/**
|
||||
* Pipe used for signaling reloading of our key state.
|
||||
*/
|
||||
static int reload_pipe[2] = { -1, -1 };
|
||||
|
||||
|
||||
/**
|
||||
* Handle a signal, writing relevant signal numbers to the pipe.
|
||||
*
|
||||
* @param signal_number the signal number
|
||||
*/
|
||||
static void
|
||||
handle_signal (int signal_number)
|
||||
{
|
||||
char c = (char) signal_number; /* never seen a signal_number > 127 on any platform */
|
||||
|
||||
(void) ! write (reload_pipe[1],
|
||||
&c,
|
||||
1);
|
||||
/* While one might like to "handle errors" here, even logging via fprintf()
|
||||
isn't safe inside of a signal handler. So there is nothing we safely CAN
|
||||
do. OTOH, also very little that can go wrong in practice. Calling _exit()
|
||||
on errors might be a possibility, but that might do more harm than good. *///
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call #handle_signal() to pass the received signal via
|
||||
* the control pipe.
|
||||
*/
|
||||
static void
|
||||
handle_sigint (void)
|
||||
{
|
||||
handle_signal (SIGINT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call #handle_signal() to pass the received signal via
|
||||
* the control pipe.
|
||||
*/
|
||||
static void
|
||||
handle_sigterm (void)
|
||||
{
|
||||
handle_signal (SIGTERM);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call #handle_signal() to pass the received signal via
|
||||
* the control pipe.
|
||||
*/
|
||||
static void
|
||||
handle_sighup (void)
|
||||
{
|
||||
handle_signal (SIGHUP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call #handle_signal() to pass the received signal via
|
||||
* the control pipe.
|
||||
*/
|
||||
static void
|
||||
handle_sigchld (void)
|
||||
{
|
||||
handle_signal (SIGCHLD);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
TEH_loop_run (void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 2;
|
||||
while (2 == ret)
|
||||
{
|
||||
char c;
|
||||
ssize_t res;
|
||||
|
||||
errno = 0;
|
||||
res = read (reload_pipe[0],
|
||||
&c,
|
||||
1);
|
||||
if ((res < 0) && (EINTR != errno))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
ret = GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
if (EINTR == errno)
|
||||
continue;
|
||||
switch (c)
|
||||
{
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
/* terminate */
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
case SIGHUP:
|
||||
/* restart updated binary */
|
||||
ret = GNUNET_NO;
|
||||
break;
|
||||
#if HAVE_DEVELOPER
|
||||
case SIGCHLD:
|
||||
/* running in test-mode, test finished, terminate */
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* unexpected character */
|
||||
GNUNET_break (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct GNUNET_SIGNAL_Context *sigterm;
|
||||
static struct GNUNET_SIGNAL_Context *sigint;
|
||||
static struct GNUNET_SIGNAL_Context *sighup;
|
||||
static struct GNUNET_SIGNAL_Context *sigchld;
|
||||
|
||||
|
||||
int
|
||||
TEH_loop_init (void)
|
||||
{
|
||||
if (0 != pipe (reload_pipe))
|
||||
{
|
||||
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
|
||||
"pipe");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
|
||||
&handle_sigterm);
|
||||
sigint = GNUNET_SIGNAL_handler_install (SIGINT,
|
||||
&handle_sigint);
|
||||
sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
|
||||
&handle_sighup);
|
||||
sigchld = GNUNET_SIGNAL_handler_install (SIGCHLD,
|
||||
&handle_sigchld);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TEH_loop_done (void)
|
||||
{
|
||||
if (NULL != sigterm)
|
||||
{
|
||||
GNUNET_SIGNAL_handler_uninstall (sigterm);
|
||||
sigterm = NULL;
|
||||
}
|
||||
if (NULL != sigint)
|
||||
{
|
||||
GNUNET_SIGNAL_handler_uninstall (sigint);
|
||||
sigint = NULL;
|
||||
}
|
||||
if (NULL != sighup)
|
||||
{
|
||||
GNUNET_SIGNAL_handler_uninstall (sighup);
|
||||
sighup = NULL;
|
||||
}
|
||||
if (NULL != sigchld)
|
||||
{
|
||||
GNUNET_SIGNAL_handler_uninstall (sigchld);
|
||||
sigchld = NULL;
|
||||
}
|
||||
if (-1 != reload_pipe[0])
|
||||
{
|
||||
GNUNET_break (0 == close (reload_pipe[0]));
|
||||
GNUNET_break (0 == close (reload_pipe[1]));
|
||||
reload_pipe[0] = reload_pipe[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* end of taler-exchange-httpd_loop.c */
|
60
src/exchange/taler-exchange-httpd_loop.h
Normal file
60
src/exchange/taler-exchange-httpd_loop.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
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 Affero General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file exchange/taler-exchange-httpd_loop.h
|
||||
* @brief management of our main loop
|
||||
* @author Florian Dold
|
||||
* @author Benedikt Mueller
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#ifndef TALER_EXCHANGE_HTTPD_LOOP_H
|
||||
#define TALER_EXCHANGE_HTTPD_LOOP_H
|
||||
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include <microhttpd.h>
|
||||
#include "taler-exchange-httpd.h"
|
||||
|
||||
|
||||
/**
|
||||
* Setup our signal handlers.
|
||||
*
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
int
|
||||
TEH_loop_init (void);
|
||||
|
||||
|
||||
/**
|
||||
* Finally, tear down our signal handlers.
|
||||
*/
|
||||
void
|
||||
TEH_loop_done (void);
|
||||
|
||||
|
||||
/**
|
||||
* Read signals from a pipe in a loop, and reload keys from disk if
|
||||
* SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
|
||||
* restart if SIGHUP is received.
|
||||
*
|
||||
* @return #GNUNET_SYSERR on errors,
|
||||
* #GNUNET_OK to terminate normally
|
||||
* #GNUNET_NO to restart an update version of the binary
|
||||
*/
|
||||
int
|
||||
TEH_loop_run (void);
|
||||
|
||||
|
||||
#endif
|
@ -28,7 +28,7 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
|
||||
/**
|
||||
* Closure for the #add_auditor transaction.
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
|
||||
/**
|
||||
* Closure for the #del_auditor transaction.
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "taler_signatures.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -202,6 +203,7 @@ TEH_handler_management_denominations_wire (
|
||||
&awc);
|
||||
if (qs < 0)
|
||||
return ret;
|
||||
TEH_wire_update_state ();
|
||||
return TALER_MHD_reply_static (
|
||||
connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
|
@ -28,7 +28,8 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
|
||||
|
||||
/**
|
||||
* Closure for the #del_wire transaction.
|
||||
@ -182,6 +183,7 @@ TEH_handler_management_denominations_wire_disable (
|
||||
&awc);
|
||||
if (qs < 0)
|
||||
return ret;
|
||||
TEH_wire_update_state ();
|
||||
return TALER_MHD_reply_static (
|
||||
connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "taler_signatures.h"
|
||||
#include "taler-exchange-httpd_management.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -247,6 +248,7 @@ TEH_handler_management_post_wire_fees (
|
||||
&afc);
|
||||
if (qs < 0)
|
||||
return ret;
|
||||
TEH_wire_update_state ();
|
||||
return TALER_MHD_reply_static (
|
||||
connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include "taler-exchange-httpd_mhd.h"
|
||||
#include "taler-exchange-httpd_melt.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
#include "taler_exchangedb_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -463,19 +463,6 @@ static MHD_RESULT
|
||||
check_for_denomination_key (struct MHD_Connection *connection,
|
||||
struct MeltContext *rmc)
|
||||
{
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
|
||||
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
|
||||
if (NULL == key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
|
||||
"no keys");
|
||||
}
|
||||
|
||||
{
|
||||
/* Baseline: check if deposits/refreshs are generally
|
||||
simply still allowed for this denomination */
|
||||
struct TEH_DenominationKey *dk;
|
||||
@ -489,7 +476,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
&hc);
|
||||
if (NULL == dk)
|
||||
{
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
@ -500,7 +486,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us >= dk->meta.expire_legal.abs_value_us)
|
||||
{
|
||||
/* Way too late now, even zombies have expired */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_GONE,
|
||||
@ -510,7 +495,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us < dk->meta.start.abs_value_us)
|
||||
{
|
||||
/* This denomination is not yet valid */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_PRECONDITION_FAILED,
|
||||
@ -533,7 +517,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
&denom_hash);
|
||||
if (0 > qs)
|
||||
{
|
||||
TEH_KS_release (key_state);
|
||||
/* There is no good reason for a serialization failure here: */
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
@ -548,7 +531,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||
{
|
||||
/* We never saw this coin before, so _this_ justification is not OK */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_GONE,
|
||||
@ -572,7 +554,6 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
&rmc->coin_value) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
@ -585,14 +566,11 @@ check_for_denomination_key (struct MHD_Connection *connection,
|
||||
&dk->denom_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
TEH_KS_release (key_state);
|
||||
|
||||
/* sanity-check that "total melt amount > melt fee" */
|
||||
if (0 <
|
||||
|
@ -30,9 +30,8 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_recoup.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
#include "taler_exchangedb_lib.h"
|
||||
|
||||
/**
|
||||
* Closure for #recoup_transaction.
|
||||
@ -366,27 +365,14 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
size_t coin_ev_size;
|
||||
enum TALER_ErrorCode ec;
|
||||
unsigned int hc;
|
||||
|
||||
/* check denomination exists and is in recoup mode */
|
||||
{
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
|
||||
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
|
||||
if (NULL == key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
|
||||
"no keys");
|
||||
}
|
||||
/* check denomination exists and is in recoup mode */
|
||||
dk = TEH_keys_denomination_by_hash (&coin->denom_pub_hash,
|
||||
&ec,
|
||||
&hc);
|
||||
if (NULL == dk)
|
||||
{
|
||||
TEH_KS_release (key_state);
|
||||
TALER_LOG_WARNING (
|
||||
"Denomination key in recoup request not in recoup mode\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
@ -399,7 +385,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
|
||||
{
|
||||
/* This denomination is past the expiration time for recoup */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_GONE,
|
||||
@ -409,7 +394,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
if (now.abs_value_us < dk->meta.start.abs_value_us)
|
||||
{
|
||||
/* This denomination is not yet valid */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_PRECONDITION_FAILED,
|
||||
@ -419,7 +403,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
if (! dk->recoup_possible)
|
||||
{
|
||||
/* This denomination is not eligible for recoup */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
@ -435,7 +418,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
&dk->denom_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid coin passed for recoup\n");
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID,
|
||||
@ -459,7 +441,6 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid signature on recoup request\n");
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
|
||||
@ -477,14 +458,11 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
|
||||
&coin_ev_size))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
|
||||
NULL);
|
||||
}
|
||||
TEH_KS_release (key_state);
|
||||
}
|
||||
GNUNET_CRYPTO_hash (coin_ev,
|
||||
coin_ev_size,
|
||||
&pc.h_blind);
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "taler-exchange-httpd_mhd.h"
|
||||
#include "taler-exchange-httpd_refreshes_reveal.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
@ -521,9 +520,8 @@ refreshes_reveal_persist (void *cls,
|
||||
|
||||
|
||||
/**
|
||||
* Resolve denomination hashes using the @a key_state
|
||||
* Resolve denomination hashes.
|
||||
*
|
||||
* @param key_state the key state
|
||||
* @param connection the MHD connection to handle
|
||||
* @param rctx context for the operation, partially built at this time
|
||||
* @param link_sigs_json link signatures in JSON format
|
||||
@ -532,8 +530,7 @@ refreshes_reveal_persist (void *cls,
|
||||
* @return MHD result code
|
||||
*/
|
||||
static MHD_RESULT
|
||||
resolve_refreshes_reveal_denominations (struct TEH_KS_StateHandle *key_state,
|
||||
struct MHD_Connection *connection,
|
||||
resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
||||
struct RevealContext *rctx,
|
||||
const json_t *link_sigs_json,
|
||||
const json_t *new_denoms_h_json,
|
||||
@ -905,28 +902,11 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection,
|
||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||
}
|
||||
|
||||
{
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
int ret;
|
||||
|
||||
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
|
||||
if (NULL == key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
|
||||
NULL);
|
||||
}
|
||||
ret = resolve_refreshes_reveal_denominations (key_state,
|
||||
connection,
|
||||
return resolve_refreshes_reveal_denominations (connection,
|
||||
rctx,
|
||||
link_sigs_json,
|
||||
new_denoms_h_json,
|
||||
coin_evs);
|
||||
TEH_KS_release (key_state);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_refund.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
@ -448,19 +447,7 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
{
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
|
||||
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
|
||||
if (NULL == key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
|
||||
"no keys");
|
||||
}
|
||||
/* Obtain information about the coin's denomination! */
|
||||
{
|
||||
struct TEH_DenominationKey *dk;
|
||||
unsigned int hc;
|
||||
enum TALER_ErrorCode ec;
|
||||
@ -473,7 +460,6 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
||||
/* DKI not found, but we do have a coin with this DK in our database;
|
||||
not good... */
|
||||
GNUNET_break (0);
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
hc,
|
||||
ec,
|
||||
@ -484,7 +470,6 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
||||
dk->meta.expire_deposit.abs_value_us)
|
||||
{
|
||||
/* This denomination is past the expiration time for deposits, and thus refunds */
|
||||
TEH_KS_release (key_state);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_GONE,
|
||||
@ -493,8 +478,6 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
||||
}
|
||||
refund->details.refund_fee = dk->meta.fee_refund;
|
||||
}
|
||||
TEH_KS_release (key_state);
|
||||
}
|
||||
|
||||
/* Finally run the actual transaction logic */
|
||||
{
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler-exchange-httpd_reserves_get.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <pthread.h>
|
||||
#include "taler_signatures.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_transfers_get.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler_json_lib.h"
|
||||
|
@ -1,399 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2015-2020 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Affero General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file taler-exchange-httpd_wire.c
|
||||
* @brief Handle /wire requests
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <gnunet/gnunet_json_lib.h>
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_mhd_lib.h"
|
||||
#include <jansson.h>
|
||||
|
||||
/**
|
||||
* Cached JSON for /wire response.
|
||||
*/
|
||||
static json_t *wire_methods;
|
||||
|
||||
/**
|
||||
* Array of wire methods supported by this exchange.
|
||||
*/
|
||||
static json_t *wire_accounts_array;
|
||||
|
||||
/**
|
||||
* Object mapping wire methods to the respective fee structure.
|
||||
*/
|
||||
static json_t *wire_fee_object;
|
||||
|
||||
|
||||
/**
|
||||
* Convert fee structure to JSON result to be returned
|
||||
* as part of a /wire response.
|
||||
*
|
||||
* @param af fee structure to convert
|
||||
* @return NULL on error, otherwise json data structure for /wire.
|
||||
*/
|
||||
static json_t *
|
||||
fees_to_json (struct TALER_EXCHANGEDB_AggregateFees *af)
|
||||
{
|
||||
json_t *a;
|
||||
|
||||
a = json_array ();
|
||||
if (NULL == a)
|
||||
{
|
||||
GNUNET_break (0); /* out of memory? */
|
||||
return NULL;
|
||||
}
|
||||
while (NULL != af)
|
||||
{
|
||||
if ( (GNUNET_NO == GNUNET_TIME_round_abs (&af->start_date)) ||
|
||||
(GNUNET_NO == GNUNET_TIME_round_abs (&af->end_date)) )
|
||||
{
|
||||
GNUNET_break (0); /* bad timestamps, should not happen */
|
||||
json_decref (a);
|
||||
return NULL;
|
||||
}
|
||||
if (0 !=
|
||||
json_array_append_new (a,
|
||||
json_pack ("{s:o, s:o, s:o, s:o, s:o}",
|
||||
"wire_fee", TALER_JSON_from_amount (
|
||||
&af->wire_fee),
|
||||
"closing_fee",
|
||||
TALER_JSON_from_amount (
|
||||
&af->closing_fee),
|
||||
"start_date",
|
||||
GNUNET_JSON_from_time_abs (
|
||||
af->start_date),
|
||||
"end_date",
|
||||
GNUNET_JSON_from_time_abs (
|
||||
af->end_date),
|
||||
"sig", GNUNET_JSON_from_data_auto (
|
||||
&af->master_sig))))
|
||||
{
|
||||
GNUNET_break (0); /* out of memory? */
|
||||
json_decref (a);
|
||||
return NULL;
|
||||
}
|
||||
af = af->next;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain fee structure for @a method wire transfers.
|
||||
*
|
||||
* @param method method to load fees for
|
||||
* @return JSON object (to be freed by caller) with fee structure
|
||||
*/
|
||||
static json_t *
|
||||
get_fees (const char *method)
|
||||
{
|
||||
struct TALER_EXCHANGEDB_AggregateFees *af;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
|
||||
af = TALER_EXCHANGEDB_fees_read (TEH_cfg,
|
||||
method);
|
||||
now = GNUNET_TIME_absolute_get ();
|
||||
while ( (NULL != af) &&
|
||||
(af->end_date.abs_value_us < now.abs_value_us) )
|
||||
{
|
||||
struct TALER_EXCHANGEDB_AggregateFees *n = af->next;
|
||||
|
||||
GNUNET_free (af);
|
||||
af = n;
|
||||
}
|
||||
if (NULL == af)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to find current wire transfer fees for `%s' at time %s\n",
|
||||
method,
|
||||
GNUNET_STRINGS_absolute_time_to_string (now));
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
json_t *j;
|
||||
|
||||
j = fees_to_json (af);
|
||||
TALER_EXCHANGEDB_fees_free (af);
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load wire fees for @a method.
|
||||
*
|
||||
* @param method wire method to load fee structure for
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static int
|
||||
load_fee (const char *method)
|
||||
{
|
||||
json_t *fees;
|
||||
|
||||
if (NULL != json_object_get (wire_fee_object,
|
||||
method))
|
||||
return GNUNET_OK; /* already have them */
|
||||
fees = get_fees (method);
|
||||
if (NULL == fees)
|
||||
return GNUNET_SYSERR;
|
||||
/* Add fees to #wire_fee_object */
|
||||
if (0 !=
|
||||
json_object_set_new (wire_fee_object,
|
||||
method,
|
||||
fees))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize account; checks if @a ai has /wire information, and if so,
|
||||
* adds the /wire information (if included) to our responses.
|
||||
*
|
||||
* @param cls pointer to `int` to set to #GNUNET_SYSERR on errors
|
||||
* @param ai details about the account we should load the wire details for
|
||||
*/
|
||||
static void
|
||||
load_account (void *cls,
|
||||
const struct TALER_EXCHANGEDB_AccountInfo *ai)
|
||||
{
|
||||
int *ret = cls;
|
||||
|
||||
if ( (NULL != ai->wire_response_filename) &&
|
||||
(GNUNET_YES == ai->credit_enabled) )
|
||||
{
|
||||
json_t *wire_s;
|
||||
json_error_t error;
|
||||
|
||||
if (NULL == (wire_s = json_load_file (ai->wire_response_filename,
|
||||
JSON_REJECT_DUPLICATES,
|
||||
&error)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to parse `%s': %s at %d:%d (%d)\n",
|
||||
ai->wire_response_filename,
|
||||
error.text,
|
||||
error.line,
|
||||
error.column,
|
||||
error.position);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char *url;
|
||||
|
||||
if (NULL == (url = TALER_JSON_wire_to_payto (wire_s)))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire response file `%s' malformed\n",
|
||||
ai->wire_response_filename);
|
||||
json_decref (wire_s);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
if (0 != strcasecmp (url,
|
||||
ai->payto_uri))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"URL in wire response file `%s' does not match URL in configuration (%s vs %s)!\n",
|
||||
ai->wire_response_filename,
|
||||
url,
|
||||
ai->payto_uri);
|
||||
json_decref (wire_s);
|
||||
GNUNET_free (url);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
GNUNET_free (url);
|
||||
}
|
||||
/* Provide friendly error message if user forgot to sign wire response. */
|
||||
if (NULL == json_object_get (wire_s,
|
||||
"master_sig"))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire response file `%s' has not been signed."
|
||||
" Use taler-exchange-wire to sign it.\n",
|
||||
ai->wire_response_filename);
|
||||
json_decref (wire_s);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_JSON_exchange_wire_signature_check (wire_s,
|
||||
&TEH_master_public_key))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Invalid signature in `%s' for public key `%s'\n",
|
||||
ai->wire_response_filename,
|
||||
GNUNET_p2s (&TEH_master_public_key.eddsa_pub));
|
||||
json_decref (wire_s);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK ==
|
||||
load_fee (ai->method))
|
||||
{
|
||||
if (0 !=
|
||||
json_array_append_new (wire_accounts_array,
|
||||
wire_s))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*ret = GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire fees not specified for `%s'\n",
|
||||
ai->method);
|
||||
*ret = GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
else if (GNUNET_YES == ai->debit_enabled)
|
||||
{
|
||||
if (GNUNET_OK !=
|
||||
load_fee (ai->method))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Wire transfer fees for `%s' are not given correctly\n",
|
||||
ai->method);
|
||||
*ret = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a "/wire" request.
|
||||
*
|
||||
* @param rh context of the handler
|
||||
* @param connection the MHD connection to handle
|
||||
* @param args array of additional options (must be empty for this function)
|
||||
* @return MHD result code
|
||||
*/
|
||||
MHD_RESULT
|
||||
TEH_handler_wire (const struct TEH_RequestHandler *rh,
|
||||
struct MHD_Connection *connection,
|
||||
const char *const args[])
|
||||
{
|
||||
(void) rh;
|
||||
(void) args;
|
||||
GNUNET_assert (NULL != wire_methods);
|
||||
return TALER_MHD_reply_json (connection,
|
||||
wire_methods,
|
||||
MHD_HTTP_OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize wire subsystem.
|
||||
*
|
||||
* @param cfg configuration to use
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR if we found no valid
|
||||
* wire methods
|
||||
*/
|
||||
int
|
||||
TEH_WIRE_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||
{
|
||||
wire_accounts_array = json_array ();
|
||||
if (NULL == wire_accounts_array)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
wire_fee_object = json_object ();
|
||||
if (NULL == wire_fee_object)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TEH_WIRE_done ();
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = GNUNET_OK;
|
||||
TALER_EXCHANGEDB_find_accounts (cfg,
|
||||
&load_account,
|
||||
&ret);
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Error setting up bank accounts\n");
|
||||
TEH_WIRE_done ();
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
if ( (0 == json_array_size (wire_accounts_array)) ||
|
||||
(0 == json_object_size (wire_fee_object)) )
|
||||
{
|
||||
TEH_WIRE_done ();
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"No bank accounts configured\n");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
wire_methods = json_pack ("{s:O, s:O, s:o}",
|
||||
"accounts", wire_accounts_array,
|
||||
"fees", wire_fee_object,
|
||||
"master_public_key",
|
||||
GNUNET_JSON_from_data_auto (
|
||||
&TEH_master_public_key));
|
||||
if (NULL == wire_methods)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to find properly configured wire transfer method\n");
|
||||
TEH_WIRE_done ();
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up wire subsystem.
|
||||
*/
|
||||
void
|
||||
TEH_WIRE_done ()
|
||||
{
|
||||
if (NULL != wire_methods)
|
||||
{
|
||||
json_decref (wire_methods);
|
||||
wire_methods = NULL;
|
||||
}
|
||||
if (NULL != wire_fee_object)
|
||||
{
|
||||
json_decref (wire_fee_object);
|
||||
wire_fee_object = NULL;
|
||||
}
|
||||
if (NULL != wire_accounts_array)
|
||||
{
|
||||
json_decref (wire_accounts_array);
|
||||
wire_accounts_array = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* end of taler-exchange-httpd_wire.c */
|
@ -29,12 +29,10 @@
|
||||
/**
|
||||
* Initialize wire subsystem.
|
||||
*
|
||||
* @param cfg configuration to use
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR if we found no valid
|
||||
* wire methods
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error.
|
||||
*/
|
||||
int
|
||||
TEH_WIRE_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
|
||||
TEH_WIRE_init (void);
|
||||
|
||||
|
||||
/**
|
||||
@ -44,6 +42,19 @@ void
|
||||
TEH_WIRE_done (void);
|
||||
|
||||
|
||||
/**
|
||||
* Something changed in the database. Rebuild the wire replies. This function
|
||||
* should be called if the exchange learns about a new signature from our
|
||||
* master key.
|
||||
*
|
||||
* (We do not do so immediately, but merely signal to all threads that they
|
||||
* need to rebuild their wire state upon the next call to
|
||||
* #wire_get_state()).
|
||||
*/
|
||||
void
|
||||
TEH_wire_update_state (void);
|
||||
|
||||
|
||||
/**
|
||||
* Handle a "/wire" request.
|
||||
*
|
||||
|
@ -20,7 +20,6 @@
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <gnunet/gnunet_json_lib.h>
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_wire.h"
|
||||
#include "taler_json_lib.h"
|
||||
@ -76,6 +75,47 @@ destroy_wire_state (struct WireStateHandle *wsh)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free memory assciated with wire state. Signature
|
||||
* suitable for pthread_key_create().
|
||||
*
|
||||
* @param[in] cls the `struct WireStateHandle` to destroy
|
||||
*/static void
|
||||
destroy_wire_state_cb (void *cls)
|
||||
{
|
||||
struct WireStateHandle *wsh = cls;
|
||||
|
||||
destroy_wire_state (wsh);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize WIRE submodule.
|
||||
*
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
int
|
||||
TEH_WIRE_init ()
|
||||
{
|
||||
if (0 !=
|
||||
pthread_key_create (&wire_state,
|
||||
&destroy_wire_state_cb))
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fully clean up our state.
|
||||
*/
|
||||
void
|
||||
TEH_WIRE_done ()
|
||||
{
|
||||
GNUNET_assert (0 ==
|
||||
pthread_key_delete (wire_state));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add information about a wire account to @a cls.
|
||||
*
|
||||
@ -95,9 +135,9 @@ add_wire_account (void *cls,
|
||||
json_array_append_new (
|
||||
a,
|
||||
json_pack ("{s:s, s:o}",
|
||||
"url", /* "payto_uri" would be better, but this is the name in the spec */
|
||||
"payto_uri",
|
||||
payto_uri,
|
||||
"sig",
|
||||
"master_sig",
|
||||
GNUNET_JSON_from_data_auto (master_sig))))
|
||||
{
|
||||
GNUNET_break (0); /* out of memory!? */
|
||||
@ -182,7 +222,7 @@ build_wire_state (void)
|
||||
json_array_foreach (wire_accounts_array, index, account) {
|
||||
char *wire_method;
|
||||
const char *payto_uri = json_string_value (json_object_get (account,
|
||||
"url"));
|
||||
"payto_uri"));
|
||||
GNUNET_assert (NULL != payto_uri);
|
||||
wire_method = TALER_payto_get_method (payto_uri);
|
||||
if (NULL == json_object_get (wire_fee_object,
|
||||
@ -230,17 +270,8 @@ build_wire_state (void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Something changed in the database. Rebuild the wire replies. This function
|
||||
* should be called if the exchange learns about a new signature from our
|
||||
* master key.
|
||||
*
|
||||
* (We do not do so immediately, but merely signal to all threads that they
|
||||
* need to rebuild their wire state upon the next call to
|
||||
* #wire_get_state()).
|
||||
*/
|
||||
void
|
||||
TEH_wire_update_state ()
|
||||
TEH_wire_update_state (void)
|
||||
{
|
||||
__sync_fetch_and_add (&wire_generation,
|
||||
1);
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "taler_mhd_lib.h"
|
||||
#include "taler-exchange-httpd_withdraw.h"
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler-exchange-httpd_keystate.h"
|
||||
#include "taler-exchange-httpd_keys.h"
|
||||
|
||||
|
||||
@ -124,11 +123,6 @@ struct WithdrawContext
|
||||
*/
|
||||
char *blinded_msg;
|
||||
|
||||
/**
|
||||
* Key state to use to inspect previous withdrawal values.
|
||||
*/
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
|
||||
/**
|
||||
* Number of bytes in @e blinded_msg.
|
||||
*/
|
||||
@ -384,16 +378,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
if (GNUNET_OK != res)
|
||||
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||
}
|
||||
wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
|
||||
if (NULL == wc.key_state)
|
||||
{
|
||||
TALER_LOG_ERROR ("Lacking keys to operate\n");
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION,
|
||||
"no keys");
|
||||
}
|
||||
{
|
||||
unsigned int hc;
|
||||
enum TALER_ErrorCode ec;
|
||||
@ -405,7 +389,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
if (NULL == dk)
|
||||
{
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TEH_KS_release (wc.key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
hc,
|
||||
ec,
|
||||
@ -415,7 +398,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
if (now.abs_value_us >= dk->meta.expire_withdraw.abs_value_us)
|
||||
{
|
||||
/* This denomination is past the expiration time for withdraws */
|
||||
TEH_KS_release (wc.key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -426,7 +408,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
if (now.abs_value_us < dk->meta.start.abs_value_us)
|
||||
{
|
||||
/* This denomination is not yet valid */
|
||||
TEH_KS_release (wc.key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -437,7 +418,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
if (dk->recoup_possible)
|
||||
{
|
||||
/* This denomination has been revoked */
|
||||
TEH_KS_release (wc.key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
@ -454,7 +434,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
&dk->meta.fee_withdraw))
|
||||
{
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TEH_KS_release (wc.key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
|
||||
@ -483,7 +462,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
TALER_LOG_WARNING (
|
||||
"Client supplied invalid signature for withdraw request\n");
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TEH_KS_release (wc.key_state);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID,
|
||||
@ -501,7 +479,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TEH_KS_release (wc.key_state);
|
||||
return TALER_MHD_reply_with_ec (connection,
|
||||
ec,
|
||||
NULL);
|
||||
@ -519,7 +496,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
&withdraw_transaction,
|
||||
&wc))
|
||||
{
|
||||
TEH_KS_release (wc.key_state);
|
||||
/* Even if #withdraw_transaction() failed, it may have created a signature
|
||||
(or we might have done it optimistically above). */
|
||||
if (NULL != wc.collectable.sig.rsa_signature)
|
||||
@ -530,7 +506,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
|
||||
}
|
||||
|
||||
/* Clean up and send back final (positive) response */
|
||||
TEH_KS_release (wc.key_state);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ unset XDG_CONFIG_HOME
|
||||
echo -n "Launching exchange ..."
|
||||
PREFIX=
|
||||
# Uncomment this line to run with valgrind...
|
||||
# PREFIX="valgrind --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p"
|
||||
#PREFIX="valgrind --leak-check=yes --track-fds=yes --error-exitcode=1 --log-file=valgrind.%p"
|
||||
|
||||
# Setup database
|
||||
taler-exchange-dbinit -c test_taler_exchange_httpd.conf &> /dev/null
|
||||
|
@ -446,13 +446,6 @@ struct TALER_TESTING_Interpreter
|
||||
*/
|
||||
char *exchange_url;
|
||||
|
||||
/**
|
||||
* #GNUNET_OK if key state should be reloaded. NOTE: this
|
||||
* field can be removed because a new "send signal" command
|
||||
* has been introduced.
|
||||
*/
|
||||
int reload_keys;
|
||||
|
||||
/**
|
||||
* Is the interpreter running (#GNUNET_YES) or waiting
|
||||
* for /keys (#GNUNET_NO)?
|
||||
@ -1227,54 +1220,6 @@ TALER_TESTING_cmd_exec_transfer (const char *label,
|
||||
const char *config_filename);
|
||||
|
||||
|
||||
/**
|
||||
* Make the "keyup" CMD.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param config_filename configuration filename.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exec_keyup (const char *label,
|
||||
const char *config_filename);
|
||||
|
||||
|
||||
/**
|
||||
* Make the "keyup" CMD, with "--timestamp" option.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param config_filename configuration filename.
|
||||
* @param now Unix timestamp representing the fake "now".
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exec_keyup_with_now (const char *label,
|
||||
const char *config_filename,
|
||||
struct GNUNET_TIME_Absolute now);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
* generation /keys downloads took place. If the number
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @param now timestamp to use when fetching keys
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_now (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys,
|
||||
struct GNUNET_TIME_Absolute now);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "auditor sign" CMD.
|
||||
*
|
||||
@ -1840,27 +1785,21 @@ TALER_TESTING_cmd_wait_service (const char *label,
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys.
|
||||
* Make a "check keys" command.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation how many /keys responses are expected to
|
||||
* have been returned when this CMD will be run.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
*
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys);
|
||||
unsigned int generation);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command that forcedly does NOT cherry pick;
|
||||
* just redownload the whole /keys. Then checks whether the number
|
||||
* of denomination keys from @a exchange matches @a num_denom_keys.
|
||||
* just redownload the whole /keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
@ -1868,20 +1807,15 @@ TALER_TESTING_cmd_check_keys (const char *label,
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys);
|
||||
unsigned int generation);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys. Additionally,
|
||||
* it lets the user set a last denom issue date to be
|
||||
* Make a "check keys" command. It lets the user set a last denom issue date to be
|
||||
* used in the request for /keys.
|
||||
*
|
||||
* @param label command label
|
||||
@ -1890,17 +1824,15 @@ TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label,
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @param last_denom_date date to be set in the "last_denom_issue"
|
||||
* URL parameter of /keys.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (const char *label,
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (
|
||||
const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys,
|
||||
struct GNUNET_TIME_Absolute
|
||||
last_denom_date);
|
||||
struct GNUNET_TIME_Absolute last_denom_date);
|
||||
|
||||
|
||||
/**
|
||||
@ -2169,6 +2101,22 @@ TALER_TESTING_cmd_exec_offline_sign_keys (const char *label,
|
||||
const char *config_filename);
|
||||
|
||||
|
||||
/**
|
||||
* Sign a wire fee.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param config_filename configuration filename.
|
||||
* @param wire_fee the wire fee to affirm (for the current year)
|
||||
* @param closing_fee the closing fee to affirm (for the current year)
|
||||
* @return the command
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exec_offline_sign_fees (const char *label,
|
||||
const char *config_filename,
|
||||
const char *wire_fee,
|
||||
const char *closing_fee);
|
||||
|
||||
|
||||
/**
|
||||
* Revoke an exchange denomination key.
|
||||
*
|
||||
|
@ -56,10 +56,10 @@ libtalertesting_la_SOURCES = \
|
||||
testing_api_cmd_exec_aggregator.c \
|
||||
testing_api_cmd_exec_auditor-sign.c \
|
||||
testing_api_cmd_exec_closer.c \
|
||||
testing_api_cmd_exec_keyup.c \
|
||||
testing_api_cmd_exec_transfer.c \
|
||||
testing_api_cmd_exec_wirewatch.c \
|
||||
testing_api_cmd_insert_deposit.c \
|
||||
testing_api_cmd_offline_sign_fees.c \
|
||||
testing_api_cmd_offline_sign_keys.c \
|
||||
testing_api_cmd_set_wire_fee.c \
|
||||
testing_api_cmd_recoup.c \
|
||||
|
@ -630,8 +630,7 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
2,
|
||||
270 /* FIXME: wrong number... */),
|
||||
2),
|
||||
CMD_RUN_AUDITOR ("virgin-auditor"),
|
||||
TALER_TESTING_cmd_exchanges_with_url ("check-exchange",
|
||||
MHD_HTTP_OK,
|
||||
|
@ -956,9 +956,12 @@ run (void *cls,
|
||||
false),
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
|
||||
CONFIG_FILE,
|
||||
"EUR:0.01",
|
||||
"EUR:0.01"),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
270 /* FIXME: wrong number... */),
|
||||
1),
|
||||
TALER_TESTING_cmd_batch ("wire",
|
||||
wire),
|
||||
TALER_TESTING_cmd_batch ("withdraw",
|
||||
|
@ -81,14 +81,11 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
1 /* FIXME: wrong number... */),
|
||||
1),
|
||||
TALER_TESTING_cmd_check_keys ("first-download",
|
||||
1,
|
||||
1),
|
||||
/* Causes GET /keys?last_denom_issue=0 */
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom ("second-download",
|
||||
3,
|
||||
1,
|
||||
GNUNET_TIME_UNIT_ZERO_ABS),
|
||||
TALER_TESTING_cmd_end ()
|
||||
|
@ -72,8 +72,7 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
270 /* FIXME: wrong number... */),
|
||||
1),
|
||||
/**
|
||||
* Fill reserve with EUR:10.02, as withdraw fee is 1 ct per
|
||||
* config.
|
||||
|
@ -221,8 +221,7 @@ run (void *cls,
|
||||
"Wed, 19 Jan 586524 08:01:49 GMT"),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys (
|
||||
"check-keys-expiration-0",
|
||||
2,
|
||||
270),
|
||||
2),
|
||||
/**
|
||||
* Run some normal commands after this to make sure everything is fine.
|
||||
*/
|
||||
@ -244,8 +243,7 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
270 /* FIXME: wrong number... */),
|
||||
1),
|
||||
TALER_TESTING_cmd_batch ("refresh-reveal-409-conflict",
|
||||
refresh_409_conflict),
|
||||
TALER_TESTING_cmd_batch ("refund",
|
||||
|
@ -143,8 +143,7 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("download-future-keys",
|
||||
CONFIG_FILE),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
270 /* FIXME: wrong number... */),
|
||||
1),
|
||||
TALER_TESTING_cmd_end ()
|
||||
};
|
||||
|
||||
|
@ -92,8 +92,7 @@ run (void *cls,
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
config_filename),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys",
|
||||
1,
|
||||
58 /* FIXME: wrong number... */),
|
||||
1),
|
||||
TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-on-start"),
|
||||
CMD_EXEC_AGGREGATOR ("run-aggregator-on-empty"),
|
||||
TALER_TESTING_cmd_exec_wirewatch ("run-wirewatch-on-empty",
|
||||
|
@ -46,12 +46,6 @@ struct CheckKeysState
|
||||
*/
|
||||
unsigned int generation;
|
||||
|
||||
/**
|
||||
* How many denomination keys the exchange is
|
||||
* supposed to have.
|
||||
*/
|
||||
unsigned int num_denom_keys;
|
||||
|
||||
/**
|
||||
* If this value is GNUNET_YES, then the "cherry
|
||||
* picking" facility is turned off; whole /keys is
|
||||
@ -156,19 +150,6 @@ check_keys_run (void *cls,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* "/keys" was updated, let's check they were OK! */
|
||||
if (cks->num_denom_keys != is->keys->num_denom_keys)
|
||||
{
|
||||
/* Did not get the expected number of denomination keys! */
|
||||
GNUNET_break (0);
|
||||
TALER_LOG_ERROR ("Got %u keys in step %s, expected %u\n",
|
||||
is->keys->num_denom_keys,
|
||||
cmd->label,
|
||||
cks->num_denom_keys);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Let's unset the fake now before moving on. */
|
||||
TALER_EXCHANGE_unset_now (is->exchange);
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
@ -192,36 +173,16 @@ check_keys_cleanup (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys. Additionally,
|
||||
* it lets the user set a last denom issue date to be
|
||||
* used in the request for /keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
* generation /keys downloads took place. If the number
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @param last_denom_date date to be set in the "last_denom_issue"
|
||||
* URL parameter of /keys.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (const char *label,
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (
|
||||
const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys,
|
||||
struct GNUNET_TIME_Absolute
|
||||
last_denom_date)
|
||||
struct GNUNET_TIME_Absolute last_denom_date)
|
||||
{
|
||||
struct CheckKeysState *cks;
|
||||
|
||||
cks = GNUNET_new (struct CheckKeysState);
|
||||
cks->generation = generation;
|
||||
cks->num_denom_keys = num_denom_keys;
|
||||
cks->set_last_denom = GNUNET_YES;
|
||||
cks->last_denom_date = last_denom_date;
|
||||
{
|
||||
@ -237,30 +198,14 @@ TALER_TESTING_cmd_check_keys_with_last_denom (const char *label,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
* generation /keys downloads took place. If the number
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys)
|
||||
unsigned int generation)
|
||||
{
|
||||
struct CheckKeysState *cks;
|
||||
|
||||
cks = GNUNET_new (struct CheckKeysState);
|
||||
cks->generation = generation;
|
||||
cks->num_denom_keys = num_denom_keys;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = cks,
|
||||
@ -274,74 +219,14 @@ TALER_TESTING_cmd_check_keys (const char *label,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. This type of command
|
||||
* checks whether the number of denomination keys from
|
||||
* @a exchange matches @a num_denom_keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
* generation /keys downloads took place. If the number
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @param now timestamp to use when fetching keys
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_now (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys,
|
||||
struct GNUNET_TIME_Absolute now)
|
||||
{
|
||||
struct CheckKeysState *cks;
|
||||
|
||||
cks = GNUNET_new (struct CheckKeysState);
|
||||
cks->generation = generation;
|
||||
cks->num_denom_keys = num_denom_keys;
|
||||
cks->now = now;
|
||||
cks->with_now = GNUNET_YES;
|
||||
|
||||
/* Force to NOT cherry pick, otherwise they conflict. */
|
||||
cks->pull_all_keys = GNUNET_YES;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = cks,
|
||||
.label = label,
|
||||
.run = &check_keys_run,
|
||||
.cleanup = &check_keys_cleanup
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command that forcedly does NOT cherry pick;
|
||||
* just redownload the whole /keys. Then checks whether the number
|
||||
* of denomination keys from @a exchange matches @a num_denom_keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param generation when this command is run, exactly @a
|
||||
* generation /keys downloads took place. If the number
|
||||
* of downloads is less than @a generation, the logic will
|
||||
* first make sure that @a generation downloads are done,
|
||||
* and _then_ execute the rest of the command.
|
||||
* @param num_denom_keys expected number of denomination keys.
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label,
|
||||
unsigned int generation,
|
||||
unsigned int num_denom_keys)
|
||||
unsigned int generation)
|
||||
{
|
||||
struct CheckKeysState *cks;
|
||||
|
||||
cks = GNUNET_new (struct CheckKeysState);
|
||||
cks->generation = generation;
|
||||
cks->num_denom_keys = num_denom_keys;
|
||||
cks->pull_all_keys = GNUNET_YES;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
|
192
src/testing/testing_api_cmd_offline_sign_fees.c
Normal file
192
src/testing/testing_api_cmd_offline_sign_fees.c
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 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_cmd_offline_sign_fees.c
|
||||
* @brief run the taler-exchange-offline command to download, sign and upload wire fees
|
||||
* @author Marcello Stanisci
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_testing_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* State for a "offlinesign" CMD.
|
||||
*/
|
||||
struct OfflineSignState
|
||||
{
|
||||
|
||||
/**
|
||||
* Process for the "offlinesign" command.
|
||||
*/
|
||||
struct GNUNET_OS_Process *offlinesign_proc;
|
||||
|
||||
/**
|
||||
* Configuration file used by the command.
|
||||
*/
|
||||
const char *config_filename;
|
||||
|
||||
/**
|
||||
* The wire fee to sign.
|
||||
*/
|
||||
const char *wire_fee_s;
|
||||
|
||||
/**
|
||||
* The closing fee to sign.
|
||||
*/
|
||||
const char *closing_fee_s;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Run the command; calls the `taler-exchange-offline' program.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the commaind being run.
|
||||
* @param is interpreter state.
|
||||
*/
|
||||
static void
|
||||
offlinesign_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct OfflineSignState *ks = cls;
|
||||
|
||||
ks->offlinesign_proc
|
||||
= GNUNET_OS_start_process (
|
||||
GNUNET_OS_INHERIT_STD_ALL,
|
||||
NULL, NULL, NULL,
|
||||
"taler-exchange-offline",
|
||||
"taler-exchange-offline",
|
||||
"-c", ks->config_filename,
|
||||
"-L", "INFO",
|
||||
"wire-fee",
|
||||
"now",
|
||||
"x-taler-bank",
|
||||
ks->wire_fee_s,
|
||||
ks->closing_fee_s,
|
||||
"upload",
|
||||
NULL);
|
||||
if (NULL == ks->offlinesign_proc)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_wait_for_sigchld (is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free the state of a "offlinesign" CMD, and possibly kills its
|
||||
* process if it did not terminate correctly.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command being freed.
|
||||
*/
|
||||
static void
|
||||
offlinesign_cleanup (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd)
|
||||
{
|
||||
struct OfflineSignState *ks = cls;
|
||||
|
||||
(void) cmd;
|
||||
if (NULL != ks->offlinesign_proc)
|
||||
{
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (ks->offlinesign_proc,
|
||||
SIGKILL));
|
||||
GNUNET_OS_process_wait (ks->offlinesign_proc);
|
||||
GNUNET_OS_process_destroy (ks->offlinesign_proc);
|
||||
ks->offlinesign_proc = NULL;
|
||||
}
|
||||
GNUNET_free (ks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Offer "offlinesign" CMD internal data to other commands.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param[out] ret result
|
||||
* @param trait name of the trait.
|
||||
* @param index index number of the object to offer.
|
||||
* @return #GNUNET_OK on success.
|
||||
*/
|
||||
static int
|
||||
offlinesign_traits (void *cls,
|
||||
const void **ret,
|
||||
const char *trait,
|
||||
unsigned int index)
|
||||
{
|
||||
struct OfflineSignState *ks = cls;
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_process (0,
|
||||
&ks->offlinesign_proc),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
return TALER_TESTING_get_trait (traits,
|
||||
ret,
|
||||
trait,
|
||||
index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sign a wire fee.
|
||||
*
|
||||
* @param label command label.
|
||||
* @param config_filename configuration filename.
|
||||
* @param wire_fee the wire fee to affirm (for the current year)
|
||||
* @param closing_fee the closing fee to affirm (for the current year)
|
||||
* @return the command
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_exec_offline_sign_fees (const char *label,
|
||||
const char *config_filename,
|
||||
const char *wire_fee,
|
||||
const char *closing_fee)
|
||||
{
|
||||
struct OfflineSignState *ks;
|
||||
|
||||
ks = GNUNET_new (struct OfflineSignState);
|
||||
ks->config_filename = config_filename;
|
||||
ks->wire_fee_s = wire_fee;
|
||||
ks->closing_fee_s = closing_fee;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = ks,
|
||||
.label = label,
|
||||
.run = &offlinesign_run,
|
||||
.cleanup = &offlinesign_cleanup,
|
||||
.traits = &offlinesign_traits
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* end of testing_api_cmd_exec_offline_sign_fees.c */
|
@ -181,8 +181,6 @@ revoke_run (void *cls,
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Revoke is ongoing..\n");
|
||||
|
||||
is->reload_keys = GNUNET_OK;
|
||||
TALER_TESTING_wait_for_sigchld (is);
|
||||
}
|
||||
|
||||
|
@ -463,24 +463,6 @@ maint_child_death (void *cls)
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: remove reload_keys, obsolete!
|
||||
if (GNUNET_OK == is->reload_keys)
|
||||
{
|
||||
if (NULL == is->exchanged)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Triggering key state reload at exchange\n");
|
||||
GNUNET_break (0 ==
|
||||
GNUNET_OS_process_kill (is->exchanged,
|
||||
SIGUSR1));
|
||||
sleep (5); /* make sure signal was received and processed */
|
||||
}
|
||||
}
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Dead child, go on with next command.\n");
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
|
Loading…
Reference in New Issue
Block a user