aboutsummaryrefslogtreecommitdiff
path: root/src/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/extensions')
-rw-r--r--src/extensions/age_restriction/age_restriction.c4
-rw-r--r--src/extensions/extensions.c72
-rw-r--r--src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c254
3 files changed, 251 insertions, 79 deletions
diff --git a/src/extensions/age_restriction/age_restriction.c b/src/extensions/age_restriction/age_restriction.c
index 576a6039..3c38d0f8 100644
--- a/src/extensions/age_restriction/age_restriction.c
+++ b/src/extensions/age_restriction/age_restriction.c
@@ -154,8 +154,8 @@ struct TALER_Extension TE_age_restriction = {
/* This extension is not a policy extension */
.parse_policy_details = NULL,
- .http_get_handler = NULL,
- .http_post_handler = NULL,
+ .policy_get_handler = NULL,
+ .policy_post_handler = NULL,
};
diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c
index 52f9061a..cfc10940 100644
--- a/src/extensions/extensions.c
+++ b/src/extensions/extensions.c
@@ -353,13 +353,38 @@ TALER_extensions_load_manifests (
}
+/*
+ * Policy related
+ */
+
+static char *fulfilment2str[] = {
+ [TALER_PolicyFulfilmentPending] = "Pending",
+ [TALER_PolicyFulfilmentSuccessTransfer] = "SuccessTransfer",
+ [TALER_PolicyFulfilmentSuccessRefreshable] = "SuccessRefreshable",
+ [TALER_PolicyFulfilmentFailureTransfer] = "FailureTransfer",
+ [TALER_PolicyFulfilmentFailureRefreshable] = "FailureRefreshable",
+ [TALER_PolicyFulfilmentTimeoutTransfer] = "TimeoutTransfer",
+ [TALER_PolicyFulfilmentTimeoutRefreshable] = "TimeoutRefreshable",
+};
+
+const char *
+TALER_policy_fulfilment_state_str (
+ enum TALER_PolicyFulfilmentState state)
+{
+ GNUNET_assert (TALER_PolicyFulfilmentStateMax >= state);
+ return fulfilment2str[state];
+}
+
+
enum GNUNET_GenericReturnValue
-TALER_extensions_serial_from_policy_details (
+TALER_extensions_extract_meta_data_from_policy_details (
const json_t *policy_details,
struct GNUNET_HashCode *serial,
struct GNUNET_TIME_Timestamp *deadline,
+ enum TALER_PolicyFulfilmentState *state_on_deadline,
const char **error_hint)
{
+ enum GNUNET_GenericReturnValue ret;
const struct TALER_Extension *extension;
const json_t *jtype;
const char *type;
@@ -399,11 +424,48 @@ TALER_extensions_serial_from_policy_details (
}
*deadline = GNUNET_TIME_UNIT_FOREVER_TS;
- return extension->parse_policy_details (policy_details,
- serial,
- deadline,
- error_hint);
+ ret = extension->parse_policy_details (policy_details,
+ serial,
+ deadline,
+ state_on_deadline,
+ error_hint);
+
+ GNUNET_assert ((TALER_PolicyFulfilmentTimeoutRefreshable ==
+ *state_on_deadline) ||
+ (TALER_PolicyFulfilmentTimeoutTransfer ==
+ *state_on_deadline));
+
+ return ret;
+
+}
+
+
+struct TALER_PolicyFulfilmentOutcome *
+TALER_policy_fulfilment_outcome_new (size_t len)
+{
+ struct TALER_PolicyFulfilmentOutcome *out;
+
+ out = GNUNET_new (struct TALER_PolicyFulfilmentOutcome);
+ out->len = len;
+ out->positions = GNUNET_new_array (len,
+ struct
+ TALER_PolicyFulfilmentOutcomePosition);
+
+ return out;
+}
+
+
+void
+TALER_policy_fulfilment_outcome_free (
+ struct TALER_PolicyFulfilmentOutcome *outcome)
+{
+ if (NULL == outcome)
+ return;
+
+ if (NULL != outcome->positions)
+ GNUNET_free (outcome->positions);
+ GNUNET_free (outcome);
}
diff --git a/src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c b/src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c
index 8521711b..bfd7b813 100644
--- a/src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c
+++ b/src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c
@@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file policy_brandt_vickery_auction.c
+ * @file policy_brandt_vickrey_auction.c
* @brief Extension for replay of auctions of type Brandt
* @author Özgür Kesim
*/
@@ -26,8 +26,8 @@
#include "stdint.h"
#include <microhttpd.h>
-#define POLICY_AUCTION "policy_brandt_vickery_auction"
-#define LOG_PREFIX "[policy_brandt_vickery_auction] "
+#define POLICY_AUCTION "policy_brandt_vickrey_auction"
+#define LOG_PREFIX "[policy_brandt_vickrey_auction] "
#define MAX_RESULT_SIZE 10 * 1024
/* (public) configuration of this extension */
@@ -54,7 +54,7 @@ struct result
{
uint16_t bidder;
uint16_t price_idx;
- const char *price;
+ const char *price;
};
/*
@@ -73,12 +73,19 @@ struct transcript
/* Payto URL */
const char *payto;
- /* Number of bidders + 1 (for seller) */
+ /* Number of bidders */
uint16_t n;
/* (n-1) public keys of bidders */
struct GNUNET_CRYPTO_EddsaPublicKey *bidder_pub;
+ /* Hash of the auction */
+ struct GNUNET_HashCode h_auction;
+
+ /* (n-1) calculated serial_ids */
+ struct GNUNET_HashCode *serial_ids;
+
+
/* Type of auction, see libbrandt */
uint16_t m;
@@ -137,6 +144,25 @@ json_error (json_t **output,
};
+/* Create serial as H(bidder_pub, h_auction) */
+static void
+calculate_serial (
+ struct GNUNET_CRYPTO_EddsaPublicKey *pub,
+ struct GNUNET_HashCode *hc,
+ struct GNUNET_HashCode *serial)
+{
+ struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
+ GNUNET_CRYPTO_hash_context_read (ctx,
+ pub,
+ sizeof(*pub));
+ GNUNET_CRYPTO_hash_context_read (ctx,
+ hc,
+ sizeof(*hc));
+ GNUNET_CRYPTO_hash_context_finish (ctx,
+ serial);
+}
+
+
/*
* @brief Parses a given json as transcript.
*
@@ -165,8 +191,8 @@ parse_transcript (const json_t *jtr,
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_bool ("outcome_public", &tr->public),
+ GNUNET_JSON_spec_uint16 ("auction_type", &tr->m),
GNUNET_JSON_spec_fixed_auto ("pubkey", &tr->seller_pub),
GNUNET_JSON_spec_timestamp ("time_start", &tr->time_start),
GNUNET_JSON_spec_relative_time ("time_round", &tr->time_round),
@@ -187,6 +213,13 @@ parse_transcript (const json_t *jtr,
return json_error (jerror,
perr);
+ {
+ const char *auc_js = json_dumps (auc, JSON_COMPACT);
+ GNUNET_CRYPTO_hash (auc_js,
+ strlen (auc_js),
+ &tr->h_auction);
+ }
+
// Prices...
{
size_t idx;
@@ -235,15 +268,23 @@ parse_transcript (const json_t *jtr,
tr->n = json_array_size (bidders);
- tr->bidder_pub = GNUNET_new_array (tr->n, struct
- GNUNET_CRYPTO_EddsaPublicKey);
+ tr->bidder_pub = GNUNET_new_array (
+ tr->n,
+ struct GNUNET_CRYPTO_EddsaPublicKey);
+
+ tr->serial_ids = GNUNET_new_array (
+ tr->n,
+ struct GNUNET_HashCode);
+
json_array_foreach (bidders, idx, val)
{
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL,
- &(tr->bidder_pub[idx])),
+ &tr->bidder_pub[idx]),
GNUNET_JSON_spec_end (),
};
+
+ /* TODO: cleanup */
if (GNUNET_OK !=
GNUNET_JSON_parse (val,
spec,
@@ -252,12 +293,13 @@ parse_transcript (const json_t *jtr,
return json_error (jerror,
"bidder no %ld public key couldn't be parsed",
idx + 1);
+
+ calculate_serial (&tr->bidder_pub[idx],
+ &tr->h_auction,
+ &tr->serial_ids[idx]);
}
}
- // TODO: parse and verify signatures from bidders of the auction
-
-
// Messages
{
size_t nm;
@@ -322,7 +364,6 @@ parse_transcript (const json_t *jtr,
DONE:
- *jerror = NULL;
return GNUNET_OK;
}
@@ -331,7 +372,8 @@ DONE:
* @brief replay an auction using the external program
*
* @param[in] root The original JSON transcript
- * @param[in] transcript The transcript object parsed so far
+ * @param[in,out] transcript The transcript object parsed so far
+ * @param[out] outcome Outcome object to fill
* @param[out] result The JSON result from the program
* @return GNUNET_OK on success
*
@@ -340,8 +382,10 @@ DONE:
static enum GNUNET_GenericReturnValue
replay_transcript (const json_t*root,
struct transcript *tr,
+ struct TALER_PolicyFulfilmentOutcome **outcome,
json_t **result)
{
+ enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
struct GNUNET_DISK_PipeHandle *pi;
struct GNUNET_DISK_PipeHandle *po;
const struct GNUNET_DISK_FileHandle *fd;
@@ -444,32 +488,106 @@ replay_transcript (const json_t*root,
return json_error (result, "internal error");
}
- {
- // TODO: check each winner with tr->expected, if applicable
- json_object_set (res, "exchange_sig", json_string (
- "sig(priv_E, winners)"));
+ // TODO: check each winner with tr->expected, if applicable
- }
- // TODO: return own result object.
- *result = json_copy (res);
- json_decref (res);
+ // Create the outcome object
+ {
+ json_t *w;
+ size_t idx;
+ struct TALER_PolicyFulfilmentOutcomePosition *pos;
+
+ *outcome =
+ TALER_policy_fulfilment_outcome_new (tr->n);
+
+ /* Set outcome for all bidders to a default value first */
+ for (uint16_t i = 0; i<tr->n; i++)
+ {
+ pos = &((*outcome)->positions[i]);
+ pos->serial_id = tr->serial_ids[i];
+ pos->has_new_amount = false;
+ pos->state = TALER_PolicyFulfilmentFailureRefreshable;
+ }
+
+ /* Set the outcome of the winners */
+ json_array_foreach (winners, idx, w)
+ {
+ enum GNUNET_GenericReturnValue ret;
+ const char *jerror;
+ uint16_t bidder;
+ uint16_t price_idx;
+ struct TALER_Amount price;
+
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_uint16 ("bidder",
+ &bidder),
+ GNUNET_JSON_spec_uint16 ("price_idx",
+ &price_idx),
+ TALER_JSON_spec_amount ("price",
+ BV_config.auction_fee.currency,
+ &price),
+ GNUNET_JSON_spec_end ()
+ };
+
+ ret = GNUNET_JSON_parse (w,
+ spec,
+ &jerror,
+ NULL);
+
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ LOG_PREFIX
+ "couldn't parse output of replay program: %s\n",
+ jerror);
+ ret = json_error (result, "internal error");
+ goto DONE;
+ }
+
+ if (bidder > tr->n - 1)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ LOG_PREFIX
+ "replay program sent a bidder out of range\n");
+ ret = json_error (result, "internal error");
+ goto DONE;
+ }
+
+ // Fill the outcome position for this winning bidder.
+ pos = &((*outcome)->positions[idx]);
+ pos->has_new_amount = true;
+ pos->new_amount = price;
+ pos->state = TALER_PolicyFulfilmentSuccessTransfer;
+ }
+
+ // TODO: return own result object.
+ // TODO: sign the result by the exchange
+ *result = json_copy (res);
+ json_decref (res);
+ }
}
-
+ ret = GNUNET_OK;
}
- if (GNUNET_OK != GNUNET_OS_process_wait (proc))
+ ret = GNUNET_OS_process_wait (proc);
+ if (GNUNET_OK != ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- LOG_PREFIX "error while launching auction replay program '%s'\n",
+ LOG_PREFIX
+ "error waiting for auction replay program '%s'\n",
replay_program);
json_object_clear (*result);
- return json_error (result, "internal error");
+ ret = json_error (result, "internal error");
}
-
- return GNUNET_OK;
+DONE:
+ if (GNUNET_OK != ret)
+ {
+ TALER_policy_fulfilment_outcome_free (*outcome);
+ *outcome = NULL;
+ }
+ return ret;
}
@@ -531,60 +649,58 @@ auction_load_config (
/**
- * @brief implements the TALER_Extension.http_get_handler
+ * @brief implements the TALER_Extension.policy_get_handler
*/
static MHD_RESULT
-auction_http_get_handler (
+auction_policy_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,
- LOG_PREFIX "auction_http_get_handler not implemented yet\n");
+ LOG_PREFIX "auction_policy_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");
+ "auction_policy_get_handler not implemented yet\n");
}
/**
- * @brief implements the TALER_Extension.http_post_handler
+ * @brief implements the TALER_Extension.policy_post_handler
*
* TODO: make this non-blocking
*/
-static MHD_RESULT
-auction_http_post_handler (
- struct MHD_Connection *connection,
+enum GNUNET_GenericReturnValue
+auction_policy_post_handler (
const json_t *root,
- const char *const args[])
+ const char *const args[],
+ enum GNUNET_GenericReturnValue (*serial_id_check)(struct GNUNET_HashCode
+ serial_ids[], size_t size),
+ struct TALER_PolicyFulfilmentOutcome **outcome,
+ json_t **output)
{
struct transcript tr = {};
enum GNUNET_GenericReturnValue ret;
- json_t *result1;
- json_t *result2;
+ *outcome = NULL;
ret = parse_transcript (root,
&tr,
- &result1);
+ output);
+
+ /* TODO: cleanups! */
if (GNUNET_OK != ret)
- return TALER_MHD_reply_json_steal (connection,
- result1,
- MHD_HTTP_BAD_REQUEST);
- GNUNET_assert (NULL == result1);
-
- ret = replay_transcript (root,
- &tr,
- &result2);
-
- return TALER_MHD_reply_json_steal (connection,
- result2,
- GNUNET_OK == ret?
- MHD_HTTP_OK :
- MHD_HTTP_BAD_REQUEST);
+ return ret;
+
+ serial_id_check (tr.serial_ids, tr.n);
+
+ return replay_transcript (root,
+ &tr,
+ outcome,
+ output);
}
@@ -594,6 +710,7 @@ auction_http_post_handler (
* @param[in] input The policy_details for this handler during deposit
* @param[out] serial On success will contain the serial-ID under which the
* @param[out] deadline On success will contain a deadline, might be "forever"
+ * @param[out] state_on_timeout On success, will be set to the default state that the policy shall be put in case of a timeout.
* @param[out] error_hint On error, will contain a hint
* exchange should store the policy_details in the policy_details table.
* @return GNUNET_OK if the request was OK
@@ -603,6 +720,7 @@ auction_parse_policy_details (
const json_t *input,
struct GNUNET_HashCode *serial,
struct GNUNET_TIME_Timestamp *deadline,
+ enum TALER_PolicyFulfilmentState *state_on_timeout,
const char **error_hint)
{
enum GNUNET_GenericReturnValue ret = GNUNET_NO;
@@ -636,22 +754,14 @@ auction_parse_policy_details (
LOG_PREFIX "check of deadline %ld not implemented!\n",
deadline->abs_time.abs_value_us);
- /* Create serial as H(bidder_pub, h_auction) */
- {
- struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start ();
- GNUNET_CRYPTO_hash_context_read (hc,
- &pub,
- sizeof(pub));
- GNUNET_CRYPTO_hash_context_read (hc,
- &hc,
- sizeof(hc));
- GNUNET_CRYPTO_hash_context_finish (hc,
- serial);
- }
+ calculate_serial (&pub, &hc, serial);
ret = GNUNET_OK;
} while(0);
+ /* In case of timeout, the coin shall be refreshable by the owner */
+ *state_on_timeout = TALER_PolicyFulfilmentTimeoutRefreshable;
+
return ret;
}
@@ -668,8 +778,8 @@ struct TALER_Extension TE_auction_brandt = {
.load_config = &auction_load_config,
.manifest = &auction_manifest,
.parse_policy_details = &auction_parse_policy_details,
- .http_get_handler = &auction_http_get_handler,
- .http_post_handler = &auction_http_post_handler,
+ .policy_get_handler = &auction_policy_get_handler,
+ .policy_post_handler = &auction_policy_post_handler,
};
@@ -687,7 +797,7 @@ struct TALER_Extension TE_auction_brandt = {
* @return Pointer to TE_auction_brandt
*/
struct TALER_Extension *
-libtaler_extension_policy_brandt_vickery_auction_init (void *arg)
+libtaler_extension_policy_brandt_vickrey_auction_init (void *arg)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
@@ -751,7 +861,7 @@ libtaler_extension_policy_brandt_vickery_auction_init (void *arg)
* @return null
*/
void *
-libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
+libtaler_extension_policy_brandt_vickrey_auction_done (void *arg)
{
auction_disable (&TE_auction_brandt);
GNUNET_free (replay_program);
@@ -761,4 +871,4 @@ libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
}
-/* end of policy_brandt_vickery_auction.c */
+/* end of policy_brandt_vickrey_auction.c */