From 0b40e7802798dfde3ac6cc5f24dd1f20e03b8fb5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 9 Jan 2015 17:10:38 +0100 Subject: stop exporting microhttpd_lib API --- src/include/Makefile.am | 1 - src/include/taler_microhttpd_lib.h | 119 ---------- src/include/taler_rsa.h | 3 + src/mint/Makefile.am | 1 + src/mint/taler-mint-httpd.c | 2 +- src/mint/taler-mint-httpd_deposit.c | 2 +- src/mint/taler-mint-httpd_json.c | 417 +++++++++++++++++++++++++++++++++++ src/mint/taler-mint-httpd_json.h | 119 ++++++++++ src/mint/taler-mint-httpd_keys.c | 2 +- src/mint/taler-mint-httpd_mhd.c | 2 +- src/mint/taler-mint-httpd_refresh.c | 2 +- src/mint/taler-mint-httpd_withdraw.c | 2 +- src/util/Makefile.am | 1 - src/util/microhttpd.c | 417 ----------------------------------- src/util/rsa.c | 3 + src/util/test_rsa.c | 4 + 16 files changed, 553 insertions(+), 544 deletions(-) delete mode 100644 src/include/taler_microhttpd_lib.h create mode 100644 src/mint/taler-mint-httpd_json.c create mode 100644 src/mint/taler-mint-httpd_json.h delete mode 100644 src/util/microhttpd.c diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 42e6dda91..c95940ea2 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -4,7 +4,6 @@ talerinclude_HEADERS = \ platform.h \ taler_db_lib.h \ taler_json_lib.h \ - taler_microhttpd_lib.h \ taler_mint_service.h \ taler_rsa.h \ taler_signatures.h \ diff --git a/src/include/taler_microhttpd_lib.h b/src/include/taler_microhttpd_lib.h deleted file mode 100644 index da601401f..000000000 --- a/src/include/taler_microhttpd_lib.h +++ /dev/null @@ -1,119 +0,0 @@ - - -#ifndef TALER_MICROHTTPD_LIB_H_ -#define TALER_MICROHTTPD_LIB_H_ - - -#include -#include - - -/** - * Constants for JSON navigation description. - */ -enum -{ - /** - * Access a field. - * Param: const char * - */ - JNAV_FIELD, - /** - * Access an array index. - * Param: int - */ - JNAV_INDEX, - /** - * Return base32crockford encoded data of - * constant size. - * Params: (void *, size_t) - */ - JNAV_RET_DATA, - /** - * Return base32crockford encoded data of - * variable size. - * Params: (void **, size_t *) - */ - JNAV_RET_DATA_VAR, - /** - * Return a json object, which must be - * of the given type (JSON_* type constants, - * or -1 for any type). - * Params: (int, json_t **) - */ - JNAV_RET_TYPED_JSON -}; - - - -/** - * Send JSON object as response. Decreases - * the reference count of the JSON object. - * - * @param connection the MHD connection - * @param json the json object - * @param status_code the http status code - * @return MHD result code (MHD_YES on success) - */ -int -send_response_json (struct MHD_Connection *connection, - json_t *json, - unsigned int status_code); - - -/** - * Send a JSON object via an MHD connection, - * specified with the JANSSON pack syntax (see json_pack). - * - * @param connection connection to send the JSON over - * @param http_code HTTP status for the response - * @param fmt format string for pack - * @param ... varargs - * @return MHD_YES on success or MHD_NO on error - */ -int -request_send_json_pack (struct MHD_Connection *connection, - unsigned int http_code, - const char *fmt, ...); - - -/** - * Process a POST request containing a JSON object. - * - * @param connection the MHD connection - * @param con_cs the closure (contains a 'struct Buffer *') - * @param upload_data the POST data - * @param upload_data_size the POST data size - * @param json the JSON object for a completed request - * - * @returns - * GNUNET_YES if json object was parsed - * GNUNET_NO is request incomplete or invalid - * GNUNET_SYSERR on internal error - */ -int -process_post_json (struct MHD_Connection *connection, - void **con_cls, - const char *upload_data, - size_t *upload_data_size, - json_t **json); - - -/** - * Navigate through a JSON tree. - * - * Sends an error response if navigation is impossible (i.e. - * the JSON object is invalid) - * - * @param connection the connection to send an error response to - * @param root the JSON node to start the navigation at. - * @param ... navigation specification (see JNAV_*) - * @return GNUNET_YES if navigation was successful - * GNUNET_NO if json is malformed, error response was generated - * GNUNET_SYSERR on internal error - */ -int -request_json_require_nav (struct MHD_Connection *connection, - const json_t *root, ...); - -#endif /* TALER_MICROHTTPD_LIB_H_ */ diff --git a/src/include/taler_rsa.h b/src/include/taler_rsa.h index 1ed530013..1d263ae09 100644 --- a/src/include/taler_rsa.h +++ b/src/include/taler_rsa.h @@ -1,3 +1,6 @@ +/* NOTE: this is obsolete logic, we should migrate to the + GNUNET_CRYPTO_rsa-API as soon as possible */ + /* This file is part of TALER (C) 2014 Christian Grothoff (and other contributing authors) diff --git a/src/mint/Makefile.am b/src/mint/Makefile.am index 2ae153485..d0a58812e 100644 --- a/src/mint/Makefile.am +++ b/src/mint/Makefile.am @@ -75,6 +75,7 @@ taler_mint_reservemod_LDFLAGS = \ taler_mint_httpd_SOURCES = \ taler-mint-httpd.c \ taler-mint-httpd_mhd.c \ + taler-mint-httpd_json.c taler-mint-httpd_json.h \ taler-mint-httpd_keys.c \ taler-mint-httpd_deposit.c \ taler-mint-httpd_withdraw.c \ diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index 6d69813c0..1734e61ef 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -33,7 +33,7 @@ #include "taler_signatures.h" #include "taler_rsa.h" #include "taler_json_lib.h" -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd_mhd.h" #include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_deposit.h" diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index ecbc5c13b..2f6c3bc8f 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -32,7 +32,7 @@ #include "taler_signatures.h" #include "taler_rsa.h" #include "taler_json_lib.h" -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_deposit.h" diff --git a/src/mint/taler-mint-httpd_json.c b/src/mint/taler-mint-httpd_json.c new file mode 100644 index 000000000..e9183073f --- /dev/null +++ b/src/mint/taler-mint-httpd_json.c @@ -0,0 +1,417 @@ +#include "platform.h" +#include +#include "taler-mint-httpd_json.h" + + + +/** + * Initial size for POST + * request buffer. + */ +#define REQUEST_BUFFER_INITIAL 1024 + +/** + * Maximum POST request size + */ +#define REQUEST_BUFFER_MAX (1024*1024) + + +/** + * Buffer for POST requests. + */ +struct Buffer +{ + /** + * Allocated memory + */ + char *data; + + /** + * Number of valid bytes in buffer. + */ + size_t fill; + + /** + * Number of allocated bytes in buffer. + */ + size_t alloc; +}; + + +/** + * Initialize a buffer. + * + * @param buf the buffer to initialize + * @param data the initial data + * @param data_size size of the initial data + * @param alloc_size size of the buffer + * @param max_size maximum size that the buffer can grow to + * @return a GNUnet result code + */ +static int +buffer_init (struct Buffer *buf, const void *data, size_t data_size, size_t alloc_size, size_t max_size) +{ + if (data_size > max_size || alloc_size > max_size) + return GNUNET_SYSERR; + if (data_size > alloc_size) + alloc_size = data_size; + buf->data = GNUNET_malloc (alloc_size); + memcpy (buf->data, data, data_size); + return GNUNET_OK; +} + + +/** + * Free the data in a buffer. Does *not* free + * the buffer object itself. + * + * @param buf buffer to de-initialize + */ +static void +buffer_deinit (struct Buffer *buf) +{ + GNUNET_free (buf->data); + buf->data = NULL; +} + + +/** + * Append data to a buffer, growing the buffer if necessary. + * + * @param buf the buffer to append to + * @param data the data to append + * @param size the size of @a data + * @param max_size maximum size that the buffer can grow to + * @return GNUNET_OK on success, + * GNUNET_NO if the buffer can't accomodate for the new data + * GNUNET_SYSERR on fatal error (out of memory?) + */ +static int +buffer_append (struct Buffer *buf, const void *data, size_t data_size, size_t max_size) +{ + if (buf->fill + data_size > max_size) + return GNUNET_NO; + if (data_size + buf->fill > buf->alloc) + { + char *new_buf; + size_t new_size = buf->alloc; + while (new_size < buf->fill + data_size) + new_size += 2; + if (new_size > max_size) + return GNUNET_NO; + new_buf = GNUNET_malloc (new_size); + memcpy (new_buf, buf->data, buf->fill); + buf->data = new_buf; + buf->alloc = new_size; + } + memcpy (buf->data + buf->fill, data, data_size); + buf->fill += data_size; + return GNUNET_OK; +} + + +/** + * Send JSON object as response. Decreases the reference count of the + * JSON object. + * + * @param connection the MHD connection + * @param json the json object + * @param status_code the http status code + * @return MHD result code + */ +int +send_response_json (struct MHD_Connection *connection, + json_t *json, + unsigned int status_code) +{ + struct MHD_Response *resp; + char *json_str; + + json_str = json_dumps (json, JSON_INDENT(2)); + json_decref (json); + resp = MHD_create_response_from_buffer (strlen (json_str), json_str, + MHD_RESPMEM_MUST_FREE); + if (NULL == resp) + return MHD_NO; + return MHD_queue_response (connection, status_code, resp); +} + + +/** + * Send a JSON object via an MHD connection, + * specified with the JANSSON pack syntax (see json_pack). + * + * @param connection connection to send the JSON over + * @param http_code HTTP status for the response + * @param fmt format string for pack + * @param ... varargs + * @return MHD_YES on success or MHD_NO on error + */ +int +request_send_json_pack (struct MHD_Connection *connection, + unsigned int http_code, + const char *fmt, ...) +{ + json_t *msg; + va_list argp; + int ret; + + va_start(argp, fmt); + msg = json_vpack_ex (NULL, 0, fmt, argp); + va_end(argp); + if (NULL == msg) + return MHD_NO; + ret = send_response_json (connection, msg, http_code); + json_decref (msg); + return ret; +} + + +/** + * Process a POST request containing a JSON object. + * + * @param connection the MHD connection + * @param con_cs the closure (contains a 'struct Buffer *') + * @param upload_data the POST data + * @param upload_data_size the POST data size + * @param json the JSON object for a completed request + * + * @returns + * GNUNET_YES if json object was parsed + * GNUNET_NO is request incomplete or invalid + * GNUNET_SYSERR on internal error + */ +int +process_post_json (struct MHD_Connection *connection, + void **con_cls, + const char *upload_data, + size_t *upload_data_size, + json_t **json) +{ + struct Buffer *r = *con_cls; + + if (NULL == *con_cls) + { + /* We are seeing a fresh POST request. */ + + r = GNUNET_new (struct Buffer); + if (GNUNET_OK != buffer_init (r, upload_data, *upload_data_size, + REQUEST_BUFFER_INITIAL, REQUEST_BUFFER_MAX)) + { + *con_cls = NULL; + buffer_deinit (r); + GNUNET_free (r); + return GNUNET_SYSERR; + } + *upload_data_size = 0; + *con_cls = r; + return GNUNET_NO; + } + if (0 != *upload_data_size) + { + /* We are seeing an old request with more data available. */ + + if (GNUNET_OK != buffer_append (r, upload_data, *upload_data_size, + REQUEST_BUFFER_MAX)) + { + /* Request too long or we're out of memory. */ + + *con_cls = NULL; + buffer_deinit (r); + GNUNET_free (r); + return GNUNET_SYSERR; + } + *upload_data_size = 0; + return GNUNET_NO; + } + + /* We have seen the whole request. */ + + *json = json_loadb (r->data, r->fill, 0, NULL); + buffer_deinit (r); + GNUNET_free (r); + if (NULL == *json) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Can't parse JSON request body\n"); + return request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + GNUNET_NO, GNUNET_SYSERR, + "{s:s}", + "error", "invalid json"); + } + *con_cls = NULL; + + return GNUNET_YES; +} + + +/** + * Navigate through a JSON tree. + * + * Sends an error response if navigation is impossible (i.e. + * the JSON object is invalid) + * + * @param connection the connection to send an error response to + * @param root the JSON node to start the navigation at. + * @param ... navigation specification (see JNAV_*) + * @return GNUNET_YES if navigation was successful + * GNUNET_NO if json is malformed, error response was generated + * GNUNET_SYSERR on internal error + */ +int +request_json_require_nav (struct MHD_Connection *connection, + const json_t *root, ...) +{ + va_list argp; + int ignore = GNUNET_NO; + // what's our current path from 'root'? + json_t *path; + + path = json_array (); + + va_start(argp, root); + + while (1) + { + int command = va_arg(argp, int); + switch (command) + { + case JNAV_FIELD: + { + const char *fname = va_arg(argp, const char *); + if (GNUNET_YES == ignore) + break; + json_array_append_new (path, json_string (fname)); + root = json_object_get (root, fname); + if (NULL == root) + { + + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s,s:o}", + "error", "missing field in JSON", + "path", path); + ignore = GNUNET_YES; + break; + } + } + break; + case JNAV_INDEX: + { + int fnum = va_arg(argp, int); + if (GNUNET_YES == ignore) + break; + json_array_append_new (path, json_integer (fnum)); + root = json_array_get (root, fnum); + if (NULL == root) + { + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s, s:o}", + "error", "missing index in JSON", + "path", path); + ignore = GNUNET_YES; + break; + } + } + break; + case JNAV_RET_DATA: + { + void *where = va_arg (argp, void *); + size_t len = va_arg (argp, size_t); + const char *str; + int res; + + va_end(argp); + if (GNUNET_YES == ignore) + return GNUNET_NO; + str = json_string_value (root); + if (NULL == str) + { + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s, s:o}", + "error", "string expected", + "path", path); + return GNUNET_NO; + } + res = GNUNET_STRINGS_string_to_data (str, strlen (str), + where, len); + if (GNUNET_OK != res) + { + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s,s:o}", + "error", "malformed binary data in JSON", + "path", path); + return GNUNET_NO; + } + return GNUNET_YES; + } + break; + case JNAV_RET_DATA_VAR: + { + void **where = va_arg (argp, void **); + size_t *len = va_arg (argp, size_t *); + const char *str; + + va_end(argp); + if (GNUNET_YES == ignore) + return GNUNET_NO; + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + *len = (strlen (str) * 5) / 8; + if (where != NULL) + { + int res; + *where = GNUNET_malloc (*len); + res = GNUNET_STRINGS_string_to_data (str, strlen (str), + *where, *len); + if (GNUNET_OK != res) + { + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s, s:o}", + "error", "malformed binary data in JSON", + "path", path); + return GNUNET_NO; + } + } + return GNUNET_OK; + } + break; + case JNAV_RET_TYPED_JSON: + { + int typ = va_arg (argp, int); + const json_t **r_json = va_arg (argp, const json_t **); + + va_end(argp); + if (GNUNET_YES == ignore) + return GNUNET_NO; + if (typ != -1 && json_typeof (root) != typ) + { + (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, + 0, 0, + "{s:s, s:i, s:i s:o}", + "error", "wrong JSON field type", + "type_expected", typ, + "type_actual", json_typeof (root), + "path", path); + return GNUNET_NO; + } + *r_json = root; + return GNUNET_OK; + } + break; + default: + GNUNET_assert (0); + } + } + GNUNET_assert (0); +} + + + diff --git a/src/mint/taler-mint-httpd_json.h b/src/mint/taler-mint-httpd_json.h new file mode 100644 index 000000000..da601401f --- /dev/null +++ b/src/mint/taler-mint-httpd_json.h @@ -0,0 +1,119 @@ + + +#ifndef TALER_MICROHTTPD_LIB_H_ +#define TALER_MICROHTTPD_LIB_H_ + + +#include +#include + + +/** + * Constants for JSON navigation description. + */ +enum +{ + /** + * Access a field. + * Param: const char * + */ + JNAV_FIELD, + /** + * Access an array index. + * Param: int + */ + JNAV_INDEX, + /** + * Return base32crockford encoded data of + * constant size. + * Params: (void *, size_t) + */ + JNAV_RET_DATA, + /** + * Return base32crockford encoded data of + * variable size. + * Params: (void **, size_t *) + */ + JNAV_RET_DATA_VAR, + /** + * Return a json object, which must be + * of the given type (JSON_* type constants, + * or -1 for any type). + * Params: (int, json_t **) + */ + JNAV_RET_TYPED_JSON +}; + + + +/** + * Send JSON object as response. Decreases + * the reference count of the JSON object. + * + * @param connection the MHD connection + * @param json the json object + * @param status_code the http status code + * @return MHD result code (MHD_YES on success) + */ +int +send_response_json (struct MHD_Connection *connection, + json_t *json, + unsigned int status_code); + + +/** + * Send a JSON object via an MHD connection, + * specified with the JANSSON pack syntax (see json_pack). + * + * @param connection connection to send the JSON over + * @param http_code HTTP status for the response + * @param fmt format string for pack + * @param ... varargs + * @return MHD_YES on success or MHD_NO on error + */ +int +request_send_json_pack (struct MHD_Connection *connection, + unsigned int http_code, + const char *fmt, ...); + + +/** + * Process a POST request containing a JSON object. + * + * @param connection the MHD connection + * @param con_cs the closure (contains a 'struct Buffer *') + * @param upload_data the POST data + * @param upload_data_size the POST data size + * @param json the JSON object for a completed request + * + * @returns + * GNUNET_YES if json object was parsed + * GNUNET_NO is request incomplete or invalid + * GNUNET_SYSERR on internal error + */ +int +process_post_json (struct MHD_Connection *connection, + void **con_cls, + const char *upload_data, + size_t *upload_data_size, + json_t **json); + + +/** + * Navigate through a JSON tree. + * + * Sends an error response if navigation is impossible (i.e. + * the JSON object is invalid) + * + * @param connection the connection to send an error response to + * @param root the JSON node to start the navigation at. + * @param ... navigation specification (see JNAV_*) + * @return GNUNET_YES if navigation was successful + * GNUNET_NO if json is malformed, error response was generated + * GNUNET_SYSERR on internal error + */ +int +request_json_require_nav (struct MHD_Connection *connection, + const json_t *root, ...); + +#endif /* TALER_MICROHTTPD_LIB_H_ */ diff --git a/src/mint/taler-mint-httpd_keys.c b/src/mint/taler-mint-httpd_keys.c index ba023fe69..ce8bdf6e0 100644 --- a/src/mint/taler-mint-httpd_keys.c +++ b/src/mint/taler-mint-httpd_keys.c @@ -32,7 +32,7 @@ #include "taler_signatures.h" #include "taler_rsa.h" #include "taler_json_lib.h" -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd_keys.h" diff --git a/src/mint/taler-mint-httpd_mhd.c b/src/mint/taler-mint-httpd_mhd.c index 09f3025b8..d78f36d95 100644 --- a/src/mint/taler-mint-httpd_mhd.c +++ b/src/mint/taler-mint-httpd_mhd.c @@ -27,7 +27,7 @@ #include #include #include -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd.h" #include "taler-mint-httpd_mhd.h" diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 8121bb234..913f40fa2 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -32,7 +32,7 @@ #include "taler_signatures.h" #include "taler_rsa.h" #include "taler_json_lib.h" -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_mhd.h" #include "taler-mint-httpd_refresh.h" diff --git a/src/mint/taler-mint-httpd_withdraw.c b/src/mint/taler-mint-httpd_withdraw.c index 7ffa45706..0fd418540 100644 --- a/src/mint/taler-mint-httpd_withdraw.c +++ b/src/mint/taler-mint-httpd_withdraw.c @@ -32,7 +32,7 @@ #include "taler_signatures.h" #include "taler_rsa.h" #include "taler_json_lib.h" -#include "taler_microhttpd_lib.h" +#include "taler-mint-httpd_json.h" #include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_mhd.h" #include "taler-mint-httpd_withdraw.h" diff --git a/src/util/Makefile.am b/src/util/Makefile.am index f935802a6..b74e90da9 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -7,7 +7,6 @@ libtalerutil_la_SOURCES = \ util.c \ json.c \ db.c \ - microhttpd.c \ rsa.c libtalerutil_la_LIBADD = \ diff --git a/src/util/microhttpd.c b/src/util/microhttpd.c deleted file mode 100644 index f3bea74f8..000000000 --- a/src/util/microhttpd.c +++ /dev/null @@ -1,417 +0,0 @@ -#include "platform.h" -#include -#include "taler_microhttpd_lib.h" - - - -/** - * Initial size for POST - * request buffer. - */ -#define REQUEST_BUFFER_INITIAL 1024 - -/** - * Maximum POST request size - */ -#define REQUEST_BUFFER_MAX (1024*1024) - - -/** - * Buffer for POST requests. - */ -struct Buffer -{ - /** - * Allocated memory - */ - char *data; - - /** - * Number of valid bytes in buffer. - */ - size_t fill; - - /** - * Number of allocated bytes in buffer. - */ - size_t alloc; -}; - - -/** - * Initialize a buffer. - * - * @param buf the buffer to initialize - * @param data the initial data - * @param data_size size of the initial data - * @param alloc_size size of the buffer - * @param max_size maximum size that the buffer can grow to - * @return a GNUnet result code - */ -static int -buffer_init (struct Buffer *buf, const void *data, size_t data_size, size_t alloc_size, size_t max_size) -{ - if (data_size > max_size || alloc_size > max_size) - return GNUNET_SYSERR; - if (data_size > alloc_size) - alloc_size = data_size; - buf->data = GNUNET_malloc (alloc_size); - memcpy (buf->data, data, data_size); - return GNUNET_OK; -} - - -/** - * Free the data in a buffer. Does *not* free - * the buffer object itself. - * - * @param buf buffer to de-initialize - */ -static void -buffer_deinit (struct Buffer *buf) -{ - GNUNET_free (buf->data); - buf->data = NULL; -} - - -/** - * Append data to a buffer, growing the buffer if necessary. - * - * @param buf the buffer to append to - * @param data the data to append - * @param size the size of @a data - * @param max_size maximum size that the buffer can grow to - * @return GNUNET_OK on success, - * GNUNET_NO if the buffer can't accomodate for the new data - * GNUNET_SYSERR on fatal error (out of memory?) - */ -static int -buffer_append (struct Buffer *buf, const void *data, size_t data_size, size_t max_size) -{ - if (buf->fill + data_size > max_size) - return GNUNET_NO; - if (data_size + buf->fill > buf->alloc) - { - char *new_buf; - size_t new_size = buf->alloc; - while (new_size < buf->fill + data_size) - new_size += 2; - if (new_size > max_size) - return GNUNET_NO; - new_buf = GNUNET_malloc (new_size); - memcpy (new_buf, buf->data, buf->fill); - buf->data = new_buf; - buf->alloc = new_size; - } - memcpy (buf->data + buf->fill, data, data_size); - buf->fill += data_size; - return GNUNET_OK; -} - - -/** - * Send JSON object as response. Decreases the reference count of the - * JSON object. - * - * @param connection the MHD connection - * @param json the json object - * @param status_code the http status code - * @return MHD result code - */ -int -send_response_json (struct MHD_Connection *connection, - json_t *json, - unsigned int status_code) -{ - struct MHD_Response *resp; - char *json_str; - - json_str = json_dumps (json, JSON_INDENT(2)); - json_decref (json); - resp = MHD_create_response_from_buffer (strlen (json_str), json_str, - MHD_RESPMEM_MUST_FREE); - if (NULL == resp) - return MHD_NO; - return MHD_queue_response (connection, status_code, resp); -} - - -/** - * Send a JSON object via an MHD connection, - * specified with the JANSSON pack syntax (see json_pack). - * - * @param connection connection to send the JSON over - * @param http_code HTTP status for the response - * @param fmt format string for pack - * @param ... varargs - * @return MHD_YES on success or MHD_NO on error - */ -int -request_send_json_pack (struct MHD_Connection *connection, - unsigned int http_code, - const char *fmt, ...) -{ - json_t *msg; - va_list argp; - int ret; - - va_start(argp, fmt); - msg = json_vpack_ex (NULL, 0, fmt, argp); - va_end(argp); - if (NULL == msg) - return MHD_NO; - ret = send_response_json (connection, msg, http_code); - json_decref (msg); - return ret; -} - - -/** - * Process a POST request containing a JSON object. - * - * @param connection the MHD connection - * @param con_cs the closure (contains a 'struct Buffer *') - * @param upload_data the POST data - * @param upload_data_size the POST data size - * @param json the JSON object for a completed request - * - * @returns - * GNUNET_YES if json object was parsed - * GNUNET_NO is request incomplete or invalid - * GNUNET_SYSERR on internal error - */ -int -process_post_json (struct MHD_Connection *connection, - void **con_cls, - const char *upload_data, - size_t *upload_data_size, - json_t **json) -{ - struct Buffer *r = *con_cls; - - if (NULL == *con_cls) - { - /* We are seeing a fresh POST request. */ - - r = GNUNET_new (struct Buffer); - if (GNUNET_OK != buffer_init (r, upload_data, *upload_data_size, - REQUEST_BUFFER_INITIAL, REQUEST_BUFFER_MAX)) - { - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return GNUNET_SYSERR; - } - *upload_data_size = 0; - *con_cls = r; - return GNUNET_NO; - } - if (0 != *upload_data_size) - { - /* We are seeing an old request with more data available. */ - - if (GNUNET_OK != buffer_append (r, upload_data, *upload_data_size, - REQUEST_BUFFER_MAX)) - { - /* Request too long or we're out of memory. */ - - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return GNUNET_SYSERR; - } - *upload_data_size = 0; - return GNUNET_NO; - } - - /* We have seen the whole request. */ - - *json = json_loadb (r->data, r->fill, 0, NULL); - buffer_deinit (r); - GNUNET_free (r); - if (NULL == *json) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Can't parse JSON request body\n"); - return request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - GNUNET_NO, GNUNET_SYSERR, - "{s:s}", - "error", "invalid json"); - } - *con_cls = NULL; - - return GNUNET_YES; -} - - -/** - * Navigate through a JSON tree. - * - * Sends an error response if navigation is impossible (i.e. - * the JSON object is invalid) - * - * @param connection the connection to send an error response to - * @param root the JSON node to start the navigation at. - * @param ... navigation specification (see JNAV_*) - * @return GNUNET_YES if navigation was successful - * GNUNET_NO if json is malformed, error response was generated - * GNUNET_SYSERR on internal error - */ -int -request_json_require_nav (struct MHD_Connection *connection, - const json_t *root, ...) -{ - va_list argp; - int ignore = GNUNET_NO; - // what's our current path from 'root'? - json_t *path; - - path = json_array (); - - va_start(argp, root); - - while (1) - { - int command = va_arg(argp, int); - switch (command) - { - case JNAV_FIELD: - { - const char *fname = va_arg(argp, const char *); - if (GNUNET_YES == ignore) - break; - json_array_append_new (path, json_string (fname)); - root = json_object_get (root, fname); - if (NULL == root) - { - - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s,s:o}", - "error", "missing field in JSON", - "path", path); - ignore = GNUNET_YES; - break; - } - } - break; - case JNAV_INDEX: - { - int fnum = va_arg(argp, int); - if (GNUNET_YES == ignore) - break; - json_array_append_new (path, json_integer (fnum)); - root = json_array_get (root, fnum); - if (NULL == root) - { - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s, s:o}", - "error", "missing index in JSON", - "path", path); - ignore = GNUNET_YES; - break; - } - } - break; - case JNAV_RET_DATA: - { - void *where = va_arg (argp, void *); - size_t len = va_arg (argp, size_t); - const char *str; - int res; - - va_end(argp); - if (GNUNET_YES == ignore) - return GNUNET_NO; - str = json_string_value (root); - if (NULL == str) - { - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s, s:o}", - "error", "string expected", - "path", path); - return GNUNET_NO; - } - res = GNUNET_STRINGS_string_to_data (str, strlen (str), - where, len); - if (GNUNET_OK != res) - { - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s,s:o}", - "error", "malformed binary data in JSON", - "path", path); - return GNUNET_NO; - } - return GNUNET_YES; - } - break; - case JNAV_RET_DATA_VAR: - { - void **where = va_arg (argp, void **); - size_t *len = va_arg (argp, size_t *); - const char *str; - - va_end(argp); - if (GNUNET_YES == ignore) - return GNUNET_NO; - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - *len = (strlen (str) * 5) / 8; - if (where != NULL) - { - int res; - *where = GNUNET_malloc (*len); - res = GNUNET_STRINGS_string_to_data (str, strlen (str), - *where, *len); - if (GNUNET_OK != res) - { - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s, s:o}", - "error", "malformed binary data in JSON", - "path", path); - return GNUNET_NO; - } - } - return GNUNET_OK; - } - break; - case JNAV_RET_TYPED_JSON: - { - int typ = va_arg (argp, int); - const json_t **r_json = va_arg (argp, const json_t **); - - va_end(argp); - if (GNUNET_YES == ignore) - return GNUNET_NO; - if (typ != -1 && json_typeof (root) != typ) - { - (void) request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST, - 0, 0, - "{s:s, s:i, s:i s:o}", - "error", "wrong JSON field type", - "type_expected", typ, - "type_actual", json_typeof (root), - "path", path); - return GNUNET_NO; - } - *r_json = root; - return GNUNET_OK; - } - break; - default: - GNUNET_assert (0); - } - } - GNUNET_assert (0); -} - - - diff --git a/src/util/rsa.c b/src/util/rsa.c index cde56be9e..c34ab1661 100644 --- a/src/util/rsa.c +++ b/src/util/rsa.c @@ -1,3 +1,6 @@ +/* NOTE: this is obsolete logic, we should migrate to the + GNUNET_CRYPTO_rsa-API as soon as possible */ + /* This file is part of TALER (C) 2014 Christian Grothoff (and other contributing authors) diff --git a/src/util/test_rsa.c b/src/util/test_rsa.c index ac3ae2cd4..85114843d 100644 --- a/src/util/test_rsa.c +++ b/src/util/test_rsa.c @@ -1,3 +1,7 @@ +/* NOTE: this is obsolete logic, we should migrate to the + GNUNET_CRYPTO_rsa-API as soon as possible */ + + /* This file is part of TALER (C) 2014 Christian Grothoff (and other contributing authors) -- cgit v1.2.3