1
2
3
4
5
6
7 package auth
8
9 import (
10 "bytes"
11 "context"
12 "testing"
13
14 "go.mongodb.org/mongo-driver/bson"
15 "go.mongodb.org/mongo-driver/internal/assert"
16 "go.mongodb.org/mongo-driver/internal/handshake"
17 "go.mongodb.org/mongo-driver/mongo/address"
18 "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
19 "go.mongodb.org/mongo-driver/x/mongo/driver/drivertest"
20 )
21
22 var (
23 x509Response bsoncore.Document = bsoncore.BuildDocumentFromElements(nil,
24 bsoncore.AppendStringElement(nil, "dbname", "$external"),
25 bsoncore.AppendStringElement(nil, "user", "username"),
26 bsoncore.AppendInt32Element(nil, "ok", 1),
27 )
28 )
29
30 func TestSpeculativeX509(t *testing.T) {
31 t.Run("speculative response included", func(t *testing.T) {
32
33
34
35 authenticator, err := CreateAuthenticator("MONGODB-X509", &Cred{})
36 assert.Nil(t, err, "CreateAuthenticator error: %v", err)
37 handshaker := Handshaker(nil, &HandshakeOptions{
38 Authenticator: authenticator,
39 })
40
41 numResponses := 1
42 responses := make(chan []byte, numResponses)
43 writeReplies(responses, createSpeculativeX509Handshake()...)
44
45 conn := &drivertest.ChannelConn{
46 Written: make(chan []byte, numResponses),
47 ReadResp: responses,
48 }
49
50 info, err := handshaker.GetHandshakeInformation(context.Background(), address.Address("localhost:27017"), conn)
51 assert.Nil(t, err, "GetDescription error: %v", err)
52 assert.NotNil(t, info.SpeculativeAuthenticate, "desc.SpeculativeAuthenticate not set")
53 conn.Desc = info.Description
54
55 err = handshaker.FinishHandshake(context.Background(), conn)
56 assert.Nil(t, err, "FinishHandshake error: %v", err)
57 assert.Equal(t, 0, len(conn.ReadResp), "%d messages left unread", len(conn.ReadResp))
58
59 assert.Equal(t, numResponses, len(conn.Written), "expected %d wire messages to be sent, got %d",
60 numResponses, len(conn.Written))
61 hello, err := drivertest.GetCommandFromQueryWireMessage(<-conn.Written)
62 assert.Nil(t, err, "error parsing hello command: %v", err)
63 assertCommandName(t, hello, handshake.LegacyHello)
64
65 authDocVal, err := hello.LookupErr("speculativeAuthenticate")
66 assert.Nil(t, err, "expected command %s to contain 'speculativeAuthenticate'", bson.Raw(hello))
67 authDoc := authDocVal.Document()
68 expectedAuthDoc := bsoncore.BuildDocumentFromElements(nil,
69 bsoncore.AppendInt32Element(nil, "authenticate", 1),
70 bsoncore.AppendStringElement(nil, "mechanism", "MONGODB-X509"),
71 )
72 assert.True(t, bytes.Equal(expectedAuthDoc, authDoc), "expected speculative auth document %s, got %s",
73 expectedAuthDoc, authDoc)
74 })
75 t.Run("speculative response not included", func(t *testing.T) {
76
77
78
79 authenticator, err := CreateAuthenticator("MONGODB-X509", &Cred{})
80 assert.Nil(t, err, "CreateAuthenticator error: %v", err)
81 handshaker := Handshaker(nil, &HandshakeOptions{
82 Authenticator: authenticator,
83 })
84
85 numResponses := 2
86 responses := make(chan []byte, numResponses)
87 writeReplies(responses, createRegularX509Handshake()...)
88
89 conn := &drivertest.ChannelConn{
90 Written: make(chan []byte, numResponses),
91 ReadResp: responses,
92 }
93
94 info, err := handshaker.GetHandshakeInformation(context.Background(), address.Address("localhost:27017"), conn)
95 assert.Nil(t, err, "GetDescription error: %v", err)
96 assert.Nil(t, info.SpeculativeAuthenticate, "expected desc.SpeculativeAuthenticate to be unset, got %s",
97 bson.Raw(info.SpeculativeAuthenticate))
98 conn.Desc = info.Description
99
100 err = handshaker.FinishHandshake(context.Background(), conn)
101 assert.Nil(t, err, "FinishHandshake error: %v", err)
102 assert.Equal(t, 0, len(conn.ReadResp), "%d messages left unread", len(conn.ReadResp))
103
104 assert.Equal(t, numResponses, len(conn.Written), "expected %d wire messages to be sent, got %d",
105 numResponses, len(conn.Written))
106 hello, err := drivertest.GetCommandFromQueryWireMessage(<-conn.Written)
107 assert.Nil(t, err, "error parsing hello command: %v", err)
108 assertCommandName(t, hello, handshake.LegacyHello)
109 _, err = hello.LookupErr("speculativeAuthenticate")
110 assert.Nil(t, err, "expected command %s to contain 'speculativeAuthenticate'", bson.Raw(hello))
111
112 authenticate, err := drivertest.GetCommandFromMsgWireMessage(<-conn.Written)
113 assert.Nil(t, err, "error parsing authenticate command: %v", err)
114 assertCommandName(t, authenticate, "authenticate")
115 })
116 }
117
118
119
120
121
122 func createSpeculativeX509Handshake() []bsoncore.Document {
123 firstAuthElem := bsoncore.AppendDocumentElement(nil, "speculativeAuthenticate", x509Response)
124 hello := bsoncore.BuildDocumentFromElements(nil, append(handshakeHelloElements, firstAuthElem)...)
125 return []bsoncore.Document{hello}
126 }
127
128
129
130
131
132
133 func createRegularX509Handshake() []bsoncore.Document {
134 hello := bsoncore.BuildDocumentFromElements(nil, handshakeHelloElements...)
135 return []bsoncore.Document{hello, x509Response}
136 }
137
View as plain text