From 2cb59820a8715a0fc7d57e9f321d0917aeb0ec03 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 4 Mar 2021 16:02:07 +0100 Subject: fix #6785 --- src/backend/taler-merchant-httpd.c | 87 ++++++++++++++-------- ...er-merchant-httpd_private-delete-instances-ID.c | 43 +++++++++-- ...er-merchant-httpd_private-delete-instances-ID.h | 17 ++++- ...taler-merchant-httpd_private-get-instances-ID.c | 43 +++++++++-- ...taler-merchant-httpd_private-get-instances-ID.h | 17 ++++- ...ler-merchant-httpd_private-patch-instances-ID.c | 45 +++++++++-- ...ler-merchant-httpd_private-patch-instances-ID.h | 16 ++++ ...merchant-httpd_private-post-instances-ID-auth.c | 46 ++++++++++-- ...merchant-httpd_private-post-instances-ID-auth.h | 16 ++++ 9 files changed, 273 insertions(+), 57 deletions(-) diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index e46e4c8e..721221a0 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -1066,6 +1066,51 @@ url_handler (void *cls, in the code... */ .max_upload = 1024 * 1024 * 8 }, + /* GET /instances/$ID/: MUST be at the beginning of the + array, as this endpoint ONLY applies to the + default instance! See use_default logic below. */ + { + .url_prefix = "/instances/", + .method = MHD_HTTP_METHOD_GET, + .have_id_segment = true, + .handler = &TMH_private_get_instances_default_ID + }, + /* DELETE /private/instances/$ID: MUST be at the beginning of the + array, as this endpoint ONLY applies to the + default instance! See use_default logic below. */ + { + .url_prefix = "/instances/", + .method = MHD_HTTP_METHOD_DELETE, + .have_id_segment = true, + .handler = &TMH_private_delete_instances_default_ID + }, + /* PATCH /instances/$ID/: MUST be at the beginning of the + array, as this endpoint ONLY applies to the + default instance! See use_default logic below.*/ + { + .url_prefix = "/instances/", + .method = MHD_HTTP_METHOD_PATCH, + .have_id_segment = true, + .handler = &TMH_private_patch_instances_default_ID, + /* allow instance data of up to 8 MB, that should be plenty; + note that exceeding #GNUNET_MAX_MALLOC_CHECKED (40 MB) + would require further changes to the allocation logic + in the code... */ + .max_upload = 1024 * 1024 * 8 + }, + /* POST /auth: MUST be at the beginning of the + array, as this endpoint ONLY applies to the + default instance! See use_default logic below.*/ + { + .url_prefix = "/instances/", + .url_suffix = "auth", + .method = MHD_HTTP_METHOD_POST, + .have_id_segment = true, + .handler = &TMH_private_post_instances_default_ID_auth, + /* Body should be pretty small. */ + .max_upload = 1024 * 1024, + }, + /* **** End of array entries specific to default instance **** */ /* GET /instances/$ID/: */ { @@ -1555,7 +1600,7 @@ url_handler (void *cls, if (use_default) handlers = private_handlers; else - handlers = &private_handlers[2]; /* skip first two methods: default instance-only! */ + handlers = &private_handlers[6]; /* skip first six methods: default instance-only! */ url += strlen (private_prefix) - 1; use_private = true; } @@ -1617,7 +1662,7 @@ url_handler (void *cls, rh->url_prefix, prefix_strlen)) ) continue; - if (GNUNET_NO == rh->have_id_segment) + if (! rh->have_id_segment) { if (NULL != suffix_url) continue; /* too many segments to match */ @@ -1634,7 +1679,7 @@ url_handler (void *cls, else { if ( (NULL == infix_url) - ^ (GNUNET_NO == rh->have_id_segment) ) + ^ (! rh->have_id_segment) ) // FIXME: have_id_segment is always 'true' here! continue; /* infix existence mismatch */ if ( ( (NULL == suffix_url) ^ (NULL == rh->url_suffix) ) ) @@ -1679,13 +1724,11 @@ url_handler (void *cls, if (use_private) { const char *auth; - struct TMH_MerchantInstance *def_instance; bool auth_ok; bool auth_malformed = false; /* PATCHing an instance can alternatively be checked against the default instance */ - def_instance = TMH_lookup_instance (NULL); auth = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION); @@ -1702,30 +1745,16 @@ url_handler (void *cls, auth_malformed = true; } - /* Are the credentials provided OK for the default instance? - Check against CLI override and default instance. */ - auth_ok = ( (NULL == default_auth) || - ( (NULL != auth) && - (0 == strcmp (auth, - default_auth)) ) ); - /* If we have no default instance, authentication is satisfied EVEN - if the 'default_auth' is NULL; otherwise, only if the default_auth - matched OR the auth_hash matched */ - if ( (NULL != def_instance) && - (NULL == default_auth) ) - auth_ok = (GNUNET_OK == - TMH_check_auth (auth, - &def_instance->auth.auth_salt, - &def_instance->auth.auth_hash)); - /* Only permit 'default' auth if we are either working with - the default instance OR patching/deleting an instance OR have no instance */ - if ( (hc->rh->handler != &TMH_private_patch_instances_ID) && - (hc->rh->handler != &TMH_private_delete_instances_ID) && - ( (NULL != hc->instance) || - (def_instance != hc->instance) ) ) - auth_ok = false; - - /* Check against selected instance if we have one */ + /* If we have not even a default instance AND no override + credentials, THEN we accept anything (no access control) */ + auth_ok = ( (NULL == TMH_lookup_instance (NULL)) && + (NULL == default_auth) ); + /* Are the credentials provided OK for CLI override? */ + auth_ok |= ( (NULL != default_auth) && + (NULL != auth) && + (0 == strcmp (auth, + default_auth)) ); + /* Check against selected instance, if we have one */ if (NULL != hc->instance) auth_ok |= (GNUNET_OK == TMH_check_auth (auth, diff --git a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c index 1b1184cf..baa082a2 100644 --- a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c @@ -26,17 +26,14 @@ /** * Handle a DELETE "/instances/$ID" request. * - * @param rh context of the handler + * @param mi instance to delete * @param connection the MHD connection to handle - * @param[in,out] hc context with further information about the request * @return MHD result code */ -MHD_RESULT -TMH_private_delete_instances_ID (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) +static MHD_RESULT +delete_instances_ID (struct TMH_MerchantInstance *mi, + struct MHD_Connection *connection) { - struct TMH_MerchantInstance *mi = hc->instance; const char *purge; enum GNUNET_DB_QueryStatus qs; @@ -87,4 +84,36 @@ TMH_private_delete_instances_ID (const struct TMH_RequestHandler *rh, } +MHD_RESULT +TMH_private_delete_instances_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + + return delete_instances_ID (mi, + connection); +} + + +MHD_RESULT +TMH_private_delete_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi; + + mi = TMH_lookup_instance (hc->infix); + if (NULL == mi) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN, + hc->infix); + } + return delete_instances_ID (mi, + connection); +} + + /* end of taler-merchant-httpd_private-delete-instances-ID.c */ diff --git a/src/backend/taler-merchant-httpd_private-delete-instances-ID.h b/src/backend/taler-merchant-httpd_private-delete-instances-ID.h index 6fc38f54..42add77c 100644 --- a/src/backend/taler-merchant-httpd_private-delete-instances-ID.h +++ b/src/backend/taler-merchant-httpd_private-delete-instances-ID.h @@ -25,7 +25,7 @@ /** - * Handle a DELETE "/instances/$ID" request. + * Handle a DELETE "/instances/$ID/private" request. * * @param rh context of the handler * @param connection the MHD connection to handle @@ -37,5 +37,20 @@ TMH_private_delete_instances_ID (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc); + +/** + * Handle a DELETE "/private/instances/$ID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_delete_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + + /* end of taler-merchant-httpd_private-delete-instances-ID.h */ #endif diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID.c b/src/backend/taler-merchant-httpd_private-get-instances-ID.c index 8f392393..6c3730a2 100644 --- a/src/backend/taler-merchant-httpd_private-get-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-get-instances-ID.c @@ -26,17 +26,14 @@ /** * Handle a GET "/instances/$ID" request. * - * @param rh context of the handler + * @param mi instance to return information about * @param connection the MHD connection to handle - * @param[in,out] hc context with further information about the request * @return MHD result code */ -MHD_RESULT -TMH_private_get_instances_ID (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) +static MHD_RESULT +get_instances_ID (struct TMH_MerchantInstance *mi, + struct MHD_Connection *connection) { - struct TMH_MerchantInstance *mi = hc->instance; json_t *ja; GNUNET_assert (NULL != mi); @@ -104,4 +101,36 @@ TMH_private_get_instances_ID (const struct TMH_RequestHandler *rh, } +MHD_RESULT +TMH_private_get_instances_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + + return get_instances_ID (mi, + connection); +} + + +MHD_RESULT +TMH_private_get_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi; + + mi = TMH_lookup_instance (hc->infix); + if (NULL == mi) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN, + hc->infix); + } + return get_instances_ID (mi, + connection); +} + + /* end of taler-merchant-httpd_private-get-instances-ID.c */ diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID.h b/src/backend/taler-merchant-httpd_private-get-instances-ID.h index 08ac05d5..b2a0262a 100644 --- a/src/backend/taler-merchant-httpd_private-get-instances-ID.h +++ b/src/backend/taler-merchant-httpd_private-get-instances-ID.h @@ -25,7 +25,7 @@ /** - * Handle a GET "/instances/$ID" request. + * Handle a GET "/instances/$ID/private" request. * * @param rh context of the handler * @param connection the MHD connection to handle @@ -37,5 +37,20 @@ TMH_private_get_instances_ID (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc); + +/** + * Handle a GET "/private/instances/$ID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_get_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + + /* end of taler-merchant-httpd_private-get-instances-ID.h */ #endif diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c index edda6228..8f21c76d 100644 --- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c @@ -50,17 +50,16 @@ free_wm (struct TMH_WireMethod *wm) /** * PATCH configuration of an existing instance, given its configuration. * - * @param rh context of the handler + * @param mi instance to patch * @param connection the MHD connection to handle * @param[in,out] hc context with further information about the request * @return MHD result code */ -MHD_RESULT -TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) +static MHD_RESULT +patch_instances_ID (struct TMH_MerchantInstance *mi, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) { - struct TMH_MerchantInstance *mi = hc->instance; struct TALER_MERCHANTDB_InstanceSettings is; json_t *payto_uris; const char *name; @@ -421,4 +420,38 @@ giveup: } +MHD_RESULT +TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + + return patch_instances_ID (mi, + connection, + hc); +} + + +MHD_RESULT +TMH_private_patch_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi; + + mi = TMH_lookup_instance (hc->infix); + if (NULL == mi) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN, + hc->infix); + } + return patch_instances_ID (mi, + connection, + hc); +} + + /* end of taler-merchant-httpd_private-patch-instances-ID.c */ diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.h b/src/backend/taler-merchant-httpd_private-patch-instances-ID.h index 5fe29645..d96bb7b3 100644 --- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.h +++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.h @@ -29,6 +29,7 @@ /** * PATCH configuration of an existing instance, given its configuration. + * This is the handler called using the instance's own authentication. * * @param rh context of the handler * @param connection the MHD connection to handle @@ -40,4 +41,19 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc); + +/** + * PATCH configuration of an existing instance, given its configuration. + * This is the handler called using the default instance's authentication. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_patch_instances_default_ID (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + #endif diff --git a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c index 8d8df93f..084310bb 100644 --- a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c +++ b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c @@ -37,19 +37,18 @@ /** * Change the authentication settings of an instance. * - * @param rh context of the handler + * @param mi instance to modify settings of * @param connection the MHD connection to handle * @param[in,out] hc context with further information about the request * @return MHD result code */ -MHD_RESULT -TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) +static MHD_RESULT +post_instances_ID_auth (struct TMH_MerchantInstance *mi, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) { struct TALER_MERCHANTDB_InstanceAuthSettings ias; const char *auth_token = NULL; - struct TMH_MerchantInstance *mi = hc->instance; json_t *jauth = hc->request_body; { @@ -159,4 +158,39 @@ retry: 0); } + +MHD_RESULT +TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi = hc->instance; + + return post_instances_ID_auth (mi, + connection, + hc); +} + + +MHD_RESULT +TMH_private_post_instances_default_ID_auth (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + struct TMH_MerchantInstance *mi; + + mi = TMH_lookup_instance (hc->infix); + if (NULL == mi) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN, + hc->infix); + } + return post_instances_ID_auth (mi, + connection, + hc); +} + + /* end of taler-merchant-httpd_private-post-instances-ID-auth.c */ diff --git a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h index 3a47c42c..2acb42f0 100644 --- a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h +++ b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h @@ -30,6 +30,7 @@ /** * Change the instance's auth settings. + * This is the handler called using the instance's own authentication. * * @param rh context of the handler * @param connection the MHD connection to handle @@ -41,4 +42,19 @@ TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc); + +/** + * Change the instance's auth settings. + * This is the handler called using the default instance's authentication. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_post_instances_default_ID_auth (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + #endif -- cgit v1.2.3