/// <summary> /// Clears the QuickPass entries of all identities from memory. After calling /// this method, SQRL will ask for the full master password again for all /// available identities. /// </summary> /// <param name="reason">The reason for clearing the QuickPass.</param> /// <param name="combineEvents">If set to <c>true</c>, <c>QuickPassManager</c> /// will not raise individual <c>QuickPassCleared</c> events for each of the /// QuickPass entries affected, but instead raise a combined event.</param> public void ClearAllQuickPass(QuickPassClearReason reason, bool combineEvents = true) { Log.Verbose("{MethodName} called", nameof(ClearAllQuickPass)); List <string> uniqueIdsAvailable = null; List <string> uniqueIdsCleared = new List <string>(); lock (_dataSyncObj) { uniqueIdsAvailable = new List <string>(_quickPassItems.Keys); } foreach (string uniqueId in uniqueIdsAvailable) { if (ClearQuickPass(uniqueId, reason, !combineEvents)) { uniqueIdsCleared.Add(uniqueId); } } // Only fire a combined QuickPassCleared event if combining events is enabled // and if any QuickPass entries have actually been cleared. if (combineEvents && uniqueIdsCleared.Count > 0) { QuickPassCleared?.Invoke(this, new QuickPassClearedEventArgs(uniqueIdsCleared)); Log.Information("Fired combined ClickPassCleared event. Reason: {Reason}", reason.ToString()); } }
/// <summary> /// Clears the QuickPass entries of all identities from memory. After calling /// this method, SQRL will ask for the full master password again for all /// available identities. /// </summary> /// <param name="identityUniqueId">The unique id (block 0) of the identity for /// which to clear the QuickPass entry.</param> /// <param name="reason">The reason for clearing the QuickPass.</param> /// <param name="fireClearedEvent">If set to <c>true</c>, a /// <c>QuickPassCleared</c> event will be fired if the QuickPass for the given /// <paramref name="identityUniqueId"/> could be successfully cleared.</param> public bool ClearQuickPass(string identityUniqueId, QuickPassClearReason reason, bool fireClearedEvent = true) { Log.Verbose("{MethodName} called", nameof(ClearQuickPass)); lock (_dataSyncObj) { if (!_quickPassItems.ContainsKey(identityUniqueId)) { Log.Warning("No QuickPass entry found for identity {IdentityUniqueId}", identityUniqueId); return(false); } QuickPassItem qpi = _quickPassItems[identityUniqueId]; if (reason == QuickPassClearReason.IdentityChange && !ClearQuickPassOnIdentityChange) { return(false); } if (reason == QuickPassClearReason.IdleTimeout && !qpi.ClearQuickPassOnIdle) { return(false); } if (reason == QuickPassClearReason.EnterBlankingState && !qpi.ClearQuickPassOnSleep) { return(false); } if (reason == QuickPassClearReason.UserSwitching && !qpi.ClearQuickPassOnSwitchingUser) { return(false); } // First, stop the QuickPass timer qpi.Timer.Stop(); // Then, overwrite the encrypted imk and ilk so that we don't // leave any traces of key material in RAM. qpi.EncryptedImk.ZeroFill(); qpi.EncryptedIlk.ZeroFill(); // Delete the QuickPass entry from our dictionary _quickPassItems.Remove(identityUniqueId); } Log.Information("QuickPass entry cleared. ID: {IdentityUniqueId} Reason: {Reason}", identityUniqueId, reason.ToString()); // Finally, fire the QuickPassCleared event if (fireClearedEvent) { QuickPassCleared?.Invoke(this, new QuickPassClearedEventArgs(new List <string>() { identityUniqueId })); Log.Information("Firing QuickPassCleared event"); } return(true); }