When PGSSLMODE=disable no fallback config was created which would cause
the check that fallbacks are deep copied to crash on:
copied.Fallbacks[0].Port = uint16(5433)
ParseConfig currently treats the libpq "verify-ca" SSL mode as
"verify-full". This is okay from a security standpoint because
"verify-full" performs certificate verification and hostname
verification, whereas "verify-ca" only performs certificate
verification.
The downside to this approach is that checking the hostname is
unnecessary when the server's certificate has been signed by a private
CA. It can also cause the SSL handshake to fail when connecting to an
instance by IP. For example, a Google Cloud SQL instance typically
doesn't have a hostname and uses its own private CA to sign its
server and client certs.
This change uses the tls.Config.VerifyPeerCertificate function to
perform certificate verification without checking the hostname when the
"verify-ca" SSL mode is set. This brings pgconn's behavior closer to
that of libpq.
See https://github.com/golang/go/issues/21971#issuecomment-332693931
and https://pkg.go.dev/crypto/tls?tab=doc#example-Config-VerifyPeerCertificate
for more details on how this is implemented.
Original implementation: 2d9d8dc52a by
Joshua Barone <joshua.barone@gmail.com>.
Also changed DSN tests to use "dbname" as key rather than "database" as
that is what the PostgreSQL documentation specifies. "database" still
actually works but it should not be encouraged as it is non-standard.
This avoids the foot-gun of ParseConfig setting AfterConnect because of
target_session_attrs and the user inadvertently overriding it with an
AfterConnect designed to setup the connection.
Now target_session_attrs will be handled with ValidateConnect.