[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: WIP backend refactor
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: WIP backend refactor |
Date: |
Sun, 07 Feb 2021 20:25:25 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository anastasis.
The following commit(s) were added to refs/heads/master by this push:
new 545b2f4 WIP backend refactor
545b2f4 is described below
commit 545b2f438f0a73094e25310bffd2d816c3b8600d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Feb 7 20:25:22 2021 +0100
WIP backend refactor
---
src/backend/anastasis-httpd.c | 140 ++---
src/backend/anastasis-httpd.h | 37 +-
src/backend/anastasis-httpd_config.c | 131 ++--
src/backend/anastasis-httpd_policy.c | 116 +---
src/backend/anastasis-httpd_policy.h | 18 +-
src/backend/anastasis-httpd_policy_upload.c | 669 ++++++++++-----------
src/backend/anastasis-httpd_salt.c | 29 +-
src/backend/anastasis-httpd_salt.h | 5 +-
src/backend/anastasis-httpd_terms.c | 1 -
src/backend/anastasis-httpd_truth.c | 201 +++----
src/backend/anastasis_authorization_plugin.c | 84 ++-
src/backend/anastasis_authorization_plugin_email.c | 16 +-
src/backend/anastasis_authorization_plugin_file.c | 33 +-
src/backend/anastasis_authorization_plugin_sms.c | 4 +-
src/include/anastasis_crypto_lib.h | 2 +-
src/include/anastasis_database_plugin.h | 14 +-
src/stasis/plugin_anastasis_postgres.c | 20 +-
src/stasis/test_anastasis_db.c | 13 +-
18 files changed, 688 insertions(+), 845 deletions(-)
diff --git a/src/backend/anastasis-httpd.c b/src/backend/anastasis-httpd.c
index a426894..e5ac332 100644
--- a/src/backend/anastasis-httpd.c
+++ b/src/backend/anastasis-httpd.c
@@ -21,7 +21,6 @@
* @author Dominik Meister
*/
#include "platform.h"
-#include <microhttpd.h>
#include "anastasis-httpd.h"
#include "anastasis_util_lib.h"
#include "anastasis-httpd_mhd.h"
@@ -31,7 +30,6 @@
#include "anastasis-httpd_salt.h"
#include "anastasis-httpd_terms.h"
#include "anastasis-httpd_config.h"
-#include <taler/taler_mhd_lib.h>
/**
@@ -44,11 +42,6 @@
*/
unsigned long long int AH_upload_limit_mb;
-/**
- * Supported methods.
- */
-char *AH_supported_methods;
-
/**
* Annual fee for the backup account.
*/
@@ -59,36 +52,10 @@ struct TALER_Amount AH_annual_fee;
*/
struct TALER_Amount AH_insurance;
-const struct GNUNET_CONFIGURATION_Handle *AH_cfg;
-
-/**
- * Cost of authentication by question
- */
-struct TALER_Amount AH_question_cost;
-
/**
- * Cost of authentication by email
+ * Our configuration.
*/
-struct TALER_Amount AH_email_cost;
-
-/**
- * Cost of authentication by post
- */
-struct TALER_Amount AH_post_cost;
-
-/**
- * Cost of authentication by video
- */
-struct TALER_Amount AH_video_cost;
-
-/**
- * Cost of authentication by sms
- */
-struct TALER_Amount AH_sms_cost;
-/**
- * Cost of authentication by file (used for testing only)
- */
-struct TALER_Amount AH_file_cost;
+const struct GNUNET_CONFIGURATION_Handle *AH_cfg;
/**
* Our Taler backend to process payments.
@@ -100,7 +67,6 @@ char *AH_backend_url;
*/
char *AH_currency;
-
/**
* Our fulfillment URL.
*/
@@ -114,7 +80,7 @@ struct GNUNET_TIME_Relative AH_truth_expiration;
/**
* Our server salt.
*/
-char *AH_server_salt;
+struct ANASTASIS_CRYPTO_PowSalt AH_server_salt;
/**
* Our context for making HTTP requests.
@@ -124,7 +90,7 @@ struct GNUNET_CURL_Context *AH_ctx;
/**
* Should a "Connection: close" header be added to each HTTP response?
*/
-static int TMH_anastasis_connection_close;
+static int AH_connection_close;
/**
* Task running the HTTP server.
@@ -134,7 +100,7 @@ static struct GNUNET_SCHEDULER_Task *mhd_task;
/**
* Global return code
*/
-static int result;
+static int global_result;
/**
* The MHD Daemon
@@ -336,7 +302,7 @@ url_handler (void *cls,
(GNUNET_YES != GNUNET_CURL_is_valid_scope_id (correlation_id)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "illegal incoming correlation ID\n");
+ "Invalid incoming correlation ID\n");
correlation_id = NULL;
}
hc = GNUNET_new (struct TM_HandlerContext);
@@ -372,8 +338,8 @@ url_handler (void *cls,
{
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- 42, // FIXME: reasonable ec
- "account public key malformed");
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "account public key");
}
if (0 == strcmp (method,
MHD_HTTP_METHOD_GET))
@@ -395,8 +361,6 @@ url_handler (void *cls,
"/truth/",
strlen ("/truth/")))
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "arrived at truth get");
- // return handle_truth (...);
if (0 == strcmp (method,
MHD_HTTP_METHOD_GET))
{
@@ -591,11 +555,11 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Starting anastasis-httpd\n");
go = TALER_MHD_GO_NONE;
- if (TMH_anastasis_connection_close)
+ if (AH_connection_close)
go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
TALER_MHD_setup (go);
AH_cfg = config;
- result = GNUNET_SYSERR;
+ global_result = GNUNET_SYSERR;
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
NULL);
GNUNET_assert (GNUNET_OK ==
@@ -639,33 +603,31 @@ run (void *cls,
return;
}
if (GNUNET_OK !=
- TALER_config_get_amount (config,
- "anastasis",
- "QUESTION_COST",
- &AH_question_cost))
+ TALER_config_get_currency (config,
+ &AH_currency))
{
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "anastasis",
- "QUESTION_COST");
GNUNET_SCHEDULER_shutdown ();
return;
}
- if (GNUNET_OK !=
- TALER_config_get_amount (config,
- "anastasis",
- "FILE_COST",
- &AH_file_cost))
+ if (0 != strcasecmp (AH_currency,
+ AH_annual_fee.currency))
{
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"anastasis",
- "FILE_COST");
+ "ANNUAL_FEE",
+ "currency mismatch");
GNUNET_SCHEDULER_shutdown ();
return;
}
if (GNUNET_OK !=
- TALER_config_get_currency (config,
- &AH_currency))
+ TALER_amount_cmp_currency (&AH_insurance,
+ &AH_annual_fee))
{
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "anastasis",
+ "INSURANCE",
+ "currency mismatch");
+ GNUNET_SCHEDULER_shutdown ();
return;
}
if (GNUNET_OK !=
@@ -704,29 +666,31 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (config,
- "anastasis",
- "SERVER_SALT",
- &AH_server_salt))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "anastasis",
- "SERVER_SALT");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (config,
- "anastasis",
- "SUPPORTED_METHODS",
- &AH_supported_methods))
{
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "anastasis",
- "SUPPORTED_METHODS");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ char *server_salt;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (config,
+ "anastasis",
+ "SERVER_SALT",
+ &server_salt))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "anastasis",
+ "SERVER_SALT");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CRYPTO_kdf (&AH_server_salt,
+ sizeof (AH_server_salt),
+ "anastasis-server-salt",
+ strlen ("anastasis-server-salt"),
+ server_salt,
+ strlen (server_salt),
+ NULL,
+ 0));
+ GNUNET_free (server_salt);
}
/* setup HTTP client event loop */
@@ -794,7 +758,7 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
- result = GNUNET_OK;
+ global_result = GNUNET_OK;
mhd_task = prepare_daemon ();
}
@@ -820,7 +784,7 @@ main (int argc,
GNUNET_GETOPT_option_flag ('C',
"connection-close",
"force HTTP connections to be closed after each
request",
- &TMH_anastasis_connection_close),
+ &AH_connection_close),
GNUNET_GETOPT_option_string ('k',
"key",
"KEYFILE",
@@ -834,7 +798,7 @@ main (int argc,
GNUNET_GETOPT_option_string ('K',
"apikey",
"APIKEY",
- "API key to use in the HTTP request",
+ "API key to use in the HTTP request to the
merchant backend",
&apikey),
GNUNET_GETOPT_option_string ('t',
"type",
@@ -858,5 +822,5 @@ main (int argc,
return 3;
if (GNUNET_NO == res)
return 0;
- return (GNUNET_OK == result) ? 0 : 1;
+ return (GNUNET_OK == global_result) ? 0 : 1;
}
diff --git a/src/backend/anastasis-httpd.h b/src/backend/anastasis-httpd.h
index 317a9f3..96282e2 100644
--- a/src/backend/anastasis-httpd.h
+++ b/src/backend/anastasis-httpd.h
@@ -149,36 +149,6 @@ extern struct TALER_Amount AH_annual_fee;
*/
extern struct TALER_Amount AH_insurance;
-/**
- * Cost of authentication by question
- */
-extern struct TALER_Amount AH_question_cost;
-
-/**
- * Cost of authentication by email
- */
-extern struct TALER_Amount AH_email_cost;
-
-/**
- * Cost of authentication by post
- */
-extern struct TALER_Amount AH_post_cost;
-
-/**
- * Cost of authentication by file (for testing only)
- */
-extern struct TALER_Amount AH_file_cost;
-
-/**
- * Cost of authentication by video
- */
-extern struct TALER_Amount AH_video_cost;
-
-/**
- * Cost of authentication by sms
- */
-extern struct TALER_Amount AH_sms_cost;
-
/**
* Our Taler backend to process payments.
*/
@@ -190,10 +160,8 @@ extern char *AH_backend_url;
extern char *AH_currency;
/**
- * Supported methods.
+ * Our configuration.
*/
-extern char *AH_supported_methods;
-
extern const struct GNUNET_CONFIGURATION_Handle *AH_cfg;
/**
@@ -209,8 +177,7 @@ extern struct GNUNET_TIME_Relative AH_truth_expiration;
/**
* Our server salt.
*/
-extern char *AH_server_salt;
-
+extern struct ANASTASIS_CRYPTO_PowSalt AH_server_salt;
/**
* Our context for making HTTP requests.
diff --git a/src/backend/anastasis-httpd_config.c
b/src/backend/anastasis-httpd_config.c
index 3517586..e7e24bb 100644
--- a/src/backend/anastasis-httpd_config.c
+++ b/src/backend/anastasis-httpd_config.c
@@ -25,6 +25,54 @@
#include "anastasis-httpd_config.h"
#include <taler/taler_json_lib.h>
+
+/**
+ * Add enabled methods and their fees to the ``/config`` response.
+ *
+ * @param[in,out] cls a `json_t` array to build
+ * @param section configuration section to inspect
+ */
+static void
+add_methods (void *cls,
+ const char *section)
+{
+ json_t *method_arr = cls;
+ struct ANASTASIS_AuthorizationPlugin *p;
+ struct TALER_Amount cost;
+ json_t *method;
+
+ if (0 != strncasecmp (section,
+ "authorization-",
+ strlen ("authorization-")))
+ return;
+ if (GNUNET_YES !=
+ GNUNET_CONFIGURATION_get_value_yesno (AH_cfg,
+ section,
+ "ENABLED"))
+ return;
+ section += strlen ("authorization-");
+ p = ANASTASIS_authorization_plugin_load (section,
+ AH_cfg,
+ &cost);
+ if (NULL == p)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load authorization plugin `%s'\n",
+ section);
+ return;
+ }
+ method = json_pack ("{s:s, s:o}",
+ "method",
+ section,
+ "cost",
+ TALER_JSON_from_amount (&AH_question_cost));
+ GNUNET_assert (
+ 0 ==
+ json_array_append_new (method_arr,
+ method));
+}
+
+
/**
* Manages a /config call.
*
@@ -36,84 +84,19 @@ MHD_RESULT
AH_handler_config (struct TMH_RequestHandler *rh,
struct MHD_Connection *connection)
{
- json_t *methods = json_object ();
json_t *method_arr = json_array ();
- struct ANASTASIS_CRYPTO_PowSalt salt;
-
- if (! method_arr)
- return MHD_HTTP_BAD_GATEWAY;
- GNUNET_memcpy (&salt,
- AH_server_salt,
- strlen (AH_server_salt));
-
- if (strstr (AH_supported_methods, "question"))
- {
- json_t *question = json_pack ("{s:s, s:o}",
- "method",
- "question",
- "cost",
- TALER_JSON_from_amount (&AH_question_cost));
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr, question));
- }
- if (strstr (AH_supported_methods, "sms"))
- {
- json_t *sms = json_pack ("{s:s, s:o}",
- "method",
- "sms",
- "cost",
- TALER_JSON_from_amount (&AH_sms_cost));
-
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr, sms));
- }
- if (strstr (AH_supported_methods, "email"))
- {
- json_t *email = json_pack ("{s:s, s:o}",
- "method",
- "email",
- "cost",
- TALER_JSON_from_amount (&AH_email_cost));
-
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr, email));
- }
- if (strstr (AH_supported_methods, "video"))
- {
- json_t *video = json_pack ("{s:s, s:o}",
- "method",
- "video",
- "cost",
- TALER_JSON_from_amount (&AH_video_cost));
-
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr, video));
- }
- if (strstr (AH_supported_methods, "post"))
- {
- json_t *post = json_pack ("{s:s, s:o}",
- "method",
- "post",
- "cost",
- TALER_JSON_from_amount (&AH_post_cost));
-
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr, post));
- }
- json_object_set_new (methods, "methods", method_arr);
+ GNUNET_assert (NULL != method_arr);
+ GNUNET_CONFIGURATION_iterate_sections (AH_cfg,
+ &add_methods,
+ method_arr);
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:s, s:s, s:I, s:s, s:o, s:o, s:o, s:s}",
+ "{s:s, s:o, s:I, s:s, s:o, s:o, s:o, s:s}",
"name",
"anastasis",
"methods",
- json_dumps (methods, JSON_COMPACT),
+ method_arr,
"storage_limit_in_megabytes",
(json_int_t) AH_upload_limit_mb,
"currency",
@@ -123,8 +106,10 @@ AH_handler_config (struct TMH_RequestHandler *rh,
"insurance",
TALER_JSON_from_amount (&AH_insurance),
"server_salt",
- GNUNET_JSON_from_data_auto (&salt),
- "version", "0:0:0");
+ GNUNET_JSON_from_data_auto (
+ &AH_server_salt),
+ "version",
+ "0:0:0");
}
diff --git a/src/backend/anastasis-httpd_policy.c
b/src/backend/anastasis-httpd_policy.c
index 80d8203..23873c0 100644
--- a/src/backend/anastasis-httpd_policy.c
+++ b/src/backend/anastasis-httpd_policy.c
@@ -44,18 +44,14 @@
*
* @param connection MHD connection to use
* @param account account to query
- * @param default_http_status HTTP status to queue response
- * with on success (#MHD_HTTP_OK or #MHD_HTTP_CONFLICT)
* @return MHD result code
*/
-MHD_RESULT
-AH_return_policy (struct MHD_Connection *connection,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP *account_pub,
- unsigned int default_http_status)
+static MHD_RESULT
+return_policy (struct MHD_Connection *connection,
+ const struct ANASTASIS_CRYPTO_AccountPublicKeyP *account_pub)
{
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
struct MHD_Response *resp;
- MHD_RESULT ret;
struct ANASTASIS_AccountSignatureP account_sig;
struct GNUNET_HashCode recovery_data_hash;
const char *version_s;
@@ -68,14 +64,13 @@ AH_return_policy (struct MHD_Connection *connection,
"version");
if (NULL != version_s)
{
-
if (1 != sscanf (version_s,
"%u",
&version))
{
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- 43, // FIXME: use proper EC!
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
"version");
}
qs = db->get_recovery_document (db->cls,
@@ -97,50 +92,29 @@ AH_return_policy (struct MHD_Connection *connection,
&version);
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Account Signature from db: %s\n",
- TALER_B2S (&account_sig));
switch (qs)
{
- case ANASTASIS_DB_STATUS_OLD_RECOVERY_UPLOAD_MISSMATCH:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
-
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "unexpected return status (backup
mismatch)");
- case ANASTASIS_DB_STATUS_PAYMENT_REQUIRED:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
-
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "unexpected return status (payment
required)");
- case ANASTASIS_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"recovery document");
- case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_SOFT_FAILURE,
NULL);
- case ANASTASIS_DB_STATUS_NO_RESULTS:
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
"unexpected empty result set (try
again?)");
- case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
/* interesting case below */
break;
- default:
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "unexpected query status");
-
}
resp = MHD_create_response_from_buffer (res_recovery_data_size,
res_recovery_data,
@@ -148,84 +122,60 @@ AH_return_policy (struct MHD_Connection *connection,
TALER_MHD_add_global_headers (resp);
{
char *sig_s;
- // char *prev_s;
char *etag;
sig_s = GNUNET_STRINGS_data_to_string_alloc (&account_sig,
sizeof (account_sig));
- /*
- prev_s = GNUNET_STRINGS_data_to_string_alloc (&prev_hash,
- sizeof (prev_hash));
- */
etag = GNUNET_STRINGS_data_to_string_alloc (&recovery_data_hash,
sizeof (recovery_data_hash));
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
"Anastasis-Policy-Signature",
sig_s));
- /*
GNUNET_break (MHD_YES ==
- MHD_add_response_header (resp,
- "Anastasis-Previous",
- prev_s));
- */GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
MHD_HTTP_HEADER_ETAG,
etag));
GNUNET_free (etag);
- // GNUNET_free (prev_s);
GNUNET_free (sig_s);
}
- ret = MHD_queue_response (connection,
- default_http_status,
- resp);
- MHD_destroy_response (resp);
- return ret;
+ {
+ MHD_RESULT ret;
+
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
}
-/**
- * @param connection the MHD connection to handle
- * @param account_pub public key of the account
- * @return MHD result code
- */
MHD_RESULT
AH_policy_get (struct MHD_Connection *connection,
const struct ANASTASIS_CRYPTO_AccountPublicKeyP *account_pub)
{
struct GNUNET_HashCode recovery_data_hash;
- enum ANASTASIS_DB_QueryStatus qs;
+ enum ANASTASIS_DB_AccountStatus as;
MHD_RESULT ret;
- qs = db->lookup_account (db->cls,
+ as = db->lookup_account (db->cls,
account_pub,
&recovery_data_hash);
- switch (qs)
+ switch (as)
{
- case ANASTASIS_DB_STATUS_OLD_RECOVERY_UPLOAD_MISSMATCH:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
-
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "unexpected return status (backup
missing)");
- case ANASTASIS_DB_STATUS_PAYMENT_REQUIRED:
+ case ANASTASIS_DB_ACCOUNT_STATUS_PAYMENT_REQUIRED:
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_SYNC_ACCOUNT_UNKNOWN,
NULL);
- case ANASTASIS_DB_STATUS_HARD_ERROR:
+ case ANASTASIS_DB_ACCOUNT_STATUS_HARD_ERROR:
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"lookup account");
- case ANASTASIS_DB_STATUS_SOFT_ERROR:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_SOFT_FAILURE,
- NULL);
- case ANASTASIS_DB_STATUS_NO_RESULTS:
+ case ANASTASIS_DB_ACCOUNT_STATUS_NO_RESULTS:
{
struct MHD_Response *resp;
@@ -239,7 +189,7 @@ AH_policy_get (struct MHD_Connection *connection,
MHD_destroy_response (resp);
}
return ret;
- case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ case ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED:
{
const char *inm;
@@ -259,8 +209,8 @@ AH_policy_get (struct MHD_Connection *connection,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- TALER_EC_SYNC_BAD_IF_NONE_MATCH,
- "Etag does not include a
base32-encoded SHA-512 hash");
+
TALER_EC_ANASTASIS_BAD_IF_NONE_MATCH,
+ "Etag must be a base32-encoded
SHA-512 hash");
}
if (0 == GNUNET_memcmp (&inm_h,
&recovery_data_hash))
@@ -281,15 +231,7 @@ AH_policy_get (struct MHD_Connection *connection,
}
/* We have a result, should fetch and return it! */
break;
- default:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "unexpected database status code");
-
}
- return AH_return_policy (connection,
- account_pub,
- MHD_HTTP_OK);
+ return return_policy (connection,
+ account_pub);
}
diff --git a/src/backend/anastasis-httpd_policy.h
b/src/backend/anastasis-httpd_policy.h
index b525443..6285508 100644
--- a/src/backend/anastasis-httpd_policy.h
+++ b/src/backend/anastasis-httpd_policy.h
@@ -33,6 +33,8 @@ AH_resume_all_bc (void);
/**
+ * Handle GET /policy/$ACCOUNT_PUB request.
+ *
* @param connection the MHD connection to handle
* @param account_pub public key of the account
* @return MHD result code
@@ -59,20 +61,4 @@ AH_handler_policy_post (
size_t *upload_data_size);
-/**
- * Return the current recoverydocument of @a account on @a connection
- * using @a default_http_status on success.
- *
- * @param connection MHD connection to use
- * @param account account to query
- * @param default_http_status HTTP status to queue response
- * with on success (#MHD_HTTP_OK or #MHD_HTTP_CONFLICT)
- * @return MHD result code
- */
-MHD_RESULT
-AH_return_policy (struct MHD_Connection *connection,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP *account,
- unsigned int default_http_status);
-
-
#endif
diff --git a/src/backend/anastasis-httpd_policy_upload.c
b/src/backend/anastasis-httpd_policy_upload.c
index fa329e5..69b3ee5 100644
--- a/src/backend/anastasis-httpd_policy_upload.c
+++ b/src/backend/anastasis-httpd_policy_upload.c
@@ -70,6 +70,11 @@ struct PolicyUploadContext
*/
struct GNUNET_HashCode new_policy_upload_hash;
+ /**
+ * The claim token
+ */
+ struct TALER_ClaimTokenP claim_token;
+
/**
* Hash context for the upload.
*/
@@ -115,21 +120,16 @@ struct PolicyUploadContext
*/
const char *order_id;
- /**
- * Order ID for the client that we found in our database.
- */
- char *existing_order_id;
-
/**
* Payment Identifier
*/
struct ANASTASIS_PaymentSecretP payment_identifier;
/**
- * Timestamp of the order in @e existing_order_id. Used to
+ * Timestamp of the order in @e payment_identifier. Used to
* select the most recent unpaid offer.
*/
- struct GNUNET_TIME_Absolute existing_order_timestamp;
+ struct GNUNET_TIME_Absolute existing_pi_timestamp;
/**
* Expected total upload size.
@@ -156,11 +156,6 @@ struct PolicyUploadContext
*/
bool payment_identifier_provided;
- /**
- * The claim token
- */
- struct TALER_ClaimTokenP claim_token;
-
};
@@ -219,7 +214,6 @@ cleanup_ctx (struct TM_HandlerContext *hc)
GNUNET_CRYPTO_hash_context_abort (puc->hash_ctx);
if (NULL != puc->resp)
MHD_destroy_response (puc->resp);
- GNUNET_free (puc->existing_order_id);
GNUNET_free (puc->upload);
GNUNET_free (puc);
}
@@ -230,20 +224,22 @@ cleanup_ctx (struct TM_HandlerContext *hc)
*
* @param connection MHD connection
* @param order_id our backend's order ID
- * @return MHD response to use
+ * @return #GNUNET_OK on success
*/
-static struct MHD_Response *
-make_payment_request (const char *order_id)
+static int
+make_payment_request (struct PolicyUploadContext *puc)
{
struct MHD_Response *resp;
/* request payment via Taler */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Creating payment request for order `%s'\n",
- order_id);
resp = MHD_create_response_from_buffer (0,
NULL,
MHD_RESPMEM_PERSISTENT);
+ if (NULL == resp)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
TALER_MHD_add_global_headers (resp);
{
char *hdr;
@@ -268,28 +264,36 @@ make_payment_request (const char *order_id)
{
GNUNET_break (0);
MHD_destroy_response (resp);
- return NULL;
+ return GNUNET_SYSERR;
}
if (0 == strlen (hn))
{
GNUNET_break (0);
MHD_destroy_response (resp);
- return NULL;
+ return GNUNET_SYSERR;
+ }
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &puc->payment_identifier,
+ sizeof (puc->payment_identifier));
+ GNUNET_asprintf (&hdr,
+ "%spay/%s%s/",
+ pfx,
+ hn,
+ order_id);
+ GNUNET_free (order_id);
}
-
- GNUNET_asprintf (&hdr,
- "%spay/%s%s/",
- pfx,
- hn,
- order_id);
-
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
"Taler",
hdr));
GNUNET_free (hdr);
}
- return resp;
+ puc->resp = resp;
+ puc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ return GNUNET_OK;
}
@@ -316,14 +320,10 @@ proposal_cb (void *cls,
const struct TALER_MERCHANT_PostOrdersReply *por)
{
struct PolicyUploadContext *puc = cls;
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
uint32_t post_counter;
puc->po = NULL;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Resuming connection with order `%s'\n",
- puc->order_id);
GNUNET_CONTAINER_DLL_remove (puc_head,
puc_tail,
puc);
@@ -377,12 +377,15 @@ proposal_cb (void *cls,
puc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Obtained fresh order `%s'\n",
- por->details.ok.order_id);
- puc->resp = make_payment_request (por->details.ok.order_id);
- GNUNET_assert (NULL != puc->resp);
- puc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ if (GNUNET_OK !=
+ make_payment_request (puc))
+ {
+ GNUNET_break (0);
+ puc->resp = TALER_MHD_make_error (
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "failed to initiate payment");
+ puc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
}
@@ -392,13 +395,13 @@ proposal_cb (void *cls,
*
* @param cls closure, our `struct BackupContext`
* @param timestamp for how long have we been waiting
- * @param order_id order id in the backend
+ * @param ps payment secret in the backend
* @param amount how much is the order for
*/
static void
ongoing_payment_cb (void *cls,
struct GNUNET_TIME_Absolute timestamp,
- const char *order_id,
+ const struct ANASTASIS_PaymentSecretP *ps,
const struct TALER_Amount *amount)
{
struct PolicyUploadContext *puc = cls;
@@ -407,12 +410,10 @@ ongoing_payment_cb (void *cls,
if (0 != TALER_amount_cmp (amount,
&AH_annual_fee))
return; /* can't re-use, fees changed */
- if ( (NULL == puc->existing_order_id) ||
- (puc->existing_order_timestamp.abs_value_us < timestamp.abs_value_us) )
+ if (puc->existing_pi_timestamp.abs_value_us < timestamp.abs_value_us)
{
- GNUNET_free (puc->existing_order_id);
- puc->existing_order_id = GNUNET_strdup (order_id);
- puc->existing_order_timestamp = timestamp;
+ puc->payment_identifier = *ps;
+ puc->existing_pi_timestamp = timestamp;
}
}
@@ -428,7 +429,6 @@ static void
check_payment_cb (void *cls,
const struct TALER_MERCHANT_HttpResponse *hr,
const struct TALER_MERCHANT_OrderStatusResponse *osr)
-
{
struct PolicyUploadContext *puc = cls;
@@ -447,8 +447,7 @@ check_payment_cb (void *cls,
{
case TALER_MERCHANT_OSC_PAID:
{
-
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
qs = db->increment_lifetime (db->cls,
&puc->account,
@@ -467,14 +466,20 @@ check_payment_cb (void *cls,
case TALER_MERCHANT_OSC_CLAIMED:
break;
}
- if (NULL != puc->existing_order_id)
+ if (0 != puc->existing_pi_timestamp.abs_value_us)
{
/* repeat payment request */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Repeating payment request\n");
- puc->resp = make_payment_request (puc->existing_order_id);
- GNUNET_assert (NULL != puc->resp);
- puc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ if (GNUNET_OK !=
+ make_payment_request (puc))
+ {
+ GNUNET_break (0);
+ puc->resp = TALER_MHD_make_error (
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "failed to initiate payment");
+ puc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -492,26 +497,31 @@ check_payment_cb (void *cls,
*
* @param puc context to begin payment for.
* @param timeout when to give up trying
- * @param order_id which order to check for the payment
*/
static void
await_payment (struct PolicyUploadContext *puc,
- struct GNUNET_TIME_Relative timeout,
- const char *order_id)
+ struct GNUNET_TIME_Relative timeout)
{
GNUNET_CONTAINER_DLL_insert (puc_head,
puc_tail,
puc);
MHD_suspend_connection (puc->con);
- puc->order_id = order_id;
- puc->cpo = TALER_MERCHANT_merchant_order_get (AH_ctx,
- AH_backend_url,
- order_id,
- NULL /* our payments are NOT
session-bound */,
- false,
- timeout,
- &check_payment_cb,
- puc);
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &puc->payment_identifier,
+ sizeof (puc->payment_identifier));
+ puc->cpo = TALER_MERCHANT_merchant_order_get (AH_ctx,
+ AH_backend_url,
+ order_id,
+ NULL /* our payments are NOT
session-bound */,
+ false,
+ timeout,
+ &check_payment_cb,
+ puc);
+ GNUNET_free (order_id);
+ }
AH_trigger_curl ();
}
@@ -532,8 +542,7 @@ begin_payment (struct PolicyUploadContext *puc,
int pay_req)
{
json_t *order;
- enum ANASTASIS_DB_QueryStatus qs;
- const char *order_id;
+ enum GNUNET_DB_QueryStatus qs;
qs = db->lookup_pending_payments_by_account (db->cls,
&puc->account,
@@ -544,9 +553,8 @@ begin_payment (struct PolicyUploadContext *puc,
struct MHD_Response *resp;
MHD_RESULT ret;
- resp = TALER_MHD_make_error (
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "pending payments by account");
+ resp = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "pending payments by account");
ret = MHD_queue_response (puc->con,
MHD_HTTP_INTERNAL_SERVER_ERROR,
resp);
@@ -554,21 +562,13 @@ begin_payment (struct PolicyUploadContext *puc,
return ret;
}
- if (NULL != puc->existing_order_id)
+ if (0 != puc->existing_pi_timestamp.abs_value_us)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Have existing order, waiting for `%s' to complete\n",
- puc->existing_order_id);
await_payment (puc,
- GNUNET_TIME_UNIT_ZERO /* no long polling */,
- puc->existing_order_id);
+ GNUNET_TIME_UNIT_ZERO);
return MHD_YES;
}
- order_id = GNUNET_STRINGS_data_to_string_alloc (
- &puc->payment_identifier,
- sizeof(struct ANASTASIS_PaymentSecretP));
-
GNUNET_CONTAINER_DLL_insert (puc_head,
puc_tail,
puc);
@@ -576,12 +576,20 @@ begin_payment (struct PolicyUploadContext *puc,
"Suspending connection while creating order at `%s'\n",
AH_backend_url);
MHD_suspend_connection (puc->con);
- order = json_pack ("{s:o, s:s, s:s, s:s}",
- "amount", TALER_JSON_from_amount (&AH_annual_fee),
- "summary", "annual fee for anastasis service",
- "fulfillment_url", AH_fulfillment_url,
- "order_id", order_id);
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &puc->payment_identifier,
+ sizeof(struct ANASTASIS_PaymentSecretP));
+ order = json_pack ("{s:o, s:s, s:s, s:s}",
+ "amount", TALER_JSON_from_amount (&AH_annual_fee),
+ "summary", "annual fee for anastasis service",
+ "fulfillment_url", AH_fulfillment_url,
+ "order_id", order_id);
+ GNUNET_free (order_id);
+ }
puc->po = TALER_MERCHANT_orders_post2 (AH_ctx,
AH_backend_url,
order,
@@ -594,13 +602,40 @@ begin_payment (struct PolicyUploadContext *puc,
false, /* do NOT require claim token
*/
&proposal_cb,
puc);
-
AH_trigger_curl ();
json_decref (order);
return MHD_YES;
}
+/**
+ * Prepare to receive a payment, possibly requesting it, or just waiting
+ * for it to be completed by the client.
+ *
+ * @param puc context to prepare payment for
+ * @return MHD status
+ */
+static MHD_RESULT
+prepare_payment (struct PolicyUploadContext *puc)
+{
+ if (! puc->payment_identifier_provided)
+ {
+ GNUNET_CRYPTO_random_block (
+ GNUNET_CRYPTO_QUALITY_NONCE,
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Payment-Identifier generated: %s, starting payment process\n",
+ TALER_B2S (&puc->payment_identifier));
+ return begin_payment (puc,
+ GNUNET_NO);
+ }
+ await_payment (puc,
+ CHECK_PAYMENT_GENERIC_TIMEOUT);
+ return MHD_YES;
+}
+
+
/**
* We got some query status from the DB. Handle the error cases.
* May perform asynchronous operations by suspending the connection
@@ -612,69 +647,23 @@ begin_payment (struct PolicyUploadContext *puc,
*/
static MHD_RESULT
handle_database_error (struct PolicyUploadContext *puc,
- enum ANASTASIS_DB_QueryStatus qs)
+ enum GNUNET_DB_QueryStatus qs)
{
switch (qs)
{
- case ANASTASIS_DB_STATUS_OLD_RECOVERY_UPLOAD_MISSMATCH:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Update failed: prev_hash value not matching previous
version\n");
- return TALER_MHD_reply_with_error (puc->con,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_SYNC_PREVIOUS_BACKUP_UNKNOWN,
- "Cannot update, unknown previous
recovery document");
- case ANASTASIS_DB_STATUS_PAYMENT_REQUIRED:
- {
- if (! puc->payment_identifier_provided)
- {
- GNUNET_CRYPTO_random_block (
- GNUNET_CRYPTO_QUALITY_NONCE,
- &puc->payment_identifier,
- sizeof (struct ANASTASIS_PaymentSecretP));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Payment-Identifier generated: %s, starting payment
process\n",
- TALER_B2S (&puc->payment_identifier));
- return begin_payment (puc,
- GNUNET_NO);
- }
-
- {
- char *order_id;
-
- order_id = GNUNET_STRINGS_data_to_string_alloc (
- &puc->payment_identifier,
- sizeof (puc->payment_identifier));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Payment required, awaiting completion of `%s'\n",
- order_id);
- await_payment (puc,
- CHECK_PAYMENT_GENERIC_TIMEOUT,
- order_id);
- GNUNET_free (order_id);
- }
- }
- return MHD_YES;
- case ANASTASIS_DB_STATUS_HARD_ERROR:
- case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
return TALER_MHD_reply_with_error (puc->con,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
NULL);
- case ANASTASIS_DB_STATUS_NO_RESULTS:
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_assert (0);
return MHD_NO;
- /* intentional fall-through! */
- case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
GNUNET_assert (0);
return MHD_NO;
- /*Should never happen*/
- default:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (puc->con,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- NULL);
}
GNUNET_break (0);
return MHD_NO;
@@ -682,20 +671,14 @@ handle_database_error (struct PolicyUploadContext *puc,
MHD_RESULT
-AH_handler_policy_post (struct MHD_Connection *connection,
- struct TM_HandlerContext *hc,
- const struct
- ANASTASIS_CRYPTO_AccountPublicKeyP *account_pub,
- const char *recovery_data,
- size_t *recovery_data_size)
+AH_handler_policy_post (
+ struct MHD_Connection *connection,
+ struct TM_HandlerContext *hc,
+ const struct ANASTASIS_CRYPTO_AccountPublicKeyP *account_pub,
+ const char *recovery_data,
+ size_t *recovery_data_size)
{
struct PolicyUploadContext *puc = hc->ctx;
- struct TALER_Amount zero_amount;
- bool zero_cost = false;
-
- TALER_amount_get_zero (AH_currency, &zero_amount);
- if (0 == TALER_amount_cmp (&AH_annual_fee, &zero_amount))
- zero_cost = true;
if (NULL == puc)
{
@@ -714,30 +697,22 @@ AH_handler_policy_post (struct MHD_Connection *connection,
if (NULL != pay_id)
{
if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (pay_id,
- strlen (pay_id),
- &puc->payment_identifier,
- sizeof (struct
- ANASTASIS_PaymentSecretP)))
+ GNUNET_STRINGS_string_to_data (
+ pay_id,
+ strlen (pay_id),
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- // FIXME: find error code
- TALER_EC_SYNC_BAD_IF_MATCH,
- "Payment-Identifier does not
include a base32-encoded Payment-Secret");
+
TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "Payment-Identifier header must
be a base32-encoded Payment-Secret");
}
puc->payment_identifier_provided = true;
}
}
puc->account = *account_pub;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d public key is %s-%llu b\n",
- __FILE__,
- __LINE__,
- TALER_B2S (&puc->account),
- (unsigned long long) sizeof (struct
-
ANASTASIS_CRYPTO_AccountPublicKeyP));
/* now setup 'puc' */
{
const char *lens;
@@ -747,22 +722,18 @@ AH_handler_policy_post (struct MHD_Connection *connection,
MHD_HEADER_KIND,
MHD_HTTP_HEADER_CONTENT_LENGTH);
if ( (NULL == lens) ||
- (1 !=
- sscanf (lens,
- "%lu",
- &len)) )
+ (1 != sscanf (lens,
+ "%lu",
+ &len)) )
{
GNUNET_break_op (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- (NULL == lens)
- ?
- TALER_EC_SYNC_MISSING_CONTENT_LENGTH
- :
-
TALER_EC_SYNC_MALFORMED_CONTENT_LENGTH,
- (NULL == lens)
- ? "Content-length value missing"
- : "Content-length value malformed");
+ return TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_BAD_REQUEST,
+ (NULL == lens)
+ ? TALER_EC_ANASTASIS_MISSING_CONTENT_LENGTH
+ : TALER_EC_ANASTASIS_MALFORMED_CONTENT_LENGTH,
+ NULL);
}
if (len / 1024 / 1024 >= AH_upload_limit_mb)
{
@@ -779,13 +750,13 @@ AH_handler_policy_post (struct MHD_Connection *connection,
"malloc");
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_PAYLOAD_TOO_LARGE,
-
TALER_EC_SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH,
- "Server out of memory, try again
later");
+
TALER_EC_ANASTASIS_OUT_OF_MEMORY_ON_CONTENT_LENGTH,
+ NULL);
}
puc->upload_size = (size_t) len;
}
{
- // Check if header contains Anastasis-Policy-Signature
+ /* Check if header contains Anastasis-Policy-Signature */
const char *sig_s;
sig_s = MHD_lookup_connection_value (connection,
@@ -801,17 +772,12 @@ AH_handler_policy_post (struct MHD_Connection *connection,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- TALER_EC_SYNC_BAD_SYNC_SIGNATURE,
+
TALER_EC_ANASTASIS_BAD_POLICY_SIGNATURE,
"Anastasis-Policy-Signature does
not include a base32-encoded EdDSA signature");
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d Account Signature to save is: %s\n",
- __FILE__,
- __LINE__,
- TALER_B2S (&puc->account_sig));
}
{
- // Check if header contains an ETAG
+ /* Check if header contains an ETAG */
const char *etag;
etag = MHD_lookup_connection_value (connection,
@@ -827,8 +793,8 @@ AH_handler_policy_post (struct MHD_Connection *connection,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- TALER_EC_SYNC_BAD_IF_MATCH,
- "Etag does not include a
base32-encoded SHA-512 hash");
+ TALER_EC_ANASTASIS_BAD_IF_MATCH,
+ "Etag must include a base32-encoded
SHA-512 hash");
}
}
/* validate signature */
@@ -839,6 +805,7 @@ AH_handler_policy_post (struct MHD_Connection *connection,
// usp.old_recovery_data_hash = puc->old_policy_upload_hash,
.new_recovery_data_hash = puc->new_policy_upload_hash
};
+
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD,
&usp,
@@ -848,8 +815,8 @@ AH_handler_policy_post (struct MHD_Connection *connection,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
- TALER_EC_SYNC_INVALID_SIGNATURE,
- "Account signature does not match
upload");
+
TALER_EC_ANASTASIS_GENERIC_BAD_SIGNATURE,
+ "Anastasis-Policy-Signature");
}
}
/* get ready to hash (done here as we may go async for payments next) */
@@ -857,20 +824,12 @@ AH_handler_policy_post (struct MHD_Connection *connection,
/* Check database to see if the transaction is permissible */
{
- struct GNUNET_HashCode hc;
- enum ANASTASIS_DB_QueryStatus qs;
-
if (puc->payment_identifier_provided)
{
- // check if payment identifier is valid (existing and paid)
+ /* check if payment identifier is valid (existing and paid) */
bool paid;
bool valid_counter;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d Payment-Identifier from header is: %s\n",
- __FILE__,
- __LINE__,
- TALER_B2S (&puc->payment_identifier));
+ enum GNUNET_DB_QueryStatus qs;
qs = db->check_payment_identifier (db->cls,
&puc->payment_identifier,
@@ -880,31 +839,16 @@ AH_handler_policy_post (struct MHD_Connection *connection,
return handle_database_error (puc,
qs);
- if ((qs >= 0) && (! paid || ! valid_counter))
+ if ( (! paid) || (! valid_counter) )
{
- if (qs == 0)
+ if (0 == qs)
{
- // generate new payment identifier
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
- &puc->payment_identifier,
- sizeof (
- struct ANASTASIS_PaymentSecretP));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d Payment-Identifier generated is: %s\n",
- __FILE__,
- __LINE__,
- TALER_B2S (&puc->payment_identifier));
+ /* generate fresh payment identifier */
+ GNUNET_CRYPTO_random_block (
+ GNUNET_CRYPTO_QUALITY_STRONG,
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d paid is: '%d' and valid_counter is '%d'\n",
- __FILE__,
- __LINE__,
- paid,
- valid_counter);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "At %s:%d Payment is required, starting payment
process.\n",
- __FILE__,
- __LINE__);
return begin_payment (puc,
GNUNET_YES);
}
@@ -912,78 +856,39 @@ AH_handler_policy_post (struct MHD_Connection *connection,
if (! puc->payment_identifier_provided)
{
- // generate new payment identifier
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
- &puc->payment_identifier,
- sizeof (
- struct ANASTASIS_PaymentSecretP));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d Payment-Identifier generated is: %s\n",
- __FILE__,
- __LINE__,
- TALER_B2S (&puc->payment_identifier));
-
- if (zero_cost)
- {
- /** FIXME: not really reasonable */
- int post_counter = 10;
-
- qs = db->record_recdoc_payment (db->cls,
- account_pub,
- post_counter,
- &puc->payment_identifier,
- &AH_annual_fee);
- if (qs >= 0)
- {
- qs = db->increment_lifetime (db->cls,
- account_pub,
- &puc->payment_identifier,
- GNUNET_TIME_UNIT_YEARS);
- }
- if (qs < 0)
- return handle_database_error (puc,
- qs);
- }
+ struct TALER_Amount zero_amount;
+ enum GNUNET_DB_QueryStatus qs;
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "At %s:%d Payment is required, starting payment
process\n",
- __FILE__,
- __LINE__);
+ TALER_amount_get_zero (AH_currency,
+ &zero_amount);
+ /* generate fresh payment identifier */
+ GNUNET_CRYPTO_random_block (
+ GNUNET_CRYPTO_QUALITY_STRONG,
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
+ if (0 != TALER_amount_cmp (&AH_annual_fee,
+ &zero_amount))
return begin_payment (puc,
GNUNET_YES);
- }
- }
-
- qs = db->lookup_account (db->cls,
- account_pub,
- &hc);
-
- if (qs < 0)
- return handle_database_error (puc,
- qs);
- if (ANASTASIS_DB_STATUS_NO_RESULTS == qs)
- memset (&hc, 0, sizeof (hc));
- if (0 == GNUNET_memcmp (&hc,
- &puc->new_policy_upload_hash))
- {
- /* Refuse upload: we already have that backup! */
- struct MHD_Response *resp;
- MHD_RESULT ret;
-
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- TALER_MHD_add_global_headers (resp);
- ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_MODIFIED,
- resp);
- GNUNET_break (MHD_YES == ret);
- MHD_destroy_response (resp);
- return ret;
+ /* Cost is zero, fake "zero" payment having happened */
+ qs = db->record_recdoc_payment (db->cls,
+ account_pub,
+ 16 /* post_counter */,
+ &puc->payment_identifier,
+ &AH_annual_fee);
+ if (qs <= 0)
+ return handle_database_error (puc,
+ qs);
+ qs = db->increment_lifetime (db->cls,
+ account_pub,
+ &puc->payment_identifier,
+ GNUNET_TIME_UNIT_YEARS);
+ if (qs <= 0)
+ return handle_database_error (puc,
+ qs);
}
}
+
/* check if the client insists on paying */
{
const char *order_req;
@@ -992,16 +897,64 @@ AH_handler_policy_post (struct MHD_Connection *connection,
MHD_GET_ARGUMENT_KIND,
"pay");
if (NULL != order_req)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Payment requested, starting payment process\n");
return begin_payment (puc,
GNUNET_YES);
+ }
+
+ /* Check if existing policy matches upload (and if, skip it) */
+ {
+ struct GNUNET_HashCode hc;
+ enum ANASTASIS_DB_AccountStatus as;
+ uint32_t version;
+
+ as = db->lookup_account (db->cls,
+ account_pub,
+ &hc,
+ &version);
+ switch (as)
+ {
+ case ANASTASIS_DB_ACCOUNT_STATUS_PAYMENT_REQUIRED:
+ return prepare_payment (puc);
+ case ANASTASIS_DB_ACCOUNT_STATUS_HARD_ERROR:
+ return handle_database_error (puc,
+ GNUNET_DB_STATUS_HARD_ERROR);
+ case ANASTASIS_DB_ACCOUNT_STATUS_NO_RESULTS:
+ /* continue below */
+ break;
+ case ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED:
+ if (0 == GNUNET_memcmp (&hc,
+ &puc->new_policy_upload_hash))
+ {
+ /* Refuse upload: we already have that backup! */
+ struct MHD_Response *resp;
+ MHD_RESULT ret;
+ char version_s[14];
+
+ GNUNET_snprintf (version_s,
+ sizeof (version_s),
+ "%u",
+ (unsigned int) version);
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ "Anastasis-Version",
+ version_s));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ GNUNET_break (MHD_YES == ret);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ break;
}
}
/* ready to begin! */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Upload starting\n");
+ "Policy upload starting\n");
return MHD_YES;
}
@@ -1009,11 +962,6 @@ AH_handler_policy_post (struct MHD_Connection *connection,
if (0 != *recovery_data_size)
{
/* check MHD invariant */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Upload progressing\n");
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Processing %u bytes of recovery data\n",
- (unsigned int) *recovery_data_size);
GNUNET_assert (puc->upload_off + *recovery_data_size <= puc->upload_size);
memcpy (&puc->upload[puc->upload_off],
recovery_data,
@@ -1025,6 +973,7 @@ AH_handler_policy_post (struct MHD_Connection *connection,
*recovery_data_size = 0;
return MHD_YES;
}
+
if ( (0 == puc->upload_off) &&
(0 != puc->upload_size) &&
(NULL == puc->resp) )
@@ -1032,6 +981,7 @@ AH_handler_policy_post (struct MHD_Connection *connection,
/* wait for upload */
return MHD_YES;
}
+
if (NULL != puc->resp)
{
MHD_RESULT ret;
@@ -1065,20 +1015,20 @@ AH_handler_policy_post (struct MHD_Connection
*connection,
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
- TALER_EC_SYNC_INVALID_UPLOAD,
+
TALER_EC_ANASTASIS_INVALID_POLICY_UPLOAD,
"Data uploaded does not match Etag
promise");
}
}
/* store backup to database */
{
- enum ANASTASIS_DB_QueryStatus qs;
+ enum ANASTASIS_DB_StoreStatus ss;
+ uint32_t version = UINT32_MAX;
+ char version_s[14];
- // FIXME: version has to be delivered by header
- uint32_t version;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Uploading recovery document\n");
- qs = db->store_recovery_document (db->cls,
+ ss = db->store_recovery_document (db->cls,
&puc->account,
&puc->account_sig,
&puc->new_policy_upload_hash,
@@ -1086,47 +1036,76 @@ AH_handler_policy_post (struct MHD_Connection
*connection,
puc->upload_size,
&puc->payment_identifier,
&version);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "DB status after uploading recovery document: %i\n",
- qs);
- if (qs < 0)
- return handle_database_error (puc,
- qs);
- if (0 == qs)
+ GNUNET_snprintf (version_s,
+ sizeof (version_s),
+ "%u",
+ (unsigned int) version);
+ switch (ss)
{
- /* database says nothing actually changed, 304 (could
- theoretically happen if another equivalent upload succeeded
- since we last checked!) */
- struct MHD_Response *resp;
- MHD_RESULT ret;
-
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- TALER_MHD_add_global_headers (resp);
- ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_MODIFIED,
- resp);
- GNUNET_break (MHD_YES == ret);
- MHD_destroy_response (resp);
- return ret;
- }
- }
+ case ANASTASIS_DB_STORE_STATUS_STORE_LIMIT_EXCEEDED:
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
+ return begin_payment (puc,
+ GNUNET_YES);
+ case ANASTASIS_DB_STORE_STATUS_PAYMENT_REQUIRED:
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &puc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
+ return begin_payment (puc,
+ GNUNET_YES);
+ case ANASTASIS_DB_STORE_STATUS_HARD_ERROR:
+ return handle_database_error (puc,
+ GNUNET_DB_STATUS_HARD_ERROR);
+ case ANASTASIS_DB_STORE_STATUS_SOFT_ERROR:
+ return handle_database_error (puc,
+ GNUNET_DB_STATUS_SOFT_ERROR);
+ case ANASTASIS_DB_STORE_STATUS_NO_RESULTS:
+ {
+ /* database says nothing actually changed, 304 (could
+ theoretically happen if another equivalent upload succeeded
+ since we last checked!) */
+ struct MHD_Response *resp;
+ MHD_RESULT ret;
- /* generate main (204) standard success reply */
- {
- struct MHD_Response *resp;
- MHD_RESULT ret;
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ "Anastasis-Version",
+ version_s));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ GNUNET_break (MHD_YES == ret);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ case ANASTASIS_DB_STORE_STATUS_SUCCESS:
+ /* generate main (204) standard success reply */
+ {
+ struct MHD_Response *resp;
+ MHD_RESULT ret;
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- TALER_MHD_add_global_headers (resp);
- ret = MHD_queue_response (connection,
- MHD_HTTP_NO_CONTENT,
- resp);
- GNUNET_break (MHD_YES == ret);
- MHD_destroy_response (resp);
- return ret;
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ "Anastasis-Version",
+ version_s));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ resp);
+ GNUNET_break (MHD_YES == ret);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ }
}
+ GNUNET_break (0);
+ return MHD_NO;
}
diff --git a/src/backend/anastasis-httpd_salt.c
b/src/backend/anastasis-httpd_salt.c
index 4be8620..c965e70 100644
--- a/src/backend/anastasis-httpd_salt.c
+++ b/src/backend/anastasis-httpd_salt.c
@@ -21,34 +21,17 @@
* @author Christian Grothoff
*/
#include "platform.h"
-#include "anastasis-httpd.h"
#include "anastasis-httpd_salt.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_rest_lib.h>
-/**
- * @param connection the MHD connection to handle
- * @return MHD result code
- */
MHD_RESULT
AH_handler_salt (struct TMH_RequestHandler *rh,
struct MHD_Connection *connection)
{
- struct ANASTASIS_CRYPTO_PowSalt salt;
-
- GNUNET_memcpy (&salt,
- AH_server_salt,
- strlen (AH_server_salt));
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "At %s:%d Server Salt is %s-%llu b\n", __FILE__, __LINE__,
- TALER_B2S (&salt),
- (unsigned long long) sizeof (salt));
-
- return TALER_MHD_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "server_salt",
- GNUNET_JSON_from_data_auto (&salt));
+ return TALER_MHD_reply_json_pack (
+ connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "server_salt",
+ GNUNET_JSON_from_data_auto (&AH_server_salt));
}
diff --git a/src/backend/anastasis-httpd_salt.h
b/src/backend/anastasis-httpd_salt.h
index 6c46bd8..a60e481 100644
--- a/src/backend/anastasis-httpd_salt.h
+++ b/src/backend/anastasis-httpd_salt.h
@@ -22,9 +22,12 @@
*/
#ifndef ANASTASIS_HTTPD_SALT_H
#define ANASTASIS_HTTPD_SALT_H
-#include <microhttpd.h>
+
+#include "anastasis-httpd.h"
/**
+ * Return this providers salt.
+ *
* @param connection the MHD connection to handle
* @return MHD result code
*/
diff --git a/src/backend/anastasis-httpd_terms.c
b/src/backend/anastasis-httpd_terms.c
index 7e79a94..0819f73 100644
--- a/src/backend/anastasis-httpd_terms.c
+++ b/src/backend/anastasis-httpd_terms.c
@@ -35,7 +35,6 @@ MHD_RESULT
AH_handler_terms (struct TMH_RequestHandler *rh,
struct MHD_Connection *connection)
{
- // FIXME AGB
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:I, s:o, s:s}",
diff --git a/src/backend/anastasis-httpd_truth.c
b/src/backend/anastasis-httpd_truth.c
index 362835d..0b7cdd3 100644
--- a/src/backend/anastasis-httpd_truth.c
+++ b/src/backend/anastasis-httpd_truth.c
@@ -85,21 +85,11 @@ struct GetContext
*/
struct MHD_Response *resp;
- /**
- * Order under which the client promised payment, or NULL.
- */
- const char *order_id;
-
- /**
- * Order ID for the client that we found in our database.
- */
- char *existing_order_id;
-
/**
* Timestamp of the order in @e existing_order_id. Used to
* select the most recent unpaid offer.
*/
- struct GNUNET_TIME_Absolute existing_order_timestamp;
+ struct GNUNET_TIME_Absolute existing_pi_timestamp;
/**
* Payment Identifier
@@ -188,40 +178,44 @@ request_done (struct TM_HandlerContext *hc)
/**
* Transmit a payment request for @a order_id on @a connection
*
- * @param connection MHD connection
- * @param order_id our backend's order ID
+ * @param gc context to make payment request for
* @return MHD response to use
*/
-static struct MHD_Response *
-make_payment_request (const char *order_id)
+// FIXME: share logic with anastasis-http_policy_upload.c!
+static int
+make_payment_request (struct GetContext *gc)
{
struct MHD_Response *resp;
/* request payment via Taler */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Creating payment request for order `%s'\n",
- order_id);
resp = MHD_create_response_from_buffer (0,
NULL,
MHD_RESPMEM_PERSISTENT);
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (resp,
-
MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
- "*"));
+ if (NULL == resp)
+ return GNUNET_SYSERR;
+ TALER_MHD_add_global_headers (resp);
{
char *hdr;
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &gc->payment_identifier,
+ sizeof (gc->payment_identifier));
GNUNET_asprintf (&hdr,
"taler://pay/%s/%s",
AH_backend_url,
order_id);
+ GNUNET_free (order_id);
GNUNET_break (MHD_YES ==
MHD_add_response_header (resp,
"Taler",
hdr));
GNUNET_free (hdr);
}
- return resp;
+ gc->resp = resp;
+ gc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ return GNUNET_OK;
}
@@ -237,11 +231,8 @@ proposal_cb (void *cls,
const struct TALER_MERCHANT_PostOrdersReply *por)
{
struct GetContext *gc = cls;
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Resuming connection with order `%s'\n",
- gc->order_id);
GNUNET_CONTAINER_DLL_remove (gc_head,
gc_tail,
gc);
@@ -273,10 +264,6 @@ proposal_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Storing payment request for order `%s'\n",
por->details.ok.order_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Payment-Identifier to be saved to db: %s\n",
- TALER_B2S (&gc->payment_identifier));
-
qs = db->record_challenge_payment (db->cls,
&gc->truth_public_key,
&gc->payment_identifier,
@@ -292,9 +279,11 @@ proposal_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Obtained fresh order `%s'\n",
por->details.ok.order_id);
- gc->resp = make_payment_request (por->details.ok.order_id);
- GNUNET_assert (NULL != gc->resp);
- gc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ if (GNUNET_OK !=
+ make_payment_request (por->details.ok.order_id))
+ {
+ // FIXME: generate error!
+ }
}
@@ -304,7 +293,7 @@ return_key_share (const struct
struct MHD_Connection *connection)
{
// load encrypted keyshare from db
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
void *encrypted_keyshare;
size_t encrypted_keyshare_size;
struct MHD_Response *resp;
@@ -315,7 +304,7 @@ return_key_share (const struct
&encrypted_keyshare,
&encrypted_keyshare_size);
- if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT)
+ if (qs != GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)
{
return MHD_HTTP_NOT_FOUND;
}
@@ -338,27 +327,24 @@ return_key_share (const struct
*
* @param cls closure, our `struct BackupContext`
* @param timestamp for how long have we been waiting
- * @param order_id order id in the backend
+ * @param ps order id in the backend
* @param amount how much is the order for
*/
static void
ongoing_payment_cb (void *cls,
struct GNUNET_TIME_Absolute timestamp,
- const char *order_id,
+ const struct ANASTASIS_PaymentSecretP *ps,
const struct TALER_Amount *amount)
{
struct GetContext *gc = cls;
- (void) amount;
if (0 != TALER_amount_cmp (amount,
&gc->challenge_cost))
return; /* can't re-use, fees changed */
- if ( (NULL == gc->existing_order_id) ||
- (gc->existing_order_timestamp.abs_value_us < timestamp.abs_value_us) )
+ if (gc->existing_pi_timestamp.abs_value_us < timestamp.abs_value_us)
{
- GNUNET_free (gc->existing_order_id);
- gc->existing_order_id = GNUNET_strdup (order_id);
- gc->existing_order_timestamp = timestamp;
+ gc->payment_identifier = *ps;
+ gc->existing_pi_timestamp = timestamp;
}
}
@@ -391,7 +377,7 @@ check_payment_cb (void *cls,
if (osr->status)
{
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
qs = db->update_challenge_payment (db->cls,
&gc->truth_public_key,
@@ -404,14 +390,16 @@ check_payment_cb (void *cls,
gc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
return; /* continue as planned */
}
- if (NULL != gc->existing_order_id)
+ if (0 != gc->existing_pi_timestamp.abs_value_us)
{
/* repeat payment request */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Repeating payment request\n");
- gc->resp = make_payment_request (gc->existing_order_id);
- GNUNET_assert (NULL != gc->resp);
- gc->response_code = MHD_HTTP_PAYMENT_REQUIRED;
+ if (GNUNET_OK !=
+ make_payment_request (gc))
+ {
+ // FIXME: generate error
+ }
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -429,26 +417,31 @@ check_payment_cb (void *cls,
*
* @param puc context to begin payment for.
* @param timeout when to give up trying
- * @param order_id which order to check for the payment
*/
static void
await_payment (struct GetContext *gc,
- struct GNUNET_TIME_Relative timeout,
- const char *order_id)
+ struct GNUNET_TIME_Relative timeout)
{
GNUNET_CONTAINER_DLL_insert (gc_tail,
gc_head,
gc);
MHD_suspend_connection (gc->connection);
- gc->order_id = order_id;
- gc->cpo = TALER_MERCHANT_merchant_order_get (AH_ctx,
- AH_backend_url,
- order_id,
- NULL /* our payments are NOT
session-bound */,
- false,
- timeout,
- &check_payment_cb,
- gc);
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &gc->payment_identifier,
+ sizeof (gc->payment_identifier));
+ gc->cpo = TALER_MERCHANT_merchant_order_get (AH_ctx,
+ AH_backend_url,
+ order_id,
+ NULL /* our payments are NOT
session-bound */,
+ false,
+ timeout,
+ &check_payment_cb,
+ gc);
+ GNUNET_free (order_id);
+ }
AH_trigger_curl ();
}
@@ -469,8 +462,7 @@ begin_payment (struct GetContext *gc,
int pay_req)
{
json_t *order;
- enum ANASTASIS_DB_QueryStatus qs;
- const char *order_id;
+ enum GNUNET_DB_QueryStatus qs;
qs = db->lookup_challenge_payment (db->cls,
&gc->truth_public_key,
@@ -490,22 +482,13 @@ begin_payment (struct GetContext *gc,
return ret;
}
- if (NULL != gc->existing_order_id)
+ if (0 != gc->existing_pi_timestamp.abs_value_us)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Have existing order, waiting for `%s' to complete\n",
- gc->existing_order_id);
await_payment (gc,
- GNUNET_TIME_UNIT_ZERO /* no long polling */,
- gc->existing_order_id);
+ GNUNET_TIME_UNIT_ZERO);
return MHD_YES;
}
- order_id = GNUNET_STRINGS_data_to_string_alloc (&gc->payment_identifier,
- sizeof(
- struct
- ANASTASIS_PaymentSecretP));
-
GNUNET_CONTAINER_DLL_insert (gc_head,
gc_tail,
gc);
@@ -513,12 +496,19 @@ begin_payment (struct GetContext *gc,
"Suspending connection while creating order at `%s'\n",
AH_backend_url);
MHD_suspend_connection (gc->connection);
- order = json_pack ("{s:o, s:s, s:s, s:s}",
- "amount", TALER_JSON_from_amount (&gc->challenge_cost),
- "summary", "annual fee for anastasis service",
- "fulfillment_url", AH_fulfillment_url,
- "order_id", order_id);
-
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &gc->payment_identifier,
+ sizeof(struct ANASTASIS_PaymentSecretP));
+ order = json_pack ("{s:o, s:s, s:s, s:s}",
+ "amount", TALER_JSON_from_amount (&gc->challenge_cost),
+ "summary", "annual fee for anastasis service",
+ "fulfillment_url", AH_fulfillment_url,
+ "order_id", order_id);
+ GNUNET_free (order_id);
+ }
gc->po = TALER_MERCHANT_orders_post2 (AH_ctx,
AH_backend_url,
order,
@@ -561,27 +551,12 @@ handle_database_error (struct GetContext *gc,
GNUNET_CRYPTO_QUALITY_NONCE,
&gc->payment_identifier,
sizeof (struct ANASTASIS_PaymentSecretP));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Payment-Identifier generated: %s, starting payment
process\n",
- TALER_B2S (&gc->payment_identifier));
return begin_payment (gc,
GNUNET_NO);
}
- {
- char *order_id;
-
- order_id = GNUNET_STRINGS_data_to_string_alloc (
- &gc->payment_identifier,
- sizeof (gc->payment_identifier));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Payment required, awaiting completion of `%s'\n",
- order_id);
- await_payment (gc,
- CHECK_PAYMENT_GENERIC_TIMEOUT,
- order_id);
- GNUNET_free (order_id);
- }
+ await_payment (gc,
+ CHECK_PAYMENT_GENERIC_TIMEOUT);
}
return MHD_YES;
case ANASTASIS_DB_STATUS_HARD_ERROR:
@@ -778,7 +753,7 @@ AH_handler_truth_get (struct MHD_Connection *connection,
}
{
// load encrypted truth from db
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
qs = db->get_escrow_challenge (db->cls,
&truth_public_key,
@@ -786,7 +761,7 @@ AH_handler_truth_get (struct MHD_Connection *connection,
&encrypted_truth_size,
&truth_mime,
&method);
- if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT)
+ if (qs != GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)
{
return MHD_HTTP_NOT_FOUND;
}
@@ -819,7 +794,7 @@ AH_handler_truth_get (struct MHD_Connection *connection,
if (! zero_cost)
{
- enum ANASTASIS_DB_QueryStatus qs;
+ enum GNUNET_DB_QueryStatus qs;
if (0 == strcmp ("question",
method))
@@ -891,34 +866,34 @@ AH_handler_truth_get (struct MHD_Connection *connection,
}
}
+ GNUNET_free (decrypted_truth);
/* Not security question, check for answer in DB */
if (NULL != challenge_response_s)
{
- enum ANASTASIS_DB_QueryStatus qs;
+ enum ANASTASIS_DB_CodeStatus cs;
- qs = db->verify_challenge_code (db->cls,
+ cs = db->verify_challenge_code (db->cls,
&truth_public_key,
&challenge_response);
- switch (qs)
+ switch (cs)
{
+ case ANASTASIS_DB_STATUS_CHALLENGE_CODE_MISMATCH:
+
case ANASTASIS_DB_STATUS_HARD_ERROR:
- GNUNET_free (decrypted_truth);
+ // FIXME: proper reply!
return MHD_NO;
case ANASTASIS_DB_STATUS_SOFT_ERROR:
- GNUNET_free (decrypted_truth);
+ // FIXME: proper reply!
return MHD_NO;
case ANASTASIS_DB_STATUS_NO_RESULTS:
- GNUNET_free (decrypted_truth);
+ // FIXME: proper reply!
return MHD_NO;
case ANASTASIS_DB_STATUS_VALID_CODE_STORED:
- break;
- default:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
+ return return_key_share (&truth_public_key,
+ connection);
}
-
- return return_key_share (&truth_public_key,
- connection);
+ GNUNET_break (0);
+ return MHD_NO;
}
/* Not security question and no answer: use plugin to generate challenge! */
diff --git a/src/backend/anastasis_authorization_plugin.c
b/src/backend/anastasis_authorization_plugin.c
index 447365f..b79fb84 100644
--- a/src/backend/anastasis_authorization_plugin.c
+++ b/src/backend/anastasis_authorization_plugin.c
@@ -25,20 +25,35 @@
/**
- *Linked list for all loaded plugins
+ * Head of linked list for all loaded plugins
*/
static struct AuthPlugin *ap_head;
+
+/**
+ * Tail ofinked list for all loaded plugins
+ */
static struct AuthPlugin *ap_tail;
+
/**
* Authentication plugin which is used to verify code based authentication
* like SMS, E-Mail.
*/
struct AuthPlugin
{
+ /**
+ * Kept in a DLL.
+ */
struct AuthPlugin *next;
+
+ /**
+ * Kept in a DLL.
+ */
struct AuthPlugin *prev;
+ /**
+ * Actual plugin handle.
+ */
struct ANASTASIS_AuthorizationPlugin *authorization;
/**
@@ -46,31 +61,78 @@ struct AuthPlugin
*/
char *name;
+ /**
+ * Name of the shared object providing the plugin logic.
+ */
char *lib_name;
+
+ /**
+ * Cost of using this plugin.
+ */
+ struct TALER_Amount cost;
};
+
/**
* Load authorization plugin.
*
* @param method name of the method to load
+ * @param AH_cfg configuration to use
+ * @param[out] set to the cost for using the plugin during recovery
* @return #GNUNET_OK on success
*/
struct ANASTASIS_AuthorizationPlugin *
ANASTASIS_authorization_plugin_load (
const char *method,
- const struct GNUNET_CONFIGURATION_Handle *AH_cfg)
+ const struct GNUNET_CONFIGURATION_Handle *AH_cfg,
+ struct TALER_Amount *cost)
{
struct ANASTASIS_AuthorizationPlugin *authorization;
char *lib_name;
+ char *sec_name;
struct AuthPlugin *ap;
for (ap = ap_head; NULL != ap; ap = ap->next)
if (0 == strcmp (method,
ap->name))
+ {
+ *cost = ap->cost;
return ap->authorization;
- (void) GNUNET_asprintf (&lib_name,
- "libanastasis_plugin_authorization_%s",
- method);
+ }
+
+ ap = GNUNET_new (struct AuthPlugin);
+ GNUNET_asprintf (&sec_name,
+ "authorization-%s",
+ method);
+ if (GNUNET_OK !=
+ TALER_config_get_amount (AH_cfg,
+ sec_name,
+ "COST",
+ &ap->cost))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+ sec_name,
+ "COST");
+ GNUNET_free (sec_name);
+ GNUNET_free (ap);
+ return NULL;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&ap->cost,
+ &AH_annual_fee))
+ {
+ GNUNET_log_config_malformed (GNUNET_ERROR_TYPE_ERROR,
+ sec_name,
+ "COST",
+ "currency mismatch");
+ GNUNET_free (sec_name);
+ GNUNET_free (ap);
+ return NULL;
+ }
+ GNUNET_free (sec_name);
+ GNUNET_asprintf (&lib_name,
+ "libanastasis_plugin_authorization_%s",
+ method);
authorization = GNUNET_PLUGIN_load (lib_name,
(void *) AH_cfg);
if (NULL == authorization)
@@ -79,15 +141,16 @@ ANASTASIS_authorization_plugin_load (
"Authentication method `%s' not supported\n",
method);
GNUNET_free (lib_name);
+ GNUNET_free (ap);
return NULL;
}
- ap = GNUNET_new (struct AuthPlugin);
ap->name = GNUNET_strdup (method);
ap->lib_name = lib_name;
ap->authorization = authorization;
GNUNET_CONTAINER_DLL_insert (ap_head,
ap_tail,
ap);
+ *cost = ap->cost;
return authorization;
}
@@ -98,8 +161,8 @@ ANASTASIS_authorization_plugin_load (
* @param plugin the plugin to unload
*/
void
-ANASTASIS_authorization_plugin_unload
- (struct ANASTASIS_AuthorizationPlugin *plugin)
+ANASTASIS_authorization_plugin_unload (
+ struct ANASTASIS_AuthorizationPlugin *plugin)
{
char *lib_name;
@@ -116,6 +179,7 @@ void
ANASTASIS_authorization_plugin_shutdown (void)
{
struct AuthPlugin *ap;
+
while (NULL != (ap = ap_head))
{
GNUNET_CONTAINER_DLL_remove (ap_head,
@@ -140,7 +204,7 @@ static char *old_dlsearchpath;
* Setup libtool paths.
*/
void __attribute__ ((constructor))
-plugin_init ()
+anastasis_authorization_plugin_init (void)
{
int err;
const char *opath;
@@ -181,7 +245,7 @@ plugin_init ()
* Shutdown libtool.
*/
void __attribute__ ((destructor))
-plugin_fini ()
+anastasis_authorization_plugin_fini (void)
{
lt_dlsetsearchpath (old_dlsearchpath);
if (NULL != old_dlsearchpath)
diff --git a/src/backend/anastasis_authorization_plugin_email.c
b/src/backend/anastasis_authorization_plugin_email.c
index a38c414..c203526 100644
--- a/src/backend/anastasis_authorization_plugin_email.c
+++ b/src/backend/anastasis_authorization_plugin_email.c
@@ -27,27 +27,30 @@
/**
- * Saves the State of a authorization process
+ * Saves the state of a authorization process
*/
-
struct ANASTASIS_AUTHORIZATION_State
{
/**
* Public key of the challenge which is authorised
*/
const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key;
+
/**
* Code which is sent to the user (here saved into a file)
*/
uint64_t code;
+
/**
* holds the truth information
*/
char *email;
+
/**
* closure
*/
void *cls;
+
/**
* Command which is executed to run the email authentication
*/
@@ -164,7 +167,6 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as,
/*FIXME ERROR HANDLING*/
int ret = pipe (p);
-
pid_t pid = fork ();
switch (pid)
{
@@ -233,13 +235,13 @@ libanastasis_plugin_authorization_email_init (void *cls)
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
- "anastasis",
- "EMAILAUTH_COMMAND",
+ "authorization-email",
+ "COMMAND",
&plugin->auth_command))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "anastasis",
- "EMAILAUTH_COMMAND");
+ "authorization-email",
+ "COMMAND");
GNUNET_free (plugin);
return NULL;
}
diff --git a/src/backend/anastasis_authorization_plugin_file.c
b/src/backend/anastasis_authorization_plugin_file.c
index 4c6bc8a..e23a21b 100644
--- a/src/backend/anastasis_authorization_plugin_file.c
+++ b/src/backend/anastasis_authorization_plugin_file.c
@@ -25,23 +25,25 @@
/**
- * Saves the State of a authorization process
+ * Saves the state of a authorization process
*/
-
struct ANASTASIS_AUTHORIZATION_State
{
/**
* Public key of the challenge which is authorised
*/
const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key;
+
/**
* Code which is sent to the user (here saved into a file)
*/
uint64_t code;
+
/**
* holds the truth information
*/
char *filename;
+
/**
* closure
*/
@@ -72,28 +74,24 @@ file_validate (void *cls,
size_t data_length)
{
char *filename;
+ bool flag;
- if (data == NULL)
- {
+ if (NULL == data)
return GNUNET_NO;
- }
-
filename = GNUNET_STRINGS_data_to_string_alloc (data,
data_length);
- int i = 0;
- int flag = 0;
- for (i = 0; i<strlen (filename); i++)
+ flag = false;
+ for (size_t i = 0; i<strlen (filename); i++)
{
- if ((filename[i] == ' ') || (filename[i] == '/'))
+ if ( (filename[i] == ' ') ||
+ (filename[i] == '/') )
{
- flag = 1;
+ flag = true;
break;
}
}
- if (flag == 1)
- {
+ if (flag)
return GNUNET_NO;
- }
GNUNET_free (filename);
return GNUNET_OK;
}
@@ -177,8 +175,7 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as,
return ANASTASIS_AUTHORIZATION_RES_FAILED;
}
fclose (f);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Filename before: %s", as->filename);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STRLEN: %ld",strlen (as->filename));
+
size_t response_size;
response_size = strlen (as->filename) * 5 / 8;
void *response = malloc (response_size);
@@ -188,9 +185,6 @@ file_process (struct ANASTASIS_AUTHORIZATION_State *as,
response_size);
char *test = GNUNET_STRINGS_data_to_string_alloc (response,
response_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Filename after: %s", test);
-
-
resp = MHD_create_response_from_buffer (response_size,
response,
MHD_RESPMEM_MUST_FREE);
@@ -248,6 +242,7 @@ void *
libanastasis_plugin_authorization_file_done (void *cls)
{
struct ANASTASIS_AuthorizationPlugin *plugin = cls;
+
GNUNET_free (plugin);
return NULL;
}
diff --git a/src/backend/anastasis_authorization_plugin_sms.c
b/src/backend/anastasis_authorization_plugin_sms.c
index e40789a..f3d1ea8 100644
--- a/src/backend/anastasis_authorization_plugin_sms.c
+++ b/src/backend/anastasis_authorization_plugin_sms.c
@@ -228,12 +228,12 @@ libanastasis_plugin_authorization_sms_init (void *cls)
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
- "anastasis",
+ "authorization-sms",
"SMSAUTH_COMMAND",
&plugin->auth_command))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "anastasis",
+ "authorization-sms",
"SMSAUTH_COMMAND");
GNUNET_free (plugin);
return NULL;
diff --git a/src/include/anastasis_crypto_lib.h
b/src/include/anastasis_crypto_lib.h
index bad543d..b2ef561 100644
--- a/src/include/anastasis_crypto_lib.h
+++ b/src/include/anastasis_crypto_lib.h
@@ -78,7 +78,7 @@ struct ANASTASIS_CRYPTO_SaltP
/**
* Specifies a Salt value of size 16 Byte for GNUNET_CRYPTO_pow_hash.
-*/
+ */
struct ANASTASIS_CRYPTO_PowSalt
{
struct GNUNET_CRYPTO_PowSalt salt;
diff --git a/src/include/anastasis_database_plugin.h
b/src/include/anastasis_database_plugin.h
index 419a7de..43f407f 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -152,11 +152,11 @@ struct ANASTASIS_DB_Truth
* @param amount how much is the order for
*/
typedef void
-(*ANASTASIS_DB_PaymentPendingIterator)(void *cls,
- struct GNUNET_TIME_Absolute timestamp,
- struct ANASTASIS_PaymentSecretP *
- payment_secret,
- const struct TALER_Amount *amount);
+(*ANASTASIS_DB_PaymentPendingIterator)(
+ void *cls,
+ struct GNUNET_TIME_Absolute timestamp,
+ const struct ANASTASIS_PaymentSecretP *payment_secret,
+ const struct TALER_Amount *amount);
/**
@@ -401,13 +401,15 @@ struct ANASTASIS_DatabasePlugin
* @param cls closure
* @param anastasis_pub account identifier
* @param[out] recovery_data_hash set to hash of @a recovery document
+ * @param[out] version set to the recovery policy version
* @return transaction status
*/
enum ANASTASIS_DB_AccountStatus
(*lookup_account)(
void *cls,
const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub,
- struct GNUNET_HashCode *recovery_data_hash);
+ struct GNUNET_HashCode *recovery_data_hash,
+ uint32_t *version);
/**
diff --git a/src/stasis/plugin_anastasis_postgres.c
b/src/stasis/plugin_anastasis_postgres.c
index aad7829..c2727b7 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -711,8 +711,6 @@ postgres_increment_lifetime (
GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
GNUNET_PQ_query_param_end
};
- check_connection (pg);
- postgres_preflight (pg);
qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
"recdoc_payment_done",
params);
@@ -1161,13 +1159,15 @@ postgres_get_key_share (
* @param cls closure
* @param anastasis_pub account identifier
* @param[out] recovery_data_hash set to hash of @a recovery document
+ * @param[out] version set to the recovery policy version
* @return transaction status
*/
enum ANASTASIS_DB_AccountStatus
postgres_lookup_account (
void *cls,
const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub,
- struct GNUNET_HashCode *recovery_data_hash)
+ struct GNUNET_HashCode *recovery_data_hash,
+ uint32_t *version)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
@@ -1182,11 +1182,13 @@ postgres_lookup_account (
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("recovery_data_hash",
recovery_data_hash),
+ GNUNET_PQ_result_spec_uint32 ("version",
+ version),
GNUNET_PQ_result_spec_end
};
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-
"recoverydocument_select_hash",
+
"latest_recovery_version_select",
params,
rs);
}
@@ -1824,16 +1826,6 @@ libanastasis_plugin_db_postgres_init (void *cls)
"anastasis_truth "
"WHERE truth_public_key =$1;",
1),
- GNUNET_PQ_make_prepare ("recoverydocument_select_hash",
- "SELECT "
- " recovery_data_hash "
- "FROM"
- " anastasis_recoverydocument "
- "WHERE"
- " user_id=$1"
- " ORDER BY version DESC "
- "LIMIT 1;",
- 1),
GNUNET_PQ_make_prepare ("challengecode_insert",
"INSERT INTO anastasis_challengecode "
"(truth_public_key"
diff --git a/src/stasis/test_anastasis_db.c b/src/stasis/test_anastasis_db.c
index 056a7ac..7d7d6fa 100644
--- a/src/stasis/test_anastasis_db.c
+++ b/src/stasis/test_anastasis_db.c
@@ -193,10 +193,15 @@ run (void *cls)
strlen (recovery_data),
&paymentSecretP,
&docVersion));
- FAILIF (ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED !=
- plugin->lookup_account (plugin->cls,
- &accountPubP,
- &r));
+ {
+ uint32_t vrs;
+
+ FAILIF (ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED !=
+ plugin->lookup_account (plugin->cls,
+ &accountPubP,
+ &r,
+ &vrs));
+ }
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_key_share (plugin->cls,
&truth_public_key,
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: WIP backend refactor,
gnunet <=