/
mongodb_sspi.js
133 lines (112 loc) · 4.67 KB
/
mongodb_sspi.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
var DbCommand = require('../commands/db_command').DbCommand
, utils = require('../utils')
, format = require('util').format;
// Kerberos class
var Kerberos = null;
// Try to grab the Kerberos class
try {
Kerberos = require('kerberos').Kerberos
// Authentication process for Mongo
MongoAuthProcess = require('kerberos').processes.MongoAuthProcess
} catch(err) {console.dir(err)}
var authenticate = function(db, username, password, authdb, options, callback) {
var numberOfConnections = 0;
var errorObject = null;
// We don't have the Kerberos library
if(Kerberos == null) return callback(new Error("Kerberos library is not installed"));
if(options['connection'] != null) {
//if a connection was explicitly passed on options, then we have only one...
numberOfConnections = 1;
} else {
// Get the amount of connections in the pool to ensure we have authenticated all comments
numberOfConnections = db.serverConfig.allRawConnections().length;
options['onAll'] = true;
}
var connection = db.serverConfig.allRawConnections()[0];
// Grab all the connections
var connections = db.serverConfig.allRawConnections();
var error = null;
// Authenticate all connections
for(var i = 0; i < numberOfConnections; i++) {
// Start Auth process for a connection
SSIPAuthenticate(db, username, password, authdb, connections[i], function(err, result) {
// Adjust number of connections left to connect
numberOfConnections = numberOfConnections - 1;
// If we have an error save it
if(err) error = err;
// We are done
if(numberOfConnections == 0) {
if(err) return callback(err, false);
// We authenticated correctly save the credentials
db.auths = [{'username':username, 'password':password, 'authdb': authdb, 'authMechanism': 'GSSAPI'}];
// Return valid callback
return callback(null, true);
}
});
}
}
var SSIPAuthenticate = function(db, username, password, authdb, connection, callback) {
// --------------------------------------------------------------
// Async Version
// --------------------------------------------------------------
var command = {
saslStart: 1
, mechanism: 'GSSAPI'
, payload: ''
, autoAuthorize: 1
};
// Create authenticator
var mongo_auth_process = new MongoAuthProcess(connection.socketOptions.host, connection.socketOptions.port);
// Execute first sasl step
db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
if(err) return callback(err);
doc = doc.documents[0];
mongo_auth_process.init(username, password, function(err) {
if(err) return callback(err);
mongo_auth_process.transition(doc.payload, function(err, payload) {
if(err) return callback(err);
// Perform the next step against mongod
var command = {
saslContinue: 1
, conversationId: doc.conversationId
, payload: payload
};
// Execute the command
db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
if(err) return callback(err);
doc = doc.documents[0];
mongo_auth_process.transition(doc.payload, function(err, payload) {
if(err) return callback(err);
// Perform the next step against mongod
var command = {
saslContinue: 1
, conversationId: doc.conversationId
, payload: payload
};
// Execute the command
db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
if(err) return callback(err);
doc = doc.documents[0];
mongo_auth_process.transition(doc.payload, function(err, payload) {
// Perform the next step against mongod
var command = {
saslContinue: 1
, conversationId: doc.conversationId
, payload: payload
};
// Execute the command
db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
if(err) return callback(err);
doc = doc.documents[0];
if(doc.done) return callback(null, true);
callback(new Error("Authentication failed"), false);
});
});
});
});
});
});
});
});
}
exports.authenticate = authenticate;