diff options
Diffstat (limited to 'src/extensions')
-rw-r--r-- | src/extensions/auction_brandt/extension_auction_brandt.c | 166 |
1 files changed, 145 insertions, 21 deletions
diff --git a/src/extensions/auction_brandt/extension_auction_brandt.c b/src/extensions/auction_brandt/extension_auction_brandt.c index a5f3af8c..24ac452b 100644 --- a/src/extensions/auction_brandt/extension_auction_brandt.c +++ b/src/extensions/auction_brandt/extension_auction_brandt.c @@ -27,6 +27,8 @@ #include <microhttpd.h> #define AUCTION_BRANDT "auction_brandt" +#define LOG_PREFIX "[auction_brandt] " +#define MAX_RESULT_SIZE 10 * 1024 /* Path to the replay program. */ static char *replay_program; @@ -77,7 +79,7 @@ json_error (json_t **output, GNUNET_assert (*output); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "[auction_brandt] got error: %s\n", + LOG_PREFIX "got error: %s\n", error); return GNUNET_SYSERR; @@ -86,6 +88,7 @@ json_error (json_t **output, /** * @brief returns an JSON with the result */ +#if 0 static enum GNUNET_GenericReturnValue json_result (json_t **output, const struct transcript *tr) @@ -119,6 +122,9 @@ json_result (json_t **output, } +#endif + + /* * @brief Parses a given json as transcript. * @@ -126,13 +132,16 @@ json_result (json_t **output, * @param[out] transcript Parsed transcript data * @param[out] jresult JSON output, both, for results or errors * @return GNUNET_OK on succes + * + * TODO: + * - fix leakages + * - parse and verify signatures */ 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); @@ -167,7 +176,7 @@ parse_transcript (const json_t *jtr, if (! json_is_array (prices)) - // TODO: leak!? + // TODO: fix leak!? return json_error (output, "no prices found"); tr->k = json_array_size (prices); @@ -176,7 +185,7 @@ parse_transcript (const json_t *jtr, json_array_foreach (prices, idx, val) { if (! json_is_string (val)) - // TODO: leak!_ + // TODO: fix leak!_ return json_error (output, "prices not strings"); tr->prices[idx] = (char *) json_string_value (val); @@ -192,7 +201,7 @@ parse_transcript (const json_t *jtr, bidders = json_object_get (jtr, "bidders"); if (! bidders || ! json_is_array (bidders)) - // TODO: leak!_ + // TODO: fix leak!_ return json_error (output, "bidders not found"); // TODO: parse bidders as pub keys; @@ -207,14 +216,14 @@ parse_transcript (const json_t *jtr, messages = json_object_get (jtr, "transcript"); if (! json_is_array (messages)) - // TODO: leak! + // TODO: fix leak! return json_error (output, "no messages found"); nm = json_array_size (messages); if (nm != (4 * tr->n)) - // TODO: leak! + // TODO: fix leak! return json_error (output, "not the right no. of messages found"); } @@ -229,7 +238,8 @@ parse_transcript (const json_t *jtr, if (! json_is_array (winners)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "winners not provided, continuing without\n"); + LOG_PREFIX "winners not provided, continuing without\n"); + // TODO: fix leakage goto CONT; } @@ -255,13 +265,118 @@ parse_transcript (const json_t *jtr, spec, (const char**) &error, NULL)) - // TODO: leak! + // TODO: fix leak! return json_error (output, "couldn't parse winners"); } CONT: + // TODO: fix leakages + } + *output = NULL; + return GNUNET_OK; +} + + +/** + * @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[out] result The JSON result from the program + * @return GNUNET_OK on success + * + * TODO: Make this asynchronous (giving out a replay-ID to poll from)? + */ +static enum GNUNET_GenericReturnValue +replay_transcript (const json_t*root, + struct transcript *tr, + json_t **result) +{ + struct GNUNET_DISK_PipeHandle *pi; + struct GNUNET_DISK_PipeHandle *po; + const struct GNUNET_DISK_FileHandle *fd; + struct GNUNET_OS_Process *proc; + + pi = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_WRITE); + po = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_READ); + proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, + pi, po, NULL, + replay_program, + replay_program, + NULL); + if (NULL == proc) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + LOG_PREFIX "couldn't create auction replay program '%s'\n", + replay_program); + + return json_error (result, "internal error"); + } + + // Write original transcript JSON to stdin + { + ssize_t sz; + char *str; + size_t str_len; + + + fd = GNUNET_DISK_pipe_handle (pi, GNUNET_DISK_PIPE_END_WRITE); + str = json_dumps (root, JSON_COMPACT); + str_len = strlen (str); + sz = GNUNET_DISK_file_write (fd, + str, + str_len); + free (str); + if (sz != str_len) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + LOG_PREFIX "couldn't write all data to replay_program\n"); + } + } + + // Read output from stdout + { + ssize_t sz; + char buf[MAX_RESULT_SIZE]; + fd = GNUNET_DISK_pipe_handle (po, GNUNET_DISK_PIPE_END_READ); + + sz = GNUNET_DISK_file_read (fd, + buf, + sizeof(buf)); + if (GNUNET_SYSERR == sz) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + LOG_PREFIX "couldn't read data from replay_program\n"); + } + else + { + json_error_t error; + json_t *res; + res = json_loads (buf, + JSON_DECODE_ANY, + &error); + + if (! res) + return json_error (result, error.text); + + *result = json_copy (res); + json_decref (res); + } } - return json_result (output, tr); + + if (GNUNET_OK != GNUNET_OS_process_wait (proc)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + LOG_PREFIX "error while launching auction replay program '%s'\n", + replay_program); + + json_object_clear (*result); + return json_error (result, "internal error"); + } + + + // TODO: parse result + return GNUNET_OK; } @@ -338,7 +453,7 @@ auction_http_get_handler ( /* TODO: return some meta-data about supported version, limits, etc.*/ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "auction_http_get_handler not implemented yet\n"); + LOG_PREFIX "auction_http_get_handler not implemented yet\n"); return TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_IMPLEMENTED, @@ -359,17 +474,26 @@ auction_http_post_handler ( { 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\n"); + json_t *result1; + json_t *result2; + + ret = parse_transcript (root, + &tr, + &result1); + 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, - result, - GNUNET_OK == ret? MHD_HTTP_OK : + result2, + GNUNET_OK == ret? + MHD_HTTP_OK : MHD_HTTP_BAD_REQUEST); } @@ -427,7 +551,7 @@ libtaler_extension_auction_brandt_init (void *arg) } /* TODO: check if replay_program is actually executable */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "[auction_brandt] loading... using replay_program '%s'\n", + LOG_PREFIX "loading... using replay_program '%s'\n", replay_program); return &TE_auction_brandt; |