diff options
| author | Phallacy <Dragoonmac@gmail.com> | 2019-02-12 02:16:03 -0800 |
|---|---|---|
| committer | Phallacy <Dragoonmac@gmail.com> | 2019-02-12 02:16:03 -0800 |
| commit | 05bbf71b6d97614888efe103f763753e4487cc2c (patch) | |
| tree | a43ea503958842d1852c19e871d995cf9a747dc1 /Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs | |
| parent | 8bf88f4cb2ddb140baffd8e4542d8f528b482a67 (diff) | |
sha256 with salt auth and sha1 interop
Diffstat (limited to 'Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs')
| -rw-r--r-- | Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs | 167 |
1 files changed, 137 insertions, 30 deletions
diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs index 4013ac0c8..92346c65a 100644 --- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs +++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Text; using System.Threading.Tasks; using MediaBrowser.Controller.Authentication; @@ -19,31 +20,110 @@ namespace Emby.Server.Implementations.Library public bool IsEnabled => true; + + //This is dumb and an artifact of the backwards way auth providers were designed. + //This version of authenticate was never meant to be called, but needs to be here for interface compat + //Only the providers that don't provide local user support use this public Task<ProviderAuthenticationResult> Authenticate(string username, string password) { throw new NotImplementedException(); } - public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser) - { - if (resolvedUser == null) - { - throw new Exception("Invalid username or password"); - } - - var success = string.Equals(GetPasswordHash(resolvedUser), GetHashedString(resolvedUser, password), StringComparison.OrdinalIgnoreCase); - if (!success) - { - throw new Exception("Invalid username or password"); - } + //This is the verson that we need to use for local users. Because reasons. + public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
+ {
+ ConvertPasswordFormat(resolvedUser);
+ byte[] passwordbytes = Encoding.UTF8.GetBytes(password);
+ bool success = false;
+ if (resolvedUser == null)
+ {
+ success = false;
+ throw new Exception("Invalid username or password");
+ }
+ if (!resolvedUser.Password.Contains("$"))
+ {
+ ConvertPasswordFormat(resolvedUser);
+ }
+ PasswordHash ReadyHash = new PasswordHash(resolvedUser.Password);
+ byte[] CalculatedHash; + string CalculatedHashString;
+ if (_cryptographyProvider.GetSupportedHashMethods().Any(i => i == ReadyHash.Id))
+ {
+ if (String.IsNullOrEmpty(ReadyHash.Salt))
+ {
+ CalculatedHash = _cryptographyProvider.ComputeHash(ReadyHash.Id, passwordbytes); + CalculatedHashString = BitConverter.ToString(CalculatedHash).Replace("-", string.Empty);
+ }
+ else
+ {
+ CalculatedHash = _cryptographyProvider.ComputeHash(ReadyHash.Id, passwordbytes, ReadyHash.SaltBytes); + CalculatedHashString = BitConverter.ToString(CalculatedHash).Replace("-", string.Empty);
+ }
+ if (CalculatedHashString == ReadyHash.Hash)
+ {
+ success = true;
+ //throw new Exception("Invalid username or password");
+ }
+ }
+ else
+ {
+ success = false;
+ throw new Exception(String.Format("Requested crypto method not available in provider: {0}", ReadyHash.Id)); + }
+
+ //var success = string.Equals(GetPasswordHash(resolvedUser), GetHashedString(resolvedUser, password), StringComparison.OrdinalIgnoreCase);
+
+ if (!success)
+ {
+ throw new Exception("Invalid username or password");
+ }
+
+ return Task.FromResult(new ProviderAuthenticationResult
+ {
+ Username = username
+ });
+ } - return Task.FromResult(new ProviderAuthenticationResult - { - Username = username - }); + //This allows us to move passwords forward to the newformat without breaking. They are still insecure, unsalted, and dumb before a password change + //but at least they are in the new format. + private void ConvertPasswordFormat(User user)
+ {
+ if (!string.IsNullOrEmpty(user.Password))
+ {
+ if (!user.Password.Contains("$"))
+ {
+ string hash = user.Password;
+ user.Password = String.Format("$SHA1${0}", hash);
+ } + if (user.EasyPassword != null && !user.EasyPassword.Contains("$"))
+ {
+ string hash = user.EasyPassword;
+ user.EasyPassword = String.Format("$SHA1${0}", hash);
+ }
+ }
} + // OLD VERSION //public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser) + // OLD VERSION //{ + // OLD VERSION // if (resolvedUser == null) + // OLD VERSION // { + // OLD VERSION // throw new Exception("Invalid username or password"); + // OLD VERSION // } + // OLD VERSION // + // OLD VERSION // var success = string.Equals(GetPasswordHash(resolvedUser), GetHashedString(resolvedUser, password), StringComparison.OrdinalIgnoreCase); + // OLD VERSION // + // OLD VERSION // if (!success) + // OLD VERSION // { + // OLD VERSION // throw new Exception("Invalid username or password"); + // OLD VERSION // } + // OLD VERSION // + // OLD VERSION // return Task.FromResult(new ProviderAuthenticationResult + // OLD VERSION // { + // OLD VERSION // Username = username + // OLD VERSION // }); + // OLD VERSION //} + public Task<bool> HasPassword(User user) { var hasConfiguredPassword = !IsPasswordEmpty(user, GetPasswordHash(user)); @@ -57,19 +137,26 @@ namespace Emby.Server.Implementations.Library public Task ChangePassword(User user, string newPassword) { - string newPasswordHash = null; - - if (newPassword != null) + //string newPasswordHash = null; + ConvertPasswordFormat(user); + PasswordHash passwordHash = new PasswordHash(user.Password); + if(passwordHash.Id == "SHA1" && string.IsNullOrEmpty(passwordHash.Salt)) { - newPasswordHash = GetHashedString(user, newPassword); + passwordHash.SaltBytes = _cryptographyProvider.GenerateSalt(); + passwordHash.Salt = BitConverter.ToString(passwordHash.SaltBytes).Replace("-",""); + passwordHash.Id = _cryptographyProvider.DefaultHashMethod; + passwordHash.Hash = GetHashedStringChangeAuth(newPassword, passwordHash); + }else if (newPassword != null) + { + passwordHash.Hash = GetHashedString(user, newPassword); } - if (string.IsNullOrWhiteSpace(newPasswordHash)) + if (string.IsNullOrWhiteSpace(passwordHash.Hash)) { - throw new ArgumentNullException(nameof(newPasswordHash)); + throw new ArgumentNullException(nameof(passwordHash.Hash)); } - user.Password = newPasswordHash; + user.Password = passwordHash.ToString(); return Task.CompletedTask; } @@ -86,19 +173,39 @@ namespace Emby.Server.Implementations.Library return GetHashedString(user, string.Empty); } + public string GetHashedStringChangeAuth(string NewPassword, PasswordHash passwordHash) + { + return BitConverter.ToString(_cryptographyProvider.ComputeHash(passwordHash.Id, Encoding.UTF8.GetBytes(NewPassword), passwordHash.SaltBytes)).Replace("-", string.Empty); + } + /// <summary> /// Gets the hashed string. /// </summary> - public string GetHashedString(User user, string str) - { - var salt = user.Salt; - if (salt != null) + public string GetHashedString(User user, string str)
+ {
+ //This is legacy. Deprecated in the auth method.
+ //return BitConverter.ToString(_cryptoProvider2.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty);
+ PasswordHash passwordHash;
+ if (String.IsNullOrEmpty(user.Password))
+ {
+ passwordHash = new PasswordHash(_cryptographyProvider);
+ }
+ else
{ - // return BCrypt.HashPassword(str, salt); + ConvertPasswordFormat(user);
+ passwordHash = new PasswordHash(user.Password);
+ }
+ if (passwordHash.SaltBytes != null)
+ {
+ return BitConverter.ToString(_cryptographyProvider.ComputeHash(passwordHash.Id, Encoding.UTF8.GetBytes(str), passwordHash.SaltBytes)).Replace("-",string.Empty);
+ }
+ else
+ {
+ return BitConverter.ToString(_cryptographyProvider.ComputeHash(passwordHash.Id, Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty);
+ //throw new Exception("User does not have a hash, this should not be possible");
} - // legacy - return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty); + } } } |
