From 1165ccf9d536e9e8cdefa288fff8413ab0a0e699 Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Wed, 5 Aug 2020 08:48:05 -0500 Subject: [PATCH 1/7] Add insecure ssl options --- session.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/session.go b/session.go index cd2a53e19..e020dbd0c 100644 --- a/session.go +++ b/session.go @@ -340,6 +340,7 @@ func ParseURL(url string) (*DialInfo, error) { } ssl := false direct := false + sslSkipVerify := false mechanism := "" service := "" source := "" @@ -357,6 +358,14 @@ func ParseURL(url string) (*DialInfo, error) { if v, err := strconv.ParseBool(opt.value); err == nil && v { ssl = true } + case "sslAllowInvalidCertificates": + if v, err := strconv.ParseBool(opt.value); err == nil && v { + sslSkipVerify = true + } + case "sslAllowInvalidHostnames": + if v, err := strconv.ParseBool(opt.value); err == nil && v { + sslSkipVerify = true + } case "authSource": source = opt.value case "authMechanism": @@ -475,7 +484,9 @@ func ParseURL(url string) (*DialInfo, error) { if ssl && info.DialServer == nil { // Set DialServer only if nil, we don't want to override user's settings. info.DialServer = func(addr *ServerAddr) (net.Conn, error) { - conn, err := tls.Dial("tcp", addr.String(), &tls.Config{}) + conn, err := tls.Dial("tcp", addr.String(), &tls.Config{ + InsecureSkipVerify: sslSkipVerify, + }) return conn, err } } @@ -2912,7 +2923,6 @@ func (p *Pipe) SetMaxTime(d time.Duration) *Pipe { return p } - // Collation allows to specify language-specific rules for string comparison, // such as rules for lettercase and accent marks. // When specifying collation, the locale field is mandatory; all other collation From 4b92dd581a79735b9b4f0285409f256eccbe2129 Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Fri, 7 Aug 2020 08:19:44 -0500 Subject: [PATCH 2/7] Don't error out on unknown option --- session.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.go b/session.go index e020dbd0c..63d750048 100644 --- a/session.go +++ b/session.go @@ -453,7 +453,7 @@ func ParseURL(url string) (*DialInfo, error) { } fallthrough default: - return nil, errors.New("unsupported connection URL option: " + opt.key + "=" + opt.value) + fmt.Println("WARN: unsupported connection URL option: " + opt.key + "=" + opt.value) } } From 8245c93bdf2a936058dfa974e6698367f5fb0cb2 Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Fri, 30 Oct 2020 10:09:47 -0500 Subject: [PATCH 3/7] Allow ca-certs file in connection string --- session.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/session.go b/session.go index cd2a53e19..367f57c37 100644 --- a/session.go +++ b/session.go @@ -35,6 +35,7 @@ import ( "encoding/hex" "errors" "fmt" + "io/ioutil" "math" "net" "net/url" @@ -347,6 +348,7 @@ func ParseURL(url string) (*DialInfo, error) { poolLimit := 0 appName := "" readPreferenceMode := Primary + sslCAFile := "" var readPreferenceTagSets []bson.D minPoolSize := 0 maxIdleTimeMS := 0 @@ -357,10 +359,18 @@ func ParseURL(url string) (*DialInfo, error) { if v, err := strconv.ParseBool(opt.value); err == nil && v { ssl = true } + case "tls": + if v, err := strconv.ParseBool(opt.value); err == nil && v { + ssl = true + } case "authSource": source = opt.value case "authMechanism": mechanism = opt.value + case "sslCAFile": + sslCAFile = opt.value + case "tlsCAFile": + sslCAFile = opt.value case "gssapiServiceName": service = opt.value case "replicaSet": @@ -473,9 +483,24 @@ func ParseURL(url string) (*DialInfo, error) { MaxIdleTimeMS: maxIdleTimeMS, } if ssl && info.DialServer == nil { + tlsConfig := tls.Config{} + + // Optionally load RootCAs from a file + if sslCAFile != "" { + cert, err := ioutil.ReadFile(sslCAFile) + if err != nil { + return nil, err + } + + tlsConfig.RootCAs = x509.NewCertPool() + if !tlsConfig.RootCAs.AppendCertsFromPEM(cert) { + return nil, errors.New("Unable to load ca certs") + } + } + // Set DialServer only if nil, we don't want to override user's settings. info.DialServer = func(addr *ServerAddr) (net.Conn, error) { - conn, err := tls.Dial("tcp", addr.String(), &tls.Config{}) + conn, err := tls.Dial("tcp", addr.String(), &tlsConfig) return conn, err } } @@ -2912,7 +2937,6 @@ func (p *Pipe) SetMaxTime(d time.Duration) *Pipe { return p } - // Collation allows to specify language-specific rules for string comparison, // such as rules for lettercase and accent marks. // When specifying collation, the locale field is mandatory; all other collation From b466fec8aad6131b8a0ee4f1be4752e8f00c0e9c Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Thu, 5 Nov 2020 13:04:00 -0600 Subject: [PATCH 4/7] Fix casing --- session.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/session.go b/session.go index f0ddb42dd..e10bfee35 100644 --- a/session.go +++ b/session.go @@ -356,15 +356,11 @@ func ParseURL(url string) (*DialInfo, error) { safe := Safe{} for _, opt := range uinfo.options { switch opt.key { - case "ssl": - case "tls": + case "ssl", "tls": if v, err := strconv.ParseBool(opt.value); err == nil && v { ssl = true } - case "sslAllowInvalidCertificates": - case "sslAllowInvalidHostnames": - case "tlsAllowInvalidCertificates": - case "tlsAllowInvalidHostnames": + case "sslAllowInvalidCertificates", "sslAllowInvalidHostnames", "tlsAllowInvalidCertificates", "tlsAllowInvalidHostnames": if v, err := strconv.ParseBool(opt.value); err == nil && v { sslSkipVerify = true } @@ -372,9 +368,7 @@ func ParseURL(url string) (*DialInfo, error) { source = opt.value case "authMechanism": mechanism = opt.value - case "sslCAFile": - sslCAFile = opt.value - case "tlsCAFile": + case "sslCAFile", "tlsCAFile": sslCAFile = opt.value case "gssapiServiceName": service = opt.value From 7de3b960cab4719a36f325b1bed2fd44bf4c02ad Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Mon, 9 Nov 2020 11:26:40 -0600 Subject: [PATCH 5/7] Minimal implementation --- session.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/session.go b/session.go index e10bfee35..286832129 100644 --- a/session.go +++ b/session.go @@ -341,7 +341,6 @@ func ParseURL(url string) (*DialInfo, error) { } ssl := false direct := false - sslSkipVerify := false mechanism := "" service := "" source := "" @@ -356,19 +355,15 @@ func ParseURL(url string) (*DialInfo, error) { safe := Safe{} for _, opt := range uinfo.options { switch opt.key { - case "ssl", "tls": + case "ssl": if v, err := strconv.ParseBool(opt.value); err == nil && v { ssl = true } - case "sslAllowInvalidCertificates", "sslAllowInvalidHostnames", "tlsAllowInvalidCertificates", "tlsAllowInvalidHostnames": - if v, err := strconv.ParseBool(opt.value); err == nil && v { - sslSkipVerify = true - } case "authSource": source = opt.value case "authMechanism": mechanism = opt.value - case "sslCAFile", "tlsCAFile": + case "sslCAFile": sslCAFile = opt.value case "gssapiServiceName": service = opt.value @@ -482,9 +477,7 @@ func ParseURL(url string) (*DialInfo, error) { MaxIdleTimeMS: maxIdleTimeMS, } if ssl && info.DialServer == nil { - tlsConfig := tls.Config{ - InsecureSkipVerify: sslSkipVerify, - } + tlsConfig := tls.Config{} // Optionally load RootCAs from a file if sslCAFile != "" { From a344b25629c84e21a41fb50fbc54fbe79a03297f Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Mon, 9 Nov 2020 11:33:02 -0600 Subject: [PATCH 6/7] Don't have an opinion --- session.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.go b/session.go index 286832129..740aab961 100644 --- a/session.go +++ b/session.go @@ -448,7 +448,7 @@ func ParseURL(url string) (*DialInfo, error) { } fallthrough default: - fmt.Println("WARN: unsupported connection URL option: " + opt.key + "=" + opt.value) + return nil, errors.New("unsupported connection URL option: " + opt.key + "=" + opt.value) } } From 120efafe9d6fee7eed9897f738b39df50e3235ae Mon Sep 17 00:00:00 2001 From: Justin Ehlert Date: Mon, 23 Nov 2020 09:25:54 -0600 Subject: [PATCH 7/7] Enable tls aliases --- session.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.go b/session.go index 740aab961..b7827049e 100644 --- a/session.go +++ b/session.go @@ -355,7 +355,7 @@ func ParseURL(url string) (*DialInfo, error) { safe := Safe{} for _, opt := range uinfo.options { switch opt.key { - case "ssl": + case "ssl", "tls": if v, err := strconv.ParseBool(opt.value); err == nil && v { ssl = true } @@ -363,7 +363,7 @@ func ParseURL(url string) (*DialInfo, error) { source = opt.value case "authMechanism": mechanism = opt.value - case "sslCAFile": + case "sslCAFile", "tlsCAFile": sslCAFile = opt.value case "gssapiServiceName": service = opt.value