Skip to content

Commit b8af7cf

Browse files
tbruyelledomodwyer
authored andcommitted
Add support for ssl dial string (#184)
* Add support for ssl dial string * Ensure we dont override user settings * update examples * update ssl value parsing * PingSsl test * skip test requiring system certificates
1 parent 728c7df commit b8af7cf

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

example_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,21 @@ func ExampleSession_concurrency() {
137137

138138
func ExampleDial_usingSSL() {
139139
// To connect via TLS/SSL (enforced for MongoDB Atlas for example) requires
140-
// configuring the dialer to use a TLS connection:
140+
// to set the ssl query param to true.
141+
url := "mongodb://localhost:40003?ssl=true"
142+
143+
session, err := Dial(url)
144+
if err != nil {
145+
panic(err)
146+
}
147+
148+
// Use session as normal
149+
session.Close()
150+
}
151+
152+
func ExampleDial_tlsConfig() {
153+
// You can define a custom tlsConfig, this one enables TLS, like if you have
154+
// ssl=true in the connection string.
141155
url := "mongodb://localhost:40003"
142156

143157
tlsConfig := &tls.Config{

session.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ package mgo
2828

2929
import (
3030
"crypto/md5"
31+
"crypto/tls"
3132
"crypto/x509"
3233
"crypto/x509/pkix"
3334
"encoding/asn1"
@@ -294,6 +295,12 @@ const (
294295
// The identifier of this client application. This parameter is used to
295296
// annotate logs / profiler output and cannot exceed 128 bytes.
296297
//
298+
// ssl=<true|false>
299+
//
300+
// true: Initiate the connection with TLS/SSL.
301+
// false: Initiate the connection without TLS/SSL.
302+
// The default value is false.
303+
//
297304
// Relevant documentation:
298305
//
299306
// http://docs.mongodb.org/manual/reference/connection-string/
@@ -331,6 +338,7 @@ func ParseURL(url string) (*DialInfo, error) {
331338
if err != nil {
332339
return nil, err
333340
}
341+
ssl := false
334342
direct := false
335343
mechanism := ""
336344
service := ""
@@ -345,6 +353,10 @@ func ParseURL(url string) (*DialInfo, error) {
345353
safe := Safe{}
346354
for _, opt := range uinfo.options {
347355
switch opt.key {
356+
case "ssl":
357+
if v, err := strconv.ParseBool(opt.value); err == nil && v {
358+
ssl = true
359+
}
348360
case "authSource":
349361
source = opt.value
350362
case "authMechanism":
@@ -460,6 +472,13 @@ func ParseURL(url string) (*DialInfo, error) {
460472
MinPoolSize: minPoolSize,
461473
MaxIdleTimeMS: maxIdleTimeMS,
462474
}
475+
if ssl && info.DialServer == nil {
476+
// Set DialServer only if nil, we don't want to override user's settings.
477+
info.DialServer = func(addr *ServerAddr) (net.Conn, error) {
478+
conn, err := tls.Dial("tcp", addr.String(), &tls.Config{})
479+
return conn, err
480+
}
481+
}
463482
return &info, nil
464483
}
465484

session_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ func (s *S) TestPing(c *C) {
8787
c.Assert(stats.ReceivedOps, Equals, 1)
8888
}
8989

90+
func (s *S) TestPingSsl(c *C) {
91+
c.Skip("this test requires the usage of the system provided certificates")
92+
session, err := mgo.Dial("localhost:40001?ssl=true")
93+
c.Assert(err, IsNil)
94+
defer session.Close()
95+
96+
c.Assert(session.Ping(), IsNil)
97+
}
98+
9099
func (s *S) TestDialIPAddress(c *C) {
91100
session, err := mgo.Dial("127.0.0.1:40001")
92101
c.Assert(err, IsNil)
@@ -135,6 +144,25 @@ func (s *S) TestURLParsing(c *C) {
135144
}
136145
}
137146

147+
func (s *S) TestURLSsl(c *C) {
148+
type test struct {
149+
url string
150+
nilDialServer bool
151+
}
152+
153+
tests := []test{
154+
{"localhost:40001", true},
155+
{"localhost:40001?ssl=false", true},
156+
{"localhost:40001?ssl=true", false},
157+
}
158+
159+
for _, test := range tests {
160+
info, err := mgo.ParseURL(test.url)
161+
c.Assert(err, IsNil)
162+
c.Assert(info.DialServer == nil, Equals, test.nilDialServer)
163+
}
164+
}
165+
138166
func (s *S) TestURLReadPreference(c *C) {
139167
type test struct {
140168
url string

0 commit comments

Comments
 (0)