Compare commits

..

No commits in common. "3ec07d62c35f0e74ed53cb0712ccb446fe656728" and "e1bf3661ecc4a884a2ee4545a93621e649c740f4" have entirely different histories.

3 changed files with 75 additions and 238 deletions

View File

@ -532,8 +532,6 @@ AC_CONFIG_FILES([Makefile
src/exchangedb/Makefile src/exchangedb/Makefile
src/exchange-tools/Makefile src/exchange-tools/Makefile
src/extensions/Makefile src/extensions/Makefile
src/extensions/age_restriction/Makefile
src/extensions/auction_brandt/Makefile
src/lib/Makefile src/lib/Makefile
src/kyclogic/Makefile src/kyclogic/Makefile
src/testing/Makefile src/testing/Makefile

View File

@ -1040,7 +1040,6 @@ handle_post_auditors (struct TEH_RequestContext *rc,
root); root);
} }
/** /**
* Handle GET "/extensions/..." requests. * Handle GET "/extensions/..." requests.
* *
@ -1070,10 +1069,7 @@ handle_get_extensions (struct TEH_RequestContext *rc,
} }
if (NULL == ext->http_get_handler) if (NULL == ext->http_get_handler)
return TALER_MHD_reply_with_error (rc->connection, return MHD_HTTP_NOT_IMPLEMENTED;
MHD_HTTP_NOT_IMPLEMENTED,
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
"GET /extensions/$EXTENSION not supported");
return ext->http_get_handler ( return ext->http_get_handler (
rc->connection, rc->connection,
@ -1112,10 +1108,7 @@ handle_post_extensions (struct TEH_RequestContext *rc,
} }
if (NULL == ext->http_post_handler) if (NULL == ext->http_post_handler)
return TALER_MHD_reply_with_error (rc->connection, return MHD_HTTP_NOT_IMPLEMENTED;
MHD_HTTP_NOT_IMPLEMENTED,
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
"POST /extensions/$EXTENSION not supported");
return ext->http_post_handler ( return ext->http_post_handler (
rc->connection, rc->connection,

View File

@ -33,9 +33,6 @@
/* Path to the replay program. */ /* Path to the replay program. */
static char *replay_program; static char *replay_program;
/* supported currency */
static char *currency;
/* This is basically BRANDT_Result with an extra string field */ /* This is basically BRANDT_Result with an extra string field */
struct result struct result
{ {
@ -45,54 +42,28 @@ struct result
}; };
/* /*
* @brief Transcript information * TODO: Transcript information
*
*/ */
struct transcript struct transcript
{ {
/* // All fields from json come here.
* The first couple of fields are from a JSON transcript uint16_t n; // #bidders + 1
*/ uint16_t k; // #prices
uint16_t m; // type of auction
/* Public key of seller */ struct GNUNET_TIME_Absolute time_start;
struct GNUNET_CRYPTO_EddsaPublicKey seller_pub;
/* Payto URL */
const char *payto;
/* Number of bidders + 1 (for seller) */
uint16_t n;
/* (n-1) public keys of bidders */
struct GNUNET_CRYPTO_EddsaPublicKey *bidder_pub;
/* Type of auction, see libbrandt */
uint16_t m;
/* Auction public outcome? */
bool public;
/* Start date of the auction */
struct GNUNET_TIME_Timestamp time_start;
/* End date of the auction */
struct GNUNET_TIME_Relative time_round; 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
/* Number of prices */ // struct BRANDT_Auction *auction;
uint16_t k;
/* Prices, must be length k */
struct TALER_Amount *prices;
/* Expected winner(s), maybe NULL */
struct result *expected;
size_t expected_len;
/*
* These are the results from the replay via the external program.
*/
struct result *results; struct result *results;
size_t results_len; size_t results_len;
struct result *expected;
size_t expected_len;
uint16_t id;
struct GNUNET_CRYPTO_EccDlogContext *edc;
}; };
/** /**
@ -100,25 +71,16 @@ struct transcript
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
json_error (json_t **output, json_error (json_t **output,
char *error, ...) char *error)
{ {
va_list ap;
int n = 0;
char buf[4096];
GNUNET_assert (error); GNUNET_assert (error);
va_start (ap, error); *output = json_pack ("{s:s}", "error", error);
n = vsprintf (buf, error, ap); GNUNET_assert (*output);
va_end (ap);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
LOG_PREFIX "got error: %s\n", LOG_PREFIX "got error: %s\n",
n < 0 ? error: buf); error);
*output = json_pack ("{s:s}",
"error",
n < 0 ? error : buf);
GNUNET_assert (*output);
return GNUNET_SYSERR; return GNUNET_SYSERR;
}; };
@ -167,153 +129,118 @@ json_result (json_t **output,
* @brief Parses a given json as transcript. * @brief Parses a given json as transcript.
* *
* @param[in] jtr JSON input * @param[in] jtr JSON input
* @param[out] tr Parsed transcript data * @param[out] transcript Parsed transcript data
* @param[out] jerror JSON output for errors * @param[out] jresult JSON output, both, for results or errors
* @return GNUNET_OK on succes * @return GNUNET_OK on succes
* *
* TODO: * TODO:
* - fix leakages
* - parse and verify signatures * - parse and verify signatures
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
parse_transcript (const json_t *jtr, parse_transcript (const json_t *jtr,
struct transcript *tr, struct transcript *tr,
json_t **jerror) json_t **output)
{ {
json_t *auc;
// TODO: struct GNUNET_CRYPTO_EddsaSignature sig; // TODO: struct GNUNET_CRYPTO_EddsaSignature sig;
GNUNET_assert (jtr); GNUNET_assert (jtr);
GNUNET_assert (tr); GNUNET_assert (tr);
// Parse auction
{ {
json_t *auc;
char *perr; char *perr;
unsigned int eline; unsigned int eline;
struct GNUNET_JSON_Specification au_spec[] = { struct GNUNET_JSON_Specification au_spec[] = {
GNUNET_JSON_spec_bool ("public", &tr->public), GNUNET_JSON_spec_bool ("public", &tr->public),
GNUNET_JSON_spec_uint16 ("type", &tr->m), GNUNET_JSON_spec_uint16 ("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),
GNUNET_JSON_spec_string ("payto", &tr->payto),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
auc = json_object_get (jtr, "auction"); auc = json_object_get (jtr, "auction");
if (NULL == auc) if (NULL == auc)
return json_error (jerror, return json_error (output, "no auction found in transcript");
"no auction found in transcript");
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (auc, GNUNET_JSON_parse (auc,
au_spec, au_spec,
(const char **) &perr, (const char **) &perr,
&eline)) &eline))
return json_error (jerror, return json_error (output, perr);
perr);
// Prices... // Prices...
{ {
json_t *prices = json_object_get (auc, "prices");
size_t idx; size_t idx;
json_t *val; json_t *val;
json_t *prices;
prices = json_object_get (auc, "prices");
if (! json_is_array (prices)) if (! json_is_array (prices))
return json_error (jerror, // TODO: fix leak!?
"no prices found"); return json_error (output, "no prices found");
tr->k = json_array_size (prices); tr->k = json_array_size (prices);
tr->prices = GNUNET_new_array (tr->k, struct TALER_Amount); tr->prices = GNUNET_new_array (tr->k, char *);
json_array_foreach (prices, idx, val) json_array_foreach (prices, idx, val)
{ {
struct GNUNET_JSON_Specification spec[] = { if (! json_is_string (val))
TALER_JSON_spec_amount (NULL, // TODO: fix leak!_
currency, return json_error (output, "prices not strings");
&(tr->prices[idx])),
GNUNET_JSON_spec_end (),
};
if (GNUNET_OK != tr->prices[idx] = (char *) json_string_value (val);
GNUNET_JSON_parse (val,
spec, // TODO: parse prices
NULL,
NULL))
return json_error (jerror,
"price no. %ld couldn't be parsed",
idx + 1);
} }
} }
} }
// Bidders // Bidders
{ {
size_t idx;
json_t *val;
json_t *bidders; json_t *bidders;
bidders = json_object_get (jtr, "bidders"); bidders = json_object_get (jtr, "bidders");
if (! bidders || ! json_is_array (bidders)) if (! bidders || ! json_is_array (bidders))
return json_error (jerror, // TODO: fix leak!_
"no bidders found"); return json_error (output, "bidders not found");
// TODO: parse bidders as pub keys;
tr->n = json_array_size (bidders); tr->n = json_array_size (bidders);
tr->bidder_pub = GNUNET_new_array (tr->n, struct
GNUNET_CRYPTO_EddsaPublicKey);
json_array_foreach (bidders, idx, val)
{
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL,
&(tr->bidder_pub[idx])),
GNUNET_JSON_spec_end (),
};
if (GNUNET_OK !=
GNUNET_JSON_parse (val,
spec,
NULL,
NULL))
return json_error (jerror,
"bidder no %ld public key couldn't be parsed",
idx + 1);
} }
}
// TODO: parse and verify signatures from bidders of the auction
// Messages // Messages
{ {
json_t *messages;
size_t nm; size_t nm;
json_t *messages = json_object_get (jtr, "transcript");
messages = json_object_get (jtr, "transcript");
if (! json_is_array (messages)) if (! json_is_array (messages))
return json_error (jerror, // TODO: fix leak!
"no messages found"); return json_error (output, "no messages found");
nm = json_array_size (messages); nm = json_array_size (messages);
if (nm != (4 * tr->n)) if (nm != (4 * tr->n))
return json_error (jerror, // TODO: fix leak!
"not the right no. of messages found"); return json_error (output, "not the right no. of messages found");
/* TODO: parse and evaluate signatures */
} }
// Winners // Winners
{ {
json_t *winners;
size_t idx; size_t idx;
json_t *val; json_t *val;
json_t *winners = json_object_get (jtr, "winners");
winners = json_object_get (jtr, "winners");
if (! json_is_array (winners)) if (! json_is_array (winners))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
LOG_PREFIX "winners not provided, continuing without\n"); LOG_PREFIX "winners not provided, continuing without\n");
goto DONE; // TODO: fix leakage
goto CONT;
} }
tr->expected_len = json_array_size (winners); tr->expected_len = json_array_size (winners);
@ -321,6 +248,8 @@ parse_transcript (const json_t *jtr,
struct result); struct result);
json_array_foreach (winners, idx, val) { json_array_foreach (winners, idx, val) {
char *error;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_uint16 ("bidder", GNUNET_JSON_spec_uint16 ("bidder",
&(tr->expected[idx].bidder)), &(tr->expected[idx].bidder)),
@ -334,21 +263,16 @@ parse_transcript (const json_t *jtr,
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (val, GNUNET_JSON_parse (val,
spec, spec,
NULL, (const char**) &error,
NULL)) NULL))
return json_error (jerror, // TODO: fix leak!
"couldn't parse winner no. %ld", return json_error (output, "couldn't parse winners");
idx + 1);
}
} }
// TODO: parse and evalue sig of seller CONT:
// TODO: fix leakages
// TODO: check for max values }
*output = NULL;
DONE:
*jerror = NULL;
return GNUNET_OK; return GNUNET_OK;
} }
@ -361,7 +285,7 @@ DONE:
* @param[out] result The JSON result from the program * @param[out] result The JSON result from the program
* @return GNUNET_OK on success * @return GNUNET_OK on success
* *
* TODO: Make this resumable * TODO: Make this asynchronous (giving out a replay-ID to poll from)?
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
replay_transcript (const json_t*root, replay_transcript (const json_t*root,
@ -414,9 +338,6 @@ replay_transcript (const json_t*root,
{ {
ssize_t sz; ssize_t sz;
char buf[MAX_RESULT_SIZE]; char buf[MAX_RESULT_SIZE];
json_error_t error;
json_t *res;
fd = GNUNET_DISK_pipe_handle (po, GNUNET_DISK_PIPE_END_READ); fd = GNUNET_DISK_pipe_handle (po, GNUNET_DISK_PIPE_END_READ);
sz = GNUNET_DISK_file_read (fd, sz = GNUNET_DISK_file_read (fd,
@ -426,62 +347,21 @@ replay_transcript (const json_t*root,
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
LOG_PREFIX "couldn't read data from replay_program\n"); LOG_PREFIX "couldn't read data from replay_program\n");
return json_error (result, "internal error");
} }
else
buf[sz] = 0; {
json_error_t error;
json_t *res;
res = json_loads (buf, res = json_loads (buf,
JSON_DECODE_ANY, JSON_DECODE_ANY,
&error); &error);
if (! res) if (! res)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
LOG_PREFIX
"couldn't parse response from replay_program: %s (for '%s')\n",
error.text,
buf);
return json_error (result, error.text); return json_error (result, error.text);
}
// Handle error case first
{
json_t *err = json_object_get (res,
"error");
if (NULL != err)
{
*result = json_copy (res);
json_decref (res);
return GNUNET_SYSERR;
}
}
// Parse the result
{
json_t *winners = json_object_get (res,
"winners");
if ((NULL == winners) ||
(! json_is_array (winners)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
LOG_PREFIX
"replay program didn't return a known result type, instead: '%s'\n",
json_dumps (res, JSON_INDENT (2)));
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: return own result object.
*result = json_copy (res); *result = json_copy (res);
json_decref (res); json_decref (res);
} }
} }
if (GNUNET_OK != GNUNET_OS_process_wait (proc)) if (GNUNET_OK != GNUNET_OS_process_wait (proc))
@ -495,6 +375,7 @@ replay_transcript (const json_t*root,
} }
// TODO: parse result
return GNUNET_OK; return GNUNET_OK;
} }
@ -508,7 +389,6 @@ static void
auction_disable ( auction_disable (
struct TALER_Extension *ext) struct TALER_Extension *ext)
{ {
/* TODO: cleanup configuration */
ext->enabled = false; ext->enabled = false;
} }
@ -538,7 +418,7 @@ static json_t *
auction_config_to_json ( auction_config_to_json (
const struct TALER_Extension *ext) const struct TALER_Extension *ext)
{ {
/* TODO: add configuration */ /* This extension has no configuration */
return GNUNET_JSON_PACK ( return GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical", ext->critical), GNUNET_JSON_pack_bool ("critical", ext->critical),
GNUNET_JSON_pack_string ("version", ext->version)); GNUNET_JSON_pack_string ("version", ext->version));
@ -556,7 +436,7 @@ auction_load_json_config (
struct TALER_Extension *ext, struct TALER_Extension *ext,
json_t *jconfig) json_t *jconfig)
{ {
/* TODO: add configuration */ /* This extension has no configuration */
ext->enabled = true; ext->enabled = true;
return GNUNET_OK; return GNUNET_OK;
} }
@ -585,8 +465,6 @@ auction_http_get_handler (
/** /**
* @brief implements the TALER_Extension.http_post_handler * @brief implements the TALER_Extension.http_post_handler
*
* TODO: make this non-blocking
*/ */
static MHD_RESULT static MHD_RESULT
auction_http_post_handler ( auction_http_post_handler (
@ -627,7 +505,7 @@ struct TALER_Extension TE_auction_brandt = {
.critical = false, .critical = false,
.version = "0", .version = "0",
.enabled = false, /* disabled per default */ .enabled = false, /* disabled per default */
.has_config = true, .has_config = false, /* This extension has no configuration */
.config = NULL, .config = NULL,
.config_json = NULL, .config_json = NULL,
.disable = &auction_disable, .disable = &auction_disable,
@ -659,12 +537,6 @@ libtaler_extension_auction_brandt_init (void *arg)
{ {
const struct GNUNET_CONFIGURATION_Handle *cfg = arg; const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
if (GNUNET_OK !=
TALER_config_get_currency (cfg,
&currency))
return NULL;
if (GNUNET_SYSERR == if (GNUNET_SYSERR ==
GNUNET_CONFIGURATION_get_value_string (cfg, GNUNET_CONFIGURATION_get_value_string (cfg,
TALER_EXTENSION_SECTION_PREFIX TALER_EXTENSION_SECTION_PREFIX
@ -677,37 +549,11 @@ libtaler_extension_auction_brandt_init (void *arg)
"REPLAY_PROGRAM"); "REPLAY_PROGRAM");
return NULL; return NULL;
} }
/* TODO: check if replay_program is actually executable */
/* check if replay_program is actually an executable */
{
struct stat sb;
if (0 != stat (replay_program, &sb))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
LOG_PREFIX "replay_program '%s' not found\n",
replay_program);
return NULL;
}
if ( (sb.st_mode & S_IFDIR) ||
! (sb.st_mode & S_IXUSR))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
LOG_PREFIX "replay_program '%s' is not an executable\n",
replay_program);
return NULL;
}
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
LOG_PREFIX "loading... using replay_program '%s'\n", LOG_PREFIX "loading... using replay_program '%s'\n",
replay_program); replay_program);
/* TODO: read other config parameters and generate configuration */
return &TE_auction_brandt; return &TE_auction_brandt;
} }