Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-3351): use hostname canonicalization #3122

Merged
merged 10 commits into from Feb 8, 2022
4 changes: 3 additions & 1 deletion src/cmap/auth/gssapi.ts
Expand Up @@ -13,7 +13,9 @@ import { Callback, ns } from '../../utils';
import { AuthContext, AuthProvider } from './auth_provider';

type MechanismProperties = {
/** @deprecated use `CANONICALIZE_HOST_NAME` instead */
gssapiCanonicalizeHostName?: boolean;
CANONICALIZE_HOST_NAME?: boolean;
SERVICE_NAME?: string;
SERVICE_REALM?: string;
};
Expand Down Expand Up @@ -174,7 +176,7 @@ function performGssapiCanonicalizeHostName(
mechanismProperties: MechanismProperties,
callback: Callback<string>
): void {
if (!mechanismProperties.gssapiCanonicalizeHostName) return callback(undefined, host);
if (!mechanismProperties.CANONICALIZE_HOST_NAME) return callback(undefined, host);
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved

// Attempt to resolve the host name
dns.resolveCname(host, (err, r) => {
Expand Down
10 changes: 9 additions & 1 deletion src/cmap/auth/mongo_credentials.ts
@@ -1,7 +1,7 @@
// Resolves the default auth mechanism according to

import type { Document } from '../../bson';
import { MongoAPIError, MongoMissingCredentialsError } from '../../error';
import { emitWarningOnce } from '../../utils';
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './providers';

// https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
Expand Down Expand Up @@ -89,6 +89,14 @@ export class MongoCredentials {
}
}

if ('gssapiCanonicalizeHostName' in this.mechanismProperties) {
emitWarningOnce(
'gssapiCanonicalizeHostName is deprecated. Please use CANONICALIZE_HOST_NAME instead.'
);
this.mechanismProperties.CANONICALIZE_HOST_NAME =
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
this.mechanismProperties.gssapiCanonicalizeHostName;
}

Object.freeze(this.mechanismProperties);
Object.freeze(this);
}
Expand Down
35 changes: 35 additions & 0 deletions test/manual/kerberos.test.js
@@ -1,8 +1,11 @@
'use strict';
const { MongoClient } = require('../../src');
const chai = require('chai');
const sinon = require('sinon');
dariakp marked this conversation as resolved.
Show resolved Hide resolved
const dns = require('dns');

const expect = chai.expect;
chai.use(require('sinon-chai'));

function verifyKerberosAuthentication(client, done) {
client
Expand All @@ -23,6 +26,16 @@ function verifyKerberosAuthentication(client, done) {
}

describe('Kerberos', function () {
const sandbox = sinon.createSandbox();

beforeEach(function () {
sandbox.spy(dns);
});

afterEach(function () {
sandbox.restore();
});

if (process.env.MONGODB_URI == null) {
console.error('skipping Kerberos tests, MONGODB_URI environment variable is not defined');
return;
Expand Down Expand Up @@ -51,6 +64,28 @@ describe('Kerberos', function () {
});
});

it('validate that gssapiCanonicalizeHostName can be passed in', function (done) {
const client = new MongoClient(
`${krb5Uri}&authMechanismProperties=SERVICE_NAME:mongodb,gssapiCanonicalizeHostName:true&maxPoolSize=1`
);
client.connect(function (err, client) {
if (err) return done(err);
expect(dns.resolveCname).to.be.calledOnce;
verifyKerberosAuthentication(client, done);
});
});

it('validate that CANONICALIZE_HOST_NAME can be passed in', function (done) {
const client = new MongoClient(
`${krb5Uri}&authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:true&maxPoolSize=1`
);
client.connect(function (err, client) {
if (err) return done(err);
expect(dns.resolveCname).to.be.calledOnce;
verifyKerberosAuthentication(client, done);
});
});

// Unskip this test when a proper setup is available - see NODE-3060
it.skip('validate that SERVICE_REALM and CANONICALIZE_HOST_NAME can be passed in', function (done) {
dariakp marked this conversation as resolved.
Show resolved Hide resolved
const client = new MongoClient(
Expand Down