@ -180,11 +180,6 @@ namespace Emby.Server.Implementations.Library
}
}
}
}
public Task < User > AuthenticateUser ( string username , string passwordSha1 , string remoteEndPoint )
{
return AuthenticateUser ( username , passwordSha1 , null , remoteEndPoint ) ;
}
public bool IsValidUsername ( string username )
public bool IsValidUsername ( string username )
{
{
// Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)
// Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)
@ -223,7 +218,7 @@ namespace Emby.Server.Implementations.Library
return builder . ToString ( ) ;
return builder . ToString ( ) ;
}
}
public async Task < User > AuthenticateUser ( string username , string password Sha1 , string passwordMd5 , string remoteEndPoint )
public async Task < User > AuthenticateUser ( string username , string password , string hashedPassword , string passwordMd5 , string remoteEndPoint )
{
{
if ( string . IsNullOrWhiteSpace ( username ) )
if ( string . IsNullOrWhiteSpace ( username ) )
{
{
@ -237,23 +232,23 @@ namespace Emby.Server.Implementations.Library
if ( user ! = null )
if ( user ! = null )
{
{
if ( password ! = null )
{
hashedPassword = GetHashedString ( user , password ) ;
}
// Authenticate using local credentials if not a guest
// Authenticate using local credentials if not a guest
if ( ! user . ConnectLinkType . HasValue | | user . ConnectLinkType . Value ! = UserLinkType . Guest )
if ( ! user . ConnectLinkType . HasValue | | user . ConnectLinkType . Value ! = UserLinkType . Guest )
{
{
success = string . Equals ( GetPasswordHash ( user ) , passwordSha1 . Replace ( "-" , string . Empty ) , StringComparison . OrdinalIgnoreCase ) ;
success = AuthenticateLocalUser ( user , password , hashedPassword , remoteEndPoint ) ;
if ( ! success & & _networkManager . IsInLocalNetwork ( remoteEndPoint ) & & user . Configuration . EnableLocalPassword )
{
success = string . Equals ( GetLocalPasswordHash ( user ) , passwordSha1 . Replace ( "-" , string . Empty ) , StringComparison . OrdinalIgnoreCase ) ;
}
}
}
// Maybe user accidently entered connect credentials. let's be flexible
// Maybe user accidently entered connect credentials. let's be flexible
if ( ! success & & user . ConnectLinkType . HasValue & & ! string . IsNullOrWhiteSpace ( passwordMd5) & & ! string . IsNullOrWhiteSpace ( user. ConnectUserName ) )
if ( ! success & & user . ConnectLinkType . HasValue & & ! string . IsNullOrWhiteSpace ( user . ConnectUserName ) )
{
{
try
try
{
{
await _connectFactory ( ) . Authenticate ( user . ConnectUserName , password Md5) . ConfigureAwait ( false ) ;
await _connectFactory ( ) . Authenticate ( user . ConnectUserName , password , password Md5) . ConfigureAwait ( false ) ;
success = true ;
success = true ;
}
}
catch
catch
@ -268,7 +263,7 @@ namespace Emby.Server.Implementations.Library
{
{
try
try
{
{
var connectAuthResult = await _connectFactory ( ) . Authenticate ( username , password Md5) . ConfigureAwait ( false ) ;
var connectAuthResult = await _connectFactory ( ) . Authenticate ( username , password , password Md5) . ConfigureAwait ( false ) ;
user = Users . FirstOrDefault ( i = > string . Equals ( i . ConnectUserId , connectAuthResult . User . Id , StringComparison . OrdinalIgnoreCase ) ) ;
user = Users . FirstOrDefault ( i = > string . Equals ( i . ConnectUserId , connectAuthResult . User . Id , StringComparison . OrdinalIgnoreCase ) ) ;
@ -307,6 +302,36 @@ namespace Emby.Server.Implementations.Library
return success ? user : null ;
return success ? user : null ;
}
}
private bool AuthenticateLocalUser ( User user , string password , string hashedPassword , string remoteEndPoint )
{
bool success ;
if ( password = = null )
{
// legacy
success = string . Equals ( GetPasswordHash ( user ) , hashedPassword . Replace ( "-" , string . Empty ) , StringComparison . OrdinalIgnoreCase ) ;
}
else
{
success = string . Equals ( GetPasswordHash ( user ) , GetHashedString ( user , password ) , StringComparison . OrdinalIgnoreCase ) ;
}
if ( ! success & & _networkManager . IsInLocalNetwork ( remoteEndPoint ) & & user . Configuration . EnableLocalPassword )
{
if ( password = = null )
{
// legacy
success = string . Equals ( GetLocalPasswordHash ( user ) , hashedPassword . Replace ( "-" , string . Empty ) , StringComparison . OrdinalIgnoreCase ) ;
}
else
{
success = string . Equals ( GetLocalPasswordHash ( user ) , GetHashedString ( user , password ) , StringComparison . OrdinalIgnoreCase ) ;
}
}
return success ;
}
private void UpdateInvalidLoginAttemptCount ( User user , int newValue )
private void UpdateInvalidLoginAttemptCount ( User user , int newValue )
{
{
if ( user . Policy . InvalidLoginAttemptCount ! = newValue | | newValue > 0 )
if ( user . Policy . InvalidLoginAttemptCount ! = newValue | | newValue > 0 )
@ -342,29 +367,39 @@ namespace Emby.Server.Implementations.Library
private string GetPasswordHash ( User user )
private string GetPasswordHash ( User user )
{
{
return string . IsNullOrEmpty ( user . Password )
return string . IsNullOrEmpty ( user . Password )
? Get Sha1String( string . Empty )
? Get EmptyHashedString( user )
: user . Password ;
: user . Password ;
}
}
private string GetLocalPasswordHash ( User user )
private string GetLocalPasswordHash ( User user )
{
{
return string . IsNullOrEmpty ( user . EasyPassword )
return string . IsNullOrEmpty ( user . EasyPassword )
? Get Sha1String( string . Empty )
? Get EmptyHashedString( user )
: user . EasyPassword ;
: user . EasyPassword ;
}
}
private bool IsPasswordEmpty ( string passwordHash )
private bool IsPasswordEmpty ( User user , string passwordHash )
{
{
return string . Equals ( passwordHash , GetSha1String ( string . Empty ) , StringComparison . OrdinalIgnoreCase ) ;
return string . Equals ( passwordHash , GetEmptyHashedString ( user ) , StringComparison . OrdinalIgnoreCase ) ;
}
private string GetEmptyHashedString ( User user )
{
return GetHashedString ( user , string . Empty ) ;
}
}
/// <summary>
/// <summary>
/// Gets the sha1 string.
/// Gets the hashed string.
/// </summary>
/// </summary>
/// <param name="str">The STR.</param>
private string GetHashedString ( User user , string str )
/// <returns>System.String.</returns>
private string GetSha1String ( string str )
{
{
var salt = user . Salt ;
if ( salt ! = null )
{
// return BCrypt.HashPassword(str, salt);
}
// legacy
return BitConverter . ToString ( _cryptographyProvider . ComputeSHA1 ( Encoding . UTF8 . GetBytes ( str ) ) ) . Replace ( "-" , string . Empty ) ;
return BitConverter . ToString ( _cryptographyProvider . ComputeSHA1 ( Encoding . UTF8 . GetBytes ( str ) ) ) . Replace ( "-" , string . Empty ) ;
}
}
@ -407,8 +442,8 @@ namespace Emby.Server.Implementations.Library
var passwordHash = GetPasswordHash ( user ) ;
var passwordHash = GetPasswordHash ( user ) ;
var hasConfiguredPassword = ! IsPasswordEmpty ( passwordHash) ;
var hasConfiguredPassword = ! IsPasswordEmpty ( user, passwordHash) ;
var hasConfiguredEasyPassword = ! IsPasswordEmpty ( GetLocalPasswordHash( user ) ) ;
var hasConfiguredEasyPassword = ! IsPasswordEmpty ( user, GetLocalPasswordHash( user ) ) ;
var hasPassword = user . Configuration . EnableLocalPassword & & ! string . IsNullOrEmpty ( remoteEndPoint ) & & _networkManager . IsInLocalNetwork ( remoteEndPoint ) ?
var hasPassword = user . Configuration . EnableLocalPassword & & ! string . IsNullOrEmpty ( remoteEndPoint ) & & _networkManager . IsInLocalNetwork ( remoteEndPoint ) ?
hasConfiguredEasyPassword :
hasConfiguredEasyPassword :
@ -460,14 +495,6 @@ namespace Emby.Server.Implementations.Library
{
{
var dto = GetUserDto ( user ) ;
var dto = GetUserDto ( user ) ;
var offlinePasswordHash = GetLocalPasswordHash ( user ) ;
dto . HasPassword = ! IsPasswordEmpty ( offlinePasswordHash ) ;
dto . OfflinePasswordSalt = Guid . NewGuid ( ) . ToString ( "N" ) ;
// Hash the pin with the device Id to create a unique result for this device
dto . OfflinePassword = GetSha1String ( ( offlinePasswordHash + dto . OfflinePasswordSalt ) . ToLower ( ) ) ;
dto . ServerName = _appHost . FriendlyName ;
dto . ServerName = _appHost . FriendlyName ;
return dto ;
return dto ;
@ -682,23 +709,29 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns>
/// <returns>Task.</returns>
public void ResetPassword ( User user )
public void ResetPassword ( User user )
{
{
ChangePassword ( user , GetSha1String ( string . Empty ) ) ;
ChangePassword ( user , string . Empty , null ) ;
}
}
public void ResetEasyPassword ( User user )
public void ResetEasyPassword ( User user )
{
{
ChangeEasyPassword ( user , GetSha1String ( string . Empty ) ) ;
ChangeEasyPassword ( user , string . Empty , null ) ;
}
}
public void ChangePassword ( User user , string newPassword Sha1 )
public void ChangePassword ( User user , string newPassword , string newPasswordHash )
{
{
if ( user = = null )
if ( user = = null )
{
{
throw new ArgumentNullException ( "user" ) ;
throw new ArgumentNullException ( "user" ) ;
}
}
if ( string . IsNullOrWhiteSpace ( newPasswordSha1 ) )
if ( newPassword ! = null )
{
newPasswordHash = GetHashedString ( user , newPassword ) ;
}
if ( string . IsNullOrWhiteSpace ( newPasswordHash ) )
{
{
throw new ArgumentNullException ( "newPasswordSha1" ) ;
throw new ArgumentNullException ( "newPassword Hash ") ;
}
}
if ( user . ConnectLinkType . HasValue & & user . ConnectLinkType . Value = = UserLinkType . Guest )
if ( user . ConnectLinkType . HasValue & & user . ConnectLinkType . Value = = UserLinkType . Guest )
@ -706,25 +739,31 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentException ( "Passwords for guests cannot be changed." ) ;
throw new ArgumentException ( "Passwords for guests cannot be changed." ) ;
}
}
user . Password = newPassword Sha1 ;
user . Password = newPassword Hash ;
UpdateUser ( user ) ;
UpdateUser ( user ) ;
EventHelper . FireEventIfNotNull ( UserPasswordChanged , this , new GenericEventArgs < User > ( user ) , _logger ) ;
EventHelper . FireEventIfNotNull ( UserPasswordChanged , this , new GenericEventArgs < User > ( user ) , _logger ) ;
}
}
public void ChangeEasyPassword ( User user , string newPassword Sha1 )
public void ChangeEasyPassword ( User user , string newPassword , string newPasswordHash )
{
{
if ( user = = null )
if ( user = = null )
{
{
throw new ArgumentNullException ( "user" ) ;
throw new ArgumentNullException ( "user" ) ;
}
}
if ( string . IsNullOrWhiteSpace ( newPasswordSha1 ) )
if ( newPassword ! = null )
{
newPasswordHash = GetHashedString ( user , newPassword ) ;
}
if ( string . IsNullOrWhiteSpace ( newPasswordHash ) )
{
{
throw new ArgumentNullException ( "newPasswordSha1" ) ;
throw new ArgumentNullException ( "newPassword Hash ") ;
}
}
user . EasyPassword = newPasswordSha1 ;
user . EasyPassword = newPassword Hash ;
UpdateUser ( user ) ;
UpdateUser ( user ) ;
@ -744,7 +783,8 @@ namespace Emby.Server.Implementations.Library
Id = Guid . NewGuid ( ) ,
Id = Guid . NewGuid ( ) ,
DateCreated = DateTime . UtcNow ,
DateCreated = DateTime . UtcNow ,
DateModified = DateTime . UtcNow ,
DateModified = DateTime . UtcNow ,
UsesIdForConfigurationPath = true
UsesIdForConfigurationPath = true ,
//Salt = BCrypt.GenerateSalt()
} ;
} ;
}
}