chore: ⬆️ updated deps
This commit is contained in:
+64
-15
@@ -79,6 +79,7 @@ const (
|
||||
ApplicationIntent = "applicationintent"
|
||||
FailoverPartner = "failoverpartner"
|
||||
FailOverPort = "failoverport"
|
||||
FailoverPartnerSpn = "failoverpartnerspn"
|
||||
DisableRetry = "disableretry"
|
||||
Server = "server"
|
||||
Protocol = "protocol"
|
||||
@@ -88,6 +89,7 @@ const (
|
||||
NoTraceID = "notraceid"
|
||||
GuidConversion = "guid conversion"
|
||||
Timezone = "timezone"
|
||||
EpaEnabled = "epa enabled"
|
||||
)
|
||||
|
||||
type EncodeParameters struct {
|
||||
@@ -114,8 +116,9 @@ type Config struct {
|
||||
Encryption Encryption
|
||||
TLSConfig *tls.Config
|
||||
|
||||
FailOverPartner string
|
||||
FailOverPort uint64
|
||||
FailOverPartner string
|
||||
FailOverPort uint64
|
||||
FailOverPartnerSPN string
|
||||
|
||||
// If true the TLSConfig servername should use the routed server.
|
||||
HostInCertificateProvided bool
|
||||
@@ -159,8 +162,13 @@ type Config struct {
|
||||
// When true, no connection id or trace id value is sent in the prelogin packet.
|
||||
// Some cloud servers may block connections that lack such values.
|
||||
NoTraceID bool
|
||||
// TrustServerCertificate controls whether the client verifies the server certificate.
|
||||
// When true, the server certificate is accepted without validation.
|
||||
TrustServerCertificate bool
|
||||
// Parameters related to type encoding
|
||||
Encoding EncodeParameters
|
||||
// EPA mode determines how the Channel Bindings are calculated.
|
||||
EpaEnabled bool
|
||||
}
|
||||
|
||||
func readDERFile(filename string) ([]byte, error) {
|
||||
@@ -282,8 +290,8 @@ func setupTLSServerCertificateOnly(config *tls.Config, pemData []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parse and handle encryption parameters. If encryption is desired, it returns the corresponding tls.Config object.
|
||||
func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, error) {
|
||||
// parseTLS parses encryption parameters and returns the TLS configuration and trustServerCertificate value.
|
||||
func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, bool, error) {
|
||||
trustServerCert := false
|
||||
|
||||
var encryption Encryption = EncryptionOff
|
||||
@@ -301,7 +309,7 @@ func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, e
|
||||
encryption = EncryptionOff
|
||||
default:
|
||||
f := "invalid encrypt '%s'"
|
||||
return encryption, nil, fmt.Errorf(f, encrypt)
|
||||
return encryption, nil, false, fmt.Errorf(f, encrypt)
|
||||
}
|
||||
} else {
|
||||
trustServerCert = true
|
||||
@@ -312,7 +320,7 @@ func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, e
|
||||
trustServerCert, err = strconv.ParseBool(trust)
|
||||
if err != nil {
|
||||
f := "invalid trust server certificate '%s': %s"
|
||||
return encryption, nil, fmt.Errorf(f, trust, err.Error())
|
||||
return encryption, nil, false, fmt.Errorf(f, trust, err.Error())
|
||||
}
|
||||
}
|
||||
certificate := params[Certificate]
|
||||
@@ -322,10 +330,10 @@ func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, e
|
||||
// Validate parameter combinations
|
||||
if len(serverCertificate) > 0 {
|
||||
if len(certificate) > 0 {
|
||||
return encryption, nil, errors.New("cannot specify both 'certificate' and 'serverCertificate' parameters")
|
||||
return encryption, nil, false, errors.New("cannot specify both 'certificate' and 'serverCertificate' parameters")
|
||||
}
|
||||
if len(hostInCertificate) > 0 {
|
||||
return encryption, nil, errors.New("cannot specify both 'serverCertificate' and 'hostnameincertificate' parameters")
|
||||
return encryption, nil, false, errors.New("cannot specify both 'serverCertificate' and 'hostnameincertificate' parameters")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,11 +344,11 @@ func parseTLS(params map[string]string, host string) (Encryption, *tls.Config, e
|
||||
}
|
||||
tlsConfig, err := SetupTLS(certificate, serverCertificate, trustServerCert, host, tlsMin)
|
||||
if err != nil {
|
||||
return encryption, nil, fmt.Errorf("failed to setup TLS: %w", err)
|
||||
return encryption, nil, trustServerCert, fmt.Errorf("failed to setup TLS: %w", err)
|
||||
}
|
||||
return encryption, tlsConfig, nil
|
||||
return encryption, tlsConfig, trustServerCert, nil
|
||||
}
|
||||
return encryption, nil, nil
|
||||
return encryption, nil, trustServerCert, nil
|
||||
}
|
||||
|
||||
var skipSetup = errors.New("skip setting up TLS")
|
||||
@@ -525,6 +533,11 @@ func Parse(dsn string) (Config, error) {
|
||||
}
|
||||
}
|
||||
|
||||
failOverPartnerSPN, ok := params[FailoverPartnerSpn]
|
||||
if ok {
|
||||
p.FailOverPartnerSPN = failOverPartnerSPN
|
||||
}
|
||||
|
||||
disableRetry, ok := params[DisableRetry]
|
||||
if ok {
|
||||
var err error
|
||||
@@ -582,7 +595,7 @@ func Parse(dsn string) (Config, error) {
|
||||
p.HostInCertificateProvided = false
|
||||
}
|
||||
|
||||
p.Encryption, p.TLSConfig, err = parseTLS(params, hostInCertificate)
|
||||
p.Encryption, p.TLSConfig, p.TrustServerCertificate, err = parseTLS(params, hostInCertificate)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
@@ -639,6 +652,19 @@ func Parse(dsn string) (Config, error) {
|
||||
p.Encoding.GuidConversion = false
|
||||
}
|
||||
|
||||
p.EpaEnabled = false
|
||||
epaString, ok := params[EpaEnabled]
|
||||
if !ok {
|
||||
epaString = os.Getenv("MSSQL_USE_EPA")
|
||||
}
|
||||
if epaString != "" {
|
||||
epaEnabled, err := strconv.ParseBool(epaString)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("invalid epa enabled value '%s': %v", epaString, err)
|
||||
}
|
||||
p.EpaEnabled = epaEnabled
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
@@ -663,7 +689,8 @@ func (p Config) URL() *url.URL {
|
||||
}
|
||||
}
|
||||
if p.Port > 0 {
|
||||
host = fmt.Sprintf("%s:%d", host, p.Port)
|
||||
// Use net.JoinHostPort to properly handle IPv6 addresses (e.g., [::1]:1433)
|
||||
host = net.JoinHostPort(host, strconv.Itoa(int(p.Port)))
|
||||
}
|
||||
q.Add(DisableRetry, fmt.Sprintf("%t", p.DisableRetry))
|
||||
protocolParam, ok := p.Parameters[Protocol]
|
||||
@@ -696,6 +723,10 @@ func (p Config) URL() *url.URL {
|
||||
case EncryptionRequired:
|
||||
q.Add(Encrypt, "true")
|
||||
}
|
||||
// Only include TrustServerCertificate if it was explicitly set in the original connection string
|
||||
if _, ok := p.Parameters[TrustServerCertificate]; ok {
|
||||
q.Add(TrustServerCertificate, strconv.FormatBool(p.TrustServerCertificate))
|
||||
}
|
||||
if p.ColumnEncryption {
|
||||
q.Add("columnencryption", "true")
|
||||
}
|
||||
@@ -708,6 +739,19 @@ func (p Config) URL() *url.URL {
|
||||
q.Add(Timezone, tz.String())
|
||||
}
|
||||
|
||||
if p.FailOverPartner != "" {
|
||||
q.Add(FailoverPartner, p.FailOverPartner)
|
||||
}
|
||||
if p.FailOverPort != 0 {
|
||||
q.Add(FailOverPort, strconv.FormatUint(p.FailOverPort, 10))
|
||||
}
|
||||
if p.ServerSPN != "" {
|
||||
q.Add(ServerSpn, p.ServerSPN)
|
||||
}
|
||||
if p.FailOverPartnerSPN != "" {
|
||||
q.Add(FailoverPartnerSpn, p.FailOverPartnerSPN)
|
||||
}
|
||||
|
||||
if len(q) > 0 {
|
||||
res.RawQuery = q.Encode()
|
||||
}
|
||||
@@ -820,7 +864,8 @@ func splitConnectionStringURL(dsn string) (map[string]string, error) {
|
||||
|
||||
u, err := url.Parse(dsn)
|
||||
if err != nil {
|
||||
return res, err
|
||||
// Do not include the original error which may contain credentials
|
||||
return res, fmt.Errorf("unable to parse connection string: invalid URL format")
|
||||
}
|
||||
|
||||
if u.Scheme != "sqlserver" {
|
||||
@@ -855,7 +900,11 @@ func splitConnectionStringURL(dsn string) (map[string]string, error) {
|
||||
if len(v) > 1 {
|
||||
return res, fmt.Errorf("key %s provided more than once", k)
|
||||
}
|
||||
res[strings.ToLower(k)] = v[0]
|
||||
lk := strings.ToLower(k)
|
||||
if _, exists := res[lk]; exists {
|
||||
return res, fmt.Errorf("key %q provided more than once (connection string keys are case-insensitive; remove the duplicate)", k)
|
||||
}
|
||||
res[lk] = v[0]
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
||||
Reference in New Issue
Block a user