SafeDispatch/Dongle RegLib/RegLib.cs
2024-02-22 18:43:59 +02:00

991 lines
29 KiB
C#

//#define jurgen
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.IO;
using Microsoft.Win32;
using SafeMobileLib;
namespace RegLibDLL
{
public class RegLib
{
private String parola = "ab09ads08asd8080fg09a90g08sfd808bfb08hg0j08f80";
private Int32 uid = 1738349905;
private Int32 hid = 0;
private Int32 handle;
private String decodedMessage;
private Boolean validDongle;
private Boolean existsDongle;
private Int16 offset = -20;
private Int16 zonesIndex = 315;
private Int16 reportsIndex = 316;
private Int16 telemetryIndex = 317;
private Int16 voiceIndex = 318;
private Int16 emailGatewayIndex = 319;
private Int16 unitCountIndex = 320;
private Int16 mapType1Index = 325;
private Int16 mapType2Index = 326;
private Int16 mapType3Index = 327;
private Int16 mapType4Index = 328;
private Int16 safeDispatchIndex = 329;
private Int16 gatewayIndex = 330;
private Int16 gpsIndex = 331;
private Int16 smsIndex = 332;
private Int16 SDMobileIndex = 333;
private Int16 jobTicketingIndex = 334;
private Int16 recordingsIndex = 335;
private Int16 audibleAlertsIndex = 336;
private Int16 dbAccessIndex = 337;
private String msgIPs = "";
private Boolean oldDongle = false;
public Boolean demoMode = false;
private String password = "ab09ads08asd8080fg09a90g08sfd808bfb08hg0j08f80";
private uint firstRunTime = 0;
private uint lastRunTime = 0;
private uint remainingDemoTime = 0;
private uint demoPeriod30DaysInSec = 2592000;
private uint demoPeriod14DaysInSec = 1209600;
private uint demoDuration = 2 * 2592000;
//private String licenseFileName = "E:\\WorkSpace_cSharp\\SafeDispatch_v4\\AppServerService\\bin\\Debug\\NSpeex2.dll";
public Boolean AIRTURKEYLIMIT = false;
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=--=
[DllImport("SDX.dll")]
static extern int SDX_Find();
[DllImport("SDX.dll")]
static extern int SDX_Open(int mode, Int32 uid, ref Int32 hid);
[DllImport("SDX.dll")]
static extern void SDX_Close(int handle);
[DllImport("SDX.dll")]
static extern int SDX_Read(int handle, int block_index, byte[] buffer512);
[DllImport("SDX.dll")]
static extern int SDX_Write(int handle, int block_index, String buffer512);
//public RegLib(String pathToRegFile, bool aaaa)
//{
// if (!pathToRegFile.EndsWith("\\"))
// pathToRegFile += "\\";
// licenseFileName = pathToRegFile + licenseFileName;
//}
public RegLib()
{
String msg;
String safemobilePath = Utils.GetRegValue("Path", "SafeMobile");
String licenseFileName = safemobilePath + "\\AppServer\\NSpeex2.dll";
if (findDongle())
{
applyOffset();
openDongle();
msg = readDataFromDongle(0);
msgIPs = readDataFromDongle(1);
existsDongle = true;
//checks that a valid message is written on the dongle
int index = msg.IndexOf("SafeMobi");
if (index > 0)
{
String data = msg.Substring(0, index);
decodedMessage = DecryptString(data, parola);
validDongle = true;
remainingDemoTime = 2*2592001;
}
else
{
decodedMessage = "";
validDongle = false;
}
}
else
{
existsDongle = false;
String data = "";
try
{
data = File.ReadAllText(licenseFileName);
String decryptedData = DecryptString(data, password);
demoMode = true;
if (decryptedData.Substring(199, 10).Equals("1111111111"))
{
Console.WriteLine("Demo invalidated");
remainingDemoTime = 1;
validDongle = false;
}
else
{
if (decryptedData.Substring(89, 10).Equals("0000000000"))
{
uint firstRunTime = DateTo70Format(DateTime.Now);
String firstPart = decryptedData.Substring(0, 89);
String middlePart = decryptedData.Substring(99, 100);
String lastPart = decryptedData.Substring(209);
String newData = firstPart + firstRunTime.ToString() + middlePart + firstRunTime.ToString()
+ lastPart;
String encryptedData = EncryptString(newData, password);
File.WriteAllText(licenseFileName, encryptedData);
remainingDemoTime = demoDuration;
}
else
{
firstRunTime = (uint)Int32.Parse(decryptedData.Substring(89, 10));
lastRunTime = (uint)Int32.Parse(decryptedData.Substring(199, 10));
uint currentRunTime = DateTo70Format(DateTime.Now);
if (currentRunTime > firstRunTime + demoDuration)
{
Console.WriteLine("Demo expired");
remainingDemoTime = 0;
validDongle = false;
}
else
{
String firstPart = decryptedData.Substring(0, 199);
String lastPart = decryptedData.Substring(209);
String newData = "";
if (currentRunTime < lastRunTime)//detected user attempt to cheat, invalidating license for good
{
remainingDemoTime = 1;
Console.WriteLine("Detected rollback of system time, disabling demo.");
newData = firstPart + "1111111111" + lastPart;
}
else
{
remainingDemoTime = firstRunTime + demoDuration - currentRunTime;
newData = firstPart + currentRunTime.ToString() + lastPart;
}
String encryptedData = EncryptString(newData, "ab09ads08asd8080fg09a90g08sfd808bfb08hg0j08f80");
File.WriteAllText(licenseFileName, encryptedData);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Invalid dongle AND invalid license file. Exception: " + ex.ToString());
validDongle = false;
return;
}
}
}
public RegLib(String dataToWrite)
{
applyOffset();
if (findDongle())
{
openDongle();
writeToDongle(dataToWrite, 0);
existsDongle = true;
int index = dataToWrite.IndexOf("SafeMobi");
if (index > 0)
{
String data = dataToWrite.Substring(0, index);
decodedMessage = DecryptString(data, parola);
validDongle = true;
}
else
{
decodedMessage = "";
validDongle = false;
}
}
}
/// <summary>
/// Returns the remaining demo time, in seconds
/// </summary>
/// <returns></returns>
public uint remainingTime()
{
return remainingDemoTime;
}
private uint DateTo70Format(DateTime param)
{
long nOfSeconds;
System.DateTime dt70 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan span = param - dt70;
nOfSeconds = (long)span.TotalSeconds;
return ((uint)nOfSeconds);
}
private void applyOffset()
{
zonesIndex = (Int16)(zonesIndex + offset);
reportsIndex = (Int16)(reportsIndex + offset);
telemetryIndex = (Int16)(telemetryIndex + offset);
voiceIndex = (Int16)(voiceIndex + offset);
emailGatewayIndex = (Int16)(emailGatewayIndex + offset);
unitCountIndex = (Int16)(unitCountIndex + offset);
mapType1Index = (Int16)(mapType1Index + offset);
mapType2Index = (Int16)(mapType2Index + offset);
mapType3Index = (Int16)(mapType3Index + offset);
mapType4Index = (Int16)(mapType4Index + offset);
safeDispatchIndex = (Int16)(safeDispatchIndex + offset);
gatewayIndex = (Int16)(gatewayIndex + offset);
gpsIndex = (Int16)(gpsIndex + offset);
smsIndex = (Int16)(smsIndex + offset);
jobTicketingIndex = (Int16)(jobTicketingIndex + offset);
recordingsIndex = (Int16)(recordingsIndex + offset);
SDMobileIndex = (Int16)(SDMobileIndex + offset);
audibleAlertsIndex = (Int16)(audibleAlertsIndex + offset);
dbAccessIndex = (Int16)(dbAccessIndex + offset);
}
private String getDecodedMessage()
{
return decodedMessage;
}
public Boolean findDongle()
{
#if jurgen
return true;
#else
int ret = SDX_Find();
if (ret > 1)
{
return true;
}
else if (ret == 1)
{
return true;
}
else
{
return false;
}
#endif
}
private Boolean openDongle()
{
#if jurgen
return true;
#else
int ret = SDX_Open(1, uid, ref hid);
if (ret < 0)
{
return false;
}
handle = ret;
return true;
#endif
}
private String readDataFromDongle(int blockNumber)
{
Byte[] retbuff = new byte[512];
int ret = SDX_Read(handle, blockNumber, retbuff);
if (ret < 0)
{
return "";
}
String sReturn = System.Text.ASCIIEncoding.ASCII.GetString(retbuff);
return sReturn;
}
public Int32 writeToDongle(String dataToWrite, Int32 blockIndex)
{
int ret = SDX_Write(handle, blockIndex, dataToWrite);
if (ret < 0)
{
return -1;
}
return 0;
}
private String DecryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToDecrypt = Convert.FromBase64String(Message);
try
{
ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return UTF8.GetString(Results);
}
public static string EncryptString(string Message, string Passphrase)
{
byte[] results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
byte[] DataToEncrypt = UTF8.GetBytes(Message);
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
TDESAlgorithm.Clear();
HashProvider.Clear();
}
return (Convert.ToBase64String(results));
}
/// <summary>
/// Checks for existence of dongle.
/// </summary>
/// <returns>true if dongle exists and false otherwise</returns>
public Boolean dongleDetected()
{
#if jurgen
return true;
#else
if (existsDongle)
{
return true;
}
else
{
return false;
}
#endif
}
/// <summary>
/// Checks for validity of data on dongle
/// </summary>
/// <returns>true if valid dongle (i.e. data) and false otherwies</returns>
public Boolean validData()
{
#if jurgen
return true;
#else
if (validDongle)
{
return true;
}
else
{
return false;
}
#endif
}
/// <summary>
/// Get the customer ID from the dongle
/// </summary>
/// <returns>A string with the customer ID or null if incorrect data on dongle</returns>
public String customerID()
{
if (validDongle)
{
Int32 length = Convert.ToInt32(decodedMessage.Substring(10, 3));
return decodedMessage.Substring(13, length);
}
else
{
return null;
}
}
/// <summary>
/// Get the customer name from the dongle
/// </summary>
/// <returns>A string with the customer name or null if incorrect data on dongle</returns>
public String customerName()
{
if (validDongle)
{
Int32 length = Convert.ToInt32(decodedMessage.Substring(35, 3));
return decodedMessage.Substring(38, length);
}
else
{
return null;
}
}
/// <summary>
/// Get the customer address from the dongle
/// </summary>
/// <returns>A string with the customer address or null if incorrect data on dongle</returns>
public String customerAddress()
{
if (validDongle)
{
Int32 length = Convert.ToInt32(decodedMessage.Substring(85, 3));
return decodedMessage.Substring(88, length);
}
else
{
return null;
}
}
/// <summary>
/// Get the customer contact person from the dongle
/// </summary>
/// <returns>A string with the customer contact person name or null if incorrect data on dongle</returns>
public String customerContactPerson()
{
if (validDongle)
{
Int32 length = Convert.ToInt32(decodedMessage.Substring(195, 3));
return decodedMessage.Substring(198, length);
}
else
{
return null;
}
}
/// <summary>
/// Get the zones count from the dongle
/// </summary>
/// <returns>number of registered zones from the dongle, and 0 if dongle not valid</returns>
public int zonesCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[zonesIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the gps count from the dongle
/// </summary>
/// <returns>number of gps licenses from the dongle, and 0 if dongle not valid</returns>
public int gpsCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[gpsIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the sms count from the dongle
/// </summary>
/// <returns>number of sms licenses from the dongle, and 0 if dongle not valid</returns>
public int smsCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[smsIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the job ticketing count from the dongle
/// </summary>
/// <returns>number of job ticketing licenses from the dongle, and 0 if dongle not valid</returns>
public int jobTicketingCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[jobTicketingIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the recordings count from the dongle
/// </summary>
/// <returns>number of recordings licenses from the dongle, and 0 if dongle not valid</returns>
public int recordingsCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[recordingsIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the voip count from the dongle
/// </summary>
/// <returns>number of voip licences from the dongle, and 0 if dongle not valid</returns>
public int voiceCount()
{
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[voiceIndex]);
}
else
{
return 0;
}
}
/// <summary>
/// Get the Audible Alerts count from the dongle
/// </summary>
/// <returns> 1 if user has audible alerts or 0 if user doesn't have audible alerts</returns>
public int audibleAlertsCount()
{
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[audibleAlertsIndex]);
}
else
{
return 0;
}
}
/// <summary>
/// Get the DB Access count from the dongle
/// </summary>
/// <returns>number of voip licences from the dongle, and 0 if dongle not valid</returns>
public int dbAccessCount()
{
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[dbAccessIndex]);
}
else
{
return 0;
}
}
/// <summary>
/// Get the email gateway count status from the dongle
/// </summary>
/// <returns>number of email licences from the dongle, and 0 if dongle not valid</returns>
public int emailGatewayCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[emailGatewayIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the number of units from the dongle
/// </summary>
/// <returns>The number of units from the dongle data, or 0 if no dongle is detected</returns>
public int getNumberOfUnits()
{
#if jurgen
return 45;
#else
if (demoMode)
{
return 12; //10
}
if (oldDongle)
{
return 12; //10
}
int numberOfUnits = 0;
if (validDongle)
{
String numbersString = decodedMessage.Substring(unitCountIndex, 5);
numberOfUnits = Convert.ToInt32(numbersString);
if (numberOfUnits == 12345)
{
AIRTURKEYLIMIT = true;
return 150;
}
else return numberOfUnits;
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the reports count from the dongle
/// </summary>
/// <returns>number of reports licences from the dongle, and 0 if dongle not valid</returns>
public int reportsCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[reportsIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the telemetry count from the dongle
/// </summary>
/// <returns>number of telemetry licences from the dongle, and 0 if dongle not valid</returns>
public int telemetryCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[telemetryIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the map type 1 count (initially Google only) from the dongle
/// </summary>
/// <returns>number of map type 1 licences from the dongle, and 0 if dongle not valid</returns>
public int mapType1Count()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[mapType1Index]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the map type 2 count from the dongle
/// </summary>
/// <returns>number of map type 2 licences from the dongle, and 0 if dongle not valid</returns>
public int mapType2Count()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[mapType2Index]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the map type 3 count from the dongle
/// </summary>
/// <returns>number of map type 3 licences from the dongle, and 0 if dongle not valid</returns>
public int mapType3Count()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[mapType3Index]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the map type 4 count from the dongle
/// </summary>
/// <returns>number of map type 4 licences from the dongle, and 0 if dongle not valid</returns>
public int mapType4Count()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[mapType4Index]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the SafeDispatch activation count from the dongle
/// </summary>
/// <returns>number of SafeDispatch licences from the dongle, and 0 if dongle not valid</returns>
public int safeDispatchCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
if (validDongle)
{
return ((int)decodedMessage[safeDispatchIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the gateway activation status from the dongle
/// </summary>
/// <returns>true if gateway is enabled and false if gateway not enabled or incorrect data on dongle</returns>
public Boolean enabledGateway()
{
#if jurgen
return true;
#else
if (demoMode)
{
return true;
}
if (validDongle)
{
if (decodedMessage[342].CompareTo('y') == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
#endif
}
/// <summary>
/// Get the gateway activation count from the dongle
/// </summary>
/// <returns>number of gateway licences from the dongle, and 0 if dongle not valid</returns>
public int gatewayCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
/*if (enabledGateway())
{
oldDongle = true;
return 1;
}
oldDongle = false;*/
if (validDongle)
{
return ((int)decodedMessage[gatewayIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Get the SDMobile activation count from the dongle
/// </summary>
/// <returns>number of SDMobile licences from the dongle, and 0 if dongle not valid</returns>
public int SDMobileCount()
{
#if jurgen
return 2;
#else
if (demoMode)
{
return 1;
}
/*if (enabledGateway())
{
oldDongle = true;
return 1;
}
oldDongle = false;*/
if (validDongle)
{
return ((int)decodedMessage[SDMobileIndex]);
}
else
{
return 0;
}
#endif
}
/// <summary>
/// Detects if the HID in the dongle data corresponds with the HID of the dongle itself
/// </summary>
/// <returns>true if HID checks out and false if HID is different or incorrect data on dongle</returns>
public Boolean isCorrectHID()
{
#if jurgen
return true;
#else
if (demoMode)
{
return true;
}
if (validDongle)
{
Int32 length = Convert.ToInt32(decodedMessage.Substring(320, 3));
String HID_READ = decodedMessage.Substring(323, length);
if (HID_READ.CompareTo(hid.ToString()) == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
#endif
}
}
}