diff --git a/src/cmap/auth/gssapi.ts b/src/cmap/auth/gssapi.ts index c55acacb07..56d5206cce 100644 --- a/src/cmap/auth/gssapi.ts +++ b/src/cmap/auth/gssapi.ts @@ -16,6 +16,7 @@ type MechanismProperties = { /** @deprecated use `CANONICALIZE_HOST_NAME` instead */ gssapiCanonicalizeHostName?: boolean; CANONICALIZE_HOST_NAME?: boolean; + SERVICE_HOST?: string; SERVICE_NAME?: string; SERVICE_REALM?: string; }; @@ -72,6 +73,7 @@ export class GSSAPI extends AuthProvider { }); } } + function makeKerberosClient(authContext: AuthContext, callback: Callback): void { const { hostAddress } = authContext.options; const { credentials } = authContext; @@ -102,7 +104,8 @@ function makeKerberosClient(authContext: AuthContext, callback: Callback { + expectedError = e; + }); + if (!expectedError) { + expect.fail('Expected connect with invalid SERVICE_HOST to fail'); + } + expect(expectedError.message).to.match(/GSS failure|UNKNOWN_SERVER/); + }); + }); + + context('when the SERVICE_HOST is valid', function () { + const client = new MongoClient(`${krb5Uri}&maxPoolSize=1`, { + authMechanismProperties: { + SERVICE_HOST: 'ldaptest.10gen.cc' + } + }); + + it('authenticates', function (done) { + client.connect(function (err, client) { + expect(err).to.not.exist; + verifyKerberosAuthentication(client, done); + }); + }); + }); + }); + describe('should use the SERVICE_NAME property', function () { it('as an option handed to the MongoClient', function (done) { const client = new MongoClient(`${krb5Uri}&maxPoolSize=1`, { diff --git a/test/spec/auth/connection-string.json b/test/spec/auth/connection-string.json index 7fc3c5c45f..ea2bdf0eba 100644 --- a/test/spec/auth/connection-string.json +++ b/test/spec/auth/connection-string.json @@ -80,7 +80,7 @@ }, { "description": "should accept generic mechanism property (GSSAPI)", - "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true", + "uri": "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com", "valid": true, "credential": { "username": "user@DOMAIN.COM", @@ -89,7 +89,8 @@ "mechanism": "GSSAPI", "mechanism_properties": { "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true + "CANONICALIZE_HOST_NAME": true, + "SERVICE_HOST": "example.com" } } }, @@ -368,4 +369,4 @@ "valid": false } ] -} \ No newline at end of file +} diff --git a/test/spec/auth/connection-string.yml b/test/spec/auth/connection-string.yml index c4f34def63..70a76afe9b 100644 --- a/test/spec/auth/connection-string.yml +++ b/test/spec/auth/connection-string.yml @@ -64,7 +64,7 @@ tests: SERVICE_NAME: "mongodb" - description: "should accept generic mechanism property (GSSAPI)" - uri: "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true" + uri: "mongodb://user%40DOMAIN.COM@localhost/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com" valid: true credential: username: "user@DOMAIN.COM" @@ -74,6 +74,7 @@ tests: mechanism_properties: SERVICE_NAME: "other" CANONICALIZE_HOST_NAME: true + SERVICE_HOST: "example.com" - description: "should accept the password (GSSAPI)" uri: "mongodb://user%40DOMAIN.COM:password@localhost/?authMechanism=GSSAPI&authSource=$external" diff --git a/test/spec/connection-string/valid-auth.json b/test/spec/connection-string/valid-auth.json index 672777ff84..3b00b0e503 100644 --- a/test/spec/connection-string/valid-auth.json +++ b/test/spec/connection-string/valid-auth.json @@ -263,7 +263,7 @@ }, { "description": "Escaped username (GSSAPI)", - "uri": "mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authMechanism=GSSAPI", + "uri": "mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com&authMechanism=GSSAPI", "valid": true, "warning": false, "hosts": [ @@ -282,7 +282,8 @@ "authmechanism": "GSSAPI", "authmechanismproperties": { "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true + "CANONICALIZE_HOST_NAME": true, + "SERVICE_HOST": "example.com" } } }, diff --git a/test/spec/connection-string/valid-auth.yml b/test/spec/connection-string/valid-auth.yml index 1319a41888..2f8dc4da0f 100644 --- a/test/spec/connection-string/valid-auth.yml +++ b/test/spec/connection-string/valid-auth.yml @@ -206,7 +206,7 @@ tests: authmechanism: "MONGODB-X509" - description: "Escaped username (GSSAPI)" - uri: "mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authMechanism=GSSAPI" + uri: "mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com&authMechanism=GSSAPI" valid: true warning: false hosts: @@ -222,7 +222,8 @@ tests: authmechanism: "GSSAPI" authmechanismproperties: SERVICE_NAME: "other" - CANONICALIZE_HOST_NAME: true + CANONICALIZE_HOST_NAME: true, + SERVICE_HOST: "example.com" - description: "At-signs in options aren't part of the userinfo" uri: "mongodb://alice:secret@example.com/admin?replicaset=my@replicaset" diff --git a/test/spec/uri-options/auth-options.json b/test/spec/uri-options/auth-options.json index fadbac35d2..612d9144fb 100644 --- a/test/spec/uri-options/auth-options.json +++ b/test/spec/uri-options/auth-options.json @@ -2,7 +2,7 @@ "tests": [ { "description": "Valid auth options are parsed correctly (GSSAPI)", - "uri": "mongodb://foo:bar@example.com/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authSource=$external", + "uri": "mongodb://foo:bar@example.com/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com&authSource=$external", "valid": true, "warning": false, "hosts": null, @@ -11,7 +11,8 @@ "authMechanism": "GSSAPI", "authMechanismProperties": { "SERVICE_NAME": "other", - "CANONICALIZE_HOST_NAME": true + "CANONICALIZE_HOST_NAME": true, + "SERVICE_HOST": "example.com" }, "authSource": "$external" } diff --git a/test/spec/uri-options/auth-options.yml b/test/spec/uri-options/auth-options.yml index cd63b0738d..45ac1e7915 100644 --- a/test/spec/uri-options/auth-options.yml +++ b/test/spec/uri-options/auth-options.yml @@ -1,7 +1,7 @@ tests: - description: "Valid auth options are parsed correctly (GSSAPI)" - uri: "mongodb://foo:bar@example.com/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authSource=$external" + uri: "mongodb://foo:bar@example.com/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com&authSource=$external" valid: true warning: false hosts: ~ @@ -10,7 +10,8 @@ tests: authMechanism: "GSSAPI" authMechanismProperties: SERVICE_NAME: "other" - CANONICALIZE_HOST_NAME: true + CANONICALIZE_HOST_NAME: true, + SERVICE_HOST: "example.com" authSource: "$external" - description: "Valid auth options are parsed correctly (SCRAM-SHA-1)" diff --git a/test/unit/connection_string.test.ts b/test/unit/connection_string.test.ts index c051a95221..9de26fd23b 100644 --- a/test/unit/connection_string.test.ts +++ b/test/unit/connection_string.test.ts @@ -77,9 +77,10 @@ describe('Connection String', function () { it('should parse `authMechanismProperties`', function () { const options = parseOptions( - 'mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,SERVICE_REALM:blah,CANONICALIZE_HOST_NAME:true&authMechanism=GSSAPI' + 'mongodb://user%40EXAMPLE.COM:secret@localhost/?authMechanismProperties=SERVICE_NAME:other,SERVICE_REALM:blah,CANONICALIZE_HOST_NAME:true,SERVICE_HOST:example.com&authMechanism=GSSAPI' ); expect(options.credentials.mechanismProperties).to.deep.include({ + SERVICE_HOST: 'example.com', SERVICE_NAME: 'other', SERVICE_REALM: 'blah', CANONICALIZE_HOST_NAME: true