diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2022-03-10 04:18:17 +0100 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2022-03-10 04:18:17 +0100 |
commit | 69e887bb68064ddf40db83d46ae3333659112db4 (patch) | |
tree | 0624b5ca5963eb7f42b98f6e3a948534585f0ec2 /src | |
parent | 2ba4773bc79ee6dff50a6322dbbf3569e47708eb (diff) | |
download | anastasis-69e887bb68064ddf40db83d46ae3333659112db4.tar.gz anastasis-69e887bb68064ddf40db83d46ae3333659112db4.tar.bz2 anastasis-69e887bb68064ddf40db83d46ae3333659112db4.zip |
-clean up challenge logic for new truth api
Diffstat (limited to 'src')
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_email.c | 35 | ||||
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_file.c | 22 | ||||
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_iban.c | 224 | ||||
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_post.c | 39 | ||||
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_sms.c | 35 | ||||
-rw-r--r-- | src/authorization/anastasis_authorization_plugin_totp.c | 43 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_truth-challenge.c | 87 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_truth-solve.c | 62 | ||||
-rw-r--r-- | src/include/anastasis_authorization_plugin.h | 72 |
9 files changed, 305 insertions, 314 deletions
diff --git a/src/authorization/anastasis_authorization_plugin_email.c b/src/authorization/anastasis_authorization_plugin_email.c index 78be9b6..1f27922 100644 --- a/src/authorization/anastasis_authorization_plugin_email.c +++ b/src/authorization/anastasis_authorization_plugin_email.c @@ -310,20 +310,17 @@ email_done_cb (void *cls, * I.e. start to send SMS or e-mail or launch video identification. * * @param as authorization state - * @param timeout how long do we have to produce a reply * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -email_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_ChallengeResult +email_challenge (struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection) { MHD_RESULT mres; const char *mime; const char *lang; - (void) timeout; mime = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT); @@ -348,8 +345,8 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_EMAIL_HELPER_EXEC_FAILED, "pipe"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, p, @@ -367,8 +364,8 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_EMAIL_HELPER_EXEC_FAILED, "exec"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } pipe_stdin = GNUNET_DISK_pipe_detach_end (p, GNUNET_DISK_PIPE_END_WRITE); @@ -401,8 +398,8 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_EMAIL_HELPER_EXEC_FAILED, "write"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->msg_off += ret; off += ret; @@ -415,14 +412,14 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, as); as->connection = connection; MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if (NULL != as->cwh) { /* Spurious call, why are we here? */ GNUNET_break (0); MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if ( (GNUNET_OS_PROCESS_EXITED != as->pst) || (0 != as->exit_code) ) @@ -439,8 +436,8 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_EMAIL_HELPER_COMMAND_FAILED, es); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } /* Build HTTP response */ @@ -495,8 +492,8 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_SUCCESS; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS; } } @@ -595,7 +592,7 @@ libanastasis_plugin_authorization_email_init (void *cls) plugin->cls = ctx; plugin->validate = &email_validate; plugin->start = &email_start; - plugin->process = &email_process; + plugin->challenge = &email_challenge; plugin->cleanup = &email_cleanup; if (GNUNET_OK != diff --git a/src/authorization/anastasis_authorization_plugin_file.c b/src/authorization/anastasis_authorization_plugin_file.c index 5186ae8..2f4fcb4 100644 --- a/src/authorization/anastasis_authorization_plugin_file.c +++ b/src/authorization/anastasis_authorization_plugin_file.c @@ -161,14 +161,12 @@ file_start (void *cls, * I.e. start to send SMS or e-mail or launch video identification. * * @param as authorization state - * @param timeout how long do we have to produce a reply * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -file_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_ChallengeResult +file_challenge (struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection) { const char *mime; const char *lang; @@ -201,8 +199,8 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } /* print challenge code to file */ @@ -221,8 +219,8 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } GNUNET_break (0 == fclose (f)); } @@ -266,8 +264,8 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_SUCCESS; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS; } } } @@ -306,7 +304,7 @@ libanastasis_plugin_authorization_file_init (void *cls) plugin->code_retransmission_frequency = GNUNET_TIME_UNIT_MINUTES; plugin->validate = &file_validate; plugin->start = &file_start; - plugin->process = &file_process; + plugin->challenge = &file_challenge; plugin->cleanup = &file_cleanup; return plugin; } diff --git a/src/authorization/anastasis_authorization_plugin_iban.c b/src/authorization/anastasis_authorization_plugin_iban.c index e557152..8aebbce 100644 --- a/src/authorization/anastasis_authorization_plugin_iban.c +++ b/src/authorization/anastasis_authorization_plugin_iban.c @@ -298,95 +298,6 @@ bank_event_cb (void *cls, } -/** - * Respond with instructions to the user how to - * satisfy the challenge. - * - * @param as our state - * @param connection connection to respond on - * @return state of the request - */ -static enum ANASTASIS_AUTHORIZATION_Result -respond_with_challenge (struct ANASTASIS_AUTHORIZATION_State *as, - struct MHD_Connection *connection) -{ - struct IBAN_Context *ctx = as->ctx; - const char *mime; - const char *lang; - MHD_RESULT mres; - - mime = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_ACCEPT); - if (NULL == mime) - mime = "text/plain"; - lang = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_ACCEPT_LANGUAGE); - if (NULL == lang) - lang = "en"; - - /* Build HTTP response */ - { - struct MHD_Response *resp; - - if (TALER_MHD_xmime_matches (mime, - "application/json")) - { - char subject[64]; - - GNUNET_snprintf (subject, - sizeof (subject), - "Anastasis %llu", - (unsigned long long) as->code); - resp = TALER_MHD_MAKE_JSON_PACK ( - GNUNET_JSON_pack_string ("challenge_type", - "IBAN_WIRE"), - GNUNET_JSON_pack_uint64 ("answer_code", - as->code), - TALER_JSON_pack_amount ("challenge_amount", - &ctx->expected_amount), - GNUNET_JSON_pack_string ("credit_iban", - ctx->business_iban), - GNUNET_JSON_pack_string ("business_name", - ctx->business_name), - GNUNET_JSON_pack_string ("wire_transfer_subject", - subject)); - } - else - { - size_t reply_len; - char *reply; - - reply_len = GNUNET_asprintf (&reply, - get_message (ctx->messages, - connection, - "instructions"), - TALER_amount2s (&ctx->expected_amount), - ctx->business_name, - ctx->business_iban, - (unsigned long long) as->code); - resp = MHD_create_response_from_buffer (reply_len, - reply, - MHD_RESPMEM_MUST_COPY); - GNUNET_free (reply); - TALER_MHD_add_global_headers (resp); - GNUNET_break (MHD_YES == - MHD_add_response_header (resp, - MHD_HTTP_HEADER_CONTENT_TYPE, - "text/plain")); - } - mres = MHD_queue_response (connection, - MHD_HTTP_ACCEPTED, - resp); - MHD_destroy_response (resp); - if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_SUCCESS; - } -} - - #include "iban.c" @@ -496,18 +407,109 @@ test_wire_transfers (struct ANASTASIS_AUTHORIZATION_State *as) /** + * Respond with instructions to the user how to + * satisfy the challenge. + * + * @param as authorization state + * @param connection HTTP client request (for queuing response, such as redirection to video portal) + * @return state of the request + */ +static enum ANASTASIS_AUTHORIZATION_ChallengeResult +iban_challenge (struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection) +{ + struct IBAN_Context *ctx = as->ctx; + const char *mime; + const char *lang; + MHD_RESULT mres; + + mime = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_ACCEPT); + if (NULL == mime) + mime = "text/plain"; + lang = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_ACCEPT_LANGUAGE); + if (NULL == lang) + lang = "en"; + + /* Build HTTP response */ + { + struct MHD_Response *resp; + + if (TALER_MHD_xmime_matches (mime, + "application/json")) + { + char subject[64]; + + GNUNET_snprintf (subject, + sizeof (subject), + "Anastasis %llu", + (unsigned long long) as->code); + resp = TALER_MHD_MAKE_JSON_PACK ( + GNUNET_JSON_pack_string ("challenge_type", + "IBAN_WIRE"), + GNUNET_JSON_pack_uint64 ("answer_code", + as->code), + TALER_JSON_pack_amount ("challenge_amount", + &ctx->expected_amount), + GNUNET_JSON_pack_string ("credit_iban", + ctx->business_iban), + GNUNET_JSON_pack_string ("business_name", + ctx->business_name), + GNUNET_JSON_pack_string ("wire_transfer_subject", + subject)); + } + else + { + size_t reply_len; + char *reply; + + reply_len = GNUNET_asprintf (&reply, + get_message (ctx->messages, + connection, + "instructions"), + TALER_amount2s (&ctx->expected_amount), + ctx->business_name, + ctx->business_iban, + (unsigned long long) as->code); + resp = MHD_create_response_from_buffer (reply_len, + reply, + MHD_RESPMEM_MUST_COPY); + GNUNET_free (reply); + TALER_MHD_add_global_headers (resp); + GNUNET_break (MHD_YES == + MHD_add_response_header (resp, + MHD_HTTP_HEADER_CONTENT_TYPE, + "text/plain")); + } + mres = MHD_queue_response (connection, + MHD_HTTP_ACCEPTED, + resp); + MHD_destroy_response (resp); + if (MHD_YES != mres) + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS; + } +} + + +/** * Begin issuing authentication challenge to user based on @a data. * I.e. start to send IBAN or e-mail or launch video identification. * * @param as authorization state * @param timeout how long do we have to produce a reply + * @param challenge_response hash of the challenge response, or NULL * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -iban_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_SolveResult +iban_solve (struct ANASTASIS_AUTHORIZATION_State *as, + struct GNUNET_TIME_Absolute timeout, + const struct GNUNET_HashCode *challenge_response, + struct MHD_Connection *connection) { struct IBAN_Context *ctx = as->ctx; struct ANASTASIS_DatabasePlugin *db = ctx->ac->db; @@ -550,45 +552,53 @@ iban_process (struct ANASTASIS_AUTHORIZATION_State *as, { case GNUNET_DB_STATUS_HARD_ERROR: case GNUNET_DB_STATUS_SOFT_ERROR: - resp = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED, - "test_challenge_code_satisfied"); + resp = TALER_MHD_make_error (TALER_EC_ANASTASIS_TRUTH_AUTH_TIMEOUT, + "IBAN payment not yet received"); mres = MHD_queue_response (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: switch (test_wire_transfers (as)) { case WTS_SUCCESS: GNUNET_log (GNUNET_ERROR_TYPE_INFO, "IBAN authorization finished!\n"); - return ANASTASIS_AUTHORIZATION_RES_FINISHED; + return ANASTASIS_AUTHORIZATION_SRES_FINISHED; case WTS_NOT_READY: break; /* continue below */ case WTS_FAILED_WITH_REPLY: - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED; case WTS_FAILED_WITHOUT_REPLY: - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED; } if (GNUNET_TIME_absolute_is_future (timeout)) { as->connection = connection; MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_SRES_SUSPENDED; } - return respond_with_challenge (as, - connection); + + resp = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); + mres = MHD_queue_response (connection, + MHD_HTTP_FORBIDDEN, + resp); + MHD_destroy_response (resp); + if (MHD_YES != mres) + return ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED; case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: GNUNET_log (GNUNET_ERROR_TYPE_INFO, "IBAN authorization finished!\n"); - return ANASTASIS_AUTHORIZATION_RES_FINISHED; + return ANASTASIS_AUTHORIZATION_SRES_FINISHED; } /* should be impossible */ GNUNET_break (0); - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED; } @@ -703,9 +713,9 @@ libanastasis_plugin_authorization_iban_init (void *cls) plugin->cls = ctx; plugin->validate = &iban_validate; plugin->start = &iban_start; - plugin->process = &iban_process; + plugin->challenge = &iban_challenge; + plugin->solve = &iban_solve; plugin->cleanup = &iban_cleanup; - return plugin; } diff --git a/src/authorization/anastasis_authorization_plugin_post.c b/src/authorization/anastasis_authorization_plugin_post.c index ad0ed15..a8810ff 100644 --- a/src/authorization/anastasis_authorization_plugin_post.c +++ b/src/authorization/anastasis_authorization_plugin_post.c @@ -348,14 +348,12 @@ post_done_cb (void *cls, * I.e. start to send SMS or e-mail or launch video identification. * * @param as authorization state - * @param timeout how long do we have to produce a reply * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -post_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_ChallengeResult +post_challenge (struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection) { const char *mime; const char *lang; @@ -379,7 +377,6 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, GNUNET_JSON_spec_end () }; - (void) timeout; mime = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT); @@ -401,8 +398,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_POST_INVALID, "address information incomplete"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } if (NULL == as->msg) { @@ -418,8 +415,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_POST_HELPER_EXEC_FAILED, "pipe"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, p, @@ -441,8 +438,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_POST_HELPER_EXEC_FAILED, "exec"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } pipe_stdin = GNUNET_DISK_pipe_detach_end (p, GNUNET_DISK_PIPE_END_WRITE); @@ -474,8 +471,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_POST_HELPER_EXEC_FAILED, "write"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->msg_off += ret; off += ret; @@ -488,14 +485,14 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, as); as->connection = connection; MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if (NULL != as->cwh) { /* Spurious call, why are we here? */ GNUNET_break (0); MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if ( (GNUNET_OS_PROCESS_EXITED != as->pst) || (0 != as->exit_code) ) @@ -512,8 +509,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_POST_HELPER_COMMAND_FAILED, es); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } /* Build HTTP response */ @@ -550,8 +547,8 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_SUCCESS; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS; } } @@ -636,7 +633,7 @@ libanastasis_plugin_authorization_post_init (void *cls) plugin->cls = ctx; plugin->validate = &post_validate; plugin->start = &post_start; - plugin->process = &post_process; + plugin->challenge = &post_challenge; plugin->cleanup = &post_cleanup; if (GNUNET_OK != diff --git a/src/authorization/anastasis_authorization_plugin_sms.c b/src/authorization/anastasis_authorization_plugin_sms.c index 6598d29..797c576 100644 --- a/src/authorization/anastasis_authorization_plugin_sms.c +++ b/src/authorization/anastasis_authorization_plugin_sms.c @@ -309,20 +309,17 @@ sms_done_cb (void *cls, * I.e. start to send SMS or e-mail or launch video identification. * * @param as authorization state - * @param timeout how long do we have to produce a reply * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -sms_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_ChallengeResult +sms_challenge (struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection) { MHD_RESULT mres; const char *mime; const char *lang; - (void) timeout; mime = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT); @@ -347,8 +344,8 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_SMS_HELPER_EXEC_FAILED, "pipe"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, p, @@ -366,8 +363,8 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_SMS_HELPER_EXEC_FAILED, "exec"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } pipe_stdin = GNUNET_DISK_pipe_detach_end (p, GNUNET_DISK_PIPE_END_WRITE); @@ -397,8 +394,8 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_SMS_HELPER_EXEC_FAILED, "write"); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } as->msg_off += ret; off += ret; @@ -411,14 +408,14 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, as); as->connection = connection; MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if (NULL != as->cwh) { /* Spurious call, why are we here? */ GNUNET_break (0); MHD_suspend_connection (connection); - return ANASTASIS_AUTHORIZATION_RES_SUSPENDED; + return ANASTASIS_AUTHORIZATION_CRES_SUSPENDED; } if ( (GNUNET_OS_PROCESS_EXITED != as->pst) || (0 != as->exit_code) ) @@ -435,8 +432,8 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, TALER_EC_ANASTASIS_SMS_HELPER_COMMAND_FAILED, es); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_FAILED; } /* Build HTTP response */ @@ -485,8 +482,8 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as, resp); MHD_destroy_response (resp); if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_SUCCESS; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_CRES_SUCCESS; } } @@ -584,7 +581,7 @@ libanastasis_plugin_authorization_sms_init (void *cls) plugin->cls = ctx; plugin->validate = &sms_validate; plugin->start = &sms_start; - plugin->process = &sms_process; + plugin->challenge = &sms_challenge; plugin->cleanup = &sms_cleanup; if (GNUNET_OK != diff --git a/src/authorization/anastasis_authorization_plugin_totp.c b/src/authorization/anastasis_authorization_plugin_totp.c index 1f01652..77a5909 100644 --- a/src/authorization/anastasis_authorization_plugin_totp.c +++ b/src/authorization/anastasis_authorization_plugin_totp.c @@ -244,46 +244,29 @@ totp_start (void *cls, /** - * Begin issuing authentication challenge to user based on @a data. + * Check authentication response from the user. * * @param as authorization state * @param timeout how long do we have to produce a reply + * @param challenge_response hash of the response * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ -static enum ANASTASIS_AUTHORIZATION_Result -totp_process (struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection) +static enum ANASTASIS_AUTHORIZATION_SolveResult +totp_solve (struct ANASTASIS_AUTHORIZATION_State *as, + struct GNUNET_TIME_Absolute timeout, + const struct GNUNET_HashCode *challenge_response, + struct MHD_Connection *connection) { MHD_RESULT mres; const char *mime; const char *lang; - const char *challenge_response_s; - struct GNUNET_HashCode challenge_response; - - challenge_response_s = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "response"); - if ( (NULL == challenge_response_s) || - (GNUNET_OK != - GNUNET_CRYPTO_hash_from_string (challenge_response_s, - &challenge_response)) ) - { - GNUNET_break_op (0); - mres = TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "response"); - if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; - } + for (unsigned int i = 0; i<=TIME_INTERVAL_RANGE * 2; i++) if (0 == - GNUNET_memcmp (&challenge_response, + GNUNET_memcmp (challenge_response, &as->valid_replies[i])) - return ANASTASIS_AUTHORIZATION_RES_FINISHED; + return ANASTASIS_AUTHORIZATION_SRES_FINISHED; mime = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT); @@ -338,8 +321,8 @@ totp_process (struct ANASTASIS_AUTHORIZATION_State *as, MHD_destroy_response (resp); } if (MHD_YES != mres) - return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED; - return ANASTASIS_AUTHORIZATION_RES_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED; + return ANASTASIS_AUTHORIZATION_SRES_FAILED; } @@ -376,7 +359,7 @@ libanastasis_plugin_authorization_totp_init (void *cls) plugin->code_retransmission_frequency = plugin->code_validity_period; plugin->validate = &totp_validate; plugin->start = &totp_start; - plugin->process = &totp_process; + plugin->solve = &totp_solve; plugin->cleanup = &totp_cleanup; return plugin; } diff --git a/src/backend/anastasis-httpd_truth-challenge.c b/src/backend/anastasis-httpd_truth-challenge.c index 65dc244..3a3688e 100644 --- a/src/backend/anastasis-httpd_truth-challenge.c +++ b/src/backend/anastasis-httpd_truth-challenge.c @@ -44,6 +44,12 @@ #define AUTO_REFUND_TIMEOUT GNUNET_TIME_relative_multiply ( \ GNUNET_TIME_UNIT_MINUTES, 2) +/** + * How long should the wallet check for payment before giving up? + */ +#define PAYMENT_TIMEOUT GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_SECONDS, 15) + /** * How many retries do we allow per code? @@ -135,8 +141,7 @@ struct ChallengeContext struct GNUNET_CONTAINER_HeapNode *hn; /** - * How long do we wait at most for payment or - * authorization? + * When should this request time out? */ struct GNUNET_TIME_Absolute timeout; @@ -887,16 +892,23 @@ static MHD_RESULT run_authorization_process (struct MHD_Connection *connection, struct ChallengeContext *gc) { - enum ANASTASIS_AUTHORIZATION_Result ret; + enum ANASTASIS_AUTHORIZATION_ChallengeResult ret; enum GNUNET_DB_QueryStatus qs; GNUNET_assert (! gc->suspended); - ret = gc->authorization->process (gc->as, - gc->timeout, - connection); + if (NULL == gc->authorization->challenge) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (gc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED, + "challenge method not implemented for authorization method"); + } + ret = gc->authorization->challenge (gc->as, + connection); switch (ret) { - case ANASTASIS_AUTHORIZATION_RES_SUCCESS: + case ANASTASIS_AUTHORIZATION_CRES_SUCCESS: /* Challenge sent successfully */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Authorization request sent successfully\n"); @@ -908,7 +920,7 @@ run_authorization_process (struct MHD_Connection *connection, gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_FAILED: + case ANASTASIS_AUTHORIZATION_CRES_FAILED: if (gc->payment_identifier_provided) { begin_refund (gc); @@ -916,11 +928,11 @@ run_authorization_process (struct MHD_Connection *connection, gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_SUSPENDED: + case ANASTASIS_AUTHORIZATION_CRES_SUSPENDED: /* connection was suspended */ gc_suspended (gc); return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED: + case ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED: /* Challenge sent successfully */ qs = db->mark_challenge_sent (db->cls, &gc->payment_identifier, @@ -930,27 +942,10 @@ run_authorization_process (struct MHD_Connection *connection, gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_NO; - case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED: + case ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED: gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_NO; - case ANASTASIS_AUTHORIZATION_RES_FINISHED: - /* Neither case should EVER happen here! */ - GNUNET_break (0); - GNUNET_assert (! gc->suspended); - gc->authorization->cleanup (gc->as); - gc->as = NULL; - if (gc->in_list) - { - GNUNET_CONTAINER_DLL_remove (gc_head, - gc_tail, - gc); - gc->in_list = false; - } - return TALER_MHD_reply_with_error (gc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "authorization successful when we were only supposed to be challenging"); } GNUNET_break (0); return MHD_NO; @@ -981,40 +976,8 @@ AH_handler_truth_challenge ( gc->connection = connection; gc->truth_uuid = *truth_uuid; gc->hc->cc = &request_done; - - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - gc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - } - else - { - gc->timeout = GNUNET_TIME_relative_to_absolute ( - GNUNET_TIME_UNIT_SECONDS); - } - } + gc->timeout = GNUNET_TIME_relative_to_absolute ( + PAYMENT_TIMEOUT); } /* end of first-time initialization (if NULL == gc) */ else { diff --git a/src/backend/anastasis-httpd_truth-solve.c b/src/backend/anastasis-httpd_truth-solve.c index 2e4fea0..9142ad2 100644 --- a/src/backend/anastasis-httpd_truth-solve.c +++ b/src/backend/anastasis-httpd_truth-solve.c @@ -789,37 +789,36 @@ static MHD_RESULT run_authorization_process (struct MHD_Connection *connection, struct SolveContext *gc) { - enum ANASTASIS_AUTHORIZATION_Result ret; + enum ANASTASIS_AUTHORIZATION_SolveResult ret; GNUNET_assert (! gc->suspended); - ret = gc->authorization->process (gc->as, - gc->timeout, - connection); - switch (ret) + if (NULL == gc->authorization->solve) { - case ANASTASIS_AUTHORIZATION_RES_SUCCESS: - case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED: - /* Neither case should EVER happen here! */ GNUNET_break (0); - gc->authorization->cleanup (gc->as); - gc->as = NULL; return TALER_MHD_reply_with_error (gc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "challenge sent when we were only supposed to be checking"); - case ANASTASIS_AUTHORIZATION_RES_SUSPENDED: + TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED, + "solve method not implemented for authorization method"); + } + ret = gc->authorization->solve (gc->as, + gc->timeout, + &gc->challenge_response, + connection); + switch (ret) + { + case ANASTASIS_AUTHORIZATION_SRES_SUSPENDED: /* connection was suspended */ gc_suspended (gc); return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_FAILED: + case ANASTASIS_AUTHORIZATION_SRES_FAILED: gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED: + case ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED: gc->authorization->cleanup (gc->as); gc->as = NULL; return MHD_NO; - case ANASTASIS_AUTHORIZATION_RES_FINISHED: + case ANASTASIS_AUTHORIZATION_SRES_FINISHED: GNUNET_assert (! gc->suspended); gc->authorization->cleanup (gc->as); gc->as = NULL; @@ -983,7 +982,7 @@ direct_validation (struct SolveContext *gc, size_t decrypted_truth_size) { /* Non-random code, call plugin directly! */ - enum ANASTASIS_AUTHORIZATION_Result aar; + enum ANASTASIS_AUTHORIZATION_SolveResult aar; enum GNUNET_GenericReturnValue res; res = rate_limit (gc); @@ -1004,25 +1003,28 @@ direct_validation (struct SolveContext *gc, TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED, NULL); } - aar = gc->authorization->process (gc->as, - GNUNET_TIME_UNIT_ZERO_ABS, - gc->connection); - switch (aar) + if (NULL == gc->authorization->solve) { - case ANASTASIS_AUTHORIZATION_RES_SUCCESS: GNUNET_break (0); + return TALER_MHD_reply_with_error (gc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED, + "solve method not implemented for authorization method"); + } + aar = gc->authorization->solve (gc->as, + GNUNET_TIME_UNIT_ZERO_ABS, + &gc->challenge_response, + gc->connection); + switch (aar) + { + case ANASTASIS_AUTHORIZATION_SRES_FAILED: return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_FAILED: - return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_SUSPENDED: + case ANASTASIS_AUTHORIZATION_SRES_SUSPENDED: gc_suspended (gc); return MHD_YES; - case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED: - GNUNET_break (0); - return MHD_NO; - case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED: + case ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED: return MHD_NO; - case ANASTASIS_AUTHORIZATION_RES_FINISHED: + case ANASTASIS_AUTHORIZATION_SRES_FINISHED: return return_key_share (&gc->truth_uuid, gc->connection); } diff --git a/src/include/anastasis_authorization_plugin.h b/src/include/anastasis_authorization_plugin.h index 10b99f3..a9d993d 100644 --- a/src/include/anastasis_authorization_plugin.h +++ b/src/include/anastasis_authorization_plugin.h @@ -33,21 +33,21 @@ struct ANASTASIS_AUTHORIZATION_State; /** * Enumeration values indicating the various possible - * outcomes of the plugin's `process` function. + * outcomes of the plugin's `challenge` function. */ -enum ANASTASIS_AUTHORIZATION_Result +enum ANASTASIS_AUTHORIZATION_ChallengeResult { /** * We successfully sent the authorization challenge * and queued a reply to MHD. */ - ANASTASIS_AUTHORIZATION_RES_SUCCESS = 0, + ANASTASIS_AUTHORIZATION_CRES_SUCCESS = 0, /** * We failed to transmit the authorization challenge, * but successfully queued a failure response to MHD. */ - ANASTASIS_AUTHORIZATION_RES_FAILED = 1, + ANASTASIS_AUTHORIZATION_CRES_FAILED = 1, /** * The plugin suspended the MHD connection as it needs some more @@ -55,7 +55,7 @@ enum ANASTASIS_AUTHORIZATION_Result * plugin will resume the MHD connection when its work is done, and * then the `process` function should be called again. */ - ANASTASIS_AUTHORIZATION_RES_SUSPENDED = 2, + ANASTASIS_AUTHORIZATION_CRES_SUSPENDED = 2, /** * The plugin tried to queue a reply on the MHD connection and @@ -65,7 +65,7 @@ enum ANASTASIS_AUTHORIZATION_Result * However, we were successful at transmitting the challenge, * so the challenge should be marked as sent. */ - ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED = 4, + ANASTASIS_AUTHORIZATION_CRES_SUCCESS_REPLY_FAILED = 4, /** * The plugin tried to queue a reply on the MHD connection and @@ -74,14 +74,45 @@ enum ANASTASIS_AUTHORIZATION_Result * * Additionally, we failed to transmit the challenge. */ - ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED = 5, + ANASTASIS_AUTHORIZATION_CRES_FAILED_REPLY_FAILED = 5 +}; + + +/** + * Enumeration values indicating the various possible + * outcomes of the plugin's `solve` function. + */ +enum ANASTASIS_AUTHORIZATION_SolveResult +{ + /** + * We failed to transmit the authorization challenge, + * but successfully queued a failure response to MHD. + */ + ANASTASIS_AUTHORIZATION_SRES_FAILED = 0, + + /** + * The plugin suspended the MHD connection as it needs some more + * time to do its (asynchronous) work before we can proceed. The + * plugin will resume the MHD connection when its work is done, and + * then the `process` function should be called again. + */ + ANASTASIS_AUTHORIZATION_SRES_SUSPENDED = 1, + + /** + * The plugin tried to queue a reply on the MHD connection and + * failed to do so. We should return #MHD_NO to MHD to cause the + * HTTP connection to be closed without any reply. + * + * Additionally, we failed to transmit the challenge. + */ + ANASTASIS_AUTHORIZATION_SRES_FAILED_REPLY_FAILED = 2, /** * The authentication process completed successfully * and we should signal success to the client by * returning the truth. */ - ANASTASIS_AUTHORIZATION_RES_FINISHED = 6 + ANASTASIS_AUTHORIZATION_SRES_FINISHED = 3 }; @@ -210,18 +241,31 @@ struct ANASTASIS_AuthorizationPlugin /** * Continue issuing authentication challenge to user based on @a data. * I.e. check if the transmission of the challenge via SMS or e-mail - * has completed and/or manipulate @a connection to redirect the client - * to a video identification site. + * has completed and/or manipulate @a connection to direct the client towards solving the challenge. + * + * @param as authorization state + * @param connection HTTP client request (for queuing response, such as redirection to video portal) + * @return state of the request + */ + enum ANASTASIS_AUTHORIZATION_ChallengeResult + (*challenge)(struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection); + + + /** + * Check if the client has solved the challenge. * * @param as authorization state * @param timeout how long do we have to produce a reply + * @param challenge_response hash of the challenge response, or NULL * @param connection HTTP client request (for queuing response, such as redirection to video portal) * @return state of the request */ - enum ANASTASIS_AUTHORIZATION_Result - (*process)(struct ANASTASIS_AUTHORIZATION_State *as, - struct GNUNET_TIME_Absolute timeout, - struct MHD_Connection *connection); + enum ANASTASIS_AUTHORIZATION_SolveResult + (*solve)(struct ANASTASIS_AUTHORIZATION_State *as, + struct GNUNET_TIME_Absolute timeout, + const struct GNUNET_HashCode *challenge_response, + struct MHD_Connection *connection); /** |