Skip to content

Commit

Permalink
Kerberos tests are passing
Browse files Browse the repository at this point in the history
  • Loading branch information
christkv committed Apr 23, 2013
1 parent 97a9a31 commit 99aeb61
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 153 deletions.
2 changes: 1 addition & 1 deletion lib/mongodb/auth/mongodb_gssapi.js
Expand Up @@ -27,7 +27,7 @@ var authenticate = function(db, username, password, authdb, options, callback) {
}

// Grab all the connections
var connections = db.serverConfig.allRawConnections();
var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections();
var error = null;
// Authenticate all connections
for(var i = 0; i < numberOfConnections; i++) {
Expand Down
68 changes: 47 additions & 21 deletions lib/mongodb/connection/base.js
@@ -1,5 +1,8 @@
var EventEmitter = require('events').EventEmitter
, inherits = require('util').inherits;
, inherits = require('util').inherits
, mongodb_cr_authenticate = require('../auth/mongodb_cr.js').authenticate
, mongodb_gssapi_authenticate = require('../auth/mongodb_gssapi.js').authenticate
, mongodb_sspi_authenticate = require('../auth/mongodb_sspi.js').authenticate;

var id = 0;

Expand Down Expand Up @@ -41,18 +44,13 @@ NonExecutedOperationStore.prototype.read = function(op) {
}

NonExecutedOperationStore.prototype.execute_queries = function(executeInsertCommand) {
// console.log("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ execute_queries :: " + this.commands.read.length)
var connection = this.config.checkoutReader();
if(connection == null || connection instanceof Error) return;
// console.dir(connection)
// console.log("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ EXECUTE")

// Write out all the queries
while(this.commands.read.length > 0) {
// Get the next command
var command = this.commands.read.shift();
// // Remove any connection
// if(command['options'] == null) command['options'] = {};
// command['options'].connection = this.config.checkoutReader();
command.options.connection = connection;
// Execute the next command
Expand All @@ -61,11 +59,8 @@ NonExecutedOperationStore.prototype.execute_queries = function(executeInsertComm
}

NonExecutedOperationStore.prototype.execute_writes = function() {
// console.log("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ execute_writes :: " + this.commands.write_reads.length + " :: " + this.commands.write.length)
var connection = this.config.checkoutWriter();
// console.dir(connection)
if(connection == null || connection instanceof Error) return;
// console.log("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ EXECUTE")

// Write out all the queries to the primary
while(this.commands.write_reads.length > 0) {
Expand Down Expand Up @@ -147,6 +142,10 @@ AuthStore.prototype.length = function() {
return this._auths.length;
}

AuthStore.prototype.toArray = function() {
return this._auths.slice(0);
}

/**
* @ignore
*/
Expand All @@ -173,14 +172,50 @@ var Base = function Base() {
*/
inherits(Base, EventEmitter);

/**
* @ignore
*/
Base.prototype._apply_auths = function(db, callback) {
_apply_auths_serially(this, db, this.auth.toArray(), callback);
}

var _apply_auths_serially = function(self, db, auths, callback) {
if(auths.length == 0) return callback(null, null);
// Get the first auth
var auth = auths.shift();
var connections = self.allRawConnections();
var connectionsLeft = connections.length;

// Let's apply it to all raw connections
for(var i = 0; i < connections.length; i++) {
if(auth.authMechanism == 'GSSAPI') {
var options = {connection: connections[i]};

var connectionHandler = function(err, result) {
connectionsLeft = connectionsLeft - 1;
// If no more connections are left return
if(connectionsLeft == 0) {
return _apply_auths_serially(self, db, auths, callback);
}
}

// We have the kerberos library, execute auth process
if(process.platform == 'win32') {
mongodb_sspi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
} else {
mongodb_gssapi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
}
} else if(auth.authMechanism == 'MONGODB-CR') {
mongodb_cr_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
}
}
}

/**
* Fire all the errors
* @ignore
*/
Base.prototype.__executeAllCallbacksWithError = function(err) {
// console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! __executeAllCallbacksWithError")
// console.dir(err)
// console.log(arguments.callee.caller.toString());
// Check all callbacks
var keys = Object.keys(this._callBackStore._notReplied);
// For each key check if it's a callback that needs to be returned
Expand Down Expand Up @@ -216,8 +251,6 @@ Base.prototype.__executeAllCallbacksWithError = function(err) {
* @ignore
*/
Base.prototype.__executeAllServerSpecificErrorCallbacks = function(host, port, err) {
// console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! __executeAllServerSpecificErrorCallbacks")
// console.dir(err)
// Check all callbacks
var keys = Object.keys(this._callBackStore._notReplied);
// For each key check if it's a callback that needs to be returned
Expand Down Expand Up @@ -263,7 +296,6 @@ Base.prototype.__executeAllServerSpecificErrorCallbacks = function(host, port, e
* @api private
*/
Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) {
// console.log('----- _registerHandler :: ' + this._callBackStore.id + " connection :: " + (connection != null ? connection.socketOptions.port : 'no connection'));
// If we have an array of commands, chain them
var chained = Array.isArray(db_command);

Expand Down Expand Up @@ -301,7 +333,6 @@ Base.prototype._registerHandler = function(db_command, raw, connection, exhaust,
* @api private
*/
Base.prototype._reRegisterHandler = function(newId, object, callback) {
// console.log('----- _reRegisterHandler :: ' + this._callBackStore.id)
// Add the callback to the list of handlers
this._callBackStore.once(newId, object.callback.listener);
// Add the information about the reply
Expand All @@ -314,8 +345,6 @@ Base.prototype._reRegisterHandler = function(newId, object, callback) {
* @api private
*/
Base.prototype._callHandler = function(id, document, err) {
// console.log('----- _callHandler :: ' + this._callBackStore.id)
// console.dir(document)
// If there is a callback peform it
if(this._callBackStore.listeners(id).length >= 1) {
// Get info object
Expand All @@ -333,7 +362,6 @@ Base.prototype._callHandler = function(id, document, err) {
* @api private
*/
Base.prototype._hasHandler = function(id) {
// console.log('----- _hasHandler :: ' + this._callBackStore.id)
// If there is a callback peform it
return this._callBackStore.listeners(id).length >= 1;
}
Expand All @@ -344,7 +372,6 @@ Base.prototype._hasHandler = function(id) {
* @api private
*/
Base.prototype._removeHandler = function(id) {
// console.log('----- _removeHandler :: ' + this._callBackStore.id)
// Remove the information
if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id];
// Remove the callback if it's registered
Expand All @@ -359,7 +386,6 @@ Base.prototype._removeHandler = function(id) {
* @api private
*/
Base.prototype._findHandler = function(id) {
// console.log('----- _findHandler :: ' + this._callBackStore.id)
var info = this._callBackStore._notReplied[id];
// Return the callback
return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null}
Expand Down
113 changes: 0 additions & 113 deletions lib/mongodb/connection/repl_set/ha.js
@@ -1,119 +1,6 @@
var DbCommand = require('../../commands/db_command').DbCommand
format = require('util').format;

// var HighAvailabilityProcess = function(replset, options) {
// this.replset = replset;
// this.options = options;
// this.server = null;
// this.state = HighAvailabilityProcess.INIT;
// }

// HighAvailabilityProcess.INIT = 'init';
// HighAvailabilityProcess.RUNNING = 'running';
// HighAvailabilityProcess.STOPPED = 'stopped';

// HighAvailabilityProcess.prototype.start = function() {
// console.log("===== HighAvailabilityProcess.prototype.start")
// if(this.server == null) {
// start_server(this);
// // // Unpack connection options
// // var connectTimeoutMS = this.options.connectTimeoutMS || 30000;
// // // var socketTimeoutMS = self.options.socketTimeoutMS || 30000;
// // var socketTimeoutMS = 30000;
// }
// }

// var start_server = function(self) {
// console.log("===== start_server")

// // Just ensure we don't have a full cycle dependency
// var Db = require('../../db').Db
// var Server = require('../server').Server;

// // Get all possible reader servers
// var candidate_servers = self.replset._state.getAllReadServers();
// if(candidate_servers.length == 0) {
// self.state = HighAvailabilityProcess.STOPPED;
// return;
// }

// // Unpack connection options
// var connectTimeoutMS = self.options.connectTimeoutMS || 30000;
// // var socketTimeoutMS = self.options.socketTimeoutMS || 30000;
// var socketTimeoutMS = 30000;
// // Get the first server
// var server = candidate_servers.pop();

// // Attempt to reconnect the server
// return setTimeout(function() {
// start_server(self)
// }, self.options.haInterval);


// // Set up a new server instance
// var _server = new Server(server.host, server.port, {
// auto_reconnect: false
// , returnIsMasterResults: true
// , poolSize: 1
// , socketOptions: {
// connectTimeoutMS: connectTimeoutMS,
// socketTimeoutMS: socketTimeoutMS,
// keepAlive: 100
// }
// , ssl: self.options.ssl
// , sslValidate: self.options.sslValidate
// , sslCA: self.options.sslCA
// , sslCert: self.options.sslCert
// , sslKey: self.options.sslKey
// , sslPass: self.options.sslPass
// });

// // Create new dummy db for app
// var _db = new Db('local', _server, {w:1});

// // Set up the event listeners
// // _server.once("error", _handle(self, _server));
// // _server.once("close", _handle(self, _server));
// // _server.once("timeout", _handle(self, _server));
// // _server.name = format("%s:%s", server.host, server.port);

// // Let's attempt a connection over here
// _server.connect(_db, function(err, result, __server) {
// if(self.state == HighAvailabilityProcess.STOPPED) {
// _server.close();
// }

// if(err) {
// _server.close();
// // Attempt to reconnect the server
// setTimeout(function() {
// start_server(self)
// }, self.options.haInterval);
// } else {
// // self.db.command({ismaster:true}, function(err, doc) {
// // console.log("============================ PING")
// // console.dir(err)
// // console.dir(doc)

// _server.close();
// // Attempt to reconnect the server
// setTimeout(function() {
// start_server(self)
// }, self.options.haInterval);
// // });
// }
// });
// }

// var _handle = function(self, server) {
// return function() {
// }
// }

// HighAvailabilityProcess.prototype.stop = function() {
// this.state = HighAvailabilityProcess.STOPPED;
// }

var HighAvailabilityProcess = function(replset, options) {
this.replset = replset;
this.options = options;
Expand Down
21 changes: 9 additions & 12 deletions lib/mongodb/connection/server.js
Expand Up @@ -279,6 +279,7 @@ Server.prototype.connect = function(dbInstance, options, callback) {
if('function' === typeof options) callback = options, options = {};
if(options == null) options = {};
if(!('function' === typeof callback)) callback = null;
var self = this;
// Save the options
this.options = options;

Expand Down Expand Up @@ -329,11 +330,10 @@ Server.prototype.connect = function(dbInstance, options, callback) {

// Set basic parameters passed in
var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults;
// console.log("++++++++++++++++++++++++++++++++++++++++++ connect :: " + returnIsMasterResults)

// Create a default connect handler, overriden when using replicasets
var connectCallback = function(_server) {
return function(err, reply) {
return function(err, reply) {
// ensure no callbacks get called twice
var internalCallback = callback;
callback = null;
Expand Down Expand Up @@ -682,15 +682,18 @@ Server.prototype.connect = function(dbInstance, options, callback) {
return setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds);
}
} else {
server._reconnectInProgreess = false;
server._commandsStore.execute_queries();
server._commandsStore.execute_writes();
// Apply any auths, we don't try to catch any errors here
// as there are nowhere to simply propagate them to
self._apply_auths(server.db, function(err, result) {
server._reconnectInProgreess = false;
server._commandsStore.execute_queries();
server._commandsStore.execute_writes();
});
}
});
}
}


// If we have a parser error we are in an unknown state, close everything and emit
// error
connectionPool.on("parseError", function(message) {
Expand Down Expand Up @@ -779,9 +782,6 @@ var canCheckoutWriter = function(self, read) {
* @ignore
*/
Server.prototype.checkoutWriter = function(read) {
// console.log("======================== SERVER :: checkout writer :: " + this.port)
// console.dir(read)
// console.dir(this.isMasterDoc)
if(read == true) return this.connectionPool.checkoutConnection();
// Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
var result = canCheckoutWriter(this, read);
Expand Down Expand Up @@ -820,9 +820,6 @@ var canCheckoutReader = function(self) {
* @ignore
*/
Server.prototype.checkoutReader = function(read) {
// console.log("======================== SERVER :: checkout reader :: " + this.port)
// console.dir(read)
// console.dir(this.isMasterDoc)
// Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
var result = canCheckoutReader(this);
// If the result is null check out a writer
Expand Down
1 change: 0 additions & 1 deletion lib/mongodb/db.js
Expand Up @@ -676,7 +676,6 @@ Db.prototype.authenticate = function(username, password, options, callback) {
throw new Error("Kerberos library not installed");
}


if(process.platform == 'win32') {
mongodb_sspi_authenticate(self, username, password, authdb, options, callback);
} else {
Expand Down
19 changes: 14 additions & 5 deletions test/tests/kerberos/kdc_tests.js
Expand Up @@ -51,16 +51,25 @@ exports['Should Correctly Authenticate using kerberos with MongoClient and then
test.equal(null, err);
test.ok(db != null);

// Close the connection
db.close();

// Attempt an operation
db.admin().command({listDatabases:1}, function(err, docs) {
test.equal(null, err);
test.ok(docs.documents[0].databases);

db.close();
test.done();
// Close the connection
// db.close();
db.serverConfig.connectionPool.openConnections[0].connection.destroy();

setTimeout(function() {
// Attempt an operation
db.admin().command({listDatabases:1}, function(err, docs) {
test.equal(null, err);
test.ok(docs.documents[0].databases);

db.close();
test.done();
});
}, 1000);
});
});
}
Expand Down

0 comments on commit 99aeb61

Please sign in to comment.