private async Task IssueAlertIfIpIsNowBlocked(IPAddress ipAddress) { if (await IsIpBlockedAsync(ipAddress)) { BruteforceIpAddressAlert alert = new BruteforceIpAddressAlert(ipAddress); await _alertManager.AddAlertAsync(alert); } }
public override async Task <BindReply> ExecuteBindRequest(BindRequest request, ServerCallContext context) { if (!RequestIsFromLoopback(context)) { throw new Exception("Request is not from loopback"); } List <string> cns = request.UserIdentity.Cn.ToList(); List <string> dcs = request.UserIdentity.Dc.ToList(); List <string> ous = request.UserIdentity.Ou.ToList(); Guid appGuid = new Guid(dcs[0]); LdapAppSettings?settings = await _authDbContext.LdapAppSettings .Include(s => s.AuthApp) .SingleOrDefaultAsync(s => s.AuthApp.Id == appGuid); if (settings == null) { return(new BindReply { WasBindSuccessful = false }); } if (!request.IsEncryptedRequest) { LdapUnencryptedConnectionAlert alert = new LdapUnencryptedConnectionAlert ( IPAddress.Parse(request.IpAddress), settings ); await _alertManager.AddAlertAsync(alert); } if (cns.Count > 0 && dcs.Count > 0) { if (cns[0] == "BindUser" && ous.Count == 0) { if (settings != null) { byte[] correctPassword = Encoding.ASCII.GetBytes(_ldapSettingsDataProtector.Unprotect(settings.BindUserPassword)); byte[] providedPassword = Encoding.ASCII.GetBytes(request.Password); bool isCorrectPassword = CryptographicOperations.FixedTimeEquals(correctPassword, providedPassword); return(new BindReply { WasBindSuccessful = isCorrectPassword }); } } else if (ous.Count > 0 && ous[0] == "people") { Guid userId = new Guid(cns[0]); IEnumerable <LdapAppUserCredentials> creds = await _authDbContext.LdapAppUserCredentials .Where(c => c.User.Id == userId) .Where(c => c.User.IsDisabled == false) .Where(c => c.LdapAppSettings.AuthApp.Id == appGuid) .ToListAsync(); bool validCredentials = false; CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions po = new ParallelOptions(); po.CancellationToken = cts.Token; po.CancellationToken.ThrowIfCancellationRequested(); try { Parallel.ForEach(creds, po, (cred) => { bool isValid = _hasher.VerifyHash(cred.HashedPassword, request.Password); if (isValid) { validCredentials = true; cts.Cancel(); } }); } catch (OperationCanceledException) { } finally { cts.Dispose(); } return(new BindReply { WasBindSuccessful = validCredentials }); } } return(new BindReply { WasBindSuccessful = false }); }