more refactoring towards using libtalermhd

This commit is contained in:
Christian Grothoff 2019-11-23 18:47:07 +01:00
parent 8bca461ea9
commit e8a88392da
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
14 changed files with 331 additions and 542 deletions

View File

@ -23,7 +23,6 @@ taler_auditor_dbinit_SOURCES = \
taler-auditor-dbinit.c taler-auditor-dbinit.c
taler_auditor_dbinit_LDADD = \ taler_auditor_dbinit_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/pq/libtalerpq.la \ $(top_builddir)/src/pq/libtalerpq.la \
$(top_builddir)/src/auditordb/libtalerauditordb.la \ $(top_builddir)/src/auditordb/libtalerauditordb.la \
@ -58,6 +57,7 @@ taler_auditor_httpd_SOURCES = \
taler-auditor-httpd_responses.c taler-auditor-httpd_responses.h taler-auditor-httpd_responses.c taler-auditor-httpd_responses.h
taler_auditor_httpd_LDADD = \ taler_auditor_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/wire/libtalerwire.la \

View File

@ -385,7 +385,7 @@ handle_mhd_request (void *cls,
&TAH_MHD_handler_static_response, MHD_HTTP_OK }, &TAH_MHD_handler_static_response, MHD_HTTP_OK },
/* AGPL licensing page, redirect to source. As per the AGPL-license, /* AGPL licensing page, redirect to source. As per the AGPL-license,
every deployment is required to offer the user a download of the every deployment is required to offer the user a download of the
source. We make this easy by including a redirect to the source source. We make this easy by including a redirect t the source
here. */ here. */
{ "/agpl", MHD_HTTP_METHOD_GET, "text/plain", { "/agpl", MHD_HTTP_METHOD_GET, "text/plain",
NULL, 0, NULL, 0,
@ -393,11 +393,6 @@ handle_mhd_request (void *cls,
{ NULL, NULL, NULL, NULL, 0, 0 } { NULL, NULL, NULL, NULL, 0, 0 }
}; };
static struct TAH_RequestHandler h404 = {
"", NULL, "text/html",
"<html><title>404: not found</title></html>", 0,
&TAH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
};
struct TAH_RequestHandler *rh; struct TAH_RequestHandler *rh;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -420,11 +415,13 @@ handle_mhd_request (void *cls,
upload_data, upload_data,
upload_data_size); upload_data_size);
} }
return TAH_MHD_handler_static_response (&h404, #define NOT_FOUND "<html><title>404: not found</title></html>"
connection, return TALER_MHD_reply_static (connection,
con_cls, MHD_HTTP_NOT_FOUND,
upload_data, "text/html",
upload_data_size); NOT_FOUND,
strlen (NOT_FOUND));
#undef NOT_FOUND
} }

View File

@ -28,6 +28,8 @@
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include <pthread.h> #include <pthread.h>
#include "taler_mhd_lib.h"
#include "taler-auditor-httpd_responses.h"
#include "taler-auditor-httpd_responses.h" #include "taler-auditor-httpd_responses.h"
#include "taler-auditor-httpd.h" #include "taler-auditor-httpd.h"
#include "taler-auditor-httpd_mhd.h" #include "taler-auditor-httpd_mhd.h"
@ -94,38 +96,12 @@ TAH_MHD_handler_agpl_redirect (struct TAH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
const char *agpl = (void) rh;
"This server is licensed under the Affero GPL. You will now be redirected to the source code."; (void) connection_cls;
struct MHD_Response *response; (void) upload_data;
int ret; (void) upload_data_size;
return TALER_MHD_reply_agpl (connection,
response = MHD_create_response_from_buffer (strlen (agpl), "http://www.git.taler.net/?p=exchange.git");
(void *) agpl,
MHD_RESPMEM_PERSISTENT);
if (NULL == response)
{
GNUNET_break (0);
return MHD_NO;
}
TAH_RESPONSE_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
rh->mime_type);
if (MHD_NO ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_LOCATION,
"http://www.git.taler.net/?p=auditor.git"))
{
GNUNET_break (0);
MHD_destroy_response (response);
return MHD_NO;
}
ret = MHD_queue_response (connection,
rh->response_code,
response);
MHD_destroy_response (response);
return ret;
} }

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
/** /**
* @file taler-exchange-httpd_responses.c * @file taler-auditor-httpd_responses.c
* @brief API for generating genric replies of the exchange; these * @brief API for generating genric replies of the exchange; these
* functions are called TAH_RESPONSE_reply_ and they generate * functions are called TAH_RESPONSE_reply_ and they generate
* and queue MHD response objects for a given connection. * and queue MHD response objects for a given connection.
@ -24,6 +24,7 @@
*/ */
#include "platform.h" #include "platform.h"
#include <zlib.h> #include <zlib.h>
#include "taler_mhd_lib.h"
#include "taler-auditor-httpd_responses.h" #include "taler-auditor-httpd_responses.h"
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"

View File

@ -737,7 +737,6 @@ connection_done (void *cls,
static void static void
write_stats () write_stats ()
{ {
struct GNUNET_DISK_FileHandle *fh; struct GNUNET_DISK_FileHandle *fh;
pid_t pid = getpid (); pid_t pid = getpid ();
char *benchmark_dir; char *benchmark_dir;

View File

@ -29,6 +29,7 @@
#include <microhttpd.h> #include <microhttpd.h>
#include <pthread.h> #include <pthread.h>
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_deposit.h" #include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_responses.h"
@ -83,17 +84,17 @@ reply_deposit_success (struct MHD_Connection *connection,
&pub, &pub,
&sig)) &sig))
{ {
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
} }
return TEH_RESPONSE_reply_json_pack (connection, return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:s, s:o, s:o}", "{s:s, s:o, s:o}",
"status", "DEPOSIT_OK", "status", "DEPOSIT_OK",
"sig", GNUNET_JSON_from_data_auto (&sig), "sig", GNUNET_JSON_from_data_auto (&sig),
"pub", GNUNET_JSON_from_data_auto ( "pub", GNUNET_JSON_from_data_auto (&pub));
&pub));
} }
@ -149,8 +150,10 @@ deposit_transaction (void *cls,
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
"Could not check for existing identical deposit");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
return qs; return qs;
@ -197,8 +200,10 @@ deposit_transaction (void *cls,
{ {
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
"could not access coin history");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
/* Check that cost of all transactions is smaller than /* Check that cost of all transactions is smaller than
@ -223,8 +228,10 @@ deposit_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
TALER_LOG_WARNING ("Failed to store /deposit information in database\n"); TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_STORE_DB_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_DEPOSIT_STORE_DB_ERROR,
"Could not persist /deposit data");
} }
return qs; return qs;
} }
@ -273,9 +280,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
&deposit->coin.coin_pub.eddsa_pub)) &deposit->coin.coin_pub.eddsa_pub))
{ {
TALER_LOG_WARNING ("Invalid signature on /deposit request\n"); TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID, MHD_HTTP_UNAUTHORIZED,
"coin_sig"); TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
"coin_sig");
} }
/* check denomination */ /* check denomination */
@ -295,9 +303,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
if (NULL == dki) if (NULL == dki)
{ {
TEH_KS_release (mks); TEH_KS_release (mks);
return TEH_RESPONSE_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
ec, ec,
hc); hc,
"Could not find denomination key used in deposit");
} }
TALER_amount_ntoh (&dc.value, TALER_amount_ntoh (&dc.value,
&dki->issue.properties.value); &dki->issue.properties.value);
@ -445,9 +454,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, MHD_HTTP_BAD_REQUEST,
"refund_deadline"); TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
"refund_deadline");
} }
if (TALER_EC_NONE != if (TALER_EC_NONE !=
@ -466,9 +476,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_INVALID_TIMESTAMP, MHD_HTTP_BAD_REQUEST,
"timestamp"); TALER_EC_DEPOSIT_INVALID_TIMESTAMP,
"timestamp");
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_JSON_merchant_wire_signature_hash (wire, TALER_JSON_merchant_wire_signature_hash (wire,
@ -477,18 +488,20 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ( TALER_LOG_WARNING (
"Failed to parse JSON wire format specification for /deposit request\n"); "Failed to parse JSON wire format specification for /deposit request\n");
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON, MHD_HTTP_BAD_REQUEST,
"wire"); TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
"wire");
} }
if (0 != GNUNET_memcmp (&deposit.h_wire, if (0 != GNUNET_memcmp (&deposit.h_wire,
&my_h_wire)) &my_h_wire))
{ {
/* Client hashed contract differently than we did, reject */ /* Client hashed contract differently than we did, reject */
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT, MHD_HTTP_BAD_REQUEST,
"H_wire"); TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
"H_wire");
} }
/* check denomination exists and is valid */ /* check denomination exists and is valid */
@ -497,9 +510,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
} }
dki = TEH_KS_denomination_key_lookup_by_hash (key_state, dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&deposit.coin.denom_pub_hash, &deposit.coin.denom_pub_hash,
@ -511,9 +525,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TEH_KS_release (key_state); TEH_KS_release (key_state);
TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n"); TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
ec, ec,
hc); hc,
"Could not find denomination key used in deposit");
} }
TALER_amount_ntoh (&deposit.deposit_fee, TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit); &dki->issue.properties.fee_deposit);
@ -525,9 +540,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n"); TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
TEH_KS_release (key_state); TEH_KS_release (key_state);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID, MHD_HTTP_UNAUTHORIZED,
"ub_sig"); TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
"ub_sig");
} }
TALER_amount_ntoh (&deposit.deposit_fee, TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit); &dki->issue.properties.fee_deposit);
@ -538,9 +554,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_external_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, MHD_HTTP_BAD_REQUEST,
"deposited amount smaller than depositing fee"); TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
"deposited amount smaller than depositing fee");
} }
/* make sure coin is 'known' in database */ /* make sure coin is 'known' in database */

View File

@ -23,6 +23,7 @@
#include "platform.h" #include "platform.h"
#include <pthread.h> #include <pthread.h>
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_keystate.h" #include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_responses.h"
#include "taler_exchangedb_plugin.h" #include "taler_exchangedb_plugin.h"
@ -2378,9 +2379,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
&cherrypickn)) &cherrypickn))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_KEYS_HAVE_NOT_NUMERIC, MHD_HTTP_BAD_REQUEST,
"last_issue_date"); TALER_EC_KEYS_HAVE_NOT_NUMERIC,
"last_issue_date");
} }
last_issue_date.abs_value_us = (uint64_t) cherrypickn * 1000000LLU; last_issue_date.abs_value_us = (uint64_t) cherrypickn * 1000000LLU;
} }
@ -2402,9 +2404,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
&fakenown)) &fakenown))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_KEYS_HAVE_NOT_NUMERIC, MHD_HTTP_BAD_REQUEST,
"now"); TALER_EC_KEYS_HAVE_NOT_NUMERIC,
"now");
} }
now.abs_value_us = (uint64_t) fakenown * 1000000LLU; now.abs_value_us = (uint64_t) fakenown * 1000000LLU;
} }
@ -2413,9 +2416,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
if (NULL == key_state) if (NULL == key_state)
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
} }
krd = bsearch (&last_issue_date, krd = bsearch (&last_issue_date,
key_state->krd_array, key_state->krd_array,
@ -2444,7 +2448,7 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
} }
ret = MHD_queue_response (connection, ret = MHD_queue_response (connection,
rh->response_code, rh->response_code,
(MHD_YES == TEH_RESPONSE_can_compress (connection)) (MHD_YES == TALER_MHD_can_compress (connection))
? krd->response_compressed ? krd->response_compressed
: krd->response_uncompressed); : krd->response_uncompressed);
TEH_KS_release (key_state); TEH_KS_release (key_state);

View File

@ -28,6 +28,7 @@
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include <pthread.h> #include <pthread.h>
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd.h" #include "taler-exchange-httpd.h"
#include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_mhd.h"
@ -97,41 +98,12 @@ TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
const char *agpl = (void) rh;
"This server is licensed under the Affero GPL. You will now be redirected to the source code.";
struct MHD_Response *response;
int ret;
(void) connection_cls; (void) connection_cls;
(void) upload_data; (void) upload_data;
(void) upload_data_size; (void) upload_data_size;
response = MHD_create_response_from_buffer (strlen (agpl), return TALER_MHD_reply_agpl (connection,
(void *) agpl, "http://www.git.taler.net/?p=exchange.git");
MHD_RESPMEM_PERSISTENT);
if (NULL == response)
{
GNUNET_break (0);
return MHD_NO;
}
TEH_RESPONSE_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
rh->mime_type);
if (MHD_NO ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_LOCATION,
"http://www.git.taler.net/?p=exchange.git"))
{
GNUNET_break (0);
MHD_destroy_response (response);
return MHD_NO;
}
ret = MHD_queue_response (connection,
rh->response_code,
response);
MHD_destroy_response (response);
return ret;
} }

View File

@ -34,26 +34,6 @@
#include "taler-exchange-httpd_validation.h" #include "taler-exchange-httpd_validation.h"
/**
* A wallet asked for /payback, but we do not know anything about the
* original withdraw operation specified. Generates a 404 reply.
*
* @param connection connection to the client
* @param ec Taler error code
* @return MHD result code
*/
static int
reply_payback_unknown (struct MHD_Connection *connection,
enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
"{s:s, s:I}",
"error", "blinded coin unknown",
"code", (json_int_t) ec);
}
/** /**
* A wallet asked for /payback, return the successful response. * A wallet asked for /payback, return the successful response.
* *
@ -268,8 +248,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
GNUNET_break (0); GNUNET_break (0);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_DB_FETCH_FAILED); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_DB_FETCH_FAILED,
"failed to fetch old coin of blind coin");
} }
return qs; return qs;
} }
@ -285,8 +267,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
GNUNET_break (0); GNUNET_break (0);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_DB_FETCH_FAILED); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_DB_FETCH_FAILED,
"failed to fetch reserve of blinded coin");
} }
return qs; return qs;
} }
@ -296,8 +280,10 @@ payback_transaction (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Payback requested for unknown envelope %s\n", "Payback requested for unknown envelope %s\n",
GNUNET_h2s (&pc->h_blind)); GNUNET_h2s (&pc->h_blind));
*mhd_ret = reply_payback_unknown (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND); MHD_HTTP_NOT_FOUND,
TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND,
"blind coin unknown");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
@ -312,8 +298,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
GNUNET_break (0); GNUNET_break (0);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_DB_FETCH_FAILED); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_DB_FETCH_FAILED,
"failed to fetch old coin transaction history");
} }
return qs; return qs;
} }
@ -329,8 +317,10 @@ payback_transaction (void *cls,
GNUNET_break (0); GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_HISTORY_DB_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_HISTORY_DB_ERROR,
"failed to calculate old coin transaction history");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (GNUNET_SYSERR == if (GNUNET_SYSERR ==
@ -341,8 +331,10 @@ payback_transaction (void *cls,
GNUNET_break (0); GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE,
"calculated negative old coin balance");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if ( (0 == pc->amount.fraction) && if ( (0 == pc->amount.fraction) &&
@ -391,8 +383,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
TALER_LOG_WARNING ("Failed to store /payback information in database\n"); TALER_LOG_WARNING ("Failed to store /payback information in database\n");
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_DB_PUT_FAILED); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PAYBACK_DB_PUT_FAILED,
"failed to persist payback data");
} }
return qs; return qs;
} }
@ -437,9 +431,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
if (NULL == key_state) if (NULL == key_state)
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
} }
dki = TEH_KS_denomination_key_lookup_by_hash (key_state, dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&coin->denom_pub_hash, &coin->denom_pub_hash,
@ -451,9 +446,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
TEH_KS_release (key_state); TEH_KS_release (key_state);
TALER_LOG_WARNING ( TALER_LOG_WARNING (
"Denomination key in /payback request not in payback mode\n"); "Denomination key in /payback request not in payback mode\n");
return TEH_RESPONSE_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
ec, ec,
hc); hc,
"denomination not allowing payback");
} }
TALER_amount_ntoh (&pc.value, TALER_amount_ntoh (&pc.value,
&dki->issue.properties.value); &dki->issue.properties.value);
@ -465,9 +461,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
{ {
TALER_LOG_WARNING ("Invalid coin passed for /payback\n"); TALER_LOG_WARNING ("Invalid coin passed for /payback\n");
TEH_KS_release (key_state); TEH_KS_release (key_state);
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID, MHD_HTTP_FORBIDDEN,
"denom_sig"); TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
"denom_sig");
} }
/* check payback request signature */ /* check payback request signature */
@ -485,9 +482,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
{ {
TALER_LOG_WARNING ("Invalid signature on /payback request\n"); TALER_LOG_WARNING ("Invalid signature on /payback request\n");
TEH_KS_release (key_state); TEH_KS_release (key_state);
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_SIGNATURE_INVALID, MHD_HTTP_FORBIDDEN,
"coin_sig"); TALER_EC_PAYBACK_SIGNATURE_INVALID,
"coin_sig");
} }
GNUNET_CRYPTO_hash (&coin->coin_pub.eddsa_pub, GNUNET_CRYPTO_hash (&coin->coin_pub.eddsa_pub,
@ -503,9 +501,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
GNUNET_break (0); GNUNET_break (0);
TEH_KS_release (key_state); TEH_KS_release (key_state);
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_PAYBACK_BLINDING_FAILED, MHD_HTTP_INTERNAL_SERVER_ERROR,
"coin_bks"); TALER_EC_PAYBACK_BLINDING_FAILED,
"coin_bks");
} }
TEH_KS_release (key_state); TEH_KS_release (key_state);
GNUNET_CRYPTO_hash (coin_ev, GNUNET_CRYPTO_hash (coin_ev,

View File

@ -24,6 +24,7 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_link.h" #include "taler-exchange-httpd_refresh_link.h"
@ -156,16 +157,18 @@ refresh_link_transaction (void *cls,
ctx); ctx);
if (NULL == ctx->mlist) if (NULL == ctx->mlist)
{ {
*mhd_ret = TEH_RESPONSE_reply_internal_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
ctx->ec, MHD_HTTP_INTERNAL_SERVER_ERROR,
"coin_pub"); ctx->ec,
"coin_pub");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{ {
*mhd_ret = TEH_RESPONSE_reply_arg_unknown (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_LINK_COIN_UNKNOWN, MHD_HTTP_NOT_FOUND,
"coin_pub"); TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
"coin_pub");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
return qs; return qs;
@ -222,9 +225,9 @@ TEH_REFRESH_handler_refresh_link (struct TEH_RequestHandler *rh,
json_decref (ctx.mlist); json_decref (ctx.mlist);
return mhd_ret; return mhd_ret;
} }
mhd_ret = TEH_RESPONSE_reply_json (connection, mhd_ret = TALER_MHD_reply_json (connection,
ctx.mlist, ctx.mlist,
MHD_HTTP_OK); MHD_HTTP_OK);
json_decref (ctx.mlist); json_decref (ctx.mlist);
return mhd_ret; return mhd_ret;
} }

View File

@ -24,6 +24,7 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_melt.h" #include "taler-exchange-httpd_refresh_melt.h"
@ -60,26 +61,28 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
history = TEH_RESPONSE_compile_transaction_history (tl); history = TEH_RESPONSE_compile_transaction_history (tl);
if (NULL == history) if (NULL == history)
return TEH_RESPONSE_reply_internal_db_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS); MHD_HTTP_INTERNAL_SERVER_ERROR,
return TEH_RESPONSE_reply_json_pack (connection, TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
MHD_HTTP_FORBIDDEN, "Failed to compile transaction history");
"{s:s, s:I, s:o, s:o, s:o, s:o, s:o}", return TALER_MHD_reply_json_pack (connection,
"error", MHD_HTTP_FORBIDDEN,
"insufficient funds", "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
"code", "error",
(json_int_t) "insufficient funds",
TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS, "code",
"coin_pub", (json_int_t)
GNUNET_JSON_from_data_auto (coin_pub), TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
"original_value", "coin_pub",
TALER_JSON_from_amount (&coin_value), GNUNET_JSON_from_data_auto (coin_pub),
"residual_value", "original_value",
TALER_JSON_from_amount (residual), TALER_JSON_from_amount (&coin_value),
"requested_value", "residual_value",
TALER_JSON_from_amount (requested), TALER_JSON_from_amount (residual),
"history", "requested_value",
history); TALER_JSON_from_amount (requested),
"history",
history);
} }
@ -110,19 +113,20 @@ reply_refresh_melt_success (struct MHD_Connection *connection,
&pub, &pub,
&sig)) &sig))
{ {
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
} }
sig_json = GNUNET_JSON_from_data_auto (&sig); sig_json = GNUNET_JSON_from_data_auto (&sig);
GNUNET_assert (NULL != sig_json); GNUNET_assert (NULL != sig_json);
return TEH_RESPONSE_reply_json_pack (connection, return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:i, s:o, s:o}", "{s:i, s:o, s:o}",
"noreveal_index", (int) noreveal_index, "noreveal_index", (int) noreveal_index,
"exchange_sig", sig_json, "exchange_sig", sig_json,
"exchange_pub", "exchange_pub",
GNUNET_JSON_from_data_auto (&pub)); GNUNET_JSON_from_data_auto (&pub));
} }
@ -189,8 +193,10 @@ refresh_check_melt (struct MHD_Connection *connection,
if (0 > qs) if (0 > qs)
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
"failed to fetch old coin history");
return qs; return qs;
} }
if (rmc->zombie_required) if (rmc->zombie_required)
@ -211,9 +217,10 @@ refresh_check_melt (struct MHD_Connection *connection,
GNUNET_break (0); GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TEH_RESPONSE_reply_external_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE, MHD_HTTP_BAD_REQUEST,
"denomination expired"); TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE,
"denomination expired");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
} }
@ -225,8 +232,10 @@ refresh_check_melt (struct MHD_Connection *connection,
GNUNET_break (0); GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED,
"failed to compute coin transaction history");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
@ -310,8 +319,10 @@ refresh_melt_transaction (void *cls,
if (0 > qs) if (0 > qs)
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
"failed to fetch melt index");
return qs; return qs;
} }
@ -335,8 +346,10 @@ refresh_melt_transaction (void *cls,
{ {
if (GNUNET_DB_STATUS_SOFT_ERROR != qs) if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
{ {
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR,
"failed to persist melt data");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
return qs; return qs;
@ -370,9 +383,10 @@ handle_refresh_melt (struct MHD_Connection *connection,
&rmc->refresh_session.amount_with_fee) > 0) &rmc->refresh_session.amount_with_fee) > 0)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_external_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION, MHD_HTTP_BAD_REQUEST,
"melt amount smaller than melting fee"); TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
"melt amount smaller than melting fee");
} }
} }
@ -398,9 +412,10 @@ handle_refresh_melt (struct MHD_Connection *connection,
eddsa_pub)) eddsa_pub))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID, MHD_HTTP_FORBIDDEN,
"confirm_sig"); TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
"confirm_sig");
} }
} }
@ -492,9 +507,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (NULL == key_state) if (NULL == key_state)
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
res = TEH_RESPONSE_reply_internal_error (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, MHD_HTTP_INTERNAL_SERVER_ERROR,
"no keys"); TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys");
goto cleanup; goto cleanup;
} }
@ -530,8 +546,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (0); GNUNET_break (0);
res = TEH_RESPONSE_reply_internal_db_error (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
"failed to find information about old coin");
goto cleanup; goto cleanup;
} }
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@ -566,9 +584,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (NULL == rmc.dki) if (NULL == rmc.dki)
{ {
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
res = TEH_RESPONSE_reply_with_error (connection, res = TALER_MHD_reply_with_error (connection,
ec, ec,
hc); hc,
"unknown denomination");
goto cleanup; goto cleanup;
} }
@ -579,9 +598,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
TEH_KS_release (key_state); TEH_KS_release (key_state);
return TEH_RESPONSE_reply_signature_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID, MHD_HTTP_FORBIDDEN,
"denom_sig"); TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
"denom_sig");
} }
/* run actual logic, now that the request was parsed */ /* run actual logic, now that the request was parsed */

View File

@ -24,6 +24,7 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_reveal.h" #include "taler-exchange-httpd_refresh_reveal.h"
@ -84,9 +85,9 @@ reply_refresh_reveal_success (struct MHD_Connection *connection,
json_object_set_new (root, json_object_set_new (root,
"ev_sigs", "ev_sigs",
list); list);
ret = TEH_RESPONSE_reply_json (connection, ret = TALER_MHD_reply_json (connection,
root, root,
MHD_HTTP_OK); MHD_HTTP_OK);
json_decref (root); json_decref (root);
} }
return ret; return ret;
@ -105,15 +106,15 @@ static int
reply_refresh_reveal_missmatch (struct MHD_Connection *connection, reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
const struct TALER_RefreshCommitmentP *rc) const struct TALER_RefreshCommitmentP *rc)
{ {
return TEH_RESPONSE_reply_json_pack (connection, return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_CONFLICT, MHD_HTTP_CONFLICT,
"{s:s, s:I, s:o}", "{s:s, s:I, s:o}",
"error", "commitment violation", "error", "commitment violation",
"code", "code",
(json_int_t) (json_int_t)
TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION, TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
"rc_expected", "rc_expected",
GNUNET_JSON_from_data_auto (rc)); GNUNET_JSON_from_data_auto (rc));
} }
@ -258,8 +259,10 @@ refresh_reveal_preflight (void *cls,
return qs; return qs;
case GNUNET_DB_STATUS_HARD_ERROR: case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_break (qs); GNUNET_break (qs);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_DB_FETCH_REVEAL_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_REVEAL_DB_FETCH_REVEAL_ERROR,
"failed to fetch reveal data");
rctx->preflight_ok = GNUNET_SYSERR; rctx->preflight_ok = GNUNET_SYSERR;
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
@ -308,9 +311,10 @@ refresh_reveal_transaction (void *cls,
&refresh_melt); &refresh_melt);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{ {
*mhd_ret = TEH_RESPONSE_reply_arg_invalid (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN, MHD_HTTP_NOT_FOUND,
"rc"); TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
"rc");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (GNUNET_DB_STATUS_SOFT_ERROR == qs) if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@ -319,8 +323,10 @@ refresh_reveal_transaction (void *cls,
(refresh_melt.session.noreveal_index >= TALER_CNC_KAPPA) ) (refresh_melt.session.noreveal_index >= TALER_CNC_KAPPA) )
{ {
GNUNET_break (0); GNUNET_break (0);
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR,
"failed to fetch valid challenge from database");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
@ -437,9 +443,10 @@ refresh_reveal_transaction (void *cls,
&total)) ) &total)) )
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
*mhd_ret = TEH_RESPONSE_reply_internal_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_COST_CALCULATION_OVERFLOW, MHD_HTTP_INTERNAL_SERVER_ERROR,
"failed to add up refresh costs"); TALER_EC_REFRESH_REVEAL_COST_CALCULATION_OVERFLOW,
"failed to add up refresh costs");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
} }
@ -447,9 +454,10 @@ refresh_reveal_transaction (void *cls,
&refresh_melt.session.amount_with_fee)) &refresh_melt.session.amount_with_fee))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
*mhd_ret = TEH_RESPONSE_reply_external_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_AMOUNT_INSUFFICIENT, MHD_HTTP_INTERNAL_SERVER_ERROR,
"melted coin value is insufficient to cover cost of operation"); TALER_EC_REFRESH_REVEAL_AMOUNT_INSUFFICIENT,
"melted coin value is insufficient to cover cost of operation");
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
} }
@ -501,8 +509,10 @@ refresh_reveal_persist (void *cls,
} }
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_DB_COMMIT_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_REVEAL_DB_COMMIT_ERROR,
"failed to persist reveal data");
} }
return qs; return qs;
} }
@ -542,26 +552,29 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
(0 == num_fresh_coins) ) (0 == num_fresh_coins) )
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE, MHD_HTTP_BAD_REQUEST,
"new_denoms_h"); TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
"new_denoms_h");
} }
if (json_array_size (new_denoms_h_json) != if (json_array_size (new_denoms_h_json) !=
json_array_size (coin_evs)) json_array_size (coin_evs))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH, MHD_HTTP_BAD_REQUEST,
"new_denoms/coin_evs"); TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
"new_denoms/coin_evs");
} }
if (json_array_size (new_denoms_h_json) != if (json_array_size (new_denoms_h_json) !=
json_array_size (link_sigs_json)) json_array_size (link_sigs_json))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH, MHD_HTTP_BAD_REQUEST,
"new_denoms/link_sigs"); TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
"new_denoms/link_sigs");
} }
/* Parse transfer private keys array */ /* Parse transfer private keys array */
@ -597,9 +610,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
{ {
TALER_LOG_ERROR ("Lacking keys to operate\n"); TALER_LOG_ERROR ("Lacking keys to operate\n");
/* FIXME: use correct EC code! */ /* FIXME: use correct EC code! */
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_SIGNING_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
"exchange lacks keys"); TALER_EC_REFRESH_REVEAL_SIGNING_ERROR,
"exchange lacks keys");
} }
/* Parse denomination key hashes */ /* Parse denomination key hashes */
@ -631,9 +645,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
if (NULL == dkis[i]) if (NULL == dkis[i])
{ {
TEH_KS_release (key_state); TEH_KS_release (key_state);
return TEH_RESPONSE_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
ec, ec,
hc); hc,
"failed to find denomination key");
} }
GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key); GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
} }
@ -677,19 +692,24 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
switch (qs) switch (qs)
{ {
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
res = TEH_RESPONSE_reply_arg_invalid (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN, MHD_HTTP_NOT_FOUND,
"rc"); TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
"rc");
break; break;
case GNUNET_DB_STATUS_HARD_ERROR: case GNUNET_DB_STATUS_HARD_ERROR:
res = TEH_RESPONSE_reply_internal_db_error (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR,
"failed to fetch session data");
break; break;
case GNUNET_DB_STATUS_SOFT_ERROR: case GNUNET_DB_STATUS_SOFT_ERROR:
default: default:
GNUNET_break (0); /* should be impossible */ GNUNET_break (0); /* should be impossible */
res = TEH_RESPONSE_reply_internal_db_error (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_INTERNAL_INVARIANT_FAILURE); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_INTERNAL_INVARIANT_FAILURE,
"assertion failed");
break; break;
} }
goto cleanup; goto cleanup;
@ -731,9 +751,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
eddsa_pub)) eddsa_pub))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
res = TEH_RESPONSE_reply_signature_invalid (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID, MHD_HTTP_FORBIDDEN,
"link_sig"); TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID,
"link_sig");
goto cleanup; goto cleanup;
} }
} }
@ -757,8 +778,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
if (NULL == rctx->ev_sigs[i].rsa_signature) if (NULL == rctx->ev_sigs[i].rsa_signature)
{ {
GNUNET_break (0); GNUNET_break (0);
res = TEH_RESPONSE_reply_internal_db_error (connection, res = TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_SIGNING_ERROR); MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_REVEAL_SIGNING_ERROR,
"internal signing error");
goto cleanup; goto cleanup;
} }
} }
@ -909,9 +932,10 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
{ {
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0); GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID, MHD_HTTP_BAD_REQUEST,
"transfer_privs"); TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_privs");
} }
res = handle_refresh_reveal_json (connection, res = handle_refresh_reveal_json (connection,
&rctx, &rctx,

View File

@ -27,6 +27,7 @@
#include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_responses.h"
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_keystate.h" #include "taler-exchange-httpd_keystate.h"
/** /**
@ -874,15 +875,16 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct MHD_Connection *connection,
history = TEH_RESPONSE_compile_transaction_history (tl); history = TEH_RESPONSE_compile_transaction_history (tl);
if (NULL == history) if (NULL == history)
return TEH_RESPONSE_reply_internal_error (connection, return TALER_MHD_reply_with_error (connection,
TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS, MHD_HTTP_INTERNAL_SERVER_ERROR,
"failed to convert transaction history to JSON"); TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
return TEH_RESPONSE_reply_json_pack (connection, "failed to convert transaction history to JSON");
MHD_HTTP_FORBIDDEN, return TALER_MHD_reply_json_pack (connection,
"{s:s, s:I, s:o}", MHD_HTTP_FORBIDDEN,
"error", "insufficient funds", "{s:s, s:I, s:o}",
"code", (json_int_t) ec, "error", "insufficient funds",
"history", history); "code", (json_int_t) ec,
"history", history);
} }

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014 GNUnet e.V. Copyright (C) 2014-2019 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU Affero General Public License as published by the Free Software
@ -13,7 +13,6 @@
You should have received a copy of the GNU Affero General Public License along with 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/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
/** /**
* @file taler-exchange-httpd_responses.h * @file taler-exchange-httpd_responses.h
* @brief API for generating generic replies of the exchange; these * @brief API for generating generic replies of the exchange; these
@ -34,216 +33,6 @@
#include "taler-exchange-httpd_db.h" #include "taler-exchange-httpd_db.h"
/**
* Add headers we want to return in every response.
* Useful for testing, like if we want to always close
* connections.
*
* @param response response to modify
*/
void
TEH_RESPONSE_add_global_headers (struct MHD_Response *response);
/**
* Try to compress a response body. Updates @a buf and @a buf_size.
*
* @param[in,out] buf pointer to body to compress
* @param[in,out] buf_size pointer to initial size of @a buf
* @return #MHD_YES if @a buf was compressed
*/
int
TEH_RESPONSE_body_compress (void **buf,
size_t *buf_size);
/**
* Is HTTP body deflate compression supported by the client?
*
* @param connection connection to check
* @return #MHD_YES if 'deflate' compression is allowed
*/
int
TEH_RESPONSE_can_compress (struct MHD_Connection *connection);
/**
* Send JSON object as response.
*
* @param connection the MHD connection
* @param json the json object
* @param response_code the http response code
* @return MHD result code
*/
int
TEH_RESPONSE_reply_json (struct MHD_Connection *connection,
const json_t *json,
unsigned int response_code);
/**
* Function to call to handle the request by building a JSON
* reply from a format string and varargs.
*
* @param connection the MHD connection to handle
* @param response_code HTTP response code to use
* @param fmt format string for pack
* @param ... varargs
* @return MHD result code
*/
int
TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
unsigned int response_code,
const char *fmt,
...);
/**
* Send a response indicating an invalid signature.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *param_name);
/**
* Send a response indicating an invalid argument.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return MHD result code
*/
int
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *param_name);
/**
* Send a response indicating an argument refering to a
* resource unknown to the exchange (i.e. unknown reserve or
* denomination key).
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *param_name);
/**
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param param_name the parameter that is missing
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *param_name);
/**
* Send a response indicating an internal error.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param hint hint about the internal error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *hint);
/**
* Send a response indicating an error.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param http_status HTTP status code to use
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_with_error (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
unsigned int http_status);
/**
* Send a response indicating an external error.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param hint hint about the error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
enum TALER_ErrorCode ec,
const char *hint);
/**
* Send a response indicating an error committing a
* transaction (concurrent interference).
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
enum TALER_ErrorCode ec);
/**
* Send a response indicating a failure to talk to the Exchange's
* database.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
enum TALER_ErrorCode ec);
/**
* Send a response indicating that the request was too big.
*
* @param connection the MHD connection to use
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
/**
* Send a response indicating that the JSON was malformed.
*
* @param connection the MHD connection to use
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connectionx);
/** /**
* Compile the history of a reserve into a JSON object * Compile the history of a reserve into a JSON object
* and calculate the total balance. * and calculate the total balance.
@ -276,20 +65,6 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct MHD_Connection *connection,
TALER_EXCHANGEDB_TransactionList *tl); TALER_EXCHANGEDB_TransactionList *tl);
/**
* A merchant asked for details about a deposit, but
* we do not know anything about the deposit. Generate the
* 404 reply.
*
* @param connection connection to the client
* @param ec Taler error code
* @return MHD result code
*/
int
TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
enum TALER_ErrorCode ec);
/** /**
* Compile the transaction history of a coin into a JSON object. * Compile the transaction history of a coin into a JSON object.
* *