summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-06-21 09:00:58 +0200
committerChristian Grothoff <christian@grothoff.org>2023-06-21 09:00:58 +0200
commitf5ce22ddf6da6aae6a9077dba122013c1dbc55d9 (patch)
treedc80e36922103c8008fab36a825b1c0e3b1cae22
parentaf77a2a178a818abe851e4e25e768e2c1963b49c (diff)
downloadexchange-f5ce22ddf6da6aae6a9077dba122013c1dbc55d9.tar.gz
exchange-f5ce22ddf6da6aae6a9077dba122013c1dbc55d9.tar.bz2
exchange-f5ce22ddf6da6aae6a9077dba122013c1dbc55d9.zip
-more clean up of auditor api: atomization complete
-rw-r--r--src/include/taler_auditor_service.h55
-rw-r--r--src/include/taler_testing_lib.h1
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/auditor_api_deposit_confirmation.c3
-rw-r--r--src/lib/auditor_api_exchanges.c3
-rw-r--r--src/lib/auditor_api_get_config.c288
-rw-r--r--src/lib/auditor_api_handle.c438
-rw-r--r--src/lib/auditor_api_handle.h59
-rw-r--r--src/lib/exchange_api_handle.c23
-rw-r--r--src/testing/test_auditor_api_version.c19
-rw-r--r--src/testing/testing_api_cmd_get_auditor.c27
11 files changed, 363 insertions, 555 deletions
diff --git a/src/include/taler_auditor_service.h b/src/include/taler_auditor_service.h
index 2c6685c1c..3d8ca9efb 100644
--- a/src/include/taler_auditor_service.h
+++ b/src/include/taler_auditor_service.h
@@ -28,12 +28,12 @@
#include <gnunet/gnunet_curl_lib.h>
-/* ********************* /version *********************** */
+/* ********************* /config *********************** */
/**
- * @brief Information we get from the auditor about auditors.
+ * @brief Information we get from the auditor about itself.
*/
-struct TALER_AUDITOR_VersionInformation
+struct TALER_AUDITOR_ConfigInformation
{
/**
* Public key of the auditing institution. Wallets and merchants
@@ -147,9 +147,9 @@ struct TALER_AUDITOR_HttpResponse
/**
- * Response to /version request.
+ * Response to /config request.
*/
-struct TALER_AUDITOR_VersionResponse
+struct TALER_AUDITOR_ConfigResponse
{
/**
* HTTP response.
@@ -174,11 +174,12 @@ struct TALER_AUDITOR_VersionResponse
enum TALER_AUDITOR_VersionCompatibility compat;
/**
- * Version data returned by /config.
+ * Config data returned by /config.
*/
- struct TALER_AUDITOR_VersionInformation vi;
+ struct TALER_AUDITOR_ConfigInformation vi;
} ok;
+
} details;
};
@@ -191,46 +192,45 @@ struct TALER_AUDITOR_VersionResponse
* @param vr response data
*/
typedef void
-(*TALER_AUDITOR_VersionCallback) (
+(*TALER_AUDITOR_ConfigCallback) (
void *cls,
- const struct TALER_AUDITOR_VersionResponse *vr);
+ const struct TALER_AUDITOR_ConfigResponse *vr);
/**
* @brief Handle to the auditor. This is where we interact with
* a particular auditor and keep the per-auditor information.
*/
-struct TALER_AUDITOR_Handle;
+struct TALER_AUDITOR_GetConfigHandle;
/**
- * Initialise a connection to the auditor. Will connect to the
+ * Obtain meta data about an auditor. Will connect to the
* auditor and obtain information about the auditor's master public
* key and the auditor's auditor. The respective information will
- * be passed to the @a version_cb once available, and all future
- * interactions with the auditor will be checked to be signed
- * (where appropriate) by the respective master key.
+ * be passed to the @a config_cb once available.
*
* @param ctx the context for CURL requests
* @param url HTTP base URL for the auditor
- * @param version_cb function to call with the auditor's version information
- * @param version_cb_cls closure for @a version_cb
+ * @param config_cb function to call with the auditor's config information
+ * @param config_cb_cls closure for @a config_cb
* @return the auditor handle; NULL upon error
*/
-struct TALER_AUDITOR_Handle *
-TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_AUDITOR_VersionCallback version_cb,
- void *version_cb_cls);
+struct TALER_AUDITOR_GetConfigHandle *
+TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_AUDITOR_ConfigCallback config_cb,
+ void *config_cb_cls);
/**
- * Disconnect from the auditor.
+ * Cancel auditor config request.
*
* @param auditor the auditor handle
*/
void
-TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor);
+TALER_AUDITOR_get_config_cancel (struct
+ TALER_AUDITOR_GetConfigHandle *auditor);
/**
@@ -271,11 +271,10 @@ typedef void
* that the response is well-formed. If the auditor's reply is not
* well-formed, we return an HTTP status code of zero to @a cb.
*
- * We also verify that the @a exchange_sig is valid for this deposit-confirmation
- * request, and that the @a master_sig is a valid signature for @a
- * exchange_pub. Also, the @a auditor must be ready to operate (i.e. have
- * finished processing the /version reply). If either check fails, we do
- * NOT initiate the transaction with the auditor and instead return NULL.
+ * We also verify that the @a exchange_sig is valid for this
+ * deposit-confirmation request, and that the @a master_sig is a valid
+ * signature for @a exchange_pub. If the check fails, we do NOT initiate the
+ * transaction with the auditor and instead return NULL.
*
* @param ctx the context for CURL requests
* @param url HTTP base URL for the auditor
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 175d25e66..2c9f58596 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -2692,7 +2692,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
op (claim_token, const struct TALER_ClaimTokenP) \
op (relative_time, const struct GNUNET_TIME_Relative) \
- op (auditor, struct TALER_AUDITOR_Handle) \
op (exchange, struct TALER_EXCHANGE_Handle) \
op (fakebank, struct TALER_FAKEBANK_Handle) \
op (process, struct GNUNET_OS_Process *)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 529a2d019..2c9031428 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -96,7 +96,7 @@ libtalerauditor_la_LDFLAGS = \
-no-undefined
libtalerauditor_la_SOURCES = \
auditor_api_curl_defaults.c auditor_api_curl_defaults.h \
- auditor_api_handle.c auditor_api_handle.h \
+ auditor_api_get_config.c \
auditor_api_deposit_confirmation.c \
auditor_api_exchanges.c
libtalerauditor_la_LIBADD = \
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
index 21479c106..0b0f4dd4d 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -25,9 +25,10 @@
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include <gnunet/gnunet_curl_lib.h>
+#include "taler_util.h"
+#include "taler_curl_lib.h"
#include "taler_json_lib.h"
#include "taler_auditor_service.h"
-#include "auditor_api_handle.h"
#include "taler_signatures.h"
#include "auditor_api_curl_defaults.h"
diff --git a/src/lib/auditor_api_exchanges.c b/src/lib/auditor_api_exchanges.c
index 8acf59467..897dfe60f 100644
--- a/src/lib/auditor_api_exchanges.c
+++ b/src/lib/auditor_api_exchanges.c
@@ -27,7 +27,8 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_json_lib.h"
#include "taler_auditor_service.h"
-#include "auditor_api_handle.h"
+#include "taler_util.h"
+#include "taler_curl_lib.h"
#include "taler_signatures.h"
#include "auditor_api_curl_defaults.h"
diff --git a/src/lib/auditor_api_get_config.c b/src/lib/auditor_api_get_config.c
new file mode 100644
index 000000000..ede702a0d
--- /dev/null
+++ b/src/lib/auditor_api_get_config.c
@@ -0,0 +1,288 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file lib/auditor_api_get_config.c
+ * @brief Implementation of /config for the auditor's HTTP API
+ * @author Sree Harsha Totakura <sreeharsha@totakura.in>
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <microhttpd.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_json_lib.h"
+#include "taler_auditor_service.h"
+#include "taler_signatures.h"
+#include "auditor_api_curl_defaults.h"
+
+
+/**
+ * Which revision of the Taler auditor protocol is implemented
+ * by this library? Used to determine compatibility.
+ */
+#define TALER_PROTOCOL_CURRENT 0
+
+/**
+ * How many revisions back are we compatible to?
+ */
+#define TALER_PROTOCOL_AGE 0
+
+
+/**
+ * Log error related to CURL operations.
+ *
+ * @param type log level
+ * @param function which function failed to run
+ * @param code what was the curl error code
+ */
+#define CURL_STRERROR(type, function, code) \
+ GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \
+ function, __FILE__, __LINE__, curl_easy_strerror (code));
+
+
+/**
+ * Handle for the get config request.
+ */
+struct TALER_AUDITOR_GetConfigHandle
+{
+ /**
+ * The context of this handle
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * Function to call with the auditor's certification data,
+ * NULL if this has already been done.
+ */
+ TALER_AUDITOR_ConfigCallback config_cb;
+
+ /**
+ * Closure to pass to @e config_cb.
+ */
+ void *config_cb_cls;
+
+ /**
+ * Data for the request to get the /config of a auditor,
+ * NULL once we are past stage #MHS_INIT.
+ */
+ struct GNUNET_CURL_Job *vr;
+
+ /**
+ * The url for the @e vr job.
+ */
+ char *vr_url;
+
+};
+
+
+/* ***************** Internal /config fetching ************* */
+
+/**
+ * Decode the JSON in @a resp_obj from the /config response and store the data
+ * in the @a key_data.
+ *
+ * @param[in] resp_obj JSON object to parse
+ * @param[in,out] auditor where to store the results we decoded
+ * @param[out] vc where to store config compatibility data
+ * @return #TALER_EC_NONE on success
+ */
+static enum TALER_ErrorCode
+decode_config_json (const json_t *resp_obj,
+ struct TALER_AUDITOR_ConfigInformation *vi,
+ enum TALER_AUDITOR_VersionCompatibility *vc)
+{
+ unsigned int age;
+ unsigned int revision;
+ unsigned int current;
+ char dummy;
+ const char *ver;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("version",
+ &ver),
+ GNUNET_JSON_spec_fixed_auto ("auditor_public_key",
+ &vi->auditor_pub),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (JSON_OBJECT != json_typeof (resp_obj))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_JSON_INVALID;
+ }
+ /* check the config */
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (resp_obj,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_JSON_INVALID;
+ }
+ if (3 != sscanf (ver,
+ "%u:%u:%u%c",
+ &current,
+ &revision,
+ &age,
+ &dummy))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_VERSION_MALFORMED;
+ }
+ vi->version = ver;
+ *vc = TALER_AUDITOR_VC_MATCH;
+ if (TALER_PROTOCOL_CURRENT < current)
+ {
+ *vc |= TALER_AUDITOR_VC_NEWER;
+ if (TALER_PROTOCOL_CURRENT < current - age)
+ *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
+ }
+ if (TALER_PROTOCOL_CURRENT > current)
+ {
+ *vc |= TALER_AUDITOR_VC_OLDER;
+ if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
+ *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
+ }
+ return TALER_EC_NONE;
+}
+
+
+/**
+ * Callback used when downloading the reply to a /config request
+ * is complete.
+ *
+ * @param cls the `struct TALER_AUDITOR_GetConfigHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
+ */
+static void
+config_completed_cb (void *cls,
+ long response_code,
+ const void *gresp_obj)
+{
+ struct TALER_AUDITOR_GetConfigHandle *auditor = cls;
+ const json_t *resp_obj = gresp_obj;
+ struct TALER_AUDITOR_ConfigResponse vr = {
+ .hr.reply = resp_obj,
+ .hr.http_status = (unsigned int) response_code
+ };
+
+ auditor->vr = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received config from URL `%s' with status %ld.\n",
+ auditor->vr_url,
+ response_code);
+ switch (response_code)
+ {
+ case 0:
+ GNUNET_break_op (0);
+ vr.hr.ec = TALER_EC_INVALID;
+ break;
+ case MHD_HTTP_OK:
+ if (NULL == resp_obj)
+ {
+ GNUNET_break_op (0);
+ vr.hr.http_status = 0;
+ vr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ }
+ vr.hr.ec = decode_config_json (resp_obj,
+ &vr.details.ok.vi,
+ &vr.details.ok.compat);
+ if (TALER_EC_NONE != vr.hr.ec)
+ {
+ GNUNET_break_op (0);
+ vr.hr.http_status = 0;
+ break;
+ }
+ break;
+ case MHD_HTTP_INTERNAL_SERVER_ERROR:
+ vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
+ vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
+ break;
+ default:
+ vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
+ vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u/%d\n",
+ (unsigned int) response_code,
+ (int) vr.hr.ec);
+ break;
+ }
+ auditor->config_cb (auditor->config_cb_cls,
+ &vr);
+ TALER_AUDITOR_get_config_cancel (auditor);
+}
+
+
+struct TALER_AUDITOR_GetConfigHandle *
+TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_AUDITOR_ConfigCallback config_cb,
+ void *config_cb_cls)
+{
+ struct TALER_AUDITOR_GetConfigHandle *auditor;
+ CURL *eh;
+
+ auditor = GNUNET_new (struct TALER_AUDITOR_GetConfigHandle);
+ auditor->config_cb = config_cb;
+ auditor->config_cb_cls = config_cb_cls;
+ auditor->ctx = ctx;
+ auditor->vr_url = TALER_url_join (url,
+ "config",
+ NULL);
+ if (NULL == auditor->vr_url)
+ {
+ GNUNET_break (0);
+ GNUNET_free (auditor->vr_url);
+ GNUNET_free (auditor);
+ return NULL;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting auditor config with URL `%s'.\n",
+ auditor->vr_url);
+ eh = TALER_AUDITOR_curl_easy_get_ (auditor->vr_url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ TALER_AUDITOR_get_config_cancel (auditor);
+ return NULL;
+ }
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TIMEOUT,
+ (long) 300));
+ auditor->vr = GNUNET_CURL_job_add (auditor->ctx,
+ eh,
+ &config_completed_cb,
+ auditor);
+ return auditor;
+}
+
+
+void
+TALER_AUDITOR_get_config_cancel (struct TALER_AUDITOR_GetConfigHandle *auditor)
+{
+ if (NULL != auditor->vr)
+ {
+ GNUNET_CURL_job_cancel (auditor->vr);
+ auditor->vr = NULL;
+ }
+ GNUNET_free (auditor->vr_url);
+ GNUNET_free (auditor);
+}
+
+
+/* end of auditor_api_get_config.c */
diff --git a/src/lib/auditor_api_handle.c b/src/lib/auditor_api_handle.c
deleted file mode 100644
index 318b63f94..000000000
--- a/src/lib/auditor_api_handle.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_handle.c
- * @brief Implementation of the "handle" component of the auditor's HTTP API
- * @author Sree Harsha Totakura <sreeharsha@totakura.in>
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_auditor_service.h"
-#include "taler_signatures.h"
-#include "auditor_api_handle.h"
-#include "auditor_api_curl_defaults.h"
-#include "backoff.h"
-
-/**
- * Which revision of the Taler auditor protocol is implemented
- * by this library? Used to determine compatibility.
- */
-#define TALER_PROTOCOL_CURRENT 0
-
-/**
- * How many revisions back are we compatible to?
- */
-#define TALER_PROTOCOL_AGE 0
-
-
-/**
- * Log error related to CURL operations.
- *
- * @param type log level
- * @param function which function failed to run
- * @param code what was the curl error code
- */
-#define CURL_STRERROR(type, function, code) \
- GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \
- function, __FILE__, __LINE__, curl_easy_strerror (code));
-
-/**
- * Stages of initialization for the `struct TALER_AUDITOR_Handle`
- */
-enum AuditorHandleState
-{
- /**
- * Just allocated.
- */
- MHS_INIT = 0,
-
- /**
- * Obtained the auditor's versioning data and version.
- */
- MHS_VERSION = 1,
-
- /**
- * Failed to initialize (fatal).
- */
- MHS_FAILED = 2
-};
-
-
-/**
- * Handle to the auditor
- */
-struct TALER_AUDITOR_Handle
-{
- /**
- * The context of this handle
- */
- struct GNUNET_CURL_Context *ctx;
-
- /**
- * The URL of the auditor (i.e. "http://auditor.taler.net/")
- */
- char *url;
-
- /**
- * Function to call with the auditor's certification data,
- * NULL if this has already been done.
- */
- TALER_AUDITOR_VersionCallback version_cb;
-
- /**
- * Closure to pass to @e version_cb.
- */
- void *version_cb_cls;
-
- /**
- * Data for the request to get the /config of a auditor,
- * NULL once we are past stage #MHS_INIT.
- */
- struct GNUNET_CURL_Job *vr;
-
- /**
- * The url for the @e vr job.
- */
- char *vr_url;
-
- /**
- * Task for retrying /config request.
- */
- struct GNUNET_SCHEDULER_Task *retry_task;
-
- /**
- * /config data of the auditor, only valid if
- * @e handshake_complete is past stage #MHS_VERSION.
- */
- char *version;
-
- /**
- * Version information for the callback.
- */
- struct TALER_AUDITOR_VersionInformation vi;
-
- /**
- * Retry /config frequency.
- */
- struct GNUNET_TIME_Relative retry_delay;
-
- /**
- * Stage of the auditor's initialization routines.
- */
- enum AuditorHandleState state;
-
-};
-
-
-/* ***************** Internal /config fetching ************* */
-
-/**
- * Decode the JSON in @a resp_obj from the /config response and store the data
- * in the @a key_data.
- *
- * @param[in] resp_obj JSON object to parse
- * @param[in,out] auditor where to store the results we decoded
- * @param[out] vc where to store version compatibility data
- * @return #TALER_EC_NONE on success
- */
-static enum TALER_ErrorCode
-decode_version_json (const json_t *resp_obj,
- struct TALER_AUDITOR_Handle *auditor,
- enum TALER_AUDITOR_VersionCompatibility *vc)
-{
- struct TALER_AUDITOR_VersionInformation *vi = &auditor->vi;
- unsigned int age;
- unsigned int revision;
- unsigned int current;
- char dummy;
- const char *ver;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("version",
- &ver),
- GNUNET_JSON_spec_fixed_auto ("auditor_public_key",
- &vi->auditor_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (JSON_OBJECT != json_typeof (resp_obj))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_JSON_INVALID;
- }
- /* check the version */
- if (GNUNET_OK !=
- GNUNET_JSON_parse (resp_obj,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_JSON_INVALID;
- }
- if (3 != sscanf (ver,
- "%u:%u:%u%c",
- &current,
- &revision,
- &age,
- &dummy))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_VERSION_MALFORMED;
- }
- GNUNET_free (auditor->version);
- auditor->version = GNUNET_strdup (ver);
- vi->version = auditor->version;
- *vc = TALER_AUDITOR_VC_MATCH;
- if (TALER_PROTOCOL_CURRENT < current)
- {
- *vc |= TALER_AUDITOR_VC_NEWER;
- if (TALER_PROTOCOL_CURRENT < current - age)
- *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
- }
- if (TALER_PROTOCOL_CURRENT > current)
- {
- *vc |= TALER_AUDITOR_VC_OLDER;
- if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
- *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
- }
- return TALER_EC_NONE;
-}
-
-
-/**
- * Initiate download of /config from the auditor.
- *
- * @param cls auditor where to download /config from
- */
-static void
-request_version (void *cls);
-
-
-/**
- * Callback used when downloading the reply to a /config request
- * is complete.
- *
- * @param cls the `struct TALER_AUDITOR_Handle`
- * @param response_code HTTP response code, 0 on error
- * @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
- */
-static void
-version_completed_cb (void *cls,
- long response_code,
- const void *gresp_obj)
-{
- struct TALER_AUDITOR_Handle *auditor = cls;
- const json_t *resp_obj = gresp_obj;
- struct TALER_AUDITOR_VersionResponse vr = {
- .hr.reply = resp_obj,
- .hr.http_status = (unsigned int) response_code
- };
-
- auditor->vr = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received version from URL `%s' with status %ld.\n",
- auditor->url,
- response_code);
- switch (response_code)
- {
- case 0:
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* NOTE: this design is debatable. We MAY want to throw this error at the
- client. We may then still additionally internally re-try. */
- GNUNET_assert (NULL == auditor->retry_task);
- auditor->retry_delay = EXCHANGE_LIB_BACKOFF (auditor->retry_delay);
- auditor->retry_task = GNUNET_SCHEDULER_add_delayed (auditor->retry_delay,
- &request_version,
- auditor);
- return;
- case MHD_HTTP_OK:
- if (NULL == resp_obj)
- {
- GNUNET_break_op (0);
- TALER_LOG_WARNING ("NULL body for a 200-OK /config\n");
- vr.hr.http_status = 0;
- vr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- vr.hr.ec = decode_version_json (resp_obj,
- auditor,
- &vr.details.ok.compat);
- if (TALER_EC_NONE != vr.hr.ec)
- {
- GNUNET_break_op (0);
- vr.hr.http_status = 0;
- break;
- }
- auditor->state = MHS_VERSION;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Auditor %s is ready!\n",
- auditor->url);
- vr.details.ok.vi = auditor->vi;
- auditor->retry_delay = GNUNET_TIME_UNIT_ZERO; /* restart quickly */
- break;
- default:
- vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
- vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d\n",
- (unsigned int) response_code,
- (int) vr.hr.ec);
- break;
- }
- if (MHD_HTTP_OK != response_code)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "/config failed for auditor %s: %u!\n",
- auditor->url,
- (unsigned int) response_code);
- auditor->state = MHS_FAILED;
- }
- auditor->version_cb (auditor->version_cb_cls,
- &vr);
-}
-
-
-/**
- * Initiate download of /config from the auditor.
- *
- * @param cls auditor where to download /config from
- */
-static void
-request_version (void *cls)
-{
- struct TALER_AUDITOR_Handle *auditor = cls;
- CURL *eh;
-
- auditor->retry_task = NULL;
- GNUNET_assert (NULL == auditor->vr);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Requesting auditor version with URL `%s'.\n",
- auditor->vr_url);
- eh = TALER_AUDITOR_curl_easy_get_ (auditor->vr_url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- auditor->retry_delay = EXCHANGE_LIB_BACKOFF (auditor->retry_delay);
- auditor->retry_task = GNUNET_SCHEDULER_add_delayed (auditor->retry_delay,
- &request_version,
- auditor);
- return;
- }
- GNUNET_break (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_TIMEOUT,
- (long) 300));
- auditor->vr = GNUNET_CURL_job_add (auditor->ctx,
- eh,
- &version_completed_cb,
- auditor);
-}
-
-
-/* ********************* library internal API ********* */
-
-
-struct GNUNET_CURL_Context *
-TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h)
-{
- return h->ctx;
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Checking if auditor at `%s` is now ready: %s\n",
- h->url,
- (MHD_VERSION == h->state) ? "yes" : "no");
- return (MHS_VERSION == h->state) ? GNUNET_YES : GNUNET_NO;
-}
-
-
-char *
-TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
- const char *path)
-{
- GNUNET_assert ('/' == path[0]);
- return TALER_url_join (h->url,
- path + 1,
- NULL);
-}
-
-
-/* ********************* public API ******************* */
-
-
-struct TALER_AUDITOR_Handle *
-TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_AUDITOR_VersionCallback version_cb,
- void *version_cb_cls)
-{
- struct TALER_AUDITOR_Handle *auditor;
-
- auditor = GNUNET_new (struct TALER_AUDITOR_Handle);
- auditor->version_cb = version_cb;
- auditor->version_cb_cls = version_cb_cls;
- auditor->retry_delay = GNUNET_TIME_UNIT_SECONDS; /* start slowly */
- auditor->ctx = ctx;
- auditor->url = GNUNET_strdup (url);
- auditor->vr_url = TALER_AUDITOR_path_to_url_ (auditor,
- "/config");
- if (NULL == auditor->vr_url)
- {
- GNUNET_break (0);
- GNUNET_free (auditor->url);
- GNUNET_free (auditor);
- return NULL;
- }
- auditor->retry_task = GNUNET_SCHEDULER_add_now (&request_version,
- auditor);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Connecting to auditor at URL `%s'.\n",
- url);
- return auditor;
-}
-
-
-void
-TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Disconnecting from auditor at URL `%s'.\n",
- auditor->url);
- if (NULL != auditor->vr)
- {
- GNUNET_CURL_job_cancel (auditor->vr);
- auditor->vr = NULL;
- }
- if (NULL != auditor->retry_task)
- {
- GNUNET_SCHEDULER_cancel (auditor->retry_task);
- auditor->retry_task = NULL;
- }
- GNUNET_free (auditor->version);
- GNUNET_free (auditor->vr_url);
- GNUNET_free (auditor->url);
- GNUNET_free (auditor);
-}
-
-
-/* end of auditor_api_handle.c */
diff --git a/src/lib/auditor_api_handle.h b/src/lib/auditor_api_handle.h
deleted file mode 100644
index 7ff5bfcdb..000000000
--- a/src/lib/auditor_api_handle.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_handle.h
- * @brief Internal interface to the handle part of the auditor's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_auditor_service.h"
-#include "taler_curl_lib.h"
-
-/**
- * Get the context of a auditor.
- *
- * @param h the auditor handle to query
- * @return ctx context to execute jobs in
- */
-struct GNUNET_CURL_Context *
-TALER_AUDITOR_handle_to_context_ (struct TALER_AUDITOR_Handle *h);
-
-
-/**
- * Check if the handle is ready to process requests.
- *
- * @param h the auditor handle to query
- * @return #GNUNET_YES if we are ready, #GNUNET_NO if not
- */
-int
-TALER_AUDITOR_handle_is_ready_ (struct TALER_AUDITOR_Handle *h);
-
-
-/**
- * Obtain the URL to use for an API request.
- *
- * @param h the auditor handle to query
- * @param path Taler API path (i.e. "/deposit-confirmation")
- * @return the full URL to use with cURL
- */
-char *
-TALER_AUDITOR_path_to_url_ (struct TALER_AUDITOR_Handle *h,
- const char *path);
-
-
-/* end of auditor_api_handle.h */
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 0d9bf0416..4d245b077 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -110,7 +110,7 @@ struct TEAH_AuditorListEntry
/**
* Handle to the auditor.
*/
- struct TALER_AUDITOR_Handle *ah;
+ struct TALER_AUDITOR_GetConfigHandle *ah;
/**
* Head of DLL of interactions with this auditor.
@@ -583,13 +583,14 @@ parse_global_fee (struct TALER_EXCHANGE_GlobalFee *gf,
* @param vr response from the auditor
*/
static void
-auditor_version_cb (
+auditor_config_cb (
void *cls,
- const struct TALER_AUDITOR_VersionResponse *vr)
+ const struct TALER_AUDITOR_ConfigResponse *vr)
{
struct TEAH_AuditorListEntry *ale = cls;
enum TALER_AUDITOR_VersionCompatibility compat;
+ ale->ah = NULL;
if (MHD_HTTP_OK != vr->hr.http_status)
{
/* In this case, we don't mark the auditor as 'up' */
@@ -664,10 +665,10 @@ update_auditors (struct TALER_EXCHANGE_Handle *exchange)
GNUNET_CONTAINER_DLL_insert (exchange->auditors_head,
exchange->auditors_tail,
ale);
- ale->ah = TALER_AUDITOR_connect (exchange->ctx,
- ale->auditor_url,
- &auditor_version_cb,
- ale);
+ ale->ah = TALER_AUDITOR_get_config (exchange->ctx,
+ ale->auditor_url,
+ &auditor_config_cb,
+ ale);
}
}
@@ -2137,9 +2138,11 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange)
GNUNET_CONTAINER_DLL_remove (exchange->auditors_head,
exchange->auditors_tail,
ale);
- TALER_LOG_DEBUG ("Disconnecting the auditor `%s'\n",
- ale->auditor_url);
- TALER_AUDITOR_disconnect (ale->ah);
+ if (NULL != ale->ah)
+ {
+ TALER_AUDITOR_get_config_cancel (ale->ah);
+ ale->ah = NULL;
+ }
GNUNET_free (ale->auditor_url);
GNUNET_free (ale);
}
diff --git a/src/testing/test_auditor_api_version.c b/src/testing/test_auditor_api_version.c
index 1b4f2b17d..dcd542ad8 100644
--- a/src/testing/test_auditor_api_version.c
+++ b/src/testing/test_auditor_api_version.c
@@ -41,7 +41,7 @@
*/
#define CONFIG_FILE "test_auditor_api-rsa.conf"
-static struct TALER_AUDITOR_Handle *ah;
+static struct TALER_AUDITOR_GetConfigHandle *ah;
static struct GNUNET_CURL_Context *ctx;
@@ -62,7 +62,11 @@ do_shutdown (void *cls)
GNUNET_SCHEDULER_cancel (tt);
tt = NULL;
}
- TALER_AUDITOR_disconnect (ah);
+ if (NULL != ah)
+ {
+ TALER_AUDITOR_get_config_cancel (ah);
+ ah = NULL;
+ }
GNUNET_CURL_fini (ctx);
GNUNET_CURL_gnunet_rc_destroy (rc);
}
@@ -86,9 +90,10 @@ do_timeout (void *cls)
*/
static void
version_cb (void *cls,
- const struct TALER_AUDITOR_VersionResponse *vr)
+ const struct TALER_AUDITOR_ConfigResponse *vr)
{
(void) cls;
+ ah = NULL;
if ( (MHD_HTTP_OK == vr->hr.http_status) &&
(TALER_AUDITOR_VC_MATCH == vr->details.ok.compat) )
global_ret = 0;
@@ -113,10 +118,10 @@ run (void *cls)
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
&rc);
rc = GNUNET_CURL_gnunet_rc_create (ctx);
- ah = TALER_AUDITOR_connect (ctx,
- auditor_url,
- &version_cb,
- NULL);
+ ah = TALER_AUDITOR_get_config (ctx,
+ auditor_url,
+ &version_cb,
+ NULL);
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
NULL);
tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
diff --git a/src/testing/testing_api_cmd_get_auditor.c b/src/testing/testing_api_cmd_get_auditor.c
index 2e9961c36..e1ae8ba54 100644
--- a/src/testing/testing_api_cmd_get_auditor.c
+++ b/src/testing/testing_api_cmd_get_auditor.c
@@ -49,9 +49,9 @@ struct GetAuditorState
struct TALER_TESTING_Interpreter *is;
/**
- * Auditor handle we produced.
+ * Auditor handle used to get the configuration.
*/
- struct TALER_AUDITOR_Handle *auditor;
+ struct TALER_AUDITOR_GetConfigHandle *auditor;
/**
* URL of the auditor.
@@ -75,16 +75,25 @@ struct GetAuditorState
static void
version_cb (
void *cls,
- const struct TALER_AUDITOR_VersionResponse *vr)
+ const struct TALER_AUDITOR_ConfigResponse *vr)
{
struct GetAuditorState *gas = cls;
+ gas->auditor = NULL;
if (MHD_HTTP_OK != vr->hr.http_status)
{
TALER_TESTING_unexpected_status (gas->is,
vr->hr.http_status);
return;
}
+ if ( (NULL != gas->priv_file) &&
+ (0 != GNUNET_memcmp (&gas->auditor_pub,
+ &vr->details.ok.vi.auditor_pub)) )
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (gas->is);
+ return;
+ }
TALER_TESTING_interpreter_next (gas->is);
}
@@ -126,10 +135,10 @@ get_auditor_run (void *cls,
}
gas->is = is;
gas->auditor
- = TALER_AUDITOR_connect (TALER_TESTING_interpreter_get_context (is),
- gas->auditor_url,
- &version_cb,
- gas);
+ = TALER_AUDITOR_get_config (TALER_TESTING_interpreter_get_context (is),
+ gas->auditor_url,
+ &version_cb,
+ gas);
if (NULL == gas->auditor)
{
GNUNET_break (0);
@@ -153,7 +162,8 @@ get_auditor_cleanup (void *cls,
if (NULL != gas->auditor)
{
- TALER_AUDITOR_disconnect (gas->auditor);
+ GNUNET_break (0);
+ TALER_AUDITOR_get_config_cancel (gas->auditor);
gas->auditor = NULL;
}
GNUNET_free (gas->priv_file);
@@ -182,7 +192,6 @@ get_auditor_traits (void *cls,
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv),
TALER_TESTING_make_trait_auditor_pub (&gas->auditor_pub),
- TALER_TESTING_make_trait_auditor (gas->auditor),
TALER_TESTING_make_trait_auditor_url (gas->auditor_url),
TALER_TESTING_trait_end ()
};