diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mint/Makefile.am | 13 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd.c | 45 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd.h | 8 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_admin.c | 4 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 4 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_validation.c | 231 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_validation.h | 76 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_wire.c | 31 | 
8 files changed, 331 insertions, 81 deletions
| diff --git a/src/mint/Makefile.am b/src/mint/Makefile.am index a115d63a..aa9b1974 100644 --- a/src/mint/Makefile.am +++ b/src/mint/Makefile.am @@ -11,17 +11,18 @@ bin_PROGRAMS = \  taler_mint_httpd_SOURCES = \    taler-mint-httpd.c taler-mint-httpd.h \ -  taler-mint-httpd_keystate.c taler-mint-httpd_keystate.h \ -  taler-mint-httpd_db.c taler-mint-httpd_db.h \ -  taler-mint-httpd_parsing.c taler-mint-httpd_parsing.h \ -  taler-mint-httpd_responses.c taler-mint-httpd_responses.h \ -  taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \    taler-mint-httpd_admin.c taler-mint-httpd_admin.h \ +  taler-mint-httpd_db.c taler-mint-httpd_db.h \    taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \ +  taler-mint-httpd_keystate.c taler-mint-httpd_keystate.h \ +  taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \ +  taler-mint-httpd_parsing.c taler-mint-httpd_parsing.h \ +  taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h \    taler-mint-httpd_reserve.c taler-mint-httpd_reserve.h \ +  taler-mint-httpd_responses.c taler-mint-httpd_responses.h \    taler-mint-httpd_tracking.c taler-mint-httpd_tracking.h \    taler-mint-httpd_wire.c taler-mint-httpd_wire.h \ -  taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h +  taler-mint-httpd_validation.c taler-mint-httpd_validation.h  taler_mint_httpd_LDADD = \    $(LIBGCRYPT_LIBS) \    $(top_builddir)/src/util/libtalerutil.la \ diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index 26a440c9..5d6aa058 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -39,6 +39,7 @@  #include "taler-mint-httpd_test.h"  #endif  #include "taler_mintdb_plugin.h" +#include "taler-mint-httpd_validation.h"  /**   * Which currency is used by this mint? @@ -67,13 +68,6 @@ struct GNUNET_CONFIGURATION_Handle *cfg;  struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;  /** - * In which format does this MINT expect wiring instructions? - * NULL-terminated array of 0-terminated wire format types, - * suitable for passing to #TALER_json_validate_wireformat(). - */ -const char **TMH_expected_wire_formats; - -/**   * Our DB plugin.   */  struct TALER_MINTDB_Plugin *TMH_plugin; @@ -384,9 +378,6 @@ mint_serve_process_config (const char *mint_directory)  {    unsigned long long port;    char *TMH_master_public_key_str; -  char *wireformats; -  const char *token; -  unsigned int len;    cfg = TALER_config_load (mint_directory);    if (NULL == cfg) @@ -414,35 +405,9 @@ mint_serve_process_config (const char *mint_directory)               (unsigned int) TALER_CURRENCY_LEN);      return GNUNET_SYSERR;    } -  /* Find out list of supported wire formats */    if (GNUNET_OK != -      GNUNET_CONFIGURATION_get_value_string (cfg, -                                             "mint", -                                             "wireformat", -                                             &wireformats)) -  { -    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, -                               "mint", -                               "wireformat"); +      TMH_VALIDATION_init (cfg))      return GNUNET_SYSERR; -  } -  /* build NULL-terminated array of TMH_expected_wire_formats */ -  TMH_expected_wire_formats = GNUNET_new_array (1, -                                                const char *); -  len = 1; -  for (token = strtok (wireformats, -                       " "); -       NULL != token; -       token = strtok (NULL, -                       " ")) -  { -    /* Grow by 1, appending NULL-terminator */ -    GNUNET_array_append (TMH_expected_wire_formats, -                         len, -                         NULL); -    TMH_expected_wire_formats[len - 2] = GNUNET_strdup (token); -  } -  GNUNET_free (wireformats);    if (GNUNET_OK !=        GNUNET_CONFIGURATION_get_value_string (cfg, @@ -453,6 +418,7 @@ mint_serve_process_config (const char *mint_directory)      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,                                 "mint",                                 "master_public_key"); +    TMH_VALIDATION_done ();      return GNUNET_SYSERR;    }    if (GNUNET_OK != @@ -463,6 +429,7 @@ mint_serve_process_config (const char *mint_directory)      fprintf (stderr,               "Invalid master public key given in mint configuration.");      GNUNET_free (TMH_master_public_key_str); +    TMH_VALIDATION_done ();      return GNUNET_SYSERR;    }    GNUNET_free (TMH_master_public_key_str); @@ -472,6 +439,7 @@ mint_serve_process_config (const char *mint_directory)    {      fprintf (stderr,               "Failed to initialize DB subsystem\n"); +    TMH_VALIDATION_done ();      return GNUNET_SYSERR;    }    if (GNUNET_YES == @@ -496,6 +464,7 @@ mint_serve_process_config (const char *mint_directory)                                 "mint",                                 "port",                                 "port number required"); +    TMH_VALIDATION_done ();      return GNUNET_SYSERR;    } @@ -505,6 +474,7 @@ mint_serve_process_config (const char *mint_directory)      fprintf (stderr,               "Invalid configuration (value out of range): %llu is not a valid port\n",               port); +    TMH_VALIDATION_done ();      return GNUNET_SYSERR;    }    serve_port = (uint16_t) port; @@ -772,6 +742,7 @@ main (int argc,                                    session);    }    TALER_MINTDB_plugin_unload (TMH_plugin); +  TMH_VALIDATION_done ();    return (GNUNET_SYSERR == ret) ? 1 : 0;  } diff --git a/src/mint/taler-mint-httpd.h b/src/mint/taler-mint-httpd.h index e83dd66f..d45325aa 100644 --- a/src/mint/taler-mint-httpd.h +++ b/src/mint/taler-mint-httpd.h @@ -27,6 +27,7 @@  #include <microhttpd.h> +  /**   * Which currency is used by this mint?   */ @@ -53,13 +54,6 @@ extern int TMH_test_mode;  extern char *TMH_mint_directory;  /** - * In which formats does this MINT expect wiring instructions? - * NULL-terminated array of 0-terminated wire format types, - * suitable for passing to #TALER_json_validate_wireformat(). - */ -extern const char **TMH_expected_wire_formats; - -/**   * Master public key (according to the   * configuration in the mint directory).   */ diff --git a/src/mint/taler-mint-httpd_admin.c b/src/mint/taler-mint-httpd_admin.c index 99f25641..e6f186f0 100644 --- a/src/mint/taler-mint-httpd_admin.c +++ b/src/mint/taler-mint-httpd_admin.c @@ -24,6 +24,7 @@  #include "taler-mint-httpd_admin.h"  #include "taler-mint-httpd_parsing.h"  #include "taler-mint-httpd_responses.h" +#include "taler-mint-httpd_validation.h"  /** @@ -144,8 +145,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,      return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;    }    if (GNUNET_YES != -      TALER_json_validate_wireformat (TMH_expected_wire_formats, -				      wire)) +      TMH_json_validate_wireformat (wire))    {      GNUNET_break_op (0);      TMH_PARSE_release_data (spec); diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index 0aef4775..40c5a4db 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -34,6 +34,7 @@  #include "taler-mint-httpd_deposit.h"  #include "taler-mint-httpd_responses.h"  #include "taler-mint-httpd_keystate.h" +#include "taler-mint-httpd_validation.h"  /** @@ -162,8 +163,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,      return MHD_YES; /* failure */    if (GNUNET_YES != -      TALER_json_validate_wireformat (TMH_expected_wire_formats, -				      wire)) +      TMH_json_validate_wireformat (wire))    {      TMH_PARSE_release_data (spec);      return TMH_RESPONSE_reply_arg_unknown (connection, diff --git a/src/mint/taler-mint-httpd_validation.c b/src/mint/taler-mint-httpd_validation.c new file mode 100644 index 00000000..461e8875 --- /dev/null +++ b/src/mint/taler-mint-httpd_validation.c @@ -0,0 +1,231 @@ +/* +  This file is part of TALER +  Copyright (C) 2016 GNUnet e.V. + +  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 +  Foundation; either version 3, or (at your option) any later version. + +  TALER is distributed in the hope that it will be useful, but WITHOUT ANY +  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details. + +  You should have received a copy of the GNU Affero General Public License along with +  TALER; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * @file taler-mint-httpd_validation.c + * @brief helpers for calling the wire plugins to validate addresses + * @author Christian Grothoff + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include "taler-mint-httpd_validation.h" +#include "taler_wire_plugin.h" + + +/** + * Information we keep for each plugin. + */ +struct Plugin +{ + +  /** +   * We keep plugins in a DLL. +   */ +  struct Plugin *next; + +  /** +   * We keep plugins in a DLL. +   */ +  struct Plugin *prev; + +  /** +   * Type of the wireformat. +   */ +  char *type; + +  /** +   * Pointer to the plugin. +   */ +  struct TALER_WIRE_Plugin *plugin; + +}; + +/** + * Head of DLL of wire plugins. + */ +static struct Plugin *wire_head; + +/** + * Tail of DLL of wire plugins. + */ +static struct Plugin *wire_tail; + + +/** + * Initialize validation subsystem. + * + * @param cfg configuration to use + * @return #GNUNET_OK on success + */ +int +TMH_VALIDATION_init (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ +  struct Plugin *p; +  char *wireformats; +  char *lib_name; +  const char *token; + +  /* Find out list of supported wire formats */ +  if (GNUNET_OK != +      GNUNET_CONFIGURATION_get_value_string (cfg, +                                             "mint", +                                             "wireformat", +                                             &wireformats)) +  { +    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, +                               "mint", +                               "wireformat"); +    return GNUNET_SYSERR; +  } +  for (token = strtok (wireformats, +                       " "); +       NULL != token; +       token = strtok (NULL, +                       " ")) +  { +    (void) GNUNET_asprintf (&lib_name, +                            "libtaler_plugin_wire_%s", +                            lib_name); +    p = GNUNET_new (struct Plugin); +    p->type = GNUNET_strdup (token); +    p->plugin = GNUNET_PLUGIN_load (lib_name, +                                    (void *) cfg); +    if (NULL == p->plugin) +    { +      GNUNET_free (p); +      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                  "Failed to load plugin %s\n", +                  lib_name); +      GNUNET_free (lib_name); +      TMH_VALIDATION_done (); +      return GNUNET_SYSERR; +    } +    p->plugin->library_name = lib_name; +    GNUNET_CONTAINER_DLL_insert (wire_head, +                                 wire_tail, +                                 p); +  } +  GNUNET_free (wireformats); +  return GNUNET_OK; +} + + +/** + * Shutdown validation subsystem. + */ +void +TMH_VALIDATION_done () +{ +  struct Plugin *p; +  char *lib_name; + +  while (NULL != (p = wire_head)) +  { +    GNUNET_CONTAINER_DLL_remove (wire_head, +                                 wire_tail, +                                 p); +    lib_name = p->plugin->library_name; +    GNUNET_assert (NULL == GNUNET_PLUGIN_unload (lib_name, +                                                 p->plugin)); +    GNUNET_free (lib_name); +    GNUNET_free (p->type); +    GNUNET_free (p); +  } +} + + +/** + * Check if the given wire format JSON object is correctly formatted as + * a wire address. + * + * @param wire the JSON wire format object + * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not + */ +int +TMH_json_validate_wireformat (const json_t *wire) +{ +  const char *stype; +  json_error_t error; +  struct Plugin *p; + +  if (0 != json_unpack_ex ((json_t *) wire, +                           &error, 0, +                           "{s:s}", +                           "type", &stype)) +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  } +  for (p=wire_head; NULL != p; p = p->next) +    if (0 == strcasecmp (p->type, +                         stype)) +      return p->plugin->wire_validate (wire); +  return GNUNET_NO; +} + + +/** + * Check if we support the given wire method. + * + * @param type type of wire method to check + * @return #GNUNET_YES if the method is supported + */ +int +TMH_VALIDATION_test_method (const char *type) +{ +  struct Plugin *p; + +  for (p=wire_head;NULL != p;p = p->next) +    if (0 == strcasecmp (type, +                         p->type)) +      return GNUNET_YES; +  return GNUNET_NO; +} + + +/** + * Obtain supported validation methods as a JSON array, + * and as a hash. + * + * @param[out] h set to the hash of the JSON methods + * @return JSON array with the supported validation methods + */ +json_t * +TMH_VALIDATION_get_methods (struct GNUNET_HashCode *h) +{ +  json_t *methods; +  struct GNUNET_HashContext *hc; +  const char *wf; +  struct Plugin *p; + +  methods = json_array (); +  hc = GNUNET_CRYPTO_hash_context_start (); +  for (p=wire_head;NULL != p;p = p->next) +  { +    wf = p->type; +    json_array_append_new (methods, +                           json_string (wf)); +    GNUNET_CRYPTO_hash_context_read (hc, +                                     wf, +                                     strlen (wf) + 1); +  } +  GNUNET_CRYPTO_hash_context_finish (hc, +                                     h); +  return methods; +} + + +/* end of taler-mint-httpd_validation.c */ diff --git a/src/mint/taler-mint-httpd_validation.h b/src/mint/taler-mint-httpd_validation.h new file mode 100644 index 00000000..f5fb1900 --- /dev/null +++ b/src/mint/taler-mint-httpd_validation.h @@ -0,0 +1,76 @@ +/* +  This file is part of TALER +  Copyright (C) 2016 GNUnet e.V. + +  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 +  Foundation; either version 3, or (at your option) any later version. + +  TALER is distributed in the hope that it will be useful, but WITHOUT ANY +  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details. + +  You should have received a copy of the GNU Affero General Public License along with +  TALER; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * @file taler-mint-httpd_validation.h + * @brief helpers for calling the wire plugins to validate addresses + * @author Christian Grothoff + */ +#ifndef TALER_MINT_HTTPD_VALIDATION_H +#define TALER_MINT_HTTPD_VALIDATION_H +#include <gnunet/gnunet_util_lib.h> +#include <jansson.h> + + +/** + * Initialize validation subsystem. + * + * @param cfg configuration to use + * @return #GNUNET_OK on success + */ +int +TMH_VALIDATION_init (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Shutdown validation subsystem. + */ +void +TMH_VALIDATION_done (void); + + +/** + * Check if the given wire format JSON object is correctly formatted as + * a wire address. + * + * @param wire the JSON wire format object + * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not + */ +int +TMH_json_validate_wireformat (const json_t *wire); + +/** + * Check if we support the given wire method. + * + * @param type type of wire method to check + * @return #GNUNET_YES if the method is supported + */ +int +TMH_VALIDATION_test_method (const char *type); + + +/** + * Obtain supported validation methods as a JSON array, + * and as a hash. + * + * @param[out] h set to the hash of the JSON methods + * @return JSON array with the supported validation methods + */ +json_t * +TMH_VALIDATION_get_methods (struct GNUNET_HashCode *h); + + +#endif diff --git a/src/mint/taler-mint-httpd_wire.c b/src/mint/taler-mint-httpd_wire.c index 1eb3f6be..020a7e10 100644 --- a/src/mint/taler-mint-httpd_wire.c +++ b/src/mint/taler-mint-httpd_wire.c @@ -21,6 +21,7 @@  #include "platform.h"  #include "taler-mint-httpd_keystate.h"  #include "taler-mint-httpd_responses.h" +#include "taler-mint-httpd_validation.h"  #include "taler-mint-httpd_wire.h"  #include <jansson.h> @@ -45,24 +46,10 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh,    struct TALER_MintPublicKeyP pub;    struct TALER_MintSignatureP sig;    json_t *methods; -  struct GNUNET_HashContext *hc; -  unsigned int i; -  const char *wf; -  methods = json_array (); -  hc = GNUNET_CRYPTO_hash_context_start (); -  for (i=0;NULL != (wf = TMH_expected_wire_formats[i]); i++) -  { -    json_array_append_new (methods, -                           json_string (wf)); -    GNUNET_CRYPTO_hash_context_read (hc, -                                     wf, -                                     strlen (wf) + 1); -  }    wsm.purpose.size = htonl (sizeof (wsm));    wsm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_WIRE_TYPES); -  GNUNET_CRYPTO_hash_context_finish (hc, -                                     &wsm.h_wire_types); +  methods = TMH_VALIDATION_get_methods (&wsm.h_wire_types);    TMH_KS_sign (&wsm.purpose,                 &pub,                 &sig); @@ -97,7 +84,6 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,    struct MHD_Response *response;    int ret;    char *wire_test_redirect; -  unsigned int i;    response = MHD_create_response_from_buffer (0, NULL,                                                MHD_RESPMEM_PERSISTENT); @@ -107,11 +93,7 @@ TMH_WIRE_handler_wire_test (struct TMH_RequestHandler *rh,      return MHD_NO;    }    TMH_RESPONSE_add_global_headers (response); -  for (i=0;NULL != TMH_expected_wire_formats[i];i++) -    if (0 == strcasecmp ("test", -                         TMH_expected_wire_formats[i])) -      break; -  if (NULL == TMH_expected_wire_formats[i]) +  if (GNUNET_NO == TMH_VALIDATION_test_method ("test"))    {      /* Return 501: not implemented */      ret = MHD_queue_response (connection, @@ -165,13 +147,8 @@ TMH_WIRE_handler_wire_sepa (struct TMH_RequestHandler *rh,    char *sepa_wire_file;    int fd;    struct stat sbuf; -  unsigned int i; -  for (i=0;NULL != TMH_expected_wire_formats[i];i++) -    if (0 == strcasecmp ("sepa", -                         TMH_expected_wire_formats[i])) -      break; -  if (NULL == TMH_expected_wire_formats[i]) +  if (GNUNET_NO == TMH_VALIDATION_test_method ("sepa"))    {      /* Return 501: not implemented */      response = MHD_create_response_from_buffer (0, NULL, | 
