Skip to content

Commit 033b6e7

Browse files
authored
fix: move kerberos client setup from prepare to auth (#2608)
A new KerberosClient should be made for each individual authentication attempt, rather than the current approach which creates one and shares it for all attempts. NODE-2859
1 parent f0cee7a commit 033b6e7

File tree

1 file changed

+66
-66
lines changed

1 file changed

+66
-66
lines changed

lib/core/auth/gssapi.js

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,88 +5,44 @@ const AuthProvider = require('./auth_provider').AuthProvider;
55
const retrieveKerberos = require('../utils').retrieveKerberos;
66
const MongoError = require('../error').MongoError;
77

8-
const kGssapiClient = Symbol('GSSAPI_CLIENT');
98
let kerberos;
109

1110
class GSSAPI extends AuthProvider {
12-
prepare(handshakeDoc, authContext, callback) {
13-
const host = authContext.options.host;
14-
const port = authContext.options.port;
15-
const credentials = authContext.credentials;
16-
if (!host || !port || !credentials) {
17-
return callback(
18-
new MongoError(
19-
`Connection must specify: ${host ? 'host' : ''}, ${port ? 'port' : ''}, ${
20-
credentials ? 'host' : 'credentials'
21-
}.`
22-
)
23-
);
24-
}
25-
if (kerberos == null) {
26-
try {
27-
kerberos = retrieveKerberos();
28-
} catch (e) {
29-
return callback(e);
30-
}
31-
}
32-
const username = credentials.username;
33-
const password = credentials.password;
34-
const mechanismProperties = credentials.mechanismProperties;
35-
const serviceName =
36-
mechanismProperties['gssapiservicename'] ||
37-
mechanismProperties['gssapiServiceName'] ||
38-
'mongodb';
39-
performGssapiCanonicalizeHostName(host, mechanismProperties, (err, host) => {
40-
if (err) return callback(err);
41-
const initOptions = {};
42-
if (password != null) {
43-
Object.assign(initOptions, { user: username, password: password });
44-
}
45-
kerberos.initializeClient(
46-
`${serviceName}${process.platform === 'win32' ? '/' : '@'}${host}`,
47-
initOptions,
48-
(err, client) => {
49-
if (err) return callback(new MongoError(err));
50-
if (client == null) return callback();
51-
this[kGssapiClient] = client;
52-
callback(undefined, handshakeDoc);
53-
}
54-
);
55-
});
56-
}
5711
auth(authContext, callback) {
5812
const connection = authContext.connection;
5913
const credentials = authContext.credentials;
6014
if (credentials == null) return callback(new MongoError('credentials required'));
6115
const username = credentials.username;
62-
const client = this[kGssapiClient];
63-
if (client == null) return callback(new MongoError('gssapi client missing'));
6416
function externalCommand(command, cb) {
6517
return connection.command('$external.$cmd', command, cb);
6618
}
67-
client.step('', (err, payload) => {
19+
makeKerberosClient(authContext, (err, client) => {
6820
if (err) return callback(err);
69-
externalCommand(saslStart(payload), (err, response) => {
70-
const result = response.result;
21+
if (client == null) return callback(new MongoError('gssapi client missing'));
22+
client.step('', (err, payload) => {
7123
if (err) return callback(err);
72-
negotiate(client, 10, result.payload, (err, payload) => {
24+
externalCommand(saslStart(payload), (err, response) => {
7325
if (err) return callback(err);
74-
externalCommand(saslContinue(payload, result.conversationId), (err, response) => {
75-
const result = response.result;
26+
const result = response.result;
27+
negotiate(client, 10, result.payload, (err, payload) => {
7628
if (err) return callback(err);
77-
finalize(client, username, result.payload, (err, payload) => {
29+
externalCommand(saslContinue(payload, result.conversationId), (err, response) => {
7830
if (err) return callback(err);
79-
externalCommand(
80-
{
81-
saslContinue: 1,
82-
conversationId: result.conversationId,
83-
payload
84-
},
85-
(err, result) => {
86-
if (err) return callback(err);
87-
callback(undefined, result);
88-
}
89-
);
31+
const result = response.result;
32+
finalize(client, username, result.payload, (err, payload) => {
33+
if (err) return callback(err);
34+
externalCommand(
35+
{
36+
saslContinue: 1,
37+
conversationId: result.conversationId,
38+
payload
39+
},
40+
(err, result) => {
41+
if (err) return callback(err);
42+
callback(undefined, result);
43+
}
44+
);
45+
});
9046
});
9147
});
9248
});
@@ -96,6 +52,50 @@ class GSSAPI extends AuthProvider {
9652
}
9753
module.exports = GSSAPI;
9854

55+
function makeKerberosClient(authContext, callback) {
56+
const host = authContext.options.host;
57+
const port = authContext.options.port;
58+
const credentials = authContext.credentials;
59+
if (!host || !port || !credentials) {
60+
return callback(
61+
new MongoError(
62+
`Connection must specify: ${host ? 'host' : ''}, ${port ? 'port' : ''}, ${
63+
credentials ? 'host' : 'credentials'
64+
}.`
65+
)
66+
);
67+
}
68+
if (kerberos == null) {
69+
try {
70+
kerberos = retrieveKerberos();
71+
} catch (e) {
72+
return callback(e);
73+
}
74+
}
75+
const username = credentials.username;
76+
const password = credentials.password;
77+
const mechanismProperties = credentials.mechanismProperties;
78+
const serviceName =
79+
mechanismProperties['gssapiservicename'] ||
80+
mechanismProperties['gssapiServiceName'] ||
81+
'mongodb';
82+
performGssapiCanonicalizeHostName(host, mechanismProperties, (err, host) => {
83+
if (err) return callback(err);
84+
const initOptions = {};
85+
if (password != null) {
86+
Object.assign(initOptions, { user: username, password: password });
87+
}
88+
kerberos.initializeClient(
89+
`${serviceName}${process.platform === 'win32' ? '/' : '@'}${host}`,
90+
initOptions,
91+
(err, client) => {
92+
if (err) return callback(new MongoError(err));
93+
callback(null, client);
94+
}
95+
);
96+
});
97+
}
98+
9999
function saslStart(payload) {
100100
return {
101101
saslStart: 1,

0 commit comments

Comments
 (0)