@@ -42,6 +42,7 @@ describe('Kerberos', function () {
4242 }
4343 let krb5Uri = process . env . MONGODB_URI ;
4444 const parts = krb5Uri . split ( '@' , 2 ) ;
45+ const host = parts [ 1 ] . split ( '/' ) [ 0 ] ;
4546
4647 if ( ! process . env . KRB5_PRINCIPAL ) {
4748 console . error ( 'skipping Kerberos tests, KRB5_PRINCIPAL environment variable is not defined' ) ;
@@ -74,24 +75,185 @@ describe('Kerberos', function () {
7475 ) ;
7576 client . connect ( function ( err , client ) {
7677 if ( err ) return done ( err ) ;
77- expect ( dns . resolveCname ) . to . be . calledOnce ;
78+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
7879 verifyKerberosAuthentication ( client , done ) ;
7980 } ) ;
8081 } ) ;
8182
82- it ( 'validate that CANONICALIZE_HOST_NAME can be passed in' , function ( done ) {
83- if ( process . platform === 'darwin' ) {
84- this . test . skipReason = 'DNS does not resolve with proper CNAME record on evergreen MacOS' ;
85- this . skip ( ) ;
86- }
87- const client = new MongoClient (
88- `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:true&maxPoolSize=1`
89- ) ;
90- client . connect ( function ( err , client ) {
91- if ( err ) return done ( err ) ;
92- expect ( dns . resolveCname ) . to . be . calledOnce ;
93- verifyKerberosAuthentication ( client , done ) ;
83+ context ( 'when passing in CANONICALIZE_HOST_NAME' , function ( ) {
84+ beforeEach ( function ( ) {
85+ if ( process . platform === 'darwin' ) {
86+ this . currentTest . skipReason =
87+ 'DNS does not resolve with proper CNAME record on evergreen MacOS' ;
88+ this . skip ( ) ;
89+ }
90+ } ) ;
91+
92+ context ( 'when the value is forward' , function ( ) {
93+ it ( 'authenticates with a forward cname lookup' , function ( done ) {
94+ const client = new MongoClient (
95+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:forward&maxPoolSize=1`
96+ ) ;
97+ client . connect ( function ( err , client ) {
98+ if ( err ) return done ( err ) ;
99+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
100+ verifyKerberosAuthentication ( client , done ) ;
101+ } ) ;
102+ } ) ;
94103 } ) ;
104+
105+ for ( const option of [ false , 'none' ] ) {
106+ context ( `when the value is ${ option } ` , function ( ) {
107+ it ( 'authenticates with no dns lookups' , function ( done ) {
108+ const client = new MongoClient (
109+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
110+ ) ;
111+ client . connect ( function ( err , client ) {
112+ if ( err ) return done ( err ) ;
113+ expect ( dns . resolveCname ) . to . not . be . called ;
114+ // 2 calls when establishing connection - expect no third call.
115+ expect ( dns . lookup ) . to . be . calledTwice ;
116+ verifyKerberosAuthentication ( client , done ) ;
117+ } ) ;
118+ } ) ;
119+ } ) ;
120+ }
121+
122+ for ( const option of [ true , 'forwardAndReverse' ] ) {
123+ context ( `when the value is ${ option } ` , function ( ) {
124+ context ( 'when the reverse lookup succeeds' , function ( ) {
125+ const resolveStub = ( address , callback ) => {
126+ callback ( null , [ host ] ) ;
127+ } ;
128+
129+ beforeEach ( function ( ) {
130+ dns . resolvePtr . restore ( ) ;
131+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
132+ } ) ;
133+
134+ it ( 'authenticates with a forward dns lookup and a reverse ptr lookup' , function ( done ) {
135+ const client = new MongoClient (
136+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
137+ ) ;
138+ client . connect ( function ( err , client ) {
139+ if ( err ) return done ( err ) ;
140+ // 2 calls to establish connection, 1 call in canonicalization.
141+ expect ( dns . lookup ) . to . be . calledThrice ;
142+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
143+ verifyKerberosAuthentication ( client , done ) ;
144+ } ) ;
145+ } ) ;
146+ } ) ;
147+
148+ context ( 'when the reverse lookup is empty' , function ( ) {
149+ const resolveStub = ( address , callback ) => {
150+ callback ( null , [ ] ) ;
151+ } ;
152+
153+ beforeEach ( function ( ) {
154+ dns . resolvePtr . restore ( ) ;
155+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
156+ } ) ;
157+
158+ it ( 'authenticates with a fallback cname lookup' , function ( done ) {
159+ const client = new MongoClient (
160+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
161+ ) ;
162+ client . connect ( function ( err , client ) {
163+ if ( err ) return done ( err ) ;
164+ // 2 calls to establish connection, 1 call in canonicalization.
165+ expect ( dns . lookup ) . to . be . calledThrice ;
166+ // This fails.
167+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
168+ // Expect the fallback to the host name.
169+ expect ( dns . resolveCname ) . to . not . be . called ;
170+ verifyKerberosAuthentication ( client , done ) ;
171+ } ) ;
172+ } ) ;
173+ } ) ;
174+
175+ context ( 'when the reverse lookup fails' , function ( ) {
176+ const resolveStub = ( address , callback ) => {
177+ callback ( new Error ( 'not found' ) , null ) ;
178+ } ;
179+
180+ beforeEach ( function ( ) {
181+ dns . resolvePtr . restore ( ) ;
182+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
183+ } ) ;
184+
185+ it ( 'authenticates with a fallback cname lookup' , function ( done ) {
186+ const client = new MongoClient (
187+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
188+ ) ;
189+ client . connect ( function ( err , client ) {
190+ if ( err ) return done ( err ) ;
191+ // 2 calls to establish connection, 1 call in canonicalization.
192+ expect ( dns . lookup ) . to . be . calledThrice ;
193+ // This fails.
194+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
195+ // Expect the fallback to be called.
196+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
197+ verifyKerberosAuthentication ( client , done ) ;
198+ } ) ;
199+ } ) ;
200+ } ) ;
201+
202+ context ( 'when the cname lookup fails' , function ( ) {
203+ const resolveStub = ( address , callback ) => {
204+ callback ( new Error ( 'not found' ) , null ) ;
205+ } ;
206+
207+ beforeEach ( function ( ) {
208+ dns . resolveCname . restore ( ) ;
209+ sinon . stub ( dns , 'resolveCname' ) . callsFake ( resolveStub ) ;
210+ } ) ;
211+
212+ it ( 'authenticates with a fallback host name' , function ( done ) {
213+ const client = new MongoClient (
214+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
215+ ) ;
216+ client . connect ( function ( err , client ) {
217+ if ( err ) return done ( err ) ;
218+ // 2 calls to establish connection, 1 call in canonicalization.
219+ expect ( dns . lookup ) . to . be . calledThrice ;
220+ // This fails.
221+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
222+ // Expect the fallback to be called.
223+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
224+ verifyKerberosAuthentication ( client , done ) ;
225+ } ) ;
226+ } ) ;
227+ } ) ;
228+
229+ context ( 'when the cname lookup is empty' , function ( ) {
230+ const resolveStub = ( address , callback ) => {
231+ callback ( null , [ ] ) ;
232+ } ;
233+
234+ beforeEach ( function ( ) {
235+ dns . resolveCname . restore ( ) ;
236+ sinon . stub ( dns , 'resolveCname' ) . callsFake ( resolveStub ) ;
237+ } ) ;
238+
239+ it ( 'authenticates with a fallback host name' , function ( done ) {
240+ const client = new MongoClient (
241+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
242+ ) ;
243+ client . connect ( function ( err , client ) {
244+ if ( err ) return done ( err ) ;
245+ // 2 calls to establish connection, 1 call in canonicalization.
246+ expect ( dns . lookup ) . to . be . calledThrice ;
247+ // This fails.
248+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
249+ // Expect the fallback to be called.
250+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
251+ verifyKerberosAuthentication ( client , done ) ;
252+ } ) ;
253+ } ) ;
254+ } ) ;
255+ } ) ;
256+ }
95257 } ) ;
96258
97259 // Unskip this test when a proper setup is available - see NODE-3060
0 commit comments