implement #3972: support multiple wire formats concurrently
This commit is contained in:
parent
1eadd66ae0
commit
a6f8fa98b0
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file util/test_json_validations.c
|
||||
* @file util/test_wireformats.c
|
||||
* @brief Tests for JSON validations
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
*/
|
||||
@ -69,6 +69,14 @@ 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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user