summaryrefslogtreecommitdiff
path: root/src/reducer/anastasis_api_recovery_redux.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-03-02 23:39:26 +0100
committerChristian Grothoff <christian@grothoff.org>2022-03-02 23:39:26 +0100
commitcf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12 (patch)
treeeeec41a888f4f9cbdb77d6f01844ef20fccc2a43 /src/reducer/anastasis_api_recovery_redux.c
parent81311476b804c054e4ee19c9b182f3b34357f88f (diff)
downloadanastasis-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.c474
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);
}
}