Browse Source

Working auth!

master
Gregory Rudolph 3 years ago
parent
commit
0e8650d4a8
Signed by: rudi
GPG Key ID: EF64F3CBD1A1EBDD
  1. 18
      Account.cs
  2. 2
      Pages/Account.cshtml
  3. 57
      Pages/Account.cshtml.cs
  4. 4
      SRP6.cs

18
Account.cs

@ -13,12 +13,10 @@ namespace NightmareCoreWeb2
public string Username { get; set; } public string Username { get; set; }
public string Email { get; set; } public string Email { get; set; }
public string LastIP { get; set; } public string LastIP { get; set; }
public string Verifier { get; set; } public byte[] Verifier { get; set; }
public DateTime LastLogin { get; set; } public DateTime LastLogin { get; set; }
public List<Character> Characters { get; set; } public List<Character> Characters { get; set; }
public List<AccountAccess> Access { get; set; } public List<AccountAccess> Access { get; set; }
private readonly BigInteger g = 7;
private readonly BigInteger N = BigInteger.Parse("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", NumberStyles.HexNumber);
public static Account AccountByID(int id) public static Account AccountByID(int id)
@ -47,7 +45,6 @@ namespace NightmareCoreWeb2
public Account(string username) public Account(string username)
{ {
MySqlConnection conn = new MySqlConnection(Program.connStr); MySqlConnection conn = new MySqlConnection(Program.connStr);
conn.Open(); conn.Open();
@ -55,7 +52,7 @@ namespace NightmareCoreWeb2
MySqlCommand cmd = new MySqlCommand(sql, conn); MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("username", username); cmd.Parameters.AddWithValue("username", username);
MySqlDataReader rdr = cmd.ExecuteReader(); MySqlDataReader rdr = cmd.ExecuteReader();
this.Verifier = new byte[32];
while (rdr.Read()) while (rdr.Read())
{ {
try try
@ -65,7 +62,7 @@ namespace NightmareCoreWeb2
this.Email = rdr.GetString(2); this.Email = rdr.GetString(2);
this.LastIP = rdr.GetString(3); this.LastIP = rdr.GetString(3);
this.LastLogin = rdr.GetDateTime(4); this.LastLogin = rdr.GetDateTime(4);
this.Verifier = rdr.GetString(5); rdr.GetBytes(5, 0, this.Verifier, 0, 32);
} }
catch (Exception e) catch (Exception e)
{ {
@ -97,7 +94,6 @@ namespace NightmareCoreWeb2
} }
} }
rdr.Close(); rdr.Close();
sql = "select SecurityLevel,RealmID from account_access where AccountID=@id"; sql = "select SecurityLevel,RealmID from account_access where AccountID=@id";
cmd = new MySqlCommand(sql, conn); cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("id", this.Id); cmd.Parameters.AddWithValue("id", this.Id);
@ -159,8 +155,12 @@ namespace NightmareCoreWeb2
} }
catch (Exception) { } catch (Exception) { }
} }
byte[] calculatedVerifier = Framework.Cryptography.SRP6.CalculateVerifier(this.Username, password, salt);
return Framework.Cryptography.SRP6.CheckLogin(this.Username, password, salt, verifier); return calculatedVerifier.Compare(verifier);
}
public bool AuthenticateAccount(byte[] verifier)
{
return verifier.Compare(this.Verifier);
} }
} }

2
Pages/Account.cshtml

@ -3,7 +3,7 @@
@{ @{
} }
<div class="container"> <div class="container">
@if (string.IsNullOrEmpty(Model.AuthToken)) @if (Model.UserAccount == null)
{ {
<div id="LoginForm"> <div id="LoginForm">

57
Pages/Account.cshtml.cs

@ -17,6 +17,7 @@ namespace NightmareCoreWeb2.Pages
public string AuthToken { get; set; } public string AuthToken { get; set; }
public string Username { get; set; } public string Username { get; set; }
public bool IsGM { get; set; } public bool IsGM { get; set; }
public bool IsAuthenticated = false;
public Account UserAccount { get; set; } public Account UserAccount { get; set; }
public List<Character> OnlineCharacters = new List<Character>(); public List<Character> OnlineCharacters = new List<Character>();
@ -28,11 +29,17 @@ namespace NightmareCoreWeb2.Pages
public AccountModel(ILogger<AccountModel> logger) public AccountModel(ILogger<AccountModel> logger)
{ {
conn = new MySqlConnection(Program.connStr); conn = new MySqlConnection(Program.connStr);
_logger = logger; _logger = logger;
} }
public void OnGetCharacterAction(int guid, int action) public void OnGetCharacterAction(int guid, int action)
{ {
if (!IsAuthenticated)
{
OnGet();
return;
}
Character c = new Character(guid); Character c = new Character(guid);
if ((c.AtLogin & Character.AtLoginOptions.AT_LOGIN_FIRST) == 0) if ((c.AtLogin & Character.AtLoginOptions.AT_LOGIN_FIRST) == 0)
{ {
@ -46,25 +53,30 @@ namespace NightmareCoreWeb2.Pages
{ {
ViewData["Title"] = "Login"; ViewData["Title"] = "Login";
AuthToken = Request.Cookies["AuthToken"]; if (Request.Cookies.Count() > 1)
if (!string.IsNullOrEmpty(AuthToken))
{ {
conn.Open(); try
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 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) public void SetupAccount(string Username)
{ {
@ -81,6 +93,7 @@ namespace NightmareCoreWeb2.Pages
} }
ViewData["Title"] = a.Username; ViewData["Title"] = a.Username;
CharacterListType = $"{a.Username}'s Characters"; CharacterListType = $"{a.Username}'s Characters";
this.UserAccount = a;
} }
@ -89,22 +102,22 @@ namespace NightmareCoreWeb2.Pages
{ {
UserEmail = Request.Form["UserEmail"]; UserEmail = Request.Form["UserEmail"];
UserPassword = Request.Form["UserPassword"]; 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); Account a = new Account(Username);
if (a.AuthenticateAccount(UserPassword)) if (a.AuthenticateAccount(UserPassword))
{ {
Response.Cookies.Append("Username", Username); Response.Cookies.Append("Username", Username);
Response.Cookies.Append("AuthToken", UserPassword); Response.Cookies.Append("AuthToken", Convert.ToBase64String(a.Verifier));
Response.Redirect("/Account"); 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")));
} }
} }

4
SRP6.cs

@ -64,6 +64,10 @@ namespace Framework.Cryptography
// v = BigInteger.ModPow(gBN, x, BN); // v = BigInteger.ModPow(gBN, x, BN);
return BigInteger.ModPow(_g, new BigInteger(_sha1.ComputeHash(salt.Combine(hash)), true), _N).ToByteArray(); 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) public static bool CheckLogin(string username, string password, byte[] salt, byte[] verifier)
{ {

Loading…
Cancel
Save