From 887e4d90543cb9e8d2f7bb0720da1a1ac36bd843 Mon Sep 17 00:00:00 2001 From: Rafi Shamim Date: Thu, 1 Sep 2022 14:26:18 -0400 Subject: [PATCH] cli: don't show password in \c metacommand Release note (cli change): The \c metacommand no longer shows the password in plaintext. Release justification: low risk change --- pkg/cli/clisqlshell/sql.go | 2 +- .../interactive_tests/test_connect_cmd.tcl | 16 +++++++++++++++ pkg/server/pgurl/generate.go | 20 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pkg/cli/clisqlshell/sql.go b/pkg/cli/clisqlshell/sql.go index afff797a760f..b828304ec344 100644 --- a/pkg/cli/clisqlshell/sql.go +++ b/pkg/cli/clisqlshell/sql.go @@ -1552,7 +1552,7 @@ func (c *cliState) handleConnectInternal(cmd []string) error { if dbName == "" { dbName = currURL.GetDatabase() } - fmt.Fprintf(c.iCtx.stdout, "Connection string: %s\n", currURL.ToPQ()) + fmt.Fprintf(c.iCtx.stdout, "Connection string: %s\n", currURL.ToPQRedacted()) fmt.Fprintf(c.iCtx.stdout, "You are connected to database %q as user %q.\n", dbName, currURL.GetUsername()) return nil diff --git a/pkg/cli/interactive_tests/test_connect_cmd.tcl b/pkg/cli/interactive_tests/test_connect_cmd.tcl index 25f9b0274943..9e1fdaf4e348 100644 --- a/pkg/cli/interactive_tests/test_connect_cmd.tcl +++ b/pkg/cli/interactive_tests/test_connect_cmd.tcl @@ -26,6 +26,7 @@ send "create user foo with password 'abc';\r" eexpect "CREATE ROLE" eexpect root@ eexpect "/t>" +end_test start_test "Check that the client-side connect cmd prints the current conn details" send "\\c\r" @@ -33,6 +34,7 @@ eexpect "Connection string:" eexpect "You are connected to database \"t\" as user \"root\"" eexpect root@ eexpect "/t>" +end_test start_test "Check that the client-side connect cmd can change databases" send "\\c postgres\r" @@ -164,6 +166,20 @@ end_test send "\\q\r" eexpect eof +start_test "Check that the client-side connect cmd prints the current conn details with password redacted" + +spawn $argv sql --certs-dir=$certs_dir --url=postgres://foo:abc@localhost:26257/defaultdb +eexpect foo@ +send "\\c\r" +eexpect "Connection string: postgresql://foo:~~~~~~@" +eexpect "You are connected to database \"defaultdb\" as user \"foo\"" +eexpect foo@ +eexpect "/defaultdb>" +end_test + +send "\\q\r" +eexpect eof + stop_server $argv # Some more tests with the insecure mode. diff --git a/pkg/server/pgurl/generate.go b/pkg/server/pgurl/generate.go index 052efd548a96..75560bbdbf29 100644 --- a/pkg/server/pgurl/generate.go +++ b/pkg/server/pgurl/generate.go @@ -103,6 +103,26 @@ func (u *URL) ToPQ() *url.URL { return nu } +// ToPQRedacted converts the URL to a connection string supported +// by drivers using libpq or compatible, with the password redacted. +func (u *URL) ToPQRedacted() *url.URL { + nu, opts := u.baseURL() + + if u.username != "" { + nu.User = url.User(u.username) + } + switch u.authn { + case authnPassword, authnPasswordWithClientCert: + if u.hasPassword { + // Use '~' since it does not need to be escaped. + nu.User = url.UserPassword(u.username, "~~~~~~") + } + } + + nu.RawQuery = opts.Encode() + return nu +} + // String makes URL printable. func (u *URL) String() string { return u.ToPQ().String() }