implement logic to check protocol version compatibility (#5035)
This commit is contained in:
parent
f048de9782
commit
d77c4160ec
@ -1234,10 +1234,12 @@ build_refresh ()
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param _keys information about keys of the exchange
|
* @param _keys information about keys of the exchange
|
||||||
|
* @param vc compatibility information
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
cert_cb (void *cls,
|
cert_cb (void *cls,
|
||||||
const struct TALER_EXCHANGE_Keys *_keys)
|
const struct TALER_EXCHANGE_Keys *_keys,
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility vc)
|
||||||
{
|
{
|
||||||
/* check that keys is OK */
|
/* check that keys is OK */
|
||||||
if (NULL == _keys)
|
if (NULL == _keys)
|
||||||
|
@ -29,6 +29,17 @@
|
|||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which revision of the Taler 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.
|
* Log error related to CURL operations.
|
||||||
@ -485,11 +496,13 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
|
|||||||
*
|
*
|
||||||
* @param[in] resp_obj JSON object to parse
|
* @param[in] resp_obj JSON object to parse
|
||||||
* @param[out] key_data where to store the results we decoded
|
* @param[out] key_data where to store the results we decoded
|
||||||
|
* @param[out] where to store version compatibility data
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error (malformed JSON)
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error (malformed JSON)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
decode_keys_json (const json_t *resp_obj,
|
decode_keys_json (const json_t *resp_obj,
|
||||||
struct TALER_EXCHANGE_Keys *key_data)
|
struct TALER_EXCHANGE_Keys *key_data,
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility *vc)
|
||||||
{
|
{
|
||||||
struct GNUNET_TIME_Absolute list_issue_date;
|
struct GNUNET_TIME_Absolute list_issue_date;
|
||||||
struct TALER_ExchangeSignatureP sig;
|
struct TALER_ExchangeSignatureP sig;
|
||||||
@ -508,6 +521,9 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
/* parse the master public key and issue date of the response */
|
/* parse the master public key and issue date of the response */
|
||||||
{
|
{
|
||||||
const char *ver;
|
const char *ver;
|
||||||
|
unsigned int age;
|
||||||
|
unsigned int revision;
|
||||||
|
unsigned int current;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_string ("version",
|
GNUNET_JSON_spec_string ("version",
|
||||||
&ver),
|
&ver),
|
||||||
@ -526,6 +542,29 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
GNUNET_JSON_parse (resp_obj,
|
GNUNET_JSON_parse (resp_obj,
|
||||||
spec,
|
spec,
|
||||||
NULL, NULL));
|
NULL, NULL));
|
||||||
|
if (3 != sscanf (ver,
|
||||||
|
"%u:%u:%u",
|
||||||
|
¤t,
|
||||||
|
&revision,
|
||||||
|
&age))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
*vc = TALER_EXCHANGE_VC_MATCH;
|
||||||
|
if (TALER_PROTOCOL_CURRENT < current)
|
||||||
|
{
|
||||||
|
*vc |= TALER_EXCHANGE_VC_NEWER;
|
||||||
|
if (TALER_PROTOCOL_CURRENT < current - age)
|
||||||
|
*vc |= TALER_EXCHANGE_VC_INCOMPATIBLE;
|
||||||
|
}
|
||||||
|
if (TALER_PROTOCOL_CURRENT > current)
|
||||||
|
{
|
||||||
|
*vc |= TALER_EXCHANGE_VC_OLDER;
|
||||||
|
if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
|
||||||
|
*vc |= TALER_EXCHANGE_VC_INCOMPATIBLE;
|
||||||
|
}
|
||||||
key_data->version = GNUNET_strdup (ver);
|
key_data->version = GNUNET_strdup (ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,12 +746,14 @@ keys_completed_cb (void *cls,
|
|||||||
struct TALER_EXCHANGE_Handle *exchange = kr->exchange;
|
struct TALER_EXCHANGE_Handle *exchange = kr->exchange;
|
||||||
struct TALER_EXCHANGE_Keys kd;
|
struct TALER_EXCHANGE_Keys kd;
|
||||||
struct TALER_EXCHANGE_Keys kd_old;
|
struct TALER_EXCHANGE_Keys kd_old;
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility vc;
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Received keys from URL `%s' with status %ld.\n",
|
"Received keys from URL `%s' with status %ld.\n",
|
||||||
kr->url,
|
kr->url,
|
||||||
response_code);
|
response_code);
|
||||||
kd_old = exchange->key_data;
|
kd_old = exchange->key_data;
|
||||||
|
vc = TALER_EXCHANGE_VC_PROTOCOL_ERROR;
|
||||||
switch (response_code)
|
switch (response_code)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -725,7 +766,8 @@ keys_completed_cb (void *cls,
|
|||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
decode_keys_json (resp_obj,
|
decode_keys_json (resp_obj,
|
||||||
&kd))
|
&kd,
|
||||||
|
&vc))
|
||||||
{
|
{
|
||||||
response_code = 0;
|
response_code = 0;
|
||||||
break;
|
break;
|
||||||
@ -748,7 +790,8 @@ keys_completed_cb (void *cls,
|
|||||||
exchange->state = MHS_FAILED;
|
exchange->state = MHS_FAILED;
|
||||||
/* notify application that we failed */
|
/* notify application that we failed */
|
||||||
exchange->cert_cb (exchange->cert_cb_cls,
|
exchange->cert_cb (exchange->cert_cb_cls,
|
||||||
NULL);
|
NULL,
|
||||||
|
vc);
|
||||||
if (NULL != exchange->key_data_raw)
|
if (NULL != exchange->key_data_raw)
|
||||||
{
|
{
|
||||||
json_decref (exchange->key_data_raw);
|
json_decref (exchange->key_data_raw);
|
||||||
@ -764,7 +807,8 @@ keys_completed_cb (void *cls,
|
|||||||
exchange->state = MHS_CERT;
|
exchange->state = MHS_CERT;
|
||||||
/* notify application about the key information */
|
/* notify application about the key information */
|
||||||
exchange->cert_cb (exchange->cert_cb_cls,
|
exchange->cert_cb (exchange->cert_cb_cls,
|
||||||
&exchange->key_data);
|
&exchange->key_data,
|
||||||
|
vc);
|
||||||
free_key_data (&kd_old);
|
free_key_data (&kd_old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3050,10 +3050,12 @@ do_shutdown (void *cls)
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param keys information about keys of the exchange
|
* @param keys information about keys of the exchange
|
||||||
|
* @param vc version compatibility
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
cert_cb (void *cls,
|
cert_cb (void *cls,
|
||||||
const struct TALER_EXCHANGE_Keys *keys)
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility vc)
|
||||||
{
|
{
|
||||||
struct InterpreterState *is = cls;
|
struct InterpreterState *is = cls;
|
||||||
|
|
||||||
|
@ -230,6 +230,58 @@ struct TALER_EXCHANGE_Keys
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How compatible are the protocol version of the exchange and this
|
||||||
|
* client? The bits (1,2,4) can be used to test if the exchange's
|
||||||
|
* version is incompatible, older or newer respectively.
|
||||||
|
*/
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange runs exactly the same protocol version.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_MATCH = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is too old or too new to be compatible with this
|
||||||
|
* implementation (bit)
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_INCOMPATIBLE = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is older than this implementation (bit)
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_OLDER = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is too old to be compatible with
|
||||||
|
* this implementation.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_INCOMPATIBLE_OUTDATED
|
||||||
|
= TALER_EXCHANGE_VC_INCOMPATIBLE
|
||||||
|
| TALER_EXCHANGE_VC_OLDER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is more recent than this implementation (bit).
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_NEWER = 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange is too recent for this implementation.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_INCOMPATIBLE_NEWER
|
||||||
|
= TALER_EXCHANGE_VC_INCOMPATIBLE
|
||||||
|
| TALER_EXCHANGE_VC_NEWER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We could not even parse the version data.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_VC_PROTOCOL_ERROR = 8
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with information about who is auditing
|
* Function called with information about who is auditing
|
||||||
* a particular exchange and what key the exchange is using.
|
* a particular exchange and what key the exchange is using.
|
||||||
@ -237,10 +289,12 @@ struct TALER_EXCHANGE_Keys
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param keys information about the various keys used
|
* @param keys information about the various keys used
|
||||||
* by the exchange, NULL if /keys failed
|
* by the exchange, NULL if /keys failed
|
||||||
|
* @param compat protocol compatibility information
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_CertificationCallback) (void *cls,
|
(*TALER_EXCHANGE_CertificationCallback) (void *cls,
|
||||||
const struct TALER_EXCHANGE_Keys *keys);
|
const struct TALER_EXCHANGE_Keys *keys,
|
||||||
|
enum TALER_EXCHANGE_VersionCompatibility compat);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user