MBLicenseFile.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using MediaBrowser.Common.Configuration;
  9. using MediaBrowser.Model.Cryptography;
  10. using MediaBrowser.Model.IO;
  11. namespace Emby.Server.Implementations.Security
  12. {
  13. internal class MBLicenseFile
  14. {
  15. private readonly IApplicationPaths _appPaths;
  16. private readonly IFileSystem _fileSystem;
  17. private readonly ICryptoProvider _cryptographyProvider;
  18. public string RegKey
  19. {
  20. get { return _regKey; }
  21. set
  22. {
  23. if (value != _regKey)
  24. {
  25. //if key is changed - clear out our saved validations
  26. _updateRecords.Clear();
  27. _regKey = value;
  28. }
  29. }
  30. }
  31. private string Filename
  32. {
  33. get
  34. {
  35. return Path.Combine(_appPaths.ConfigurationDirectoryPath, "mb.lic");
  36. }
  37. }
  38. private readonly ConcurrentDictionary<Guid, DateTime> _updateRecords = new ConcurrentDictionary<Guid, DateTime>();
  39. private readonly object _fileLock = new object();
  40. private string _regKey;
  41. public MBLicenseFile(IApplicationPaths appPaths, IFileSystem fileSystem, ICryptoProvider cryptographyProvider)
  42. {
  43. _appPaths = appPaths;
  44. _fileSystem = fileSystem;
  45. _cryptographyProvider = cryptographyProvider;
  46. Load();
  47. }
  48. private void SetUpdateRecord(Guid key, DateTime value)
  49. {
  50. _updateRecords.AddOrUpdate(key, value, (k, v) => value);
  51. }
  52. public void AddRegCheck(string featureId)
  53. {
  54. var key = new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId)));
  55. var value = DateTime.UtcNow;
  56. SetUpdateRecord(key, value);
  57. Save();
  58. }
  59. public void RemoveRegCheck(string featureId)
  60. {
  61. var key = new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId)));
  62. DateTime val;
  63. _updateRecords.TryRemove(key, out val);
  64. Save();
  65. }
  66. public DateTime LastChecked(string featureId)
  67. {
  68. DateTime last;
  69. _updateRecords.TryGetValue(new Guid(_cryptographyProvider.ComputeMD5(Encoding.Unicode.GetBytes(featureId))), out last);
  70. // guard agains people just putting a large number in the file
  71. return last < DateTime.UtcNow ? last : DateTime.MinValue;
  72. }
  73. private void Load()
  74. {
  75. string[] contents = null;
  76. var licenseFile = Filename;
  77. lock (_fileLock)
  78. {
  79. try
  80. {
  81. contents = _fileSystem.ReadAllLines(licenseFile);
  82. }
  83. catch (FileNotFoundException)
  84. {
  85. lock (_fileLock)
  86. {
  87. _fileSystem.WriteAllBytes(licenseFile, new byte[] {});
  88. }
  89. }
  90. catch (IOException)
  91. {
  92. lock (_fileLock)
  93. {
  94. _fileSystem.WriteAllBytes(licenseFile, new byte[] { });
  95. }
  96. }
  97. }
  98. if (contents != null && contents.Length > 0)
  99. {
  100. //first line is reg key
  101. RegKey = contents[0];
  102. //next is legacy key
  103. if (contents.Length > 1)
  104. {
  105. // Don't need this anymore
  106. }
  107. //the rest of the lines should be pairs of features and timestamps
  108. for (var i = 2; i < contents.Length; i = i + 2)
  109. {
  110. var line = contents[i];
  111. if (string.IsNullOrWhiteSpace(line))
  112. {
  113. continue;
  114. }
  115. Guid feat;
  116. if (Guid.TryParse(line, out feat))
  117. {
  118. SetUpdateRecord(feat, new DateTime(Convert.ToInt64(contents[i + 1])));
  119. }
  120. }
  121. }
  122. }
  123. public void Save()
  124. {
  125. //build our array
  126. var lines = new List<string>
  127. {
  128. RegKey,
  129. // Legacy key
  130. string.Empty
  131. };
  132. foreach (var pair in _updateRecords
  133. .ToList())
  134. {
  135. lines.Add(pair.Key.ToString());
  136. lines.Add(pair.Value.Ticks.ToString(CultureInfo.InvariantCulture));
  137. }
  138. var licenseFile = Filename;
  139. _fileSystem.CreateDirectory(Path.GetDirectoryName(licenseFile));
  140. lock (_fileLock)
  141. {
  142. _fileSystem.WriteAllLines(licenseFile, lines);
  143. }
  144. }
  145. }
  146. }