diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index a8aa1a3cd..5b965efdc 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -641,6 +641,16 @@ namespace Emby.Common.Implementations.IO }).Where(i => i != null); } + public string[] ReadAllLines(string path) + { + return File.ReadAllLines(path); + } + + public void WriteAllLines(string path, IEnumerable lines) + { + File.WriteAllLines(path, lines); + } + public Stream OpenRead(string path) { return File.OpenRead(path); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 5d27e84dd..4a27ddb74 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -159,6 +159,9 @@ + + + diff --git a/MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs b/Emby.Server.Implementations/Security/MBLicenseFile.cs similarity index 63% rename from MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs rename to Emby.Server.Implementations/Security/MBLicenseFile.cs index 7b37925ba..454ee6026 100644 --- a/MediaBrowser.Server.Implementations/Security/MBLicenseFile.cs +++ b/Emby.Server.Implementations/Security/MBLicenseFile.cs @@ -4,15 +4,18 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Security.Cryptography; using System.Text; using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Cryptography; +using MediaBrowser.Model.IO; -namespace MediaBrowser.Server.Implementations.Security +namespace Emby.Server.Implementations.Security { internal class MBLicenseFile { private readonly IApplicationPaths _appPaths; + private readonly IFileSystem _fileSystem; + private readonly ICryptographyProvider _cryptographyProvider; public string RegKey { @@ -40,9 +43,11 @@ namespace MediaBrowser.Server.Implementations.Security private readonly object _fileLock = new object(); private string _regKey; - public MBLicenseFile(IApplicationPaths appPaths) + public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider) { _appPaths = appPaths; + _fileSystem = fileSystem; + _cryptographyProvider = cryptographyProvider; Load(); } @@ -54,41 +59,30 @@ namespace MediaBrowser.Server.Implementations.Security public void AddRegCheck(string featureId) { - using (var provider = new MD5CryptoServiceProvider()) - { - var key = new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId))); - var value = DateTime.UtcNow; - - SetUpdateRecord(key, value); - Save(); - } + var key = new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))); + var value = DateTime.UtcNow; + SetUpdateRecord(key, value); + Save(); } public void RemoveRegCheck(string featureId) { - using (var provider = new MD5CryptoServiceProvider()) - { - var key = new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId))); - DateTime val; + var key = new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))); + DateTime val; - _updateRecords.TryRemove(key, out val); - - Save(); - } + _updateRecords.TryRemove(key, out val); + Save(); } public DateTime LastChecked(string featureId) { - using (var provider = new MD5CryptoServiceProvider()) - { - DateTime last; - _updateRecords.TryGetValue(new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId))), out last); + DateTime last; + _updateRecords.TryGetValue(new Guid(_cryptographyProvider.GetMD5Bytes(Encoding.Unicode.GetBytes(featureId))), out last); - // guard agains people just putting a large number in the file - return last < DateTime.UtcNow ? last : DateTime.MinValue; - } + // guard agains people just putting a large number in the file + return last < DateTime.UtcNow ? last : DateTime.MinValue; } private void Load() @@ -99,15 +93,21 @@ namespace MediaBrowser.Server.Implementations.Security { try { - contents = File.ReadAllLines(licenseFile); - } - catch (DirectoryNotFoundException) - { - File.Create(licenseFile).Close(); + contents = _fileSystem.ReadAllLines(licenseFile); } catch (FileNotFoundException) { - File.Create(licenseFile).Close(); + lock (_fileLock) + { + _fileSystem.WriteAllBytes(licenseFile, new byte[] {}); + } + } + catch (IOException) + { + lock (_fileLock) + { + _fileSystem.WriteAllBytes(licenseFile, new byte[] { }); + } } } if (contents != null && contents.Length > 0) @@ -150,8 +150,11 @@ namespace MediaBrowser.Server.Implementations.Security } var licenseFile = Filename; - Directory.CreateDirectory(Path.GetDirectoryName(licenseFile)); - lock (_fileLock) File.WriteAllLines(licenseFile, lines); + _fileSystem.CreateDirectory(Path.GetDirectoryName(licenseFile)); + lock (_fileLock) + { + _fileSystem.WriteAllLines(licenseFile, lines); + } } } } diff --git a/MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs b/Emby.Server.Implementations/Security/PluginSecurityManager.cs similarity index 95% rename from MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs rename to Emby.Server.Implementations/Security/PluginSecurityManager.cs index 7dc78a3af..c3a7e9450 100644 --- a/MediaBrowser.Server.Implementations/Security/PluginSecurityManager.cs +++ b/Emby.Server.Implementations/Security/PluginSecurityManager.cs @@ -5,18 +5,18 @@ using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; using MediaBrowser.Controller; +using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; -namespace MediaBrowser.Server.Implementations.Security +namespace Emby.Server.Implementations.Security { /// /// Class PluginSecurityManager @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Security private MBLicenseFile _licenseFile; private MBLicenseFile LicenseFile { - get { return _licenseFile ?? (_licenseFile = new MBLicenseFile(_appPaths)); } + get { return _licenseFile ?? (_licenseFile = new MBLicenseFile(_appPaths, _fileSystem, _cryptographyProvider)); } } private readonly IHttpClient _httpClient; @@ -64,6 +64,7 @@ namespace MediaBrowser.Server.Implementations.Security private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; + private readonly ICryptographyProvider _cryptographyProvider; private IEnumerable _registeredEntities; protected IEnumerable RegisteredEntities @@ -78,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Security /// Initializes a new instance of the class. /// public PluginSecurityManager(IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, - IApplicationPaths appPaths, ILogManager logManager, IFileSystem fileSystem) + IApplicationPaths appPaths, ILogManager logManager, IFileSystem fileSystem, ICryptographyProvider cryptographyProvider) { if (httpClient == null) { @@ -90,6 +91,7 @@ namespace MediaBrowser.Server.Implementations.Security _jsonSerializer = jsonSerializer; _appPaths = appPaths; _fileSystem = fileSystem; + _cryptographyProvider = cryptographyProvider; _logger = logManager.GetLogger("SecurityManager"); } @@ -191,7 +193,7 @@ namespace MediaBrowser.Server.Implementations.Security { var msg = "Result from appstore registration was null."; _logger.Error(msg); - throw new ApplicationException(msg); + throw new ArgumentException(msg); } if (!String.IsNullOrEmpty(reg.key)) { @@ -200,7 +202,7 @@ namespace MediaBrowser.Server.Implementations.Security } } - catch (ApplicationException) + catch (ArgumentException) { SaveAppStoreInfo(parameters); throw; @@ -213,14 +215,14 @@ namespace MediaBrowser.Server.Implementations.Security { throw new PaymentRequiredException(); } - throw new ApplicationException("Error registering store sale"); + throw new Exception("Error registering store sale"); } catch (Exception e) { _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT"); SaveAppStoreInfo(parameters); //TODO - could create a re-try routine on start-up if this file is there. For now we can handle manually. - throw new ApplicationException("Error registering store sale"); + throw new Exception("Error registering store sale"); } } diff --git a/MediaBrowser.Server.Implementations/Security/RegRecord.cs b/Emby.Server.Implementations/Security/RegRecord.cs similarity index 80% rename from MediaBrowser.Server.Implementations/Security/RegRecord.cs rename to Emby.Server.Implementations/Security/RegRecord.cs index 947ec629f..d484085d3 100644 --- a/MediaBrowser.Server.Implementations/Security/RegRecord.cs +++ b/Emby.Server.Implementations/Security/RegRecord.cs @@ -1,6 +1,6 @@ using System; -namespace MediaBrowser.Server.Implementations.Security +namespace Emby.Server.Implementations.Security { class RegRecord { diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index 50e32572d..ca537752a 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -276,6 +276,10 @@ namespace MediaBrowser.Model.IO /// System.String. string ReadAllText(string path, Encoding encoding); + string[] ReadAllLines(string path); + + void WriteAllLines(string path, IEnumerable lines); + /// /// Gets the directory paths. /// diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 9af765c23..d6223c465 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -171,9 +171,6 @@ - - - diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 3a5939df1..5f609de27 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -112,6 +112,7 @@ using Emby.Server.Implementations.MediaEncoder; using Emby.Server.Implementations.Notifications; using Emby.Server.Implementations.Persistence; using Emby.Server.Implementations.Playlists; +using Emby.Server.Implementations.Security; using Emby.Server.Implementations.ServerManager; using Emby.Server.Implementations.Session; using Emby.Server.Implementations.Sync; @@ -532,7 +533,7 @@ namespace MediaBrowser.Server.Startup.Common { await base.RegisterResources(progress).ConfigureAwait(false); - SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager); + SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider); RegisterSingleInstance(SecurityManager); InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider);