From c13ba70ab4a41c5ae06bfdb3066e4014216b8dc6 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 20 Jun 2017 14:50:12 -0400 Subject: [PATCH] verify all 2fa methods --- .../ResourceOwnerPasswordValidator.cs | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs index 34787ed3f..b0dce8bf5 100644 --- a/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Core/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; using Bit.Core.Services; +using System.Linq; namespace Bit.Core.IdentityServer { @@ -18,15 +19,18 @@ namespace Bit.Core.IdentityServer private UserManager _userManager; private readonly IDeviceRepository _deviceRepository; private readonly IDeviceService _deviceService; + private readonly IUserService _userService; public ResourceOwnerPasswordValidator( UserManager userManager, IDeviceRepository deviceRepository, - IDeviceService deviceService) + IDeviceService deviceService, + IUserService userService) { _userManager = userManager; _deviceRepository = deviceRepository; _deviceService = deviceService; + _userService = userService; } public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) @@ -55,8 +59,7 @@ namespace Bit.Core.IdentityServer return; } - if(!twoFactorRequest || - await _userManager.VerifyTwoFactorTokenAsync(user, twoFactorProviderType.ToString(), twoFactorToken)) + if(!twoFactorRequest || await VerifyTwoFactor(user, twoFactorProviderType, twoFactorToken)) { var device = await SaveDeviceAsync(user, context); BuildSuccessResult(user, context, device); @@ -98,17 +101,19 @@ namespace Bit.Core.IdentityServer private void BuildTwoFactorResult(User user, ResourceOwnerPasswordValidationContext context) { - var providers = new List(); - if(user.TwoFactorProvider.HasValue) + var providerKeys = new List(); + var providers = new Dictionary>(); + foreach(var provider in user.GetTwoFactorProviders().Where(p => p.Value.Enabled)) { - providers.Add((byte)user.TwoFactorProvider.Value); + providerKeys.Add((byte)provider.Key); + providers.Add((byte)provider.Key, null); } context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.", new Dictionary { - { "TwoFactorProviders", providers }, - { "TwoFactorProvider", (byte)user.TwoFactorProvider.Value } + { "TwoFactorProviders", providers.Keys }, + { "TwoFactorProviders2", providers } }); } @@ -152,6 +157,22 @@ namespace Bit.Core.IdentityServer }; } + private async Task VerifyTwoFactor(User user, TwoFactorProviderType type, string token) + { + switch(type) + { + case TwoFactorProviderType.Authenticator: + case TwoFactorProviderType.Duo: + case TwoFactorProviderType.YubiKey: + case TwoFactorProviderType.U2F: + return await _userManager.VerifyTwoFactorTokenAsync(user, type.ToString(), token); + case TwoFactorProviderType.Email: + return await _userService.VerifyTwoFactorEmailAsync(user, token); + default: + return false; + } + } + private async Task SaveDeviceAsync(User user, ResourceOwnerPasswordValidationContext context) { var device = GetDeviceFromRequest(context);