diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 308 |
1 files changed, 162 insertions, 146 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c index 1d084174..0370dedf 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -277,7 +277,7 @@ struct TokenEnvelope /** * Blinded token use public keys waiting to be signed. */ - struct TALER_TokenEnvelopeP blinded_token; + struct TALER_TokenEnvelope blinded_token; }; @@ -1473,10 +1473,11 @@ phase_batch_deposits (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED, - "Failed to lookup exchange by URL")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED, + "Failed to lookup exchange by URL")); return; } pc->pending_at_eg++; @@ -2312,7 +2313,7 @@ find_valid_input_tokens (struct PayContext *pc, unsigned int index, unsigned int expected_num) { - int num_validated = 0; + unsigned int num_validated = 0; struct TokenUseConfirmation *tuc = NULL; for (unsigned int j = 0; j < expected_num; j++) @@ -2327,19 +2328,20 @@ find_valid_input_tokens (struct PayContext *pc, GNUNET_TIME_timestamp2s (key->valid_after)); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "'tokens' array is missing " - "required input token")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "'tokens' array is missing required input token")); return GNUNET_NO; } tuc->h_issue.hash = key->pub.public_key->pub_key_hash; - if (GNUNET_OK != TALER_token_issue_verify (&tuc->pub, - &key->pub, - &tuc->unblinded_sig)) + if (GNUNET_OK != + TALER_token_issue_verify (&tuc->pub, + &key->pub, + &tuc->unblinded_sig)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Input token for public key with valid_after " @@ -2347,17 +2349,19 @@ find_valid_input_tokens (struct PayContext *pc, GNUNET_TIME_timestamp2s (key->valid_after)); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ISSUE_SIG_INVALID, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ISSUE_SIG_INVALID, + NULL)); return GNUNET_NO; } - if (GNUNET_OK != TALER_wallet_token_use_verify (&pc->h_contract_terms, - &pc->h_wallet_data, - &tuc->pub, - &tuc->sig)) + if (GNUNET_OK != + TALER_wallet_token_use_verify (&pc->h_contract_terms, + &pc->h_wallet_data, + &tuc->pub, + &tuc->sig)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Input token for public key with valid_after " @@ -2365,10 +2369,11 @@ find_valid_input_tokens (struct PayContext *pc, GNUNET_TIME_timestamp2s (key->valid_after)); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID, + NULL)); return GNUNET_NO; } @@ -2385,10 +2390,11 @@ find_valid_input_tokens (struct PayContext *pc, num_validated); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_COUNT_MISMATCH, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_COUNT_MISMATCH, + NULL)); return GNUNET_NO; } @@ -2404,46 +2410,38 @@ sign_token_envelopes (struct PayContext *pc, unsigned int index, unsigned int expected_num) { - int num_signed = 0; + unsigned int num_signed = 0; for (unsigned int j = 0; j<expected_num; j++) { unsigned int pos = index + j; + const struct TokenEnvelope *env = &pc->token_envelopes[pos]; + struct SignedOutputToken *output = &pc->output_tokens[pos]; if (pos > pc->token_envelopes_cnt || pos > pc->output_tokens_len) { GNUNET_assert (0); /* this should not happen */ return GNUNET_NO; } - - struct TokenEnvelope *env = &pc->token_envelopes[pos]; - - if (NULL == env) + if (NULL == env->blinded_token.blinded_pub) { if (! critical) - { continue; - } /* critical token families require a token envelope. */ - GNUNET_break (0); + GNUNET_break_op (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "Token envelope for critical " - "token family missing")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "Token envelope for critical token family missing")); return GNUNET_NO; } - - struct SignedOutputToken *output = &pc->output_tokens[pos]; - TALER_token_issue_sign (priv, &env->blinded_token, &output->sig); - output->h_issue.hash = key->pub.public_key->pub_key_hash; - num_signed++; } @@ -2457,10 +2455,11 @@ sign_token_envelopes (struct PayContext *pc, num_signed); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ENVELOPE_COUNT_MISMATCH, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ENVELOPE_COUNT_MISMATCH, + NULL)); return GNUNET_NO; } @@ -2469,9 +2468,10 @@ sign_token_envelopes (struct PayContext *pc, /** - * Validate tokens and token envelopes. First, we check if all tokens listed in - * the 'inputs' array of the selected choice are present in the 'tokens' array - * of the request. Then, we validate the signatures of each provided token. + * Validate tokens and token envelopes. First, we check if all tokens listed + * in the 'inputs' array of the selected choice are present in the 'tokens' + * array of the request. Then, we validate the signatures of each provided + * token. * * @param[in,out] pc context we use to handle the payment */ @@ -2493,10 +2493,11 @@ phase_validate_tokens (struct PayContext *pc) pc->order_id); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISSING, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISSING, + NULL)); return; } @@ -2510,10 +2511,11 @@ phase_validate_tokens (struct PayContext *pc) pc->choice_index); GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_OUT_OF_BOUNDS, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_OUT_OF_BOUNDS, + NULL)); return; } @@ -2535,23 +2537,25 @@ phase_validate_tokens (struct PayContext *pc) } /* TODO: Replace this with ordering convention. */ - if (GNUNET_OK != TMH_find_token_family_key (input.details.token. - token_family_slug, - input.details.token. - valid_after, - pc->token_families, - pc->token_families_len, - &family, - &key)) + if (GNUNET_OK != + TMH_find_token_family_key (input.details.token. + token_family_slug, + input.details.token. + valid_after, + pc->token_families, + pc->token_families_len, + &family, + &key)) { /* this should never happen, since the choices and token families are validated on insert. */ GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL)); return; } @@ -2603,14 +2607,15 @@ phase_validate_tokens (struct PayContext *pc) continue; } - if (GNUNET_OK != TMH_find_token_family_key (output.details.token. - token_family_slug, - output.details.token. - valid_after, - pc->token_families, - pc->token_families_len, - &family, - &key)) + if (GNUNET_OK != + TMH_find_token_family_key (output.details.token. + token_family_slug, + output.details.token. + valid_after, + pc->token_families, + pc->token_families_len, + &family, + &key)) { /* this should never happen, since the choices and token families are validated on insert. */ @@ -2643,14 +2648,15 @@ phase_validate_tokens (struct PayContext *pc) GNUNET_assert (NULL != details.priv.private_key); - if (GNUNET_OK != sign_token_envelopes (pc, - &key, - &details.priv, - /* TODO: Use critical field stored in database here instead. */ - details.token_family.kind == - TALER_MERCHANTDB_TFK_Subscription, - i, - output.details.token.count)) + if (GNUNET_OK != + sign_token_envelopes (pc, + &key, + &details.priv, + /* TODO: Use critical field stored in database here instead. */ + details.token_family.kind == + TALER_MERCHANTDB_TFK_Subscription, + i, + output.details.token.count)) { /* Error is already scheduled from sign_token_envelopes. */ return; @@ -2768,10 +2774,11 @@ phase_contract_paid (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "lookup_deposits_by_order")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_deposits_by_order")); return; } } @@ -2796,10 +2803,11 @@ phase_contract_paid (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "lookup_spent_tokens_by_order")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "lookup_spent_tokens_by_order")); return; } } @@ -2913,19 +2921,21 @@ phase_check_contract (struct PayContext *pc) /* Always report on hard error to enable diagnostics */ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "contract terms")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "contract terms")); return; } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN, - pc->order_id)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN, + pc->order_id)); return; } /* hash contract (needed later) */ @@ -2938,10 +2948,11 @@ phase_check_contract (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH, + NULL)); return; } if (paid) @@ -2964,10 +2975,11 @@ phase_check_contract (struct PayContext *pc) /* invalid contract */ GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING, + NULL)); return; } @@ -3035,10 +3047,11 @@ phase_check_contract (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - "'max_fee' in database does not match currency of contract price")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "'max_fee' in database does not match currency of contract price")); return; } @@ -3052,10 +3065,11 @@ phase_check_contract (struct PayContext *pc) { GNUNET_break_op (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_CONFLICT, - TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH, - pc->amount.currency)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH, + pc->amount.currency)); return; } } @@ -3067,20 +3081,22 @@ phase_check_contract (struct PayContext *pc) /* This should already have been checked when creating the order! */ GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE, + NULL)); return; } if (GNUNET_TIME_absolute_is_past (pc->pay_deadline.abs_time)) { /* too late */ pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_GONE, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_GONE, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED, + NULL)); return; } @@ -3096,10 +3112,11 @@ phase_check_contract (struct PayContext *pc) { GNUNET_break (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN, - NULL)); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN, + NULL)); return; } pc->wm = wm; @@ -3181,14 +3198,10 @@ phase_parse_wallet_data (struct PayContext *pc) unsigned int tokens_ev_index; json_t *token_ev; - json_array_foreach (tokens_evs, tokens_ev_index, token_ev) + json_array_foreach (tokens_evs, + tokens_ev_index, + token_ev) { - if (json_is_null (token_ev)) - { - // Skip null envelopes - continue; - } - struct TokenEnvelope *ev = &pc->token_envelopes[tokens_ev_index]; struct GNUNET_JSON_Specification ispec[] = { TALER_JSON_spec_token_envelope ("token_ev", @@ -3197,6 +3210,8 @@ phase_parse_wallet_data (struct PayContext *pc) }; enum GNUNET_GenericReturnValue res; + if (json_is_null (token_ev)) + continue; res = TALER_MHD_parse_json_data (pc->connection, token_ev, ispec); @@ -3218,10 +3233,11 @@ phase_parse_wallet_data (struct PayContext *pc) { GNUNET_break_op (0); pay_end (pc, - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "duplicate token envelope in list")); + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "duplicate token envelope in list")); return; } } |