diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-03-02 23:39:26 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-03-02 23:39:26 +0100 |
commit | cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12 (patch) | |
tree | eeec41a888f4f9cbdb77d6f01844ef20fccc2a43 /src/reducer/anastasis_api_recovery_redux.c | |
parent | 81311476b804c054e4ee19c9b182f3b34357f88f (diff) | |
download | anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.tar.gz anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.tar.bz2 anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.zip |
push new /truth/ API through the entire implementation
Diffstat (limited to 'src/reducer/anastasis_api_recovery_redux.c')
-rw-r--r-- | src/reducer/anastasis_api_recovery_redux.c | 474 |
1 files changed, 268 insertions, 206 deletions
diff --git a/src/reducer/anastasis_api_recovery_redux.c b/src/reducer/anastasis_api_recovery_redux.c index 2be963f..5de278c 100644 --- a/src/reducer/anastasis_api_recovery_redux.c +++ b/src/reducer/anastasis_api_recovery_redux.c @@ -504,7 +504,7 @@ find_challenge_in_cs (json_t *state, * @param csr response details */ static void -answer_feedback_cb ( +start_feedback_cb ( void *cls, const struct ANASTASIS_ChallengeStartResponse *csr) { @@ -533,7 +533,246 @@ answer_feedback_cb ( } switch (csr->cs) { - case ANASTASIS_CHALLENGE_STATUS_SOLVED: + case ANASTASIS_CHALLENGE_START_STATUS_FILENAME_PROVIDED: + { + json_t *instructions; + + instructions = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "hint"), + GNUNET_JSON_pack_string ("hint", + csr->details.tan_filename), + GNUNET_JSON_pack_uint64 ("http_status", + (json_int_t) csr->http_status)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + instructions)); + } + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING); + sctx->cb (sctx->cb_cls, + TALER_EC_NONE, + sctx->state); + sctx_free (sctx); + return; + case ANASTASIS_CHALLENGE_START_STATUS_TAN_SENT_HINT_PROVIDED: + { + json_t *instructions; + + instructions = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "hint"), + GNUNET_JSON_pack_string ("hint", + csr->details.tan_address_hint), + GNUNET_JSON_pack_uint64 ("http_status", + (json_int_t) csr->http_status)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + instructions)); + } + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING); + sctx->cb (sctx->cb_cls, + TALER_EC_NONE, + sctx->state); + sctx_free (sctx); + return; + case ANASTASIS_CHALLENGE_START_STATUS_PAYMENT_REQUIRED: + { + json_t *pay; + + pay = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "payment"), + GNUNET_JSON_pack_string ( + "taler_pay_uri", + csr->details.payment_required.taler_pay_uri), + GNUNET_JSON_pack_string ("provider", + cd->provider_url), + GNUNET_JSON_pack_data_auto ( + "payment_secret", + &csr->details.payment_required.payment_secret)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + pay)); + } + /* Remember payment secret for later (once application claims it paid) */ + { + json_t *challenge = find_challenge_in_ri (sctx->state, + &cd->uuid); + + GNUNET_assert (NULL != challenge); + GNUNET_assert (0 == + json_object_set_new ( + challenge, + "payment_secret", + GNUNET_JSON_from_data_auto ( + &csr->details.payment_required.payment_secret))); + } + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_PAYING); + sctx->cb (sctx->cb_cls, + TALER_EC_NONE, + sctx->state); + sctx_free (sctx); + return; + case ANASTASIS_CHALLENGE_START_STATUS_SERVER_FAILURE: + { + json_t *err; + + err = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "server-failure"), + GNUNET_JSON_pack_uint64 ("http_status", + csr->http_status), + GNUNET_JSON_pack_uint64 ("error_code", + csr->ec)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + err)); + } + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING); + sctx->cb (sctx->cb_cls, + csr->ec, + sctx->state); + sctx_free (sctx); + return; + case ANASTASIS_CHALLENGE_START_STATUS_TRUTH_UNKNOWN: + { + json_t *err; + + err = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "truth-unknown"), + GNUNET_JSON_pack_uint64 ("http_status", + csr->http_status), + GNUNET_JSON_pack_uint64 ("error_code", + TALER_EC_ANASTASIS_TRUTH_UNKNOWN)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + err)); + } + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING); + sctx->cb (sctx->cb_cls, + TALER_EC_ANASTASIS_TRUTH_UNKNOWN, + sctx->state); + sctx_free (sctx); + return; + case ANASTASIS_CHALLENGE_START_STATUS_BANK_TRANSFER_REQUIRED: + { + json_t *reply; + json_t *c; + + c = find_challenge_in_cs (sctx->state, + &cd->uuid); + if (NULL == c) + { + GNUNET_break (0); + ANASTASIS_redux_fail_ (sctx->cb, + sctx->cb_cls, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + sctx_free (sctx); + return; + } + GNUNET_assert (0 == + json_object_set_new (c, + "async", + json_true ())); + GNUNET_assert ( + 0 == + json_object_set_new ( + c, + "answer-pin", + json_integer ( + csr->details.bank_transfer_required.answer_code))); + reply = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("state", + "iban-instructions"), + GNUNET_JSON_pack_string ( + "target_iban", + csr->details.bank_transfer_required.target_iban), + GNUNET_JSON_pack_string ( + "target_business_name", + csr->details.bank_transfer_required.target_business_name), + GNUNET_JSON_pack_string ( + "wire_transfer_subject", + csr->details.bank_transfer_required.wire_transfer_subject), + TALER_JSON_pack_amount ( + "challenge_amount", + &csr->details.bank_transfer_required.amount)); + GNUNET_assert (0 == + json_object_set_new (feedback, + uuid, + reply)); + } + GNUNET_assert (0 == + json_object_set_new (sctx->state, + "selected_challenge_uuid", + GNUNET_JSON_from_data_auto ( + &cd->uuid))); + set_state (sctx->state, + ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING); + sctx->cb (sctx->cb_cls, + TALER_EC_NONE, + sctx->state); + sctx_free (sctx); + return; + } + GNUNET_break (0); + ANASTASIS_redux_fail_ (sctx->cb, + sctx->cb_cls, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + sctx_free (sctx); +} + + +/** + * Defines a callback for the response status for a challenge answer + * operation. + * + * @param cls a `struct SelectChallengeContext *` + * @param csr response details + */ +static void +answer_feedback_cb ( + void *cls, + const struct ANASTASIS_ChallengeAnswerResponse *csr) +{ + struct SelectChallengeContext *sctx = cls; + const struct ANASTASIS_ChallengeDetails *cd; + char uuid[sizeof (cd->uuid) * 2]; + char *end; + json_t *feedback; + + cd = ANASTASIS_challenge_get_details (csr->challenge); + end = GNUNET_STRINGS_data_to_string (&cd->uuid, + sizeof (cd->uuid), + uuid, + sizeof (uuid)); + GNUNET_assert (NULL != end); + *end = '\0'; + feedback = json_object_get (sctx->state, + "challenge_feedback"); + if (NULL == feedback) + { + feedback = json_object (); + GNUNET_assert (0 == + json_object_set_new (sctx->state, + "challenge_feedback", + feedback)); + } + switch (csr->cs) + { + case ANASTASIS_CHALLENGE_ANSWER_STATUS_SOLVED: { json_t *rd; @@ -570,77 +809,17 @@ answer_feedback_cb ( sctx->delayed_report = GNUNET_SCHEDULER_add_now (&report_solved, sctx); return; - case ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_INVALID_ANSWER: { json_t *instructions; - const char *mime; - - mime = csr->details.open_challenge.content_type; - if (NULL != mime) - { - if ( (0 == strcasecmp (mime, - "text/plain")) || - (0 == strcasecmp (mime, - "text/utf8")) ) - { - char *s = GNUNET_strndup (csr->details.open_challenge.body, - csr->details.open_challenge.body_size); - - instructions = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "hint"), - GNUNET_JSON_pack_string ("hint", - s), - GNUNET_JSON_pack_uint64 ("http_status", - (json_int_t) csr->details.open_challenge. - http_status)); - GNUNET_free (s); - } - else if (0 == strcasecmp (mime, - "application/json")) - { - json_t *body; - body = json_loadb (csr->details.open_challenge.body, - csr->details.open_challenge.body_size, - JSON_REJECT_DUPLICATES, - NULL); - if (NULL == body) - { - GNUNET_break_op (0); - mime = NULL; - } - else - { - instructions = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "details"), - GNUNET_JSON_pack_object_steal ("details", - body), - GNUNET_JSON_pack_uint64 ("http_status", - csr->details.open_challenge.http_status)); - } - } - else - { - /* unexpected / unsupported mime type */ - mime = NULL; - } - } - if (NULL == mime) - { - instructions = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "body"), - GNUNET_JSON_pack_data_varsize ("body", - csr->details.open_challenge.body, - csr->details.open_challenge.body_size), - GNUNET_JSON_pack_uint64 ("http_status", - csr->details.open_challenge.http_status), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("mime_type", - mime))); - } + instructions = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("status", + "incorrect-answer"), + GNUNET_JSON_pack_uint64 ("error_code", + csr->ec), + GNUNET_JSON_pack_uint64 ("http_status", + csr->http_status)); GNUNET_assert (0 == json_object_set_new (feedback, uuid, @@ -653,35 +832,13 @@ answer_feedback_cb ( sctx->state); sctx_free (sctx); return; - case ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION: - { - json_t *redir; - - redir = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "redirect"), - GNUNET_JSON_pack_string ("redirect_url", - csr->details.redirect_url)); - GNUNET_assert (NULL != redir); - GNUNET_assert (0 == - json_object_set_new (feedback, - uuid, - redir)); - } - set_state (sctx->state, - ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING); - sctx->cb (sctx->cb_cls, - TALER_EC_NONE, - sctx->state); - sctx_free (sctx); - return; - case ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_PAYMENT_REQUIRED: { json_t *pay; pay = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("state", - "payment"), + "payment-required"), GNUNET_JSON_pack_string ("taler_pay_uri", csr->details.payment_required. taler_pay_uri), @@ -715,7 +872,7 @@ answer_feedback_cb ( sctx->state); sctx_free (sctx); return; - case ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_SERVER_FAILURE: { json_t *err; @@ -723,10 +880,9 @@ answer_feedback_cb ( GNUNET_JSON_pack_string ("state", "server-failure"), GNUNET_JSON_pack_uint64 ("http_status", - csr->details.server_failure. - http_status), + csr->http_status), GNUNET_JSON_pack_uint64 ("error_code", - csr->details.server_failure.ec)); + csr->ec)); GNUNET_assert (0 == json_object_set_new (feedback, uuid, @@ -735,11 +891,11 @@ answer_feedback_cb ( set_state (sctx->state, ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING); sctx->cb (sctx->cb_cls, - csr->details.server_failure.ec, + csr->ec, sctx->state); sctx_free (sctx); return; - case ANASTASIS_CHALLENGE_STATUS_TRUTH_UNKNOWN: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_TRUTH_UNKNOWN: { json_t *err; @@ -760,7 +916,7 @@ answer_feedback_cb ( sctx->state); sctx_free (sctx); return; - case ANASTASIS_CHALLENGE_STATUS_RATE_LIMIT_EXCEEDED: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_RATE_LIMIT_EXCEEDED: { json_t *err; @@ -789,7 +945,8 @@ answer_feedback_cb ( sctx->state); sctx_free (sctx); return; - case ANASTASIS_CHALLENGE_STATUS_AUTH_TIMEOUT: + case ANASTASIS_CHALLENGE_ANSWER_STATUS_AUTH_TIMEOUT: + // FIXME: check if this status code is even properly generated! { json_t *err; @@ -811,95 +968,6 @@ answer_feedback_cb ( sctx->state); sctx_free (sctx); return; - - case ANASTASIS_CHALLENGE_STATUS_EXTERNAL_INSTRUCTIONS: - { - const json_t *body = csr->details.external_challenge; - const char *method; - json_t *details; - bool is_async = false; - uint64_t code = 0; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("method", - &method), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("async", - &is_async)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint64 ("answer_code", - &code)), - GNUNET_JSON_spec_json ("details", - &details), - GNUNET_JSON_spec_end () - }; - json_t *reply; - - if (GNUNET_OK != - GNUNET_JSON_parse (body, - spec, - NULL, NULL)) - { - json_t *err; - - GNUNET_break_op (0); - err = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "server-failure"), - GNUNET_JSON_pack_uint64 ("error_code", - TALER_EC_GENERIC_REPLY_MALFORMED)); - GNUNET_assert (0 == - json_object_set_new (feedback, - uuid, - err)); - return; - } - if (is_async) - { - json_t *c = find_challenge_in_cs (sctx->state, - &cd->uuid); - - if (NULL == c) - { - GNUNET_break (0); - ANASTASIS_redux_fail_ (sctx->cb, - sctx->cb_cls, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL); - sctx_free (sctx); - return; - } - GNUNET_assert (0 == - json_object_set_new (c, - "async", - json_true ())); - GNUNET_assert (0 == - json_object_set_new (c, - "answer-pin", - json_integer (code))); - } - reply = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("state", - "external-instructions"), - GNUNET_JSON_pack_string ("method", - method), - GNUNET_JSON_pack_object_incref ("details", - details)); - GNUNET_JSON_parse_free (spec); - GNUNET_assert (0 == - json_object_set_new (feedback, - uuid, - reply)); - } - json_object_set_new (sctx->state, - "selected_challenge_uuid", - GNUNET_JSON_from_data_auto (&cd->uuid)); - set_state (sctx->state, - ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING); - sctx->cb (sctx->cb_cls, - TALER_EC_NONE, - sctx->state); - sctx_free (sctx); - return; } GNUNET_break (0); ANASTASIS_redux_fail_ (sctx->cb, @@ -1197,21 +1265,19 @@ solve_challenge_cb (void *cls, sctx_free (sctx); return; } - ret = ANASTASIS_challenge_start (ci, - psp, - timeout, - &hashed_answer, - &answer_feedback_cb, - sctx); + ret = ANASTASIS_challenge_answer3 (ci, + psp, + timeout, + &hashed_answer, + &answer_feedback_cb, + sctx); } else { /* no answer provided */ ret = ANASTASIS_challenge_start (ci, psp, - timeout, - NULL, /* no answer */ - &answer_feedback_cb, + &start_feedback_cb, sctx); } } @@ -1331,9 +1397,7 @@ pay_challenge_cb (void *cls, { ret = ANASTASIS_challenge_start (ci, &sctx->ps, - sctx->timeout, - NULL, /* no answer yet */ - &answer_feedback_cb, + &start_feedback_cb, sctx); } if (GNUNET_OK != ret) @@ -1780,9 +1844,7 @@ select_challenge_cb (void *cls, { ret = ANASTASIS_challenge_start (ci, psp, - timeout, - NULL, /* no answer */ - &answer_feedback_cb, + &start_feedback_cb, sctx); } } |