Files
my-dev-server2/vscode-server-linux-x64-web/node_modules/kerberos/lib/auth_processes/mongodb.js
mol 263cb5ef03
Some checks failed
continuous-integration/drone/push Build is failing
test
2024-07-06 22:23:31 +08:00

152 lines
3.7 KiB
JavaScript

'use strict';
const dns = require('dns');
const kerberos = require('../kerberos');
class MongoAuthProcess {
constructor(host, port, serviceName, options) {
options = options || {};
this.host = host;
this.port = port;
// Set up service name
this.serviceName = serviceName || options.gssapiServiceName || 'mongodb';
// Options
this.canonicalizeHostName =
typeof options.gssapiCanonicalizeHostName === 'boolean'
? options.gssapiCanonicalizeHostName
: false;
// Set up first transition
this._transition = firstTransition(this);
// Number of retries
this.retries = 10;
}
init(username, password, callback) {
const self = this;
this.username = username;
this.password = password;
// Canonicialize host name if needed
function performGssapiCanonicalizeHostName(canonicalizeHostName, host, callback) {
if (!canonicalizeHostName) return callback();
// Attempt to resolve the host name
dns.resolveCname(host, (err, r) => {
if (err) return callback(err);
// Get the first resolve host id
if (Array.isArray(r) && r.length > 0) {
self.host = r[0];
}
callback();
});
}
// Canonicialize host name if needed
performGssapiCanonicalizeHostName(this.canonicalizeHostName, this.host, err => {
if (err) return callback(err);
const initOptions = {};
if (password != null) {
Object.assign(initOptions, { user: username, password });
}
const service =
process.platform === 'win32'
? `${this.serviceName}/${this.host}`
: `${this.serviceName}@${this.host}`;
kerberos.initializeClient(service, initOptions, (err, client) => {
if (err) return callback(err, null);
self.client = client;
callback(null, client);
});
});
}
transition(payload, callback) {
if (this._transition == null) {
return callback(new Error('Transition finished'));
}
this._transition(payload, callback);
}
}
function firstTransition(auth) {
return (payload, callback) => {
auth.client.step('', (err, response) => {
if (err) return callback(err);
// Set up the next step
auth._transition = secondTransition(auth);
// Return the payload
callback(null, response);
});
};
}
function secondTransition(auth) {
return (payload, callback) => {
auth.client.step(payload, (err, response) => {
if (err && auth.retries === 0) return callback(err);
// Attempt to re-establish a context
if (err) {
// Adjust the number of retries
auth.retries = auth.retries - 1;
// Call same step again
return auth.transition(payload, callback);
}
// Set up the next step
auth._transition = thirdTransition(auth);
// Return the payload
callback(null, response || '');
});
};
}
function thirdTransition(auth) {
return (payload, callback) => {
// GSS Client Unwrap
auth.client.unwrap(payload, (err, response) => {
if (err) return callback(err, false);
// Wrap the response
auth.client.wrap(response, { user: auth.username }, (err, wrapped) => {
if (err) return callback(err, false);
// Set up the next step
auth._transition = fourthTransition(auth);
// Return the payload
callback(null, wrapped);
});
});
};
}
function fourthTransition(auth) {
return (payload, callback) => {
// Set the transition to null
auth._transition = null;
// Callback with valid authentication
callback(null, true);
};
}
// Set the process
module.exports = {
MongoAuthProcess
};