diff options
32 files changed, 331 insertions, 112 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 4290668d..f787385c 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -66,13 +66,6 @@ #include "taler-merchant-httpd_statics.h" #include "taler-merchant-httpd_templating.h" -/** - * Required prefix for the authorization header as per RFC 8959. - * (Follows RFC 6750 albeit technically violates RFC 7235, but - * Mark Nottingham thinks this should be fixed by revising HTTP - * spec (https://github.com/httpwg/http-core/issues/733)) - */ -#define RFC_8959_PREFIX "Bearer secret-token:" /** * Backlog for listen operation on unix-domain sockets. @@ -193,6 +186,8 @@ TMH_check_auth (const char *token, if (GNUNET_is_zero (hash)) return GNUNET_OK; + if (NULL == token) + return GNUNET_SYSERR; GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&val, sizeof (val), @@ -1520,57 +1515,6 @@ url_handler (void *cls, } } - /* Access control for private handlers */ - if (use_private) - { - const char *auth; - - auth = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_AUTHORIZATION); - if (NULL != auth) - { - if (0 != strncasecmp (auth, - RFC_8959_PREFIX, - strlen (RFC_8959_PREFIX))) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_UNAUTHORIZED, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "'" RFC_8959_PREFIX - "' prefix missing in 'Authorization' header"); - } - auth += strlen (RFC_8959_PREFIX); - } - if (NULL == hc->instance) - { - /* maybe before default instance is even created? - Check against 'default_auth' */ - if ( (NULL != default_auth) && - (0 != strcmp (auth, - default_auth)) ) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_UNAUTHORIZED, - TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, - "Command-line authentication override is in effect"); - } - } - else - { - if (GNUNET_OK != - TMH_check_auth (auth, - &hc->instance->settings.auth_salt, - &hc->instance->settings.auth_hash)) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_UNAUTHORIZED, - TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, - "Check 'Authentication' header"); - } - } - } - if (0 == strcmp (url, "")) url = "/"; /* code below does not like empty string */ @@ -1680,6 +1624,74 @@ url_handler (void *cls, } /* At this point, we must have found a handler */ GNUNET_assert (NULL != hc->rh); + + /* Access control for private handlers */ + if (use_private) + { + const char *auth; + struct TMH_MerchantInstance *def_instance; + bool auth_ok; + + /* 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); + if (NULL != auth) + { + if (0 != strncasecmp (auth, + RFC_8959_PREFIX, + strlen (RFC_8959_PREFIX))) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "'" RFC_8959_PREFIX + "' prefix missing in 'Authorization' header"); + } + auth += strlen (RFC_8959_PREFIX); + } + + /* 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->settings.auth_salt, + &def_instance->settings.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 (NULL != hc->instance) + auth_ok |= (GNUNET_OK == + TMH_check_auth (auth, + &hc->instance->settings.auth_salt, + &hc->instance->settings.auth_hash)); + if (! auth_ok) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, + "Check 'Authentication' header"); + } + } + + if ( (NULL == hc->instance) && (GNUNET_YES != hc->rh->skip_instance) ) return TALER_MHD_reply_with_error (connection, diff --git a/src/include/platform.h b/src/include/platform.h index b843c298..70c296fd 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA + Copyright (C) 2014, 2015, 2016, 2021 Taler Systems SA 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 @@ -55,6 +55,16 @@ to "ancient" MHD releases. */ #define MHD_NO_DEPRECATION 1 + +/** + * Required prefix for the authorization header as per RFC 8959. + * (Follows RFC 6750 albeit technically violates RFC 7235, but + * Mark Nottingham thinks this should be fixed by revising HTTP + * spec (https://github.com/httpwg/http-core/issues/733)) + */ +#define RFC_8959_PREFIX "Bearer secret-token:" + + #endif /* PLATFORM_H_ */ /* end of platform.h */ diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h index c1f8d4dc..4eafd6fa 100644 --- a/src/include/taler_merchant_testing_lib.h +++ b/src/include/taler_merchant_testing_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2018 Taler Systems SA + (C) 2018-2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -542,20 +542,19 @@ TALER_TESTING_cmd_merchant_post_orders_no_claim (const char *label, * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_post_orders2 (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *order_id, - struct GNUNET_TIME_Absolute - refund_deadline, - struct GNUNET_TIME_Absolute - pay_deadline, - bool claim_token, - const char *amount, - const char *payment_target, - const char *products, - const char *locks, - const char *duplicate_of); +TALER_TESTING_cmd_merchant_post_orders2 ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *order_id, + struct GNUNET_TIME_Absolute refund_deadline, + struct GNUNET_TIME_Absolute pay_deadline, + bool claim_token, + const char *amount, + const char *payment_target, + const char *products, + const char *locks, + const char *duplicate_of); /** @@ -1329,15 +1328,15 @@ TALER_TESTING_cmd_tip_authorize_with_ec (const char *label, * @param ec expected Taler-defined error code. */ struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (const char *label, - const char *merchant_url, - const char *exchange_url, - const char * - reserve_reference, - unsigned int http_status, - const char *justification, - const char *amount, - enum TALER_ErrorCode ec); +TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec ( + const char *label, + const char *merchant_url, + const char *exchange_url, + const char *reserve_reference, + unsigned int http_status, + const char *justification, + const char *amount, + enum TALER_ErrorCode ec); /** @@ -1437,9 +1436,9 @@ TALER_TESTING_get_trait_merchant_sig ( * @return the trait */ struct TALER_TESTING_Trait -TALER_TESTING_make_trait_claim_nonce (unsigned int index, - const struct - GNUNET_CRYPTO_EddsaPublicKey *nonce); +TALER_TESTING_make_trait_claim_nonce ( + unsigned int index, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce); /** @@ -1449,14 +1448,13 @@ TALER_TESTING_make_trait_claim_nonce (unsigned int index, * @param index which nonce to pick if @a * cmd has multiple on offer * @param[out] nonce set to the wanted data. - * * @return #GNUNET_OK on success */ int -TALER_TESTING_get_trait_claim_nonce (const struct TALER_TESTING_Command *cmd, - unsigned int index, - const struct - GNUNET_CRYPTO_EddsaPublicKey **nonce); +TALER_TESTING_get_trait_claim_nonce ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct GNUNET_CRYPTO_EddsaPublicKey **nonce); /** @@ -1542,6 +1540,7 @@ TALER_TESTING_get_trait_planchet_secrets ( unsigned int index, struct TALER_PlanchetSecretsP **planchet_secrets); + /** * Offer planchet secrets. * @@ -1554,6 +1553,7 @@ TALER_TESTING_make_trait_planchet_secrets ( unsigned int index, const struct TALER_PlanchetSecretsP *planchet_secrets); + /** * Offer tip id. * @@ -1566,6 +1566,7 @@ struct TALER_TESTING_Trait TALER_TESTING_make_trait_tip_id (unsigned int index, const struct GNUNET_HashCode *tip_id); + /** * Obtain tip id from a @a cmd. * diff --git a/src/lib/merchant_api_delete_instance.c b/src/lib/merchant_api_delete_instance.c index 87b88e0c..793b413c 100644 --- a/src/lib/merchant_api_delete_instance.c +++ b/src/lib/merchant_api_delete_instance.c @@ -91,9 +91,10 @@ handle_delete_instance_finished (void *cls, { case MHD_HTTP_NO_CONTENT: break; - case MHD_HTTP_NOT_FOUND: + case MHD_HTTP_UNAUTHORIZED: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ break; default: /* unexpected response code */ diff --git a/src/lib/merchant_api_delete_order.c b/src/lib/merchant_api_delete_order.c index 4651fcf7..c3771ba8 100644 --- a/src/lib/merchant_api_delete_order.c +++ b/src/lib/merchant_api_delete_order.c @@ -88,6 +88,11 @@ handle_delete_order_finished (void *cls, { case MHD_HTTP_NO_CONTENT: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (response); + hr.hint = TALER_JSON_get_error_hint (response); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: break; case MHD_HTTP_CONFLICT: diff --git a/src/lib/merchant_api_delete_product.c b/src/lib/merchant_api_delete_product.c index 196ec09d..ba2aaaf4 100644 --- a/src/lib/merchant_api_delete_product.c +++ b/src/lib/merchant_api_delete_product.c @@ -91,6 +91,11 @@ handle_delete_product_finished (void *cls, { case MHD_HTTP_NO_CONTENT: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_delete_reserve.c b/src/lib/merchant_api_delete_reserve.c index 9a8d3991..4eedea61 100644 --- a/src/lib/merchant_api_delete_reserve.c +++ b/src/lib/merchant_api_delete_reserve.c @@ -92,6 +92,11 @@ handle_delete_reserve_finished (void *cls, { case MHD_HTTP_NO_CONTENT: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_get_instance.c b/src/lib/merchant_api_get_instance.c index 512d1b7c..42d77da9 100644 --- a/src/lib/merchant_api_get_instance.c +++ b/src/lib/merchant_api_get_instance.c @@ -195,6 +195,11 @@ handle_get_instance_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: /* instance does not exist */ hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/lib/merchant_api_get_orders.c b/src/lib/merchant_api_get_orders.c index 420510bd..c7b04ab2 100644 --- a/src/lib/merchant_api_get_orders.c +++ b/src/lib/merchant_api_get_orders.c @@ -192,6 +192,11 @@ handle_get_orders_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_get_product.c b/src/lib/merchant_api_get_product.c index c88e74f9..32e06123 100644 --- a/src/lib/merchant_api_get_product.c +++ b/src/lib/merchant_api_get_product.c @@ -173,6 +173,11 @@ handle_get_product_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_get_products.c b/src/lib/merchant_api_get_products.c index d5d57252..26146ea4 100644 --- a/src/lib/merchant_api_get_products.c +++ b/src/lib/merchant_api_get_products.c @@ -180,6 +180,11 @@ handle_get_products_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; default: /* unexpected response code */ hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/lib/merchant_api_get_reserve.c b/src/lib/merchant_api_get_reserve.c index 429cccff..710bcbc4 100644 --- a/src/lib/merchant_api_get_reserve.c +++ b/src/lib/merchant_api_get_reserve.c @@ -198,6 +198,11 @@ handle_reserve_get_finished (void *cls, return; } } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ diff --git a/src/lib/merchant_api_get_reserves.c b/src/lib/merchant_api_get_reserves.c index 52853065..32455a57 100644 --- a/src/lib/merchant_api_get_reserves.c +++ b/src/lib/merchant_api_get_reserves.c @@ -181,6 +181,11 @@ handle_reserves_get_finished (void *cls, return; } } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ diff --git a/src/lib/merchant_api_get_tips.c b/src/lib/merchant_api_get_tips.c index 16a87fff..fd3dfdae 100644 --- a/src/lib/merchant_api_get_tips.c +++ b/src/lib/merchant_api_get_tips.c @@ -184,6 +184,11 @@ handle_get_tips_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; default: /* unexpected response code */ hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/lib/merchant_api_get_transfers.c b/src/lib/merchant_api_get_transfers.c index 0bfd9990..e31fb38f 100644 --- a/src/lib/merchant_api_get_transfers.c +++ b/src/lib/merchant_api_get_transfers.c @@ -143,14 +143,14 @@ handle_transfers_get_finished (void *cls, GNUNET_JSON_spec_uint64 ("transfer_serial_id", &td->credit_serial), GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_absolute_time ("execution_time", - &td->execution_time)), + TALER_JSON_spec_absolute_time ("execution_time", + &td->execution_time)), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("verified", - &td->verified)), + GNUNET_JSON_spec_bool ("verified", + &td->verified)), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("confirmed", - &td->confirmed)), + GNUNET_JSON_spec_bool ("confirmed", + &td->confirmed)), GNUNET_JSON_spec_end () }; @@ -184,6 +184,11 @@ handle_transfers_get_finished (void *cls, return; } } + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ diff --git a/src/lib/merchant_api_lock_product.c b/src/lib/merchant_api_lock_product.c index 27f4f6e5..e9593fdb 100644 --- a/src/lib/merchant_api_lock_product.c +++ b/src/lib/merchant_api_lock_product.c @@ -102,6 +102,11 @@ handle_lock_product_finished (void *cls, break; case MHD_HTTP_NO_CONTENT: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_BAD_REQUEST: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c index 9504d16b..ac7da14f 100644 --- a/src/lib/merchant_api_merchant_get_order.c +++ b/src/lib/merchant_api_merchant_get_order.c @@ -375,6 +375,14 @@ handle_merchant_order_get_finished (void *cls, omgh->job = NULL; switch (response_code) { + case MHD_HTTP_OK: + /* see below */ + break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); @@ -383,9 +391,6 @@ handle_merchant_order_get_finished (void *cls, NULL); TALER_MERCHANT_merchant_order_get_cancel (omgh); return; - case MHD_HTTP_OK: - /* see below */ - break; default: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_merchant_get_tip.c b/src/lib/merchant_api_merchant_get_tip.c index 4d4c66f7..aad72584 100644 --- a/src/lib/merchant_api_merchant_get_tip.c +++ b/src/lib/merchant_api_merchant_get_tip.c @@ -212,17 +212,22 @@ handle_merchant_tip_get_finished (void *cls, GNUNET_JSON_parse_free (spec); break; } - case MHD_HTTP_INTERNAL_SERVER_ERROR: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ + case MHD_HTTP_UNAUTHORIZED: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: /* legal, can happen if instance or tip reserve is unknown */ hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); break; + case MHD_HTTP_INTERNAL_SERVER_ERROR: + /* Server had an internal issue; we should retry, but this API + leaves this to the application */ + 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); diff --git a/src/lib/merchant_api_patch_instance.c b/src/lib/merchant_api_patch_instance.c index 721f8dd1..536fbdcf 100644 --- a/src/lib/merchant_api_patch_instance.c +++ b/src/lib/merchant_api_patch_instance.c @@ -110,6 +110,11 @@ handle_patch_instance_finished (void *cls, * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_FORBIDDEN: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); @@ -172,6 +177,19 @@ TALER_MERCHANT_instance_patch ( json_t *jpayto_uris; json_t *req_obj; + if (NULL != auth_token) + { + if (0 != strncasecmp (RFC_8959_PREFIX, + auth_token, + strlen (RFC_8959_PREFIX))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Authentication token must start with `%s'\n", + RFC_8959_PREFIX); + return NULL; + } + auth_token += strlen (RFC_8959_PREFIX); + } jpayto_uris = json_array (); if (NULL == jpayto_uris) { diff --git a/src/lib/merchant_api_patch_order_forget.c b/src/lib/merchant_api_patch_order_forget.c index b00361fc..ddb26062 100644 --- a/src/lib/merchant_api_patch_order_forget.c +++ b/src/lib/merchant_api_patch_order_forget.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -106,6 +106,11 @@ handle_forget_finished (void *cls, hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_patch_product.c b/src/lib/merchant_api_patch_product.c index e7d22520..f5630fc3 100644 --- a/src/lib/merchant_api_patch_product.c +++ b/src/lib/merchant_api_patch_product.c @@ -110,6 +110,11 @@ handle_patch_product_finished (void *cls, * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_FORBIDDEN: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_post_instances.c b/src/lib/merchant_api_post_instances.c index a21b9b55..a6452045 100644 --- a/src/lib/merchant_api_post_instances.c +++ b/src/lib/merchant_api_post_instances.c @@ -109,6 +109,11 @@ handle_post_instances_finished (void *cls, * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_FORBIDDEN: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); @@ -174,6 +179,19 @@ TALER_MERCHANT_instances_post ( json_t *jpayto_uris; json_t *req_obj; + if (NULL != auth_token) + { + if (0 != strncasecmp (RFC_8959_PREFIX, + auth_token, + strlen (RFC_8959_PREFIX))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Authentication token must start with `%s'\n", + RFC_8959_PREFIX); + return NULL; + } + auth_token += strlen (RFC_8959_PREFIX); + } jpayto_uris = json_array (); if (NULL == jpayto_uris) { diff --git a/src/lib/merchant_api_post_order_pay.c b/src/lib/merchant_api_post_order_pay.c index 28e9f6ed..d6b081bd 100644 --- a/src/lib/merchant_api_post_order_pay.c +++ b/src/lib/merchant_api_post_order_pay.c @@ -387,6 +387,13 @@ handle_pay_finished (void *cls, /* Exchange couldn't respond properly; the retry is left to the application */ break; + case MHD_HTTP_GATEWAY_TIMEOUT: + TALER_MERCHANT_parse_error_details_ (json, + response_code, + &hr); + /* Exchange couldn't respond in a timely fashion; + the retry is left to the application */ + break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, diff --git a/src/lib/merchant_api_post_order_refund.c b/src/lib/merchant_api_post_order_refund.c index 748fb8c1..80ad70d4 100644 --- a/src/lib/merchant_api_post_order_refund.c +++ b/src/lib/merchant_api_post_order_refund.c @@ -131,8 +131,13 @@ handle_refund_finished (void *cls, GNUNET_JSON_parse_free (spec); } break; - case MHD_HTTP_CONFLICT: + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: + case MHD_HTTP_CONFLICT: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); orh->cb (orh->cb_cls, diff --git a/src/lib/merchant_api_post_orders.c b/src/lib/merchant_api_post_orders.c index 56de86d1..44c44c9b 100644 --- a/src/lib/merchant_api_post_orders.c +++ b/src/lib/merchant_api_post_orders.c @@ -133,6 +133,11 @@ handle_post_order_finished (void *cls, the merchant is buggy (or API version conflict); just pass JSON reply to the application */ break; + case MHD_HTTP_UNAUTHORIZED: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, merchant says one of the signatures is invalid; as we checked them, diff --git a/src/lib/merchant_api_post_products.c b/src/lib/merchant_api_post_products.c index ed1d3899..7ed9755c 100644 --- a/src/lib/merchant_api_post_products.c +++ b/src/lib/merchant_api_post_products.c @@ -109,6 +109,11 @@ handle_post_products_finished (void *cls, * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_FORBIDDEN: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_post_reserves.c b/src/lib/merchant_api_post_reserves.c index 149ecaeb..8a8dee2d 100644 --- a/src/lib/merchant_api_post_reserves.c +++ b/src/lib/merchant_api_post_reserves.c @@ -130,6 +130,11 @@ handle_post_reserves_finished (void *cls, } case MHD_HTTP_ACCEPTED: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ diff --git a/src/lib/merchant_api_post_transfers.c b/src/lib/merchant_api_post_transfers.c index 14a44971..e78cb36d 100644 --- a/src/lib/merchant_api_post_transfers.c +++ b/src/lib/merchant_api_post_transfers.c @@ -190,6 +190,11 @@ handle_post_transfers_finished (void *cls, } case MHD_HTTP_ACCEPTED: break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ diff --git a/src/lib/merchant_api_tip_authorize.c b/src/lib/merchant_api_tip_authorize.c index 64aad420..d45f61a9 100644 --- a/src/lib/merchant_api_tip_authorize.c +++ b/src/lib/merchant_api_tip_authorize.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2017, 2020 Taler Systems SA + Copyright (C) 2014-2017, 2020, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -161,6 +161,11 @@ handle_tip_authorize_finished (void *cls, hr.http_status = 0; hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; + case MHD_HTTP_UNAUTHORIZED: + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + /* Nothing really to verify, merchant says we need to authenticate. */ + break; case MHD_HTTP_NOT_FOUND: /* Well-defined status code, pass on to application! */ hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index 9a69f121..b1932cd6 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -1251,6 +1251,41 @@ run (void *cls, PAYTO_I1, "USD", MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_merchant_post_instances2 ("instance-create-ACL", + merchant_url, + "i-acl", + 0, NULL, + "controlled instance", + json_pack ("{s:s}", "city", + "shopcity"), + json_pack ("{s:s}", "city", + "lawyercity"), + "EUR:0.1", + 42, + "EUR:0.2", + GNUNET_TIME_UNIT_MINUTES, + GNUNET_TIME_UNIT_MINUTES, + RFC_8959_PREFIX "EXAMPLE", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_patch_instance ("instance-patch-ACL", + merchant_url, + "i-acl", + 1, + payto_uris, + "controlled instance", + json_pack ("{s:s}", + "street", + "bobstreet"), + json_pack ("{s:s}", + "street", + "bobjuryst"), + "EUR:0.1", + 4, + "EUR:0.5", + GNUNET_TIME_UNIT_MINUTES, + GNUNET_TIME_UNIT_MINUTES, + RFC_8959_PREFIX "SANDBOX", + MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_instances ("instance-create-i2", merchant_url, "i2", diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c index 2248c1ac..2cbd0e5b 100644 --- a/src/testing/testing_api_cmd_patch_instance.c +++ b/src/testing/testing_api_cmd_patch_instance.c @@ -142,12 +142,13 @@ patch_instance_cb (void *cls, } switch (hr->http_status) { - case MHD_HTTP_OK: + case MHD_HTTP_NO_CONTENT: break; // FIXME: add other legitimate states here... default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); + "Unhandled HTTP status %u.\n", + hr->http_status); } TALER_TESTING_interpreter_next (pis->is); } diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c index acd623b6..7eb2e7fa 100644 --- a/src/testing/testing_api_cmd_post_instances.c +++ b/src/testing/testing_api_cmd_post_instances.c @@ -150,7 +150,8 @@ post_instances_cb (void *cls, default: GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); + "Unhandled HTTP status %u.\n", + hr->http_status); } TALER_TESTING_interpreter_next (pis->is); } @@ -188,7 +189,12 @@ post_instances_run (void *cls, pis->auth_token, &post_instances_cb, pis); - GNUNET_assert (NULL != pis->iph); + if (NULL == pis->iph) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pis->is); + return; + } } |