summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs2
-rw-r--r--TwoStepsAuthenticator/Authenticator.cs15
-rw-r--r--TwoStepsAuthenticator/TwoStepsAuthenticator.csproj1
-rw-r--r--TwoStepsAuthenticator/UsedCodesManager.cs79
4 files changed, 95 insertions, 2 deletions
diff --git a/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs b/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs
index 3a1ae68..43469af 100644
--- a/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs
+++ b/TwoStepsAuthenticator.TestApp/MainWindow.xaml.cs
@@ -31,7 +31,7 @@ namespace TwoStepsAuthenticatorTestApp
private void Button_Click(object sender, RoutedEventArgs e)
{
- model.GetCode();
+ model.GetCode();
}
}
}
diff --git a/TwoStepsAuthenticator/Authenticator.cs b/TwoStepsAuthenticator/Authenticator.cs
index de383d9..d196525 100644
--- a/TwoStepsAuthenticator/Authenticator.cs
+++ b/TwoStepsAuthenticator/Authenticator.cs
@@ -9,6 +9,12 @@ namespace TwoStepsAuthenticator
{
public class Authenticator
{
+ private static UsedCodesManager usedCodes = new UsedCodesManager();
+
+ public string GenerateKey()
+ {
+ throw new NotImplementedException();
+ }
public string GetCode(string secret)
{
@@ -55,17 +61,24 @@ namespace TwoStepsAuthenticator
public bool CheckCode(string secret, string code)
{
+ if (usedCodes.IsCodeUsed(secret, code))
+ return false;
+
var baseTime = DateTime.Now;
- for (int i = -2; i <= 2; i++)
+ for (int i = -2; i <= 1; i++)
{
var checkTime = baseTime.AddSeconds(30 * i);
if (GetCode(secret, checkTime) == code)
+ {
+ usedCodes.AddCode(secret, code);
return true;
+ }
}
return false;
}
+
}
}
diff --git a/TwoStepsAuthenticator/TwoStepsAuthenticator.csproj b/TwoStepsAuthenticator/TwoStepsAuthenticator.csproj
index 7e9e1e0..b628bfd 100644
--- a/TwoStepsAuthenticator/TwoStepsAuthenticator.csproj
+++ b/TwoStepsAuthenticator/TwoStepsAuthenticator.csproj
@@ -42,6 +42,7 @@
<Compile Include="Base32Encoding.cs" />
<Compile Include="Authenticator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UsedCodesManager.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/TwoStepsAuthenticator/UsedCodesManager.cs b/TwoStepsAuthenticator/UsedCodesManager.cs
new file mode 100644
index 0000000..d60e1cb
--- /dev/null
+++ b/TwoStepsAuthenticator/UsedCodesManager.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+//using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Timers;
+
+namespace TwoStepsAuthenticator
+{
+ internal class UsedCodesManager
+ {
+ private class UsedCode
+ {
+ public UsedCode(String secret, String code)
+ {
+ this.UseDate = DateTime.Now;
+ this.Code = secret + code;
+ }
+
+ public DateTime UseDate { get; set; }
+ public String Code { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ return obj.ToString().Equals(Code);
+ }
+ public override string ToString()
+ {
+ return Code;
+ }
+ public override int GetHashCode()
+ {
+ return Code.GetHashCode();
+ }
+ }
+
+ private Queue<UsedCode> codes;
+ private object codeLock = new object();
+ private Timer cleaner;
+
+ public UsedCodesManager()
+ {
+ codes = new Queue<UsedCode>();
+ cleaner = new Timer(TimeSpan.FromSeconds(5).TotalMilliseconds);
+ cleaner.Elapsed += cleaner_Elapsed;
+ cleaner.Start();
+ }
+
+ void cleaner_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ var timeToClean = DateTime.Now.AddSeconds(-5);
+ lock (codeLock)
+ {
+ while (codes.Count > 0 && codes.Peek().UseDate < timeToClean)
+ {
+ codes.Dequeue();
+ }
+ }
+ }
+
+ public void AddCode(String secret, String code)
+ {
+ lock (codeLock)
+ {
+ codes.Enqueue(new UsedCode(secret, code));
+ }
+ }
+
+ public bool IsCodeUsed(String secret, String code)
+ {
+ lock (codeLock)
+ {
+ return codes.Contains(new UsedCode(secret, code));
+ }
+ }
+ }
+
+
+}