/// <summary> /// Initializes the mechanism. /// </summary> /// <param name="connection">The connection.</param> /// <param name="credentials">The credentials.</param> /// <returns>The initial step.</returns> public ISaslStep Initialize(Internal.MongoConnection connection, MongoCredentials credentials) { return new ManagedDigestMD5Implementation( connection.ServerInstance.Address.Host, credentials.Username, ((PasswordEvidence)credentials.Evidence).Password); }
// public methods /// <summary> /// Authenticates the connection against the given database. /// </summary> /// <param name="connection">The connection.</param> /// <param name="credentials">The credentials.</param> public void Authenticate(MongoConnection connection, MongoCredentials credentials) { var nonceCommand = new CommandDocument("getnonce", 1); var commandResult = connection.RunCommand(credentials.Source, QueryFlags.None, nonceCommand, false); if (!commandResult.Ok) { throw new MongoAuthenticationException( "Error getting nonce for authentication.", new MongoCommandException(commandResult)); } var nonce = commandResult.Response["nonce"].AsString; var passwordDigest = MongoUtils.Hash(credentials.Username + ":mongo:" + ((PasswordEvidence)credentials.Evidence).Password); var digest = MongoUtils.Hash(nonce + credentials.Username + passwordDigest); var authenticateCommand = new CommandDocument { { "authenticate", 1 }, { "user", credentials.Username }, { "nonce", nonce }, { "key", digest } }; commandResult = connection.RunCommand(credentials.Source, QueryFlags.None, authenticateCommand, false); if (!commandResult.Ok) { var message = string.Format("Invalid credentials for database '{0}'.", credentials.Source); throw new MongoAuthenticationException( message, new MongoCommandException(commandResult)); } }
// private methods private void Authenticate(MongoCredentials credentials, List<string> serverSupportedMethods) { foreach (var clientSupportedMethod in __clientSupportedMethods) { if (serverSupportedMethods.Contains(clientSupportedMethod.Name) && clientSupportedMethod.CanUse(credentials)) { clientSupportedMethod.Authenticate(_connection, credentials); return; } } var message = string.Format("Unable to negotiate a protocol to authenticate. Credentials for source {0}, username {1} over protocol {2} could not be authenticated", credentials.Source, credentials.Username, credentials.AuthenticationProtocol); throw new MongoSecurityException(message); }
/// <summary> /// Initializes the mechanism. /// </summary> /// <param name="connection">The connection.</param> /// <param name="credentials">The credentials.</param> /// <returns>The initial step.</returns> public ISaslStep Initialize(MongoConnection connection, MongoCredentials credentials) { // TODO: provide an override to force the use of gsasl? bool useGsasl = !Environment.OSVersion.Platform.ToString().Contains("Win"); if (useGsasl) { throw new NotImplementedException("Gssapi Support on Non-Windows Machinse is Not Implemented."); //return new GsaslGssapiImplementation( // connection.ServerInstance.Address.Host, // credentials.Username, // credentials.Evidence); } return new WindowsGssapiImplementation( connection.ServerInstance.Address.Host, credentials.Username, credentials.Evidence); }
// public methods /// <summary> /// Authenticates the connection against the given database. /// </summary> /// <param name="connection">The connection.</param> /// <param name="credentials">The credentials.</param> public void Authenticate(MongoConnection connection, MongoCredentials credentials) { using (var conversation = new SaslConversation()) { var currentStep = _mechanism.Initialize(connection, credentials); var command = new CommandDocument { { "saslStart", 1 }, { "mechanism", _mechanism.Name }, { "payload", currentStep.BytesToSendToServer } }; while (true) { var result = connection.RunCommand(credentials.Source, QueryFlags.SlaveOk, command, true); var code = result.Response["code"].AsInt32; if (code != 0) { HandleError(result, code); } if (result.Response["done"].AsBoolean) { break; } currentStep = currentStep.Transition(conversation, result.Response["payload"].AsByteArray); command = new CommandDocument { { "saslContinue", 1 }, { "conversationId", result.Response["conversationId"].AsInt32 }, { "payload", currentStep.BytesToSendToServer } }; } } }
/// <summary> /// Initializes the mechanism. /// </summary> /// <param name="connection">The connection.</param> /// <param name="credentials">The credentials.</param> /// <returns>The initial step.</returns> public ISaslStep Initialize(MongoConnection connection, MongoCredentials credentials) { return new ManagedCramMD5Implementation(credentials.Username, ((PasswordEvidence)credentials.Evidence).Password); //return new GsaslCramMD5Implementation(identity); }
/// <summary> /// Determines whether this instance can use the specified credentials. /// </summary> /// <param name="credentials">The credentials.</param> /// <returns> /// <c>true</c> if this instance can use the specified credentials; otherwise, <c>false</c>. /// </returns> public bool CanUse(MongoCredentials credentials) { return _mechanism.CanUse(credentials); }
public bool DatabaseExists(string databaseName, MongoCredentials adminCredentials) { return(_mongoServer.DatabaseExists(databaseName, adminCredentials)); }
IMongoDatabase IMongoServer.this[string databaseName, MongoCredentials credentials, SafeMode safeMode] { get { return(new MongoDatabaseProxy(_mongoServer[databaseName, credentials, safeMode])); } }
// constructors public Authentication(MongoCredentials credentials) { _credentials = credentials; _lastUsed = DateTime.UtcNow; }
internal MongoConnection AcquireConnection(string databaseName, MongoCredentials credentials, AcquireConnectionOptions options) { MongoConnection connectionToClose = null; try { DateTime timeoutAt = DateTime.UtcNow + options.WaitQueueTimeout; lock (_connectionPoolLock) { if (_waitQueueSize >= _settings.WaitQueueSize && !options.OkToExceedWaitQueueSize) { throw new MongoConnectionException("Too many threads are already waiting for a connection."); } _waitQueueSize += 1; try { while (true) { if (_availableConnections.Count > 0) { // first try to find the most recently used connection that is already authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { var connection = _availableConnections[i]; if (connection.IsExpired()) { _availableConnections.RemoveAt(i); connectionToClose = connection; return new MongoConnection(this); } else if (connection.IsAuthenticated(databaseName, credentials)) { _availableConnections.RemoveAt(i); return connection; } } // otherwise find the most recently used connection that can be authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { var connection = _availableConnections[i]; if (connection.CanAuthenticate(databaseName, credentials)) { _availableConnections.RemoveAt(i); return connection; } } // otherwise replace the least recently used connection with a brand new one // if this happens a lot the connection pool size should be increased connectionToClose = _availableConnections[0]; _availableConnections.RemoveAt(0); return new MongoConnection(this); } // avoid waiting by creating a new connection if options allow it if (options.OkToAvoidWaitingByCreatingNewConnection) { if (_poolSize < _settings.MaxConnectionPoolSize || options.OkToExceedMaxConnectionPoolSize) { // make sure connection is created successfully before incrementing poolSize // connection will be opened later outside of the lock var connection = new MongoConnection(this); _poolSize += 1; return connection; } } // wait for a connection to be released var timeRemaining = timeoutAt - DateTime.UtcNow; if (timeRemaining > TimeSpan.Zero) { // other methods should call Monitor.Pulse whenever: // 1. an available connection is added _availableConnections // 2. the _poolSize changes Monitor.Wait(_connectionPoolLock, timeRemaining); } else { if (options.OkToExceedMaxConnectionPoolSize) { // make sure connection is created successfully before incrementing poolSize // connection will be opened later outside of the lock var connection = new MongoConnection(this); _poolSize += 1; return connection; } else { throw new TimeoutException("Timeout waiting for a MongoConnection."); } } } } finally { _waitQueueSize -= 1; } } } finally { if (connectionToClose != null) { try { connectionToClose.Close(); } catch { // ignore exceptions } } } }
// internal methods internal MongoConnection AcquireConnection(string databaseName, MongoCredentials credentials) { lock (_connectionPoolLock) { if (_waitQueueSize >= _settings.WaitQueueSize) { throw new MongoConnectionException("Too many threads are already waiting for a connection."); } _waitQueueSize += 1; try { DateTime timeoutAt = DateTime.UtcNow + _settings.WaitQueueTimeout; while (true) { if (_availableConnections.Count > 0) { // first try to find the most recently used connection that is already authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { if (_availableConnections[i].IsAuthenticated(databaseName, credentials)) { var connection = _availableConnections[i]; _availableConnections.RemoveAt(i); return connection; } } // otherwise find the most recently used connection that can be authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { if (_availableConnections[i].CanAuthenticate(databaseName, credentials)) { var connection = _availableConnections[i]; _availableConnections.RemoveAt(i); return connection; } } // otherwise replace the least recently used connection with a brand new one // if this happens a lot the connection pool size should be increased _availableConnections[0].Close(); _availableConnections.RemoveAt(0); return new MongoConnection(this); } // create a new connection if maximum pool size has not been reached if (_poolSize < _settings.MaxConnectionPoolSize) { // make sure connection is created successfully before incrementing poolSize // connection will be opened later outside of the lock var connection = new MongoConnection(this); _poolSize += 1; return connection; } // wait for a connection to be released var timeRemaining = timeoutAt - DateTime.UtcNow; if (timeRemaining > TimeSpan.Zero) { Monitor.Wait(_connectionPoolLock, timeRemaining); } else { throw new TimeoutException("Timeout waiting for a MongoConnection."); } } } finally { _waitQueueSize -= 1; } } }
// internal methods internal MongoConnection AcquireConnection(string databaseName, MongoCredentials credentials) { return AcquireConnection(databaseName, credentials, _defaultAcquireConnectionOptions); }
/// <summary> /// Determines whether this instance can use the specified credentials. /// </summary> /// <param name="credentials">The credentials.</param> /// <returns> /// <c>true</c> if this instance can use the specified credentials; otherwise, <c>false</c>. /// </returns> public bool CanUse(MongoCredentials credentials) { return credentials.AuthenticationProtocol == MongoAuthenticationProtocol.Strongest && credentials.Evidence is PasswordEvidence; }
public void AddUser(MongoCredentials credentials, bool readOnly) { _mongoDatabase.AddUser(credentials, readOnly); }
public void AddUser(MongoCredentials credentials) { _mongoDatabase.AddUser(credentials); }
public CommandResult RenameCollection(string oldCollectionName, string newCollectionName, MongoCredentials adminCredentials) { return(_mongoDatabase.RenameCollection(oldCollectionName, newCollectionName, adminCredentials)); }
// internal methods internal MongoConnection AcquireConnection(string databaseName, MongoCredentials credentials) { lock (_connectionPoolLock) { if (_waitQueueSize >= _settings.WaitQueueSize) { throw new MongoConnectionException("Too many threads are already waiting for a connection."); } _waitQueueSize += 1; try { DateTime timeoutAt = DateTime.UtcNow + _settings.WaitQueueTimeout; while (true) { if (_availableConnections.Count > 0) { // first try to find the most recently used connection that is already authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { if (_availableConnections[i].IsAuthenticated(databaseName, credentials)) { var connection = _availableConnections[i]; _availableConnections.RemoveAt(i); return(connection); } } // otherwise find the most recently used connection that can be authenticated for this database for (int i = _availableConnections.Count - 1; i >= 0; i--) { if (_availableConnections[i].CanAuthenticate(databaseName, credentials)) { var connection = _availableConnections[i]; _availableConnections.RemoveAt(i); return(connection); } } // otherwise replace the least recently used connection with a brand new one // if this happens a lot the connection pool size should be increased _availableConnections[0].Close(); _availableConnections.RemoveAt(0); return(new MongoConnection(this)); } // create a new connection if maximum pool size has not been reached if (_poolSize < _settings.MaxConnectionPoolSize) { // make sure connection is created successfully before incrementing poolSize // connection will be opened later outside of the lock var connection = new MongoConnection(this); _poolSize += 1; return(connection); } // wait for a connection to be released var timeRemaining = timeoutAt - DateTime.UtcNow; if (timeRemaining > TimeSpan.Zero) { Monitor.Wait(_connectionPoolLock, timeRemaining); } else { throw new TimeoutException("Timeout waiting for a MongoConnection."); } } } finally { _waitQueueSize -= 1; } } }
// public methods /// <summary> /// Determines whether this instance can authenticate with the specified credentials. /// </summary> /// <param name="credentials">The credentials.</param> /// <returns> /// <c>true</c> if this instance can authenticate with the specified credentials; otherwise, <c>false</c>. /// </returns> /// <exception cref="System.NotImplementedException"></exception> public bool CanUse(MongoCredentials credentials) { return credentials.AuthenticationProtocol == MongoAuthenticationProtocol.Gssapi && credentials.Identity is MongoExternalIdentity; }
private MongoUser GetMongoUser() { var credentials = new MongoCredentials(this.UserName, this.Password, this.Admin); return(new MongoUser(credentials, !credentials.Admin)); }
// constructors public Authentication(MongoCredentials credentials) { this.credentials = credentials; this.lastUsed = DateTime.UtcNow; }