aboutsummaryrefslogtreecommitdiff
path: root/src/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/extensions')
-rw-r--r--src/extensions/age_restriction/extension_age_restriction.c9
-rw-r--r--src/extensions/auction_brandt/extension_auction_brandt.c309
2 files changed, 296 insertions, 22 deletions
diff --git a/src/extensions/age_restriction/extension_age_restriction.c b/src/extensions/age_restriction/extension_age_restriction.c
index 1399fbc7..697d066f 100644
--- a/src/extensions/age_restriction/extension_age_restriction.c
+++ b/src/extensions/age_restriction/extension_age_restriction.c
@@ -105,8 +105,8 @@ age_restriction_load_json_config (
json_decref (ext->config_json);
ext->enabled = true;
- ext->config_json = json_copy(jconfig);
- json_decref(jconfig);
+ ext->config_json = json_copy (jconfig);
+ json_decref (jconfig);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"loaded new age restriction config with age groups: %s\n",
@@ -155,7 +155,7 @@ age_restriction_config_to_json (
GNUNET_JSON_pack_string ("age_groups", mask_str)
);
- free(mask_str);
+ free (mask_str);
return GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical", ext->critical),
@@ -188,6 +188,7 @@ struct TALER_Extension TE_extension_age_restriction = {
.critical = false,
.version = "1",
.enabled = false, /* disabled per default */
+ .has_config = true, /* we need to store configuration */
.config = NULL,
.config_json = NULL,
.disable = &age_restriction_disable,
@@ -264,7 +265,7 @@ libtaler_extension_age_restriction_init (void *arg)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"[age restriction] setting age mask to %s with #groups: %d\n",
- TALER_age_mask_to_string(&AR_config.mask),
+ TALER_age_mask_to_string (&AR_config.mask),
__builtin_popcount (AR_config.mask.bits) - 1);
TE_extension_age_restriction.config = &AR_config;
diff --git a/src/extensions/auction_brandt/extension_auction_brandt.c b/src/extensions/auction_brandt/extension_auction_brandt.c
index a6efd94b..a5f3af8c 100644
--- a/src/extensions/auction_brandt/extension_auction_brandt.c
+++ b/src/extensions/auction_brandt/extension_auction_brandt.c
@@ -26,11 +26,245 @@
#include "stdint.h"
#include <microhttpd.h>
-#define EXTENSION_NAME "auction_brandt"
+#define AUCTION_BRANDT "auction_brandt"
/* Path to the replay program. */
static char *replay_program;
+/* This is basically BRANDT_Result with an extra string field */
+struct result
+{
+ uint16_t bidder;
+ uint16_t price_idx;
+ const char *price;
+};
+
+/*
+ * TODO: Transcript information
+ */
+struct transcript
+{
+ // All fields from json come here.
+ uint16_t n; // #bidders + 1
+ uint16_t k; // #prices
+ uint16_t m; // type of auction
+ struct GNUNET_TIME_Absolute time_start;
+ struct GNUNET_TIME_Relative time_round;
+ bool public;
+ char **prices; // Must be of length k. We do not parse those
+ // struct msg *msgs; // Array must be of length 4*n
+
+ // struct BRANDT_Auction *auction;
+
+ struct result *results;
+ size_t results_len;
+ struct result *expected;
+ size_t expected_len;
+ uint16_t id;
+ struct GNUNET_CRYPTO_EccDlogContext *edc;
+};
+
+/**
+ * @brief returns an JSON with the error
+ */
+static enum GNUNET_GenericReturnValue
+json_error (json_t **output,
+ char *error)
+{
+ GNUNET_assert (error);
+
+ *output = json_pack ("{s:s}", "error", error);
+ GNUNET_assert (*output);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "[auction_brandt] got error: %s\n",
+ error);
+
+ return GNUNET_SYSERR;
+};
+
+/**
+ * @brief returns an JSON with the result
+ */
+static enum GNUNET_GenericReturnValue
+json_result (json_t **output,
+ const struct transcript *tr)
+{
+ json_t *results;
+
+ GNUNET_assert (NULL != tr);
+
+ *output = json_object ();
+ results = json_array ();
+ GNUNET_assert (*output);
+ GNUNET_assert (results);
+
+ for (size_t i = 0; i < tr->results_len; i++)
+ {
+ json_t *result = json_pack ("{s:i, s:s}",
+ "bidder", tr->results[i].bidder,
+ "price", tr->results[i].price);
+ GNUNET_assert (result);
+
+ GNUNET_assert (-1 !=
+ json_array_append_new (results, result));
+ }
+
+ GNUNET_assert (-1 !=
+ json_object_set_new (*output,
+ "winners",
+ results));
+
+ return GNUNET_OK;
+}
+
+
+/*
+ * @brief Parses a given json as transcript.
+ *
+ * @param[in] jtr JSON input
+ * @param[out] transcript Parsed transcript data
+ * @param[out] jresult JSON output, both, for results or errors
+ * @return GNUNET_OK on succes
+ */
+static enum GNUNET_GenericReturnValue
+parse_transcript (const json_t *jtr,
+ struct transcript *tr,
+ json_t **output)
+{
+ // TODO: json_error_t jerror;
+ // TODO: struct GNUNET_CRYPTO_EddsaSignature sig;
+
+ GNUNET_assert (jtr);
+ GNUNET_assert (tr);
+
+ {
+ json_t *auc;
+ char *perr;
+ unsigned int eline;
+ struct GNUNET_JSON_Specification au_spec[] = {
+ GNUNET_JSON_spec_bool ("public", &tr->public),
+ GNUNET_JSON_spec_uint16 ("type", &tr->m),
+ GNUNET_JSON_spec_end ()
+ };
+
+ auc = json_object_get (jtr, "auction");
+ if (NULL == auc)
+ return json_error (output, "no auction found in transcript");
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (auc,
+ au_spec,
+ (const char **) &perr,
+ &eline))
+ return json_error (output, perr);
+
+ // Prices...
+ {
+ json_t *prices = json_object_get (auc, "prices");
+ size_t idx;
+ json_t *val;
+
+
+ if (! json_is_array (prices))
+ // TODO: leak!?
+ return json_error (output, "no prices found");
+
+ tr->k = json_array_size (prices);
+
+ tr->prices = GNUNET_new_array (tr->k, char *);
+ json_array_foreach (prices, idx, val)
+ {
+ if (! json_is_string (val))
+ // TODO: leak!_
+ return json_error (output, "prices not strings");
+
+ tr->prices[idx] = (char *) json_string_value (val);
+
+ // TODO: parse prices
+ }
+ }
+ }
+
+ // Bidders
+ {
+ json_t *bidders;
+
+ bidders = json_object_get (jtr, "bidders");
+ if (! bidders || ! json_is_array (bidders))
+ // TODO: leak!_
+ return json_error (output, "bidders not found");
+
+ // TODO: parse bidders as pub keys;
+ tr->n = json_array_size (bidders);
+ }
+
+
+ // Messages
+ {
+ json_t *messages;
+ size_t nm;
+
+ messages = json_object_get (jtr, "transcript");
+ if (! json_is_array (messages))
+ // TODO: leak!
+ return json_error (output, "no messages found");
+
+
+ nm = json_array_size (messages);
+
+ if (nm != (4 * tr->n))
+ // TODO: leak!
+ return json_error (output, "not the right no. of messages found");
+ }
+
+ // Winners
+ {
+ json_t *winners;
+ size_t idx;
+ json_t *val;
+
+ winners = json_object_get (jtr, "winners");
+
+ if (! json_is_array (winners))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "winners not provided, continuing without\n");
+ goto CONT;
+ }
+
+ tr->expected_len = json_array_size (winners);
+ tr->expected = GNUNET_new_array (tr->expected_len,
+ struct result);
+
+ json_array_foreach (winners, idx, val) {
+ char *error;
+
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_uint16 ("bidder",
+ &(tr->expected[idx].bidder)),
+ GNUNET_JSON_spec_uint16 ("price_idx",
+ &(tr->expected[idx].price_idx)),
+ GNUNET_JSON_spec_string ("price",
+ &(tr->expected[idx].price)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (val,
+ spec,
+ (const char**) &error,
+ NULL))
+ // TODO: leak!
+ return json_error (output, "couldn't parse winners");
+ }
+
+CONT:
+ }
+ return json_result (output, tr);
+}
+
+
/**
* @brief implements the TALER_Extension.disable interface.
*
@@ -70,7 +304,9 @@ auction_config_to_json (
const struct TALER_Extension *ext)
{
/* This extension has no configuration */
- return json_null ();
+ return GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_bool ("critical", ext->critical),
+ GNUNET_JSON_pack_string ("version", ext->version));
}
@@ -92,35 +328,67 @@ auction_load_json_config (
/**
- * @brief implements the TALER_Extension.http_post_handler
+ * @brief implements the TALER_Extension.http_get_handler
*/
+static MHD_RESULT
+auction_http_get_handler (
+ struct MHD_Connection *connection,
+ const char *const args[])
+{
+ /* TODO: return some meta-data about supported version, limits, etc.*/
+
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "auction_http_get_handler not implemented yet\n");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_IMPLEMENTED,
+ TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
+ "auction_http_get_handler not implemented yet\n");
+
+}
+
+
+/**
+ * @brief implements the TALER_Extension.http_post_handler
+ */
static MHD_RESULT
auction_http_post_handler (
struct MHD_Connection *connection,
const json_t *root,
const char *const args[])
{
+ struct transcript tr = {};
+ enum GNUNET_GenericReturnValue ret;
+ json_t *result;
+
+ ret = parse_transcript (root, &tr, &result);
+
/* TODO */
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "auction_http_post_handler not implemented yet");
- return MHD_HTTP_NOT_IMPLEMENTED;
+ "auction_http_post_handler not implemented yet\n");
+
+ return TALER_MHD_reply_json_steal (connection,
+ result,
+ GNUNET_OK == ret? MHD_HTTP_OK :
+ MHD_HTTP_BAD_REQUEST);
}
/* The extension struct for auctions of brandt-style */
struct TALER_Extension TE_auction_brandt = {
- .type = 0x0815, /* TODO: where do we get this from? */
- .name = EXTENSION_NAME,
+ .type = TALER_Extension_AuctionBrandt,
+ .name = AUCTION_BRANDT,
.critical = false,
.version = "0",
.enabled = false, /* disabled per default */
+ .has_config = false, /* This extension has no configuration */
.config = NULL,
.config_json = NULL,
.disable = &auction_disable,
.test_json_config = &auction_test_json_config,
.load_json_config = &auction_load_json_config,
.config_to_json = &auction_config_to_json,
+ .http_get_handler = &auction_http_get_handler,
.http_post_handler = &auction_http_post_handler,
};
@@ -141,25 +409,31 @@ struct TALER_Extension TE_auction_brandt = {
* @return Pointer to TE_auction_brandt
*/
struct TALER_Extension *
-init (void *arg)
+libtaler_extension_auction_brandt_init (void *arg)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
if (GNUNET_SYSERR ==
GNUNET_CONFIGURATION_get_value_string (cfg,
- "extension_" EXTENSION_NAME,
- "replay_program",
+ TALER_EXTENSION_SECTION_PREFIX
+ AUCTION_BRANDT,
+ "REPLAY_PROGRAM",
&replay_program))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "extension_" EXTENSION_NAME,
- "replay_program");
+ TALER_EXTENSION_SECTION_PREFIX AUCTION_BRANDT,
+ "REPLAY_PROGRAM");
return NULL;
}
+ /* TODO: check if replay_program is actually executable */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "[auction_brandt] loading... using replay_program '%s'\n",
+ replay_program);
return &TE_auction_brandt;
}
+
/**
* @brief Tear-down function for the extension.
* Will be called by GNUNET_PLUGIN_unload.
@@ -168,15 +442,14 @@ init (void *arg)
* @return null
*/
void *
-done (void *arg)
+libtaler_extension_auction_brandt_done (void *arg)
{
- auction_disable(&TE_auction_brandt);
- GNUNET_free(replay_program);
- replay_program=NULL;
+ auction_disable (&TE_auction_brandt);
+ GNUNET_free (replay_program);
+ replay_program = NULL;
- return NULL;
+ return NULL;
}
-
/* end of extension_auction_brandt.c */