From: | Jacob Champion <jacob(dot)champion(at)enterprisedb(dot)com> |
---|---|
To: | Matheus Alcantara <matheusssilv97(at)gmail(dot)com> |
Cc: | Peter Eisentraut <peter(at)eisentraut(dot)org>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: dblink: Add SCRAM pass-through authentication |
Date: | 2025-03-13 19:54:46 |
Message-ID: | CAOYmi+=u9OVceeWSob2pxs16L6EPsZZmDTuFbSgAsnkLGCva0g@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Thu, Mar 13, 2025 at 6:59 AM Matheus Alcantara
<matheusssilv97(at)gmail(dot)com> wrote:
> Fixed by wrapping on PG_CATCH/pfree/PG_RE_THROW. I didn't managed to
> create a test that use this code path, so let me know if I'm still
> missing something.
Thanks! Looks like the regression suite has one test that takes that
path (found by adding an Assert(false) to the PG_CATCH branch):
SET SESSION AUTHORIZATION regress_dblink_user;
-- should fail
SELECT dblink_connect('myconn', 'fdtest');
> PG_CATCH();
> {
> if (rconn)
> pfree(rconn);
A comment in this branch might be nice, to draw attention to the fact
that rconn is allocated in the TopMemoryContext and we can't leak it.
> I've added a code comment on dblink_connstr_has_required_scram_options
> function which is called on "connstr check" and "security check". Please
> let me know what you think.
That comment does not seem to match the code now:
> + * All required scram options is set by ourself, so we just need to ensure
> + * that these options are not overwritten by the user.
But later, there's no provision to detect if the keys have been overwritten:
> + if (strcmp(option->keyword, "scram_client_key") == 0 && option->val[0] != '\0')
> + has_scram_client_key = true;
> + if (strcmp(option->keyword, "scram_server_key") == 0 && option->val[0] != '\0')
> + has_scram_server_key = true;
This needs to match the handling directly above it, if we want to
claim that we'll detect duplicates.
> I was also thinking about this, maybe we could add a new validation
> (similar with PQconnectionUsedPassword, on fe-connect.c) that check if
> the scram keys is set on PGconn (we only set these keys if we are
> actually using the scram pass-through feature)
>
> +int
> +PQconnectionUsedScramKeys(const PGconn *conn)
> +{
> + if (conn->scram_client_key && conn->scram_server_key)
> + return true;
> +
> + return false;
> +}
If we implement this, it needs to check that the keys were actually
sent during scram_exchange(). Having them set on the PGconn doesn't
mean that we used them for authentication.
> So, I think that having something similar to what Peter implemented on
> his patch and adding require_auth=scram-sha-256 may prevent this kind of
> security issue?
Right. I think it'll come down to how Peter feels about putting that
into the solution, vs. PQconnectionUsedScramKeys() or some third
option.
--
Miscellaneous patch review:
> -dblink_security_check(PGconn *conn, remoteConn *rconn, const char *connstr)
> +dblink_security_check(PGconn *conn, remoteConn *rconn,
> + const char *connstr)
nit: this whitespace change is not necessary now that
useScramPassthrough is no longer in the signature.
Speaking of which, does get_connect_string() still need to take
user_mapping as an argument?
> + if (has_scram_keys && has_require_auth)
> + return true;
> +
> + return false;
nit: this is equivalent to `return (has_scram_keys && has_require_auth);`
> + my ($ret2, $stdout2, $stderr2) = $node->psql(
Declaring a second set of return values is probably unnecessary; the
previous ones can be reused.
> + is( $stderr,
> + "psql:<stdin>:1: ERROR: invalid option \"scram_client_key\"",
> + 'user mapping creation fails when using scram_client_key');
I think the two new tests like this should be using like() rather than
is() so that they can match only the important part of the error. I
don't think we want to pin the "psql:<stdin>" stuff in this test.
> +($ret, $stdout, $stderr) = $node1->psql(
> + $db0,
> + "SELECT * FROM dblink('$fdw_server', 'SELECT * FROM t') AS t(a int, b int)",
> + connstr => $node1->connstr($db0) . " user=$user");
> +
> +is($ret, 3, 'loopback trust fails on the same cluster');
> +like(
> + $stderr,
> + qr/failed: authentication method requirement "scram-sha-256" failed: server did not complete authentication/,
> + 'expected error from loopback trust (same cluster)');
Is this the same as the previous loopback-trust test? If so I think it
can be removed (or the two sections merged completely).
Thanks!
--Jacob
From | Date | Subject | |
---|---|---|---|
Next Message | Aleksander Alekseev | 2025-03-13 20:22:21 | Proposal: manipulating pg_control file from Perl |
Previous Message | Tom Lane | 2025-03-13 18:31:24 | Re: Adding support for SSLKEYLOGFILE in the frontend |