mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-06 22:30:56 +03:00
data providers: allow to disable SNI for TLS connections
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -211,6 +211,7 @@ The configuration file contains the following sections:
|
|||||||
- `password`, string. Database password. Leave empty for drivers `sqlite`, `bolt` and `memory`
|
- `password`, string. Database password. Leave empty for drivers `sqlite`, `bolt` and `memory`
|
||||||
- `sslmode`, integer. Used for drivers `mysql` and `postgresql`. 0 disable TLS connections, 1 require TLS, 2 set TLS mode to `verify-ca` for driver `postgresql` and `skip-verify` for driver `mysql`, 3 set TLS mode to `verify-full` for driver `postgresql` and `preferred` for driver `mysql`
|
- `sslmode`, integer. Used for drivers `mysql` and `postgresql`. 0 disable TLS connections, 1 require TLS, 2 set TLS mode to `verify-ca` for driver `postgresql` and `skip-verify` for driver `mysql`, 3 set TLS mode to `verify-full` for driver `postgresql` and `preferred` for driver `mysql`
|
||||||
- `root_cert`, string. Path to the root certificate authority used to verify that the server certificate was signed by a trusted CA
|
- `root_cert`, string. Path to the root certificate authority used to verify that the server certificate was signed by a trusted CA
|
||||||
|
- `disable_sni`, boolean. Allows to opt out Server Name Indication (SNI) for TLS connections. Default: `false`
|
||||||
- `client_cert`, string. Path to the client certificate for two-way TLS authentication
|
- `client_cert`, string. Path to the client certificate for two-way TLS authentication
|
||||||
- `client_key`,string. Path to the client key for two-way TLS authentication
|
- `client_key`,string. Path to the client key for two-way TLS authentication
|
||||||
- `connection_string`, string. Provide a custom database connection string. If not empty, this connection string will be used instead of building one using the previous parameters. Leave empty for drivers `bolt` and `memory`
|
- `connection_string`, string. Provide a custom database connection string. If not empty, this connection string will be used instead of building one using the previous parameters. Leave empty for drivers `bolt` and `memory`
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -37,7 +37,7 @@ require (
|
|||||||
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
|
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
|
||||||
github.com/klauspost/compress v1.15.9
|
github.com/klauspost/compress v1.15.9
|
||||||
github.com/lestrrat-go/jwx v1.2.25
|
github.com/lestrrat-go/jwx v1.2.25
|
||||||
github.com/lib/pq v1.10.6
|
github.com/lib/pq v1.10.7
|
||||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||||
github.com/mattn/go-sqlite3 v1.14.15
|
github.com/mattn/go-sqlite3 v1.14.15
|
||||||
github.com/mhale/smtpd v0.8.0
|
github.com/mhale/smtpd v0.8.0
|
||||||
@@ -68,9 +68,9 @@ require (
|
|||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
||||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
||||||
google.golang.org/api v0.94.0
|
google.golang.org/api v0.95.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
11
go.sum
11
go.sum
@@ -589,8 +589,9 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
|
||||||
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||||
|
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
||||||
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
@@ -977,8 +978,8 @@ golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77 h1:C1tElbkWrsSkn3IRl1GCW/gETw1TywWIPgwZtXTZbYg=
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U=
|
||||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -1119,8 +1120,8 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69
|
|||||||
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
|
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
|
||||||
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
|
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
|
||||||
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
|
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
|
||||||
google.golang.org/api v0.94.0 h1:KtKM9ru3nzQioV1HLlUf1cR7vMYJIpgls5VhAYQXIwA=
|
google.golang.org/api v0.95.0 h1:d1c24AAS01DYqXreBeuVV7ewY/U8Mnhh47pwtsgVtYg=
|
||||||
google.golang.org/api v0.94.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
|
google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ func Init() {
|
|||||||
ConnectionString: "",
|
ConnectionString: "",
|
||||||
SQLTablesPrefix: "",
|
SQLTablesPrefix: "",
|
||||||
SSLMode: 0,
|
SSLMode: 0,
|
||||||
|
DisableSNI: false,
|
||||||
RootCert: "",
|
RootCert: "",
|
||||||
ClientCert: "",
|
ClientCert: "",
|
||||||
ClientKey: "",
|
ClientKey: "",
|
||||||
@@ -1927,6 +1928,7 @@ func setViperDefaults() {
|
|||||||
viper.SetDefault("data_provider.username", globalConf.ProviderConf.Username)
|
viper.SetDefault("data_provider.username", globalConf.ProviderConf.Username)
|
||||||
viper.SetDefault("data_provider.password", globalConf.ProviderConf.Password)
|
viper.SetDefault("data_provider.password", globalConf.ProviderConf.Password)
|
||||||
viper.SetDefault("data_provider.sslmode", globalConf.ProviderConf.SSLMode)
|
viper.SetDefault("data_provider.sslmode", globalConf.ProviderConf.SSLMode)
|
||||||
|
viper.SetDefault("data_provider.disable_sni", globalConf.ProviderConf.DisableSNI)
|
||||||
viper.SetDefault("data_provider.root_cert", globalConf.ProviderConf.RootCert)
|
viper.SetDefault("data_provider.root_cert", globalConf.ProviderConf.RootCert)
|
||||||
viper.SetDefault("data_provider.client_cert", globalConf.ProviderConf.ClientCert)
|
viper.SetDefault("data_provider.client_cert", globalConf.ProviderConf.ClientCert)
|
||||||
viper.SetDefault("data_provider.client_key", globalConf.ProviderConf.ClientKey)
|
viper.SetDefault("data_provider.client_key", globalConf.ProviderConf.ClientKey)
|
||||||
|
|||||||
@@ -330,6 +330,8 @@ type Config struct {
|
|||||||
// 2 set ssl mode to verify-ca for driver postgresql and skip-verify for driver mysql.
|
// 2 set ssl mode to verify-ca for driver postgresql and skip-verify for driver mysql.
|
||||||
// 3 set ssl mode to verify-full for driver postgresql and preferred for driver mysql.
|
// 3 set ssl mode to verify-full for driver postgresql and preferred for driver mysql.
|
||||||
SSLMode int `json:"sslmode" mapstructure:"sslmode"`
|
SSLMode int `json:"sslmode" mapstructure:"sslmode"`
|
||||||
|
// Used for drivers mysql and postgresql. Set to true to disable SNI
|
||||||
|
DisableSNI bool `json:"disable_sni" mapstructure:"disable_sni"`
|
||||||
// Path to the root certificate authority used to verify that the server certificate was signed by a trusted CA
|
// Path to the root certificate authority used to verify that the server certificate was signed by a trusted CA
|
||||||
RootCert string `json:"root_cert" mapstructure:"root_cert"`
|
RootCert string `json:"root_cert" mapstructure:"root_cert"`
|
||||||
// Path to the client certificate for two-way TLS authentication
|
// Path to the client certificate for two-way TLS authentication
|
||||||
@@ -493,6 +495,9 @@ func (c *Config) IsDefenderSupported() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) requireCustomTLSForMySQL() bool {
|
func (c *Config) requireCustomTLSForMySQL() bool {
|
||||||
|
if config.DisableSNI {
|
||||||
|
return config.SSLMode != 0
|
||||||
|
}
|
||||||
if config.RootCert != "" && util.IsFileInputValid(config.RootCert) {
|
if config.RootCert != "" && util.IsFileInputValid(config.RootCert) {
|
||||||
return config.SSLMode != 0
|
return config.SSLMode != 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -219,37 +220,8 @@ func getMySQLConnectionString(redactedPwd bool) (string, error) {
|
|||||||
}
|
}
|
||||||
sslMode := getSSLMode()
|
sslMode := getSSLMode()
|
||||||
if sslMode == "custom" && !redactedPwd {
|
if sslMode == "custom" && !redactedPwd {
|
||||||
tlsConfig := &tls.Config{}
|
if err := registerMySQLCustomTLSConfig(); err != nil {
|
||||||
if config.RootCert != "" {
|
return "", err
|
||||||
rootCAs, err := x509.SystemCertPool()
|
|
||||||
if err != nil {
|
|
||||||
rootCAs = x509.NewCertPool()
|
|
||||||
}
|
|
||||||
rootCrt, err := os.ReadFile(config.RootCert)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("unable to load root certificate %#v: %v", config.RootCert, err)
|
|
||||||
}
|
|
||||||
if !rootCAs.AppendCertsFromPEM(rootCrt) {
|
|
||||||
return "", fmt.Errorf("unable to parse root certificate %#v", config.RootCert)
|
|
||||||
}
|
|
||||||
tlsConfig.RootCAs = rootCAs
|
|
||||||
}
|
|
||||||
if config.ClientCert != "" && config.ClientKey != "" {
|
|
||||||
clientCert := make([]tls.Certificate, 0, 1)
|
|
||||||
tlsCert, err := tls.LoadX509KeyPair(config.ClientCert, config.ClientKey)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("unable to load key pair %#v, %#v: %v", config.ClientCert, config.ClientKey, err)
|
|
||||||
}
|
|
||||||
clientCert = append(clientCert, tlsCert)
|
|
||||||
tlsConfig.Certificates = clientCert
|
|
||||||
}
|
|
||||||
if config.SSLMode == 2 {
|
|
||||||
tlsConfig.InsecureSkipVerify = true
|
|
||||||
}
|
|
||||||
providerLog(logger.LevelInfo, "registering custom TLS config, root cert %#v, client cert %#v, client key %#v",
|
|
||||||
config.RootCert, config.ClientCert, config.ClientKey)
|
|
||||||
if err := mysql.RegisterTLSConfig("custom", tlsConfig); err != nil {
|
|
||||||
return "", fmt.Errorf("unable to register tls config: %v", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectionString = fmt.Sprintf("%v:%v@tcp([%v]:%v)/%v?charset=utf8mb4&interpolateParams=true&timeout=10s&parseTime=true&tls=%v&writeTimeout=60s&readTimeout=60s",
|
connectionString = fmt.Sprintf("%v:%v@tcp([%v]:%v)/%v?charset=utf8mb4&interpolateParams=true&timeout=10s&parseTime=true&tls=%v&writeTimeout=60s&readTimeout=60s",
|
||||||
@@ -260,6 +232,45 @@ func getMySQLConnectionString(redactedPwd bool) (string, error) {
|
|||||||
return connectionString, nil
|
return connectionString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerMySQLCustomTLSConfig() error {
|
||||||
|
tlsConfig := &tls.Config{}
|
||||||
|
if config.RootCert != "" {
|
||||||
|
rootCAs, err := x509.SystemCertPool()
|
||||||
|
if err != nil {
|
||||||
|
rootCAs = x509.NewCertPool()
|
||||||
|
}
|
||||||
|
rootCrt, err := os.ReadFile(config.RootCert)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load root certificate %#v: %v", config.RootCert, err)
|
||||||
|
}
|
||||||
|
if !rootCAs.AppendCertsFromPEM(rootCrt) {
|
||||||
|
return fmt.Errorf("unable to parse root certificate %#v", config.RootCert)
|
||||||
|
}
|
||||||
|
tlsConfig.RootCAs = rootCAs
|
||||||
|
}
|
||||||
|
if config.ClientCert != "" && config.ClientKey != "" {
|
||||||
|
clientCert := make([]tls.Certificate, 0, 1)
|
||||||
|
tlsCert, err := tls.LoadX509KeyPair(config.ClientCert, config.ClientKey)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load key pair %#v, %#v: %v", config.ClientCert, config.ClientKey, err)
|
||||||
|
}
|
||||||
|
clientCert = append(clientCert, tlsCert)
|
||||||
|
tlsConfig.Certificates = clientCert
|
||||||
|
}
|
||||||
|
if config.SSLMode == 2 || config.SSLMode == 3 {
|
||||||
|
tlsConfig.InsecureSkipVerify = true
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(config.Host) && !config.DisableSNI {
|
||||||
|
tlsConfig.ServerName = config.Host
|
||||||
|
}
|
||||||
|
providerLog(logger.LevelInfo, "registering custom TLS config, root cert %#v, client cert %#v, client key %#v, disable SNI? %v",
|
||||||
|
config.RootCert, config.ClientCert, config.ClientKey, config.DisableSNI)
|
||||||
|
if err := mysql.RegisterTLSConfig("custom", tlsConfig); err != nil {
|
||||||
|
return fmt.Errorf("unable to register tls config: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *MySQLProvider) checkAvailability() error {
|
func (p *MySQLProvider) checkAvailability() error {
|
||||||
return sqlCommonCheckAvailability(p.dbHandle)
|
return sqlCommonCheckAvailability(p.dbHandle)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,6 +231,9 @@ func getPGSQLConnectionString(redactedPwd bool) string {
|
|||||||
if config.ClientCert != "" && config.ClientKey != "" {
|
if config.ClientCert != "" && config.ClientKey != "" {
|
||||||
connectionString += fmt.Sprintf(" sslcert='%v' sslkey='%v'", config.ClientCert, config.ClientKey)
|
connectionString += fmt.Sprintf(" sslcert='%v' sslkey='%v'", config.ClientCert, config.ClientKey)
|
||||||
}
|
}
|
||||||
|
if config.DisableSNI {
|
||||||
|
connectionString += " sslsni=0"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
connectionString = config.ConnectionString
|
connectionString = config.ConnectionString
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,7 @@
|
|||||||
"username": "",
|
"username": "",
|
||||||
"password": "",
|
"password": "",
|
||||||
"sslmode": 0,
|
"sslmode": 0,
|
||||||
|
"disable_sni": false,
|
||||||
"root_cert": "",
|
"root_cert": "",
|
||||||
"client_cert": "",
|
"client_cert": "",
|
||||||
"client_key": "",
|
"client_key": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user