commit 2be1f98af702ec9781932cc3cf84f76346244cb4
parent db1e89f7e64e74bea1a91a0570fea4f4a655e035
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 13 Nov 2025 17:55:21 +0100
improve logging for #10604
Diffstat:
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),