public inbox for [email protected]
help / color / mirror / Atom feedFrom: Jonathan Gonzalez V. <[email protected]>
To: Zsolt Parragi <[email protected]>
Cc: Daniel Gustafsson <[email protected]>
Cc: Jacob Champion <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: Make PGOAUTHCAFILE in libpq-oauth work out of debug mode
Date: Tue, 17 Mar 2026 22:37:39 +0100
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAN4CZFPYyC5Y44ux_Egxj5j43R1tdtuz_PGqkaz3ngUQnRwSYQ@mail.gmail.com>
References: <[email protected]>
<[email protected]>
<CAOYmi+=fbZNJSkHVci=GpR8XPYObK=H+2ERRha0LDTS+ifsWnw@mail.gmail.com>
<CAN4CZFPhm2NCRWzZpX=kRLqyxu4Ps-d0xE5W75a-iDoKrLbXBw@mail.gmail.com>
<CAOYmi+=HcXJub1rDsQ7vpKMHuBB6NTA2Z5T=zAkaFdRThf+9zg@mail.gmail.com>
<[email protected]>
<CAOYmi+mMx1DnNpKG8RdknH0-GuPR9jv+G9r2iFND=Yve7DOF6g@mail.gmail.com>
<[email protected]>
<CAOYmi+nQawWHzC4mRhJnzZzzqjnUDg-yxN3f3ZqPX=+jpKU+zg@mail.gmail.com>
<[email protected]>
<CAOYmi+mTHahYXqBZH-bE1Z3Yc5SJ0gTHsM69LSVna2h7ftgVzQ@mail.gmail.com>
<[email protected]>
<CAOYmi+kNGJXy3YqPDoceb1doNfA-S6fmdKv-AH3j0PPUicyUQQ@mail.gmail.com>
<[email protected]>
<[email protected]>
<[email protected]>
<CAN4CZFMtcRDBQACw==1aHRBmdQDWNz=v4RqY0--iF=G6QfiQ3A@mail.gmail.com>
<[email protected]>
<CAN4CZFPYyC5Y44ux_Egxj5j43R1tdtuz_PGqkaz3ngUQnRwSYQ@mail.gmail.com>
Hello!!
On Tue, 2026-03-17 at 06:41 +0000, Zsolt Parragi wrote:
> Hello
>
> These variables are still not freed, I am missing something why it
> isn't required?
>
> + char *oauth_ca_file; /* CA file path */
>
> Shouldn't we free this in freePGconn?
>
>
> + char *ca_file; /* oauth_ca_file */
>
> Similarly with free_async_ctx?
I totally miss this comments, and I had it noted
Attaching v5
--
Jonathan Gonzalez V.
EDB: https://www.enterprisedb.com
Attachments:
[text/x-patch] v5-0001-libpq-oauth-allow-changing-the-CA-when-not-in-deb.patch (8.6K, 2-v5-0001-libpq-oauth-allow-changing-the-CA-when-not-in-deb.patch)
download | inline diff:
From a27875e770b9f74481cf839b168ea187e040d279 Mon Sep 17 00:00:00 2001
From: "Jonathan Gonzalez V." <[email protected]>
Date: Wed, 29 Oct 2025 16:54:42 +0100
Subject: [PATCH v5 1/1] libpq-oauth: allow changing the CA when not in debug
mode
Allowing to set a CA enables users environment like companies with
internal CA or developers working on their own local system while
using a self-signed CA and don't need to see all the debug messages
while testing inside an internal environment.
Reviewed-by: Zsolt Parragi <zsolt,[email protected]>
Signed-off-by: Jonathan Gonzalez V. <[email protected]>
---
doc/src/sgml/libpq.sgml | 23 ++++++++---
src/interfaces/libpq-oauth/oauth-curl.c | 27 +++++++------
src/interfaces/libpq/fe-connect.c | 5 +++
src/interfaces/libpq/libpq-int.h | 1 +
.../modules/oauth_validator/t/001_server.pl | 40 ++++++++++++++++++-
.../modules/oauth_validator/t/OAuth/Server.pm | 2 +-
6 files changed, 76 insertions(+), 22 deletions(-)
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 6db823808fc..24fda826dd1 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -10620,12 +10620,6 @@ typedef struct
permits the use of unencrypted HTTP during the OAuth provider exchange
</para>
</listitem>
- <listitem>
- <para>
- allows the system's trusted CA list to be completely replaced using the
- <envar>PGOAUTHCAFILE</envar> environment variable
- </para>
- </listitem>
<listitem>
<para>
prints HTTP traffic (containing several critical secrets) to standard
@@ -10647,6 +10641,23 @@ typedef struct
</para>
</warning>
</sect2>
+ <sect2 id="libpq-oauth-environment">
+ <title>Environment variables</title>
+ <para>
+ The behavior of the OAuth calls may be affected by the following variables:
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGOAUTHCAFILE</envar></term>
+ <listitem>
+ <para>
+ Allows to specify the path to a CA file that will be used by the client
+ to verify the certificate from the OAuth server side.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
</sect1>
diff --git a/src/interfaces/libpq-oauth/oauth-curl.c b/src/interfaces/libpq-oauth/oauth-curl.c
index 052ecd32da2..561875d6db1 100644
--- a/src/interfaces/libpq-oauth/oauth-curl.c
+++ b/src/interfaces/libpq-oauth/oauth-curl.c
@@ -17,6 +17,7 @@
#include <curl/curl.h>
#include <math.h>
+#include <string.h>
#include <unistd.h>
#if defined(HAVE_SYS_EPOLL_H)
@@ -216,6 +217,7 @@ struct async_ctx
/* relevant connection options cached from the PGconn */
char *client_id; /* oauth_client_id */
char *client_secret; /* oauth_client_secret (may be NULL) */
+ char *ca_file; /* oauth_ca_file */
/* options cached from the PGoauthBearerRequest (we don't own these) */
const char *discovery_uri;
@@ -336,6 +338,7 @@ free_async_ctx(struct async_ctx *actx)
free(actx->client_id);
free(actx->client_secret);
+ free(actx->ca_file);
free(actx);
}
@@ -1834,20 +1837,12 @@ setup_curl_handles(struct async_ctx *actx)
}
/*
- * If we're in debug mode, allow the developer to change the trusted CA
- * list. For now, this is not something we expose outside of the UNSAFE
- * mode, because it's not clear that it's useful in production: both libpq
- * and the user's browser must trust the same authorization servers for
- * the flow to work at all, so any changes to the roots are likely to be
- * done system-wide.
+ * Allow to set the CA even if we're not in debug mode, this would make it
+ * easy to work on environments where the CA could be internal and
+ * available on every system, like big companies with airgap systems.
*/
- if (actx->debugging)
- {
- const char *env;
-
- if ((env = getenv("PGOAUTHCAFILE")) != NULL)
- CHECK_SETOPT(actx, CURLOPT_CAINFO, env, return false);
- }
+ if (actx->ca_file != NULL)
+ CHECK_SETOPT(actx, CURLOPT_CAINFO, actx->ca_file, return false);
/*
* Suppress the Accept header to make our request as minimal as possible.
@@ -3125,6 +3120,12 @@ pg_start_oauthbearer(PGconn *conn, PGoauthBearerRequestV2 *request)
if (!actx->client_secret)
goto oom;
}
+ else if (strcmp(opt->keyword, "oauth_ca_file") == 0)
+ {
+ actx->ca_file = strdup(opt->val);
+ if (!actx->ca_file)
+ goto oom;
+ }
}
PQconninfoFree(conninfo);
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index db9b4c8edbf..4f3af722881 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -413,6 +413,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"OAuth-Scope", "", 15,
offsetof(struct pg_conn, oauth_scope)},
+ {"oauth_ca_file", "PGOAUTHCAFILE", NULL, NULL,
+ "OAuth-CA-File", "", 64,
+ offsetof(struct pg_conn, oauth_ca_file)},
+
{"sslkeylogfile", NULL, NULL, NULL,
"SSL-Key-Log-File", "D", 64,
offsetof(struct pg_conn, sslkeylogfile)},
@@ -5158,6 +5162,7 @@ freePGconn(PGconn *conn)
free(conn->oauth_discovery_uri);
free(conn->oauth_client_id);
free(conn->oauth_client_secret);
+ free(conn->oauth_ca_file);
free(conn->oauth_scope);
/* Note that conn->Pfdebug is not ours to close or free */
free(conn->events);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index bd7eb59f5f8..1f1fb89e02f 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -444,6 +444,7 @@ struct pg_conn
char *oauth_client_secret; /* client secret */
char *oauth_scope; /* access token scope */
char *oauth_token; /* access token */
+ char *oauth_ca_file; /* CA file path */
bool oauth_want_retry; /* should we retry on failure? */
/* Optional file to write trace info to */
diff --git a/src/test/modules/oauth_validator/t/001_server.pl b/src/test/modules/oauth_validator/t/001_server.pl
index cdad2ae8011..b66d99dd4bb 100644
--- a/src/test/modules/oauth_validator/t/001_server.pl
+++ b/src/test/modules/oauth_validator/t/001_server.pl
@@ -137,10 +137,46 @@ $node->connect_fails(
expected_stderr =>
qr/failed to fetch OpenID discovery document:.*peer certificate/i);
-# Now we can use our alternative CA.
-$ENV{PGOAUTHCAFILE} = "$ENV{cert_dir}/root+server_ca.crt";
+# Make sure that PGOAUTHDEBUG is not required to specify the certificate
+delete $ENV{PGOAUTHDEBUG};
+# The alternative CA path to use during the tests
+my $alternative_ca = "$ENV{cert_dir}/root+server_ca.crt";
+
+# Make sure we can use oauth_ca_file option to specify the alternative CA path
my $user = "test";
+$node->connect_ok(
+ "user=$user dbname=postgres oauth_issuer=$issuer oauth_client_id=f02c6361-0635 oauth_ca_file=$alternative_ca",
+ "connect as test",
+ expected_stderr =>
+ qr@Visit https://example\.com/ and enter the code: postgresuser@,
+ log_like => [
+ qr/oauth_validator: token="9243959234", role="$user"/,
+ qr/oauth_validator: issuer="\Q$issuer\E", scope="openid postgres"/,
+ qr/connection authenticated: identity="test" method=oauth/,
+ qr/connection authorized/,
+ ]);
+
+# Make sure that we can use the environment variable without the PGOAUTHDEBUG
+# and use it for the rest of the tests
+$ENV{PGOAUTHCAFILE} = $alternative_ca;
+
+$node->connect_ok(
+ "user=$user dbname=postgres oauth_issuer=$issuer oauth_client_id=f02c6361-0635",
+ "connect as test",
+ expected_stderr =>
+ qr@Visit https://example\.com/ and enter the code: postgresuser@,
+ log_like => [
+ qr/oauth_validator: token="9243959234", role="$user"/,
+ qr/oauth_validator: issuer="\Q$issuer\E", scope="openid postgres"/,
+ qr/connection authenticated: identity="test" method=oauth/,
+ qr/connection authorized/,
+ ]);
+
+# Enable PGOAUTHDEBUG=UNSAFE to have the proper count later with the `[libpq] total number of polls` messages
+$ENV{PGOAUTHDEBUG} = "UNSAFE";
+
+$user = "test";
$node->connect_ok(
"user=$user dbname=postgres oauth_issuer=$issuer oauth_client_id=f02c6361-0635",
"connect as test",
diff --git a/src/test/modules/oauth_validator/t/OAuth/Server.pm b/src/test/modules/oauth_validator/t/OAuth/Server.pm
index d923d4c5eb2..62a29c283df 100644
--- a/src/test/modules/oauth_validator/t/OAuth/Server.pm
+++ b/src/test/modules/oauth_validator/t/OAuth/Server.pm
@@ -28,7 +28,7 @@ daemon implemented in t/oauth_server.py. (Python has a fairly usable HTTP server
in its standard library, so the implementation was ported from Perl.)
This authorization server serves HTTPS on 127.0.0.1 (IPv4 only). libpq will need
-to set PGOAUTHDEBUG=UNSAFE and PGOAUTHCAFILE with the right CA.
+to set PGOAUTHCAFILE with the right CA.
=cut
--
2.51.0
[application/pgp-signature] signature.asc (833B, 3-signature.asc)
download
view thread (31+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Subject: Re: Make PGOAUTHCAFILE in libpq-oauth work out of debug mode
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox