aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange/taler-exchange-httpd.c316
-rw-r--r--src/exchange/taler-exchange-httpd.h6
-rw-r--r--src/exchange/taler-exchange-httpd_auditors.c4
-rw-r--r--src/exchange/taler-exchange-httpd_auditors.h2
-rw-r--r--src/exchange/taler-exchange-httpd_management.h11
-rw-r--r--src/exchange/taler-exchange-httpd_management_auditors.c1
-rw-r--r--src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c10
-rw-r--r--src/exchange/taler-exchange-httpd_management_post_keys.c1
8 files changed, 316 insertions, 35 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 6dc689848..4896c8d46 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -28,20 +28,22 @@
#include <pthread.h>
#include <sys/resource.h>
#include "taler_mhd_lib.h"
-#include "taler-exchange-httpd_mhd.h"
+#include "taler-exchange-httpd_auditors.h"
#include "taler-exchange-httpd_deposit.h"
-#include "taler-exchange-httpd_refund.h"
-#include "taler-exchange-httpd_reserves_get.h"
-#include "taler-exchange-httpd_withdraw.h"
-#include "taler-exchange-httpd_recoup.h"
+#include "taler-exchange-httpd_deposits_get.h"
+#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_link.h"
+#include "taler-exchange-httpd_management.h"
#include "taler-exchange-httpd_melt.h"
+#include "taler-exchange-httpd_mhd.h"
+#include "taler-exchange-httpd_recoup.h"
#include "taler-exchange-httpd_refreshes_reveal.h"
+#include "taler-exchange-httpd_refund.h"
+#include "taler-exchange-httpd_reserves_get.h"
#include "taler-exchange-httpd_terms.h"
#include "taler-exchange-httpd_transfers_get.h"
-#include "taler-exchange-httpd_deposits_get.h"
-#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_wire.h"
+#include "taler-exchange-httpd_withdraw.h"
#include "taler_exchangedb_plugin.h"
#include <gnunet/gnunet_mhd_compat.h>
@@ -178,6 +180,24 @@ typedef MHD_RESULT
/**
+ * Generate a 404 "not found" reply on @a connection with
+ * the hint @a details.
+ *
+ * @param connection where to send the reply on
+ * @param details details for the error message, can be NULL
+ */
+static MHD_RESULT
+r404 (struct MHD_Connection *connection,
+ const char *details)
+{
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
+ details);
+}
+
+
+/**
* Handle a "/coins/$COIN_PUB/$OP" POST request. Parses the "coin_pub"
* EdDSA key of the coin and demultiplexes based on $OP.
*
@@ -249,10 +269,7 @@ handle_post_coins (const struct TEH_RequestHandler *rh,
return h[i].handler (connection,
&coin_pub,
root);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
- args[1]);
+ return r404 (connection, args[1]);
}
@@ -367,6 +384,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
char d[ulen];
/* Parse command-line arguments, if applicable */
+ args[0] = NULL;
if (rh->nargs > 0)
{
unsigned int i;
@@ -384,9 +402,10 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
args[i++] = strtok_r (NULL, "/", &sp);
/* make sure above loop ran nicely until completion, and also
that there is no excess data in 'd' afterwards */
- if ( (i != rh->nargs) ||
- (NULL == args[i - 1]) ||
- (NULL != (fin = strtok_r (NULL, "/", &sp))) )
+ if ( (! rh->nargs_is_upper_bound) &&
+ ( (i != rh->nargs) ||
+ (NULL == args[i - 1]) ||
+ (NULL != (fin = strtok_r (NULL, "/", &sp))) ) )
{
char emsg[128 + 512];
@@ -407,12 +426,12 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
emsg);
}
+
+ /* just to be safe(r), we always terminate the array with a NULL
+ (even if handlers requested precise number of arguments) */
+ args[i] = NULL;
}
- /* just to be safe(r), we always terminate the array with a NULL
- (which handlers should not read, but at least if they do, they'll
- crash pretty reliably...) */
- args[rh->nargs] = NULL;
/* Above logic ensures that 'root' is exactly non-NULL for POST operations,
so we test for 'root' to decide which handler to invoke. */
@@ -473,6 +492,244 @@ handler_seed (const struct TEH_RequestHandler *rh,
/**
+ * Handle POST "/management/..." requests.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param root uploaded JSON data
+ * @param args array of additional options
+ * @return MHD result code
+ */
+static MHD_RESULT
+handle_post_management (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const json_t *root,
+ const char *const args[])
+{
+ if (NULL == args[0])
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/management");
+ }
+ if (0 == strcmp (args[0],
+ "auditors"))
+ {
+ struct TALER_AuditorPublicKeyP auditor_pub;
+
+ if (NULL == args[1])
+ return TEH_handler_management_auditors (connection,
+ root);
+ if ( (NULL == args[1]) ||
+ (NULL == args[2]) ||
+ (0 != strcmp (args[2],
+ "disable")) ||
+ (NULL != args[3]) )
+ return r404 (connection,
+ "/management/auditors/$AUDITOR_PUB/disable");
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[1],
+ strlen (args[1]),
+ &auditor_pub,
+ sizeof (auditor_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ args[1]);
+ }
+ return TEH_handler_management_auditors_AP_disable (connection,
+ &auditor_pub,
+ root);
+ }
+ if (0 == strcmp (args[0],
+ "denominations"))
+ {
+ struct GNUNET_HashCode h_denom_pub;
+
+ if ( (NULL == args[0]) ||
+ (NULL == args[1]) ||
+ (NULL == args[2]) ||
+ (0 != strcmp (args[2],
+ "revoke")) ||
+ (NULL != args[3]) )
+ return r404 (connection,
+ "/management/denominations/$HDP/revoke");
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[2],
+ strlen (args[2]),
+ &h_denom_pub,
+ sizeof (h_denom_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ args[2]);
+ }
+ return TEH_handler_management_denominations_HDP_revoke (connection,
+ &h_denom_pub,
+ root);
+ }
+ if (0 == strcmp (args[0],
+ "signkeys"))
+ {
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ if ( (NULL == args[0]) ||
+ (NULL == args[1]) ||
+ (NULL == args[2]) ||
+ (0 != strcmp (args[2],
+ "revoke")) ||
+ (NULL != args[3]) )
+ return r404 (connection,
+ "/management/signkeys/$HDP/revoke");
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[2],
+ strlen (args[2]),
+ &exchange_pub,
+ sizeof (exchange_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ args[2]);
+ }
+ return TEH_handler_management_signkeys_EP_revoke (connection,
+ &exchange_pub,
+ root);
+ }
+#if FIXME
+ /* not yet implemented! */
+ if (0 == strcmp (args[0],
+ "keys"))
+ {
+ if (NULL != args[1])
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/management/keys/*");
+ }
+ return TEH_handler_management_post_keys (connection,
+ root);
+ }
+#endif
+ if (0 == strcmp (args[0],
+ "wire"))
+ {
+ if (NULL == args[1])
+ return TEH_handler_management_denominations_wire (connection,
+ root);
+ if ( (0 != strcmp (args[1],
+ "disable")) ||
+ (NULL != args[2]) )
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/management/wire/disable");
+ }
+ return TEH_handler_management_denominations_wire_disable (connection,
+ root);
+ }
+ if (0 == strcmp (args[0],
+ "wire-fees"))
+ {
+ if (NULL != args[1])
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/management/wire-fees/*");
+ }
+ return TEH_handler_management_post_wire_fees (connection,
+ root);
+ }
+ GNUNET_break_op (0);
+ return r404 (connection, "/management/*");
+}
+
+
+/**
+ * Handle a get "/management" request.
+ *
+ * @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
+ */
+static MHD_RESULT
+handle_get_management (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const char *const args[1])
+{
+ if ( (NULL == args[0]) ||
+ (0 != strcmp (args[0],
+ "keys")) ||
+ (NULL != args[1]) )
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/management/*");
+ }
+ GNUNET_break (0); // not implemented
+ return MHD_NO;
+}
+
+
+/**
+ * Handle POST "/auditors/..." requests.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param root uploaded JSON data
+ * @param args array of additional options
+ * @return MHD result code
+ */
+static MHD_RESULT
+handle_post_auditors (const struct TEH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ const json_t *root,
+ const char *const args[])
+{
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ struct GNUNET_HashCode h_denom_pub;
+
+ if ( (NULL == args[0]) ||
+ (NULL == args[1]) ||
+ (NULL != args[0]) )
+ {
+ GNUNET_break_op (0);
+ return r404 (connection, "/auditors/$AUDITOR_PUB/$H_DENOM_PUB");
+ }
+
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[0],
+ strlen (args[0]),
+ &auditor_pub,
+ sizeof (auditor_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ args[0]);
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (args[1],
+ strlen (args[1]),
+ &h_denom_pub,
+ sizeof (h_denom_pub)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ args[1]);
+ }
+ return TEH_handler_auditors (connection,
+ &auditor_pub,
+ &h_denom_pub,
+ root);
+}
+
+
+/**
* Handle incoming HTTP request.
*
* @param cls closure for MHD daemon (unused)
@@ -600,6 +857,29 @@ handle_mhd_request (void *cls,
.handler.get = &TEH_handler_deposits_get,
.nargs = 4
},
+ /* POST management endpoints */
+ {
+ .url = "management",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler.post = &handle_post_management,
+ .nargs = 4,
+ .nargs_is_upper_bound = true
+ },
+ /* GET management endpoints (we only really have "/management/keys") */
+ {
+ .url = "management",
+ .method = MHD_HTTP_METHOD_GET,
+ .handler.get = &handle_get_management,
+ .nargs = 1
+ },
+ /* auditor endpoints */
+ {
+ .url = "auditors",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler.post = &handle_post_auditors,
+ .nargs = 4,
+ .nargs_is_upper_bound = true
+ },
/* mark end of list */
{
.url = NULL
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index ad46788c4..5e7738163 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -134,6 +134,12 @@ struct TEH_RequestHandler
unsigned int nargs;
/**
+ * Is the number of arguments given in @e nargs only an upper bound,
+ * and calling with fewer arguments could be OK?
+ */
+ bool nargs_is_upper_bound;
+
+ /**
* Mime type to use in reply (hint, can be NULL).
*/
const char *mime_type;
diff --git a/src/exchange/taler-exchange-httpd_auditors.c b/src/exchange/taler-exchange-httpd_auditors.c
index 60c633cf5..f0fbb7ebe 100644
--- a/src/exchange/taler-exchange-httpd_auditors.c
+++ b/src/exchange/taler-exchange-httpd_auditors.c
@@ -209,7 +209,7 @@ add_auditor_denom_sig (void *cls,
MHD_RESULT
-TEH_handler_management_denominations_auditors (
+TEH_handler_auditors (
struct MHD_Connection *connection,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const struct GNUNET_HashCode *h_denom_pub,
@@ -255,4 +255,4 @@ TEH_handler_management_denominations_auditors (
}
-/* end of taler-exchange-httpd_management_auditors.c */
+/* end of taler-exchange-httpd_auditors.c */
diff --git a/src/exchange/taler-exchange-httpd_auditors.h b/src/exchange/taler-exchange-httpd_auditors.h
index de180587d..f8191f8a2 100644
--- a/src/exchange/taler-exchange-httpd_auditors.h
+++ b/src/exchange/taler-exchange-httpd_auditors.h
@@ -36,7 +36,7 @@
* @return MHD result code
*/
MHD_RESULT
-TEH_handler_management_denominations_auditors (
+TEH_handler_auditors (
struct MHD_Connection *connection,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const struct GNUNET_HashCode *h_denom_pub,
diff --git a/src/exchange/taler-exchange-httpd_management.h b/src/exchange/taler-exchange-httpd_management.h
index cd5c5d8af..b5ab8478e 100644
--- a/src/exchange/taler-exchange-httpd_management.h
+++ b/src/exchange/taler-exchange-httpd_management.h
@@ -29,14 +29,12 @@
* Handle a "/management/auditors" request.
*
* @param connection the MHD connection to handle
- * @param h_denom_pub hash of the public key of the denomination to revoke
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_management_auditors (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
const json_t *root);
@@ -44,14 +42,14 @@ TEH_handler_management_auditors (
* Handle a "/management/auditors/$AUDITOR_PUB/disable" request.
*
* @param connection the MHD connection to handle
- * @param h_denom_pub hash of the public key of the denomination to revoke
+ * @param auditor_pub public key of the auditor to disable
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_management_auditors_AP_disable (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
const json_t *root);
@@ -89,16 +87,15 @@ TEH_handler_management_signkeys_EP_revoke (
* Handle a POST "/management/keys" request.
*
* @param connection the MHD connection to handle
- * @param h_denom_pub hash of the public key of the denomination to revoke
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_management_post_keys (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
const json_t *root);
+
/**
* Handle a "/management/wire" request.
*
@@ -113,7 +110,7 @@ TEH_handler_management_denominations_wire (
/**
- * Handle a "/management/wire" request.
+ * Handle a "/management/wire/disable" request.
*
* @param connection the MHD connection to handle
* @param root uploaded JSON data
diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c b/src/exchange/taler-exchange-httpd_management_auditors.c
index 02e4d4fa2..33f1c6df3 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors.c
@@ -145,7 +145,6 @@ add_auditor (void *cls,
MHD_RESULT
TEH_handler_management_auditors (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
const json_t *root)
{
struct AddAuditorContext aac;
diff --git a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
index 8904b444d..e360c1a52 100644
--- a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
+++ b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c
@@ -137,16 +137,16 @@ del_auditor (void *cls,
MHD_RESULT
TEH_handler_management_auditors_AP_disable (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
const json_t *root)
{
struct TALER_MasterSignatureP master_sig;
- struct DelAuditorContext dac;
+ struct DelAuditorContext dac = {
+ .auditor_pub = *auditor_pub
+ };
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_sig",
&master_sig),
- GNUNET_JSON_spec_fixed_auto ("auditor_pub",
- &dac.auditor_pub),
TALER_JSON_spec_absolute_time ("validity_end",
&dac.validity_end),
GNUNET_JSON_spec_end ()
@@ -171,7 +171,7 @@ TEH_handler_management_auditors_AP_disable (
TALER_SIGNATURE_MASTER_DEL_AUDITOR),
.purpose.size = htonl (sizeof (da)),
.end_date = GNUNET_TIME_absolute_hton (dac.validity_end),
- .auditor_pub = dac.auditor_pub
+ .auditor_pub = *auditor_pub
};
if (GNUNET_OK !=
diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c
index ab4399bd8..2ac69a1db 100644
--- a/src/exchange/taler-exchange-httpd_management_post_keys.c
+++ b/src/exchange/taler-exchange-httpd_management_post_keys.c
@@ -323,7 +323,6 @@ add_keys (void *cls,
MHD_RESULT
TEH_handler_management_post_keys (
struct MHD_Connection *connection,
- const struct GNUNET_HashCode *h_denom_pub,
const json_t *root)
{
struct AddKeysContext akc;