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
|
src/lib/test_mint_api
|
||||||
doc/doxygen/doxygen_sqlite3.db
|
doc/doxygen/doxygen_sqlite3.db
|
||||||
src/mint-lib/test_mint_api
|
src/mint-lib/test_mint_api
|
||||||
|
src/mint-tools/taler-auditor-sign
|
||||||
src/mint-tools/taler-mint-dbinit
|
src/mint-tools/taler-mint-dbinit
|
||||||
src/mint-tools/taler-mint-keycheck
|
src/mint-tools/taler-mint-keycheck
|
||||||
src/mint-tools/taler-mint-keyup
|
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
|
* 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
|
* @param wire the JSON wire format object
|
||||||
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_json_validate_wireformat (const char *type,
|
TALER_json_validate_wireformat (const char **allowed,
|
||||||
const json_t *wire);
|
const json_t *wire);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1992,13 +1992,13 @@ run (void *cls,
|
|||||||
|
|
||||||
#if WIRE_TEST
|
#if WIRE_TEST
|
||||||
{ .oc = OC_WIRE,
|
{ .oc = OC_WIRE,
|
||||||
.label = "wire",
|
.label = "wire-test",
|
||||||
/* /wire/test replies with a 302 redirect */
|
/* /wire/test replies with a 302 redirect */
|
||||||
.expected_response_code = MHD_HTTP_FOUND },
|
.expected_response_code = MHD_HTTP_FOUND },
|
||||||
#endif
|
#endif
|
||||||
#if WIRE_SEPA
|
#if WIRE_SEPA
|
||||||
{ .oc = OC_WIRE,
|
{ .oc = OC_WIRE,
|
||||||
.label = "wire",
|
.label = "wire-sepa",
|
||||||
/* /wire/sepa replies with a 200 redirect */
|
/* /wire/sepa replies with a 200 redirect */
|
||||||
.expected_response_code = MHD_HTTP_OK },
|
.expected_response_code = MHD_HTTP_OK },
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,8 +62,10 @@ struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* In which format does this MINT expect wiring instructions?
|
* 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.
|
* Our DB plugin.
|
||||||
@ -363,6 +365,9 @@ mint_serve_process_config (const char *mint_directory)
|
|||||||
{
|
{
|
||||||
unsigned long long port;
|
unsigned long long port;
|
||||||
char *TMH_master_public_key_str;
|
char *TMH_master_public_key_str;
|
||||||
|
char *wireformats;
|
||||||
|
const char *token;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
cfg = TALER_config_load (mint_directory);
|
cfg = TALER_config_load (mint_directory);
|
||||||
if (NULL == cfg)
|
if (NULL == cfg)
|
||||||
@ -390,17 +395,36 @@ mint_serve_process_config (const char *mint_directory)
|
|||||||
(unsigned int) TALER_CURRENCY_LEN);
|
(unsigned int) TALER_CURRENCY_LEN);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
/* Find out list of supported wire formats */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
"mint",
|
"mint",
|
||||||
"wireformat",
|
"wireformat",
|
||||||
&TMH_expected_wire_format))
|
&wireformats))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"mint",
|
"mint",
|
||||||
"wireformat");
|
"wireformat");
|
||||||
return GNUNET_SYSERR;
|
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 !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
"mint",
|
"mint",
|
||||||
|
@ -48,9 +48,11 @@ extern int TMH_test_mode;
|
|||||||
extern char *TMH_mint_directory;
|
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
|
* 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;
|
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||||
}
|
}
|
||||||
if (GNUNET_YES !=
|
if (GNUNET_YES !=
|
||||||
TALER_json_validate_wireformat (TMH_expected_wire_format,
|
TALER_json_validate_wireformat (TMH_expected_wire_formats,
|
||||||
wire))
|
wire))
|
||||||
{
|
{
|
||||||
TMH_PARSE_release_data (spec);
|
TMH_PARSE_release_data (spec);
|
||||||
|
@ -160,7 +160,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
|||||||
return MHD_YES; /* failure */
|
return MHD_YES; /* failure */
|
||||||
|
|
||||||
if (GNUNET_YES !=
|
if (GNUNET_YES !=
|
||||||
TALER_json_validate_wireformat (TMH_expected_wire_format,
|
TALER_json_validate_wireformat (TMH_expected_wire_formats,
|
||||||
wire))
|
wire))
|
||||||
{
|
{
|
||||||
TMH_PARSE_release_data (spec);
|
TMH_PARSE_release_data (spec);
|
||||||
|
@ -45,23 +45,32 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh,
|
|||||||
struct TALER_MintPublicKeyP pub;
|
struct TALER_MintPublicKeyP pub;
|
||||||
struct TALER_MintSignatureP sig;
|
struct TALER_MintSignatureP sig;
|
||||||
json_t *methods;
|
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.size = htonl (sizeof (wsm));
|
||||||
wsm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_WIRE_TYPES);
|
wsm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_WIRE_TYPES);
|
||||||
GNUNET_CRYPTO_hash (TMH_expected_wire_format,
|
GNUNET_CRYPTO_hash_context_finish (hc,
|
||||||
strlen (TMH_expected_wire_format) + 1,
|
&wsm.h_wire_types);
|
||||||
&wsm.h_wire_types);
|
|
||||||
TMH_KS_sign (&wsm.purpose,
|
TMH_KS_sign (&wsm.purpose,
|
||||||
&pub,
|
&pub,
|
||||||
&sig);
|
&sig);
|
||||||
methods = json_array ();
|
|
||||||
/* NOTE: for now, we only support *ONE* wire format per
|
/* NOTE: for now, we only support *ONE* wire format per
|
||||||
mint instance; if we supply multiple, we need to
|
mint instance; if we supply multiple, we need to
|
||||||
add the strings for each type separately here -- and
|
add the strings for each type separately here -- and
|
||||||
hash the 0-terminated strings above differently as well...
|
hash the 0-terminated strings above differently as well...
|
||||||
See #3972. */
|
See #3972. */
|
||||||
json_array_append_new (methods,
|
|
||||||
json_string (TMH_expected_wire_format));
|
|
||||||
return TMH_RESPONSE_reply_json_pack (connection,
|
return TMH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
"{s:o, s:o, s:o}",
|
"{s:o, s:o, s:o}",
|
||||||
@ -93,6 +102,7 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,
|
|||||||
struct MHD_Response *response;
|
struct MHD_Response *response;
|
||||||
int ret;
|
int ret;
|
||||||
char *wire_test_redirect;
|
char *wire_test_redirect;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
response = MHD_create_response_from_buffer (0, NULL,
|
response = MHD_create_response_from_buffer (0, NULL,
|
||||||
MHD_RESPMEM_PERSISTENT);
|
MHD_RESPMEM_PERSISTENT);
|
||||||
@ -101,8 +111,11 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
}
|
}
|
||||||
if (0 != strcasecmp ("test",
|
for (i=0;NULL != TMH_expected_wire_formats[i];i++)
|
||||||
TMH_expected_wire_format))
|
if (0 == strcasecmp ("test",
|
||||||
|
TMH_expected_wire_formats[i]))
|
||||||
|
break;
|
||||||
|
if (NULL == TMH_expected_wire_formats[i])
|
||||||
{
|
{
|
||||||
/* Return 501: not implemented */
|
/* Return 501: not implemented */
|
||||||
ret = MHD_queue_response (connection,
|
ret = MHD_queue_response (connection,
|
||||||
@ -155,9 +168,13 @@ TMH_WIRE_handler_wire_sepa (struct TMH_RequestHandler *rh,
|
|||||||
char *sepa_wire_file;
|
char *sepa_wire_file;
|
||||||
int fd;
|
int fd;
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (0 != strcasecmp ("sepa",
|
for (i=0;NULL != TMH_expected_wire_formats[i];i++)
|
||||||
TMH_expected_wire_format))
|
if (0 == strcasecmp ("sepa",
|
||||||
|
TMH_expected_wire_formats[i]))
|
||||||
|
break;
|
||||||
|
if (NULL == TMH_expected_wire_formats[i])
|
||||||
{
|
{
|
||||||
/* Return 501: not implemented */
|
/* Return 501: not implemented */
|
||||||
response = MHD_create_response_from_buffer (0, NULL,
|
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
|
* @brief Tests for JSON validations
|
||||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||||
*/
|
*/
|
||||||
@ -69,6 +69,14 @@ int
|
|||||||
main(int argc,
|
main(int argc,
|
||||||
const char *const argv[])
|
const char *const argv[])
|
||||||
{
|
{
|
||||||
|
const char *unsupported[] = {
|
||||||
|
"unsupported",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char *sepa[] = {
|
||||||
|
"SEPA",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
json_t *wire;
|
json_t *wire;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
int ret;
|
int ret;
|
||||||
@ -76,16 +84,16 @@ main(int argc,
|
|||||||
GNUNET_log_setup ("test-json-validations", "WARNING", NULL);
|
GNUNET_log_setup ("test-json-validations", "WARNING", NULL);
|
||||||
(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 (1 != TALER_json_validate_wireformat ("unsupported", wire));
|
GNUNET_assert (1 != TALER_json_validate_wireformat (unsupported, wire));
|
||||||
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 (1 != TALER_json_validate_wireformat ("SEPA", wire));
|
GNUNET_assert (1 != TALER_json_validate_wireformat (sepa, wire));
|
||||||
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 (1 != TALER_json_validate_wireformat ("SEPA", wire));
|
GNUNET_assert (1 != TALER_json_validate_wireformat (sepa, wire));
|
||||||
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 = TALER_json_validate_wireformat ("SEPA", wire);
|
ret = TALER_json_validate_wireformat (sepa, wire);
|
||||||
json_decref (wire);
|
json_decref (wire);
|
||||||
if (1 == ret)
|
if (1 == ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -395,12 +395,12 @@ struct FormatHandler
|
|||||||
/**
|
/**
|
||||||
* Check if the given wire format JSON object is correctly formatted
|
* 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
|
* @param wire the JSON wire format object
|
||||||
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_json_validate_wireformat (const char *type,
|
TALER_json_validate_wireformat (const char **allowed,
|
||||||
const json_t *wire)
|
const json_t *wire)
|
||||||
{
|
{
|
||||||
static const struct FormatHandler format_handlers[] = {
|
static const struct FormatHandler format_handlers[] = {
|
||||||
@ -409,33 +409,33 @@ TALER_json_validate_wireformat (const char *type,
|
|||||||
{ NULL, NULL}
|
{ NULL, NULL}
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *stype;
|
const char *stype;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
|
|
||||||
UNPACK_EXITIF (0 != json_unpack_ex
|
UNPACK_EXITIF (0 != json_unpack_ex
|
||||||
((json_t *) wire,
|
((json_t *) wire,
|
||||||
&error, 0,
|
&error, 0,
|
||||||
"{"
|
"{s:s}",
|
||||||
"s:s " /* TYPE: type */
|
|
||||||
"}",
|
|
||||||
"type", &stype));
|
"type", &stype));
|
||||||
if (0 != strcasecmp (type,
|
for (i=0;NULL != allowed[i];i++)
|
||||||
stype))
|
if (0 == strcasecmp (allowed[i],
|
||||||
|
stype))
|
||||||
|
break;
|
||||||
|
if (NULL == allowed[i])
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Wireformat `%s' does not match mint's expected `%s' format\n",
|
"Wireformat `%s' does not match mint's allowed formats\n",
|
||||||
stype,
|
stype);
|
||||||
type);
|
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;NULL != format_handlers[i].type;i++)
|
for (i=0;NULL != format_handlers[i].type;i++)
|
||||||
if (0 == strcasecmp (format_handlers[i].type,
|
if (0 == strcasecmp (format_handlers[i].type,
|
||||||
type))
|
stype))
|
||||||
return format_handlers[i].handler (wire);
|
return format_handlers[i].handler (wire);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Wireformat `%s' not supported\n",
|
"Wireformat `%s' not supported\n",
|
||||||
type);
|
stype);
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
EXITIF_exit:
|
EXITIF_exit:
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
|
Loading…
Reference in New Issue
Block a user