merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 2be1f98af702ec9781932cc3cf84f76346244cb4
parent db1e89f7e64e74bea1a91a0570fea4f4a655e035
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 13 Nov 2025 17:55:21 +0100

improve logging for #10604

Diffstat:
Msrc/backend/taler-merchant-httpd.c | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/backend/taler-merchant-httpd_private-get-token-families.c | 1+
2 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -311,6 +311,9 @@ get_scope_permissions (enum TMH_AuthScope as, (scope_permissions[i].as & ~TMH_AS_REFRESHABLE) ) return scope_permissions[i].permissions; } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to find required permissions for scope %d\n", + as); return NULL; } @@ -338,6 +341,9 @@ permission_in_scope (const char *permission_required, &refreshable); if (NULL == perms_tmp) { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Permission check failed: scope %d not understood\n", + (int) scope); return false; } last_dash = strrchr (permission_required, @@ -352,7 +358,14 @@ permission_in_scope (const char *permission_required, if (0 == strcmp ("token-refresh", permission_required)) + { + if (! refreshable) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Permission check failed: token not refreshable\n"); + } return refreshable; + } permissions = GNUNET_strdup (perms_tmp); { const char *perm = strtok (permissions, @@ -361,6 +374,8 @@ permission_in_scope (const char *permission_required, if (NULL == perm) { GNUNET_free (permissions); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Permission check failed: empty permission set\n"); return false; } while (NULL != perm) @@ -395,6 +410,10 @@ permission_in_scope (const char *permission_required, ","); } } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Permission check failed: %s not found in %s\n", + permission_required, + permissions); GNUNET_free (permissions); return false; } @@ -460,12 +479,16 @@ TMH_get_scope_by_name (const char *name) name)) return scope_permissions[i].as; } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Name `%s' does not match any scope we understand\n", + name); return TMH_AS_NONE; } const char* -TMH_get_name_by_scope (enum TMH_AuthScope scope, bool *refreshable) +TMH_get_name_by_scope (enum TMH_AuthScope scope, + bool *refreshable) { *refreshable = scope & TMH_AS_REFRESHABLE; for (unsigned int i = 0; TMH_AS_NONE != scope_permissions[i].as; i++) @@ -475,6 +498,9 @@ TMH_get_name_by_scope (enum TMH_AuthScope scope, bool *refreshable) (scope_permissions[i].as & ~TMH_AS_REFRESHABLE) ) return scope_permissions[i].name; } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Scope #%d does not match any scope we understand\n", + (int) scope); return NULL; } @@ -489,18 +515,26 @@ TMH_check_auth (const char *password, if (GNUNET_is_zero (hash)) return GNUNET_OK; if (NULL == password) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Denying access: empty password provided\n"); return GNUNET_SYSERR; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking against token with salt %s\n", TALER_B2S (salt)); TALER_merchant_instance_auth_hash_with_salt (&val, salt, password); - return (0 == - GNUNET_memcmp (&val, - hash)) - ? GNUNET_OK - : GNUNET_SYSERR; + if (0 != + GNUNET_memcmp (&val, + hash)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Access denied: password does not match\n"); + return GNUNET_SYSERR; + } + return GNUNET_OK; } @@ -526,18 +560,23 @@ check_auth_instance (const char *userpass, if (GNUNET_is_zero (&instance->auth.auth_hash)) return GNUNET_OK; if (NULL == userpass) + { + GNUNET_break_op (0); return GNUNET_SYSERR; + } if (0 == GNUNET_STRINGS_base64_decode (userpass, strlen (userpass), (void**) &tmp)) { + GNUNET_break_op (0); return GNUNET_SYSERR; } colon = strchr (tmp, ':'); if (NULL == colon) { + GNUNET_break_op (0); GNUNET_free (tmp); return GNUNET_SYSERR; } @@ -550,7 +589,7 @@ check_auth_instance (const char *userpass, if (0 != strcmp (instance_name, target_instance)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Somebody tried to login to instance %s with username %s (login failed).\n", target_instance, instance_name); @@ -561,6 +600,12 @@ check_auth_instance (const char *userpass, &instance->auth.auth_salt, &instance->auth.auth_hash); GNUNET_free (tmp); + if (GNUNET_OK != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Password provided does not match credentials for %s\n", + target_instance); + } return ret; } @@ -1087,7 +1132,7 @@ process_basic_auth (struct TMH_HandlerContext *hc, } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Basic authentication failed!\n"); hc->auth_scope = TMH_AS_NONE; } @@ -1137,6 +1182,9 @@ process_bearer_auth (struct TMH_HandlerContext *hc, { GNUNET_break_op (0); hc->auth_scope = TMH_AS_NONE; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Authentication token invalid: %d\n", + (int) ec); return ec; } GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -2441,9 +2489,14 @@ url_handler (void *cls, else /* Check bearer token */ { enum TALER_ErrorCode ec; - ec = process_bearer_auth (hc, auth); + + ec = process_bearer_auth (hc, + auth); if (TALER_EC_NONE != ec) { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Bearer authentication failed: %d\n", + (int) ec); return TALER_MHD_reply_with_ec (connection, ec, NULL); @@ -2469,6 +2522,10 @@ url_handler (void *cls, "'" RFC_8959_PREFIX "' prefix or 'Bearer' missing in 'Authorization' header"); } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Credentials provided are %d which are insufficient for access to `%s'\n", + (int) hc->auth_scope, + hc->rh->permission); return TALER_MHD_reply_with_error (connection, MHD_HTTP_UNAUTHORIZED, TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, diff --git a/src/backend/taler-merchant-httpd_private-get-token-families.c b/src/backend/taler-merchant-httpd_private-get-token-families.c @@ -56,6 +56,7 @@ add_token_family (void *cls, description), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("description_i18n", + (json_t *) description_i18n)), GNUNET_JSON_pack_timestamp ("valid_after", valid_after),