diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c46a96..624095be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ unreleased ---------- +- As announced in the release notes for v1.12.0, this release changes the + default `sslmode` from `require` to `prefer`, which is the default used by + libpq and the rest of the PostgreSQL ecosystem ([#1271]). + +- pq now requires Go 1.23. + +### Features + +### Fixes + +- Add Redshift-specific OID mappings ([#1291], [#1317]). + +[#1291]: https://github.com/lib/pq/pull/1291 +[#1317]: https://github.com/lib/pq/pull/1317 + v1.12.3 (2026-04-03) -------------------- diff --git a/conn.go b/conn.go index 78687c15..e4661c84 100644 --- a/conn.go +++ b/conn.go @@ -261,6 +261,9 @@ restartAll: ) for _, cfg := range c.cfg.hosts() { mode := cfg.SSLMode + if mode == "" { + mode = SSLModePrefer + } restartHost: if debugProto { fmt.Fprintln(os.Stderr, "CONNECT ", cfg.string()) diff --git a/connector.go b/connector.go index 5c8d58aa..358792b7 100644 --- a/connector.go +++ b/connector.go @@ -545,6 +545,7 @@ func newConfig(dsn string, env []string) (Config, error) { Host: "localhost", Port: 5432, SSLSNI: true, + SSLMode: SSLModePrefer, MinProtocolVersion: "3.0", MaxProtocolVersion: "3.0", } @@ -1030,7 +1031,7 @@ func (cfg Config) string() string { switch k { case "datestyle", "client_encoding": continue - case "host", "port", "user", "sslsni", "min_protocol_version", "max_protocol_version": + case "host", "port", "user", "sslsni", "sslmode", "min_protocol_version", "max_protocol_version": if !cfg.isset(k) { continue } diff --git a/connector_test.go b/connector_test.go index 5eadad2c..a3cf1cb5 100644 --- a/connector_test.go +++ b/connector_test.go @@ -333,14 +333,14 @@ func TestNewConfig(t *testing.T) { }{ // Override defaults {"", nil, "", ""}, - {"user=u port=1 host=example.com", nil, - "host=example.com port=1 user=u", ""}, - {"", []string{"PGUSER=u", "PGPORT=1", "PGHOST=example.com"}, - "host=example.com port=1 user=u", ""}, + {"user=u port=1 host=example.com sslmode=verify-ca", nil, + "host=example.com port=1 sslmode=verify-ca user=u", ""}, + {"", []string{"PGUSER=u", "PGPORT=1", "PGHOST=example.com", "PGSSLMODE=verify-ca"}, + "host=example.com port=1 sslmode=verify-ca user=u", ""}, // Socket - {"host=/var/run/psql", nil, "host=/var/run/psql sslmode=disable", ""}, - {"host=@/var/run/psql", nil, "host=@/var/run/psql sslmode=disable", ""}, + {"host=/var/run/psql", nil, "host=/var/run/psql", ""}, + {"host=@/var/run/psql", nil, "host=@/var/run/psql", ""}, {"host=/var/run/psql sslmode=require", nil, "host=/var/run/psql sslmode=disable", ""}, // Empty value, value with space, and value with escaped \' @@ -903,16 +903,16 @@ func TestService(t *testing.T) { wantErr string }{ {"service=doesntexist", nil, ``, `definition of service "doesntexist" not found`}, - {"service=svc1", nil, `connect_timeout=20 dbname=xyz host=firsthost port=1234 service=svc1 sslmode=disable user=pqgo`, ``}, - {"service=svc2", nil, `connect_timeout=20 dbname='with space' host=localhost service=svc2 sslmode=disable user=''`, ``}, + {"service=svc1", nil, `connect_timeout=20 dbname=xyz host=firsthost port=1234 service=svc1 user=pqgo`, ``}, + {"service=svc2", nil, `connect_timeout=20 dbname='with space' host=localhost service=svc2 user=''`, ``}, {"service=svc3", nil, ``, `pq: unknown setting "unknown" in service file for service "svc3"`}, - {"service=svc4", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc4 sslmode=disable user=pqgo`, ``}, - {"service=svc5", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc5 sslmode=disable user=pqgo`, ``}, + {"service=svc4", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc4 user=pqgo`, ``}, + {"service=svc5", nil, `connect_timeout=20 dbname=pqgo host=localhost service=svc5 user=pqgo`, ``}, {"service=svc5", map[string]string{"PGSERVICEFILE": "none"}, ``, `service file "none" not found`}, {"service=svc1", map[string]string{"PGSERVICEFILE": filepath.Join(h, "other")}, ``, `definition of service "svc1" not found`}, {"service=other", map[string]string{"PGSERVICEFILE": filepath.Join(h, "other")}, - `connect_timeout=20 dbname=other host=localhost service=other sslmode=disable user=pqgo`, ``}, + `connect_timeout=20 dbname=other host=localhost service=other user=pqgo`, ``}, } pqtest.Write(t, []byte("[other]\ndbname=other"), h, "other") diff --git a/error_test.go b/error_test.go index 7d0e5bd2..b4e75808 100644 --- a/error_test.go +++ b/error_test.go @@ -253,7 +253,7 @@ func TestRetryError(t *testing.T) { } func TestNetworkError(t *testing.T) { - c, err := NewConnector("") + c, err := NewConnector("sslmode=disable") if err != nil { t.Fatal(err) } diff --git a/internal/pqtest/pqtest.go b/internal/pqtest/pqtest.go index 21ce854d..8a174b9a 100644 --- a/internal/pqtest/pqtest.go +++ b/internal/pqtest/pqtest.go @@ -85,7 +85,6 @@ func DSN(conninfo string) string { defaultTo("PGHOST", "localhost") defaultTo("PGDATABASE", "pqgo") defaultTo("PGUSER", "pqgo") - defaultTo("PGSSLMODE", "disable") defaultTo("PGCONNECT_TIMEOUT", "20") os.Setenv("PGAPPNAME", "pqgo") }) diff --git a/ssl.go b/ssl.go index b9357854..081aa9d9 100644 --- a/ssl.go +++ b/ssl.go @@ -82,7 +82,7 @@ func ssl(cfg Config, mode SSLMode) (func(net.Conn) (net.Conn, error), error) { case mode == SSLModeDisable || mode == SSLModeAllow: return nil, nil - case mode == "" || mode == SSLModeRequire || mode == SSLModePrefer: + case mode == SSLModeRequire || mode == SSLModePrefer: // Skip TLS's own verification since it requires full verification. tlsConf.InsecureSkipVerify = true diff --git a/ssl_test.go b/ssl_test.go index 2564fb72..8b8641b8 100644 --- a/ssl_test.go +++ b/ssl_test.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "net" - "os" "testing" "time" @@ -52,6 +51,10 @@ func TestSSLMode(t *testing.T) { connect string wantErr string }{ + // Default (prefer) should work both with and without ssl. + {"user=pqgossl", ""}, + {f.DSN(), ""}, + // sslmode=require: require SSL, but don't verify certificate. {"sslmode=require user=pqgossl", ""}, {"sslmode=require " + f.DSN(), "pq: SSL is not enabled on the server"}, @@ -384,12 +387,7 @@ func TestSSLDefaults(t *testing.T) { func TestSSLRootCA(t *testing.T) { startSSLTest(t, "pqgossl") - // TODO: can remove this once https://github.com/lib/pq/pull/1271 is merged. - os.Unsetenv("PGSSLMODE") - t.Cleanup(func() { - os.Setenv("PGSSLMODE", "disable") - testSystemRoots = nil - }) + t.Cleanup(func() { testSystemRoots = nil }) testSystemRoots = x509.NewCertPool() if !testSystemRoots.AppendCertsFromPEM(pqtest.Read(t, "testdata/ssl/root.crt")) { t.Fatal()