implement #3972: support multiple wire formats concurrently

This commit is contained in:
Christian Grothoff 2015-09-20 13:48:15 +02:00
parent 1eadd66ae0
commit a6f8fa98b0
10 changed files with 93 additions and 41 deletions

1
.gitignore vendored
View File

@ -30,6 +30,7 @@ GTAGS
src/lib/test_mint_api
doc/doxygen/doxygen_sqlite3.db
src/mint-lib/test_mint_api
src/mint-tools/taler-auditor-sign
src/mint-tools/taler-mint-dbinit
src/mint-tools/taler-mint-keycheck
src/mint-tools/taler-mint-keyup

View File

@ -167,12 +167,12 @@ TALER_hash_json (json_t *json,
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param type the type of the wire format
* @param allowed NULL-terminated array of allowed wire format types
* @param wire the JSON wire format object
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int
TALER_json_validate_wireformat (const char *type,
TALER_json_validate_wireformat (const char **allowed,
const json_t *wire);

View File

@ -1992,13 +1992,13 @@ run (void *cls,
#if WIRE_TEST
{ .oc = OC_WIRE,
.label = "wire",
.label = "wire-test",
/* /wire/test replies with a 302 redirect */
.expected_response_code = MHD_HTTP_FOUND },
#endif
#if WIRE_SEPA
{ .oc = OC_WIRE,
.label = "wire",
.label = "wire-sepa",
/* /wire/sepa replies with a 200 redirect */
.expected_response_code = MHD_HTTP_OK },
#endif

View File

@ -62,8 +62,10 @@ struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;
/**
* In which format does this MINT expect wiring instructions?
* NULL-terminated array of 0-terminated wire format types,
* suitable for passing to #TALER_json_validate_wireformat().
*/
char *TMH_expected_wire_format;
const char **TMH_expected_wire_formats;
/**
* Our DB plugin.
@ -363,6 +365,9 @@ mint_serve_process_config (const char *mint_directory)
{
unsigned long long port;
char *TMH_master_public_key_str;
char *wireformats;
const char *token;
unsigned int len;
cfg = TALER_config_load (mint_directory);
if (NULL == cfg)
@ -390,17 +395,36 @@ mint_serve_process_config (const char *mint_directory)
(unsigned int) TALER_CURRENCY_LEN);
return GNUNET_SYSERR;
}
/* Find out list of supported wire formats */
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"mint",
"wireformat",
&TMH_expected_wire_format))
&wireformats))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"mint",
"wireformat");
return GNUNET_SYSERR;
}
/* build NULL-terminated array of TMH_expected_wire_formats */
TMH_expected_wire_formats = GNUNET_new_array (1,
const char *);
len = 1;
for (token = strtok (wireformats,
" ");
NULL != token;
token = strtok (NULL,
" "))
{
/* Grow by 1, appending NULL-terminator */
GNUNET_array_append (TMH_expected_wire_formats,
len,
NULL);
TMH_expected_wire_formats[len - 2] = GNUNET_strdup (token);
}
GNUNET_free (wireformats);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"mint",

View File

@ -48,9 +48,11 @@ extern int TMH_test_mode;
extern char *TMH_mint_directory;
/**
* In which format does this MINT expect wiring instructions?
* In which formats does this MINT expect wiring instructions?
* NULL-terminated array of 0-terminated wire format types,
* suitable for passing to #TALER_json_validate_wireformat().
*/
extern char *TMH_expected_wire_format;
extern const char **TMH_expected_wire_formats;
/**
* Master public key (according to the

View File

@ -142,7 +142,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
if (GNUNET_YES !=
TALER_json_validate_wireformat (TMH_expected_wire_format,
TALER_json_validate_wireformat (TMH_expected_wire_formats,
wire))
{
TMH_PARSE_release_data (spec);

View File

@ -160,7 +160,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
return MHD_YES; /* failure */
if (GNUNET_YES !=
TALER_json_validate_wireformat (TMH_expected_wire_format,
TALER_json_validate_wireformat (TMH_expected_wire_formats,
wire))
{
TMH_PARSE_release_data (spec);

View File

@ -45,23 +45,32 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh,
struct TALER_MintPublicKeyP pub;
struct TALER_MintSignatureP sig;
json_t *methods;
struct GNUNET_HashContext *hc;
unsigned int i;
const char *wf;
methods = json_array ();
hc = GNUNET_CRYPTO_hash_context_start ();
for (i=0;NULL != (wf = TMH_expected_wire_formats[i]); i++)
{
json_array_append_new (methods,
json_string (wf));
GNUNET_CRYPTO_hash_context_read (hc,
wf,
strlen (wf) + 1);
}
wsm.purpose.size = htonl (sizeof (wsm));
wsm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_WIRE_TYPES);
GNUNET_CRYPTO_hash (TMH_expected_wire_format,
strlen (TMH_expected_wire_format) + 1,
&wsm.h_wire_types);
GNUNET_CRYPTO_hash_context_finish (hc,
&wsm.h_wire_types);
TMH_KS_sign (&wsm.purpose,
&pub,
&sig);
methods = json_array ();
/* NOTE: for now, we only support *ONE* wire format per
mint instance; if we supply multiple, we need to
add the strings for each type separately here -- and
hash the 0-terminated strings above differently as well...
See #3972. */
json_array_append_new (methods,
json_string (TMH_expected_wire_format));
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o, s:o}",
@ -93,6 +102,7 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,
struct MHD_Response *response;
int ret;
char *wire_test_redirect;
unsigned int i;
response = MHD_create_response_from_buffer (0, NULL,
MHD_RESPMEM_PERSISTENT);
@ -101,8 +111,11 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,
GNUNET_break (0);
return MHD_NO;
}
if (0 != strcasecmp ("test",
TMH_expected_wire_format))
for (i=0;NULL != TMH_expected_wire_formats[i];i++)
if (0 == strcasecmp ("test",
TMH_expected_wire_formats[i]))
break;
if (NULL == TMH_expected_wire_formats[i])
{
/* Return 501: not implemented */
ret = MHD_queue_response (connection,
@ -155,9 +168,13 @@ TMH_WIRE_handler_wire_sepa (struct TMH_RequestHandler *rh,
char *sepa_wire_file;
int fd;
struct stat sbuf;
unsigned int i;
if (0 != strcasecmp ("sepa",
TMH_expected_wire_format))
for (i=0;NULL != TMH_expected_wire_formats[i];i++)
if (0 == strcasecmp ("sepa",
TMH_expected_wire_formats[i]))
break;
if (NULL == TMH_expected_wire_formats[i])
{
/* Return 501: not implemented */
response = MHD_create_response_from_buffer (0, NULL,

View File

@ -15,9 +15,9 @@
*/
/**
* @file util/test_json_validations.c
* @file util/test_wireformats.c
* @brief Tests for JSON validations
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
#include "platform.h"
@ -65,10 +65,18 @@ static const char * const unsupported_wire_str =
\"address\": \"foobar\"}";
int
main(int argc,
int
main(int argc,
const char *const argv[])
{
const char *unsupported[] = {
"unsupported",
NULL
};
const char *sepa[] = {
"SEPA",
NULL
};
json_t *wire;
json_error_t error;
int ret;
@ -76,16 +84,16 @@ main(int argc,
GNUNET_log_setup ("test-json-validations", "WARNING", NULL);
(void) memset(&error, 0, sizeof(error));
GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL)));
GNUNET_assert (1 != TALER_json_validate_wireformat ("unsupported", wire));
GNUNET_assert (1 != TALER_json_validate_wireformat (unsupported, wire));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL)));
GNUNET_assert (1 != TALER_json_validate_wireformat ("SEPA", wire));
GNUNET_assert (1 != TALER_json_validate_wireformat (sepa, wire));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL)));
GNUNET_assert (1 != TALER_json_validate_wireformat ("SEPA", wire));
GNUNET_assert (1 != TALER_json_validate_wireformat (sepa, wire));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error)));
ret = TALER_json_validate_wireformat ("SEPA", wire);
ret = TALER_json_validate_wireformat (sepa, wire);
json_decref (wire);
if (1 == ret)
return 0;

View File

@ -395,12 +395,12 @@ struct FormatHandler
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param type the expected type of the wire format
* @param allowed NULL-terminated array of allowed wire format types
* @param wire the JSON wire format object
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int
TALER_json_validate_wireformat (const char *type,
TALER_json_validate_wireformat (const char **allowed,
const json_t *wire)
{
static const struct FormatHandler format_handlers[] = {
@ -409,33 +409,33 @@ TALER_json_validate_wireformat (const char *type,
{ NULL, NULL}
};
unsigned int i;
char *stype;
const char *stype;
json_error_t error;
UNPACK_EXITIF (0 != json_unpack_ex
((json_t *) wire,
&error, 0,
"{"
"s:s " /* TYPE: type */
"}",
"{s:s}",
"type", &stype));
if (0 != strcasecmp (type,
stype))
for (i=0;NULL != allowed[i];i++)
if (0 == strcasecmp (allowed[i],
stype))
break;
if (NULL == allowed[i])
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' does not match mint's expected `%s' format\n",
stype,
type);
"Wireformat `%s' does not match mint's allowed formats\n",
stype);
return GNUNET_NO;
}
for (i=0;NULL != format_handlers[i].type;i++)
if (0 == strcasecmp (format_handlers[i].type,
type))
stype))
return format_handlers[i].handler (wire);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' not supported\n",
type);
stype);
return GNUNET_NO;
EXITIF_exit:
return GNUNET_NO;