addressing #4803: nicer error messages for invalid wire formats

This commit is contained in:
Christian Grothoff 2016-11-18 18:29:18 +01:00
parent de68a7b301
commit 7d6b8d53d5
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
14 changed files with 259 additions and 116 deletions

View File

@ -95,7 +95,8 @@ verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
const struct TALER_EXCHANGE_Keys *key_state; const struct TALER_EXCHANGE_Keys *key_state;
struct TALER_WIRE_Plugin *plugin; struct TALER_WIRE_Plugin *plugin;
char *lib_name; char *lib_name;
int ret; char *emsg;
enum TALER_ErrorCode ec;
key_state = TALER_EXCHANGE_get_keys (wh->exchange); key_state = TALER_EXCHANGE_get_keys (wh->exchange);
(void) GNUNET_asprintf (&lib_name, (void) GNUNET_asprintf (&lib_name,
@ -112,13 +113,15 @@ verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
return GNUNET_NO; return GNUNET_NO;
} }
plugin->library_name = lib_name; plugin->library_name = lib_name;
ret = plugin->wire_validate (plugin->cls, ec = plugin->wire_validate (plugin->cls,
json, json,
&key_state->master_pub); &key_state->master_pub,
&emsg);
GNUNET_free_non_null (emsg);
GNUNET_PLUGIN_unload (lib_name, GNUNET_PLUGIN_unload (lib_name,
plugin); plugin);
GNUNET_free (lib_name); GNUNET_free (lib_name);
return (GNUNET_YES == ret) ? GNUNET_OK : GNUNET_SYSERR; return (TALER_EC_NONE == ec) ? GNUNET_OK : GNUNET_SYSERR;
} }

View File

@ -1596,6 +1596,7 @@ deposit_wtid_cb (void *cls,
} }
break; break;
default: default:
GNUNET_break (0);
break; break;
} }
next_command (is); next_command (is);
@ -2427,6 +2428,10 @@ do_shutdown (void *cls)
struct Command *cmd; struct Command *cmd;
unsigned int i; unsigned int i;
fprintf (stderr,
"Executing shutdown at `%s'\n",
is->commands[is->ip].label);
for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++) for (i=0;OC_END != (cmd = &is->commands[i])->oc;i++)
{ {
switch (cmd->oc) switch (cmd->oc)
@ -3084,6 +3089,9 @@ main (int argc,
/* These might get in the way... */ /* These might get in the way... */
unsetenv ("XDG_DATA_HOME"); unsetenv ("XDG_DATA_HOME");
unsetenv ("XDG_CONFIG_HOME"); unsetenv ("XDG_CONFIG_HOME");
GNUNET_log_setup ("test-exchange-api",
"INFO",
NULL);
proc = GNUNET_OS_start_process (GNUNET_NO, proc = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL, GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL, NULL, NULL, NULL,
@ -3145,6 +3153,7 @@ main (int argc,
result = GNUNET_SYSERR; result = GNUNET_SYSERR;
sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
GNUNET_assert (NULL != sigpipe); GNUNET_assert (NULL != sigpipe);
sleep (30);
shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
&sighandler_child_death); &sighandler_child_death);
GNUNET_SCHEDULER_run (&run, NULL); GNUNET_SCHEDULER_run (&run, NULL);

View File

@ -50,6 +50,8 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub;
struct TALER_Amount amount; struct TALER_Amount amount;
struct GNUNET_TIME_Absolute at; struct GNUNET_TIME_Absolute at;
enum TALER_ErrorCode ec;
char *emsg;
json_t *sender_account_details; json_t *sender_account_details;
json_t *transfer_details; json_t *transfer_details;
json_t *root; json_t *root;
@ -82,15 +84,17 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
json_decref (root); json_decref (root);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
if (GNUNET_YES != if (TALER_EC_NONE !=
TEH_json_validate_wireformat (sender_account_details, (ec = TEH_json_validate_wireformat (sender_account_details,
GNUNET_NO)) GNUNET_NO,
&emsg)))
{ {
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection, res = TEH_RESPONSE_reply_external_error (connection,
TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED, ec,
"sender_account_details"); emsg);
GNUNET_free (emsg);
return res;
} }
if (0 != strcasecmp (amount.currency, if (0 != strcasecmp (amount.currency,
TEH_exchange_currency_string)) TEH_exchange_currency_string))

View File

@ -106,6 +106,8 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
json_t *json; json_t *json;
int res; int res;
json_t *wire; json_t *wire;
char *emsg;
enum TALER_ErrorCode ec;
struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_Deposit deposit;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct TEH_KS_StateHandle *key_state; struct TEH_KS_StateHandle *key_state;
@ -156,14 +158,17 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
"refund_deadline"); "refund_deadline");
} }
if (GNUNET_YES != if (TALER_EC_NONE !=
TEH_json_validate_wireformat (wire, (ec = TEH_json_validate_wireformat (wire,
GNUNET_NO)) GNUNET_NO,
&emsg)))
{ {
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection, res = TEH_RESPONSE_reply_external_error (connection,
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT, ec,
"wire"); emsg);
GNUNET_free (emsg);
return res;
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_JSON_hash (wire, TALER_JSON_hash (wire,
@ -223,7 +228,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
"deposited amount smaller than depositing fee"); "deposited amount smaller than depositing fee");
} }
res = verify_and_execute_deposit (connection, res = verify_and_execute_deposit (connection,
&deposit); &deposit);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);

View File

@ -144,23 +144,27 @@ TEH_VALIDATION_done ()
* *
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param ours #GNUNET_YES if the signature should match our master key * @param ours #GNUNET_YES if the signature should match our master key
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to error message if we return an error code
* @return #TALER_EC_NONE if correctly formatted; otherwise error code
*/ */
int enum TALER_ErrorCode
TEH_json_validate_wireformat (const json_t *wire, TEH_json_validate_wireformat (const json_t *wire,
int ours) int ours,
char **emsg)
{ {
const char *stype; const char *stype;
json_error_t error; json_error_t error;
struct Plugin *p; struct Plugin *p;
*emsg = NULL;
if (0 != json_unpack_ex ((json_t *) wire, if (0 != json_unpack_ex ((json_t *) wire,
&error, 0, &error, 0,
"{s:s}", "{s:s}",
"type", &stype)) "type", &stype))
{ {
GNUNET_break (0); GNUNET_asprintf (emsg,
return GNUNET_SYSERR; "No `type' specified in the wire details\n");
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_MISSING;
} }
for (p=wire_head; NULL != p; p = p->next) for (p=wire_head; NULL != p; p = p->next)
if (0 == strcasecmp (p->type, if (0 == strcasecmp (p->type,
@ -169,8 +173,12 @@ TEH_json_validate_wireformat (const json_t *wire,
wire, wire,
(GNUNET_YES == ours) (GNUNET_YES == ours)
? &TEH_master_public_key ? &TEH_master_public_key
: NULL); : NULL,
return GNUNET_NO; emsg);
GNUNET_asprintf (emsg,
"Wire format type `%s' is not supported by this exchange\n",
stype);
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_UNSUPPORTED;
} }
@ -190,6 +198,8 @@ TEH_VALIDATION_get_wire_methods (const char *prefix)
struct Plugin *p; struct Plugin *p;
struct TALER_WIRE_Plugin *plugin; struct TALER_WIRE_Plugin *plugin;
char *account_name; char *account_name;
char *emsg;
enum TALER_ErrorCode ec;
methods = json_object (); methods = json_object ();
for (p=wire_head;NULL != p;p = p->next) for (p=wire_head;NULL != p;p = p->next)
@ -202,13 +212,17 @@ TEH_VALIDATION_get_wire_methods (const char *prefix)
method = plugin->get_wire_details (plugin->cls, method = plugin->get_wire_details (plugin->cls,
cfg, cfg,
account_name); account_name);
if (GNUNET_YES != if (TALER_EC_NONE !=
TEH_json_validate_wireformat (method, (ec = TEH_json_validate_wireformat (method,
GNUNET_YES)) GNUNET_YES,
&emsg)))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Account details for method `%s' ill-formed. Disabling method\n", "Disabling method `%s' as details are ill-formed: %s (%d)\n",
p->type); p->type,
emsg,
ec);
GNUNET_free (emsg);
json_decref (method); json_decref (method);
method = NULL; method = NULL;
} }

View File

@ -48,11 +48,13 @@ TEH_VALIDATION_done (void);
* *
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param ours #GNUNET_YES if the signature should match our master key * @param ours #GNUNET_YES if the signature should match our master key
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to error message if we return an error code
* @return #TALER_EC_NONE if correctly formatted; otherwise error code
*/ */
int enum TALER_ErrorCode
TEH_json_validate_wireformat (const json_t *wire, TEH_json_validate_wireformat (const json_t *wire,
int ours); int ours,
char **emsg);
/** /**

View File

@ -48,6 +48,10 @@ enum TALER_ErrorCode
*/ */
TALER_EC_INVALID_RESPONSE = 2, TALER_EC_INVALID_RESPONSE = 2,
/**
* Generic implementation error: this function was not yet implemented.
*/
TALER_EC_NOT_IMPLEMENTED = 3,
/* ********** generic error codes ************* */ /* ********** generic error codes ************* */
@ -324,10 +328,11 @@ enum TALER_ErrorCode
/** /**
* The exchange does not recognize the validity of or support the * The exchange does not recognize the validity of or support the
* given wire (bank account) address. This response is provided * given wire format type.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST. * with HTTP status code MHD_HTTP_BAD_REQUEST.
*/ */
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT = 1209, TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE = 1209,
/** /**
* The exchange failed to canonicalize and hash the given wire format. * The exchange failed to canonicalize and hash the given wire format.
@ -353,6 +358,46 @@ enum TALER_ErrorCode
*/ */
TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212, TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212,
/**
* The exchange detected that the given account number
* is invalid for the selected wire format type.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST.
*/
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_ACCOUNT_NUMBER = 1213,
/**
* The signature over the given wire details is invalid.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST.
*/
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE = 1214,
/**
* The bank specified in the wire transfer format is not supported
* by this exchange.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST.
*/
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_BANK = 1215,
/**
* No wire format type was specified in the JSON wire format
* details.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST.
*/
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_MISSING = 1216,
/**
* The given wire format type is not supported by this
* exchange.
* This response is provided
* with HTTP status code MHD_HTTP_BAD_REQUEST.
*/
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_UNSUPPORTED = 1217,
/** /**
* The respective coin did not have sufficient residual value * The respective coin did not have sufficient residual value
* for the /refresh/melt operation. The "history" in this * for the /refresh/melt operation. The "history" in this

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 "taler_util.h" #include "taler_util.h"
#include "taler_error_codes.h"
/** /**
@ -137,12 +138,15 @@ struct TALER_WIRE_Plugin
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against * @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to an error message, unless we return #TALER_EC_NONE;
* error message must be freed by the caller using GNUNET_free()
* @return #TALER_EC_NONE if correctly formatted
*/ */
int enum TALER_ErrorCode
(*wire_validate) (void *cls, (*wire_validate) (void *cls,
const json_t *wire, const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub); const struct TALER_MasterPublicKeyP *master_pub,
char **emsg);
/** /**

View File

@ -9,7 +9,6 @@ endif
pkgcfgdir = $(prefix)/share/taler/config.d/ pkgcfgdir = $(prefix)/share/taler/config.d/
pkgcfg_DATA = \ pkgcfg_DATA = \
paths.conf paths.conf

View File

@ -451,12 +451,15 @@ verify_wire_sepa_signature_ok (const json_t *json,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against * @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to an error message, unless we return #TALER_EC_NONE;
* error message must be freed by the caller using GNUNET_free()
* @return #TALER_EC_NONE if correctly formatted
*/ */
static int static enum TALER_ErrorCode
sepa_wire_validate (void *cls, sepa_wire_validate (void *cls,
const json_t *wire, const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub) const struct TALER_MasterPublicKeyP *master_pub,
char **emsg)
{ {
json_error_t error; json_error_t error;
const char *type; const char *type;
@ -464,6 +467,7 @@ sepa_wire_validate (void *cls,
const char *name; const char *name;
const char *bic; const char *bic;
*emsg = NULL;
if (0 != json_unpack_ex if (0 != json_unpack_ex
((json_t *) wire, ((json_t *) wire,
&error, 0, &error, 0,
@ -478,39 +482,44 @@ sepa_wire_validate (void *cls,
"name", &name, "name", &name,
"bic", &bic)) "bic", &bic))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, char *dump;
"JSON parsing failed at %s:%u: %s (%s)\n",
__FILE__, __LINE__, dump = json_dumps (wire, 0);
error.text, error.source); GNUNET_asprintf (emsg,
json_dumpf (wire, stderr, 0); "JSON parsing failed at %s:%u: %s (%s): %s\n",
fprintf (stderr, "\n"); __FILE__, __LINE__,
return GNUNET_SYSERR; error.text,
error.source,
dump);
free (dump);
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON;
} }
if (0 != strcasecmp (type, if (0 != strcasecmp (type,
"sepa")) "sepa"))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_asprintf (emsg,
"Transfer type `%s' invalid\n", "Transfer type `%s' invalid for SEPA wire plugin\n",
type); type);
return GNUNET_SYSERR; return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE;
} }
if (1 != validate_iban (iban)) if (1 != validate_iban (iban))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_asprintf (emsg,
"IBAN `%s' invalid\n", "IBAN `%s' invalid\n",
iban); iban);
return GNUNET_NO; return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_ACCOUNT_NUMBER;
} }
/* FIXME: don't parse again, integrate properly... */ /* FIXME: don't parse again, integrate properly... */
if (GNUNET_OK != if (GNUNET_OK !=
verify_wire_sepa_signature_ok (wire, verify_wire_sepa_signature_ok (wire,
master_pub)) master_pub))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_asprintf (emsg,
"Signature invalid\n"); "Signature using public key `%s' invalid\n",
return GNUNET_NO; TALER_B2S (master_pub));
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE;
} }
return GNUNET_YES; return TALER_EC_NONE;
} }
@ -531,6 +540,7 @@ sepa_get_wire_details (void *cls,
char *sepa_wire_file; char *sepa_wire_file;
json_error_t err; json_error_t err;
json_t *ret; json_t *ret;
char *emsg;
/* Fetch reply */ /* Fetch reply */
if (GNUNET_OK != if (GNUNET_OK !=
@ -558,13 +568,17 @@ sepa_get_wire_details (void *cls,
GNUNET_free (sepa_wire_file); GNUNET_free (sepa_wire_file);
return NULL; return NULL;
} }
if (GNUNET_YES != sepa_wire_validate (cls, if (TALER_EC_NONE !=
ret, sepa_wire_validate (cls,
NULL)) ret,
{ NULL,
&emsg))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to validate SEPA data in %s\n", "Failed to validate SEPA data in %s: %s\n",
sepa_wire_file); sepa_wire_file,
emsg);
GNUNET_free (emsg);
GNUNET_free (sepa_wire_file); GNUNET_free (sepa_wire_file);
json_decref (ret); json_decref (ret);
return NULL; return NULL;

View File

@ -98,15 +98,19 @@ template_get_wire_details (void *cls,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against * @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to an error message, unless we return #TALER_EC_NONE;
* error message must be freed by the caller using GNUNET_free()
* @return #TALER_EC_NONE if correctly formatted
*/ */
static int static enum TALER_ErrorCode
template_wire_validate (void *cls, template_wire_validate (void *cls,
const json_t *wire, const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub) const struct TALER_MasterPublicKeyP *master_pub,
char **emsg)
{ {
GNUNET_break (0); GNUNET_asprintf (emsg,
return GNUNET_SYSERR; "Not implemented");
return TALER_EC_NOT_IMPLEMENTED;
} }

View File

@ -213,12 +213,15 @@ compute_purpose (uint64_t account,
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object * @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against * @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not * @param[OUT] emsg set to an error message, unless we return #TALER_EC_NONE;
* error message must be freed by the caller using GNUNET_free()
* @return #TALER_EC_NONE if correctly formatted
*/ */
static int static enum TALER_ErrorCode
test_wire_validate (void *cls, test_wire_validate (void *cls,
const json_t *wire, const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub) const struct TALER_MasterPublicKeyP *master_pub,
char **emsg)
{ {
struct TestClosure *tc = cls; struct TestClosure *tc = cls;
json_error_t error; json_error_t error;
@ -228,6 +231,7 @@ test_wire_validate (void *cls,
struct TALER_MasterWireDetailsPS wsd; struct TALER_MasterWireDetailsPS wsd;
struct TALER_MasterSignatureP sig; struct TALER_MasterSignatureP sig;
*emsg = NULL;
if (0 != if (0 !=
json_unpack_ex ((json_t *) wire, json_unpack_ex ((json_t *) wire,
&error, &error,
@ -236,30 +240,41 @@ test_wire_validate (void *cls,
"account_number", &account_no, "account_number", &account_no,
"bank_uri", &bank_uri)) "bank_uri", &bank_uri))
{ {
GNUNET_break_op (0); char *dump;
return GNUNET_SYSERR;
dump = json_dumps (wire, 0);
GNUNET_asprintf (emsg,
"JSON parsing failed at %s:%u: %s (%s): %s\n",
__FILE__, __LINE__,
error.text,
error.source,
dump);
free (dump);
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON;
} }
if ( (account_no < 0) || if ( (account_no < 0) ||
(account_no > (1LL << 53)) ) (account_no > (1LL << 53)) )
{ {
GNUNET_break (0); GNUNET_asprintf (emsg,
return GNUNET_SYSERR; "Account number %llu outside of permitted range\n",
account_no);
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_ACCOUNT_NUMBER;
} }
if ( (NULL != tc->bank_uri) && if ( (NULL != tc->bank_uri) &&
(0 != strcmp (bank_uri, (0 != strcmp (bank_uri,
tc->bank_uri)) ) tc->bank_uri)) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_asprintf (emsg,
"Wire specifies bank URI %s, but this exchange only supports %s\n", "Wire specifies bank URI `%s', but this exchange only supports `%s'\n",
bank_uri, bank_uri,
tc->bank_uri); tc->bank_uri);
return GNUNET_NO; return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_BANK;
} }
if (NULL == master_pub) if (NULL == master_pub)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Skipping signature check as master public key not given\n"); "Skipping signature check as master public key not given\n");
return GNUNET_OK; return TALER_EC_NONE;
} }
if (0 != if (0 !=
json_unpack_ex ((json_t *) wire, json_unpack_ex ((json_t *) wire,
@ -268,9 +283,9 @@ test_wire_validate (void *cls,
"{s:s}", "{s:s}",
"sig", &sig_s)) "sig", &sig_s))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_asprintf (emsg,
"Signature check required, but signature is missing\n"); "Signature check required, but signature is missing\n");
return GNUNET_NO; return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE;
} }
compute_purpose (account_no, compute_purpose (account_no,
bank_uri, bank_uri,
@ -290,10 +305,12 @@ test_wire_validate (void *cls,
&sig.eddsa_signature, &sig.eddsa_signature,
&master_pub->eddsa_pub)) &master_pub->eddsa_pub))
{ {
GNUNET_break (0); GNUNET_asprintf (emsg,
return GNUNET_SYSERR; "Signature using public key `%s' invalid\n",
TALER_B2S (master_pub));
return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE;
} }
return GNUNET_YES; return TALER_EC_NONE;
} }
@ -315,6 +332,7 @@ test_get_wire_details (void *cls,
char *test_wire_file; char *test_wire_file;
json_error_t err; json_error_t err;
json_t *ret; json_t *ret;
char *emsg;
/* Fetch reply */ /* Fetch reply */
if (GNUNET_OK != if (GNUNET_OK !=
@ -342,13 +360,17 @@ test_get_wire_details (void *cls,
GNUNET_free (test_wire_file); GNUNET_free (test_wire_file);
return NULL; return NULL;
} }
if (GNUNET_YES != test_wire_validate (tc, if (TALER_EC_NONE !=
ret, test_wire_validate (tc,
NULL)) ret,
NULL,
&emsg))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to validate TEST wire data in %s\n", "Failed to validate TEST wire data in %s: %s\n",
test_wire_file); test_wire_file,
emsg);
GNUNET_free (emsg);
GNUNET_free (test_wire_file); GNUNET_free (test_wire_file);
json_decref (ret); json_decref (ret);
return NULL; return NULL;
@ -478,13 +500,16 @@ test_prepare_wire_transfer (void *cls,
{ {
struct TestClosure *tc = cls; struct TestClosure *tc = cls;
struct TALER_WIRE_PrepareHandle *pth; struct TALER_WIRE_PrepareHandle *pth;
char *emsg;
if (GNUNET_YES != if (TALER_EC_NONE !=
test_wire_validate (tc, test_wire_validate (tc,
wire, wire,
NULL)) NULL,
&emsg))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_free (emsg);
return NULL; return NULL;
} }
pth = GNUNET_new (struct TALER_WIRE_PrepareHandle); pth = GNUNET_new (struct TALER_WIRE_PrepareHandle);
@ -624,6 +649,7 @@ test_execute_wire_transfer (void *cls,
struct TALER_Amount amount; struct TALER_Amount amount;
json_int_t account_no; json_int_t account_no;
struct BufFormatP bf; struct BufFormatP bf;
char *emsg;
if (NULL == tc->ctx) if (NULL == tc->ctx)
{ {
@ -650,10 +676,11 @@ test_execute_wire_transfer (void *cls,
GNUNET_break (0); GNUNET_break (0);
return NULL; return NULL;
} }
GNUNET_assert (GNUNET_YES == GNUNET_assert (TALER_EC_NONE ==
test_wire_validate (tc, test_wire_validate (tc,
wire, wire,
NULL)); NULL,
&emsg));
if (0 != if (0 !=
json_unpack_ex (wire, json_unpack_ex (wire,
&error, &error,

View File

@ -67,6 +67,7 @@ main(int argc,
const char *const argv[]) const char *const argv[])
{ {
json_t *wire; json_t *wire;
char *emsg;
json_error_t error; json_error_t error;
int ret; int ret;
struct GNUNET_CONFIGURATION_Handle *cfg; struct GNUNET_CONFIGURATION_Handle *cfg;
@ -85,28 +86,35 @@ main(int argc,
GNUNET_assert (NULL != plugin); GNUNET_assert (NULL != plugin);
(void) memset(&error, 0, sizeof(error)); (void) memset(&error, 0, sizeof(error));
GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL))); GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL)));
GNUNET_assert (GNUNET_YES != plugin->wire_validate (NULL, GNUNET_assert (TALER_EC_NONE != plugin->wire_validate (NULL,
wire, wire,
NULL)); NULL,
&emsg));
GNUNET_free (emsg);
json_decref (wire); json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL))); GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL)));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL, GNUNET_assert (TALER_EC_NONE != plugin->wire_validate (NULL,
wire, wire,
NULL)); NULL,
&emsg));
GNUNET_free (emsg);
json_decref (wire); json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL))); GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL)));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL, GNUNET_assert (TALER_EC_NONE != plugin->wire_validate (NULL,
wire, wire,
NULL)); NULL,
&emsg));
GNUNET_free (emsg);
json_decref (wire); json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error))); GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error)));
ret = plugin->wire_validate (NULL, ret = plugin->wire_validate (NULL,
wire, wire,
NULL); NULL,
&emsg);
json_decref (wire); json_decref (wire);
TALER_WIRE_plugin_unload (plugin); TALER_WIRE_plugin_unload (plugin);
GNUNET_CONFIGURATION_destroy (cfg); GNUNET_CONFIGURATION_destroy (cfg);
if (GNUNET_NO == ret) if (TALER_EC_NONE != ret)
return 1; return 1;
return 0; return 0;
} }

View File

@ -112,6 +112,7 @@ run_test (const struct TestBlock *test,
json_t *lwire; json_t *lwire;
struct TALER_Amount in; struct TALER_Amount in;
struct TALER_Amount expect; struct TALER_Amount expect;
char *emsg;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
&salt, &salt,
@ -134,12 +135,14 @@ run_test (const struct TestBlock *test,
"sig", "sig",
GNUNET_JSON_from_data (&sig, GNUNET_JSON_from_data (&sig,
sizeof (sig))); sizeof (sig)));
if (GNUNET_OK != if (TALER_EC_NONE !=
plugin->wire_validate (plugin->cls, plugin->wire_validate (plugin->cls,
wire, wire,
&pub_key)) &pub_key,
&emsg))
{ {
GNUNET_break (0); GNUNET_break (0);
GNUNET_free (emsg);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* load wire details from file */ /* load wire details from file */
@ -151,12 +154,14 @@ run_test (const struct TestBlock *test,
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_OK != if (TALER_EC_NONE !=
plugin->wire_validate (plugin->cls, plugin->wire_validate (plugin->cls,
lwire, lwire,
&pub_key)) &pub_key,
&emsg))
{ {
GNUNET_break (0); GNUNET_break (0);
GNUNET_free (emsg);
json_decref (lwire); json_decref (lwire);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }