Hello! > > Right -- I hadn't meant that you should remove the PGOAUTHCAFILE > envvar from your patch, just that an oauth_ca_file parameter should > be > added as well. > >
I'm attached a v2 of this patch I'm not really sure if this is what you mean. I want to add some test for this option that I think it could be really useful, what do you think? -- Jonathan Gonzalez V. <[email protected]>
From ed6b0146d45ded6f0970f9bb8eb9a34d78960f2d Mon Sep 17 00:00:00 2001 From: "Jonathan Gonzalez V." <[email protected]> Date: Wed, 29 Oct 2025 16:54:42 +0100 Subject: [PATCH v2 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. Signed-off-by: Jonathan Gonzalez V. <[email protected]> --- doc/src/sgml/libpq.sgml | 23 ++++++++++++++++------ src/interfaces/libpq-oauth/oauth-curl.c | 25 ++++++++++-------------- src/interfaces/libpq-oauth/oauth-utils.c | 3 +++ src/interfaces/libpq-oauth/oauth-utils.h | 2 ++ src/interfaces/libpq/fe-auth-oauth.c | 3 +++ src/interfaces/libpq/fe-connect.c | 4 ++++ src/interfaces/libpq/libpq-int.h | 1 + src/tools/pgindent/typedefs.list | 1 + 8 files changed, 41 insertions(+), 21 deletions(-) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 21e1ba34a4e..f28871d402a 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -10519,12 +10519,6 @@ typedef struct PGoauthBearerRequest 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 @@ -10546,6 +10540,23 @@ typedef struct PGoauthBearerRequest </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 691e7ec1d9f..0460cce65bb 100644 --- a/src/interfaces/libpq-oauth/oauth-curl.c +++ b/src/interfaces/libpq-oauth/oauth-curl.c @@ -56,6 +56,7 @@ #define conn_oauth_discovery_uri(CONN) (CONN->oauth_discovery_uri) #define conn_oauth_issuer_id(CONN) (CONN->oauth_issuer_id) #define conn_oauth_scope(CONN) (CONN->oauth_scope) +#define conn_oauth_ca_file(CONN) (CONN->oauth_ca_file) #define conn_sasl_state(CONN) (CONN->sasl_state) #define set_conn_altsock(CONN, VAL) do { CONN->altsock = VAL; } while (0) @@ -1708,8 +1709,10 @@ debug_callback(CURL *handle, curl_infotype type, char *data, size_t size, * start_request(). */ static bool -setup_curl_handles(struct async_ctx *actx) +setup_curl_handles(struct async_ctx *actx, PGconn *conn) { + const char *ca_path = conn_oauth_ca_file(conn); + /* * Create our multi handle. This encapsulates the entire conversation with * libcurl for this connection. @@ -1798,20 +1801,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 were 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 (ca_path != NULL) + CHECK_SETOPT(actx, CURLOPT_CAINFO, ca_path, return false); /* * Suppress the Accept header to make our request as minimal as possible. @@ -2804,7 +2799,7 @@ pg_fe_run_oauth_flow_impl(PGconn *conn) if (!setup_multiplexer(actx)) goto error_return; - if (!setup_curl_handles(actx)) + if (!setup_curl_handles(actx, conn)) goto error_return; } diff --git a/src/interfaces/libpq-oauth/oauth-utils.c b/src/interfaces/libpq-oauth/oauth-utils.c index 4ebe7d0948c..52a8599e15d 100644 --- a/src/interfaces/libpq-oauth/oauth-utils.c +++ b/src/interfaces/libpq-oauth/oauth-utils.c @@ -41,6 +41,7 @@ conn_oauth_client_secret_func conn_oauth_client_secret; conn_oauth_discovery_uri_func conn_oauth_discovery_uri; conn_oauth_issuer_id_func conn_oauth_issuer_id; conn_oauth_scope_func conn_oauth_scope; +conn_oauth_ca_file_func conn_oauth_ca_file; conn_sasl_state_func conn_sasl_state; set_conn_altsock_func set_conn_altsock; @@ -70,6 +71,7 @@ libpq_oauth_init(pgthreadlock_t threadlock_impl, conn_oauth_discovery_uri_func discoveryuri_impl, conn_oauth_issuer_id_func issuerid_impl, conn_oauth_scope_func scope_impl, + conn_oauth_ca_file_func cafile_impl, conn_sasl_state_func saslstate_impl, set_conn_altsock_func setaltsock_impl, set_conn_oauth_token_func settoken_impl) @@ -82,6 +84,7 @@ libpq_oauth_init(pgthreadlock_t threadlock_impl, conn_oauth_discovery_uri = discoveryuri_impl; conn_oauth_issuer_id = issuerid_impl; conn_oauth_scope = scope_impl; + conn_oauth_ca_file = cafile_impl; conn_sasl_state = saslstate_impl; set_conn_altsock = setaltsock_impl; set_conn_oauth_token = settoken_impl; diff --git a/src/interfaces/libpq-oauth/oauth-utils.h b/src/interfaces/libpq-oauth/oauth-utils.h index 9f4d5b692d2..22183f21c6a 100644 --- a/src/interfaces/libpq-oauth/oauth-utils.h +++ b/src/interfaces/libpq-oauth/oauth-utils.h @@ -40,6 +40,7 @@ DECLARE_GETTER(char *, oauth_client_secret); DECLARE_GETTER(char *, oauth_discovery_uri); DECLARE_GETTER(char *, oauth_issuer_id); DECLARE_GETTER(char *, oauth_scope); +DECLARE_GETTER(char *, oauth_ca_file); DECLARE_GETTER(fe_oauth_state *, sasl_state); DECLARE_SETTER(pgsocket, altsock); @@ -59,6 +60,7 @@ extern PGDLLEXPORT void libpq_oauth_init(pgthreadlock_t threadlock, conn_oauth_discovery_uri_func discoveryuri_impl, conn_oauth_issuer_id_func issuerid_impl, conn_oauth_scope_func scope_impl, + conn_oauth_ca_file_func cafile_impl, conn_sasl_state_func saslstate_impl, set_conn_altsock_func setaltsock_impl, set_conn_oauth_token_func settoken_impl); diff --git a/src/interfaces/libpq/fe-auth-oauth.c b/src/interfaces/libpq/fe-auth-oauth.c index 67879d64b39..74fa737e5d3 100644 --- a/src/interfaces/libpq/fe-auth-oauth.c +++ b/src/interfaces/libpq/fe-auth-oauth.c @@ -816,6 +816,7 @@ DEFINE_GETTER(char *, oauth_client_secret); DEFINE_GETTER(char *, oauth_discovery_uri); DEFINE_GETTER(char *, oauth_issuer_id); DEFINE_GETTER(char *, oauth_scope); +DEFINE_GETTER(char *, oauth_ca_file); DEFINE_GETTER(fe_oauth_state *, sasl_state); DEFINE_SETTER(pgsocket, altsock); @@ -845,6 +846,7 @@ use_builtin_flow(PGconn *conn, fe_oauth_state *state) conn_oauth_discovery_uri_func discoveryuri_impl, conn_oauth_issuer_id_func issuerid_impl, conn_oauth_scope_func scope_impl, + conn_oauth_ca_file_func cafile_impl, conn_sasl_state_func saslstate_impl, set_conn_altsock_func setaltsock_impl, set_conn_oauth_token_func settoken_impl); @@ -932,6 +934,7 @@ use_builtin_flow(PGconn *conn, fe_oauth_state *state) conn_oauth_discovery_uri, conn_oauth_issuer_id, conn_oauth_scope, + conn_oauth_ca_file, conn_sasl_state, set_conn_altsock, set_conn_oauth_token); diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index a0d2f749811..6f5a1006206 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -412,6 +412,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)}, diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index fb6a7cbf15d..3f799e9b34d 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/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 241945734ec..e09858263e7 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3587,6 +3587,7 @@ conn_oauth_client_secret_func conn_oauth_discovery_uri_func conn_oauth_issuer_id_func conn_oauth_scope_func +conn_oauth_ca_file_func conn_sasl_state_func contain_aggs_of_level_context contain_placeholder_references_context -- 2.51.0
signature.asc
Description: This is a digitally signed message part
