summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-16 08:42:36 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-16 08:42:36 +0200
commite9e57dcf55cf931020ddefe5e08995fe68f660b5 (patch)
treeb3b5443553427d81329e4d43ff2f6988d37567a4 /src
parent09e315eedb73adc9fa7d11061728cd433bee9f31 (diff)
downloadexchange-e9e57dcf55cf931020ddefe5e08995fe68f660b5.tar.gz
exchange-e9e57dcf55cf931020ddefe5e08995fe68f660b5.tar.bz2
exchange-e9e57dcf55cf931020ddefe5e08995fe68f660b5.zip
allow x-taler-bank with paht (fixes #8739)
Diffstat (limited to 'src')
-rw-r--r--src/util/Makefile.am2
-rw-r--r--src/util/payto.c72
-rw-r--r--src/util/test_payto.c39
3 files changed, 84 insertions, 29 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index ed3f382d3..d2504588b 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -120,7 +120,7 @@ libtalerutil_la_LIBADD = \
-lm
libtalerutil_la_LDFLAGS = \
- -version-info 3:2:2 \
+ -version-info 3:3:2 \
-no-undefined
diff --git a/src/util/payto.c b/src/util/payto.c
index 5e0391883..6092b73fd 100644
--- a/src/util/payto.c
+++ b/src/util/payto.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2019-2022 Taler Systems SA
+ Copyright (C) 2019-2024 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 published by the Free Software
@@ -101,7 +101,9 @@ TALER_payto_get_method (const char *payto_uri)
char *
TALER_xtalerbank_account_from_payto (const char *payto)
{
+ const char *host;
const char *beg;
+ const char *nxt;
const char *end;
if (0 != strncasecmp (payto,
@@ -111,23 +113,27 @@ TALER_xtalerbank_account_from_payto (const char *payto)
GNUNET_break_op (0);
return NULL;
}
- beg = strchr (&payto[strlen (PAYTO "x-taler-bank/")],
+ host = &payto[strlen (PAYTO "x-taler-bank/")];
+ beg = strchr (host,
'/');
if (NULL == beg)
{
GNUNET_break_op (0);
return NULL;
}
- beg++; /* now points to $ACCOUNT */
+ beg++; /* now points to $ACCOUNT or $PATH */
+ nxt = strchr (beg,
+ '/');
end = strchr (beg,
'?');
if (NULL == end)
+ end = &beg[strlen (beg)];
+ while ( (NULL != nxt) &&
+ (end - nxt > 0) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid payto URI `%s'\n",
- payto);
- GNUNET_break_op (0);
- return GNUNET_strdup (beg); /* optional part is missing */
+ beg = nxt + 1;
+ nxt = strchr (beg,
+ '/');
}
return GNUNET_strndup (beg,
end - beg);
@@ -200,36 +206,63 @@ static char *
validate_payto_xtalerbank (const char *account_url)
{
const char *user;
+ const char *nxt;
+ const char *beg;
+ const char *end;
const char *host;
bool dot_ok;
bool post_colon;
+ bool port_ok;
-#define XTALERBANK_PREFIX "payto://x-taler-bank/"
+#define XTALERBANK_PREFIX PAYTO "x-taler-bank/"
if (0 != strncasecmp (account_url,
XTALERBANK_PREFIX,
strlen (XTALERBANK_PREFIX)))
return NULL; /* not an IBAN */
host = &account_url[strlen (XTALERBANK_PREFIX)];
#undef XTALERBANK_PREFIX
- user = strchr (host, '/');
- if (NULL == user)
+ beg = strchr (host,
+ '/');
+ if (NULL == beg)
{
return GNUNET_strdup ("account name missing");
}
- if (user == host)
+ beg++; /* now points to $ACCOUNT or $PATH */
+ nxt = strchr (beg,
+ '/');
+ end = strchr (beg,
+ '?');
+ if (NULL == end)
+ {
+ return GNUNET_strdup ("'receiver-name' parameter missing");
+ }
+ while ( (NULL != nxt) &&
+ (end - nxt > 0) )
+ {
+ beg = nxt + 1;
+ nxt = strchr (beg,
+ '/');
+ }
+ user = beg;
+ if (user == host + 1)
{
return GNUNET_strdup ("domain name missing");
}
if ('-' == host[0])
return GNUNET_strdup ("invalid character '-' at start of domain name");
- if (NULL != strchr (user + 1, '/'))
- return GNUNET_strdup ("invalid character '/' after account name");
dot_ok = false;
post_colon = false;
+ port_ok = false;
while (host != user)
{
char c = host[0];
+ if ('/' == c)
+ {
+ /* path started, do not care about characters
+ in the path */
+ break;
+ }
if (':' == c)
{
post_colon = true;
@@ -247,6 +280,7 @@ validate_payto_xtalerbank (const char *account_url)
c);
return err;
}
+ port_ok = true;
}
else
{
@@ -275,6 +309,10 @@ validate_payto_xtalerbank (const char *account_url)
}
host++;
}
+ if (post_colon && (! port_ok) )
+ {
+ return GNUNET_strdup ("port missing after ':'");
+ }
{
char *target;
@@ -304,7 +342,7 @@ TALER_payto_validate (const char *payto_uri)
/* This is more strict than RFC 8905, alas we do not need to support messages/instructions/etc.,
and it is generally better to start with a narrow whitelist; we can be more permissive later ...*/
#define ALLOWED_CHARACTERS \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/:&?-.,=+%"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/:&?-.,=+%~"
if (NULL == strchr (ALLOWED_CHARACTERS,
(int) payto_uri[i]))
{
@@ -358,10 +396,10 @@ TALER_payto_get_receiver_name (const char *payto)
/**
- * Normalize "payto://x-taler-bank/$HOSTNAME/$USERNAME"
+ * Normalize "payto://x-taler-bank/$HOSTNAME/[$PATH/]$USERNAME"
* URI in @a input.
*
- * Converts to lower-case, except for $USERNAME which
+ * Converts to lower-case, except for [$PATH/]$USERNAME which
* is case-sensitive.
*
* @param len number of bytes in @a input
diff --git a/src/util/test_payto.c b/src/util/test_payto.c
index b37a6f721..62ba7d28e 100644
--- a/src/util/test_payto.c
+++ b/src/util/test_payto.c
@@ -22,16 +22,16 @@
#include "taler_util.h"
#define CHECK(a,b) do { \
- GNUNET_assert (a != NULL); \
- GNUNET_assert (b != NULL); \
- if (0 != strcmp (a,b)) { \
- GNUNET_break (0); \
- fprintf (stderr, "Got %s, wanted %s\n", b, a); \
- GNUNET_free (b); \
- return 1; \
- } else { \
- GNUNET_free (b); \
- } \
+ GNUNET_assert (a != NULL); \
+ GNUNET_assert (b != NULL); \
+ if (0 != strcmp (a,b)) { \
+ GNUNET_break (0); \
+ fprintf (stderr, "Got %s, wanted %s\n", b, a); \
+ GNUNET_free (b); \
+ return 1; \
+ } else { \
+ GNUNET_free (b); \
+ } \
} while (0)
@@ -54,11 +54,20 @@ main (int argc,
"payto://x-taler-bank/hostname/username?receiver-name=foo");
GNUNET_assert (NULL == r);
r = TALER_payto_validate (
+ "payto://x-taler-bank/hostname/~path/username?receiver-name=foo");
+ GNUNET_assert (NULL == r);
+ r = TALER_payto_validate (
+ "payto://x-taler-bank/hostname/~path/username?receiver-name=fo/o");
+ GNUNET_assert (NULL == r);
+ r = TALER_payto_validate (
+ "payto://x-taler-bank/hostname/path/username?receiver-name=foo");
+ GNUNET_assert (NULL == r);
+ r = TALER_payto_validate (
"payto://x-taler-bank/https://hostname/username?receiver-name=foo");
GNUNET_assert (NULL != r);
GNUNET_free (r);
r = TALER_payto_validate (
- "payto://x-taler-bank/hostname/username/extra?receiver-name=foo");
+ "payto://x-taler-bank/hostname:4a2/path/username?receiver-name=foo");
GNUNET_assert (NULL != r);
GNUNET_free (r);
r = TALER_payto_validate (
@@ -82,6 +91,14 @@ main (int argc,
CHECK ("alice",
r);
r = TALER_xtalerbank_account_from_payto (
+ "payto://x-taler-bank/localhost:1080/path/alice");
+ CHECK ("alice",
+ r);
+ r = TALER_xtalerbank_account_from_payto (
+ "payto://x-taler-bank/localhost:1080/path/alice?receiver-name=ali/cia");
+ CHECK ("alice",
+ r);
+ r = TALER_xtalerbank_account_from_payto (
"payto://x-taler-bank/localhost:1080/alice?subject=hello&amount=EUR:1");
CHECK ("alice",
r);