From 0e8650d4a8c44ef9419dae68728744f7b5e807a8 Mon Sep 17 00:00:00 2001 From: Gregory Rudolph Date: Tue, 7 Sep 2021 19:48:37 -0400 Subject: [PATCH] Working auth! --- Account.cs | 18 ++++++------- Pages/Account.cshtml | 2 +- Pages/Account.cshtml.cs | 57 +++++++++++++++++++++++++---------------- SRP6.cs | 4 +++ 4 files changed, 49 insertions(+), 32 deletions(-) diff --git a/Account.cs b/Account.cs index 43a9b3a..b2f8617 100644 --- a/Account.cs +++ b/Account.cs @@ -13,12 +13,10 @@ namespace NightmareCoreWeb2 public string Username { get; set; } public string Email { get; set; } public string LastIP { get; set; } - public string Verifier { get; set; } + public byte[] Verifier { get; set; } public DateTime LastLogin { get; set; } public List Characters { get; set; } public List Access { get; set; } - private readonly BigInteger g = 7; - private readonly BigInteger N = BigInteger.Parse("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", NumberStyles.HexNumber); public static Account AccountByID(int id) @@ -47,7 +45,6 @@ namespace NightmareCoreWeb2 public Account(string username) { - MySqlConnection conn = new MySqlConnection(Program.connStr); conn.Open(); @@ -55,7 +52,7 @@ namespace NightmareCoreWeb2 MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("username", username); MySqlDataReader rdr = cmd.ExecuteReader(); - + this.Verifier = new byte[32]; while (rdr.Read()) { try @@ -65,7 +62,7 @@ namespace NightmareCoreWeb2 this.Email = rdr.GetString(2); this.LastIP = rdr.GetString(3); this.LastLogin = rdr.GetDateTime(4); - this.Verifier = rdr.GetString(5); + rdr.GetBytes(5, 0, this.Verifier, 0, 32); } catch (Exception e) { @@ -97,7 +94,6 @@ namespace NightmareCoreWeb2 } } rdr.Close(); - sql = "select SecurityLevel,RealmID from account_access where AccountID=@id"; cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("id", this.Id); @@ -159,8 +155,12 @@ namespace NightmareCoreWeb2 } catch (Exception) { } } - - return Framework.Cryptography.SRP6.CheckLogin(this.Username, password, salt, verifier); + byte[] calculatedVerifier = Framework.Cryptography.SRP6.CalculateVerifier(this.Username, password, salt); + return calculatedVerifier.Compare(verifier); + } + public bool AuthenticateAccount(byte[] verifier) + { + return verifier.Compare(this.Verifier); } } diff --git a/Pages/Account.cshtml b/Pages/Account.cshtml index 8879012..b3bd6ef 100644 --- a/Pages/Account.cshtml +++ b/Pages/Account.cshtml @@ -3,7 +3,7 @@ @{ }
- @if (string.IsNullOrEmpty(Model.AuthToken)) + @if (Model.UserAccount == null) {
diff --git a/Pages/Account.cshtml.cs b/Pages/Account.cshtml.cs index ddab70c..9cfbbc0 100644 --- a/Pages/Account.cshtml.cs +++ b/Pages/Account.cshtml.cs @@ -17,6 +17,7 @@ namespace NightmareCoreWeb2.Pages public string AuthToken { get; set; } public string Username { get; set; } public bool IsGM { get; set; } + public bool IsAuthenticated = false; public Account UserAccount { get; set; } public List OnlineCharacters = new List(); @@ -28,11 +29,17 @@ namespace NightmareCoreWeb2.Pages public AccountModel(ILogger logger) { + conn = new MySqlConnection(Program.connStr); _logger = logger; } public void OnGetCharacterAction(int guid, int action) { + if (!IsAuthenticated) + { + OnGet(); + return; + } Character c = new Character(guid); if ((c.AtLogin & Character.AtLoginOptions.AT_LOGIN_FIRST) == 0) { @@ -46,25 +53,30 @@ namespace NightmareCoreWeb2.Pages { ViewData["Title"] = "Login"; - AuthToken = Request.Cookies["AuthToken"]; - if (!string.IsNullOrEmpty(AuthToken)) + if (Request.Cookies.Count() > 1) { - conn.Open(); - string sql = "select email from tokens.active_tokens where token=@token"; - MySqlCommand cmd = new MySqlCommand(sql, conn); - cmd.Parameters.AddWithValue("token", AuthToken); - MySqlDataReader rdr = cmd.ExecuteReader(); - string email = ""; - while (rdr.Read()) + try { - try + this.UserAccount = new Account(Request.Cookies["Username"]); + byte[] auth = Convert.FromBase64String(Request.Cookies["AuthToken"]); + this.Username = this.UserAccount.Username; + if (!this.UserAccount.AuthenticateAccount(auth)) { - email = rdr.GetString(0); + Console.WriteLine($"Failed to authenticate {this.UserAccount.Username}"); + Response.Cookies.Delete("Username"); + Response.Cookies.Delete("AuthToken"); + } else { + this.IsAuthenticated = true; } - catch (Exception) { } + SetupAccount(this.UserAccount.Username); + } + catch (Exception e) + { + Console.WriteLine(e); } - SetupAccount(email.Substring(0, email.IndexOf("@"))); + } + } public void SetupAccount(string Username) { @@ -81,6 +93,7 @@ namespace NightmareCoreWeb2.Pages } ViewData["Title"] = a.Username; CharacterListType = $"{a.Username}'s Characters"; + this.UserAccount = a; } @@ -89,22 +102,22 @@ namespace NightmareCoreWeb2.Pages { UserEmail = Request.Form["UserEmail"]; UserPassword = Request.Form["UserPassword"]; - Username = UserEmail.Substring(0, UserEmail.IndexOf("@")); + try + { + Username = UserEmail.Substring(0, UserEmail.IndexOf("@")); + } + catch (Exception) + { + Username = UserEmail; + } Account a = new Account(Username); if (a.AuthenticateAccount(UserPassword)) { Response.Cookies.Append("Username", Username); - Response.Cookies.Append("AuthToken", UserPassword); + Response.Cookies.Append("AuthToken", Convert.ToBase64String(a.Verifier)); Response.Redirect("/Account"); } - - } - - static string Hash(string input) - { - var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input)); - return string.Concat(hash.Select(b => b.ToString("x2"))); } } diff --git a/SRP6.cs b/SRP6.cs index 4f562be..30a05b4 100644 --- a/SRP6.cs +++ b/SRP6.cs @@ -64,6 +64,10 @@ namespace Framework.Cryptography // v = BigInteger.ModPow(gBN, x, BN); return BigInteger.ModPow(_g, new BigInteger(_sha1.ComputeHash(salt.Combine(hash)), true), _N).ToByteArray(); } + public static BigInteger CalculateBigIntVerifier(string username, string password, byte[] salt) { + byte[] hash = _sha1.ComputeHash(Encoding.UTF8.GetBytes(username.ToUpperInvariant() + ":" + password.ToUpperInvariant())); + return BigInteger.ModPow(_g, new BigInteger(_sha1.ComputeHash(salt.Combine(hash)), true), _N); + } public static bool CheckLogin(string username, string password, byte[] salt, byte[] verifier) {