diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-04-13 17:49:23 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-04-13 17:49:23 -0400 |
| commit | 9c839945235b475d40e7855a39ae5bd7a46bea26 (patch) | |
| tree | de0df1d3a4cca9f9ad2c267542bf60bdf137dc04 | |
| parent | cdd1a032993a4ca7bb34d692f9dfdea0140d55e9 (diff) | |
| parent | 5a3c46fd5e6fb1435d4d19db6b6624b061ff101a (diff) | |
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
6 files changed, 235 insertions, 9 deletions
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index b2872e22a..79344bb0d 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -35,9 +35,6 @@ <RunPostBuildEvent>Always</RunPostBuildEvent> </PropertyGroup> <ItemGroup> - <Reference Include="Mediabrowser.PluginSecurity"> - <HintPath>..\ThirdParty\PluginSecurity\Mediabrowser.PluginSecurity.dll</HintPath> - </Reference> <Reference Include="NLog"> <HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath> </Reference> @@ -79,6 +76,8 @@ <Compile Include="ScheduledTasks\Tasks\DeleteLogFileTask.cs" /> <Compile Include="ScheduledTasks\Tasks\ReloadLoggerTask.cs" /> <Compile Include="ScheduledTasks\Tasks\SystemUpdateTask.cs" /> + <Compile Include="Security\MBLicenseFile.cs" /> + <Compile Include="Security\MBRegistration.cs" /> <Compile Include="Security\PluginSecurityManager.cs" /> <Compile Include="Serialization\JsonSerializer.cs" /> <Compile Include="Serialization\XmlSerializer.cs" /> @@ -104,7 +103,6 @@ <PropertyGroup> <PostBuildEvent>if $(ConfigurationName) == Release ( xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i -xcopy "$(TargetDir)Mediabrowser.PluginSecurity.dll" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i )</PostBuildEvent> </PropertyGroup> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs new file mode 100644 index 000000000..336ca78f0 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs @@ -0,0 +1,106 @@ +using MediaBrowser.Common.Configuration; +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace Mediabrowser.Common.Implementations.Security +{ + internal class MBLicenseFile + { + private readonly IApplicationPaths _appPaths; + + private readonly string _filename; + public string RegKey + { + get { return _regKey; } + set + { + if (value != _regKey) + { + //if key is changed - clear out our saved validations + UpdateRecords.Clear(); + _regKey = value; + } + } + } + + public string LegacyKey { get; set; } + private Dictionary<Guid, DateTime> UpdateRecords { get; set; } + private readonly object _lck = new object(); + private string _regKey; + + public MBLicenseFile(IApplicationPaths appPaths) + { + _appPaths = appPaths; + + _filename = Path.Combine(_appPaths.ConfigurationDirectoryPath, "mb.lic"); + + UpdateRecords = new Dictionary<Guid, DateTime>(); + Load(); + } + + public void AddRegCheck(string featureId) + { + using (var provider = new MD5CryptoServiceProvider()) + { + UpdateRecords[new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId)))] = DateTime.UtcNow; + Save(); + } + + } + + public DateTime LastChecked(string featureId) + { + using (var provider = new MD5CryptoServiceProvider()) + { + DateTime last; + lock(_lck) UpdateRecords.TryGetValue(new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(featureId))), out last); + return last < DateTime.UtcNow ? last : DateTime.MinValue; // guard agains people just putting a large number in the file + } + } + + private void Load() + { + string[] contents = null; + lock (_lck) + { + try + { + contents = File.ReadAllLines(_filename); + } + catch (FileNotFoundException) + { + (File.Create(_filename)).Close(); + } + } + if (contents != null && contents.Length > 0) + { + //first line is reg key + RegKey = contents[0]; + //next is legacy key + if (contents.Length > 1) LegacyKey = contents[1]; + //the rest of the lines should be pairs of features and timestamps + for (var i = 2; i < contents.Length; i = i + 2) + { + var feat = Guid.Parse(contents[i]); + UpdateRecords[feat] = new DateTime(Convert.ToInt64(contents[i + 1])); + } + } + } + + public void Save() + { + //build our array + var lines = new List<string> {RegKey, LegacyKey}; + foreach (var pair in UpdateRecords) + { + lines.Add(pair.Key.ToString()); + lines.Add(pair.Value.Ticks.ToString()); + } + + lock(_lck) File.WriteAllLines(_filename, lines); + } + } +} diff --git a/MediaBrowser.Common.Implementations/Security/MBRegistration.cs b/MediaBrowser.Common.Implementations/Security/MBRegistration.cs new file mode 100644 index 000000000..570a0429c --- /dev/null +++ b/MediaBrowser.Common.Implementations/Security/MBRegistration.cs @@ -0,0 +1,109 @@ +using Mediabrowser.Model.Entities; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Serialization; +using System; +using System.Collections.Generic; +using System.Management; +using System.Threading; +using System.Threading.Tasks; + +namespace Mediabrowser.Common.Implementations.Security +{ + public static class MBRegistration + { + + private static MBLicenseFile _licenseFile; + private const string MBValidateUrl = "http://mb3admin.com/admin/service/registration/validate"; + + private static IApplicationPaths _appPaths; + + private static MBLicenseFile LicenseFile + { + get { return _licenseFile ?? (_licenseFile = new MBLicenseFile(_appPaths)); } + } + + public static string SupporterKey + { + get { return LicenseFile.RegKey; } + set { LicenseFile.RegKey = value; LicenseFile.Save(); } + } + + public static string LegacyKey + { + get { return LicenseFile.LegacyKey; } + set { LicenseFile.LegacyKey = value; LicenseFile.Save(); } + } + + public static void Init(IApplicationPaths appPaths) + { + // Ugly alert (static init) + + _appPaths = appPaths; + } + + public static async Task<MBRegistrationRecord> GetRegistrationStatus(IHttpClient httpClient, IJsonSerializer jsonSerializer, string feature, string mb2Equivalent = null) + { + var mac = GetMacAddress(); + var data = new Dictionary<string, string> {{"feature", feature}, {"key",SupporterKey}, {"mac",mac}, {"mb2equiv",mb2Equivalent}, {"legacykey", LegacyKey} }; + + var reg = new RegRecord(); + try + { + using (var json = await httpClient.Post(MBValidateUrl, data, CancellationToken.None).ConfigureAwait(false)) + { + reg = jsonSerializer.DeserializeFromStream<RegRecord>(json); + } + + if (reg.registered) + { + LicenseFile.AddRegCheck(feature); + } + + } + catch (Exception) + { + //if we have trouble obtaining from web - allow it if we've validated in the past 30 days + reg.registered = LicenseFile.LastChecked(feature) > DateTime.UtcNow.AddDays(-30); + } + + return new MBRegistrationRecord {IsRegistered = reg.registered, ExpirationDate = reg.expDate, RegChecked = true}; + } + + /// <summary> + /// Returns MAC Address from first Network Card in Computer + /// </summary> + /// <returns>[string] MAC Address</returns> + public static string GetMacAddress() + { + var mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); + var moc = mc.GetInstances(); + var macAddress = String.Empty; + foreach (ManagementObject mo in moc) + { + if (macAddress == String.Empty) // only return MAC Address from first card + { + try + { + if ((bool)mo["IPEnabled"]) macAddress = mo["MacAddress"].ToString(); + } + catch + { + mo.Dispose(); + return ""; + } + } + mo.Dispose(); + } + + return macAddress.Replace(":", ""); + } + } + + class RegRecord + { + public string featId { get; set; } + public bool registered { get; set; } + public DateTime expDate { get; set; } + } +} diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index c7c3b3a57..c71cf3802 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -2,8 +2,8 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Security; using MediaBrowser.Model.Serialization; +using Mediabrowser.Common.Implementations.Security; using Mediabrowser.Model.Entities; -using Mediabrowser.PluginSecurity; using MediaBrowser.Common.Net; using System; using System.Threading; diff --git a/MediaBrowser.Model/Entities/MBRegistrationRecord.cs b/MediaBrowser.Model/Entities/MBRegistrationRecord.cs index 1349da4d3..5eeb07a66 100644 --- a/MediaBrowser.Model/Entities/MBRegistrationRecord.cs +++ b/MediaBrowser.Model/Entities/MBRegistrationRecord.cs @@ -4,10 +4,10 @@ namespace Mediabrowser.Model.Entities { public class MBRegistrationRecord { - public DateTime ExpirationDate = DateTime.MinValue; - public bool IsRegistered = false; - public bool RegChecked = false; - public bool RegError = false; + public DateTime ExpirationDate { get; set; } + public bool IsRegistered { get; set;} + public bool RegChecked { get; set; } + public bool RegError { get; set; } private bool? _isInTrial; public bool TrialVersion { diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index c33975a64..684b72cc9 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -39,6 +39,11 @@ namespace MediaBrowser.Server.Implementations.IO private readonly ConcurrentDictionary<string,string> _tempIgnoredPaths = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase); /// <summary> + /// Any file name ending in any of these will be ignored by the watchers + /// </summary> + private readonly List<string> _alwaysIgnoreFiles = new List<string> {"thumbs.db","small.jpg","albumart.jpg"}; + + /// <summary> /// The timer lock /// </summary> private readonly object _timerLock = new object(); @@ -313,10 +318,18 @@ namespace MediaBrowser.Server.Implementations.IO /// <param name="e">The <see cref="FileSystemEventArgs" /> instance containing the event data.</param> void watcher_Changed(object sender, FileSystemEventArgs e) { + // Ignore when someone manually creates a new folder if (e.ChangeType == WatcherChangeTypes.Created && e.Name == "New folder") { return; } + + // Ignore certain files + if (_alwaysIgnoreFiles.Any(f => e.Name.EndsWith(f, StringComparison.OrdinalIgnoreCase))) + { + return; + } + if (_tempIgnoredPaths.ContainsKey(e.FullPath)) { Logger.Info("Watcher requested to ignore change to " + e.FullPath); |
