|
@@ -4,40 +4,96 @@ using System.Diagnostics;
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
+using System.Net.NetworkInformation;
|
|
|
|
|
|
namespace InABox.Core
|
|
|
{
|
|
|
public static class LicenseUtils
|
|
|
{
|
|
|
- #region License Generation
|
|
|
+ #region Mac Addresses
|
|
|
+
|
|
|
+ public static String[] GetMacAddresses()
|
|
|
+ {
|
|
|
+ return NetworkInterface
|
|
|
+ .GetAllNetworkInterfaces()
|
|
|
+ .Where(nic =>
|
|
|
+ nic.OperationalStatus == OperationalStatus.Up &&
|
|
|
+ nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
|
|
|
+ .Select(nic => nic.GetPhysicalAddress().ToString()).ToArray();
|
|
|
+ }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Generate a new, out-of-the-box license.
|
|
|
- /// </summary>
|
|
|
- /// <returns>The new license, valid for 1 month.</returns>
|
|
|
- public static LicenseData GenerateNewLicense()
|
|
|
+ public static bool ValidateMacAddresses(String[] addresses)
|
|
|
{
|
|
|
- return new LicenseData
|
|
|
- {
|
|
|
- LastRenewal = DateTime.Now,
|
|
|
- Expiry = DateTime.Now.AddMonths(1),
|
|
|
- CustomerID = Guid.Empty,
|
|
|
- RenewalAvailable = DateTime.Now.AddMonths(1).AddDays(-7)
|
|
|
- };
|
|
|
+ var hardware = GetMacAddresses();
|
|
|
+ return hardware.Any(addresses.Contains);
|
|
|
}
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region License Generation
|
|
|
+
|
|
|
|
|
|
- public static LicenseData RenewLicense(LicenseData oldLicense, DateTime renewed, DateTime newExpiry, DateTime renewAvailable)
|
|
|
+ public static LicenseData RenewLicense(LicenseData oldLicense, DateTime renewed, DateTime newExpiry, DateTime renewAvailable, String[] addresses)
|
|
|
{
|
|
|
return new LicenseData
|
|
|
{
|
|
|
LastRenewal = renewed,
|
|
|
Expiry = newExpiry,
|
|
|
- CustomerID = oldLicense.CustomerID,
|
|
|
- RenewalAvailable = renewAvailable
|
|
|
+ CustomerID = oldLicense?.CustomerID ?? Guid.Empty,
|
|
|
+ RenewalAvailable = renewAvailable,
|
|
|
+ Addresses = addresses,
|
|
|
+ IsDynamic = oldLicense?.IsDynamic ?? false
|
|
|
};
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static readonly byte[] LicenseKey = Convert.FromBase64String("dCyTyQkj1o1rqJJQlT+Jcnkxr+OQnO4KCoF/b+6cx54=");
|
|
|
+
|
|
|
+ public static string? EncryptLicenseRequest(LicenseRequest request)
|
|
|
+ {
|
|
|
+ return Encryption.EncryptV2(Serialization.Serialize(request), LicenseKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static bool TryEncryptLicenseRequest(LicenseRequest request, [NotNullWhen(true)] out string? result, [NotNullWhen(false)] out string? error)
|
|
|
+ {
|
|
|
+ return Encryption.TryEncryptV2(Serialization.Serialize(request), LicenseKey, out result, out error);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Decrypts <paramref name="request"/>.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request">The request to decrypt.</param>
|
|
|
+ /// <returns>
|
|
|
+ /// The new license request, or <see langword="null"/> if errors occurred.
|
|
|
+ /// </returns>
|
|
|
+ public static bool TryDecryptLicenseRequest(string data, [NotNullWhen(true)] out LicenseRequest? result, [NotNullWhen(false)] out string? error)
|
|
|
+ {
|
|
|
+ if (!Encryption.TryDecryptV2(data, LicenseKey, out var decrypted, out error))
|
|
|
+ {
|
|
|
+ result = null;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ result = Serialization.Deserialize<LicenseRequest>(decrypted);
|
|
|
+ if(result == null)
|
|
|
+ {
|
|
|
+ error = "Request deserialization failed";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// Decrypts <paramref name="request"/>, throwing an <see cref="Exception"/> on fail.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request">The data to decrypt.</param>
|
|
|
+ /// <returns>
|
|
|
+ /// The new license request.
|
|
|
+ /// </returns>
|
|
|
+ public static LicenseRequest DecryptLicenseRequest(string data)
|
|
|
+ {
|
|
|
+ if (!TryDecryptLicenseRequest(data, out var result, out var error))
|
|
|
+ throw new Exception(error);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// Encrypts the license data.
|
|
@@ -50,6 +106,7 @@ namespace InABox.Core
|
|
|
{
|
|
|
return Encryption.EncryptV2(Serialization.Serialize(license), LicenseKey);
|
|
|
}
|
|
|
+
|
|
|
public static bool TryEncryptLicense(LicenseData license, [NotNullWhen(true)] out string? result, [NotNullWhen(false)] out string? error)
|
|
|
{
|
|
|
return Encryption.TryEncryptV2(Serialization.Serialize(license), LicenseKey, out result, out error);
|
|
@@ -161,17 +218,17 @@ namespace InABox.Core
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- public static void LoadSummary(LicenseSummary summary)
|
|
|
+ public static void LoadSummary(LicenseFeeResponse feeResponse)
|
|
|
{
|
|
|
_licensefees.Clear();
|
|
|
_periods.Clear();
|
|
|
_userDiscounts.Clear();
|
|
|
|
|
|
- foreach (var license in summary.LicenseFees)
|
|
|
+ foreach (var license in feeResponse.LicenseFees)
|
|
|
_licensefees[license.Key] = license.Value;
|
|
|
- foreach (var (months, period) in summary.TimeDiscounts)
|
|
|
+ foreach (var (months, period) in feeResponse.TimeDiscounts)
|
|
|
_periods[months] = period;
|
|
|
- foreach (var (users, discount) in summary.UserDiscounts)
|
|
|
+ foreach (var (users, discount) in feeResponse.UserDiscounts)
|
|
|
_userDiscounts[users] = discount;
|
|
|
}
|
|
|
|
|
@@ -230,14 +287,14 @@ namespace InABox.Core
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
- public class LicenseSummaryRequest
|
|
|
+ public class LicenseFeeRequest
|
|
|
{
|
|
|
public Guid RegistrationID { get; set; }
|
|
|
}
|
|
|
|
|
|
- public class LicenseSummary
|
|
|
+ public class LicenseFeeResponse
|
|
|
{
|
|
|
- public LicenseSummary()
|
|
|
+ public LicenseFeeResponse()
|
|
|
{
|
|
|
LicenseFees = new Dictionary<string, double>();
|
|
|
TimeDiscounts = new Dictionary<int, double>();
|