Files
Work/guitar/license.cpp
2024-08-07 09:16:27 -04:00

120 lines
3.6 KiB
C++

#include <guitar/license.hpp>
#include <guitar/uutool.hpp>
#include <common/block.hpp>
#include <common/versioninfo.hpp>
/*
The license will be uuencoded on top of xor. This should be sufficient to protect the contents.
Lic: TM105R20020101013001EF
VVVVVVYYYYMMDDTTDDCCCC
XX=version TM105R. should check this against this product version and release
YYYY=year of license issuance. 30 day license will use this value to expire itself.
MM=month of license issuance 30 day license will use this value to expiure
DD=day of license issuance
TT=type of license
01=30 day license, expires 30 days from issuance.
02=Full license, never expires.
DD=for type 01 license, indicates number of days license is good for.
CCCC=checksum, just add up ASCII values of the characters through TT, display in hex.
*/
const String License::smBeginLicense="BEGIN LICENSE";
const String License::smEndLicense="END LICENSE";
String License::generate(const String &strProductVersion,const SystemTime &issueDate,LicenseType licenseType,int dayCount)
{
String strLicenseKey;
String strIssueDate;
String strLicenseType;
String strDayCount;
String strChecksum;
strLicenseKey=String("TM");
strLicenseKey+=strProductVersion.substr(0,3);
::sprintf(strIssueDate,"%4d%02d%02d",issueDate.year(),issueDate.month(),issueDate.day());
strLicenseKey+=strIssueDate;
::sprintf(strLicenseType,"%02d",licenseType);
strLicenseKey+=strLicenseType;
::sprintf(strDayCount,"%02d",dayCount);
strLicenseKey+=strDayCount;
::sprintf(strChecksum,"%04lx",calculateChecksum(strLicenseKey));
strLicenseKey+=strChecksum;
return UUTool::encode(xor(strLicenseKey));
}
String numericEncode(const String &strLicense)
{
return String();
}
String numericDecode(const String &strLicense)
{
return String();
}
bool License::fromLines(Block<String> &strLicenseLines)
{
if(3!=strLicenseLines.size())return false;
if(!(strLicenseLines[0]==smBeginLicense))return false;
if(!(strLicenseLines[2]==smEndLicense))return false;
return fromString(strLicenseLines[1]);
}
// TM105R2002040301 30 03d8
bool License::fromString(const String &strLicense)
{
VersionInfo versionInfo;
SystemTime currDate;
SystemTime expireDate;
String strHeader;
String strDecoded;
String strVersion;
int hashCode;
mUUEncodedLicense=strLicense;
strDecoded=xor(UUTool::decode(strLicense));
strHeader=strDecoded.substr(0,1);
if(!(strHeader==String("TM")))return false;
mProductVersion=strDecoded.substr(2,5);
mIssueDate.year(strDecoded.substr(6,9).toInt());
mIssueDate.month((SystemTime::Month)strDecoded.substr(10,11).toInt());
mIssueDate.day(strDecoded.substr(12,13).toInt());
mLicenseType=(LicenseType)strDecoded.substr(14,15).toInt();
mDayCount=strDecoded.substr(16,17).toInt();
hashCode=strDecoded.substr(18,21).hex();
if(hashCode!=calculateChecksum(strDecoded.substr(0,17)))return false;
strVersion=versionInfo.getProductVersionString();
strVersion.removeTokens(", ");
strVersion.upper();
if(!(strVersion==mProductVersion))return false;
if(Permanent==mLicenseType)return mIsValid=true;
expireDate=mIssueDate;
expireDate.daysAdd360(mDayCount);
if(currDate>=expireDate)return false;
return mIsValid=true;
}
String License::xor(const String &strLicense)
{
String strEncoded;
int strLength;
strEncoded.reserve((strLength=strLicense.length())+1);
for(int index=0;index<strLength;index++)strEncoded.setAt(index,strLicense.charAt(index)^XORMagic);
return strEncoded;
}
int License::calculateChecksum(const String &string)
{
int stringLength=string.length();
int sum=0;
for(int index=0;index<stringLength;index++)sum+=string[index];
return sum;
}