fix error handling for very large uploads, fix re-generation of /keys response after Expires expires

This commit is contained in:
Christian Grothoff 2021-12-08 18:12:28 +01:00
parent ed7379d235
commit 7e84b5570a
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
7 changed files with 58 additions and 29 deletions

View File

@ -1003,6 +1003,36 @@ handle_mhd_request (void *cls,
"illegal incoming correlation ID\n");
correlation_id = NULL;
}
/* Check if upload is in bounds */
if (0 == strcasecmp (method,
MHD_HTTP_METHOD_POST))
{
const char *cl;
/* Maybe check for maximum upload size
and refuse requests if they are just too big. */
cl = MHD_lookup_connection_value (connection,
MHD_HEADER_KIND,
MHD_HTTP_HEADER_CONTENT_LENGTH);
if (NULL != cl)
{
unsigned long long cv;
char dummy;
if (1 != sscanf (cl,
"%llu%c",
&cv,
&dummy))
{
/* Not valid HTTP request, just close connection. */
GNUNET_break_op (0);
return MHD_NO;
}
if (cv > TALER_MHD_REQUEST_BUFFER_MAX)
return TALER_MHD_reply_request_too_large (connection);
}
}
}
GNUNET_async_scope_enter (&rc->async_scope_id,

View File

@ -1557,7 +1557,7 @@ get_date_string (struct GNUNET_TIME_Absolute at,
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
setup_general_response_headers (const struct TEH_KeyStateHandle *ksh,
setup_general_response_headers (struct TEH_KeyStateHandle *ksh,
struct MHD_Response *response)
{
char dat[128];
@ -1590,6 +1590,9 @@ setup_general_response_headers (const struct TEH_KeyStateHandle *ksh,
MHD_add_response_header (response,
MHD_HTTP_HEADER_EXPIRES,
dat));
ksh->signature_expires
= GNUNET_TIME_absolute_min (m,
ksh->signature_expires);
}
return GNUNET_OK;
}

View File

@ -367,6 +367,8 @@ TEH_handler_management_post_keys (
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"array expected for denom_sigs and signkey_sigs");
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received /management/keys\n");
akc.nd_sigs = json_array_size (denom_sigs);
akc.d_sigs = GNUNET_new_array (akc.nd_sigs,
struct DenomSig);
@ -404,6 +406,8 @@ TEH_handler_management_post_keys (
{
GNUNET_free (akc.d_sigs);
GNUNET_JSON_parse_free (spec);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure to handle /management/keys\n");
return ret;
}
akc.ns_sigs = json_array_size (signkey_sigs);
@ -440,6 +444,8 @@ TEH_handler_management_post_keys (
}
if (! ok)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure to handle /management/keys\n");
GNUNET_free (akc.d_sigs);
GNUNET_free (akc.s_sigs);
GNUNET_JSON_parse_free (spec);

View File

@ -30,6 +30,12 @@
#include <gnunet/gnunet_mhd_compat.h>
/**
* Maximum POST request size.
*/
#define TALER_MHD_REQUEST_BUFFER_MAX (1024 * 1024 * 16)
/**
* Global options for response generation.
*/

View File

@ -99,6 +99,10 @@ handle_post_keys_finished (void *cls,
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE:
hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json);
break;
default:
/* unexpected response code */
GNUNET_break_op (0);

View File

@ -27,12 +27,6 @@
#include "taler_mhd_lib.h"
/**
* Maximum POST request size.
*/
#define REQUEST_BUFFER_MAX (1024 * 1024)
/**
* Process a POST request containing a JSON object. This function
* realizes an MHD POST processor that will (incrementally) process
@ -65,7 +59,7 @@ TALER_MHD_parse_post_json (struct MHD_Connection *connection,
{
enum GNUNET_JSON_PostResult pr;
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
pr = GNUNET_JSON_post_parser (TALER_MHD_REQUEST_BUFFER_MAX,
connection,
con_cls,
upload_data,
@ -87,9 +81,9 @@ TALER_MHD_parse_post_json (struct MHD_Connection *connection,
return GNUNET_YES;
case GNUNET_JSON_PR_REQUEST_TOO_LARGE:
GNUNET_break (NULL == *json);
return (MHD_NO ==
TALER_MHD_reply_request_too_large
(connection)) ? GNUNET_SYSERR : GNUNET_NO;
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Closing connection, upload too large\n");
return MHD_NO;
case GNUNET_JSON_PR_JSON_INVALID:
GNUNET_break (NULL == *json);
return (MHD_YES ==

View File

@ -419,24 +419,10 @@ TALER_MHD_reply_with_ec (struct MHD_Connection *connection,
MHD_RESULT
TALER_MHD_reply_request_too_large (struct MHD_Connection *connection)
{
struct MHD_Response *response;
response = MHD_create_response_from_buffer (0,
NULL,
MHD_RESPMEM_PERSISTENT);
if (NULL == response)
return MHD_NO;
TALER_MHD_add_global_headers (response);
{
MHD_RESULT ret;
ret = MHD_queue_response (connection,
MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
response);
MHD_destroy_response (response);
return ret;
}
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT,
NULL);
}