385 lines
12 KiB
C
385 lines
12 KiB
C
/*
|
|
This file is part of TALER
|
|
Copyright (C) 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 include/taler_extensions.h
|
|
* @brief Interface for extensions
|
|
* @author Özgür Kesim
|
|
*/
|
|
#ifndef TALER_EXTENSIONS_H
|
|
#define TALER_EXTENSIONS_H
|
|
|
|
#include <gnunet/gnunet_util_lib.h>
|
|
#include "taler_util.h"
|
|
#include "taler_json_lib.h"
|
|
#include "taler_mhd_lib.h"
|
|
#include "taler_extensions_policy.h"
|
|
|
|
|
|
#define TALER_EXTENSION_SECTION_PREFIX "exchange-extension-"
|
|
|
|
enum TALER_Extension_Type
|
|
{
|
|
TALER_Extension_PolicyNull = 0,
|
|
|
|
TALER_Extension_AgeRestriction = 1,
|
|
TALER_Extension_PolicyMerchantRefund = 2,
|
|
TALER_Extension_PolicyBrandtVickeryAuction = 3,
|
|
TALER_Extension_PolicyEscrowedPayment = 4,
|
|
|
|
TALER_Extension_MaxPredefined = 5 // Must be last of the predefined
|
|
};
|
|
|
|
|
|
/* Forward declarations */
|
|
enum TALER_PolicyFulfillmentState;
|
|
struct TALER_PolicyFulfillmentOutcome;
|
|
|
|
/*
|
|
* @brief Represents the implementation of an extension.
|
|
*
|
|
* An "Extension" is an optional feature for the Exchange.
|
|
* There are only two types of extensions:
|
|
*
|
|
* a) Age restriction: This is a special feature that directly interacts with
|
|
* denominations and coins, but is not define policies during deposits, see b).
|
|
* The implementation of this extension doesn't have to implement any of the
|
|
* http- or depost-handlers in the struct.
|
|
*
|
|
* b) Policies for deposits: These are extensions that define policies (such
|
|
* as refund, escrow or auctions) for deposit requests. These extensions have
|
|
* to implement at least the deposit- and post-http-handler in the struct to be
|
|
* functional.
|
|
*
|
|
* In addition to the handlers defined in this struct, an extension must also
|
|
* be a plugin in the GNUNET_Plugin sense. That is, it must implement the
|
|
* functions
|
|
* 1: (void *ext)libtaler_extension_<name>_init(void *cfg)
|
|
* and
|
|
* 2: (void *)libtaler_extension_<name>_done(void *)
|
|
*
|
|
* In 1:, the input will be the GNUNET_CONFIGURATION_Handle to the TALER
|
|
* configuration and the output must be the struct TALER_Extension * on
|
|
* success, NULL otherwise.
|
|
*
|
|
* In 2:, no arguments are passed and NULL is expected to be returned.
|
|
*/
|
|
struct TALER_Extension
|
|
{
|
|
/**
|
|
* Type of the extension. Only one extension of a type can be loaded
|
|
* at any time.
|
|
*/
|
|
enum TALER_Extension_Type type;
|
|
|
|
/**
|
|
* The name of the extension, must be unique among all loaded extensions. It
|
|
* is used in URLs for /extension/$NAME as well.
|
|
*/
|
|
char *name;
|
|
|
|
/**
|
|
* Criticality of the extension. It has the same semantics as "critical" has
|
|
* for extensions in X.509:
|
|
* - if "true", the client must "understand" the extension before proceeding,
|
|
* - if "false", clients can safely skip extensions they do not understand.
|
|
* (see https://datatracker.ietf.org/doc/html/rfc5280#section-4.2)
|
|
*/
|
|
bool critical;
|
|
|
|
/**
|
|
* Version of the extension must be provided in Taler's protocol version ranges notation, see
|
|
* https://docs.taler.net/core/api-common.html#protocol-version-ranges
|
|
*/
|
|
char *version;
|
|
|
|
/**
|
|
* If the extension is marked as enabled, it will be listed in the
|
|
* "extensions" field in the "/keys" response.
|
|
*/
|
|
bool enabled;
|
|
|
|
/**
|
|
* Opaque (public) configuration object, set by the extension.
|
|
*/
|
|
void *config;
|
|
|
|
|
|
/**
|
|
* @brief Handler to to disable the extension.
|
|
*
|
|
* @param ext The current extension object
|
|
*/
|
|
void (*disable)(struct TALER_Extension *ext);
|
|
|
|
/**
|
|
* @brief Handler to read an extension-specific configuration in JSON
|
|
* encoding and enable the extension. Must be implemented by the extension.
|
|
*
|
|
* @param[in] ext The extension object. If NULL, the configuration will only be checked.
|
|
* @param[in,out] config A JSON blob
|
|
* @return GNUNET_OK if the json was a valid configuration for the extension.
|
|
*/
|
|
enum GNUNET_GenericReturnValue (*load_config)(
|
|
const json_t *config,
|
|
struct TALER_Extension *ext);
|
|
|
|
/**
|
|
* @brief Handler to return the manifest of the extension in JSON encoding.
|
|
*
|
|
* See
|
|
* https://docs.taler.net/design-documents/006-extensions.html#tsref-type-Extension
|
|
* for the definition.
|
|
*
|
|
* @param ext The extension object
|
|
* @return The JSON encoding of the extension, if enabled, NULL otherwise.
|
|
*/
|
|
json_t *(*manifest)(
|
|
const struct TALER_Extension *ext);
|
|
|
|
/* =========================
|
|
* Policy related handlers
|
|
* =========================
|
|
*/
|
|
|
|
/**
|
|
* @brief Handler to check an incoming policy and create a
|
|
* TALER_PolicyDetails. Can be NULL;
|
|
*
|
|
* When a deposit request refers to this extension in its policy
|
|
* (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
|
|
* will be called before the deposit transaction.
|
|
*
|
|
* @param[in] policy_json Details about the policy, provided by the client
|
|
* during a deposit request.
|
|
* @param[out] details On success, will contain the details to the policy,
|
|
* evaluated by the corresponding policy handler.
|
|
* @param[out] error_hint On error, will contain a hint
|
|
* @return GNUNET_OK if the data was accepted by the extension.
|
|
*/
|
|
enum GNUNET_GenericReturnValue (*create_policy_details)(
|
|
const json_t *policy_json,
|
|
struct TALER_PolicyDetails *details,
|
|
const char **error_hint);
|
|
|
|
/**
|
|
* @brief Handler for POST-requests to the /extensions/$name endpoint. Can be NULL.
|
|
*
|
|
* @param[in] root The JSON body from the request
|
|
* @param[in] args Additional query parameters of the request.
|
|
* @param[in,out] details List of policy details related to the incoming fulfillment proof
|
|
* @param[in] details_len Size of the list @e details
|
|
* @param[out] output JSON output to return to the client
|
|
* @return GNUNET_OK on success.
|
|
*/
|
|
enum GNUNET_GenericReturnValue (*policy_post_handler)(
|
|
const json_t *root,
|
|
const char *const args[],
|
|
struct TALER_PolicyDetails *details,
|
|
size_t details_len,
|
|
json_t **output);
|
|
|
|
/**
|
|
* @brief Handler for GET-requests to the /extensions/$name endpoint. Can be NULL.
|
|
*
|
|
* @param connection The current connection
|
|
* @param root The JSON body from the request
|
|
* @param args Additional query parameters of the request.
|
|
* @return MDH result
|
|
*/
|
|
MHD_RESULT (*policy_get_handler)(
|
|
struct MHD_Connection *connection,
|
|
const char *const args[]);
|
|
};
|
|
|
|
|
|
/*
|
|
* @brief simply linked list of extensions
|
|
*/
|
|
|
|
struct TALER_Extensions
|
|
{
|
|
struct TALER_Extensions *next;
|
|
const struct TALER_Extension *extension;
|
|
};
|
|
|
|
/**
|
|
* Generic functions for extensions
|
|
*/
|
|
|
|
/**
|
|
* @brief Loads the extensions as shared libraries, as specified in the given
|
|
* TALER configuration.
|
|
*
|
|
* @param cfg Handle to the TALER configuration
|
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were found
|
|
* or any particular configuration couldn't be parsed.
|
|
*/
|
|
enum GNUNET_GenericReturnValue
|
|
TALER_extensions_init (
|
|
const struct GNUNET_CONFIGURATION_Handle *cfg);
|
|
|
|
/*
|
|
* @brief Parses a given JSON object as an extension manifest.
|
|
*
|
|
* @param[in] obj JSON object to parse as an extension manifest
|
|
* @param{out] critical will be set to 1 if the extension is critical according to obj
|
|
* @param[out] version will be set to the version of the extension according to obj
|
|
* @param[out] config will be set to the configuration of the extension according to obj
|
|
* @return OK on success, Error otherwise
|
|
*/
|
|
enum GNUNET_GenericReturnValue
|
|
TALER_extensions_parse_manifest (
|
|
json_t *obj,
|
|
int *critical,
|
|
const char **version,
|
|
json_t **config);
|
|
|
|
/*
|
|
* @brief Loads extensions according to the manifests.
|
|
*
|
|
* The JSON object must be of type ExtensionsManifestsResponse as described
|
|
* in https://docs.taler.net/design-documents/006-extensions.html#exchange
|
|
*
|
|
* @param cfg JSON object containing the manifests for all extensions
|
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were
|
|
* found or any particular configuration couldn't be parsed.
|
|
*/
|
|
enum GNUNET_GenericReturnValue
|
|
TALER_extensions_load_manifests (
|
|
const json_t *manifests);
|
|
|
|
/*
|
|
* @brief Returns the head of the linked list of extensions.
|
|
*/
|
|
const struct TALER_Extensions *
|
|
TALER_extensions_get_head (void);
|
|
|
|
/**
|
|
* @brief Finds and returns a supported extension by a given type.
|
|
*
|
|
* @param type of the extension to lookup
|
|
* @return extension found, or NULL (should not happen!)
|
|
*/
|
|
const struct TALER_Extension *
|
|
TALER_extensions_get_by_type (
|
|
enum TALER_Extension_Type type);
|
|
|
|
|
|
/**
|
|
* @brief Finds and returns a supported extension by a given name.
|
|
*
|
|
* @param name name of the extension to lookup
|
|
* @return the extension, if found, NULL otherwise
|
|
*/
|
|
const struct TALER_Extension *
|
|
TALER_extensions_get_by_name (
|
|
const char *name);
|
|
|
|
/**
|
|
* @brief Check if a given type of an extension is enabled
|
|
*
|
|
* @param type type of to check
|
|
* @return true enabled, false if not enabled, will assert if type is not found.
|
|
*/
|
|
bool
|
|
TALER_extensions_is_enabled_type (
|
|
enum TALER_Extension_Type type);
|
|
|
|
/**
|
|
* @brief Check if an extension is enabled
|
|
*
|
|
* @param extension The extension handler.
|
|
* @return true enabled, false if not enabled, will assert if type is not found.
|
|
*/
|
|
bool
|
|
TALER_extensions_is_enabled (
|
|
const struct TALER_Extension *extension);
|
|
|
|
/*
|
|
* Verify the signature of a given JSON object for extensions with the master
|
|
* key of the exchange.
|
|
*
|
|
* The JSON object must be of type ExtensionsManifestsResponse as described in
|
|
* https://docs.taler.net/design-documents/006-extensions.html#exchange
|
|
*
|
|
* @param extensions JSON object with the extension configuration
|
|
* @param extensions_sig signature of the hash of the JSON object
|
|
* @param master_pub public key to verify the signature
|
|
* @return GNUNET_OK on success, GNUNET_SYSERR when hashing of the JSON fails
|
|
* and GNUNET_NO if the signature couldn't be verified.
|
|
*/
|
|
enum GNUNET_GenericReturnValue
|
|
TALER_extensions_verify_manifests_signature (
|
|
const json_t *manifests,
|
|
struct TALER_MasterSignatureP *extensions_sig,
|
|
struct TALER_MasterPublicKeyP *master_pub);
|
|
|
|
|
|
/*
|
|
* TALER Age Restriction Extension
|
|
*
|
|
* This extension is special insofar as it directly interacts with coins and
|
|
* denominations.
|
|
*
|
|
* At the same time, it doesn't implement and http- or deposit-handlers.
|
|
*/
|
|
|
|
#define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \
|
|
"age_restriction")
|
|
|
|
/**
|
|
* The default age mask represents the age groups
|
|
* 0-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-20, 21-...
|
|
*/
|
|
#define TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_GROUPS "8:10:12:14:16:18:21"
|
|
|
|
|
|
/*
|
|
* @brief Configuration for Age Restriction
|
|
*/
|
|
struct TALER_AgeRestrictionConfig
|
|
{
|
|
struct TALER_AgeMask mask;
|
|
uint8_t num_groups;
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief Retrieve the age restriction configuration
|
|
*
|
|
* @return age restriction configuration if present, otherwise NULL.
|
|
*/
|
|
const struct TALER_AgeRestrictionConfig *
|
|
TALER_extensions_get_age_restriction_config (void);
|
|
|
|
/**
|
|
* @brief Check if age restriction is enabled
|
|
*
|
|
* @return true, if age restriction is loaded, configured and enabled; otherwise false.
|
|
*/
|
|
bool
|
|
TALER_extensions_is_age_restriction_enabled (void);
|
|
|
|
/**
|
|
* @brief Return the age mask for age restriction
|
|
*
|
|
* @return configured age mask, if age restriction is loaded, configured and enabled; otherwise zero mask.
|
|
*/
|
|
struct TALER_AgeMask
|
|
TALER_extensions_get_age_restriction_mask (void);
|
|
|
|
#endif
|