1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-10 20:43:41 +00:00

[AC-1070] Add logic to evaluate master password on unlock

This commit is contained in:
Shane Melton
2023-03-08 11:22:51 -08:00
parent da5db46d01
commit 1ea8d256b2

View File

@@ -31,6 +31,8 @@ namespace Bit.App.Pages
private readonly ILogger _logger;
private readonly IWatchDeviceService _watchDeviceService;
private readonly WeakEventManager<int?> _secretEntryFocusWeakEventManager = new WeakEventManager<int?>();
private readonly IPolicyService _policyService;
private readonly IPasswordGenerationService _passwordGenerationService;
private string _email;
private string _masterPassword;
@@ -47,6 +49,8 @@ namespace Bit.App.Pages
private bool _isPinProtected;
private bool _isPinProtectedWithKey;
private MasterPasswordPolicyOptions _enforcedMasterPasswordOptions;
public LockPageViewModel()
{
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
@@ -61,6 +65,9 @@ namespace Bit.App.Pages
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
_passwordGenerationService =
ServiceContainer.Resolve<IPasswordGenerationService>("passwordGenerationService");
PageTitle = AppResources.VerifyMasterPassword;
TogglePasswordCommand = new Command(TogglePassword);
@@ -307,7 +314,8 @@ namespace Bit.App.Pages
request.MasterPasswordHash = keyHash;
try
{
await _apiService.PostAccountVerifyPasswordAsync(request);
var response = await _apiService.PostAccountVerifyPasswordAsync(request);
_enforcedMasterPasswordOptions = response.MasterPasswordPolicy;
passwordValid = true;
var localKeyHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.LocalAuthorization);
await _cryptoService.SetKeyHashAsync(localKeyHash);
@@ -328,6 +336,14 @@ namespace Bit.App.Pages
var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, _email, kdfConfig);
await _stateService.SetPinProtectedKeyAsync(await _cryptoService.EncryptAsync(key.Key, pinKey));
}
if (await RequirePasswordChangeAsync())
{
// Save the ForcePasswordResetReason to force a password reset after unlock
await _stateService.SetForcePasswordResetReasonAsync(
ForcePasswordResetReason.WeakMasterPasswordOnLogin);
}
MasterPassword = string.Empty;
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
await SetKeyAndContinueAsync(key);
@@ -352,6 +368,30 @@ namespace Bit.App.Pages
}
}
/// <summary>
/// Checks if the master password requires updating to meet the enforced policy requirements
/// </summary>
private async Task<bool> RequirePasswordChangeAsync()
{
// If we do not have any saved policies, attempt to load them from the service
_enforcedMasterPasswordOptions ??= await _policyService.GetMasterPasswordPolicyOptions();
// No policy to enforce on login/unlock
if (!(_enforcedMasterPasswordOptions is { EnforceOnLogin: true }))
{
return false;
}
var strength = _passwordGenerationService.PasswordStrength(
MasterPassword, _passwordGenerationService.GetPasswordStrengthUserInput(_email)).Score;
return !await _policyService.EvaluateMasterPassword(
strength,
MasterPassword,
_enforcedMasterPasswordOptions
);
}
public async Task LogOutAsync()
{
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.LogoutConfirmation,