switching /withdraw/sign from GET to POST

This commit is contained in:
Christian Grothoff 2015-03-29 14:17:52 +02:00
parent 3991cd1763
commit 42147c2501
6 changed files with 125 additions and 134 deletions

View File

@ -137,54 +137,63 @@ handle_mhd_request (void *cls,
{ "/agpl", MHD_HTTP_METHOD_GET, "text/plain", { "/agpl", MHD_HTTP_METHOD_GET, "text/plain",
NULL, 0, NULL, 0,
&TMH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND }, &TMH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND },
{ "/keys", MHD_HTTP_METHOD_GET, "application/json", { "/keys", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0, NULL, 0,
&TMH_KS_handler_keys, MHD_HTTP_OK }, &TMH_KS_handler_keys, MHD_HTTP_OK },
{ "/keys", NULL, "text/plain", { "/keys", NULL, "text/plain",
"Only GET is allowed", 0, "Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/withdraw/status", MHD_HTTP_METHOD_GET, "application/json", { "/withdraw/status", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0, NULL, 0,
&TMH_WITHDRAW_handler_withdraw_status, MHD_HTTP_OK }, &TMH_WITHDRAW_handler_withdraw_status, MHD_HTTP_OK },
{ "/withdraw/status", NULL, "text/plain", { "/withdraw/status", NULL, "text/plain",
"Only GET is allowed", 0, "Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/withdraw/sign", MHD_HTTP_METHOD_GET, "application/json",
{ "/withdraw/sign", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0, NULL, 0,
&TMH_WITHDRAW_handler_withdraw_sign, MHD_HTTP_OK }, &TMH_WITHDRAW_handler_withdraw_sign, MHD_HTTP_OK },
{ "/withdraw/sign", NULL, "text/plain", { "/withdraw/sign", NULL, "text/plain",
"Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/melt", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_melt, MHD_HTTP_OK },
{ "/refresh/melt", NULL, "text/plain",
"Only POST is allowed", 0, "Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_melt, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/link", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_link, MHD_HTTP_OK },
{ "/refresh/link", NULL, "text/plain",
"Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_reveal, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/deposit", MHD_HTTP_METHOD_POST, "application/json", { "/deposit", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0, NULL, 0,
&TMH_DEPOSIT_handler_deposit, MHD_HTTP_OK }, &TMH_DEPOSIT_handler_deposit, MHD_HTTP_OK },
{ "/deposit", NULL, "text/plain", { "/deposit", NULL, "text/plain",
"Only POST is allowed", 0, "Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/melt", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_melt, MHD_HTTP_OK },
{ "/refresh/melt", NULL, "text/plain",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_melt, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_reveal, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/link", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TMH_REFRESH_handler_refresh_link, MHD_HTTP_OK },
{ "/refresh/link", NULL, "text/plain",
"Only GET is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ NULL, NULL, NULL, NULL, 0, 0 } { NULL, NULL, NULL, NULL, 0, 0 }
}; };
static struct TMH_RequestHandler h404 = static struct TMH_RequestHandler h404 =

View File

@ -144,8 +144,8 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
struct TALER_MINTDB_DenominationKeyIssueInformation *dki; struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
struct TMH_KS_StateHandle *ks; struct TMH_KS_StateHandle *ks;
struct TMH_PARSE_FieldSpecification spec[] = { struct TMH_PARSE_FieldSpecification spec[] = {
TMH_PARSE_MEMBER_RSA_PUBLIC_KEY ("denom_pub", &deposit.coin.denom_pub), TMH_PARSE_MEMBER_DENOMINATION_PUBLIC_KEY ("denom_pub", &deposit.coin.denom_pub),
TMH_PARSE_MEMBER_RSA_SIGNATURE ("ubsig", &deposit.coin.denom_sig), TMH_PARSE_MEMBER_DENOMINATION_SIGNATURE ("ubsig", &deposit.coin.denom_sig),
TMH_PARSE_MEMBER_FIXED ("coin_pub", &deposit.coin.coin_pub), TMH_PARSE_MEMBER_FIXED ("coin_pub", &deposit.coin.coin_pub),
TMH_PARSE_MEMBER_FIXED ("merchant_pub", &deposit.merchant_pub), TMH_PARSE_MEMBER_FIXED ("merchant_pub", &deposit.merchant_pub),
TMH_PARSE_MEMBER_FIXED ("H_a", &deposit.h_contract), TMH_PARSE_MEMBER_FIXED ("H_a", &deposit.h_contract),

View File

@ -555,13 +555,14 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
{ {
void **where = va_arg (argp, void **); struct TALER_DenominationPublicKey *where;
size_t len; size_t len;
const char *str; const char *str;
int res; int res;
void *buf; void *buf;
// FIXME: avoidable code duplication here... where = va_arg (argp,
struct TALER_DenominationPublicKey *);
str = json_string_value (root); str = json_string_value (root);
if (NULL == str) if (NULL == str)
{ {
@ -596,10 +597,10 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
*where = GNUNET_CRYPTO_rsa_public_key_decode (buf, where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf,
len); len);
GNUNET_free (buf); GNUNET_free (buf);
if (NULL == *where) if (NULL == where->rsa_public_key)
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
@ -618,13 +619,14 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
case TMH_PARSE_JNC_RET_RSA_SIGNATURE: case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
{ {
void **where = va_arg (argp, void **); struct TALER_DenominationSignature *where;
size_t len; size_t len;
const char *str; const char *str;
int res; int res;
void *buf; void *buf;
// FIXME: avoidable code duplication here... where = va_arg (argp,
struct TALER_DenominationSignature *);
str = json_string_value (root); str = json_string_value (root);
if (NULL == str) if (NULL == str)
{ {
@ -659,10 +661,10 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
break; break;
} }
*where = GNUNET_CRYPTO_rsa_signature_decode (buf, where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf,
len); len);
GNUNET_free (buf); GNUNET_free (buf);
if (NULL == *where) if (NULL == where->rsa_signature)
{ {
ret = (MHD_YES == ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection, TMH_RESPONSE_reply_json_pack (connection,
@ -874,19 +876,27 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
} }
break; break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
ptr = *(void **) spec[i].destination;
if (NULL != ptr)
{ {
GNUNET_CRYPTO_rsa_public_key_free (ptr); struct TALER_DenominationPublicKey pk;
*(void**) spec[i].destination = NULL;
pk = *(struct TALER_DenominationPublicKey *) 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; break;
case TMH_PARSE_JNC_RET_RSA_SIGNATURE: case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
ptr = *(void **) spec[i].destination;
if (NULL != ptr)
{ {
GNUNET_CRYPTO_rsa_signature_free (ptr); struct TALER_DenominationSignature sig;
*(void**) spec[i].destination = NULL;
sig = *(struct TALER_DenominationSignature *) spec[i].destination;
if (NULL != sig.rsa_signature)
{
GNUNET_CRYPTO_rsa_signature_free (sig.rsa_signature);
sig.rsa_signature = NULL;
}
} }
break; break;
case TMH_PARSE_JNC_RET_AMOUNT: case TMH_PARSE_JNC_RET_AMOUNT:

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014 GNUnet e.V. Copyright (C) 2014, 2015 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU Affero General Public License as published by the Free Software
@ -271,17 +271,17 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec);
* Generate line in parser specification for RSA public key. * Generate line in parser specification for RSA public key.
* *
* @param field name of the field * @param field name of the field
* @param ptrpk address of `struct GNUNET_CRYPTO_rsa_PublicKey *` initialize * @param ptrpk address of `struct TALER_DenominationPublicKey` initialize
*/ */
#define TMH_PARSE_MEMBER_RSA_PUBLIC_KEY(field,ptrpk) { field, ptrpk, 0, 0, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 } #define TMH_PARSE_MEMBER_DENOMINATION_PUBLIC_KEY(field,ptrpk) { field, ptrpk, 0, 0, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 }
/** /**
* Generate line in parser specification for RSA public key. * Generate line in parser specification for RSA public key.
* *
* @param field name of the field * @param field name of the field
* @param ptrsig address of `struct GNUNET_CRYPTO_rsa_Signature *` initialize * @param ptrsig address of `struct TALER_DenominationSignature *` initialize
*/ */
#define TMH_PARSE_MEMBER_RSA_SIGNATURE(field,ptrsig) { field, ptrsig, 0, 0, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 } #define TMH_PARSE_MEMBER_DENOMINATION_SIGNATURE(field,ptrsig) { field, ptrsig, 0, 0, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 }
/** /**
* Generate line in parser specification for an amount. * Generate line in parser specification for an amount.

View File

@ -176,8 +176,8 @@ get_coin_public_info (struct MHD_Connection *connection,
struct TALER_Amount amount; struct TALER_Amount amount;
struct TMH_PARSE_FieldSpecification spec[] = { struct TMH_PARSE_FieldSpecification spec[] = {
TMH_PARSE_MEMBER_FIXED ("coin_pub", &r_melt_detail->coin_info.coin_pub), TMH_PARSE_MEMBER_FIXED ("coin_pub", &r_melt_detail->coin_info.coin_pub),
TMH_PARSE_MEMBER_RSA_SIGNATURE ("denom_sig", &sig.rsa_signature), TMH_PARSE_MEMBER_DENOMINATION_SIGNATURE ("denom_sig", &sig.rsa_signature),
TMH_PARSE_MEMBER_RSA_PUBLIC_KEY ("denom_pub", &pk.rsa_public_key), TMH_PARSE_MEMBER_DENOMINATION_PUBLIC_KEY ("denom_pub", &pk.rsa_public_key),
TMH_PARSE_MEMBER_FIXED ("confirm_sig", &melt_sig), TMH_PARSE_MEMBER_FIXED ("confirm_sig", &melt_sig),
TMH_PARSE_MEMBER_AMOUNT ("value_with_fee", &amount), TMH_PARSE_MEMBER_AMOUNT ("value_with_fee", &amount),
TMH_PARSE_MEMBER_END TMH_PARSE_MEMBER_END
@ -884,7 +884,8 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
/** /**
* Handle a "/refresh/link" request * Handle a "/refresh/link" request. Note that for "/refresh/link"
* we do use a simple HTTP GET, and a HTTP POST!
* *
* @param rh context of the handler * @param rh context of the handler
* @param connection the MHD connection to handle * @param connection the MHD connection to handle
@ -911,7 +912,6 @@ TMH_REFRESH_handler_refresh_link (struct TMH_RequestHandler *rh,
return MHD_NO; return MHD_NO;
if (GNUNET_OK != res) if (GNUNET_OK != res)
return MHD_YES; return MHD_YES;
return TMH_DB_execute_refresh_link (connection, return TMH_DB_execute_refresh_link (connection,
&coin_pub); &coin_pub);
} }

View File

@ -88,12 +88,11 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
json_t *root;
struct TALER_WithdrawRequestPS wsrd; struct TALER_WithdrawRequestPS wsrd;
int res; int res;
struct TALER_DenominationPublicKey denomination_pub; struct TALER_DenominationPublicKey denomination_pub;
char *denomination_pub_data; const char *blinded_msg;
size_t denomination_pub_data_size;
char *blinded_msg;
size_t blinded_msg_len; size_t blinded_msg_len;
struct TALER_Amount amount; struct TALER_Amount amount;
struct TALER_Amount amount_with_fee; struct TALER_Amount amount_with_fee;
@ -102,53 +101,37 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
struct TALER_MINTDB_DenominationKeyIssueInformation *dki; struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
struct TMH_KS_StateHandle *ks; struct TMH_KS_StateHandle *ks;
res = TMH_PARSE_mhd_request_arg_data (connection, struct TMH_PARSE_FieldSpecification spec[] = {
"reserve_pub", TMH_PARSE_MEMBER_VARIABLE ("coin_ev"),
&wsrd.reserve_pub, TMH_PARSE_MEMBER_FIXED ("reserve_pub", &wsrd.reserve_pub),
sizeof (struct TALER_ReservePublicKeyP)); TMH_PARSE_MEMBER_FIXED ("reserve_sig", &signature),
TMH_PARSE_MEMBER_DENOMINATION_PUBLIC_KEY ("denom_pub", &denomination_pub),
TMH_PARSE_MEMBER_END
};
res = TMH_PARSE_post_json (connection,
connection_cls,
upload_data,
upload_data_size,
&root);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */ return MHD_NO;
if (GNUNET_NO == res) if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES; /* invalid request */ return MHD_YES;
res = TMH_PARSE_mhd_request_arg_data (connection, res = TMH_PARSE_json_data (connection,
"reserve_sig", root,
&signature, spec);
sizeof (struct TALER_ReserveSignatureP)); json_decref (root);
if (GNUNET_SYSERR == res) if (GNUNET_OK != res)
return MHD_NO; /* internal error */ return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
if (GNUNET_NO == res) blinded_msg = spec[0].destination;
return MHD_YES; /* invalid request */ blinded_msg_len = spec[0].destination_size_out;
res = TMH_PARSE_mhd_request_var_arg_data (connection,
"denom_pub",
(void **) &denomination_pub_data,
&denomination_pub_data_size);
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* invalid request */
res = TMH_PARSE_mhd_request_var_arg_data (connection,
"coin_ev",
(void **) &blinded_msg,
&blinded_msg_len);
if (GNUNET_SYSERR == res)
{
GNUNET_free (denomination_pub_data);
return MHD_NO; /* internal error */
}
if (GNUNET_NO == res)
{
GNUNET_free (denomination_pub_data);
return MHD_YES; /* invalid request */
}
denomination_pub.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_decode (denomination_pub_data,
denomination_pub_data_size);
ks = TMH_KS_acquire (); ks = TMH_KS_acquire ();
dki = TMH_KS_denomination_key_lookup (ks, dki = TMH_KS_denomination_key_lookup (ks,
&denomination_pub); &denomination_pub);
if (NULL == dki) if (NULL == dki)
{ {
GNUNET_free (denomination_pub_data); TMH_PARSE_release_data (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"denom_pub"); "denom_pub");
} }
@ -168,8 +151,8 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
/* verify signature! */ /* verify signature! */
wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS)); wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
GNUNET_CRYPTO_hash (denomination_pub_data,
denomination_pub_data_size, GNUNET_CRYPTO_rsa_public_key_hash (denomination_pub.rsa_public_key,
&wsrd.h_denomination_pub); &wsrd.h_denomination_pub);
GNUNET_CRYPTO_hash (blinded_msg, GNUNET_CRYPTO_hash (blinded_msg,
blinded_msg_len, blinded_msg_len,
@ -181,28 +164,17 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
&wsrd.reserve_pub.eddsa_pub)) &wsrd.reserve_pub.eddsa_pub))
{ {
TALER_LOG_WARNING ("Client supplied invalid signature for /withdraw/sign request\n"); TALER_LOG_WARNING ("Client supplied invalid signature for /withdraw/sign request\n");
GNUNET_free (denomination_pub_data); TMH_PARSE_release_data (spec);
GNUNET_free (blinded_msg);
GNUNET_CRYPTO_rsa_public_key_free (denomination_pub.rsa_public_key);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"reserve_sig"); "reserve_sig");
} }
GNUNET_free (denomination_pub_data);
if (NULL == denomination_pub.rsa_public_key)
{
TALER_LOG_WARNING ("Client supplied ill-formed denomination public key for /withdraw/sign request\n");
GNUNET_free (blinded_msg);
return TMH_RESPONSE_reply_arg_invalid (connection,
"denom_pub");
}
res = TMH_DB_execute_withdraw_sign (connection, res = TMH_DB_execute_withdraw_sign (connection,
&wsrd.reserve_pub, &wsrd.reserve_pub,
&denomination_pub, &denomination_pub,
blinded_msg, blinded_msg,
blinded_msg_len, blinded_msg_len,
&signature); &signature);
GNUNET_free (blinded_msg); TMH_PARSE_release_data (spec);
GNUNET_CRYPTO_rsa_public_key_free (denomination_pub.rsa_public_key);
return res; return res;
} }