public static string LoadFromLocalCache(Dictionary <LAKey, LAResult> licenseCache, Action <string> updates, string pathToCacheFolder = null) { string path = ""; if (!string.IsNullOrWhiteSpace(pathToCacheFolder)) { path = Path.Combine(pathToCacheFolder, "cache"); } else { path = Path.Combine(Directory.GetCurrentDirectory(), "cache"); } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } if (!Directory.Exists(path)) { return("Could not load the cache."); } var files = Directory.GetFiles(path); int filecount = 0; foreach (var file in files) { var fileContent = File.ReadAllText(file); string[] extractedFileInfo = Path.GetFileName(file).Split('.'); LicenseKey license = new LicenseKey(); var key = new LAKey { ProductId = Convert.ToInt32(extractedFileInfo[0]), Key = extractedFileInfo[1], SignMethod = Convert.ToInt32(extractedFileInfo[2]) }; var result = new LAResult(); result.Response = fileContent; if (key.SignMethod == 0) { result.LicenseKey = Newtonsoft.Json.JsonConvert.DeserializeObject <KeyInfoResult>(fileContent).LicenseKey; result.SignDate = result.LicenseKey.SignDate; } else { var response = Newtonsoft.Json.JsonConvert.DeserializeObject <RawResponse>(fileContent); result.LicenseKey = JsonConvert.DeserializeObject <LicenseKeyPI>(System.Text.UTF8Encoding.UTF8.GetString(Convert.FromBase64String(response.LicenseKey))).ToLicenseKey(); result.SignDate = result.LicenseKey.SignDate; } if (!string.IsNullOrEmpty(Program.RSAPublicKey) && !result.LicenseKey.HasValidSignature(Program.RSAPublicKey, Program.cacheLength).IsValid()) { updates($"The file '{file}' was not loaded from the cache. The signature check failed or the file is too old."); continue; } if (licenseCache.ContainsKey(key)) { if (licenseCache[key].SignDate < result.SignDate) { filecount++; licenseCache[key] = result; updates($"The cache was updated with '{file}'. The license was previously loaded from file was overridden."); } else { updates($"The file '{file}' was not loaded from the cache, since a newer version was provided manually."); } } else { licenseCache.Add(key, result); filecount++; updates($"The file '{file}' was loaded from the cache."); } } return($"Loaded {filecount}/{files.Count()} file(s) from cache."); }
public static string ProcessIncrementDecrementValueRequest(byte[] stream, HttpWebRequest newRequest, HttpListenerContext context, APIMethod method) { string bodyParams = System.Text.Encoding.Default.GetString(stream); var nvc = HttpUtility.ParseQueryString(bodyParams); int productId = -1; int.TryParse(nvc.Get("ProductId"), out productId); var licenseKey = nvc.Get("Key"); int intValue = -1; int.TryParse(nvc.Get("IntValue"), out intValue); int doId = -1; int.TryParse(nvc.Get("Id"), out doId); if (method == APIMethod.DecrementIntValueToKey) { doId = -1 * Math.Abs(doId); } else { doId = Math.Abs(doId); } if (!Program.attemptToRefresh && !string.IsNullOrEmpty(Program.RSAPublicKey)) { LAResult result = null; var key = new LAKey { Key = licenseKey, ProductId = productId, SignMethod = 0 }; var keyAlt = new LAKey { Key = licenseKey, ProductId = productId, SignMethod = 1 }; if (!Program.licenseCache.TryGetValue(key, out result) && !Program.licenseCache.TryGetValue(keyAlt, out result)) { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "License server error: could not find the license file (to increment/decrement the data object)." }); ReturnResponse(error, context); return($"Could not find the license file for '{licenseKey}' to continue with the increment or decrement operation."); } if (!result.LicenseKey.DataObjects.Any(x => x.Id == doId)) { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "License server error: could not find the data object in the license file (to increment/decrement the data object)." }); ReturnResponse(error, context); return($"Could not find the data object with ID {doId} in the license file for '{licenseKey}' to continue with the increment or decrement operation."); } var doKey = new DOKey { DOID = doId, Key = licenseKey, ProductId = productId }; Program.DOOperations.AddOrUpdate(doKey, doId, (x, y) => y + doId); var success = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Success, Message = "" }); ReturnResponse(success, context); return($"Updated data object successfully."); } else { // for now, just forward the request. ForwardRequest(stream, newRequest, context); //try //{ //} //catch (Exception ex) //{ //} } // add and store log. return(null); }
public static bool LoadLicenseFromFile(Dictionary <LAKey, LAResult> licenseCache, ConcurrentDictionary <LAKey, string> keysToUpdate, string pathToFile, out string errorMessage) { errorMessage = null; try { var file = System.IO.File.ReadAllText(pathToFile); var response = Newtonsoft.Json.JsonConvert.DeserializeObject <RawResponse>(file); LAKey key; LAResult result; if (!string.IsNullOrEmpty(response.LicenseKey)) { // SignMethod = 1 var licenseBytes = Convert.FromBase64String(response.LicenseKey); var licenseKey = JsonConvert.DeserializeObject <LicenseKeyPI>(System.Text.UTF8Encoding.UTF8.GetString(licenseBytes)).ToLicenseKey(); licenseKey.RawResponse = response; key = new LAKey { Key = licenseKey.Key, ProductId = licenseKey.ProductId, SignMethod = 1 }; result = new LAResult { LicenseKey = licenseKey, SignDate = licenseKey.SignDate, Response = file }; } else { // SignMethod = 0 var licenseKey = Newtonsoft.Json.JsonConvert.DeserializeObject <LicenseKey>(file); key = new LAKey { Key = licenseKey.Key, ProductId = licenseKey.ProductId, SignMethod = 0 }; result = new LAResult { LicenseKey = licenseKey, SignDate = licenseKey.SignDate, Response = JsonConvert.SerializeObject(new KeyInfoResult { Result = ResultType.Success, LicenseKey = licenseKey }) }; } if (!string.IsNullOrEmpty(Program.RSAPublicKey) && !result.LicenseKey.HasValidSignature(Program.RSAPublicKey, Program.cacheLength).IsValid()) { errorMessage = $"The file '{pathToFile}' was not loaded from the cache. The signature check failed."; return(false); } if (licenseCache.ContainsKey(key)) { if (licenseCache[key].SignDate < result.SignDate) { licenseCache[key] = result; keysToUpdate[key] = result.Response; } } else { licenseCache.Add(key, result); keysToUpdate.TryAdd(key, result.Response); } } catch (Exception ex) { return(false); } return(true); }
public static string ProcessActivateRequest(byte[] stream, Dictionary <LAKey, LAResult> licenseCache, int cacheLength, HttpWebRequest newRequest, HttpListenerContext context, ConcurrentDictionary <LAKey, string> keysToUpdate, bool attemptToRefresh, bool localFloatingServer, ConcurrentDictionary <LAKeyBase, ConcurrentDictionary <string, ActivationData> > activatedMachinesFloating, APIMethod method = APIMethod.Unknown) { string bodyParams = System.Text.Encoding.Default.GetString(stream); var nvc = HttpUtility.ParseQueryString(bodyParams); int productId = -1; int.TryParse(nvc.Get("ProductId"), out productId); int signMethod = -1; int.TryParse(nvc.Get("SignMethod"), out signMethod); if (nvc.Get("SignMethod") == "StringSign") { signMethod = 1; } var licenseKey = nvc.Get("Key"); var machineCode = nvc.Get("MachineCode"); var friendlyName = nvc.Get("FriendlyName"); int floatingTimeInterval = -1; int.TryParse(nvc.Get("FloatingTimeInterval"), out floatingTimeInterval); LAResult result = null; var key = new LAKey { Key = licenseKey, ProductId = productId, SignMethod = signMethod }; var keyAlt = new LAKey { Key = licenseKey, ProductId = productId, SignMethod = Math.Abs(signMethod - 1) }; if ((method == APIMethod.GetKey || floatingTimeInterval > 0) && localFloatingServer) { if (signMethod == 0) { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "License server error: SignMethod=1 is needed to use floating licensing offline." }); ReturnResponse(error, context); return($"SignMethod was not set to 1 for '{licenseKey}', which is needed to continue with the floating activation."); } if (Program.ConfigurationExpires != null && Program.ConfigurationExpires < DateTimeOffset.UtcNow) { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "License server error: The configuration has expired. Please contact the vendor to receive a new version of the license server to continue to use floating licenses offline." }); ReturnResponse(error, context); return($"The configuration has expired. Please contact the vendor to receive a new version of the license server to continue to use floating licenses offline."); } //floating license if (!licenseCache.TryGetValue(key, out result) && !licenseCache.TryGetValue(keyAlt, out result)) { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "License server error: could not find the license file (floating license)." }); ReturnResponse(error, context); return($"Could not find the license file for '{licenseKey}' to continue with the floating activation."); } if (result.LicenseKey.MaxNoOfMachines > 0 || method == APIMethod.GetKey) { var activationData = new ConcurrentDictionary <string, ActivationData>(); activatedMachinesFloating.TryGetValue(key, out activationData); if (activationData == null) { activationData = activatedMachinesFloating.AddOrUpdate(key, x => new ConcurrentDictionary <string, ActivationData>(), (x, y) => y); } if (method == APIMethod.GetKey) { FloatingResult(result, null, null, context, 1, activationData.Values.Select(x => new ActivationData { Time = x.Time, FloatingExpires = x.FloatingExpires, FriendlyName = x.FriendlyName, IP = x.IP, Mid = x.Mid }).ToList()); return($"Floating license {licenseKey} returned successfully using a GetKey request. The data from the local license server is used."); } var activation = new ActivationData(); activationData.TryGetValue(machineCode, out activation); if (activation != null && activation.FloatingExpires > DateTime.UtcNow) { activation.FloatingExpires = DateTime.UtcNow.AddSeconds(floatingTimeInterval); activation.FriendlyName = friendlyName; activation.IP = context.Request.RemoteEndPoint.ToString(); FloatingResult(result, activation, machineCode, context); return($"Floating license {licenseKey} returned successfully."); } else if (activationData.Count(x => x.Value.FloatingExpires > DateTime.UtcNow) < result.LicenseKey.MaxNoOfMachines) { activation = activationData.AddOrUpdate(machineCode, x => new ActivationData { Mid = machineCode, Time = DateTime.UtcNow, FloatingExpires = DateTime.UtcNow.AddSeconds(floatingTimeInterval), FriendlyName = friendlyName, IP = context.Request.RemoteEndPoint.ToString() }, (x, y) => new ActivationData { Mid = machineCode, Time = y.Time, FloatingExpires = DateTime.UtcNow.AddSeconds(floatingTimeInterval), FriendlyName = friendlyName, IP = context.Request.RemoteEndPoint.ToString() }); FloatingResult(result, activation, machineCode, context); return($"Floating license {licenseKey} returned successfully."); } else { var error = JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "Cannot activate the new device as the limit has been reached." }); ReturnResponse(error, context); return($"The limit of the number of concurrent devices for '{licenseKey}' was reached. Activation failed."); } // return new license } else { var activation = new ActivationData { Mid = machineCode, FriendlyName = friendlyName, IP = context.Request.RemoteEndPoint.ToString(), Time = DateTime.UtcNow, FloatingExpires = DateTime.UtcNow.AddSeconds(floatingTimeInterval) }; FloatingResult(result, activation, machineCode, context); return($"Floating license {licenseKey} returned successfully."); } } else if (licenseCache.TryGetValue(key, out result) && (method == APIMethod.GetKey || result?.LicenseKey?.ActivatedMachines.Any(x => x.Mid == machineCode) == true) && cacheLength > 0) { TimeSpan ts = DateTime.UtcNow - result.SignDate; if (ts.Days >= cacheLength || attemptToRefresh) { // need to obtain new license try { result.Response = ForwardRequest(stream, newRequest, context); } catch (Exception ex) { if (ts.Days >= cacheLength) { if (method == APIMethod.GetKey) { return($"Could not retrieve an updated license '{licenseKey}'."); } else { return($"Could not retrieve an updated license '{licenseKey}' and machine code '{machineCode}'."); } } else if (attemptToRefresh) { ReturnResponse(result.Response, context); if (method == APIMethod.GetKey) { return($"Retrieved cached version of the license '{licenseKey}'."); } else { return($"Retrieved cached version of the license '{licenseKey}' and machine code '{machineCode}'."); } } } if (signMethod == 1) { var resultObject = JsonConvert.DeserializeObject <RawResponse>(result.Response); var license2 = JsonConvert.DeserializeObject <LicenseKeyPI>(System.Text.UTF8Encoding.UTF8.GetString(Convert.FromBase64String(resultObject.LicenseKey))).ToLicenseKey(); result.SignDate = license2.SignDate; result.LicenseKey = license2; } else { var resultObject = JsonConvert.DeserializeObject <KeyInfoResult>(result.Response); result.SignDate = resultObject.LicenseKey.SignDate; result.LicenseKey = resultObject.LicenseKey; } keysToUpdate.AddOrUpdate(key, x => result.Response, (x, y) => result.Response); if (method == APIMethod.GetKey) { return($"Cache updated for license '{licenseKey}'."); } else { return($"Cache updated for license '{licenseKey}' and machine code '{machineCode}'."); } } else { ReturnResponse(result.Response, context); if (method == APIMethod.GetKey) { return($"Retrieved cached version of the license '{licenseKey}'."); } else { return($"Retrieved cached version of the license '{licenseKey}' and machine code '{machineCode}'."); } } } else { result = new LAResult(); try { result.Response = ForwardRequest(stream, newRequest, context); } catch (WebException ex) { try { var output = ReadToByteArray(ex.Response.GetResponseStream()); context.Response.OutputStream.Write(output, 0, output.Length); context.Response.KeepAlive = false; context.Response.Close(); return($"Could not contact the server '{licenseKey}' and machine code '{machineCode}'. Error message {ex?.Message}."); } catch (Exception ex2) { ReturnResponse(JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "Could not contact the central sever (api.cryptolens.io:443)." }), context); return($"Could not contact the server '{licenseKey}' and machine code '{machineCode}'. Error message {ex2?.Message} and stack trace {ex2?.StackTrace}"); } } catch (Exception ex) { ReturnResponse(JsonConvert.SerializeObject(new BasicResult { Result = ResultType.Error, Message = "Could not contact the central sever (api.cryptolens.io:443)." }), context); return($"Could not contact the server '{licenseKey}' and machine code '{machineCode}'. Error message {ex?.Message} and stack trace {ex?.StackTrace}"); } if (cacheLength > 0) { if (signMethod == 1) { var resultObject = JsonConvert.DeserializeObject <RawResponse>(result.Response); if (!SKM.V3.Methods.Helpers.IsSuccessful(resultObject)) { return($"The error '{resultObject?.Message}' was received from the server for license '{licenseKey}' and machine code '{machineCode}'. The method {method} was used. Read more at https://help.cryptolens.io/faq/index#troubleshooting-api-errors."); } var license2 = JsonConvert.DeserializeObject <LicenseKeyPI>(System.Text.UTF8Encoding.UTF8.GetString(Convert.FromBase64String(resultObject.LicenseKey))).ToLicenseKey(); result.SignDate = license2.SignDate; result.LicenseKey = license2; } else { var resultObject = JsonConvert.DeserializeObject <KeyInfoResult>(result.Response); result.SignDate = resultObject.LicenseKey.SignDate; result.LicenseKey = resultObject.LicenseKey; } if (licenseCache.ContainsKey(key)) { licenseCache[key] = result; } else { licenseCache.Add(key, result); } keysToUpdate.AddOrUpdate(key, x => result.Response, (x, y) => result.Response); return($"Added to the cache the license '{licenseKey}' and machine code '{machineCode}'."); } return(null); } }