commit d8d009521d384a78b9889e18bb470f9281b5e8f1
parent 836da1b8cc42ef9d076200686da0aa0be9a8ba67
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 22 Jul 2026 03:01:52 +0200
challengerdb: rename functions to match new naming conventions
Diffstat:
71 files changed, 2261 insertions(+), 2106 deletions(-)
diff --git a/contrib/check-db-naming.py b/contrib/check-db-naming.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python3
+"""Enforce the database layer naming convention.
+
+Rules checked:
+
+ 1. every public function's name starts with the name of the file it lives in
+ 2. the file's own name uses a prefix from the closed set, or is exempt
+ 3. iterate_ iff the function takes a caller-supplied callback; get_ iff not
+ 4. a .h exists beside every .c, and every .sql that is not schema or
+ boilerplate is named after the .c that runs it
+ 5. every prepared statement is named after the function preparing it
+ 6. no prepared statement name is used in two files
+ 7. no numeric suffixes and no repeated library prefix
+
+Run from the top of the source tree; exits non-zero on any violation.
+"""
+import re
+import sys
+import pathlib
+
+# ---------------------------------------------------------------- CONFIG --
+# (impl dir, header dir, symbol prefix, .c basename prefix)
+LAYERS = [
+ ("src/challengerdb", "src/include/challenger-database", "CHALLENGERDB_",
+ ""),
+]
+
+# Prefixes that describe what the caller gets.
+PREFIXES = ("get_", "get_count_", "get_exists_", "iterate_",
+ "insert_", "update_", "update_to_", "delete_", "do_")
+
+# Not CRUD: DDL and maintenance. Keep this list short and justified -- every
+# entry is a rule the checker stops enforcing. Connection handling
+# (CHALLENGERDB_connect/_connect_admin/_disconnect) lives in pg.c, which is
+# skipped below, and challenger has no explicit transaction control.
+EXEMPT = {
+ "create_tables", "drop_tables", "gc", "preflight",
+}
+
+# Files that are not part of the API surface at all: the connection handling,
+# the shared PREPARE macro, the copy-me template, and the dbinit binary.
+SKIP = {"pg", "pg_helper", "template", "challenger-dbinit"}
+
+# SQL that belongs to the schema rather than to one API function.
+SQL_NOT_A_FUNCTION = {"versioning", "drop", "commit", "procedures-prelude"}
+SQL_SCHEMA_RE = re.compile(r"^challenger-\d+$")
+# ------------------------------------------------------------ END CONFIG --
+
+PREP = re.compile(r'PREPARE\s*\(\s*\w+\s*,\s*"([A-Za-z0-9_]+)"', re.S)
+
+errors = []
+
+
+def check_layer(impl_dir, hdr_dir, prefix, fpfx):
+ impl, hdr = pathlib.Path(impl_dir), pathlib.Path(hdr_dir)
+ if not impl.is_dir():
+ return
+ decl = re.compile(r"^" + re.escape(prefix) + r"(\w+)\s*\((.*?)\)\s*;",
+ re.S | re.M)
+ stmt_owner = {}
+ stems = set()
+
+ for c in sorted(impl.glob("*.c")):
+ if c.stem in SKIP or c.stem.startswith("test_") \
+ or c.stem.startswith("plugin_"):
+ continue
+ if fpfx and not c.stem.startswith(fpfx):
+ continue
+ stem = c.stem[len(fpfx):] if fpfx else c.stem
+ stems.add(stem)
+
+ # 2. prefix from the closed set, or exempt
+ if stem not in EXEMPT and not stem.startswith(PREFIXES):
+ errors.append(f"{c}: '{stem}' uses no approved prefix")
+
+ # 7. numeric suffix
+ if re.search(r"\d$", stem):
+ errors.append(f"{c}: '{stem}' ends in a digit")
+
+ # 4. matching header
+ h = hdr / (stem + ".h")
+ if stem not in EXEMPT and not h.exists():
+ errors.append(f"{c}: no matching header {h}")
+
+ text = c.read_text(errors="replace")
+
+ # 5. prepared statements named after the function
+ for s in dict.fromkeys(PREP.findall(text)):
+ if s != stem and not s.startswith(stem + "_"):
+ errors.append(
+ f"{c}: prepared statement '{s}' is not named after "
+ f"'{stem}'")
+ # 6. cross-file uniqueness
+ if s in stmt_owner and stmt_owner[s] != str(c):
+ errors.append(
+ f"{c}: prepared statement '{s}' also prepared in "
+ f"{stmt_owner[s]}")
+ stmt_owner[s] = str(c)
+
+ if not h.exists():
+ continue
+ htext = re.sub(r"/\*.*?\*/", "", h.read_text(errors="replace"),
+ flags=re.S)
+ for name, params in decl.findall(htext):
+ # 1. declared names belong to their file. Exempt entries are the
+ # documented multi-function modules, so this does not apply there.
+ if (stem not in EXEMPT
+ and name != stem and not name.startswith(stem + "_")):
+ errors.append(
+ f"{h}: declares '{name}', which does not belong to "
+ f"'{stem}'")
+ # 3. iterate_ iff callback
+ has_cb = bool(re.search(r"\w*(Callback|Iterator)\s+\w+", params))
+ if name.startswith("iterate_") and not has_cb:
+ errors.append(
+ f"{h}: '{name}' is iterate_ but takes no callback")
+ if name.startswith("get_") and has_cb:
+ errors.append(f"{h}: '{name}' takes a callback; use iterate_")
+
+ # 4. an amalgamated .sql is named after the .c that runs it, so that a
+ # renamed function cannot leave its stored procedure behind.
+ for s in sorted(impl.glob("*.sql")):
+ if s.stem in SQL_NOT_A_FUNCTION or SQL_SCHEMA_RE.match(s.stem):
+ continue
+ if s.stem not in stems:
+ errors.append(f"{s}: no {impl}/{s.stem}.c runs this SQL")
+
+ # 7. repeated library prefix anywhere in the tree
+ head = prefix.split("_")[0]
+ for f in list(impl.glob("*.[ch]")) + list(hdr.glob("*.h")):
+ if "unc-backup" in f.name:
+ continue
+ if re.search(r"\b" + re.escape(head) + r"_" + re.escape(prefix),
+ f.read_text(errors="replace")):
+ errors.append(f"{f}: repeated '{prefix}' prefix")
+
+
+for a in LAYERS:
+ check_layer(*a)
+
+for e in errors:
+ print("ERROR:", e)
+print(f"\ndb-naming: {len(errors)} violation(s)")
+sys.exit(1 if errors else 0)
diff --git a/contrib/ci/jobs/6-db-naming/job.sh b/contrib/ci/jobs/6-db-naming/job.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+set -exuo pipefail
+
+exec ./contrib/check-db-naming.py
diff --git a/meson.build b/meson.build
@@ -221,7 +221,7 @@ if not get_option('only-doc')
libltversions = [
['libchallengerutil', '0:1:0'],
- ['libchallengerdb', '0:1:0'],
+ ['libchallengerdb', '1:0:0'],
]
solibversions = {}
diff --git a/src/challenger/challenger-admin.c b/src/challenger/challenger-admin.c
@@ -23,10 +23,10 @@
#include <gnunet/gnunet_db_lib.h>
#include "challenger_util.h"
#include "challenger_database_lib.h"
-#include "challenger-database/client_delete.h"
-#include "challenger-database/client_check.h"
-#include "challenger-database/client_modify.h"
-#include "challenger-database/client_add.h"
+#include "challenger-database/delete_client.h"
+#include "challenger-database/get_client_by_uri.h"
+#include "challenger-database/update_client.h"
+#include "challenger-database/insert_client.h"
#include "challenger-database/preflight.h"
@@ -121,7 +121,7 @@ run (void *cls,
global_ret = EXIT_INVALIDARGUMENT;
goto cleanup;
}
- qs = CHALLENGERDB_client_delete (db,
+ qs = CHALLENGERDB_delete_client (db,
redirect_uri);
switch (qs)
{
@@ -177,7 +177,7 @@ run (void *cls,
goto cleanup;
}
- qs = CHALLENGERDB_client_modify (db,
+ qs = CHALLENGERDB_update_client (db,
row_id,
redirect_uri,
client_secret);
@@ -207,10 +207,10 @@ run (void *cls,
enum GNUNET_DB_QueryStatus qs;
uint64_t row_id;
- qs = CHALLENGERDB_client_check2 (db,
- redirect_uri,
- client_secret,
- &row_id);
+ qs = CHALLENGERDB_get_client_by_uri (db,
+ redirect_uri,
+ client_secret,
+ &row_id);
switch (qs)
{
case GNUNET_DB_STATUS_SOFT_ERROR:
@@ -231,10 +231,10 @@ run (void *cls,
(unsigned long long) row_id);
goto cleanup;
}
- qs = CHALLENGERDB_client_add (db,
- redirect_uri,
- client_secret,
- &row_id);
+ qs = CHALLENGERDB_insert_client (db,
+ redirect_uri,
+ client_secret,
+ &row_id);
switch (qs)
{
case GNUNET_DB_STATUS_SOFT_ERROR:
diff --git a/src/challenger/challenger-httpd_authorize.c b/src/challenger/challenger-httpd_authorize.c
@@ -26,7 +26,7 @@
#include "challenger-httpd_authorize.h"
#include "challenger-httpd_common.h"
#include "challenger-httpd_spa.h"
-#include "challenger-database/authorize_start.h"
+#include "challenger-database/update_validation.h"
#include "challenger_cm_enums.h"
/**
@@ -215,24 +215,25 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
bool solved;
enum GNUNET_DB_QueryStatus qs;
- /* authorize_start will return 0 if a 'redirect_uri' was
+ /* update_validation will return 0 if a 'redirect_uri' was
configured for the client and this one differs. */
for (unsigned int r = 0; r<MAX_RETRIES; r++)
{
- qs = CHALLENGERDB_authorize_start (CH_context,
- &nonce,
- client_id,
- scope,
- state,
- redirect_uri,
- code_challenge,
- (uint32_t) code_challenge_method_enum,
- &last_address,
- &address_attempts_left,
- &pin_transmissions_left,
- &auth_attempts_left,
- &solved,
- &last_tx_time);
+ qs = CHALLENGERDB_update_validation (CH_context,
+ &nonce,
+ client_id,
+ scope,
+ state,
+ redirect_uri,
+ code_challenge,
+ (uint32_t) code_challenge_method_enum
+ ,
+ &last_address,
+ &address_attempts_left,
+ &pin_transmissions_left,
+ &auth_attempts_left,
+ &solved,
+ &last_tx_time);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -241,7 +242,7 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
hc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "authorize_start");
+ "update_validation");
case GNUNET_DB_STATUS_SOFT_ERROR:
if (r < MAX_RETRIES - 1)
continue;
@@ -250,7 +251,7 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
hc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "authorize_start");
+ "update_validation");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
diff --git a/src/challenger/challenger-httpd_challenge.c b/src/challenger/challenger-httpd_challenge.c
@@ -28,8 +28,8 @@
#include <taler/taler_mhd_lib.h>
#include <taler/taler_templating_lib.h>
#include <taler/taler_signatures.h>
-#include "challenger-database/challenge_set_address_and_pin.h"
-#include "challenger-database/address_get.h"
+#include "challenger-database/do_challenge_address.h"
+#include "challenger-database/get_validation_address.h"
#include "challenger-httpd_common.h"
/**
@@ -860,9 +860,9 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
json_t *ro;
GNUNET_assert (NULL == bc->client_redirect_uri);
- qs = CHALLENGERDB_address_get (CH_context,
- &bc->nonce,
- &old_address);
+ qs = CHALLENGERDB_get_validation_address (CH_context,
+ &bc->nonce,
+ &old_address);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -870,7 +870,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
return reply_error (bc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validation-get");
+ "get_validation_address");
case GNUNET_DB_STATUS_SOFT_ERROR:
if (r < MAX_RETRIES - 1)
continue;
@@ -878,7 +878,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
return reply_error (bc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validation-get");
+ "get_validation_address");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_break_op (0);
return reply_error (bc,
@@ -909,18 +909,18 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
"read_only",
ro));
- qs = CHALLENGERDB_challenge_set_address_and_pin (CH_context,
- &bc->nonce,
- bc->address,
- CH_pin_retransmission_frequency,
- &bc->tan,
- &bc->state,
- &bc->last_tx_time,
- &bc->pin_attempts_left,
- &bc->retransmit,
- &bc->client_redirect_uri,
- &bc->address_refused,
- &bc->solved);
+ qs = CHALLENGERDB_do_challenge_address (CH_context,
+ &bc->nonce,
+ bc->address,
+ CH_pin_retransmission_frequency,
+ &bc->tan,
+ &bc->state,
+ &bc->last_tx_time,
+ &bc->pin_attempts_left,
+ &bc->retransmit,
+ &bc->client_redirect_uri,
+ &bc->address_refused,
+ &bc->solved);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -928,7 +928,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
return reply_error (bc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "set-address-and-pin");
+ "do_challenge_address");
case GNUNET_DB_STATUS_SOFT_ERROR:
if (r < MAX_RETRIES - 1)
continue;
@@ -936,7 +936,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
return reply_error (bc,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "set-address-and-pin");
+ "do_challenge_address");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_break_op (0);
return reply_error (bc,
diff --git a/src/challenger/challenger-httpd_common.c b/src/challenger/challenger-httpd_common.c
@@ -21,7 +21,7 @@
#include "platform.h"
#include "challenger-httpd_common.h"
#include <gnunet/gnunet_pq_lib.h>
-#include "challenger-database/validation_get.h"
+#include "challenger-database/get_validation.h"
/**
@@ -208,7 +208,7 @@ CH_build_full_redirect_url (
enum GNUNET_DB_QueryStatus qs;
enum MHD_Result ret;
- qs = CHALLENGERDB_validation_get (CH_context,
+ qs = CHALLENGERDB_get_validation (CH_context,
nonce,
&client_secret,
&address,
@@ -224,7 +224,7 @@ CH_build_full_redirect_url (
connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validation_get");
+ "get_validation");
return (MHD_NO == ret) ? GNUNET_SYSERR : GNUNET_NO;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_break (0);
diff --git a/src/challenger/challenger-httpd_info.c b/src/challenger/challenger-httpd_info.c
@@ -24,7 +24,7 @@
#include <gnunet/gnunet_db_lib.h>
#include "challenger-httpd_common.h"
#include "challenger-httpd_info.h"
-#include "challenger-database/info_get_token.h"
+#include "challenger-database/get_token.h"
/**
@@ -94,11 +94,11 @@ CH_handler_info (struct CH_HandlerContext *hc,
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Timestamp address_expiration;
- qs = CHALLENGERDB_info_get_token (CH_context,
- &grant,
- &id,
- &address,
- &address_expiration);
+ qs = CHALLENGERDB_get_token (CH_context,
+ &grant,
+ &id,
+ &address,
+ &address_expiration);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -106,7 +106,7 @@ CH_handler_info (struct CH_HandlerContext *hc,
return TALER_MHD_reply_with_error (hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "info_get_token");
+ "get_token");
case GNUNET_DB_STATUS_SOFT_ERROR:
if (r < MAX_RETRIES - 1)
continue;
@@ -114,12 +114,12 @@ CH_handler_info (struct CH_HandlerContext *hc,
return TALER_MHD_reply_with_error (hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "info_get_token");
+ "get_token");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
return TALER_MHD_reply_with_error (hc->connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_CHALLENGER_GRANT_UNKNOWN,
- "info_get_token");
+ "get_token");
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
break;
}
diff --git a/src/challenger/challenger-httpd_setup.c b/src/challenger/challenger-httpd_setup.c
@@ -24,16 +24,10 @@
#include <gnunet/gnunet_db_lib.h>
#include "challenger-httpd_setup.h"
#include "challenger-httpd_common.h"
-#include "challenger-database/setup_nonce.h"
-#include "challenger-database/client_check.h"
+#include "challenger-database/do_insert_validation.h"
/**
- * Maximum number of retries for the database interaction.
- */
-#define MAX_RETRIES 3
-
-/**
* Set to 1 to dump addresses into the log.
*/
#define DEBUG 0
@@ -175,50 +169,6 @@ CH_handler_setup (struct CH_HandlerContext *hc,
"read_only");
}
}
- /* FIXME: the two transactions below should be folded
- into a single transaction (both to only increment
- the validation counter on success and for performance). */
- for (unsigned int r = 0; r<MAX_RETRIES; r++)
- {
- enum GNUNET_DB_QueryStatus qs;
- char *client_url = NULL;
-
- qs = CHALLENGERDB_client_check (CH_context,
- (uint64_t) client_id,
- client_secret,
- 1,
- &client_url);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (
- hc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "client_check");
- case GNUNET_DB_STATUS_SOFT_ERROR:
- if (r < MAX_RETRIES - 1)
- continue;
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (
- hc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "client_check");
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- return TALER_MHD_reply_with_error (
- hc->connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN,
- NULL);
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break;
- }
- GNUNET_free (client_url);
- break;
- }
-
{
struct CHALLENGER_ValidationNonceP nonce;
struct GNUNET_TIME_Absolute expiration_time;
@@ -227,11 +177,15 @@ CH_handler_setup (struct CH_HandlerContext *hc,
expiration_time = GNUNET_TIME_relative_to_absolute (CH_validation_duration);
GNUNET_CRYPTO_random_block (&nonce,
sizeof (nonce));
- qs = CHALLENGERDB_setup_nonce (CH_context,
- client_id,
- &nonce,
- expiration_time,
- sc->root);
+ /* Authenticating the client, charging it for the validation and
+ creating the validation row all happen in this one statement, so
+ the validation counter only moves if the setup really succeeded. */
+ qs = CHALLENGERDB_do_insert_validation (CH_context,
+ client_id,
+ client_secret,
+ &nonce,
+ expiration_time,
+ sc->root);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -241,14 +195,14 @@ CH_handler_setup (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "setup_nonce");
+ "do_insert_validation");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0);
+ /* Nothing was inserted, so the client did not authenticate. */
return TALER_MHD_reply_with_error (
hc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- "no results from setup_nonce");
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN,
+ NULL);
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
break;
}
diff --git a/src/challenger/challenger-httpd_solve.c b/src/challenger/challenger-httpd_solve.c
@@ -27,8 +27,8 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_templating_lib.h>
#include <taler/taler_signatures.h>
-#include "challenger-database/validation_get.h"
-#include "challenger-database/validate_solve_pin.h"
+#include "challenger-database/get_validation.h"
+#include "challenger-database/do_solve_challenge.h"
/**
@@ -279,7 +279,7 @@ CH_handler_solve (struct CH_HandlerContext *hc,
for (unsigned int r = 0; r<MAX_RETRIES; r++)
{
- qs = CHALLENGERDB_validate_solve_pin (CH_context,
+ qs = CHALLENGERDB_do_solve_challenge (CH_context,
&bc->nonce,
pin,
&solved,
@@ -298,7 +298,7 @@ CH_handler_solve (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validate_solve_pin");
+ "do_solve_challenge");
case GNUNET_DB_STATUS_SOFT_ERROR:
if (r < MAX_RETRIES - 1)
continue;
@@ -307,7 +307,7 @@ CH_handler_solve (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validate_solve_pin");
+ "do_solve_challenge");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
return TALER_MHD_reply_with_error (
hc->connection,
diff --git a/src/challenger/challenger-httpd_token.c b/src/challenger/challenger-httpd_token.c
@@ -27,9 +27,9 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_signatures.h>
#include "challenger_cm_enums.h"
-#include "challenger-database/validation_get_pkce.h"
-#include "challenger-database/client_check.h"
-#include "challenger-database/token_add_token.h"
+#include "challenger-database/get_validation_pkce.h"
+#include "challenger-database/get_client.h"
+#include "challenger-database/do_insert_token.h"
#define MAX_RETRIES 3
@@ -357,11 +357,10 @@ CH_handler_token (struct CH_HandlerContext *hc,
for (unsigned int r = 0; r < MAX_RETRIES; r++)
{
- qs = CHALLENGERDB_client_check (CH_context,
- client_id,
- bc->client_secret,
- 0, /* do not increment */
- &client_url);
+ qs = CHALLENGERDB_get_client (CH_context,
+ client_id,
+ bc->client_secret,
+ &client_url);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
@@ -370,7 +369,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "client_check");
+ "get_client");
case GNUNET_DB_STATUS_SOFT_ERROR:
continue;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
@@ -393,7 +392,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_SOFT_FAILURE,
- "client_check");
+ "get_client");
}
if ( (NULL != client_url) &&
(0 != strcmp (client_url,
@@ -447,7 +446,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
&code_dummy));
for (unsigned int r = 0; r < MAX_RETRIES; r++)
{
- qs = CHALLENGERDB_validation_get_pkce (CH_context,
+ qs = CHALLENGERDB_get_validation_pkce (CH_context,
&bc->nonce,
(uint64_t) code_client_id,
&client_secret,
@@ -465,7 +464,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "validation_get_pkce");
+ "get_validation_pkce");
case GNUNET_DB_STATUS_SOFT_ERROR:
continue;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
@@ -475,7 +474,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
MHD_HTTP_BAD_REQUEST,
"invalid_grant",
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
- "validation_get_pkce");
+ "get_validation_pkce");
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
break;
}
@@ -488,7 +487,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_SOFT_FAILURE,
- "validation_get_pkce");
+ "get_validation_pkce");
}
code_challenge_method_enum = CHALLENGER_cm_from_int (
@@ -746,7 +745,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
sizeof (token));
for (unsigned int r = 0; r < MAX_RETRIES; r++)
{
- qs = CHALLENGERDB_token_add_token (CH_context,
+ qs = CHALLENGERDB_do_insert_token (CH_context,
&bc->nonce,
&token,
CH_token_expiration,
@@ -759,7 +758,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- "token_add_token");
+ "do_insert_token");
case GNUNET_DB_STATUS_SOFT_ERROR:
continue;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
@@ -769,7 +768,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
MHD_HTTP_BAD_REQUEST,
"invalid_grant",
TALER_EC_CHALLENGER_GRANT_UNKNOWN,
- "token_add_token");
+ "do_insert_token");
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
break;
}
@@ -782,7 +781,7 @@ CH_handler_token (struct CH_HandlerContext *hc,
hc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_SOFT_FAILURE,
- "token_add_token");
+ "do_insert_token");
}
diff --git a/src/challengerdb/address_get.c b/src/challengerdb/address_get.c
@@ -1,56 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2025 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/address_get.c
- * @brief Implementation of the address_get function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "address_get.h"
-#include "pg_helper.h"
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_address_get (struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- json_t **address)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- TALER_PQ_result_spec_json ("address",
- address),
- NULL),
- GNUNET_PQ_result_spec_end
- };
-
- *address = NULL;
- PREPARE (ctx,
- "address_get",
- "SELECT "
- " address"
- " FROM validations"
- " WHERE nonce=$1");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "address_get",
- params,
- rs);
-}
diff --git a/src/challengerdb/authorize_start.c b/src/challengerdb/authorize_start.c
@@ -1,113 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/authorize_start.c
- * @brief Implementation of the authorize_start function for Postgres
- * @author Christian Grothoff
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "authorize_start.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_authorize_start (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint64_t client_id,
- const char *client_scope,
- const char *client_state,
- const char *client_redirect_uri,
- const char *code_challenge,
- uint32_t code_challenge_method,
- json_t **last_address,
- uint32_t *address_attempts_left,
- uint32_t *pin_transmissions_left,
- uint32_t *auth_attempts_left,
- bool *solved,
- struct GNUNET_TIME_Absolute *last_tx_time)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_uint64 (&client_id),
- NULL != client_scope
- ? GNUNET_PQ_query_param_string (client_scope)
- : GNUNET_PQ_query_param_null (),
- NULL != client_state
- ? GNUNET_PQ_query_param_string (client_state)
- : GNUNET_PQ_query_param_null (),
- NULL != client_redirect_uri
- ? GNUNET_PQ_query_param_string (client_redirect_uri)
- : GNUNET_PQ_query_param_null (),
- NULL != code_challenge
- ? GNUNET_PQ_query_param_string (code_challenge)
- : GNUNET_PQ_query_param_null (),
- GNUNET_PQ_query_param_uint32 (&code_challenge_method),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- TALER_PQ_result_spec_json ("address",
- last_address),
- NULL),
- GNUNET_PQ_result_spec_uint32 ("address_attempts_left",
- address_attempts_left),
- GNUNET_PQ_result_spec_uint32 ("pin_transmissions_left",
- pin_transmissions_left),
- GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
- auth_attempts_left),
- GNUNET_PQ_result_spec_bool ("solved",
- solved),
- GNUNET_PQ_result_spec_absolute_time ("last_tx_time",
- last_tx_time),
- GNUNET_PQ_result_spec_end
- };
-
- *last_address = NULL;
- PREPARE (ctx,
- "authorize_start_validation",
- "UPDATE validations SET"
- " client_scope=$3"
- " ,client_state=$4"
- " ,client_redirect_uri=COALESCE($5::VARCHAR,client_redirect_uri)"
- " ,code_challenge=$6"
- " ,code_challenge_method=$7"
- " WHERE nonce=$1"
- " AND client_serial_id=$2"
- " AND expiration_time > $8"
- " AND ( ($5::VARCHAR=client_redirect_uri)"
- " OR ( ($5::VARCHAR IS NULL)"
- " AND (client_redirect_uri IS NOT NULL) ) )"
- " RETURNING"
- " address"
- " ,address_attempts_left"
- " ,pin_transmissions_left"
- " ,GREATEST(0, auth_attempts_left) AS auth_attempts_left"
- " ,auth_attempts_left = -1 AS solved"
- " ,last_tx_time;");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "authorize_start_validation",
- params,
- rs);
-}
diff --git a/src/challengerdb/challenge_set_address_and_pin.c b/src/challengerdb/challenge_set_address_and_pin.c
@@ -1,125 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/challenge_set_address_and_pin.c
- * @brief Implementation of the challenge_set_address_and_pin function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "challenge_set_address_and_pin.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_challenge_set_address_and_pin (struct
- CHALLENGERDB_PostgresContext *ctx,
- const struct
- CHALLENGER_ValidationNonceP *nonce,
- const json_t *address,
- struct GNUNET_TIME_Relative
- retransmission_frequency,
- uint32_t *tan,
- char **state,
- struct GNUNET_TIME_Absolute *
- last_tx_time,
- uint32_t *auth_attempts_left,
- bool *pin_transmit,
- char **client_redirect_uri,
- bool *address_refused,
- bool *solved)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- /* We must gate retransmission on
- last_tx_time + retransmission_frequency <= now
- but 'last_tx_time' is only read (under FOR UPDATE) inside the stored
- procedure, so we cannot form that sum here. We therefore pass the
- equivalent, inverted form: the *newest* 'last_tx_time' for which a
- retransmission is still due. The SQL then merely checks
- last_tx_time <= retransmit_cutoff.
- Note that this is deliberately a subtraction from 'now', not
- 'now + retransmission_frequency': the value is compared against a
- timestamp in the *past*. GNUNET_TIME_absolute_subtract() saturates at
- zero rather than underflowing, so a FOREVER frequency degrades to
- "never *re*transmit" (the initial PIN, sent when last_tx_time is still 0,
- is unaffected). */
- struct GNUNET_TIME_Absolute retransmit_cutoff
- = GNUNET_TIME_absolute_subtract (now,
- retransmission_frequency);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- TALER_PQ_query_param_json (address),
- GNUNET_PQ_query_param_absolute_time (&retransmit_cutoff),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint32 (tan),
- GNUNET_PQ_query_param_end
- };
- bool not_found;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("not_found",
- ¬_found),
- GNUNET_PQ_result_spec_absolute_time ("last_tx_time",
- last_tx_time),
- GNUNET_PQ_result_spec_uint32 ("last_pin",
- tan),
- GNUNET_PQ_result_spec_bool ("pin_transmit",
- pin_transmit),
- GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
- auth_attempts_left),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_redirect_uri",
- client_redirect_uri),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("state",
- state),
- NULL),
- GNUNET_PQ_result_spec_bool ("address_refused",
- address_refused),
- GNUNET_PQ_result_spec_bool ("solved",
- solved),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- *client_redirect_uri = NULL;
- PREPARE (ctx,
- "do_challenge_set_address_and_pin",
- "SELECT "
- " out_not_found AS not_found"
- ",out_last_tx_time AS last_tx_time"
- ",out_pin_transmit AS pin_transmit"
- ",out_last_pin AS last_pin"
- ",out_state AS state"
- ",out_auth_attempts_left AS auth_attempts_left"
- ",out_client_redirect_uri AS client_redirect_uri"
- ",out_address_refused AS address_refused"
- ",out_solved AS solved"
- " FROM challenger_do_challenge_set_address_and_pin"
- " ($1,$2,$3,$4,$5);");
- qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "do_challenge_set_address_and_pin",
- params,
- rs);
- if (qs <= 0)
- return qs;
- if (not_found)
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- return qs;
-}
diff --git a/src/challengerdb/challenger_do_challenge_set_address_and_pin.sql b/src/challengerdb/challenger_do_challenge_set_address_and_pin.sql
@@ -1,141 +0,0 @@
---
--- This file is part of TALER
--- Copyright (C) 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
--- Foundation; either version 3, or (at your option) any later version.
---
--- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
--- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
--- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
---
--- You should have received a copy of the GNU General Public License along with
--- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
---
-
-
-DROP FUNCTION IF EXISTS challenger_do_challenge_set_address_and_pin;
-CREATE FUNCTION challenger_do_challenge_set_address_and_pin (
- IN in_nonce BYTEA,
- IN in_address TEXT,
- -- Newest last_tx_time for which a (re)transmission is still due, that is
- -- 'now - retransmission_frequency'. Computed by the caller because
- -- last_tx_time is only known here; see challenge_set_address_and_pin.c.
- IN in_retransmit_cutoff INT8,
- IN in_now INT8,
- IN in_tan INT4,
- OUT out_not_found BOOLEAN,
- OUT out_last_tx_time INT8,
- OUT out_last_pin INT4,
- OUT out_state TEXT,
- OUT out_pin_transmit BOOLEAN,
- OUT out_auth_attempts_left INT4,
- OUT out_client_redirect_uri TEXT,
- OUT out_address_refused BOOLEAN,
- OUT out_solved BOOLEAN)
-LANGUAGE plpgsql
-AS $$
-DECLARE
- my_status RECORD;
- my_do_update BOOL;
-BEGIN
-
-my_do_update = FALSE;
-
-SELECT address
- ,address_attempts_left
- ,pin_transmissions_left
- ,last_tx_time
- ,client_redirect_uri
- ,last_pin
- ,auth_attempts_left
- ,client_state
- INTO my_status
- FROM validations
- WHERE nonce=in_nonce
- AND expiration_time > in_now
- FOR UPDATE;
-
-IF NOT FOUND
-THEN
- out_not_found=TRUE;
- out_last_tx_time=0;
- out_last_pin=0;
- out_pin_transmit=FALSE;
- out_auth_attempts_left=0;
- out_client_redirect_uri=NULL;
- out_address_refused=TRUE;
- out_solved=FALSE;
- out_state=NULL;
- RETURN;
-END IF;
-out_not_found=FALSE;
-out_last_tx_time=my_status.last_tx_time;
-out_last_pin=my_status.last_pin;
-out_pin_transmit=FALSE;
-out_auth_attempts_left=my_status.auth_attempts_left;
-out_state=my_status.client_state;
-out_client_redirect_uri=my_status.client_redirect_uri;
-
-IF ( 0 > my_status.auth_attempts_left ) -- this challenge is solved
-THEN
- out_address_refused=TRUE;
- out_solved=TRUE;
- out_auth_attempts_left=0;
- RETURN;
-END IF;
-out_solved=FALSE;
-
-IF ( (0 = my_status.address_attempts_left) AND
- (in_address != my_status.address) )
-THEN
- out_address_refused=TRUE;
- out_last_pin=0;
- RETURN;
-END IF;
-out_address_refused=FALSE;
-
-IF ( (my_status.address IS NULL) OR
- (in_address != my_status.address) )
-THEN
- -- we are changing the address, update counters
- my_status.address_attempts_left
- = GREATEST(0,my_status.address_attempts_left - 1);
- my_status.address = in_address;
- my_status.pin_transmissions_left = 3;
- my_status.last_tx_time = 0;
- my_do_update=TRUE;
-END IF;
-
-IF ( (my_status.pin_transmissions_left > 0) AND
- (my_status.last_tx_time <= in_retransmit_cutoff) )
-THEN
- -- enough time has passed since the last transmission, so
- -- we are changing the PIN, update counters
- my_status.pin_transmissions_left = my_status.pin_transmissions_left - 1;
- my_status.last_pin = in_tan;
- my_status.auth_attempts_left = 3;
- my_status.last_tx_time = in_now;
- out_auth_attempts_left = 3;
- out_pin_transmit=TRUE;
- out_last_pin = in_tan;
- out_last_tx_time = in_now;
- my_do_update=TRUE;
-END IF;
-
-IF my_do_update
-THEN
- UPDATE validations SET
- address=my_status.address
- ,address_attempts_left=my_status.address_attempts_left
- ,pin_transmissions_left=my_status.pin_transmissions_left
- ,last_tx_time=my_status.last_tx_time
- ,last_pin=my_status.last_pin
- ,auth_attempts_left=my_status.auth_attempts_left
- WHERE nonce=in_nonce;
-END IF;
-
-RETURN;
-
-END $$;
diff --git a/src/challengerdb/client_add.c b/src/challengerdb/client_add.c
@@ -1,60 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/client_add.c
- * @brief Implementation of the client_add function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "client_add.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_add (struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_redirect_uri,
- const char *client_secret,
- uint64_t *client_id)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (client_redirect_uri),
- GNUNET_PQ_query_param_string (client_secret),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("client_serial_id",
- client_id),
- GNUNET_PQ_result_spec_end
- };
-
- *client_id = 0;
- PREPARE (ctx,
- "client_add",
- "INSERT INTO clients"
- " (uri"
- " ,client_secret"
- ") VALUES "
- "($1, $2)"
- " ON CONFLICT DO NOTHING" /* CONFLICT on (uri) */
- " RETURNING client_serial_id");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "client_add",
- params,
- rs);
-}
diff --git a/src/challengerdb/client_check.c b/src/challengerdb/client_check.c
@@ -1,117 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/client_check.c
- * @brief Implementation of the client_check function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "client_check.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_check (
- struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const char *client_secret,
- uint32_t counter_increment,
- char **client_redirect_uri)
-{
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("uri",
- client_redirect_uri),
- NULL),
- GNUNET_PQ_result_spec_end
- };
-
- *client_redirect_uri = NULL;
- if (0 == counter_increment)
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&client_id),
- GNUNET_PQ_query_param_string (client_secret),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (ctx,
- "client_check_ro",
- "SELECT uri"
- " FROM clients"
- " WHERE client_serial_id=$1"
- " AND client_secret=$2;");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "client_check_ro",
- params,
- rs);
- }
- else
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&client_id),
- GNUNET_PQ_query_param_string (client_secret),
- GNUNET_PQ_query_param_uint32 (&counter_increment),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (ctx,
- "client_check",
- "UPDATE clients SET"
- " validation_counter=validation_counter+CAST($3::INT4 AS INT8)"
- " WHERE client_serial_id=$1"
- " AND client_secret=$2"
- " RETURNING uri;");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "client_check",
- params,
- rs);
- }
-}
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_check2 (
- struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_uri,
- const char *client_secret,
- uint64_t *client_id)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (client_uri),
- GNUNET_PQ_query_param_string (client_secret),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("client_serial_id",
- client_id),
- GNUNET_PQ_result_spec_end
- };
-
- PREPARE (ctx,
- "client_check2",
- "SELECT client_serial_id"
- " FROM clients"
- " WHERE uri=$1"
- " AND client_secret=$2;");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "client_check2",
- params,
- rs);
-}
diff --git a/src/challengerdb/client_delete.c b/src/challengerdb/client_delete.c
@@ -1,45 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/client_delete.c
- * @brief Implementation of the client_delete function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "client_delete.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_delete (struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_redirect_uri)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (client_redirect_uri),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (ctx,
- "client_delete",
- "DELETE FROM clients"
- " WHERE uri=$1;");
- return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
- "client_delete",
- params);
-}
diff --git a/src/challengerdb/client_modify.c b/src/challengerdb/client_modify.c
@@ -1,52 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2024 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/client_modify.c
- * @brief Implementation of the client_modify function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "client_modify.h"
-#include "pg_helper.h"
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_modify (struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const char *client_redirect_uri,
- const char *client_secret)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&client_id),
- GNUNET_PQ_query_param_string (client_redirect_uri),
- NULL == client_secret
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (client_secret),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (ctx,
- "client_modify",
- "UPDATE clients"
- " SET uri=$2"
- " ,client_secret=COALESCE($3,client_secret)"
- " WHERE client_serial_id=$1");
- return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
- "client_modify",
- params);
-}
diff --git a/src/challengerdb/delete_client.c b/src/challengerdb/delete_client.c
@@ -0,0 +1,45 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/delete_client.c
+ * @brief Implementation of the delete_client function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "delete_client.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_delete_client (struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_redirect_uri)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (client_redirect_uri),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (ctx,
+ "delete_client",
+ "DELETE FROM clients"
+ " WHERE uri=$1;");
+ return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
+ "delete_client",
+ params);
+}
diff --git a/src/challengerdb/do_challenge_address.c b/src/challengerdb/do_challenge_address.c
@@ -0,0 +1,122 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/do_challenge_address.c
+ * @brief Implementation of the do_challenge_address function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "do_challenge_address.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_challenge_address (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ const json_t *address,
+ struct GNUNET_TIME_Relative retransmission_frequency,
+ uint32_t *tan,
+ char **state,
+ struct GNUNET_TIME_Absolute *last_tx_time,
+ uint32_t *auth_attempts_left,
+ bool *pin_transmit,
+ char **client_redirect_uri,
+ bool *address_refused,
+ bool *solved)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ /* We must gate retransmission on
+ last_tx_time + retransmission_frequency <= now
+ but 'last_tx_time' is only read (under FOR UPDATE) inside the stored
+ procedure, so we cannot form that sum here. We therefore pass the
+ equivalent, inverted form: the *newest* 'last_tx_time' for which a
+ retransmission is still due. The SQL then merely checks
+ last_tx_time <= retransmit_cutoff.
+ Note that this is deliberately a subtraction from 'now', not
+ 'now + retransmission_frequency': the value is compared against a
+ timestamp in the *past*. GNUNET_TIME_absolute_subtract() saturates at
+ zero rather than underflowing, so a FOREVER frequency degrades to
+ "never *re*transmit" (the initial PIN, sent when last_tx_time is still 0,
+ is unaffected). */
+ struct GNUNET_TIME_Absolute retransmit_cutoff
+ = GNUNET_TIME_absolute_subtract (now,
+ retransmission_frequency);
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ TALER_PQ_query_param_json (address),
+ GNUNET_PQ_query_param_absolute_time (&retransmit_cutoff),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_uint32 (tan),
+ GNUNET_PQ_query_param_end
+ };
+ bool not_found;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("not_found",
+ ¬_found),
+ GNUNET_PQ_result_spec_absolute_time ("last_tx_time",
+ last_tx_time),
+ GNUNET_PQ_result_spec_uint32 ("last_pin",
+ tan),
+ GNUNET_PQ_result_spec_bool ("pin_transmit",
+ pin_transmit),
+ GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
+ auth_attempts_left),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_redirect_uri",
+ client_redirect_uri),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("state",
+ state),
+ NULL),
+ GNUNET_PQ_result_spec_bool ("address_refused",
+ address_refused),
+ GNUNET_PQ_result_spec_bool ("solved",
+ solved),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ *client_redirect_uri = NULL;
+ PREPARE (ctx,
+ "do_challenge_address",
+ "SELECT "
+ " out_not_found AS not_found"
+ ",out_last_tx_time AS last_tx_time"
+ ",out_pin_transmit AS pin_transmit"
+ ",out_last_pin AS last_pin"
+ ",out_state AS state"
+ ",out_auth_attempts_left AS auth_attempts_left"
+ ",out_client_redirect_uri AS client_redirect_uri"
+ ",out_address_refused AS address_refused"
+ ",out_solved AS solved"
+ " FROM challenger_do_challenge_set_address_and_pin"
+ " ($1,$2,$3,$4,$5);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "do_challenge_address",
+ params,
+ rs);
+ if (qs <= 0)
+ return qs;
+ if (not_found)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ return qs;
+}
diff --git a/src/challengerdb/do_challenge_address.sql b/src/challengerdb/do_challenge_address.sql
@@ -0,0 +1,141 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 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
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+
+DROP FUNCTION IF EXISTS challenger_do_challenge_set_address_and_pin;
+CREATE FUNCTION challenger_do_challenge_set_address_and_pin (
+ IN in_nonce BYTEA,
+ IN in_address TEXT,
+ -- Newest last_tx_time for which a (re)transmission is still due, that is
+ -- 'now - retransmission_frequency'. Computed by the caller because
+ -- last_tx_time is only known here; see do_challenge_address.c.
+ IN in_retransmit_cutoff INT8,
+ IN in_now INT8,
+ IN in_tan INT4,
+ OUT out_not_found BOOLEAN,
+ OUT out_last_tx_time INT8,
+ OUT out_last_pin INT4,
+ OUT out_state TEXT,
+ OUT out_pin_transmit BOOLEAN,
+ OUT out_auth_attempts_left INT4,
+ OUT out_client_redirect_uri TEXT,
+ OUT out_address_refused BOOLEAN,
+ OUT out_solved BOOLEAN)
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ my_status RECORD;
+ my_do_update BOOL;
+BEGIN
+
+my_do_update = FALSE;
+
+SELECT address
+ ,address_attempts_left
+ ,pin_transmissions_left
+ ,last_tx_time
+ ,client_redirect_uri
+ ,last_pin
+ ,auth_attempts_left
+ ,client_state
+ INTO my_status
+ FROM validations
+ WHERE nonce=in_nonce
+ AND expiration_time > in_now
+ FOR UPDATE;
+
+IF NOT FOUND
+THEN
+ out_not_found=TRUE;
+ out_last_tx_time=0;
+ out_last_pin=0;
+ out_pin_transmit=FALSE;
+ out_auth_attempts_left=0;
+ out_client_redirect_uri=NULL;
+ out_address_refused=TRUE;
+ out_solved=FALSE;
+ out_state=NULL;
+ RETURN;
+END IF;
+out_not_found=FALSE;
+out_last_tx_time=my_status.last_tx_time;
+out_last_pin=my_status.last_pin;
+out_pin_transmit=FALSE;
+out_auth_attempts_left=my_status.auth_attempts_left;
+out_state=my_status.client_state;
+out_client_redirect_uri=my_status.client_redirect_uri;
+
+IF ( 0 > my_status.auth_attempts_left ) -- this challenge is solved
+THEN
+ out_address_refused=TRUE;
+ out_solved=TRUE;
+ out_auth_attempts_left=0;
+ RETURN;
+END IF;
+out_solved=FALSE;
+
+IF ( (0 = my_status.address_attempts_left) AND
+ (in_address != my_status.address) )
+THEN
+ out_address_refused=TRUE;
+ out_last_pin=0;
+ RETURN;
+END IF;
+out_address_refused=FALSE;
+
+IF ( (my_status.address IS NULL) OR
+ (in_address != my_status.address) )
+THEN
+ -- we are changing the address, update counters
+ my_status.address_attempts_left
+ = GREATEST(0,my_status.address_attempts_left - 1);
+ my_status.address = in_address;
+ my_status.pin_transmissions_left = 3;
+ my_status.last_tx_time = 0;
+ my_do_update=TRUE;
+END IF;
+
+IF ( (my_status.pin_transmissions_left > 0) AND
+ (my_status.last_tx_time <= in_retransmit_cutoff) )
+THEN
+ -- enough time has passed since the last transmission, so
+ -- we are changing the PIN, update counters
+ my_status.pin_transmissions_left = my_status.pin_transmissions_left - 1;
+ my_status.last_pin = in_tan;
+ my_status.auth_attempts_left = 3;
+ my_status.last_tx_time = in_now;
+ out_auth_attempts_left = 3;
+ out_pin_transmit=TRUE;
+ out_last_pin = in_tan;
+ out_last_tx_time = in_now;
+ my_do_update=TRUE;
+END IF;
+
+IF my_do_update
+THEN
+ UPDATE validations SET
+ address=my_status.address
+ ,address_attempts_left=my_status.address_attempts_left
+ ,pin_transmissions_left=my_status.pin_transmissions_left
+ ,last_tx_time=my_status.last_tx_time
+ ,last_pin=my_status.last_pin
+ ,auth_attempts_left=my_status.auth_attempts_left
+ WHERE nonce=in_nonce;
+END IF;
+
+RETURN;
+
+END $$;
diff --git a/src/challengerdb/do_insert_token.c b/src/challengerdb/do_insert_token.c
@@ -0,0 +1,74 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/do_insert_token.c
+ * @brief Implementation of the do_insert_token function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "do_insert_token.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_insert_token (struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ const struct CHALLENGER_AccessTokenP *token,
+ struct GNUNET_TIME_Relative token_expiration,
+ struct GNUNET_TIME_Relative address_expiration)
+{
+ struct GNUNET_TIME_Absolute ge
+ = GNUNET_TIME_relative_to_absolute (token_expiration);
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_auto_from_type (token),
+ GNUNET_PQ_query_param_absolute_time (&ge),
+ GNUNET_PQ_query_param_relative_time (&address_expiration),
+ GNUNET_PQ_query_param_end
+ };
+
+ /* Redemption must be atomic and one-shot (RFC 6749 4.1.2): consume the
+ validation by deleting it as we mint the token, so the same authorization
+ code cannot be replayed to mint additional tokens. A replay finds no
+ matching validations row and thus inserts no token (NO_RESULTS), which the
+ caller maps to 'invalid_grant'. The 'address IS NOT NULL' guard avoids
+ violating the tokens.address NOT NULL constraint (and only consumes a
+ validation that actually carries a solved address). */
+ PREPARE (ctx,
+ "do_insert_token",
+ "WITH consumed AS ("
+ " DELETE FROM validations"
+ " WHERE nonce=$1"
+ " AND address IS NOT NULL"
+ " RETURNING address, last_tx_time"
+ ") INSERT INTO tokens"
+ " (access_token"
+ " ,address"
+ " ,token_expiration_time"
+ " ,address_expiration_time"
+ ") SELECT"
+ " $2"
+ " ,address"
+ " ,$3"
+ " ,LEAST($4, 9223372036854775807::BIGINT - last_tx_time) + last_tx_time"
+ " FROM consumed;");
+ return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
+ "do_insert_token",
+ params);
+}
diff --git a/src/challengerdb/do_insert_validation.c b/src/challengerdb/do_insert_validation.c
@@ -0,0 +1,74 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/do_insert_validation.c
+ * @brief Implementation of the do_insert_validation function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "do_insert_validation.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_insert_validation (struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_secret,
+ const struct
+ CHALLENGER_ValidationNonceP *nonce,
+ struct GNUNET_TIME_Absolute expiration_time,
+ const json_t *initial_address)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&client_id),
+ GNUNET_PQ_query_param_string (client_secret),
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_absolute_time (&expiration_time),
+ NULL == initial_address
+ ? GNUNET_PQ_query_param_null ()
+ : TALER_PQ_query_param_json (initial_address),
+ GNUNET_PQ_query_param_end
+ };
+
+ /* Authenticating the client, charging it for the validation and creating
+ the validation row must happen together: the counter may only move if
+ the validation is really created. Doing it in one statement also saves
+ the round trips of an explicit transaction. A client that does not
+ exist (or presents the wrong secret) leaves the CTE empty, so nothing is
+ inserted and the caller sees NO_RESULTS. */
+ PREPARE (ctx,
+ "do_insert_validation",
+ "WITH charged AS ("
+ " UPDATE clients"
+ " SET validation_counter=validation_counter+1"
+ " WHERE client_serial_id=$1"
+ " AND client_secret=$2"
+ " RETURNING client_serial_id, uri"
+ ") INSERT INTO validations"
+ " (client_serial_id"
+ " ,nonce"
+ " ,expiration_time"
+ " ,client_redirect_uri"
+ " ,address"
+ ") SELECT client_serial_id, $3, $4, uri, $5"
+ " FROM charged;");
+ return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
+ "do_insert_validation",
+ params);
+}
diff --git a/src/challengerdb/do_solve_challenge.c b/src/challengerdb/do_solve_challenge.c
@@ -0,0 +1,109 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/do_solve_challenge.c
+ * @brief Implementation of the do_solve_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "do_solve_challenge.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_solve_challenge (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint32_t new_pin,
+ bool *solved,
+ bool *exhausted,
+ bool *no_challenge,
+ char **state,
+ uint32_t *addr_left,
+ uint32_t *auth_attempts_left,
+ uint32_t *pin_transmissions_left,
+ char **client_redirect_uri)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_uint32 (&new_pin),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ bool not_found;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("not_found",
+ ¬_found),
+ GNUNET_PQ_result_spec_bool ("solved",
+ solved),
+ GNUNET_PQ_result_spec_bool ("exhausted",
+ exhausted),
+ GNUNET_PQ_result_spec_bool ("no_challenge",
+ no_challenge),
+ GNUNET_PQ_result_spec_uint32 ("address_attempts_left",
+ addr_left),
+ GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
+ auth_attempts_left),
+ GNUNET_PQ_result_spec_uint32 ("pin_transmissions_left",
+ pin_transmissions_left),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_redirect_uri",
+ client_redirect_uri),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("state",
+ state),
+ NULL),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ *client_redirect_uri = NULL;
+ PREPARE (ctx,
+ "do_solve_challenge",
+ "SELECT "
+ " out_not_found AS not_found"
+ ",out_solved AS solved"
+ ",out_exhausted AS exhausted"
+ ",out_no_challenge AS no_challenge"
+ ",out_state AS state"
+ ",out_address_attempts_left AS address_attempts_left"
+ ",out_auth_attempts_left AS auth_attempts_left"
+ ",out_pin_transmissions_left AS pin_transmissions_left"
+ ",out_client_redirect_uri AS client_redirect_uri"
+ " FROM challenger_do_validate_and_solve_pin"
+ " ($1,$2,$3);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "do_solve_challenge",
+ params,
+ rs);
+ if (qs <= 0)
+ return qs;
+ if (not_found)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ /* On the solved path the stored procedure returns the -1 sentinel (kept in
+ the DB to mark the challenge as solved), which the uint32 result spec reads
+ as 4294967295. That value is not meaningful to the caller (which only
+ reads it when !solved); normalize it to 0 to avoid leaking the sentinel. */
+ if (*solved)
+ *auth_attempts_left = 0;
+ return qs;
+}
diff --git a/src/challengerdb/challenger_do_validate_and_solve_pin.sql b/src/challengerdb/do_solve_challenge.sql
diff --git a/src/challengerdb/get_client.c b/src/challengerdb/get_client.c
@@ -0,0 +1,60 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_client.c
+ * @brief Implementation of the get_client function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_client.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_client (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_secret,
+ char **client_redirect_uri)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&client_id),
+ GNUNET_PQ_query_param_string (client_secret),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("uri",
+ client_redirect_uri),
+ NULL),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *client_redirect_uri = NULL;
+ PREPARE (ctx,
+ "get_client",
+ "SELECT uri"
+ " FROM clients"
+ " WHERE client_serial_id=$1"
+ " AND client_secret=$2;");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_client",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/get_client_by_uri.c b/src/challengerdb/get_client_by_uri.c
@@ -0,0 +1,57 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_client_by_uri.c
+ * @brief Implementation of the get_client_by_uri function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_client_by_uri.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_client_by_uri (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_uri,
+ const char *client_secret,
+ uint64_t *client_id)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (client_uri),
+ GNUNET_PQ_query_param_string (client_secret),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("client_serial_id",
+ client_id),
+ GNUNET_PQ_result_spec_end
+ };
+
+ PREPARE (ctx,
+ "get_client_by_uri",
+ "SELECT client_serial_id"
+ " FROM clients"
+ " WHERE uri=$1"
+ " AND client_secret=$2;");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_client_by_uri",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/get_token.c b/src/challengerdb/get_token.c
@@ -0,0 +1,71 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_token.c
+ * @brief Implementation of the get_token function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_token.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_token (struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_AccessTokenP *token,
+ uint64_t *rowid,
+ json_t **address,
+ struct GNUNET_TIME_Timestamp *address_expiration)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (token),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_TIME_Absolute at;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("rowid",
+ rowid),
+ TALER_PQ_result_spec_json ("address",
+ address),
+ GNUNET_PQ_result_spec_absolute_time ("address_expiration_time",
+ &at),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ PREPARE (ctx,
+ "get_token",
+ "SELECT "
+ " grant_serial_id AS rowid"
+ " ,address"
+ " ,address_expiration_time"
+ " FROM tokens"
+ " WHERE access_token=$1"
+ " AND token_expiration_time > $2");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_token",
+ params,
+ rs);
+ if (qs > 0)
+ *address_expiration = GNUNET_TIME_absolute_to_timestamp (at);
+ return qs;
+}
diff --git a/src/challengerdb/get_validation.c b/src/challengerdb/get_validation.c
@@ -0,0 +1,86 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_validation.c
+ * @brief Implementation of the get_validation function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_validation.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ char **client_secret,
+ json_t **address,
+ char **client_scope,
+ char **client_state,
+ char **client_redirect_uri)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("client_secret",
+ client_secret),
+ GNUNET_PQ_result_spec_allow_null (
+ TALER_PQ_result_spec_json ("address",
+ address),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_scope",
+ client_scope),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_state",
+ client_state),
+ NULL),
+ GNUNET_PQ_result_spec_string ("redirect_uri",
+ client_redirect_uri),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *client_scope = NULL;
+ *client_state = NULL;
+ *address = NULL;
+ PREPARE (ctx,
+ "get_validation",
+ "SELECT "
+ " client_secret"
+ " ,address"
+ " ,client_scope"
+ " ,client_state"
+ " ,COALESCE(client_redirect_uri,uri) AS redirect_uri"
+ " FROM validations"
+ " JOIN clients "
+ " USING (client_serial_id)"
+ " WHERE nonce=$1"
+ " AND expiration_time > $2");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_validation",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/get_validation_address.c b/src/challengerdb/get_validation_address.c
@@ -0,0 +1,57 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2025 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_validation_address.c
+ * @brief Implementation of the get_validation_address function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_validation_address.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation_address (struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *
+ nonce,
+ json_t **address)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_allow_null (
+ TALER_PQ_result_spec_json ("address",
+ address),
+ NULL),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *address = NULL;
+ PREPARE (ctx,
+ "get_validation_address",
+ "SELECT "
+ " address"
+ " FROM validations"
+ " WHERE nonce=$1");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_validation_address",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/get_validation_pkce.c b/src/challengerdb/get_validation_pkce.c
@@ -0,0 +1,99 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/get_validation_pkce.c
+ * @brief Implementation of the get_validation_pkce function for Postgres
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "get_validation_pkce.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation_pkce (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint64_t client_id,
+ char **client_secret,
+ json_t **address,
+ char **client_scope,
+ char **client_state,
+ char **client_redirect_uri,
+ char **code_challenge,
+ uint32_t *code_challenge_method)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_uint64 (&client_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("client_secret",
+ client_secret),
+ GNUNET_PQ_result_spec_allow_null (
+ TALER_PQ_result_spec_json ("address",
+ address),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_scope",
+ client_scope),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("client_state",
+ client_state),
+ NULL),
+ GNUNET_PQ_result_spec_string ("redirect_uri",
+ client_redirect_uri),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("code_challenge",
+ code_challenge),
+ NULL),
+ GNUNET_PQ_result_spec_uint32 ("code_challenge_method",
+ code_challenge_method),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *client_scope = NULL;
+ *client_state = NULL;
+ *address = NULL;
+ PREPARE (ctx,
+ "get_validation_pkce",
+ "SELECT "
+ " client_secret"
+ " ,address"
+ " ,client_scope"
+ " ,client_state"
+ " ,COALESCE(client_redirect_uri,uri) AS redirect_uri"
+ " ,code_challenge"
+ " ,code_challenge_method"
+ " FROM validations"
+ " JOIN clients "
+ " USING (client_serial_id)"
+ " WHERE nonce=$1"
+ " AND expiration_time > $2"
+ " AND client_serial_id=$3");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "get_validation_pkce",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/info_get_token.c b/src/challengerdb/info_get_token.c
@@ -1,71 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/info_get_token.c
- * @brief Implementation of the info_get_token function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "info_get_token.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_info_get_token (struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_AccessTokenP *token,
- uint64_t *rowid,
- json_t **address,
- struct GNUNET_TIME_Timestamp *address_expiration)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (token),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_TIME_Absolute at;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("rowid",
- rowid),
- TALER_PQ_result_spec_json ("address",
- address),
- GNUNET_PQ_result_spec_absolute_time ("address_expiration_time",
- &at),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- PREPARE (ctx,
- "info_get_token",
- "SELECT "
- " grant_serial_id AS rowid"
- " ,address"
- " ,address_expiration_time"
- " FROM tokens"
- " WHERE access_token=$1"
- " AND token_expiration_time > $2");
- qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "info_get_token",
- params,
- rs);
- if (qs > 0)
- *address_expiration = GNUNET_TIME_absolute_to_timestamp (at);
- return qs;
-}
diff --git a/src/challengerdb/insert_client.c b/src/challengerdb/insert_client.c
@@ -0,0 +1,60 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/insert_client.c
+ * @brief Implementation of the insert_client function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "insert_client.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_insert_client (struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_redirect_uri,
+ const char *client_secret,
+ uint64_t *client_id)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (client_redirect_uri),
+ GNUNET_PQ_query_param_string (client_secret),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("client_serial_id",
+ client_id),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *client_id = 0;
+ PREPARE (ctx,
+ "insert_client",
+ "INSERT INTO clients"
+ " (uri"
+ " ,client_secret"
+ ") VALUES "
+ "($1, $2)"
+ " ON CONFLICT DO NOTHING" /* CONFLICT on (uri) */
+ " RETURNING client_serial_id");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "insert_client",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/meson.build b/src/challengerdb/meson.build
@@ -7,8 +7,8 @@ sqldir = get_option('datadir') / 'challenger' / 'sql'
procedures_sql = [
'procedures-prelude.sql',
- 'challenger_do_challenge_set_address_and_pin.sql',
- 'challenger_do_validate_and_solve_pin.sql',
+ 'do_challenge_address.sql',
+ 'do_solve_challenge.sql',
'commit.sql',
]
@@ -35,24 +35,25 @@ foreach g : generated_sql
endforeach
libchallengerdb_SOURCES = [
- 'address_get.c',
- 'client_add.c',
- 'client_modify.c',
- 'client_delete.c',
- 'client_check.c',
+ 'get_validation_address.c',
+ 'insert_client.c',
+ 'update_client.c',
+ 'delete_client.c',
+ 'get_client.c',
+ 'get_client_by_uri.c',
'create_tables.c',
'drop_tables.c',
'gc.c',
- 'info_get_token.c',
- 'token_add_token.c',
- 'setup_nonce.c',
+ 'get_token.c',
+ 'do_insert_token.c',
+ 'do_insert_validation.c',
'preflight.c',
'pg.c',
- 'authorize_start.c',
- 'challenge_set_address_and_pin.c',
- 'validate_solve_pin.c',
- 'validation_get.c',
- 'validation_get_pkce.c',
+ 'update_validation.c',
+ 'do_challenge_address.c',
+ 'do_solve_challenge.c',
+ 'get_validation.c',
+ 'get_validation_pkce.c',
]
libchallengerdb = library(
'challengerdb',
diff --git a/src/challengerdb/pg.c b/src/challengerdb/pg.c
@@ -14,7 +14,7 @@
Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file challengerdb/plugin_challengerdb_postgres.c
+ * @file src/challengerdb/pg.c
* @brief database helper functions for postgres used by challenger
* @author Christian Grothoff
*/
diff --git a/src/challengerdb/pg_helper.h b/src/challengerdb/pg_helper.h
@@ -14,7 +14,7 @@
Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file challengerdb/pg_helper.h
+ * @file src/challengerdb/pg_helper.h
* @brief database helper definitions
* @author Christian Grothoff
*/
diff --git a/src/challengerdb/setup_nonce.c b/src/challengerdb/setup_nonce.c
@@ -1,60 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/setup_nonce.c
- * @brief Implementation of the validation_setup function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "setup_nonce.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_setup_nonce (struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const struct CHALLENGER_ValidationNonceP *nonce,
- struct GNUNET_TIME_Absolute expiration_time,
- const json_t *initial_address)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&client_id),
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_absolute_time (&expiration_time),
- NULL == initial_address
- ? GNUNET_PQ_query_param_null ()
- : TALER_PQ_query_param_json (initial_address),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (ctx,
- "setup_nonce",
- "INSERT INTO validations"
- " (client_serial_id"
- " ,nonce"
- " ,expiration_time"
- " ,client_redirect_uri"
- " ,address"
- ") SELECT $1, $2, $3, uri, $4"
- " FROM CLIENTS"
- " WHERE client_serial_id=$1;");
- return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
- "setup_nonce",
- params);
-}
diff --git a/src/challengerdb/token_add_token.c b/src/challengerdb/token_add_token.c
@@ -1,74 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/token_add_token.c
- * @brief Implementation of the token_add_token function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "token_add_token.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_token_add_token (struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- const struct CHALLENGER_AccessTokenP *token,
- struct GNUNET_TIME_Relative token_expiration,
- struct GNUNET_TIME_Relative address_expiration)
-{
- struct GNUNET_TIME_Absolute ge
- = GNUNET_TIME_relative_to_absolute (token_expiration);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_auto_from_type (token),
- GNUNET_PQ_query_param_absolute_time (&ge),
- GNUNET_PQ_query_param_relative_time (&address_expiration),
- GNUNET_PQ_query_param_end
- };
-
- /* Redemption must be atomic and one-shot (RFC 6749 4.1.2): consume the
- validation by deleting it as we mint the token, so the same authorization
- code cannot be replayed to mint additional tokens. A replay finds no
- matching validations row and thus inserts no token (NO_RESULTS), which the
- caller maps to 'invalid_grant'. The 'address IS NOT NULL' guard avoids
- violating the tokens.address NOT NULL constraint (and only consumes a
- validation that actually carries a solved address). */
- PREPARE (ctx,
- "token_add_token",
- "WITH consumed AS ("
- " DELETE FROM validations"
- " WHERE nonce=$1"
- " AND address IS NOT NULL"
- " RETURNING address, last_tx_time"
- ") INSERT INTO tokens"
- " (access_token"
- " ,address"
- " ,token_expiration_time"
- " ,address_expiration_time"
- ") SELECT"
- " $2"
- " ,address"
- " ,$3"
- " ,LEAST($4, 9223372036854775807::BIGINT - last_tx_time) + last_tx_time"
- " FROM consumed;");
- return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
- "token_add_token",
- params);
-}
diff --git a/src/challengerdb/update_client.c b/src/challengerdb/update_client.c
@@ -0,0 +1,52 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2024 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/update_client.c
+ * @brief Implementation of the update_client function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "update_client.h"
+#include "pg_helper.h"
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_update_client (struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_redirect_uri,
+ const char *client_secret)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&client_id),
+ GNUNET_PQ_query_param_string (client_redirect_uri),
+ NULL == client_secret
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (client_secret),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (ctx,
+ "update_client",
+ "UPDATE clients"
+ " SET uri=$2"
+ " ,client_secret=COALESCE($3,client_secret)"
+ " WHERE client_serial_id=$1");
+ return GNUNET_PQ_eval_prepared_non_select (ctx->conn,
+ "update_client",
+ params);
+}
diff --git a/src/challengerdb/update_validation.c b/src/challengerdb/update_validation.c
@@ -0,0 +1,113 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/challengerdb/update_validation.c
+ * @brief Implementation of the update_validation function for Postgres
+ * @author Christian Grothoff
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "update_validation.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_update_validation (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint64_t client_id,
+ const char *client_scope,
+ const char *client_state,
+ const char *client_redirect_uri,
+ const char *code_challenge,
+ uint32_t code_challenge_method,
+ json_t **last_address,
+ uint32_t *address_attempts_left,
+ uint32_t *pin_transmissions_left,
+ uint32_t *auth_attempts_left,
+ bool *solved,
+ struct GNUNET_TIME_Absolute *last_tx_time)
+{
+ struct GNUNET_TIME_Absolute now
+ = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (nonce),
+ GNUNET_PQ_query_param_uint64 (&client_id),
+ NULL != client_scope
+ ? GNUNET_PQ_query_param_string (client_scope)
+ : GNUNET_PQ_query_param_null (),
+ NULL != client_state
+ ? GNUNET_PQ_query_param_string (client_state)
+ : GNUNET_PQ_query_param_null (),
+ NULL != client_redirect_uri
+ ? GNUNET_PQ_query_param_string (client_redirect_uri)
+ : GNUNET_PQ_query_param_null (),
+ NULL != code_challenge
+ ? GNUNET_PQ_query_param_string (code_challenge)
+ : GNUNET_PQ_query_param_null (),
+ GNUNET_PQ_query_param_uint32 (&code_challenge_method),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_allow_null (
+ TALER_PQ_result_spec_json ("address",
+ last_address),
+ NULL),
+ GNUNET_PQ_result_spec_uint32 ("address_attempts_left",
+ address_attempts_left),
+ GNUNET_PQ_result_spec_uint32 ("pin_transmissions_left",
+ pin_transmissions_left),
+ GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
+ auth_attempts_left),
+ GNUNET_PQ_result_spec_bool ("solved",
+ solved),
+ GNUNET_PQ_result_spec_absolute_time ("last_tx_time",
+ last_tx_time),
+ GNUNET_PQ_result_spec_end
+ };
+
+ *last_address = NULL;
+ PREPARE (ctx,
+ "update_validation",
+ "UPDATE validations SET"
+ " client_scope=$3"
+ " ,client_state=$4"
+ " ,client_redirect_uri=COALESCE($5::VARCHAR,client_redirect_uri)"
+ " ,code_challenge=$6"
+ " ,code_challenge_method=$7"
+ " WHERE nonce=$1"
+ " AND client_serial_id=$2"
+ " AND expiration_time > $8"
+ " AND ( ($5::VARCHAR=client_redirect_uri)"
+ " OR ( ($5::VARCHAR IS NULL)"
+ " AND (client_redirect_uri IS NOT NULL) ) )"
+ " RETURNING"
+ " address"
+ " ,address_attempts_left"
+ " ,pin_transmissions_left"
+ " ,GREATEST(0, auth_attempts_left) AS auth_attempts_left"
+ " ,auth_attempts_left = -1 AS solved"
+ " ,last_tx_time;");
+ return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
+ "update_validation",
+ params,
+ rs);
+}
diff --git a/src/challengerdb/validate_solve_pin.c b/src/challengerdb/validate_solve_pin.c
@@ -1,109 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/validate_solve_pin.c
- * @brief Implementation of the validate_solve_pin function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "validate_solve_pin.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validate_solve_pin (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint32_t new_pin,
- bool *solved,
- bool *exhausted,
- bool *no_challenge,
- char **state,
- uint32_t *addr_left,
- uint32_t *auth_attempts_left,
- uint32_t *pin_transmissions_left,
- char **client_redirect_uri)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_uint32 (&new_pin),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- bool not_found;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("not_found",
- ¬_found),
- GNUNET_PQ_result_spec_bool ("solved",
- solved),
- GNUNET_PQ_result_spec_bool ("exhausted",
- exhausted),
- GNUNET_PQ_result_spec_bool ("no_challenge",
- no_challenge),
- GNUNET_PQ_result_spec_uint32 ("address_attempts_left",
- addr_left),
- GNUNET_PQ_result_spec_uint32 ("auth_attempts_left",
- auth_attempts_left),
- GNUNET_PQ_result_spec_uint32 ("pin_transmissions_left",
- pin_transmissions_left),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_redirect_uri",
- client_redirect_uri),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("state",
- state),
- NULL),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- *client_redirect_uri = NULL;
- PREPARE (ctx,
- "do_validate_solve_pin",
- "SELECT "
- " out_not_found AS not_found"
- ",out_solved AS solved"
- ",out_exhausted AS exhausted"
- ",out_no_challenge AS no_challenge"
- ",out_state AS state"
- ",out_address_attempts_left AS address_attempts_left"
- ",out_auth_attempts_left AS auth_attempts_left"
- ",out_pin_transmissions_left AS pin_transmissions_left"
- ",out_client_redirect_uri AS client_redirect_uri"
- " FROM challenger_do_validate_and_solve_pin"
- " ($1,$2,$3);");
- qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "do_validate_solve_pin",
- params,
- rs);
- if (qs <= 0)
- return qs;
- if (not_found)
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- /* On the solved path the stored procedure returns the -1 sentinel (kept in
- the DB to mark the challenge as solved), which the uint32 result spec reads
- as 4294967295. That value is not meaningful to the caller (which only
- reads it when !solved); normalize it to 0 to avoid leaking the sentinel. */
- if (*solved)
- *auth_attempts_left = 0;
- return qs;
-}
diff --git a/src/challengerdb/validation_get.c b/src/challengerdb/validation_get.c
@@ -1,86 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/validation_get.c
- * @brief Implementation of the validation_get function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "validation_get.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validation_get (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- char **client_secret,
- json_t **address,
- char **client_scope,
- char **client_state,
- char **client_redirect_uri)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("client_secret",
- client_secret),
- GNUNET_PQ_result_spec_allow_null (
- TALER_PQ_result_spec_json ("address",
- address),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_scope",
- client_scope),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_state",
- client_state),
- NULL),
- GNUNET_PQ_result_spec_string ("redirect_uri",
- client_redirect_uri),
- GNUNET_PQ_result_spec_end
- };
-
- *client_scope = NULL;
- *client_state = NULL;
- *address = NULL;
- PREPARE (ctx,
- "validation_get",
- "SELECT "
- " client_secret"
- " ,address"
- " ,client_scope"
- " ,client_state"
- " ,COALESCE(client_redirect_uri,uri) AS redirect_uri"
- " FROM validations"
- " JOIN clients "
- " USING (client_serial_id)"
- " WHERE nonce=$1"
- " AND expiration_time > $2");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "validation_get",
- params,
- rs);
-}
diff --git a/src/challengerdb/validation_get_pkce.c b/src/challengerdb/validation_get_pkce.c
@@ -1,99 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/challengerdb/validation_get_pkce.c
- * @brief Implementation of the validation_get_pkce function for Postgres
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "validation_get_pkce.h"
-#include "pg_helper.h"
-
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validation_get_pkce (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint64_t client_id,
- char **client_secret,
- json_t **address,
- char **client_scope,
- char **client_state,
- char **client_redirect_uri,
- char **code_challenge,
- uint32_t *code_challenge_method)
-{
- struct GNUNET_TIME_Absolute now
- = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (nonce),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint64 (&client_id),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("client_secret",
- client_secret),
- GNUNET_PQ_result_spec_allow_null (
- TALER_PQ_result_spec_json ("address",
- address),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_scope",
- client_scope),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("client_state",
- client_state),
- NULL),
- GNUNET_PQ_result_spec_string ("redirect_uri",
- client_redirect_uri),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("code_challenge",
- code_challenge),
- NULL),
- GNUNET_PQ_result_spec_uint32 ("code_challenge_method",
- code_challenge_method),
- GNUNET_PQ_result_spec_end
- };
-
- *client_scope = NULL;
- *client_state = NULL;
- *address = NULL;
- PREPARE (ctx,
- "validation_get_pkce",
- "SELECT "
- " client_secret"
- " ,address"
- " ,client_scope"
- " ,client_state"
- " ,COALESCE(client_redirect_uri,uri) AS redirect_uri"
- " ,code_challenge"
- " ,code_challenge_method"
- " FROM validations"
- " JOIN clients "
- " USING (client_serial_id)"
- " WHERE nonce=$1"
- " AND expiration_time > $2"
- " AND client_serial_id=$3");
- return GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
- "validation_get_pkce",
- params,
- rs);
-}
diff --git a/src/include/challenger-database/address_get.h b/src/include/challenger-database/address_get.h
@@ -1,46 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2025 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/address_get.h
- * @brief implementation of the address_get function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_ADDRESS_GET_H
-#define CHALLENGER_DATABASE_ADDRESS_GET_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Return address details.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param[out] address set to client-provided address (or to NULL)
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_address_get (struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- json_t **address);
-
-#endif
diff --git a/src/include/challenger-database/authorize_start.h b/src/include/challenger-database/authorize_start.h
@@ -1,79 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/authorize_start.h
- * @brief implementation of the authorize_start function for Postgres
- * @author Christian Grothoff
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#ifndef CHALLENGER_DATABASE_AUTHORIZE_START_H
-#define CHALLENGER_DATABASE_AUTHORIZE_START_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Begin the authorization phase of a validation: record the client's OAuth2
- * scope, state, redirect URI and PKCE code challenge on the validation
- * identified by @a nonce, and return the current status (last address,
- * remaining attempt counters, whether it is already solved). Succeeds only if
- * the supplied @a client_redirect_uri matches the one registered for the client.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param client_id client that initiated the validation
- * @param client_scope scope of the validation
- * @param client_state state of the client
- * @param client_redirect_uri where to redirect at the end, NULL to use a unique one registered for the client
- * @param code_challenge PKCE code challenge
- * @param code_challenge_method PKCE code challenge method enum
- * @param[out] last_address set to the last address used
- * @param[out] address_attempts_left set to number of address changing attempts left for this address
- * @param[out] pin_transmissions_left set to number of times the PIN can still be re-requested
- * @param[out] auth_attempts_left set to number of authentication attempts remaining
- * @param[out] solved set to true if the challenge is already solved
- * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a last_address; 0 if never sent
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the validation exists and the
- * OAuth2 scope/state/redirect/PKCE parameters were recorded
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no validation matches @a nonce and
- * @a client_id, or the supplied @a client_redirect_uri does not match the
- * redirect URI registered for the client
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_authorize_start (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint64_t client_id,
- const char *client_scope,
- const char *client_state,
- const char *client_redirect_uri,
- const char *code_challenge,
- uint32_t code_challenge_method,
- json_t **last_address,
- uint32_t *address_attempts_left,
- uint32_t *pin_transmissions_left,
- uint32_t *auth_attempts_left,
- bool *solved,
- struct GNUNET_TIME_Absolute *last_tx_time);
-
-
-#endif
diff --git a/src/include/challenger-database/challenge_set_address_and_pin.h b/src/include/challenger-database/challenge_set_address_and_pin.h
@@ -1,71 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/challenge_set_address_and_pin.h
- * @brief implementation of the challenge_set_address_and_pin function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_CHALLENGE_SET_ADDRESS_AND_PIN_H
-#define CHALLENGER_DATABASE_CHALLENGE_SET_ADDRESS_AND_PIN_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Set the user-provided address in a validation process. Updates
- * the address and decrements the "addresses left" counter. If the
- * address did not change, the operation is successful even without
- * the counter change.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param address the new address to validate
- * @param retransmission_frequency minimum time that must have passed since the
- * last transmission before the PIN is (re)transmitted to @a address again
- * @param[in,out] tan set to the PIN/TAN last send to @a address, input should be random PIN/TAN to use if address did not change
- * @param[out] state set to client's OAuth2 state if available
- * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a address
- * @param[out] pin_transmit set to true if we should transmit the @a last_pin to the @a address
- * @param[out] auth_attempts_left set to number of attempts the user has left on this pin
- * @param[out] client_redirect_uri redirection URI of the client (for reporting failures)
- * @param[out] address_refused set to true if the address was refused (address change attempts exhausted)
- * @param[out] solved set to true if the challenge is already solved
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the validation @a nonce exists
- * (inspect @a address_refused / @a solved / @a pin_transmit for the actual
- * outcome)
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the validation @a nonce is unknown
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_challenge_set_address_and_pin (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- const json_t *address,
- struct GNUNET_TIME_Relative retransmission_frequency,
- uint32_t *tan,
- char **state,
- struct GNUNET_TIME_Absolute *last_tx_time,
- uint32_t *auth_attempts_left,
- bool *pin_transmit,
- char **client_redirect_uri,
- bool *address_refused,
- bool *solved);
-
-#endif
diff --git a/src/include/challenger-database/client_add.h b/src/include/challenger-database/client_add.h
@@ -1,49 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/client_add.h
- * @brief implementation of the client_add function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_CLIENT_ADD_H
-#define CHALLENGER_DATABASE_CLIENT_ADD_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-
-struct CHALLENGERDB_PostgresContext;
-/**
- * Add client to the list of authorized clients.
- *
- * @param cls
- * @param client_url URL of the client
- * @param client_secret authorization secret for the client
- * @param[out] client_id set to the client ID on success; left at 0 if the
- * client already exists (duplicate URI: ON CONFLICT DO NOTHING)
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the client was added
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if a client with this URI already
- * exists (nothing inserted, @a client_id left 0)
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_add (struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_url,
- const char *client_secret,
- uint64_t *client_id);
-
-
-#endif
diff --git a/src/include/challenger-database/client_check.h b/src/include/challenger-database/client_check.h
@@ -1,67 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/client_check.h
- * @brief implementation of the client_check function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_CLIENT_CHECK_H
-#define CHALLENGER_DATABASE_CLIENT_CHECK_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Check if a client is in the list of authorized clients. If @a
- * counter_increment is non-zero, the validation counter of the
- * client is incremented by the given value if the client was found.
- *
- * @param cls
- * @param client_id unique row of the client
- * @param client_secret secret of the client
- * @param counter_increment change in validation counter
- * @param[out] client_url set to URL of the client (if any)
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_check (
- struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const char *client_secret,
- uint32_t counter_increment,
- char **client_url);
-
-
-/**
- * Check if a client is in the list of authorized clients.
- *
- * @param cls
- * @param client_url client redirect URL (if known)
- * @param client_secret secret of the client
- * @param[out] client_id set to the ID of the client if found
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_check2 (
- struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_url,
- const char *client_secret,
- uint64_t *client_id);
-
-#endif
diff --git a/src/include/challenger-database/client_delete.h b/src/include/challenger-database/client_delete.h
@@ -1,39 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/client_delete.h
- * @brief implementation of the client_delete function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_CLIENT_DELETE_H
-#define CHALLENGER_DATABASE_CLIENT_DELETE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-
-struct CHALLENGERDB_PostgresContext;
-/**
- * Delete client from the list of authorized clients.
- *
- * @param cls
- * @param client_url URL of the client
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_delete (struct CHALLENGERDB_PostgresContext *ctx,
- const char *client_url);
-
-#endif
diff --git a/src/include/challenger-database/client_modify.h b/src/include/challenger-database/client_modify.h
@@ -1,44 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2024 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/client_modify.h
- * @brief implementation of the client_modify function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_CLIENT_MODIFY_H
-#define CHALLENGER_DATABASE_CLIENT_MODIFY_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-
-struct CHALLENGERDB_PostgresContext;
-/**
- * Modify client to the list of authorized clients.
- *
- * @param cls
- * @param client_id the client ID on success
- * @param client_url URL of the client
- * @param client_secret authorization secret for the client, NULL to not modify the secret
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_client_modify (struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const char *client_url,
- const char *client_secret);
-
-
-#endif
diff --git a/src/include/challenger-database/delete_client.h b/src/include/challenger-database/delete_client.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/delete_client.h
+ * @brief implementation of the delete_client function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_DELETE_CLIENT_H
+#define CHALLENGER_DATABASE_DELETE_CLIENT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+
+struct CHALLENGERDB_PostgresContext;
+/**
+ * Delete client from the list of authorized clients.
+ *
+ * @param cls
+ * @param client_url URL of the client
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_delete_client (struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_url);
+
+#endif
diff --git a/src/include/challenger-database/do_challenge_address.h b/src/include/challenger-database/do_challenge_address.h
@@ -0,0 +1,71 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/do_challenge_address.h
+ * @brief implementation of the do_challenge_address function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_DO_CHALLENGE_ADDRESS_H
+#define CHALLENGER_DATABASE_DO_CHALLENGE_ADDRESS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Set the user-provided address in a validation process. Updates
+ * the address and decrements the "addresses left" counter. If the
+ * address did not change, the operation is successful even without
+ * the counter change.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param address the new address to validate
+ * @param retransmission_frequency minimum time that must have passed since the
+ * last transmission before the PIN is (re)transmitted to @a address again
+ * @param[in,out] tan set to the PIN/TAN last send to @a address, input should be random PIN/TAN to use if address did not change
+ * @param[out] state set to client's OAuth2 state if available
+ * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a address
+ * @param[out] pin_transmit set to true if we should transmit the @a last_pin to the @a address
+ * @param[out] auth_attempts_left set to number of attempts the user has left on this pin
+ * @param[out] client_redirect_uri redirection URI of the client (for reporting failures)
+ * @param[out] address_refused set to true if the address was refused (address change attempts exhausted)
+ * @param[out] solved set to true if the challenge is already solved
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the validation @a nonce exists
+ * (inspect @a address_refused / @a solved / @a pin_transmit for the actual
+ * outcome)
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the validation @a nonce is unknown
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_challenge_address (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ const json_t *address,
+ struct GNUNET_TIME_Relative retransmission_frequency,
+ uint32_t *tan,
+ char **state,
+ struct GNUNET_TIME_Absolute *last_tx_time,
+ uint32_t *auth_attempts_left,
+ bool *pin_transmit,
+ char **client_redirect_uri,
+ bool *address_refused,
+ bool *solved);
+
+#endif
diff --git a/src/include/challenger-database/do_insert_token.h b/src/include/challenger-database/do_insert_token.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/do_insert_token.h
+ * @brief implementation of the do_insert_token function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_DO_INSERT_TOKEN_H
+#define CHALLENGER_DATABASE_DO_INSERT_TOKEN_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Add access @a grant to address under @a nonce.
+ *
+ * @param cls closure
+ * @param nonce validation process to grant access to
+ * @param grant grant token that grants access
+ * @param grant_expiration for how long should the grant be valid
+ * @param address_expiration for how long after validation do we consider addresses to be valid
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_insert_token (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ const struct CHALLENGER_AccessTokenP *grant,
+ struct GNUNET_TIME_Relative grant_expiration,
+ struct GNUNET_TIME_Relative address_expiration);
+
+
+#endif
diff --git a/src/include/challenger-database/do_insert_validation.h b/src/include/challenger-database/do_insert_validation.h
@@ -0,0 +1,59 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/do_insert_validation.h
+ * @brief implementation of the do_insert_validation function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_DO_INSERT_VALIDATION_H
+#define CHALLENGER_DATABASE_DO_INSERT_VALIDATION_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Start validation process by setting up a validation entry. Allows
+ * the respective user who learns the @a nonce to later begin the
+ * process.
+ *
+ * Authenticates the client against @a client_secret and charges it for
+ * the validation (by incrementing @e validation_counter) in the same
+ * statement that inserts the row, so the counter moves if and only if
+ * the validation was actually created.
+ *
+ * @param ctx database context
+ * @param client_id ID of the client
+ * @param client_secret secret of the client
+ * @param nonce unique nonce to use to identify the validation
+ * @param expiration_time when will the validation expire
+ * @param initial_address address the user should validate,
+ * NULL if the user should enter it themselves
+ * @return transaction status, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if
+ * there is no such client or @a client_secret does not match
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_insert_validation (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_secret,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ struct GNUNET_TIME_Absolute expiration_time,
+ const json_t *initial_address);
+
+#endif
diff --git a/src/include/challenger-database/do_solve_challenge.h b/src/include/challenger-database/do_solve_challenge.h
@@ -0,0 +1,67 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/do_solve_challenge.h
+ * @brief implementation of the do_solve_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_DO_SOLVE_CHALLENGE_H
+#define CHALLENGER_DATABASE_DO_SOLVE_CHALLENGE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Check PIN entered to validate an address.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param new_pin the PIN the user entered
+ * @param[out] solved set to true if the PIN was correct
+ * @param[out] exhausted set to true if the number of attempts to enter the correct PIN was exhausted before this call and @a new_pin was not evaluated
+ * @param[out] no_challenge set to true if we never even issued a challenge
+ * @param[out] state set to client's OAuth2 state if available
+ * @param[out] addr_left set to number of address changes remaining
+ * @param[out] auth_attempts_left set to number of authentication attempts
+ * remaining; only meaningful when @a solved is false (on the solved
+ * path the stored procedure uses a -1 sentinel, which is normalized
+ * to 0 here)
+ * @param[out] pin_transmissions_left set to number of times the PIN can still be re-requested
+ * @param[out] client_redirect_uri set to OAuth2 client redirect URI
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_do_solve_challenge (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint32_t new_pin,
+ bool *solved,
+ bool *exhausted,
+ bool *no_challenge,
+ char **state,
+ uint32_t *addr_left,
+ uint32_t *auth_attempts_left,
+ uint32_t *pin_transmissions_left,
+ char **client_redirect_uri);
+
+
+#endif
diff --git a/src/include/challenger-database/get_client.h b/src/include/challenger-database/get_client.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_client.h
+ * @brief implementation of the get_client function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_GET_CLIENT_H
+#define CHALLENGER_DATABASE_GET_CLIENT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Look up the client with row @a client_id, authenticating it against
+ * @a client_secret, and return its redirect URI. Pure read; callers
+ * that must also charge the client for the lookup use
+ * #CHALLENGERDB_do_insert_validation(), which authenticates and bumps
+ * the validation counter in the same statement.
+ *
+ * @param ctx database context
+ * @param client_id unique row of the client
+ * @param client_secret secret of the client
+ * @param[out] client_url set to URL of the client (if any)
+ * @return transaction status, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if
+ * there is no such client or @a client_secret does not match
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_client (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_secret,
+ char **client_url);
+
+#endif
diff --git a/src/include/challenger-database/get_client_by_uri.h b/src/include/challenger-database/get_client_by_uri.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_client_by_uri.h
+ * @brief implementation of the get_client_by_uri function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_GET_CLIENT_BY_URI_H
+#define CHALLENGER_DATABASE_GET_CLIENT_BY_URI_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Look up the client authorized under the given redirect URI
+ * and secret. Read-only.
+ *
+ * @param cls
+ * @param client_url client redirect URL (if known)
+ * @param client_secret secret of the client
+ * @param[out] client_id set to the ID of the client if found
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_client_by_uri (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_url,
+ const char *client_secret,
+ uint64_t *client_id);
+
+#endif
diff --git a/src/include/challenger-database/get_token.h b/src/include/challenger-database/get_token.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_token.h
+ * @brief implementation of the get_token function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_GET_TOKEN_H
+#define CHALLENGER_DATABASE_GET_TOKEN_H
+
+#include <taler/taler_util.h>
+#include <jansson.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Return @a address which @a grant gives access to.
+ *
+ * @param cls closure
+ * @param grant grant token that grants access
+ * @param[out] rowid account identifier within challenger
+ * @param[out] address set to the address under @a grant
+ * @param[out] address_expiration set to how long we consider @a address to be valid
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_token (struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_AccessTokenP *grant,
+ uint64_t *rowid,
+ json_t **address,
+ struct GNUNET_TIME_Timestamp *address_expiration);
+
+
+#endif
diff --git a/src/include/challenger-database/get_validation.h b/src/include/challenger-database/get_validation.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_validation.h
+ * @brief implementation of the get_validation function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_GET_VALIDATION_H
+#define CHALLENGER_DATABASE_GET_VALIDATION_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Return validation details. Used by ``/solve``, ``/auth`` and
+ * ``/info`` endpoints to authorize and return validated user
+ * address to the client.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param[out] client_secret set to secret of client (for client that setup the challenge)
+ * @param[out] address set to client-provided address
+ * @param[out] client_scope set to OAuth2 scope
+ * @param[out] client_state set to client state
+ * @param[out] client_redirect_uri set to client redirect URL
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ char **client_secret,
+ json_t **address,
+ char **client_scope,
+ char **client_state,
+ char **client_redirect_uri);
+
+#endif
diff --git a/src/include/challenger-database/get_validation_address.h b/src/include/challenger-database/get_validation_address.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2025 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_validation_address.h
+ * @brief implementation of the get_validation_address function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_GET_VALIDATION_ADDRESS_H
+#define CHALLENGER_DATABASE_GET_VALIDATION_ADDRESS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Return address details.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param[out] address set to client-provided address (or to NULL)
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation_address (struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *
+ nonce,
+ json_t **address);
+
+#endif
diff --git a/src/include/challenger-database/get_validation_pkce.h b/src/include/challenger-database/get_validation_pkce.h
@@ -0,0 +1,64 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/get_validation_pkce.h
+ * @brief implementation of the get_validation_pkce function for Postgres
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#ifndef CHALLENGER_DATABASE_GET_VALIDATION_PKCE_H
+#define CHALLENGER_DATABASE_GET_VALIDATION_PKCE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Return validation details. Used by ``/solve``, ``/auth`` and
+ * ``/info`` endpoints to authorize and return validated user
+ * address to the client.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param client_id serial id of the authenticated client redeeming the code
+ * @param[out] client_secret set to secret of client (for client that setup the challenge)
+ * @param[out] address set to client-provided address
+ * @param[out] client_scope set to OAuth2 scope
+ * @param[out] client_state set to client state
+ * @param[out] client_redirect_uri set to client redirect URL
+ * @param[out] code_challenge set to PKCE code challenge
+ * @param[out] code_challenge_method set to PKCE code challenge method enum
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_get_validation_pkce (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint64_t client_id,
+ char **client_secret,
+ json_t **address,
+ char **client_scope,
+ char **client_state,
+ char **client_redirect_uri,
+ char **code_challenge,
+ uint32_t *code_challenge_method);
+
+#endif
diff --git a/src/include/challenger-database/info_get_token.h b/src/include/challenger-database/info_get_token.h
@@ -1,48 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/info_get_token.h
- * @brief implementation of the info_get_token function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_INFO_GET_TOKEN_H
-#define CHALLENGER_DATABASE_INFO_GET_TOKEN_H
-
-#include <taler/taler_util.h>
-#include <jansson.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Return @a address which @a grant gives access to.
- *
- * @param cls closure
- * @param grant grant token that grants access
- * @param[out] rowid account identifier within challenger
- * @param[out] address set to the address under @a grant
- * @param[out] address_expiration set to how long we consider @a address to be valid
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_info_get_token (struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_AccessTokenP *grant,
- uint64_t *rowid,
- json_t **address,
- struct GNUNET_TIME_Timestamp *address_expiration);
-
-
-#endif
diff --git a/src/include/challenger-database/insert_client.h b/src/include/challenger-database/insert_client.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/insert_client.h
+ * @brief implementation of the insert_client function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_INSERT_CLIENT_H
+#define CHALLENGER_DATABASE_INSERT_CLIENT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+
+struct CHALLENGERDB_PostgresContext;
+/**
+ * Add client to the list of authorized clients.
+ *
+ * @param cls
+ * @param client_url URL of the client
+ * @param client_secret authorization secret for the client
+ * @param[out] client_id set to the client ID on success; left at 0 if the
+ * client already exists (duplicate URI: ON CONFLICT DO NOTHING)
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the client was added
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if a client with this URI already
+ * exists (nothing inserted, @a client_id left 0)
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_insert_client (struct CHALLENGERDB_PostgresContext *ctx,
+ const char *client_url,
+ const char *client_secret,
+ uint64_t *client_id);
+
+
+#endif
diff --git a/src/include/challenger-database/setup_nonce.h b/src/include/challenger-database/setup_nonce.h
@@ -1,51 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/setup_nonce.h
- * @brief implementation of the validation_setup function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_SETUP_NONCE_H
-#define CHALLENGER_DATABASE_SETUP_NONCE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Start validation process by setting up a validation entry. Allows
- * the respective user who learns the @a nonce to later begin the
- * process.
- *
- * @param cls closure
- * @param client_id ID of the client
- * @param nonce unique nonce to use to identify the validation
- * @param expiration_time when will the validation expire
- * @param initial_address address the user should validate,
- * NULL if the user should enter it themselves
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_setup_nonce (
- struct CHALLENGERDB_PostgresContext *ctx,
- uint64_t client_id,
- const struct CHALLENGER_ValidationNonceP *nonce,
- struct GNUNET_TIME_Absolute expiration_time,
- const json_t *initial_address);
-
-#endif
diff --git a/src/include/challenger-database/token_add_token.h b/src/include/challenger-database/token_add_token.h
@@ -1,49 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/token_add_token.h
- * @brief implementation of the token_add_token function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_TOKEN_ADD_TOKEN_H
-#define CHALLENGER_DATABASE_TOKEN_ADD_TOKEN_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Add access @a grant to address under @a nonce.
- *
- * @param cls closure
- * @param nonce validation process to grant access to
- * @param grant grant token that grants access
- * @param grant_expiration for how long should the grant be valid
- * @param address_expiration for how long after validation do we consider addresses to be valid
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_token_add_token (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- const struct CHALLENGER_AccessTokenP *grant,
- struct GNUNET_TIME_Relative grant_expiration,
- struct GNUNET_TIME_Relative address_expiration);
-
-
-#endif
diff --git a/src/include/challenger-database/update_client.h b/src/include/challenger-database/update_client.h
@@ -0,0 +1,44 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2024 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/update_client.h
+ * @brief implementation of the update_client function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef CHALLENGER_DATABASE_UPDATE_CLIENT_H
+#define CHALLENGER_DATABASE_UPDATE_CLIENT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+
+struct CHALLENGERDB_PostgresContext;
+/**
+ * Modify client to the list of authorized clients.
+ *
+ * @param cls
+ * @param client_id the client ID on success
+ * @param client_url URL of the client
+ * @param client_secret authorization secret for the client, NULL to not modify the secret
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_update_client (struct CHALLENGERDB_PostgresContext *ctx,
+ uint64_t client_id,
+ const char *client_url,
+ const char *client_secret);
+
+
+#endif
diff --git a/src/include/challenger-database/update_validation.h b/src/include/challenger-database/update_validation.h
@@ -0,0 +1,79 @@
+/*
+ This file is part of Challenger
+ Copyright (C) 2023 Taler Systems SA
+
+ Challenger 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/challenger-database/update_validation.h
+ * @brief implementation of the update_validation function for Postgres
+ * @author Christian Grothoff
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#ifndef CHALLENGER_DATABASE_UPDATE_VALIDATION_H
+#define CHALLENGER_DATABASE_UPDATE_VALIDATION_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "challenger_util.h"
+#include "challenger_database_lib.h"
+
+
+/**
+ * Begin the authorization phase of a validation: record the client's OAuth2
+ * scope, state, redirect URI and PKCE code challenge on the validation
+ * identified by @a nonce, and return the current status (last address,
+ * remaining attempt counters, whether it is already solved). Succeeds only if
+ * the supplied @a client_redirect_uri matches the one registered for the client.
+ *
+ * @param cls
+ * @param nonce unique nonce to use to identify the validation
+ * @param client_id client that initiated the validation
+ * @param client_scope scope of the validation
+ * @param client_state state of the client
+ * @param client_redirect_uri where to redirect at the end, NULL to use a unique one registered for the client
+ * @param code_challenge PKCE code challenge
+ * @param code_challenge_method PKCE code challenge method enum
+ * @param[out] last_address set to the last address used
+ * @param[out] address_attempts_left set to number of address changing attempts left for this address
+ * @param[out] pin_transmissions_left set to number of times the PIN can still be re-requested
+ * @param[out] auth_attempts_left set to number of authentication attempts remaining
+ * @param[out] solved set to true if the challenge is already solved
+ * @param[out] last_tx_time set to the last time when we (presumably) send a PIN to @a last_address; 0 if never sent
+ * @return transaction status:
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the validation exists and the
+ * OAuth2 scope/state/redirect/PKCE parameters were recorded
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no validation matches @a nonce and
+ * @a client_id, or the supplied @a client_redirect_uri does not match the
+ * redirect URI registered for the client
+ * #GNUNET_DB_STATUS_HARD_ERROR on failure
+ */
+enum GNUNET_DB_QueryStatus
+CHALLENGERDB_update_validation (
+ struct CHALLENGERDB_PostgresContext *ctx,
+ const struct CHALLENGER_ValidationNonceP *nonce,
+ uint64_t client_id,
+ const char *client_scope,
+ const char *client_state,
+ const char *client_redirect_uri,
+ const char *code_challenge,
+ uint32_t code_challenge_method,
+ json_t **last_address,
+ uint32_t *address_attempts_left,
+ uint32_t *pin_transmissions_left,
+ uint32_t *auth_attempts_left,
+ bool *solved,
+ struct GNUNET_TIME_Absolute *last_tx_time);
+
+
+#endif
diff --git a/src/include/challenger-database/validate_solve_pin.h b/src/include/challenger-database/validate_solve_pin.h
@@ -1,67 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/validate_solve_pin.h
- * @brief implementation of the validate_solve_pin function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_VALIDATE_SOLVE_PIN_H
-#define CHALLENGER_DATABASE_VALIDATE_SOLVE_PIN_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Check PIN entered to validate an address.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param new_pin the PIN the user entered
- * @param[out] solved set to true if the PIN was correct
- * @param[out] exhausted set to true if the number of attempts to enter the correct PIN was exhausted before this call and @a new_pin was not evaluated
- * @param[out] no_challenge set to true if we never even issued a challenge
- * @param[out] state set to client's OAuth2 state if available
- * @param[out] addr_left set to number of address changes remaining
- * @param[out] auth_attempts_left set to number of authentication attempts
- * remaining; only meaningful when @a solved is false (on the solved
- * path the stored procedure uses a -1 sentinel, which is normalized
- * to 0 here)
- * @param[out] pin_transmissions_left set to number of times the PIN can still be re-requested
- * @param[out] client_redirect_uri set to OAuth2 client redirect URI
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validate_solve_pin (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint32_t new_pin,
- bool *solved,
- bool *exhausted,
- bool *no_challenge,
- char **state,
- uint32_t *addr_left,
- uint32_t *auth_attempts_left,
- uint32_t *pin_transmissions_left,
- char **client_redirect_uri);
-
-
-#endif
diff --git a/src/include/challenger-database/validation_get.h b/src/include/challenger-database/validation_get.h
@@ -1,57 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/validation_get.h
- * @brief implementation of the validation_get function for Postgres
- * @author Christian Grothoff
- */
-#ifndef CHALLENGER_DATABASE_VALIDATION_GET_H
-#define CHALLENGER_DATABASE_VALIDATION_GET_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Return validation details. Used by ``/solve``, ``/auth`` and
- * ``/info`` endpoints to authorize and return validated user
- * address to the client.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param[out] client_secret set to secret of client (for client that setup the challenge)
- * @param[out] address set to client-provided address
- * @param[out] client_scope set to OAuth2 scope
- * @param[out] client_state set to client state
- * @param[out] client_redirect_uri set to client redirect URL
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validation_get (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- char **client_secret,
- json_t **address,
- char **client_scope,
- char **client_state,
- char **client_redirect_uri);
-
-#endif
diff --git a/src/include/challenger-database/validation_get_pkce.h b/src/include/challenger-database/validation_get_pkce.h
@@ -1,64 +0,0 @@
-/*
- This file is part of Challenger
- Copyright (C) 2023 Taler Systems SA
-
- Challenger 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
- Foundation; either version 3, or (at your option) any later version.
-
- Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/challenger-database/validation_get_pkce.h
- * @brief implementation of the validation_get_pkce function for Postgres
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#ifndef CHALLENGER_DATABASE_VALIDATION_GET_PKCE_H
-#define CHALLENGER_DATABASE_VALIDATION_GET_PKCE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "challenger_util.h"
-#include "challenger_database_lib.h"
-
-
-/**
- * Return validation details. Used by ``/solve``, ``/auth`` and
- * ``/info`` endpoints to authorize and return validated user
- * address to the client.
- *
- * @param cls
- * @param nonce unique nonce to use to identify the validation
- * @param client_id serial id of the authenticated client redeeming the code
- * @param[out] client_secret set to secret of client (for client that setup the challenge)
- * @param[out] address set to client-provided address
- * @param[out] client_scope set to OAuth2 scope
- * @param[out] client_state set to client state
- * @param[out] client_redirect_uri set to client redirect URL
- * @param[out] code_challenge set to PKCE code challenge
- * @param[out] code_challenge_method set to PKCE code challenge method enum
- * @return transaction status:
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the nonce was found
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we do not know the nonce
- * #GNUNET_DB_STATUS_HARD_ERROR on failure
- */
-enum GNUNET_DB_QueryStatus
-CHALLENGERDB_validation_get_pkce (
- struct CHALLENGERDB_PostgresContext *ctx,
- const struct CHALLENGER_ValidationNonceP *nonce,
- uint64_t client_id,
- char **client_secret,
- json_t **address,
- char **client_scope,
- char **client_state,
- char **client_redirect_uri,
- char **code_challenge,
- uint32_t *code_challenge_method);
-
-#endif