diff options
Diffstat (limited to 'src/mint')
-rw-r--r-- | src/mint/taler-mint-httpd_db.c | 8 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 17 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_keystate.c | 1 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_parsing.c | 95 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_parsing.h | 30 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_responses.c | 21 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_responses.h | 5 |
7 files changed, 122 insertions, 55 deletions
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 5afc104f5..2ac3defde 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -126,6 +126,7 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection, &deposit->h_wire, &deposit->h_contract, deposit->transaction_id, + deposit->timestamp, deposit->refund_deadline, &deposit->merchant_pub, &amount_without_fee); @@ -194,14 +195,19 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection, TALER_LOG_WARNING ("/deposit transaction commit failed\n"); return TMH_RESPONSE_reply_commit_error (connection); } + GNUNET_assert (GNUNET_OK == + TALER_amount_subtract (&amount_without_fee, + &deposit->amount_with_fee, + &deposit->deposit_fee)); return TMH_RESPONSE_reply_deposit_success (connection, &deposit->coin.coin_pub, &deposit->h_wire, &deposit->h_contract, deposit->transaction_id, + deposit->timestamp, deposit->refund_deadline, &deposit->merchant_pub, - &deposit->amount_with_fee); + &amount_without_fee); } diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index 19ea9cb50..782d05a8b 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -101,14 +101,12 @@ verify_and_execute_deposit (struct MHD_Connection *connection, } TALER_amount_ntoh (&fee_deposit, &dki->issue.fee_deposit); - if (TALER_amount_cmp (&fee_deposit, - &deposit->amount_with_fee) < 0) + if (0 < TALER_amount_cmp (&fee_deposit, + &deposit->amount_with_fee)) { TMH_KS_release (key_state); - return (MHD_YES == - TMH_RESPONSE_reply_external_error (connection, - "deposited amount smaller than depositing fee")) - ? GNUNET_NO : GNUNET_SYSERR; + return TMH_RESPONSE_reply_external_error (connection, + "deposited amount smaller than depositing fee"); } TMH_KS_release (key_state); @@ -146,7 +144,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, 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_FIXED ("transaction_id", &deposit.transaction_id), + 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_END @@ -160,6 +158,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, return MHD_NO; /* hard failure */ if (GNUNET_NO == res) return MHD_YES; /* failure */ + if (GNUNET_YES != TALER_json_validate_wireformat (TMH_expected_wire_format, wire)) @@ -197,7 +196,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, &deposit.deposit_fee)) { /* Total amount smaller than fee, invalid */ - TMH_PARSE_release_data (spec); + TMH_PARSE_release_data (spec); return TMH_RESPONSE_reply_arg_invalid (connection, "f"); } @@ -247,7 +246,7 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh, if ( (GNUNET_NO == res) || (NULL == json) ) return MHD_YES; if (-1 == json_unpack (json, - "{s:s, s:o, f:o}", + "{s:o, s:o}", "wire", &wire, "f", &f)) { diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c index 2e81c8064..096023ac5 100644 --- a/src/mint/taler-mint-httpd_keystate.c +++ b/src/mint/taler-mint-httpd_keystate.c @@ -494,6 +494,7 @@ TMH_KS_acquire (void) key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); key_state->reload_time = GNUNET_TIME_absolute_get (); + TALER_round_abs_time (&key_state->reload_time); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Loading keys from `%s'\n", TMH_mint_directory); diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index 1a4215ba0..c5827da7e 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c @@ -549,6 +549,28 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection, } break; + case TMH_PARSE_JNC_RET_UINT64: + { + uint64_t *r_u64 = va_arg (argp, uint64_t *); + + if (json_typeof (root) != JSON_INTEGER) + { + 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; @@ -803,6 +825,16 @@ TMH_PARSE_json_data (struct MHD_Connection *connection, 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 (GNUNET_YES != ret) @@ -882,6 +914,8 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec) break; case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: break; + case TMH_PARSE_JNC_RET_UINT64: + break; } } } @@ -889,8 +923,9 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec) /** * Parse absolute time specified in JSON format. The JSON format is - * "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we - * support "/forever/" to represent the end of time. + * "/Date(TIMEVAL)/" where TIMEVAL is in seconds after the Unix Epoch. + * Additionally, we support "/forever/" and "/never/" to represent the + * end of time. * * @param connection the MHD connection (to report errors) * @param f json specification of the amount @@ -906,9 +941,7 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection, struct GNUNET_TIME_Absolute *time) { const char *val; - size_t slen; - unsigned long long int tval; - char *endp; + unsigned long long tval; val = json_string_value (f); if (NULL == val) @@ -921,30 +954,18 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection, return GNUNET_SYSERR; return GNUNET_NO; } - slen = strlen (val); - if ( (slen <= 2) || - ('/' != val[0]) || - ('/' != val[slen - 1]) ) - { - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", - "error", "timestamp expected", - "value", val)) - return GNUNET_SYSERR; - return GNUNET_NO; - } - if (0 == strcasecmp (val, - "/forever/")) + if ( (0 == strcasecmp (val, + "/forever/")) || + (0 == strcasecmp (val, + "/never/")) ) + { *time = GNUNET_TIME_UNIT_FOREVER_ABS; return GNUNET_OK; } - tval = strtoull (&val[1], - &endp, - 10); - if (&val[slen - 1] != endp) + if (1 != sscanf (val, + "/Date(%llu)/", + &tval)) { if (MHD_YES != TMH_RESPONSE_reply_json_pack (connection, @@ -955,9 +976,9 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection, return GNUNET_SYSERR; return GNUNET_NO; } - /* Time is in 'ms' in JSON, but in microseconds in GNUNET_TIME_Absolute */ - time->abs_value_us = tval * 1000LL; - if ( (time->abs_value_us) / 1000LL != tval) + /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ + time->abs_value_us = tval * 1000LL * 1000LL; + if ( (time->abs_value_us) / 1000LL / 1000LL != tval) { /* Integer overflow */ if (MHD_YES != @@ -1048,6 +1069,24 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection, /** + * 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), 0, TMH_PARSE_JNC_RET_UINT64, 0 }; + return ret; +} + + +/** * Generate line in parser specification for JSON object value. * * @param field name of the field diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h index 44e74d27c..7d37bb18c 100644 --- a/src/mint/taler-mint-httpd_parsing.h +++ b/src/mint/taler-mint-httpd_parsing.h @@ -133,7 +133,14 @@ enum TMH_PARSE_JsonNavigationCommand * encoded within its own json object. * Param: struct GNUNET_TIME_Absolute * */ - TMH_PARSE_JNC_RET_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 }; @@ -254,10 +261,23 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec); /** + * 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 ptraddr address of JSON pointer to initialize + * @param[out] jsonp address of JSON pointer to initialize * @return corresponding field spec */ struct TMH_PARSE_FieldSpecification @@ -269,7 +289,7 @@ TMH_PARSE_member_array (const char *field, * Generate line in parser specification for JSON object value. * * @param field name of the field - * @param jsonp address of pointer to JSON to initialize + * @param[out] jsonp address of pointer to JSON to initialize * @return corresponding field spec */ struct TMH_PARSE_FieldSpecification @@ -351,8 +371,8 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection, /** * Parse absolute time specified in JSON format. The JSON format is - * "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we - * support "/forever/" to represent the end of time. + * "/TIMEVAL/" where TIMEVAL is in seconds. Additionally, we + * support "/forever/" and "/never/" to represent the end of time. * * @param connection the MHD connection (to report errors) * @param f json specification of the amount diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index f36369984..bb7a72f8e 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -330,6 +330,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection) * @param h_wire hash of wire details * @param h_contract hash of contract details * @param transaction_id transaction ID + * @param timestamp client's timestamp * @param refund_deadline until when this deposit be refunded * @param merchant merchant public key * @param amount_without_fee fraction of coin value to deposit, without the fee @@ -341,6 +342,7 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, + struct GNUNET_TIME_Absolute timestamp, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_MerchantPublicKeyP *merchant, const struct TALER_Amount *amount_without_fee) @@ -348,14 +350,13 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, struct TALER_DepositConfirmationPS dc; struct TALER_MintSignatureP sig; json_t *sig_json; - int ret; dc.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_DEPOSIT); dc.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)); dc.h_contract = *h_contract; dc.h_wire = *h_wire; dc.transaction_id = GNUNET_htonll (transaction_id); - dc.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); + dc.timestamp = GNUNET_TIME_absolute_hton (timestamp); dc.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline); TALER_amount_hton (&dc.amount_without_fee, amount_without_fee); @@ -363,15 +364,13 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, dc.merchant = *merchant; TMH_KS_sign (&dc.purpose, &sig); - sig_json = TALER_json_from_eddsa_sig (&dc.purpose, - &sig.eddsa_signature); - ret = TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:s, s:o}", - "status", "DEPOSIT_OK", - "signature", sig_json); - json_decref (sig_json); - return ret; + sig_json = TALER_json_from_data (&sig, + sizeof (sig)); + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s, s:o}", + "status", "DEPOSIT_OK", + "sig", sig_json); } diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h index 1f8e1e44c..7afd01884 100644 --- a/src/mint/taler-mint-httpd_responses.h +++ b/src/mint/taler-mint-httpd_responses.h @@ -205,6 +205,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection); * @param h_wire hash of wire details * @param h_contract hash of contract details * @param transaction_id transaction ID + * @param timestamp client's timestamp * @param refund_deadline until when this deposit be refunded * @param merchant merchant public key * @param amount_without_fee fraction of coin value to deposit (without fee) @@ -216,7 +217,9 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, - struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_MerchantPublicKeyP *merchant, + struct GNUNET_TIME_Absolute timestamp, + struct GNUNET_TIME_Absolute refund_deadline, + const struct TALER_MerchantPublicKeyP *merchant, const struct TALER_Amount *amount_without_fee); |