fix use of struct TALER_DepositRequestPS (unfinished)

This commit is contained in:
Christian Grothoff 2015-03-28 17:10:39 +01:00
parent d61dbb3109
commit 15b362373f
5 changed files with 178 additions and 102 deletions

View File

@ -239,6 +239,28 @@ struct TALER_MINTDB_Deposit
*/ */
uint64_t transaction_id; uint64_t transaction_id;
/**
* Time when this request was generated. Used, for example, to
* assess when (roughly) the income was achieved for tax purposes.
* Note that the Mint will only check that the timestamp is not "too
* far" into the future (i.e. several days). The fact that the
* timestamp falls within the validity period of the coin's
* denomination key is irrelevant for the validity of the deposit
* request, as obviously the customer and merchant could conspire to
* set any timestamp. Also, the Mint must accept very old deposit
* requests, as the merchant might have been unable to transmit the
* deposit request in a timely fashion (so back-dating is not
* prevented).
*/
struct GNUNET_TIME_Absolute timestamp;
/**
* How much time does the merchant have to issue a refund request?
* Zero if refunds are not allowed. After this time, the coin
* cannot be refunded.
*/
struct GNUNET_TIME_Absolute refund_deadline;
/** /**
* Fraction of the coin's remaining value to be deposited, including * Fraction of the coin's remaining value to be deposited, including
* depositing fee (if any). The coin is identified by @e coin_pub. * depositing fee (if any). The coin is identified by @e coin_pub.

View File

@ -64,9 +64,14 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
dr.h_contract = deposit->h_contract; dr.h_contract = deposit->h_contract;
dr.h_wire = deposit->h_wire; dr.h_wire = deposit->h_wire;
dr.timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline);
dr.transaction_id = GNUNET_htonll (deposit->transaction_id); dr.transaction_id = GNUNET_htonll (deposit->transaction_id);
TALER_amount_hton (&dr.amount_with_fee, TALER_amount_hton (&dr.amount_with_fee,
&deposit->amount_with_fee); &deposit->amount_with_fee);
TALER_amount_hton (&dr.deposit_fee,
&deposit->deposit_fee);
dr.merchant = deposit->merchant_pub;
dr.coin_pub = deposit->coin.coin_pub; dr.coin_pub = deposit->coin.coin_pub;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
@ -145,13 +150,15 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
TMH_PARSE_MEMBER_FIXED ("H_wire", &deposit.h_wire), TMH_PARSE_MEMBER_FIXED ("H_wire", &deposit.h_wire),
TMH_PARSE_MEMBER_FIXED ("csig", &deposit.csig), TMH_PARSE_MEMBER_FIXED ("csig", &deposit.csig),
TMH_PARSE_MEMBER_FIXED ("transaction_id", &deposit.transaction_id), TMH_PARSE_MEMBER_FIXED ("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_END TMH_PARSE_MEMBER_END
}; };
memset (&deposit, 0, sizeof (deposit)); memset (&deposit, 0, sizeof (deposit));
res = TMH_PARSE_json_data (connection, res = TMH_PARSE_json_data (connection,
root, root,
spec); spec);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */ return MHD_NO; /* hard failure */
if (GNUNET_NO == res) if (GNUNET_NO == res)
@ -169,7 +176,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n"); TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
TMH_PARSE_release_data (spec); TMH_PARSE_release_data (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"wire"); "wire");
} }
len = strlen (wire_enc) + 1; len = strlen (wire_enc) + 1;
GNUNET_CRYPTO_hash (wire_enc, GNUNET_CRYPTO_hash (wire_enc,
@ -179,6 +186,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
deposit.wire = wire; deposit.wire = wire;
deposit.amount_with_fee = *amount; deposit.amount_with_fee = *amount;
deposit.deposit_fee = *amount; // FIXME: get fee from denomination key!
res = verify_and_execute_deposit (connection, res = verify_and_execute_deposit (connection,
&deposit); &deposit);
TMH_PARSE_release_data (spec); TMH_PARSE_release_data (spec);
@ -216,10 +224,10 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
json_t *f; json_t *f;
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
connection_cls, connection_cls,
upload_data, upload_data,
upload_data_size, upload_data_size,
&json); &json);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) ) if ( (GNUNET_NO == res) || (NULL == json) )
@ -232,13 +240,13 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
GNUNET_break_op (0); GNUNET_break_op (0);
json_decref (json); json_decref (json);
return TMH_RESPONSE_reply_json_pack (connection, return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s}", "{s:s}",
"error", "Bad format"); "error", "Bad format");
} }
res = TMH_PARSE_amount_json (connection, res = TMH_PARSE_amount_json (connection,
f, f,
&amount); &amount);
json_decref (f); json_decref (f);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
{ {

View File

@ -320,9 +320,9 @@ TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
*/ */
int int
TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection, TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
const char *param_name, const char *param_name,
void **out_data, void **out_data,
size_t *out_size) size_t *out_size)
{ {
const char *str; const char *str;
size_t slen; size_t slen;
@ -567,12 +567,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"string expected", "string expected",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -587,12 +587,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
GNUNET_free (buf); GNUNET_free (buf);
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"malformed binary data in JSON", "malformed binary data in JSON",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -603,12 +603,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"malformed RSA public key in JSON", "malformed RSA public key in JSON",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -630,12 +630,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"string expected", "string expected",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -650,12 +650,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
GNUNET_free (buf); GNUNET_free (buf);
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"malformed binary data in JSON", "malformed binary data in JSON",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -666,12 +666,12 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}", "{s:s, s:o}",
"error", "error",
"malformed RSA signature in JSON", "malformed RSA signature in JSON",
"path", "path",
path)) path))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -684,8 +684,22 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
struct TALER_Amount *where = va_arg (argp, void *); struct TALER_Amount *where = va_arg (argp, void *);
ret = TMH_PARSE_amount_json (connection, ret = TMH_PARSE_amount_json (connection,
(json_t *) root, (json_t *) root,
where); where);
break;
}
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
{
struct GNUNET_TIME_Absolute *where = va_arg (argp, void *);
#if 0
ret = TMH_PARSE_time_abs_json (connection,
(json_t *) root,
where);
#endif
GNUNET_assert (0); /* FIXME: not implemented (#3741) */
(void) where;
ret = GNUNET_SYSERR;
break; break;
} }
@ -693,7 +707,7 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
GNUNET_break (0); GNUNET_break (0);
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_internal_error (connection, TMH_RESPONSE_reply_internal_error (connection,
"unhandled value in switch")) "unhandled value in switch"))
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
@ -742,64 +756,74 @@ TMH_PARSE_json_data (struct MHD_Connection *connection,
return GNUNET_SYSERR; return GNUNET_SYSERR;
case TMH_PARSE_JNC_RET_DATA: case TMH_PARSE_JNC_RET_DATA:
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_DATA, TMH_PARSE_JNC_RET_DATA,
spec[i].destination, spec[i].destination,
spec[i].destination_size_in); spec[i].destination_size_in);
break; break;
case TMH_PARSE_JNC_RET_DATA_VAR: case TMH_PARSE_JNC_RET_DATA_VAR:
ptr = NULL; ptr = NULL;
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_DATA_VAR, TMH_PARSE_JNC_RET_DATA_VAR,
&ptr, &ptr,
&spec[i].destination_size_out); &spec[i].destination_size_out);
spec[i].destination = ptr; spec[i].destination = ptr;
break; break;
case TMH_PARSE_JNC_RET_TYPED_JSON: case TMH_PARSE_JNC_RET_TYPED_JSON:
ptr = NULL; ptr = NULL;
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_TYPED_JSON, TMH_PARSE_JNC_RET_TYPED_JSON,
spec[i].type, spec[i].type,
&ptr); &ptr);
*((void**)spec[i].destination) = ptr; *((void**)spec[i].destination) = ptr;
break; break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
ptr = NULL; ptr = NULL;
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
&ptr); &ptr);
spec[i].destination = ptr; spec[i].destination = ptr;
break; break;
case TMH_PARSE_JNC_RET_RSA_SIGNATURE: case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
ptr = NULL; ptr = NULL;
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_RSA_SIGNATURE, TMH_PARSE_JNC_RET_RSA_SIGNATURE,
&ptr); &ptr);
spec[i].destination = ptr; spec[i].destination = ptr;
break; break;
case TMH_PARSE_JNC_RET_AMOUNT: case TMH_PARSE_JNC_RET_AMOUNT:
GNUNET_assert (sizeof (struct TALER_Amount) == GNUNET_assert (sizeof (struct TALER_Amount) ==
spec[i].destination_size_in); spec[i].destination_size_in);
ret = TMH_PARSE_navigate_json (connection, ret = TMH_PARSE_navigate_json (connection,
root, root,
TMH_PARSE_JNC_FIELD, TMH_PARSE_JNC_FIELD,
spec[i].field_name, spec[i].field_name,
TMH_PARSE_JNC_RET_AMOUNT, TMH_PARSE_JNC_RET_AMOUNT,
&spec[i].destination); &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; break;
} }
} }
@ -870,6 +894,8 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
0, 0,
sizeof (struct TALER_Amount)); sizeof (struct TALER_Amount));
break; break;
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
break;
} }
} }
} }
@ -888,8 +914,8 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
*/ */
int int
TMH_PARSE_amount_json (struct MHD_Connection *connection, TMH_PARSE_amount_json (struct MHD_Connection *connection,
json_t *f, json_t *f,
struct TALER_Amount *amount) struct TALER_Amount *amount)
{ {
json_int_t value; json_int_t value;
json_int_t fraction; json_int_t fraction;
@ -907,9 +933,9 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to parse JSON amount specification\n"); TALER_LOG_WARNING ("Failed to parse JSON amount specification\n");
if (MHD_YES != if (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s}", "{s:s}",
"error", "Bad format")) "error", "Bad format"))
return GNUNET_SYSERR; return GNUNET_SYSERR;
return GNUNET_NO; return GNUNET_NO;
} }
@ -921,9 +947,9 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Amount specified not in allowed range\n"); TALER_LOG_WARNING ("Amount specified not in allowed range\n");
if (MHD_YES != if (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s}", "{s:s}",
"error", "Amount outside of allowed range")) "error", "Amount outside of allowed range"))
return GNUNET_SYSERR; return GNUNET_SYSERR;
return GNUNET_NO; return GNUNET_NO;
} }
@ -933,10 +959,10 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Currency specified not supported by this mint\n"); TALER_LOG_WARNING ("Currency specified not supported by this mint\n");
if (MHD_YES != if (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
"{s:s, s:s}", "{s:s, s:s}",
"error", "Currency not supported", "error", "Currency not supported",
"currency", currency)) "currency", currency))
return GNUNET_SYSERR; return GNUNET_SYSERR;
return GNUNET_NO; return GNUNET_NO;
} }

View File

@ -126,7 +126,14 @@ enum TMH_PARSE_JsonNavigationCommand
* Return a `struct TALER_Amount` which was * Return a `struct TALER_Amount` which was
* encoded within its own json object. * encoded within its own json object.
*/ */
TMH_PARSE_JNC_RET_AMOUNT 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
}; };
@ -215,8 +222,8 @@ struct TMH_PARSE_FieldSpecification
*/ */
int int
TMH_PARSE_json_data (struct MHD_Connection *connection, TMH_PARSE_json_data (struct MHD_Connection *connection,
const json_t *root, const json_t *root,
struct TMH_PARSE_FieldSpecification *spec); struct TMH_PARSE_FieldSpecification *spec);
/** /**
@ -284,6 +291,14 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec);
*/ */
#define TMH_PARSE_MEMBER_AMOUNT(field,amount) { field, amount, sizeof(*amount), 0, TMH_PARSE_JNC_RET_AMOUNT, 0 } #define TMH_PARSE_MEMBER_AMOUNT(field,amount) { field, amount, sizeof(*amount), 0, TMH_PARSE_JNC_RET_AMOUNT, 0 }
/**
* Generate line in parser specification for an absolute time.
*
* @param field name of the field
* @param atime a `struct GNUNET_TIME_Absolute *` to initialize
*/
#define TMH_PARSE_MEMBER_TIME_ABS(field,atime) { field, atime, sizeof(*atime), 0, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 }
/** /**
* Generate line in parser specification indicating the end of the spec. * Generate line in parser specification indicating the end of the spec.
*/ */

View File

@ -348,9 +348,14 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
dr.h_contract = deposit->h_contract; dr.h_contract = deposit->h_contract;
dr.h_wire = deposit->h_wire; dr.h_wire = deposit->h_wire;
dr.timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline);
dr.transaction_id = GNUNET_htonll (deposit->transaction_id); dr.transaction_id = GNUNET_htonll (deposit->transaction_id);
TALER_amount_hton (&dr.amount_with_fee, TALER_amount_hton (&dr.amount_with_fee,
&deposit->amount_with_fee); &deposit->amount_with_fee);
TALER_amount_hton (&dr.deposit_fee,
&deposit->deposit_fee);
dr.merchant = deposit->merchant_pub;
dr.coin_pub = deposit->coin.coin_pub; dr.coin_pub = deposit->coin.coin_pub;
transaction = TALER_json_from_ecdsa_sig (&dr.purpose, transaction = TALER_json_from_ecdsa_sig (&dr.purpose,
&deposit->csig.ecdsa_signature); &deposit->csig.ecdsa_signature);