diff options
Diffstat (limited to 'src/extensions')
-rw-r--r-- | src/extensions/age_restriction/age_restriction.c | 4 | ||||
-rw-r--r-- | src/extensions/extensions.c | 72 | ||||
-rw-r--r-- | src/extensions/policy_brandt_vickrey_auction/policy_brandt_vickrey_auction.c | 254 |
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 */ |