-more clean up of auditor api: atomization complete
This commit is contained in:
parent
af77a2a178
commit
f5ce22ddf6
@ -28,12 +28,12 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#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
|
* 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.
|
* HTTP response.
|
||||||
@ -174,11 +174,12 @@ struct TALER_AUDITOR_VersionResponse
|
|||||||
enum TALER_AUDITOR_VersionCompatibility compat;
|
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;
|
} ok;
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -191,46 +192,45 @@ struct TALER_AUDITOR_VersionResponse
|
|||||||
* @param vr response data
|
* @param vr response data
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_AUDITOR_VersionCallback) (
|
(*TALER_AUDITOR_ConfigCallback) (
|
||||||
void *cls,
|
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
|
* @brief Handle to the auditor. This is where we interact with
|
||||||
* a particular auditor and keep the per-auditor information.
|
* 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
|
* auditor and obtain information about the auditor's master public
|
||||||
* key and the auditor's auditor. The respective information will
|
* key and the auditor's auditor. The respective information will
|
||||||
* be passed to the @a version_cb once available, and all future
|
* be passed to the @a config_cb once available.
|
||||||
* interactions with the auditor will be checked to be signed
|
|
||||||
* (where appropriate) by the respective master key.
|
|
||||||
*
|
*
|
||||||
* @param ctx the context for CURL requests
|
* @param ctx the context for CURL requests
|
||||||
* @param url HTTP base URL for the auditor
|
* @param url HTTP base URL for the auditor
|
||||||
* @param version_cb function to call with the auditor's version information
|
* @param config_cb function to call with the auditor's config information
|
||||||
* @param version_cb_cls closure for @a version_cb
|
* @param config_cb_cls closure for @a config_cb
|
||||||
* @return the auditor handle; NULL upon error
|
* @return the auditor handle; NULL upon error
|
||||||
*/
|
*/
|
||||||
struct TALER_AUDITOR_Handle *
|
struct TALER_AUDITOR_GetConfigHandle *
|
||||||
TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
|
TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
|
||||||
const char *url,
|
const char *url,
|
||||||
TALER_AUDITOR_VersionCallback version_cb,
|
TALER_AUDITOR_ConfigCallback config_cb,
|
||||||
void *version_cb_cls);
|
void *config_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect from the auditor.
|
* Cancel auditor config request.
|
||||||
*
|
*
|
||||||
* @param auditor the auditor handle
|
* @param auditor the auditor handle
|
||||||
*/
|
*/
|
||||||
void
|
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
|
* 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.
|
* 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
|
* We also verify that the @a exchange_sig is valid for this
|
||||||
* request, and that the @a master_sig is a valid signature for @a
|
* deposit-confirmation request, and that the @a master_sig is a valid
|
||||||
* exchange_pub. Also, the @a auditor must be ready to operate (i.e. have
|
* signature for @a exchange_pub. If the check fails, we do NOT initiate the
|
||||||
* finished processing the /version reply). If either check fails, we do
|
* transaction with the auditor and instead return NULL.
|
||||||
* NOT initiate the transaction with the auditor and instead return NULL.
|
|
||||||
*
|
*
|
||||||
* @param ctx the context for CURL requests
|
* @param ctx the context for CURL requests
|
||||||
* @param url HTTP base URL for the auditor
|
* @param url HTTP base URL for the auditor
|
||||||
|
@ -2692,7 +2692,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
|||||||
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
|
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
|
||||||
op (claim_token, const struct TALER_ClaimTokenP) \
|
op (claim_token, const struct TALER_ClaimTokenP) \
|
||||||
op (relative_time, const struct GNUNET_TIME_Relative) \
|
op (relative_time, const struct GNUNET_TIME_Relative) \
|
||||||
op (auditor, struct TALER_AUDITOR_Handle) \
|
|
||||||
op (exchange, struct TALER_EXCHANGE_Handle) \
|
op (exchange, struct TALER_EXCHANGE_Handle) \
|
||||||
op (fakebank, struct TALER_FAKEBANK_Handle) \
|
op (fakebank, struct TALER_FAKEBANK_Handle) \
|
||||||
op (process, struct GNUNET_OS_Process *)
|
op (process, struct GNUNET_OS_Process *)
|
||||||
|
@ -96,7 +96,7 @@ libtalerauditor_la_LDFLAGS = \
|
|||||||
-no-undefined
|
-no-undefined
|
||||||
libtalerauditor_la_SOURCES = \
|
libtalerauditor_la_SOURCES = \
|
||||||
auditor_api_curl_defaults.c auditor_api_curl_defaults.h \
|
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_deposit_confirmation.c \
|
||||||
auditor_api_exchanges.c
|
auditor_api_exchanges.c
|
||||||
libtalerauditor_la_LIBADD = \
|
libtalerauditor_la_LIBADD = \
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
#include <gnunet/gnunet_util_lib.h>
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
#include <gnunet/gnunet_json_lib.h>
|
#include <gnunet/gnunet_json_lib.h>
|
||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
|
#include "taler_util.h"
|
||||||
|
#include "taler_curl_lib.h"
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_auditor_service.h"
|
#include "taler_auditor_service.h"
|
||||||
#include "auditor_api_handle.h"
|
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
#include "auditor_api_curl_defaults.h"
|
#include "auditor_api_curl_defaults.h"
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_auditor_service.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 "taler_signatures.h"
|
||||||
#include "auditor_api_curl_defaults.h"
|
#include "auditor_api_curl_defaults.h"
|
||||||
|
|
||||||
|
288
src/lib/auditor_api_get_config.c
Normal file
288
src/lib/auditor_api_get_config.c
Normal file
@ -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",
|
||||||
|
¤t,
|
||||||
|
&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 */
|
@ -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",
|
|
||||||
¤t,
|
|
||||||
&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 */
|
|
@ -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 */
|
|
@ -110,7 +110,7 @@ struct TEAH_AuditorListEntry
|
|||||||
/**
|
/**
|
||||||
* Handle to the auditor.
|
* Handle to the auditor.
|
||||||
*/
|
*/
|
||||||
struct TALER_AUDITOR_Handle *ah;
|
struct TALER_AUDITOR_GetConfigHandle *ah;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Head of DLL of interactions with this auditor.
|
* 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
|
* @param vr response from the auditor
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
auditor_version_cb (
|
auditor_config_cb (
|
||||||
void *cls,
|
void *cls,
|
||||||
const struct TALER_AUDITOR_VersionResponse *vr)
|
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||||
{
|
{
|
||||||
struct TEAH_AuditorListEntry *ale = cls;
|
struct TEAH_AuditorListEntry *ale = cls;
|
||||||
enum TALER_AUDITOR_VersionCompatibility compat;
|
enum TALER_AUDITOR_VersionCompatibility compat;
|
||||||
|
|
||||||
|
ale->ah = NULL;
|
||||||
if (MHD_HTTP_OK != vr->hr.http_status)
|
if (MHD_HTTP_OK != vr->hr.http_status)
|
||||||
{
|
{
|
||||||
/* In this case, we don't mark the auditor as 'up' */
|
/* 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,
|
GNUNET_CONTAINER_DLL_insert (exchange->auditors_head,
|
||||||
exchange->auditors_tail,
|
exchange->auditors_tail,
|
||||||
ale);
|
ale);
|
||||||
ale->ah = TALER_AUDITOR_connect (exchange->ctx,
|
ale->ah = TALER_AUDITOR_get_config (exchange->ctx,
|
||||||
ale->auditor_url,
|
ale->auditor_url,
|
||||||
&auditor_version_cb,
|
&auditor_config_cb,
|
||||||
ale);
|
ale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2137,9 +2138,11 @@ TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange)
|
|||||||
GNUNET_CONTAINER_DLL_remove (exchange->auditors_head,
|
GNUNET_CONTAINER_DLL_remove (exchange->auditors_head,
|
||||||
exchange->auditors_tail,
|
exchange->auditors_tail,
|
||||||
ale);
|
ale);
|
||||||
TALER_LOG_DEBUG ("Disconnecting the auditor `%s'\n",
|
if (NULL != ale->ah)
|
||||||
ale->auditor_url);
|
{
|
||||||
TALER_AUDITOR_disconnect (ale->ah);
|
TALER_AUDITOR_get_config_cancel (ale->ah);
|
||||||
|
ale->ah = NULL;
|
||||||
|
}
|
||||||
GNUNET_free (ale->auditor_url);
|
GNUNET_free (ale->auditor_url);
|
||||||
GNUNET_free (ale);
|
GNUNET_free (ale);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
#define CONFIG_FILE "test_auditor_api-rsa.conf"
|
#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;
|
static struct GNUNET_CURL_Context *ctx;
|
||||||
|
|
||||||
@ -62,7 +62,11 @@ do_shutdown (void *cls)
|
|||||||
GNUNET_SCHEDULER_cancel (tt);
|
GNUNET_SCHEDULER_cancel (tt);
|
||||||
tt = NULL;
|
tt = NULL;
|
||||||
}
|
}
|
||||||
TALER_AUDITOR_disconnect (ah);
|
if (NULL != ah)
|
||||||
|
{
|
||||||
|
TALER_AUDITOR_get_config_cancel (ah);
|
||||||
|
ah = NULL;
|
||||||
|
}
|
||||||
GNUNET_CURL_fini (ctx);
|
GNUNET_CURL_fini (ctx);
|
||||||
GNUNET_CURL_gnunet_rc_destroy (rc);
|
GNUNET_CURL_gnunet_rc_destroy (rc);
|
||||||
}
|
}
|
||||||
@ -86,9 +90,10 @@ do_timeout (void *cls)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
version_cb (void *cls,
|
version_cb (void *cls,
|
||||||
const struct TALER_AUDITOR_VersionResponse *vr)
|
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||||
{
|
{
|
||||||
(void) cls;
|
(void) cls;
|
||||||
|
ah = NULL;
|
||||||
if ( (MHD_HTTP_OK == vr->hr.http_status) &&
|
if ( (MHD_HTTP_OK == vr->hr.http_status) &&
|
||||||
(TALER_AUDITOR_VC_MATCH == vr->details.ok.compat) )
|
(TALER_AUDITOR_VC_MATCH == vr->details.ok.compat) )
|
||||||
global_ret = 0;
|
global_ret = 0;
|
||||||
@ -113,10 +118,10 @@ run (void *cls)
|
|||||||
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||||
&rc);
|
&rc);
|
||||||
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
||||||
ah = TALER_AUDITOR_connect (ctx,
|
ah = TALER_AUDITOR_get_config (ctx,
|
||||||
auditor_url,
|
auditor_url,
|
||||||
&version_cb,
|
&version_cb,
|
||||||
NULL);
|
NULL);
|
||||||
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
|
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
|
||||||
NULL);
|
NULL);
|
||||||
tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
|
tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
|
||||||
|
@ -49,9 +49,9 @@ struct GetAuditorState
|
|||||||
struct TALER_TESTING_Interpreter *is;
|
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.
|
* URL of the auditor.
|
||||||
@ -75,16 +75,25 @@ struct GetAuditorState
|
|||||||
static void
|
static void
|
||||||
version_cb (
|
version_cb (
|
||||||
void *cls,
|
void *cls,
|
||||||
const struct TALER_AUDITOR_VersionResponse *vr)
|
const struct TALER_AUDITOR_ConfigResponse *vr)
|
||||||
{
|
{
|
||||||
struct GetAuditorState *gas = cls;
|
struct GetAuditorState *gas = cls;
|
||||||
|
|
||||||
|
gas->auditor = NULL;
|
||||||
if (MHD_HTTP_OK != vr->hr.http_status)
|
if (MHD_HTTP_OK != vr->hr.http_status)
|
||||||
{
|
{
|
||||||
TALER_TESTING_unexpected_status (gas->is,
|
TALER_TESTING_unexpected_status (gas->is,
|
||||||
vr->hr.http_status);
|
vr->hr.http_status);
|
||||||
return;
|
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);
|
TALER_TESTING_interpreter_next (gas->is);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +135,10 @@ get_auditor_run (void *cls,
|
|||||||
}
|
}
|
||||||
gas->is = is;
|
gas->is = is;
|
||||||
gas->auditor
|
gas->auditor
|
||||||
= TALER_AUDITOR_connect (TALER_TESTING_interpreter_get_context (is),
|
= TALER_AUDITOR_get_config (TALER_TESTING_interpreter_get_context (is),
|
||||||
gas->auditor_url,
|
gas->auditor_url,
|
||||||
&version_cb,
|
&version_cb,
|
||||||
gas);
|
gas);
|
||||||
if (NULL == gas->auditor)
|
if (NULL == gas->auditor)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -153,7 +162,8 @@ get_auditor_cleanup (void *cls,
|
|||||||
|
|
||||||
if (NULL != gas->auditor)
|
if (NULL != gas->auditor)
|
||||||
{
|
{
|
||||||
TALER_AUDITOR_disconnect (gas->auditor);
|
GNUNET_break (0);
|
||||||
|
TALER_AUDITOR_get_config_cancel (gas->auditor);
|
||||||
gas->auditor = NULL;
|
gas->auditor = NULL;
|
||||||
}
|
}
|
||||||
GNUNET_free (gas->priv_file);
|
GNUNET_free (gas->priv_file);
|
||||||
@ -182,7 +192,6 @@ get_auditor_traits (void *cls,
|
|||||||
struct TALER_TESTING_Trait traits[] = {
|
struct TALER_TESTING_Trait traits[] = {
|
||||||
TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv),
|
TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv),
|
||||||
TALER_TESTING_make_trait_auditor_pub (&gas->auditor_pub),
|
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_make_trait_auditor_url (gas->auditor_url),
|
||||||
TALER_TESTING_trait_end ()
|
TALER_TESTING_trait_end ()
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user