refactor to eliminate duplicated JSON parsing logic (#4150)
This commit is contained in:
parent
3d5e096fa2
commit
737e3f4bf6
@ -113,12 +113,12 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_TIME_Absolute at;
|
||||
json_t *wire;
|
||||
json_t *root;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("reserve_pub", &reserve_pub),
|
||||
TMH_PARSE_member_amount ("amount", &amount),
|
||||
TMH_PARSE_member_time_abs ("execution_date", &at),
|
||||
TMH_PARSE_member_object ("wire", &wire),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("reserve_pub", &reserve_pub),
|
||||
TALER_JSON_spec_amount ("amount", &amount),
|
||||
GNUNET_JSON_spec_absolute_time ("execution_date", &at),
|
||||
GNUNET_JSON_spec_json ("wire", &wire),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
int res;
|
||||
|
||||
@ -148,7 +148,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
|
||||
TMH_json_validate_wireformat (wire))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_unknown (connection,
|
||||
"wire");
|
||||
}
|
||||
@ -157,7 +157,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
|
||||
&amount,
|
||||
at,
|
||||
wire);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -140,19 +140,19 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
struct TMH_KS_StateHandle *ks;
|
||||
struct GNUNET_HashCode my_h_wire;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
|
||||
TMH_PARSE_member_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
|
||||
TMH_PARSE_member_fixed ("coin_pub", &deposit.coin.coin_pub),
|
||||
TMH_PARSE_member_fixed ("merchant_pub", &deposit.merchant_pub),
|
||||
TMH_PARSE_member_fixed ("H_contract", &deposit.h_contract),
|
||||
TMH_PARSE_member_fixed ("H_wire", &deposit.h_wire),
|
||||
TMH_PARSE_member_fixed ("coin_sig", &deposit.csig),
|
||||
TMH_PARSE_member_uint64 ("transaction_id", &deposit.transaction_id),
|
||||
TMH_PARSE_member_time_abs ("timestamp", &deposit.timestamp),
|
||||
TMH_PARSE_member_time_abs ("refund_deadline", &deposit.refund_deadline),
|
||||
TMH_PARSE_member_time_abs ("edate", &deposit.wire_deadline),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
|
||||
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &deposit.merchant_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("H_contract", &deposit.h_contract),
|
||||
GNUNET_JSON_spec_fixed_auto ("H_wire", &deposit.h_wire),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_sig", &deposit.csig),
|
||||
GNUNET_JSON_spec_uint64 ("transaction_id", &deposit.transaction_id),
|
||||
GNUNET_JSON_spec_absolute_time ("timestamp", &deposit.timestamp),
|
||||
GNUNET_JSON_spec_absolute_time ("refund_deadline", &deposit.refund_deadline),
|
||||
GNUNET_JSON_spec_absolute_time ("edate", &deposit.wire_deadline),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
memset (&deposit, 0, sizeof (deposit));
|
||||
@ -167,7 +167,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
if (GNUNET_YES !=
|
||||
TMH_json_validate_wireformat (wire))
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_unknown (connection,
|
||||
"wire");
|
||||
}
|
||||
@ -176,7 +176,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
&my_h_wire))
|
||||
{
|
||||
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"wire");
|
||||
}
|
||||
@ -185,7 +185,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
sizeof (struct GNUNET_HashCode)))
|
||||
{
|
||||
/* Client hashed contract differently than we did, reject */
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"H_wire");
|
||||
}
|
||||
@ -196,7 +196,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
if (NULL == dki)
|
||||
{
|
||||
TMH_KS_release (ks);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_unknown (connection,
|
||||
"denom_pub");
|
||||
}
|
||||
@ -209,13 +209,13 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
|
||||
&deposit.deposit_fee))
|
||||
{
|
||||
/* Total amount smaller than fee, invalid */
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"f");
|
||||
}
|
||||
res = verify_and_execute_deposit (connection,
|
||||
&deposit);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -247,10 +247,10 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
|
||||
json_t *wire;
|
||||
int res;
|
||||
struct TALER_Amount amount;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_object ("wire", &wire),
|
||||
TMH_PARSE_member_amount ("f", &amount),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_json ("wire", &wire),
|
||||
TALER_JSON_spec_amount ("f", &amount),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -274,7 +274,7 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
|
||||
json,
|
||||
&amount,
|
||||
wire);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
json_decref (json);
|
||||
return res;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014, 2015 GNUnet e.V.
|
||||
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
||||
|
||||
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
|
||||
@ -141,89 +141,6 @@ buffer_append (struct Buffer *buf,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Release all memory allocated for the variable-size fields in
|
||||
* the parser specification.
|
||||
*
|
||||
* @param spec specification to free
|
||||
* @param spec_len number of items in @a spec to look at
|
||||
*/
|
||||
static void
|
||||
release_data (struct TMH_PARSE_FieldSpecification *spec,
|
||||
unsigned int spec_len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i < spec_len; i++)
|
||||
{
|
||||
switch (spec[i].command)
|
||||
{
|
||||
case TMH_PARSE_JNC_FIELD:
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
case TMH_PARSE_JNC_INDEX:
|
||||
GNUNET_break (0);
|
||||
return;
|
||||
case TMH_PARSE_JNC_RET_DATA:
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_DATA_VAR:
|
||||
if (NULL != spec[i].destination)
|
||||
{
|
||||
GNUNET_free (* (void**) spec[i].destination);
|
||||
*(void**) spec[i].destination = NULL;
|
||||
*spec[i].destination_size_out = 0;
|
||||
}
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_TYPED_JSON:
|
||||
{
|
||||
json_t *json;
|
||||
|
||||
json = *(json_t **) spec[i].destination;
|
||||
if (NULL != json)
|
||||
{
|
||||
json_decref (json);
|
||||
*(json_t**) spec[i].destination = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
|
||||
{
|
||||
struct TALER_DenominationPublicKey *pk;
|
||||
|
||||
pk = spec[i].destination;
|
||||
if (NULL != pk->rsa_public_key)
|
||||
{
|
||||
GNUNET_CRYPTO_rsa_public_key_free (pk->rsa_public_key);
|
||||
pk->rsa_public_key = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
|
||||
{
|
||||
struct TALER_DenominationSignature *sig;
|
||||
|
||||
sig = spec[i].destination;
|
||||
if (NULL != sig->rsa_signature)
|
||||
{
|
||||
GNUNET_CRYPTO_rsa_signature_free (sig->rsa_signature);
|
||||
sig->rsa_signature = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_AMOUNT:
|
||||
memset (spec[i].destination,
|
||||
0,
|
||||
sizeof (struct TALER_Amount));
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_UINT64:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process a POST request containing a JSON object. This function
|
||||
* realizes an MHD POST processor that will (incrementally) process
|
||||
@ -349,8 +266,8 @@ TMH_PARSE_post_cleanup_callback (void *con_cls)
|
||||
/**
|
||||
* Extract base32crockford encoded data from request.
|
||||
*
|
||||
* Queues an error response to the connection if the parameter is missing or
|
||||
* invalid.
|
||||
* Queues an error response to the connection if the parameter is
|
||||
* missing or invalid.
|
||||
*
|
||||
* @param connection the MHD connection
|
||||
* @param param_name the name of the parameter with the key
|
||||
@ -390,759 +307,117 @@ TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extraxt variable-size base32crockford encoded data from request.
|
||||
*
|
||||
* Queues an error response to the connection if the parameter is missing
|
||||
* or the encoding is invalid.
|
||||
*
|
||||
* @param connection the MHD connection
|
||||
* @param param_name the name of the parameter with the key
|
||||
* @param[out] out_data pointer to allocate buffer and store the result
|
||||
* @param[out] out_size set to the size of the buffer allocated in @a out_data
|
||||
* @return
|
||||
* #GNUNET_YES if the the argument is present
|
||||
* #GNUNET_NO if the argument is absent or malformed
|
||||
* #GNUNET_SYSERR on internal error (error response could not be sent)
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
|
||||
const char *param_name,
|
||||
void **out_data,
|
||||
size_t *out_size)
|
||||
{
|
||||
const char *str;
|
||||
size_t slen;
|
||||
size_t olen;
|
||||
void *out;
|
||||
|
||||
str = MHD_lookup_connection_value (connection,
|
||||
MHD_GET_ARGUMENT_KIND,
|
||||
param_name);
|
||||
if (NULL == str)
|
||||
{
|
||||
return (MHD_NO ==
|
||||
TMH_RESPONSE_reply_arg_missing (connection, param_name))
|
||||
? GNUNET_SYSERR : GNUNET_NO;
|
||||
}
|
||||
slen = strlen (str);
|
||||
olen = (slen * 5) / 8;
|
||||
out = GNUNET_malloc (olen);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_STRINGS_string_to_data (str,
|
||||
strlen (str),
|
||||
out,
|
||||
olen))
|
||||
{
|
||||
GNUNET_free (out);
|
||||
*out_size = 0;
|
||||
return (MHD_NO ==
|
||||
TMH_RESPONSE_reply_arg_invalid (connection, param_name))
|
||||
? GNUNET_SYSERR : GNUNET_NO;
|
||||
}
|
||||
*out_data = out;
|
||||
*out_size = olen;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Navigate through a JSON tree.
|
||||
*
|
||||
* Sends an error response if navigation is impossible (i.e.
|
||||
* the JSON object is invalid)
|
||||
*
|
||||
* @param connection the connection to send an error response to
|
||||
* @param root the JSON node to start the navigation at.
|
||||
* @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`)
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error (no response was generated,
|
||||
* connection must be closed)
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_navigate_json (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
...)
|
||||
{
|
||||
va_list argp;
|
||||
int ret;
|
||||
json_t *path; /* what's our current path from 'root'? */
|
||||
|
||||
path = json_array ();
|
||||
va_start (argp, root);
|
||||
ret = 2; /* just not any of the valid return values */
|
||||
while (2 == ret)
|
||||
{
|
||||
enum TMH_PARSE_JsonNavigationCommand command
|
||||
= va_arg (argp,
|
||||
enum TMH_PARSE_JsonNavigationCommand);
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case TMH_PARSE_JNC_FIELD:
|
||||
{
|
||||
const char *fname = va_arg(argp, const char *);
|
||||
|
||||
json_array_append_new (path,
|
||||
json_string (fname));
|
||||
root = json_object_get (root,
|
||||
fname);
|
||||
if (NULL == root)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:s, s:O}",
|
||||
"error", "missing field in JSON",
|
||||
"field", fname,
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_INDEX:
|
||||
{
|
||||
int fnum = va_arg(argp, int);
|
||||
|
||||
json_array_append_new (path,
|
||||
json_integer (fnum));
|
||||
root = json_array_get (root,
|
||||
fnum);
|
||||
if (NULL == root)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "missing index in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_RET_DATA:
|
||||
{
|
||||
void *where = va_arg (argp, void *);
|
||||
size_t len = va_arg (argp, size_t);
|
||||
const char *str;
|
||||
int res;
|
||||
|
||||
str = json_string_value (root);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "string expected",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
res = GNUNET_STRINGS_string_to_data (str, strlen (str),
|
||||
where, len);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed binary data in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_RET_DATA_VAR:
|
||||
{
|
||||
void **where = va_arg (argp, void **);
|
||||
size_t *len = va_arg (argp, size_t *);
|
||||
const char *str;
|
||||
int res;
|
||||
|
||||
str = json_string_value (root);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_internal_error (connection,
|
||||
"json_string_value() failed"))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
*len = (strlen (str) * 5) / 8;
|
||||
if (NULL != where)
|
||||
{
|
||||
*where = GNUNET_malloc (*len);
|
||||
res = GNUNET_STRINGS_string_to_data (str,
|
||||
strlen (str),
|
||||
*where,
|
||||
*len);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_free (*where);
|
||||
*where = NULL;
|
||||
*len = 0;
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed binary data in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_RET_TYPED_JSON:
|
||||
{
|
||||
int typ = va_arg (argp, int);
|
||||
const json_t **r_json = va_arg (argp, const json_t **);
|
||||
|
||||
if ( (NULL == root) ||
|
||||
( (-1 != typ) &&
|
||||
(json_typeof (root) != typ)) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
*r_json = NULL;
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:i, s:i, s:O}",
|
||||
"error", "wrong JSON field type",
|
||||
"type_expected", typ,
|
||||
"type_actual", json_typeof (root),
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
*r_json = root;
|
||||
json_incref ((json_t *) root);
|
||||
ret = GNUNET_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_RET_UINT64:
|
||||
{
|
||||
uint64_t *r_u64 = va_arg (argp, uint64_t *);
|
||||
|
||||
if (json_typeof (root) != JSON_INTEGER)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:s, s:i, s:O}",
|
||||
"error", "wrong JSON field type",
|
||||
"type_expected", "integer",
|
||||
"type_actual", json_typeof (root),
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
*r_u64 = (uint64_t) json_integer_value (root);
|
||||
ret = GNUNET_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
|
||||
{
|
||||
struct TALER_DenominationPublicKey *where;
|
||||
size_t len;
|
||||
const char *str;
|
||||
int res;
|
||||
void *buf;
|
||||
|
||||
where = va_arg (argp,
|
||||
struct TALER_DenominationPublicKey *);
|
||||
str = json_string_value (root);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "string expected",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
len = (strlen (str) * 5) / 8;
|
||||
buf = GNUNET_malloc (len);
|
||||
res = GNUNET_STRINGS_string_to_data (str,
|
||||
strlen (str),
|
||||
buf,
|
||||
len);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_free (buf);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed binary data in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf,
|
||||
len);
|
||||
GNUNET_free (buf);
|
||||
if (NULL == where->rsa_public_key)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed RSA public key in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
|
||||
{
|
||||
struct TALER_DenominationSignature *where;
|
||||
size_t len;
|
||||
const char *str;
|
||||
int res;
|
||||
void *buf;
|
||||
|
||||
where = va_arg (argp,
|
||||
struct TALER_DenominationSignature *);
|
||||
str = json_string_value (root);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "string expected",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
len = (strlen (str) * 5) / 8;
|
||||
buf = GNUNET_malloc (len);
|
||||
res = GNUNET_STRINGS_string_to_data (str,
|
||||
strlen (str),
|
||||
buf,
|
||||
len);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_free (buf);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed binary data in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf,
|
||||
len);
|
||||
GNUNET_free (buf);
|
||||
if (NULL == where->rsa_signature)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "malformed RSA signature in JSON",
|
||||
"path", path))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case TMH_PARSE_JNC_RET_AMOUNT:
|
||||
{
|
||||
struct TALER_Amount *where = va_arg (argp, void *);
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount (NULL, where),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse ((json_t *) root,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES !=
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O}",
|
||||
"error", "Bad format",
|
||||
"path", path))
|
||||
? GNUNET_SYSERR : GNUNET_NO;
|
||||
break;
|
||||
}
|
||||
if (0 != strcmp (where->currency,
|
||||
TMH_exchange_currency_string))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES !=
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:O, s:s}",
|
||||
"error", "Currency not supported",
|
||||
"path", path,
|
||||
"currency", where->currency))
|
||||
? GNUNET_SYSERR : GNUNET_NO;
|
||||
memset (where, 0, sizeof (struct TALER_Amount));
|
||||
break;
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
|
||||
{
|
||||
struct GNUNET_TIME_Absolute *where = va_arg (argp, void *);
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_absolute_time (NULL, where),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse ((json_t *) root,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ret = (MHD_YES !=
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:s, s:O}",
|
||||
"error", "Bad format",
|
||||
"hint", "expected absolute time",
|
||||
"path", path))
|
||||
? GNUNET_SYSERR : GNUNET_NO;
|
||||
break;
|
||||
}
|
||||
ret = GNUNET_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
GNUNET_break (0);
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_internal_error (connection,
|
||||
"unhandled value in switch"))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end (argp);
|
||||
json_decref (path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse JSON object into components based on the given field
|
||||
* specification.
|
||||
* specification. Generates error response on parse errors.
|
||||
*
|
||||
* @param connection the connection to send an error response to
|
||||
* @param root the JSON node to start the navigation at.
|
||||
* @param spec field specification for the parser
|
||||
* @param[in,out] spec field specification for the parser
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful (caller is responsible
|
||||
* for freeing allocated variable-size data using
|
||||
* #TMH_PARSE_release_data() when done)
|
||||
* #GNUNET_JSON_parse_free() when done)
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_json_data (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
struct TMH_PARSE_FieldSpecification *spec)
|
||||
struct GNUNET_JSON_Specification *spec)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
const char *error_json_name;
|
||||
unsigned int error_line;
|
||||
|
||||
ret = GNUNET_YES;
|
||||
for (i=0; NULL != spec[i].field_name; i++)
|
||||
ret = GNUNET_JSON_parse (root,
|
||||
spec,
|
||||
&error_json_name,
|
||||
&error_line);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
{
|
||||
if (GNUNET_YES != ret)
|
||||
break;
|
||||
switch (spec[i].command)
|
||||
{
|
||||
case TMH_PARSE_JNC_FIELD:
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
case TMH_PARSE_JNC_INDEX:
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
case TMH_PARSE_JNC_RET_DATA:
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_DATA,
|
||||
spec[i].destination,
|
||||
spec[i].destination_size_in);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_DATA_VAR:
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_DATA_VAR,
|
||||
(void **) spec[i].destination,
|
||||
spec[i].destination_size_out);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_TYPED_JSON:
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_TYPED_JSON,
|
||||
spec[i].type,
|
||||
spec[i].destination);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
|
||||
spec[i].destination);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_RSA_SIGNATURE,
|
||||
spec[i].destination);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_AMOUNT:
|
||||
GNUNET_assert (sizeof (struct TALER_Amount) ==
|
||||
spec[i].destination_size_in);
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_AMOUNT,
|
||||
spec[i].destination);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
|
||||
GNUNET_assert (sizeof (struct GNUNET_TIME_Absolute) ==
|
||||
spec[i].destination_size_in);
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
|
||||
spec[i].destination);
|
||||
break;
|
||||
case TMH_PARSE_JNC_RET_UINT64:
|
||||
GNUNET_assert (sizeof (uint64_t) ==
|
||||
spec[i].destination_size_in);
|
||||
ret = TMH_PARSE_navigate_json (connection,
|
||||
root,
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
spec[i].field_name,
|
||||
TMH_PARSE_JNC_RET_UINT64,
|
||||
spec[i].destination);
|
||||
break;
|
||||
}
|
||||
if (NULL == error_json_name)
|
||||
error_json_name = "<no field>";
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:s, s:I}",
|
||||
"error", "parse error",
|
||||
"field", error_json_name,
|
||||
"line", (json_int_t) error_line))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
return ret;
|
||||
}
|
||||
if (GNUNET_YES != ret)
|
||||
release_data (spec,
|
||||
i - 1);
|
||||
return ret;
|
||||
return GNUNET_YES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Release all memory allocated for the variable-size fields in
|
||||
* the parser specification.
|
||||
* Parse JSON array into components based on the given field
|
||||
* specification. Generates error response on parse errors.
|
||||
*
|
||||
* @param spec specification to free
|
||||
* @param connection the connection to send an error response to
|
||||
* @param root the JSON node to start the navigation at.
|
||||
* @param[in,out] spec field specification for the parser
|
||||
* @param ... -1-terminated list of array offsets of type 'int'
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful (caller is responsible
|
||||
* for freeing allocated variable-size data using
|
||||
* #GNUNET_JSON_parse_free() when done)
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error
|
||||
*/
|
||||
void
|
||||
TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
|
||||
int
|
||||
TMH_PARSE_json_array (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
struct GNUNET_JSON_Specification *spec,
|
||||
...)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
const char *error_json_name;
|
||||
unsigned int error_line;
|
||||
va_list ap;
|
||||
json_int_t dim;
|
||||
|
||||
for (i=0; NULL != spec[i].field_name; i++) ;
|
||||
release_data (spec, i);
|
||||
va_start (ap, spec);
|
||||
dim = 0;
|
||||
while ( (-1 != (ret = va_arg (ap, int))) &&
|
||||
(NULL != root) )
|
||||
{
|
||||
dim++;
|
||||
root = json_array_get (root, ret);
|
||||
}
|
||||
if (NULL == root)
|
||||
{
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:I}",
|
||||
"error", "parse error",
|
||||
"dimension", dim))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
return ret;
|
||||
}
|
||||
ret = GNUNET_JSON_parse (root,
|
||||
spec,
|
||||
&error_json_name,
|
||||
&error_line);
|
||||
if (GNUNET_SYSERR == ret)
|
||||
{
|
||||
if (NULL == error_json_name)
|
||||
error_json_name = "<no field>";
|
||||
ret = (MHD_YES ==
|
||||
TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
"{s:s, s:s, s:I}",
|
||||
"error", "parse error",
|
||||
"field", error_json_name,
|
||||
"line", (json_int_t) error_line))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
return ret;
|
||||
}
|
||||
return GNUNET_YES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for 64-bit integer
|
||||
* given as an integer in JSON.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] u64 integer to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_uint64 (const char *field,
|
||||
uint64_t *u64)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, (void *) u64, sizeof (uint64_t), NULL, TMH_PARSE_JNC_RET_UINT64, 0 };
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for JSON object value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] jsonp address of pointer to JSON to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_object (const char *field,
|
||||
json_t **jsonp)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT };
|
||||
*jsonp = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for JSON array value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] jsonp address of JSON pointer to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_array (const char *field,
|
||||
json_t **jsonp)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY };
|
||||
*jsonp = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for an absolute time.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] atime time to initialize
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_time_abs (const char *field,
|
||||
struct GNUNET_TIME_Absolute *atime)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, atime, sizeof(struct GNUNET_TIME_Absolute), NULL, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 };
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for RSA public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] pk key to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_denomination_public_key (const char *field,
|
||||
struct TALER_DenominationPublicKey *pk)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 };
|
||||
pk->rsa_public_key = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for RSA public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param sig the signature to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_denomination_signature (const char *field,
|
||||
struct TALER_DenominationSignature *sig)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 };
|
||||
sig->rsa_signature = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for an amount.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param amount a `struct TALER_Amount *` to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_amount (const char *field,
|
||||
struct TALER_Amount *amount)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 };
|
||||
memset (amount, 0, sizeof (struct TALER_Amount));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for variable-size value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] ptr pointer to initialize
|
||||
* @param[out] ptr_size size to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_variable (const char *field,
|
||||
void **ptr,
|
||||
size_t *ptr_size)
|
||||
{
|
||||
struct TMH_PARSE_FieldSpecification ret =
|
||||
{ field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 };
|
||||
*ptr = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* end of taler-exchange-httpd_parsing.c */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014, 2015 GNUnet e.V.
|
||||
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
||||
|
||||
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
|
||||
@ -26,6 +26,7 @@
|
||||
#include <microhttpd.h>
|
||||
#include <jansson.h>
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -71,149 +72,6 @@ void
|
||||
TMH_PARSE_post_cleanup_callback (void *con_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Constants for JSON navigation description.
|
||||
*/
|
||||
enum TMH_PARSE_JsonNavigationCommand
|
||||
{
|
||||
/**
|
||||
* Access a field.
|
||||
* Param: const char *
|
||||
*/
|
||||
TMH_PARSE_JNC_FIELD,
|
||||
|
||||
/**
|
||||
* Access an array index.
|
||||
* Param: int
|
||||
*/
|
||||
TMH_PARSE_JNC_INDEX,
|
||||
|
||||
/**
|
||||
* Return base32crockford encoded data of
|
||||
* constant size.
|
||||
* Params: (void *, size_t)
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_DATA,
|
||||
|
||||
/**
|
||||
* Return base32crockford encoded data of
|
||||
* variable size.
|
||||
* Params: (void **, size_t *)
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_DATA_VAR,
|
||||
|
||||
/**
|
||||
* Return a json object, which must be
|
||||
* of the given type (JSON_* type constants,
|
||||
* or -1 for any type).
|
||||
* Params: (int, json_t **)
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_TYPED_JSON,
|
||||
|
||||
/**
|
||||
* Return a `struct GNUNET_CRYPTO_rsa_PublicKey` which was
|
||||
* encoded as variable-size base32crockford encoded data.
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
|
||||
|
||||
/**
|
||||
* Return a `struct GNUNET_CRYPTO_rsa_Signature` which was
|
||||
* encoded as variable-size base32crockford encoded data.
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_RSA_SIGNATURE,
|
||||
|
||||
/**
|
||||
* Return a `struct TALER_Amount` which was
|
||||
* encoded within its own json object.
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_AMOUNT,
|
||||
|
||||
/**
|
||||
* Return a `struct GNUNET_TIME_Absolute` which was
|
||||
* encoded within its own json object.
|
||||
* Param: struct GNUNET_TIME_Absolute *
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
|
||||
|
||||
/**
|
||||
* Return a `uint64_t` which was
|
||||
* encoded as a JSON integer.
|
||||
* Param: uint64_t *
|
||||
*/
|
||||
TMH_PARSE_JNC_RET_UINT64
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Navigate through a JSON tree.
|
||||
*
|
||||
* Sends an error response if navigation is impossible (i.e.
|
||||
* the JSON object is invalid)
|
||||
*
|
||||
* @param connection the connection to send an error response to
|
||||
* @param root the JSON node to start the navigation at.
|
||||
* @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`)
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_navigate_json (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Specification for how to parse a JSON field.
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
{
|
||||
/**
|
||||
* Name of the field. NULL only to terminate array.
|
||||
*/
|
||||
const char *field_name;
|
||||
|
||||
/**
|
||||
* Where to store the result. Must have exactly
|
||||
* @e destination_size bytes, except if @e destination_size is zero.
|
||||
* NULL to skip assignment (but check presence of the value).
|
||||
*/
|
||||
void *destination;
|
||||
|
||||
/**
|
||||
* How big should the result be, 0 for variable size. In
|
||||
* this case, @e destination must be a "void **", pointing
|
||||
* to a location that is currently NULL and is to be allocated.
|
||||
*/
|
||||
size_t destination_size_in;
|
||||
|
||||
/**
|
||||
* @e destination_size_out will then be set to the size of the
|
||||
* value that was stored in @e destination (useful for
|
||||
* variable-size allocations).
|
||||
*/
|
||||
size_t *destination_size_out;
|
||||
|
||||
/**
|
||||
* Navigation command to use to extract the value. Note that
|
||||
* #TMH_PARSE_JNC_RET_DATA or #TMH_PARSE_JNC_RET_DATA_VAR must be used for @e
|
||||
* destination_size_in and @e destination_size_out to have a
|
||||
* meaning. #TMH_PARSE_JNC_FIELD and #TMH_PARSE_JNC_INDEX must not be used here!
|
||||
*/
|
||||
enum TMH_PARSE_JsonNavigationCommand command;
|
||||
|
||||
/**
|
||||
* JSON type to use, only meaningful in connection with a @e command
|
||||
* value of #TMH_PARSE_JNC_RET_TYPED_JSON. Typical values are
|
||||
* #JSON_ARRAY and #JSON_OBJECT.
|
||||
*/
|
||||
int type;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse JSON object into components based on the given field
|
||||
* specification.
|
||||
@ -224,139 +82,36 @@ struct TMH_PARSE_FieldSpecification
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful (caller is responsible
|
||||
* for freeing allocated variable-size data using
|
||||
* #TMH_PARSE_release_data() when done)
|
||||
* #GNUNET_JSON_parse_free() when done)
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_json_data (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
struct TMH_PARSE_FieldSpecification *spec);
|
||||
struct GNUNET_JSON_Specification *spec);
|
||||
|
||||
|
||||
/**
|
||||
* Release all memory allocated for the variable-size fields in
|
||||
* the parser specification.
|
||||
* Parse JSON array into components based on the given field
|
||||
* specification. Generates error response on parse errors.
|
||||
*
|
||||
* @param spec specification to free
|
||||
* @param connection the connection to send an error response to
|
||||
* @param root the JSON node to start the navigation at.
|
||||
* @param[in,out] spec field specification for the parser
|
||||
* @param ... -1-terminated list of array offsets of type 'int'
|
||||
* @return
|
||||
* #GNUNET_YES if navigation was successful (caller is responsible
|
||||
* for freeing allocated variable-size data using
|
||||
* #GNUNET_JSON_parse_free() when done)
|
||||
* #GNUNET_NO if json is malformed, error response was generated
|
||||
* #GNUNET_SYSERR on internal error
|
||||
*/
|
||||
void
|
||||
TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for fixed-size value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param value where to store the value
|
||||
*/
|
||||
#define TMH_PARSE_member_fixed(field,value) { field, value, sizeof (*value), NULL, TMH_PARSE_JNC_RET_DATA, 0 }
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for variable-size value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] ptr pointer to initialize
|
||||
* @param[out] ptr_size size to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_variable (const char *field,
|
||||
void **ptr,
|
||||
size_t *ptr_size);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for 64-bit integer
|
||||
* given as an integer in JSON.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] u64 integer to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_uint64 (const char *field,
|
||||
uint64_t *u64);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for JSON array value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] jsonp address of JSON pointer to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_array (const char *field,
|
||||
json_t **jsonp);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for JSON object value.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] jsonp address of pointer to JSON to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_object (const char *field,
|
||||
json_t **jsonp);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for RSA public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] pk key to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_denomination_public_key (const char *field,
|
||||
struct TALER_DenominationPublicKey *pk);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for RSA public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param sig the signature to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_denomination_signature (const char *field,
|
||||
struct TALER_DenominationSignature *sig);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for an amount.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] amount a `struct TALER_Amount *` to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_amount (const char *field,
|
||||
struct TALER_Amount *amount);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for an absolute time.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] atime time to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct TMH_PARSE_FieldSpecification
|
||||
TMH_PARSE_member_time_abs (const char *field,
|
||||
struct GNUNET_TIME_Absolute *atime);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification indicating the end of the spec.
|
||||
*/
|
||||
#define TMH_PARSE_MEMBER_END { NULL, NULL, 0, NULL, TMH_PARSE_JNC_FIELD, 0 }
|
||||
int
|
||||
TMH_PARSE_json_array (struct MHD_Connection *connection,
|
||||
const json_t *root,
|
||||
struct GNUNET_JSON_Specification *spec,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
@ -381,28 +136,4 @@ TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
|
||||
size_t out_size);
|
||||
|
||||
|
||||
/**
|
||||
* Extraxt variable-size base32crockford encoded data from request.
|
||||
*
|
||||
* Queues an error response to the connection if the parameter is missing
|
||||
* or the encoding is invalid.
|
||||
*
|
||||
* @param connection the MHD connection
|
||||
* @param param_name the name of the parameter with the key
|
||||
* @param[out] out_data pointer to allocate buffer and store the result
|
||||
* @param[out] out_size set to the size of the buffer allocated in @a out_data
|
||||
* @return
|
||||
* #GNUNET_YES if the the argument is present
|
||||
* #GNUNET_NO if the argument is absent or malformed
|
||||
* #GNUNET_SYSERR on internal error (error response could not be sent)
|
||||
*/
|
||||
int
|
||||
TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
|
||||
const char *param_name,
|
||||
void **out_data,
|
||||
size_t *out_size);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* TALER_EXCHANGE_HTTPD_PARSING_H */
|
||||
|
@ -192,13 +192,13 @@ get_coin_public_info (struct MHD_Connection *connection,
|
||||
struct TALER_DenominationSignature sig;
|
||||
struct TALER_DenominationPublicKey pk;
|
||||
struct TALER_Amount amount;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("coin_pub", &r_melt_detail->coin_info.coin_pub),
|
||||
TMH_PARSE_member_denomination_signature ("denom_sig", &sig),
|
||||
TMH_PARSE_member_denomination_public_key ("denom_pub", &pk),
|
||||
TMH_PARSE_member_fixed ("confirm_sig", &melt_sig),
|
||||
TMH_PARSE_member_amount ("value_with_fee", &amount),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &r_melt_detail->coin_info.coin_pub),
|
||||
TALER_JSON_spec_denomination_signature ("denom_sig", &sig),
|
||||
TALER_JSON_spec_denomination_public_key ("denom_pub", &pk),
|
||||
GNUNET_JSON_spec_fixed_auto ("confirm_sig", &melt_sig),
|
||||
TALER_JSON_spec_amount ("value_with_fee", &amount),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
ret = TMH_PARSE_json_data (connection,
|
||||
@ -216,7 +216,7 @@ get_coin_public_info (struct MHD_Connection *connection,
|
||||
TALER_test_coin_valid (&r_melt_detail->coin_info))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
r_melt_detail->coin_info.denom_sig.rsa_signature = NULL;
|
||||
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
|
||||
return (MHD_YES ==
|
||||
@ -409,12 +409,16 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
{
|
||||
char *buf;
|
||||
size_t buf_size;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_denomination_public_key (NULL,
|
||||
&denom_pubs[i]),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
new_denoms,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
|
||||
&denom_pubs[i].rsa_public_key);
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
new_denoms,
|
||||
spec,
|
||||
i, -1);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
res = (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||
@ -436,6 +440,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
/* decode JSON data on coin to melt */
|
||||
struct TALER_AmountNBO melt_amount;
|
||||
|
||||
// FIXME: check json_array_get() return value for NULL!
|
||||
res = get_coin_public_info (connection,
|
||||
json_array_get (melt_coins, i),
|
||||
&coin_melt_details[i]);
|
||||
@ -482,15 +487,23 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
char *link_enc;
|
||||
size_t link_enc_size;
|
||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *rcc = &commit_coin[i][j];
|
||||
struct GNUNET_JSON_Specification coin_spec[] = {
|
||||
GNUNET_JSON_spec_varsize (NULL,
|
||||
(void **) &rcc->coin_ev,
|
||||
&rcc->coin_ev_size),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct GNUNET_JSON_Specification link_spec[] = {
|
||||
GNUNET_JSON_spec_varsize (NULL,
|
||||
(void **) &link_enc,
|
||||
&link_enc_size),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
coin_evs,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_INDEX, (int) j,
|
||||
TMH_PARSE_JNC_RET_DATA_VAR,
|
||||
&rcc->coin_ev,
|
||||
&rcc->coin_ev_size);
|
||||
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
coin_evs,
|
||||
coin_spec,
|
||||
i, j, -1);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -501,13 +514,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||
rcc->coin_ev,
|
||||
rcc->coin_ev_size);
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
link_encs,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_INDEX, (int) j,
|
||||
TMH_PARSE_JNC_RET_DATA_VAR,
|
||||
&link_enc,
|
||||
&link_enc_size);
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
link_encs,
|
||||
link_spec,
|
||||
i, j, -1);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -520,7 +530,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||
link_enc,
|
||||
link_enc_size);
|
||||
GNUNET_free (link_enc);
|
||||
GNUNET_JSON_parse_free (link_spec);
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,27 +541,29 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
||||
for (j = 0; j < num_oldcoins; j++)
|
||||
{
|
||||
struct TALER_RefreshCommitLinkP *rcl = &commit_link[i][j];
|
||||
struct GNUNET_JSON_Specification trans_spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->transfer_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct GNUNET_JSON_Specification sec_spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->shared_secret_enc),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
transfer_pubs,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_INDEX, (int) j,
|
||||
TMH_PARSE_JNC_RET_DATA,
|
||||
&rcl->transfer_pub,
|
||||
sizeof (struct TALER_TransferPublicKeyP));
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
transfer_pubs,
|
||||
trans_spec,
|
||||
i, j, -1);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||
goto cleanup;
|
||||
}
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
secret_encs,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_INDEX, (int) j,
|
||||
TMH_PARSE_JNC_RET_DATA,
|
||||
&rcl->shared_secret_enc,
|
||||
sizeof (struct TALER_EncryptedLinkSecretP));
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
secret_encs,
|
||||
sec_spec,
|
||||
i, j, -1);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -646,15 +658,16 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
|
||||
unsigned int num_oldcoins;
|
||||
unsigned int num_newcoins;
|
||||
json_t *coin_detail;
|
||||
json_t *trans_detail;
|
||||
int res;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_array ("new_denoms", &new_denoms),
|
||||
TMH_PARSE_member_array ("melt_coins", &melt_coins),
|
||||
TMH_PARSE_member_array ("coin_evs", &coin_evs),
|
||||
TMH_PARSE_member_array ("link_encs", &link_encs),
|
||||
TMH_PARSE_member_array ("transfer_pubs", &transfer_pubs),
|
||||
TMH_PARSE_member_array ("secret_encs", &secret_encs),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_json ("new_denoms", &new_denoms),
|
||||
GNUNET_JSON_spec_json ("melt_coins", &melt_coins),
|
||||
GNUNET_JSON_spec_json ("coin_evs", &coin_evs),
|
||||
GNUNET_JSON_spec_json ("link_encs", &link_encs),
|
||||
GNUNET_JSON_spec_json ("transfer_pubs", &transfer_pubs),
|
||||
GNUNET_JSON_spec_json ("secret_encs", &secret_encs),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -678,43 +691,36 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
|
||||
if (TALER_CNC_KAPPA != json_array_size (coin_evs))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"coin_evs");
|
||||
}
|
||||
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"transfer_pubs");
|
||||
}
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
coin_evs,
|
||||
TMH_PARSE_JNC_INDEX, (int) 0,
|
||||
TMH_PARSE_JNC_RET_TYPED_JSON,
|
||||
JSON_ARRAY, &coin_detail);
|
||||
if (GNUNET_OK != res)
|
||||
coin_detail = json_array_get (coin_evs, 0);
|
||||
if (NULL == coin_detail)
|
||||
{
|
||||
// FIXME: generate proper HTTP response!
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||
}
|
||||
num_newcoins = json_array_size (coin_detail);
|
||||
json_decref (coin_detail);
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
transfer_pubs,
|
||||
TMH_PARSE_JNC_INDEX, (int) 0,
|
||||
TMH_PARSE_JNC_RET_TYPED_JSON,
|
||||
JSON_ARRAY, &coin_detail);
|
||||
if (GNUNET_OK != res)
|
||||
|
||||
trans_detail = json_array_get (transfer_pubs, 0);
|
||||
if (NULL == trans_detail)
|
||||
{
|
||||
// FIXME: generate proper HTTP response!
|
||||
GNUNET_break_op (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||
}
|
||||
num_oldcoins = json_array_size (coin_detail);
|
||||
json_decref (coin_detail);
|
||||
num_oldcoins = json_array_size (trans_detail);
|
||||
res = handle_refresh_melt_json (connection,
|
||||
new_denoms,
|
||||
melt_coins,
|
||||
@ -724,7 +730,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
|
||||
num_newcoins,
|
||||
coin_evs,
|
||||
link_encs);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -763,15 +769,16 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
break;
|
||||
for (j = 0; j < num_oldcoins; j++)
|
||||
{
|
||||
struct GNUNET_JSON_Specification tp_spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (NULL, &transfer_privs[i][j]),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
if (GNUNET_OK != res)
|
||||
break;
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
tp_json,
|
||||
TMH_PARSE_JNC_INDEX, (int) i,
|
||||
TMH_PARSE_JNC_INDEX, (int) j,
|
||||
TMH_PARSE_JNC_RET_DATA,
|
||||
&transfer_privs[i][j],
|
||||
sizeof (struct TALER_TransferPrivateKeyP));
|
||||
res = TMH_PARSE_json_array (connection,
|
||||
tp_json,
|
||||
tp_spec,
|
||||
i, j, -1);
|
||||
GNUNET_break_op (GNUNET_OK == res);
|
||||
}
|
||||
}
|
||||
@ -817,10 +824,10 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
|
||||
json_t *reveal_detail;
|
||||
json_t *root;
|
||||
json_t *transfer_privs;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("session_hash", &session_hash),
|
||||
TMH_PARSE_member_array ("transfer_privs", &transfer_privs),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("session_hash", &session_hash),
|
||||
GNUNET_JSON_spec_json ("transfer_privs", &transfer_privs),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -846,30 +853,25 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
|
||||
/* Note we do +1 as 1 row (cut-and-choose!) is missing! */
|
||||
if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1)
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
GNUNET_break_op (0);
|
||||
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||
"transfer_privs");
|
||||
}
|
||||
res = TMH_PARSE_navigate_json (connection,
|
||||
transfer_privs,
|
||||
TMH_PARSE_JNC_INDEX, 0,
|
||||
TMH_PARSE_JNC_RET_TYPED_JSON,
|
||||
JSON_ARRAY,
|
||||
&reveal_detail);
|
||||
if (GNUNET_OK != res)
|
||||
reveal_detail = json_array_get (transfer_privs, 0);
|
||||
if (NULL == reveal_detail)
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
// FIXME: generate proper HTTP response!
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
GNUNET_break_op (0);
|
||||
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||
}
|
||||
num_oldcoins = json_array_size (reveal_detail);
|
||||
json_decref (reveal_detail);
|
||||
res = handle_refresh_reveal_json (connection,
|
||||
&session_hash,
|
||||
num_oldcoins,
|
||||
transfer_privs);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -101,17 +101,17 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
struct TMH_KS_StateHandle *ks;
|
||||
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_variable ("coin_ev",
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_varsize ("coin_ev",
|
||||
(void **) &blinded_msg,
|
||||
&blinded_msg_len),
|
||||
TMH_PARSE_member_fixed ("reserve_pub",
|
||||
GNUNET_JSON_spec_fixed_auto ("reserve_pub",
|
||||
&wsrd.reserve_pub),
|
||||
TMH_PARSE_member_fixed ("reserve_sig",
|
||||
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
|
||||
&signature),
|
||||
TMH_PARSE_member_denomination_public_key ("denom_pub",
|
||||
TALER_JSON_spec_denomination_public_key ("denom_pub",
|
||||
&denomination_pub),
|
||||
TMH_PARSE_MEMBER_END
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -135,7 +135,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
|
||||
TMH_KS_DKU_WITHDRAW);
|
||||
if (NULL == dki)
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TMH_KS_release (ks);
|
||||
return TMH_RESPONSE_reply_arg_unknown (connection,
|
||||
"denom_pub");
|
||||
@ -169,7 +169,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
|
||||
&wsrd.reserve_pub.eddsa_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_signature_invalid (connection,
|
||||
"reserve_sig");
|
||||
}
|
||||
@ -179,7 +179,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
|
||||
blinded_msg,
|
||||
blinded_msg_len,
|
||||
&signature);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -63,9 +63,9 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh,
|
||||
void *in_ptr;
|
||||
size_t in_ptr_size;
|
||||
struct GNUNET_HashCode hc;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -85,7 +85,7 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh,
|
||||
GNUNET_CRYPTO_hash (in_ptr,
|
||||
in_ptr_size,
|
||||
&hc);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
json_decref (json);
|
||||
return TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
@ -126,10 +126,10 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
|
||||
void *in_ptr;
|
||||
size_t in_ptr_size;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size),
|
||||
TMH_PARSE_member_fixed ("key_hash", &key),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
|
||||
GNUNET_JSON_spec_fixed_auto ("key_hash", &key),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
char *out;
|
||||
|
||||
@ -168,7 +168,7 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh,
|
||||
json = GNUNET_JSON_from_data (out,
|
||||
in_ptr_size);
|
||||
GNUNET_free (out);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
"{s:o}",
|
||||
@ -206,9 +206,9 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_HashCode hc;
|
||||
void *in_ptr;
|
||||
size_t in_ptr_size;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -231,7 +231,7 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh,
|
||||
in_ptr,
|
||||
in_ptr_size,
|
||||
NULL, 0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
json = GNUNET_JSON_from_data (&hc,
|
||||
sizeof (struct GNUNET_HashCode));
|
||||
return TMH_RESPONSE_reply_json_pack (connection,
|
||||
@ -268,10 +268,10 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_CRYPTO_EcdhePublicKey pub;
|
||||
struct GNUNET_CRYPTO_EcdhePrivateKey priv;
|
||||
struct GNUNET_HashCode hc;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("ecdhe_pub", &pub),
|
||||
TMH_PARSE_member_fixed ("ecdhe_priv", &priv),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("ecdhe_pub", &pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("ecdhe_priv", &priv),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -294,11 +294,11 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
|
||||
&pub,
|
||||
&hc))
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_internal_error (connection,
|
||||
"Failed to perform ECDH");
|
||||
}
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
"{s:o}",
|
||||
@ -335,10 +335,10 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_CRYPTO_EddsaPublicKey pub;
|
||||
struct GNUNET_CRYPTO_EddsaSignature sig;
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("eddsa_pub", &pub),
|
||||
TMH_PARSE_member_fixed ("eddsa_sig", &sig),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("eddsa_pub", &pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("eddsa_sig", &sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
|
||||
|
||||
@ -365,11 +365,11 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh,
|
||||
&sig,
|
||||
&pub))
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_signature_invalid (connection,
|
||||
"eddsa_sig");
|
||||
}
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
pk = GNUNET_CRYPTO_eddsa_key_create ();
|
||||
purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_TEST_EDDSA);
|
||||
if (GNUNET_OK !=
|
||||
@ -466,9 +466,9 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
|
||||
struct GNUNET_CRYPTO_rsa_Signature *sig;
|
||||
void *in_ptr;
|
||||
size_t in_ptr_size;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_variable ("blind_ev", &in_ptr, &in_ptr_size),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_varsize ("blind_ev", &in_ptr, &in_ptr_size),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -491,7 +491,7 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
|
||||
if (NULL == rsa_pk)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_internal_error (connection,
|
||||
"Failed to create RSA key");
|
||||
}
|
||||
@ -501,11 +501,11 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
|
||||
if (NULL == sig)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_internal_error (connection,
|
||||
"Failed to RSA-sign");
|
||||
}
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
res = TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_OK,
|
||||
"{s:o}",
|
||||
@ -542,11 +542,11 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
|
||||
struct TALER_EncryptedLinkSecretP secret_enc;
|
||||
struct TALER_TransferPrivateKeyP trans_priv;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("secret_enc", &secret_enc),
|
||||
TMH_PARSE_member_fixed ("trans_priv", &trans_priv),
|
||||
TMH_PARSE_member_fixed ("coin_pub", &coin_pub),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("secret_enc", &secret_enc),
|
||||
GNUNET_JSON_spec_fixed_auto ("trans_priv", &trans_priv),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct TALER_LinkSecretP secret;
|
||||
|
||||
@ -571,7 +571,7 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
|
||||
&coin_pub,
|
||||
&secret))
|
||||
{
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TMH_RESPONSE_reply_internal_error (connection,
|
||||
"Failed to decrypt secret");
|
||||
}
|
||||
|
@ -121,14 +121,14 @@ TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
|
||||
struct TALER_DepositTrackPS tps;
|
||||
uint64_t transaction_id;
|
||||
struct TALER_MerchantSignatureP merchant_sig;
|
||||
struct TMH_PARSE_FieldSpecification spec[] = {
|
||||
TMH_PARSE_member_fixed ("H_wire", &tps.h_wire),
|
||||
TMH_PARSE_member_fixed ("H_contract", &tps.h_contract),
|
||||
TMH_PARSE_member_fixed ("coin_pub", &tps.coin_pub),
|
||||
TMH_PARSE_member_uint64 ("transaction_id", &transaction_id),
|
||||
TMH_PARSE_member_fixed ("merchant_pub", &tps.merchant),
|
||||
TMH_PARSE_member_fixed ("merchant_sig", &merchant_sig),
|
||||
TMH_PARSE_MEMBER_END
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("H_wire", &tps.h_wire),
|
||||
GNUNET_JSON_spec_fixed_auto ("H_contract", &tps.h_contract),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &tps.coin_pub),
|
||||
GNUNET_JSON_spec_uint64 ("transaction_id", &transaction_id),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &tps.merchant),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
res = TMH_PARSE_post_json (connection,
|
||||
@ -156,7 +156,7 @@ TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
|
||||
&tps.merchant,
|
||||
&merchant_sig,
|
||||
transaction_id);
|
||||
TMH_PARSE_release_data (spec);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
json_decref (json);
|
||||
return res;
|
||||
}
|
||||
|
@ -57,6 +57,30 @@ TALER_JSON_spec_amount (const char *name,
|
||||
struct TALER_Amount *r_amount);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for denomination public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] pk key to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct GNUNET_JSON_Specification
|
||||
TALER_JSON_spec_denomination_public_key (const char *field,
|
||||
struct TALER_DenominationPublicKey *pk);
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for denomination signature.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param sig the signature to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct GNUNET_JSON_Specification
|
||||
TALER_JSON_spec_denomination_signature (const char *field,
|
||||
struct TALER_DenominationSignature *sig);
|
||||
|
||||
|
||||
/**
|
||||
* Hash a JSON for binary signing.
|
||||
*
|
||||
|
@ -143,4 +143,36 @@ TALER_JSON_spec_amount (const char *name,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for denomination public key.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param[out] pk key to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct GNUNET_JSON_Specification
|
||||
TALER_JSON_spec_denomination_public_key (const char *field,
|
||||
struct TALER_DenominationPublicKey *pk)
|
||||
{
|
||||
return GNUNET_JSON_spec_rsa_public_key (field,
|
||||
&pk->rsa_public_key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate line in parser specification for denomination signature.
|
||||
*
|
||||
* @param field name of the field
|
||||
* @param sig the signature to initialize
|
||||
* @return corresponding field spec
|
||||
*/
|
||||
struct GNUNET_JSON_Specification
|
||||
TALER_JSON_spec_denomination_signature (const char *field,
|
||||
struct TALER_DenominationSignature *sig)
|
||||
{
|
||||
return GNUNET_JSON_spec_rsa_signature (field,
|
||||
&sig->rsa_signature);
|
||||
}
|
||||
|
||||
|
||||
/* end of json/json_helper.c */
|
||||
|
Loading…
Reference in New Issue
Block a user