code cleanup, deduplication, DCE

This commit is contained in:
Christian Grothoff 2020-03-21 19:25:53 +01:00
parent ca943e8c3f
commit f1d3364313
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
10 changed files with 271 additions and 387 deletions

View File

@ -130,13 +130,12 @@ static int
add_denomination (void *cls, add_denomination (void *cls,
const struct TALER_DenominationKeyValidityPS *issue) const struct TALER_DenominationKeyValidityPS *issue)
{ {
struct TALER_DenominationKeyValidityPS *i;
(void) cls; (void) cls;
if (NULL != if (NULL !=
GNUNET_CONTAINER_multihashmap_get (denominations, GNUNET_CONTAINER_multihashmap_get (denominations,
&issue->denom_hash)) &issue->denom_hash))
return GNUNET_OK; /* value already known */ return GNUNET_OK; /* value already known */
#if GNUNET_EXTRA_LOGGING >= 1
{ {
struct TALER_Amount value; struct TALER_Amount value;
@ -148,25 +147,30 @@ add_denomination (void *cls,
TALER_amount2s (&value)); TALER_amount2s (&value));
TALER_amount_ntoh (&value, TALER_amount_ntoh (&value,
&issue->fee_withdraw); &issue->fee_withdraw);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Withdraw fee is %s\n", "Withdraw fee is %s\n",
TALER_amount2s (&value)); TALER_amount2s (&value));
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Start time is %s\n", "Start time is %s\n",
GNUNET_STRINGS_absolute_time_to_string GNUNET_STRINGS_absolute_time_to_string
(GNUNET_TIME_absolute_ntoh (issue->start))); (GNUNET_TIME_absolute_ntoh (issue->start)));
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Expire deposit time is %s\n", "Expire deposit time is %s\n",
GNUNET_STRINGS_absolute_time_to_string GNUNET_STRINGS_absolute_time_to_string
(GNUNET_TIME_absolute_ntoh (issue->expire_deposit))); (GNUNET_TIME_absolute_ntoh (issue->expire_deposit)));
} }
i = GNUNET_new (struct TALER_DenominationKeyValidityPS); #endif
*i = *issue; {
GNUNET_assert (GNUNET_OK == struct TALER_DenominationKeyValidityPS *i;
GNUNET_CONTAINER_multihashmap_put (denominations,
&issue->denom_hash, i = GNUNET_new (struct TALER_DenominationKeyValidityPS);
i, *i = *issue;
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (denominations,
&issue->denom_hash,
i,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
return GNUNET_OK; return GNUNET_OK;
} }
@ -184,7 +188,6 @@ TALER_ARL_get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
const struct const struct
TALER_DenominationKeyValidityPS **issue) TALER_DenominationKeyValidityPS **issue)
{ {
const struct TALER_DenominationKeyValidityPS *i;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
if (NULL == denominations) if (NULL == denominations)
@ -202,13 +205,17 @@ TALER_ARL_get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
return qs; return qs;
} }
} }
i = GNUNET_CONTAINER_multihashmap_get (denominations,
dh);
if (NULL != i)
{ {
/* cache hit */ const struct TALER_DenominationKeyValidityPS *i;
*issue = i;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; i = GNUNET_CONTAINER_multihashmap_get (denominations,
dh);
if (NULL != i)
{
/* cache hit */
*issue = i;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
} }
/* maybe database changed since we last iterated, give it one more shot */ /* maybe database changed since we last iterated, give it one more shot */
qs = TALER_ARL_adb->select_denomination_info (TALER_ARL_adb->cls, qs = TALER_ARL_adb->select_denomination_info (TALER_ARL_adb->cls,
@ -224,13 +231,17 @@ TALER_ARL_get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
TALER_B2S (dh)); TALER_B2S (dh));
return qs; return qs;
} }
i = GNUNET_CONTAINER_multihashmap_get (denominations,
dh);
if (NULL != i)
{ {
/* cache hit */ const struct TALER_DenominationKeyValidityPS *i;
*issue = i;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; i = GNUNET_CONTAINER_multihashmap_get (denominations,
dh);
if (NULL != i)
{
/* cache hit */
*issue = i;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
} }
/* We found more keys, but not the denomination we are looking for :-( */ /* We found more keys, but not the denomination we are looking for :-( */
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -250,11 +261,10 @@ TALER_ARL_get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
* @return transaction status code * @return transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
TALER_ARL_get_denomination_info (const struct TALER_ARL_get_denomination_info (
TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct const struct TALER_DenominationKeyValidityPS **issue,
TALER_DenominationKeyValidityPS **issue, struct GNUNET_HashCode *dh)
struct GNUNET_HashCode *dh)
{ {
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
@ -299,6 +309,8 @@ transact (TALER_ARL_Analysis analysis,
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
{ {
GNUNET_break (0); GNUNET_break (0);
TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
TALER_ARL_esession);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
qs = analysis (analysis_cls); qs = analysis (analysis_cls);
@ -364,15 +376,15 @@ TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana,
TALER_ARL_esession = TALER_ARL_edb->get_session (TALER_ARL_edb->cls); TALER_ARL_esession = TALER_ARL_edb->get_session (TALER_ARL_edb->cls);
if (NULL == TALER_ARL_esession) if (NULL == TALER_ARL_esession)
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize exchange session.\n"); "Failed to initialize exchange session.\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
TALER_ARL_asession = TALER_ARL_adb->get_session (TALER_ARL_adb->cls); TALER_ARL_asession = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
if (NULL == TALER_ARL_asession) if (NULL == TALER_ARL_asession)
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize auditor session.\n"); "Failed to initialize auditor session.\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
@ -414,9 +426,6 @@ test_master_present (void *cls,
int int
TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c) TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c)
{ {
int found;
struct TALER_AUDITORDB_Session *as;
TALER_ARL_cfg = c; TALER_ARL_cfg = c;
start_time = GNUNET_TIME_absolute_get (); start_time = GNUNET_TIME_absolute_get ();
if (0 == GNUNET_is_zero (&TALER_ARL_master_pub)) if (0 == GNUNET_is_zero (&TALER_ARL_master_pub))
@ -430,8 +439,8 @@ TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c)
"MASTER_PUBLIC_KEY", "MASTER_PUBLIC_KEY",
&TALER_ARL_master_public_key_str)) &TALER_ARL_master_public_key_str))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Pass option -m or set it in the configuration!\n"); "Pass option -m or set MASTER_PUBLIC_KEY in the configuration!\n");
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange", "exchange",
"MASTER_PUBLIC_KEY"); "MASTER_PUBLIC_KEY");
@ -445,8 +454,8 @@ TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c)
&TALER_ARL_master_pub. &TALER_ARL_master_pub.
eddsa_pub)) eddsa_pub))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid master public key given in configuration file."); "Malformed master public key given in configuration file.");
GNUNET_free (TALER_ARL_master_public_key_str); GNUNET_free (TALER_ARL_master_public_key_str);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
@ -478,40 +487,43 @@ TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c)
if (NULL == if (NULL ==
(TALER_ARL_edb = TALER_EXCHANGEDB_plugin_load (TALER_ARL_cfg))) (TALER_ARL_edb = TALER_EXCHANGEDB_plugin_load (TALER_ARL_cfg)))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize exchange database plugin.\n"); "Failed to initialize exchange database plugin.\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (NULL == if (NULL ==
(TALER_ARL_adb = TALER_AUDITORDB_plugin_load (TALER_ARL_cfg))) (TALER_ARL_adb = TALER_AUDITORDB_plugin_load (TALER_ARL_cfg)))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize auditor database plugin.\n"); "Failed to initialize auditor database plugin.\n");
TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb); TALER_ARL_done (NULL);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
found = GNUNET_NO;
as = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
if (NULL == as)
{ {
fprintf (stderr, struct TALER_AUDITORDB_Session *as;
"Failed to start session with auditor database.\n"); int found;
TALER_AUDITORDB_plugin_unload (TALER_ARL_adb);
TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb); as = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
return GNUNET_SYSERR; if (NULL == as)
} {
(void) TALER_ARL_adb->list_exchanges (TALER_ARL_adb->cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
as, "Failed to start session with auditor database.\n");
&test_master_present, TALER_ARL_done (NULL);
&found); return GNUNET_SYSERR;
if (GNUNET_NO == found) }
{ found = GNUNET_NO;
fprintf (stderr, (void) TALER_ARL_adb->list_exchanges (TALER_ARL_adb->cls,
"Exchange's master public key `%s' not known to auditor DB. Did you forget to run `taler-auditor-exchange`?\n", as,
GNUNET_p2s (&TALER_ARL_master_pub.eddsa_pub)); &test_master_present,
TALER_AUDITORDB_plugin_unload (TALER_ARL_adb); &found);
TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb); if (GNUNET_NO == found)
return GNUNET_SYSERR; {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Exchange's master public key `%s' not known to auditor DB. Did you forget to run `taler-auditor-exchange`?\n",
GNUNET_p2s (&TALER_ARL_master_pub.eddsa_pub));
TALER_ARL_done (NULL);
return GNUNET_SYSERR;
}
} }
return GNUNET_OK; return GNUNET_OK;
} }
@ -527,10 +539,16 @@ TALER_ARL_done (json_t *report)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Audit complete\n"); "Audit complete\n");
TALER_AUDITORDB_plugin_unload (TALER_ARL_adb); if (NULL != TALER_ARL_adb)
TALER_ARL_adb = NULL; {
TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb); TALER_AUDITORDB_plugin_unload (TALER_ARL_adb);
TALER_ARL_edb = NULL; TALER_ARL_adb = NULL;
}
if (NULL != TALER_ARL_edb)
{
TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
TALER_ARL_edb = NULL;
}
if (NULL != report) if (NULL != report)
{ {
json_dumpf (report, json_dumpf (report,
@ -539,3 +557,6 @@ TALER_ARL_done (json_t *report)
json_decref (report); json_decref (report);
} }
} }
/* end of report-lib.c */

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014, 2015 Taler Systems SA Copyright (C) 2014, 2015, 2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software terms of the GNU General Public License as published by the Free Software
@ -44,6 +44,7 @@ static int reset_db;
*/ */
static int gc_db; static int gc_db;
/** /**
* Main function that will be run. * Main function that will be run.
* *
@ -73,13 +74,19 @@ run (void *cls,
} }
if (reset_db) if (reset_db)
{ {
(void) plugin->drop_tables (plugin->cls, if (GNUNET_OK !=
GNUNET_YES); plugin->drop_tables (plugin->cls,
GNUNET_YES))
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to reset database\n");
} }
else if (restart_db) else if (restart_db)
{ {
(void) plugin->drop_tables (plugin->cls, if (GNUNET_OK !=
GNUNET_NO); plugin->drop_tables (plugin->cls,
GNUNET_NO))
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to restart audits\n");
} }
if (GNUNET_OK != if (GNUNET_OK !=
plugin->create_tables (plugin->cls)) plugin->create_tables (plugin->cls))
@ -102,7 +109,7 @@ run (void *cls,
/** /**
* The main function of the database initialization tool. * The main function of the database initialization tool.
* Used to initialize the Taler Exchange's database. * Used to initialize the Taler auditor's database.
* *
* @param argc number of arguments from the command line * @param argc number of arguments from the command line
* @param argv command line arguments * @param argv command line arguments

View File

@ -57,12 +57,12 @@
/** /**
* Should we return "Connection: close" in each response? * Should we return "Connection: close" in each response?
*/ */
int TAH_auditor_connection_close; static int auditor_connection_close;
/** /**
* The auditor's configuration (global) * The auditor's configuration (global)
*/ */
struct GNUNET_CONFIGURATION_Handle *cfg; static struct GNUNET_CONFIGURATION_Handle *cfg;
/** /**
* Our DB plugin. * Our DB plugin.
@ -107,7 +107,7 @@ static char *currency;
/** /**
* Pipe used for signaling reloading of our key state. * Pipe used for signaling reloading of our key state.
*/ */
static int reload_pipe[2]; static int reload_pipe[2] = { -1, -1 };
/** /**
@ -118,23 +118,15 @@ static int reload_pipe[2];
static void static void
handle_signal (int signal_number) handle_signal (int signal_number)
{ {
ssize_t res;
char c = signal_number; char c = signal_number;
res = write (reload_pipe[1], (void) ! write (reload_pipe[1],
&c, &c,
1); 1);
if ( (res < 0) && /* While one might like to "handle errors" here, even logging via fprintf()
(EINTR != errno) ) isn't safe inside of a signal handler. So there is nothing we safely CAN
{ do. OTOH, also very little that can go wrong in pratice. Calling _exit()
GNUNET_break (0); on errors might be a possibility, but that might do more harm than good. *///
return;
}
if (0 == res)
{
GNUNET_break (0);
return;
}
} }
@ -143,7 +135,7 @@ handle_signal (int signal_number)
* the control pipe. * the control pipe.
*/ */
static void static void
handle_sigint () handle_sigint (void)
{ {
handle_signal (SIGINT); handle_signal (SIGINT);
} }
@ -154,7 +146,7 @@ handle_sigint ()
* the control pipe. * the control pipe.
*/ */
static void static void
handle_sigterm () handle_sigterm (void)
{ {
handle_signal (SIGTERM); handle_signal (SIGTERM);
} }
@ -165,7 +157,7 @@ handle_sigterm ()
* the control pipe. * the control pipe.
*/ */
static void static void
handle_sighup () handle_sighup (void)
{ {
handle_signal (SIGHUP); handle_signal (SIGHUP);
} }
@ -176,7 +168,7 @@ handle_sighup ()
* the control pipe. * the control pipe.
*/ */
static void static void
handle_sigchld () handle_sigchld (void)
{ {
handle_signal (SIGCHLD); handle_signal (SIGCHLD);
} }
@ -199,8 +191,6 @@ signal_loop (void)
struct GNUNET_SIGNAL_Context *sighup; struct GNUNET_SIGNAL_Context *sighup;
struct GNUNET_SIGNAL_Context *sigchld; struct GNUNET_SIGNAL_Context *sigchld;
int ret; int ret;
char c;
ssize_t res;
if (0 != pipe (reload_pipe)) if (0 != pipe (reload_pipe))
{ {
@ -220,11 +210,15 @@ signal_loop (void)
ret = 2; ret = 2;
while (2 == ret) while (2 == ret)
{ {
char c;
ssize_t res;
errno = 0; errno = 0;
res = read (reload_pipe[0], res = read (reload_pipe[0],
&c, &c,
1); 1);
if ((res < 0) && (EINTR != errno)) if ( (res < 0) &&
(EINTR != errno))
{ {
GNUNET_break (0); GNUNET_break (0);
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
@ -393,7 +387,6 @@ handle_mhd_request (void *cls,
&TAH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND }, &TAH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND },
{ NULL, NULL, NULL, NULL, 0, NULL, 0 } { NULL, NULL, NULL, NULL, 0, NULL, 0 }
}; };
struct TAH_RequestHandler *rh;
(void) cls; (void) cls;
(void) version; (void) version;
@ -405,7 +398,8 @@ handle_mhd_request (void *cls,
method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */ method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
for (unsigned int i = 0; NULL != handlers[i].url; i++) for (unsigned int i = 0; NULL != handlers[i].url; i++)
{ {
rh = &handlers[i]; struct TAH_RequestHandler *rh = &handlers[i];
if ( (0 == strcasecmp (url, if ( (0 == strcasecmp (url,
rh->url)) && rh->url)) &&
( (NULL == rh->method) || ( (NULL == rh->method) ||
@ -434,15 +428,13 @@ handle_mhd_request (void *cls,
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
static int static int
auditor_serve_process_config () auditor_serve_process_config (void)
{ {
char *pub;
if (NULL == if (NULL ==
(TAH_plugin = TALER_AUDITORDB_plugin_load (cfg))) (TAH_plugin = TALER_AUDITORDB_plugin_load (cfg)))
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize DB subsystem\n"); "Failed to initialize DB subsystem\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_OK != if (GNUNET_OK !=
@ -460,11 +452,30 @@ auditor_serve_process_config ()
{ {
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_OK != {
GNUNET_CONFIGURATION_get_value_string (cfg, char *pub;
"AUDITOR",
"PUBLIC_KEY", if (GNUNET_OK ==
&pub)) GNUNET_CONFIGURATION_get_value_string (cfg,
"AUDITOR",
"PUBLIC_KEY",
&pub))
{
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_public_key_from_string (pub,
strlen (pub),
&auditor_pub.eddsa_pub))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid public key given in auditor configuration.");
GNUNET_free (pub);
return GNUNET_SYSERR;
}
GNUNET_free (pub);
return GNUNET_OK;
}
}
{ {
/* Fall back to trying to read private key */ /* Fall back to trying to read private key */
char *auditor_key_file; char *auditor_key_file;
@ -491,9 +502,9 @@ auditor_serve_process_config ()
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"AUDITOR", "AUDITOR",
"PUBLIC_KEY"); "PUBLIC_KEY");
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to initialize auditor key from file `%s'\n", "Failed to initialize auditor key from file `%s'\n",
auditor_key_file); auditor_key_file);
GNUNET_free (auditor_key_file); GNUNET_free (auditor_key_file);
return 1; return 1;
} }
@ -502,20 +513,6 @@ auditor_serve_process_config ()
&auditor_pub.eddsa_pub); &auditor_pub.eddsa_pub);
GNUNET_free (eddsa_priv); GNUNET_free (eddsa_priv);
} }
else
{
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_public_key_from_string (pub,
strlen (pub),
&auditor_pub.eddsa_pub))
{
fprintf (stderr,
"Invalid public key given in auditor configuration.");
GNUNET_free (pub);
return GNUNET_SYSERR;
}
GNUNET_free (pub);
}
return GNUNET_OK; return GNUNET_OK;
} }
@ -538,7 +535,7 @@ main (int argc,
GNUNET_GETOPT_option_flag ('C', GNUNET_GETOPT_option_flag ('C',
"connection-close", "connection-close",
"force HTTP connections to be closed after each request", "force HTTP connections to be closed after each request",
&TAH_auditor_connection_close), &auditor_connection_close),
GNUNET_GETOPT_option_cfgfile (&cfgfile), GNUNET_GETOPT_option_cfgfile (&cfgfile),
GNUNET_GETOPT_option_uint ('t', GNUNET_GETOPT_option_uint ('t',
"timeout", "timeout",
@ -564,7 +561,7 @@ main (int argc,
argc, argv)) argc, argv))
return 1; return 1;
go = TALER_MHD_GO_NONE; go = TALER_MHD_GO_NONE;
if (TAH_auditor_connection_close) if (auditor_connection_close)
go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE; go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
TALER_MHD_setup (go); TALER_MHD_setup (go);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
@ -610,8 +607,8 @@ main (int argc,
if ( (-1 == flags) && if ( (-1 == flags) &&
(EBADF == errno) ) (EBADF == errno) )
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Bad listen socket passed, ignored\n"); "Bad listen socket passed, ignored\n");
fh = -1; fh = -1;
} }
flags |= FD_CLOEXEC; flags |= FD_CLOEXEC;
@ -636,27 +633,26 @@ main (int argc,
} }
} }
mhd mhd = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN
= MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN | MHD_USE_DEBUG | MHD_USE_DUAL_STACK
| MHD_USE_DEBUG | MHD_USE_DUAL_STACK | MHD_USE_INTERNAL_POLLING_THREAD
| MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TCP_FASTOPEN,
| MHD_USE_TCP_FASTOPEN, (-1 == fh) ? serve_port : 0,
(-1 == fh) ? serve_port : 0, NULL, NULL,
NULL, NULL, &handle_mhd_request, NULL,
&handle_mhd_request, NULL, MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 32,
MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 32, MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024,
MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024, MHD_OPTION_LISTEN_SOCKET, fh,
MHD_OPTION_LISTEN_SOCKET, fh, MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs, NULL,
NULL, MHD_OPTION_NOTIFY_COMPLETED,
MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, NULL,
&handle_mhd_completion_callback, NULL, MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout, MHD_OPTION_END);
MHD_OPTION_END);
if (NULL == mhd) if (NULL == mhd)
{ {
fprintf (stderr, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to start HTTP server.\n"); "Failed to start HTTP server.\n");
TEAH_DEPOSIT_CONFIRMATION_done (); TEAH_DEPOSIT_CONFIRMATION_done ();
return 1; return 1;
} }
@ -731,6 +727,7 @@ main (int argc,
break; break;
} }
TALER_AUDITORDB_plugin_unload (TAH_plugin); TALER_AUDITORDB_plugin_unload (TAH_plugin);
TAH_plugin = NULL;
TEAH_DEPOSIT_CONFIRMATION_done (); TEAH_DEPOSIT_CONFIRMATION_done ();
return (GNUNET_SYSERR == ret) ? 1 : 0; return (GNUNET_SYSERR == ret) ? 1 : 0;
} }

View File

@ -26,15 +26,6 @@
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_auditordb_plugin.h" #include "taler_auditordb_plugin.h"
/**
* Should we return "Connection: close" in each response?
*/
extern int TAH_auditor_connection_close;
/**
* The exchange's configuration.
*/
extern struct GNUNET_CONFIGURATION_Handle *cfg;
/** /**
* Our DB plugin. * Our DB plugin.

View File

@ -57,19 +57,25 @@ static pthread_mutex_t lock;
* @return MHD result code * @return MHD result code
*/ */
static int static int
verify_and_execute_deposit_confirmation (struct MHD_Connection *connection, verify_and_execute_deposit_confirmation (
const struct struct MHD_Connection *connection,
TALER_AUDITORDB_DepositConfirmation *dc, const struct TALER_AUDITORDB_DepositConfirmation *dc,
const struct const struct TALER_AUDITORDB_ExchangeSigningKey *es)
TALER_AUDITORDB_ExchangeSigningKey *es)
{ {
struct TALER_ExchangeSigningKeyValidityPS skv;
struct TALER_DepositConfirmationPS dcs;
struct TALER_AUDITORDB_Session *session; struct TALER_AUDITORDB_Session *session;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute now;
struct GNUNET_HashCode h; struct GNUNET_HashCode h;
int cached; int cached;
struct TALER_ExchangeSigningKeyValidityPS skv = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
.purpose.size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS)),
.master_public_key = es->master_public_key,
.start = GNUNET_TIME_absolute_hton (es->ep_start),
.expire = GNUNET_TIME_absolute_hton (es->ep_expire),
.end = GNUNET_TIME_absolute_hton (es->ep_end),
.signkey_pub = es->exchange_pub
};
now = GNUNET_TIME_absolute_get (); now = GNUNET_TIME_absolute_get ();
if ( (es->ep_start.abs_value_us > now.abs_value_us) || if ( (es->ep_start.abs_value_us > now.abs_value_us) ||
@ -83,15 +89,6 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
"master_sig (expired)"); "master_sig (expired)");
} }
/* check exchange signing key signature */
skv.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
skv.purpose.size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS));
skv.master_public_key = es->master_public_key;
skv.start = GNUNET_TIME_absolute_hton (es->ep_start);
skv.expire = GNUNET_TIME_absolute_hton (es->ep_expire);
skv.end = GNUNET_TIME_absolute_hton (es->ep_end);
skv.signkey_pub = es->exchange_pub;
/* check our cache */ /* check our cache */
GNUNET_CRYPTO_hash (&skv, GNUNET_CRYPTO_hash (&skv,
sizeof (skv), sizeof (skv),
@ -152,27 +149,33 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
} }
/* check deposit confirmation signature */ /* check deposit confirmation signature */
dcs.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT);
dcs.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS));
dcs.h_contract_terms = dc->h_contract_terms;
dcs.h_wire = dc->h_wire;
dcs.timestamp = GNUNET_TIME_absolute_hton (dc->timestamp);
dcs.refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline);
TALER_amount_hton (&dcs.amount_without_fee,
&dc->amount_without_fee);
dcs.coin_pub = dc->coin_pub;
dcs.merchant = dc->merchant;
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
&dcs.purpose,
&dc->exchange_sig.eddsa_signature,
&dc->exchange_pub.eddsa_pub))
{ {
TALER_LOG_WARNING ("Invalid signature on /deposit-confirmation request\n"); struct TALER_DepositConfirmationPS dcs = {
return TALER_MHD_reply_with_error (connection, .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
MHD_HTTP_FORBIDDEN, .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID, .h_contract_terms = dc->h_contract_terms,
"exchange_sig"); .h_wire = dc->h_wire,
.timestamp = GNUNET_TIME_absolute_hton (dc->timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (dc->refund_deadline),
.coin_pub = dc->coin_pub,
.merchant = dc->merchant
};
TALER_amount_hton (&dcs.amount_without_fee,
&dc->amount_without_fee);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
&dcs.purpose,
&dc->exchange_sig.eddsa_signature,
&dc->exchange_pub.eddsa_pub))
{
TALER_LOG_WARNING (
"Invalid signature on /deposit-confirmation request\n");
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
"exchange_sig");
}
} }
/* execute transaction */ /* execute transaction */
@ -216,8 +219,6 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
json_t *json;
int res;
struct TALER_AUDITORDB_DepositConfirmation dc; struct TALER_AUDITORDB_DepositConfirmation dc;
struct TALER_AUDITORDB_ExchangeSigningKey es; struct TALER_AUDITORDB_ExchangeSigningKey es;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
@ -242,33 +243,41 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
(void) connection_cls; (void) connection_cls;
(void) upload_data; (void) upload_data;
(void) upload_data_size; (void) upload_data_size;
res = TALER_MHD_parse_post_json (connection, {
connection_cls, json_t *json;
upload_data, int res;
upload_data_size,
&json); res = TALER_MHD_parse_post_json (connection,
if (GNUNET_SYSERR == res) connection_cls,
return MHD_NO; upload_data,
if ( (GNUNET_NO == res) || upload_data_size,
(NULL == json) ) &json);
return MHD_YES; if (GNUNET_SYSERR == res)
res = TALER_MHD_parse_json_data (connection, return MHD_NO;
json, if ( (GNUNET_NO == res) ||
spec); (NULL == json) )
json_decref (json); return MHD_YES;
res = TALER_MHD_parse_json_data (connection,
json,
spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)
return MHD_YES; /* failure */
}
es.exchange_pub = dc.exchange_pub; /* used twice! */ es.exchange_pub = dc.exchange_pub; /* used twice! */
dc.master_public_key = es.master_public_key; dc.master_public_key = es.master_public_key;
{
int res;
if (GNUNET_SYSERR == res) res = verify_and_execute_deposit_confirmation (connection,
return MHD_NO; /* hard failure */ &dc,
if (GNUNET_NO == res) &es);
return MHD_YES; /* failure */ GNUNET_JSON_parse_free (spec);
return res;
res = verify_and_execute_deposit_confirmation (connection, }
&dc,
&es);
GNUNET_JSON_parse_free (spec);
return res;
} }

View File

@ -50,10 +50,10 @@ add_exchange (void *cls,
GNUNET_JSON_from_data_auto (master_pub), GNUNET_JSON_from_data_auto (master_pub),
"exchange_url", "exchange_url",
exchange_url); exchange_url);
GNUNET_assert (NULL != obj); GNUNET_break (NULL != obj);
GNUNET_assert (0 == GNUNET_break (0 ==
json_array_append_new (list, json_array_append_new (list,
obj)); obj));
} }
@ -93,6 +93,7 @@ TAH_EXCHANGES_handler (struct TAH_RequestHandler *rh,
"failed to establish session with database"); "failed to establish session with database");
} }
ja = json_array (); ja = json_array ();
GNUNET_break (NULL != ja);
qs = TAH_plugin->list_exchanges (TAH_plugin->cls, qs = TAH_plugin->list_exchanges (TAH_plugin->cls,
session, session,
&add_exchange, &add_exchange,

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2019 Taler Systems SA Copyright (C) 2014-2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -16,7 +16,7 @@
/** /**
* @file taler-auditor-httpd_mhd.c * @file taler-auditor-httpd_mhd.c
* @brief helpers for MHD interaction; these are TALER_AUDITOR_handler_ functions * @brief helpers for MHD interaction; these are TALER_MHD_handler_ functions
* that generate simple MHD replies that do not require any real operations * that generate simple MHD replies that do not require any real operations
* to be performed (error handling, static pages, etc.) * to be performed (error handling, static pages, etc.)
* @author Florian Dold * @author Florian Dold
@ -50,32 +50,16 @@ TAH_MHD_handler_static_response (struct TAH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
struct MHD_Response *response; size_t dlen;
int ret;
(void) connection_cls; dlen = (0 == rh->data_size)
(void) upload_data; ? strlen ((const char *) rh->data)
(void) upload_data_size; : rh->data_size;
if (0 == rh->data_size) return TALER_MHD_reply_static (connection,
rh->data_size = strlen ((const char *) rh->data); rh->response_code,
response = MHD_create_response_from_buffer (rh->data_size, rh->mime_type,
(void *) rh->data, rh->data,
MHD_RESPMEM_PERSISTENT); dlen);
if (NULL == response)
{
GNUNET_break (0);
return MHD_NO;
}
TALER_MHD_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
rh->mime_type);
ret = MHD_queue_response (connection,
rh->response_code,
response);
MHD_destroy_response (response);
return ret;
} }
@ -106,33 +90,4 @@ TAH_MHD_handler_agpl_redirect (struct TAH_RequestHandler *rh,
} }
/**
* Function to call to handle the request by building a JSON
* reply with an error message from @a rh.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
*/
int
TAH_MHD_handler_send_json_pack_error (struct TAH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
{
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
return TALER_MHD_reply_json_pack (connection,
rh->response_code,
"{s:s}",
"error",
rh->data);
}
/* end of taler-auditor-httpd_mhd.c */ /* end of taler-auditor-httpd_mhd.c */

View File

@ -66,46 +66,4 @@ TAH_MHD_handler_agpl_redirect (struct TAH_RequestHandler *rh,
size_t *upload_data_size); size_t *upload_data_size);
/**
* Function to call to handle the request by building a JSON
* reply from varargs.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
* @param response_code HTTP response code to use
* @param do_cache can the response be cached? (0: no, 1: yes)
* @param fmt format string for pack
* @param ... varargs
* @return MHD result code
*/
int
TAH_MHD_helper_send_json_pack (struct TAH_RequestHandler *rh,
struct MHD_Connection *connection,
void *connection_cls,
int response_code,
int do_cache,
const char *fmt,
...);
/**
* Function to call to handle the request by building a JSON
* reply with an error message from @a rh.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
*/
int
TAH_MHD_handler_send_json_pack_error (struct TAH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
#endif #endif

View File

@ -48,35 +48,17 @@ TEH_handler_static_response (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection, struct MHD_Connection *connection,
const char *const args[]) const char *const args[])
{ {
struct MHD_Response *response;
size_t dlen; size_t dlen;
(void) args; (void) args;
dlen = (0 == rh->data_size) dlen = (0 == rh->data_size)
? strlen ((const char *) rh->data) ? strlen ((const char *) rh->data)
: rh->data_size; : rh->data_size;
response = MHD_create_response_from_buffer (dlen, return TALER_MHD_reply_static (connection,
(void *) rh->data, rh->response_code,
MHD_RESPMEM_PERSISTENT); rh->mime_type,
if (NULL == response) rh->data,
{ dlen);
GNUNET_break (0);
return MHD_NO;
}
TALER_MHD_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
rh->mime_type);
{
int ret;
ret = MHD_queue_response (connection,
rh->response_code,
response);
MHD_destroy_response (response);
return ret;
}
} }
@ -101,26 +83,4 @@ TEH_handler_agpl_redirect (const struct TEH_RequestHandler *rh,
} }
/**
* Function to call to handle the request by building a JSON
* reply with an error message from @a rh.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_send_json_pack_error (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const char *const args[])
{
(void) args;
return TALER_MHD_reply_with_error (connection,
rh->response_code,
TALER_EC_METHOD_INVALID,
rh->data);
}
/* end of taler-exchange-httpd_mhd.c */ /* end of taler-exchange-httpd_mhd.c */

View File

@ -58,19 +58,4 @@ TEH_handler_agpl_redirect (const struct TEH_RequestHandler *rh,
const char *const args[]); const char *const args[]);
/**
* Function to call to handle the request by building a JSON
* reply with an error message from @a rh.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_send_json_pack_error (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const char *const args[]);
#endif #endif