Add files via upload
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
LicenceFileCheck.mqh
|
||||
Copyright 2021, Orchard Forex
|
||||
https://www.orchardforex.com
|
||||
*/
|
||||
|
||||
#property copyright "Copyright 2013-2020, Orchard Forex"
|
||||
#property link "https://www.orchardforex.com"
|
||||
#property version "1.00"
|
||||
|
||||
class CLicenceFile {
|
||||
|
||||
protected:
|
||||
string mProductName;
|
||||
string mProductKey;
|
||||
string mData;
|
||||
|
||||
virtual bool LoadData( string &data );
|
||||
virtual string LicencePath();
|
||||
|
||||
public:
|
||||
CLicenceFile( string productName, string productKey );
|
||||
~CLicenceFile() {}
|
||||
|
||||
bool Check();
|
||||
string KeyGen( string data ); // Allow account to pass in
|
||||
string Hash( string data );
|
||||
bool FileGen( string data );
|
||||
|
||||
void chekload2(string &dat1) {LoadData(dat1);}
|
||||
string GetData() { return ( mData ); }
|
||||
};
|
||||
|
||||
CLicenceFile::CLicenceFile( string productName, string productKey ) {
|
||||
|
||||
mProductName = productName;
|
||||
mProductKey = productKey;
|
||||
}
|
||||
|
||||
string CLicenceFile::LicencePath() { return ( "Orchard\\Licence\\" + mProductName + ".lic" ); }
|
||||
|
||||
bool CLicenceFile::Check() {
|
||||
|
||||
mData = "";
|
||||
string data = "";
|
||||
if ( !LoadData( data ) ) return false;
|
||||
|
||||
int pos = StringFind( data, "\n" );
|
||||
if ( pos <= 0 ) {
|
||||
Print( "Licence file is not valid" );
|
||||
return ( false );
|
||||
}
|
||||
|
||||
string signature = StringSubstr( data, 0, pos );
|
||||
mData = StringSubstr( data, pos + 1 );
|
||||
Print("mdata ",mData," sign ",signature);
|
||||
string key = KeyGen( mData );
|
||||
if ( key != signature ) {
|
||||
Print( "Licence is invalid" );
|
||||
return ( false );
|
||||
}
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
bool CLicenceFile::LoadData( string &data ) {
|
||||
Print("load 02");
|
||||
string licencePath = LicencePath();
|
||||
|
||||
// Open and read the file each time in case it has been modified between iterations
|
||||
int handle = FileOpen( licencePath, FILE_READ | FILE_BIN | FILE_ANSI );
|
||||
if ( handle == INVALID_HANDLE ) {
|
||||
PrintFormat( "Could not open licence file %s", licencePath );
|
||||
return ( false );
|
||||
}
|
||||
|
||||
int len = ( int )FileSize( handle );
|
||||
data = FileReadString( handle, len );
|
||||
FileClose( handle );
|
||||
Print("load 02 2");
|
||||
return true;
|
||||
}
|
||||
|
||||
string CLicenceFile::KeyGen( string data ) {
|
||||
|
||||
string keyString = data + mProductKey;
|
||||
return Hash( keyString );
|
||||
}
|
||||
|
||||
string CLicenceFile::Hash( string data ) {
|
||||
|
||||
uchar dataChar[];
|
||||
StringToCharArray( data, dataChar, 0, StringLen( data ) );
|
||||
|
||||
uchar cryptChar[];
|
||||
CryptEncode( CRYPT_HASH_SHA256, dataChar, dataChar, cryptChar );
|
||||
|
||||
string result = "";
|
||||
int count = ArraySize( cryptChar );
|
||||
for ( int i = 0; i < count; i++ ) {
|
||||
result += StringFormat( "%.2x", cryptChar[i] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CLicenceFile::FileGen( string data ) {
|
||||
|
||||
string licencePath = LicencePath();
|
||||
|
||||
int handle = FileOpen( licencePath, FILE_WRITE | FILE_BIN | FILE_ANSI );
|
||||
if ( handle == INVALID_HANDLE ) {
|
||||
PrintFormat( "Could not create licence file %s", licencePath );
|
||||
return ( false );
|
||||
}
|
||||
|
||||
string signature = KeyGen( data );
|
||||
string contents = signature + "\n" + data;
|
||||
FileWriteString( handle, contents );
|
||||
FileFlush( handle );
|
||||
FileClose( handle );
|
||||
|
||||
Print( "Licence file '" + licencePath + "' created" );
|
||||
return ( true );
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
LicenceWebCheck.mqh
|
||||
Copyright 2021, Orchard Forex
|
||||
https://www.orchardforex.com
|
||||
*/
|
||||
|
||||
#property copyright "Copyright 2013-2020, Orchard Forex"
|
||||
#property link "https://www.orchardforex.com"
|
||||
#property version "1.00"
|
||||
|
||||
// this is important for MT4
|
||||
#property strict
|
||||
|
||||
#include "LicenceFileCheck.mqh"
|
||||
|
||||
class CLicenceWeb : public CLicenceFile {
|
||||
|
||||
protected:
|
||||
string mAccount;
|
||||
string mRegistration;
|
||||
|
||||
virtual bool LoadData( string &data );
|
||||
virtual string LicencePath();
|
||||
|
||||
public:
|
||||
CLicenceWeb( string productName, string productKey, string registration, long account = -1 );
|
||||
~CLicenceWeb() {}
|
||||
|
||||
void SetRegistration();
|
||||
|
||||
void chekload1(string &dat1) {LoadData(dat1);}
|
||||
};
|
||||
|
||||
CLicenceWeb::CLicenceWeb( string productName, string productKey, string registration, long account = -1 ) : CLicenceFile( productName, productKey ) {
|
||||
|
||||
mRegistration = registration;
|
||||
if ( account < 0 ) {
|
||||
account = AccountInfoInteger( ACCOUNT_LOGIN );
|
||||
}
|
||||
mAccount = string( account );
|
||||
string data2;
|
||||
chekload2(data2);
|
||||
Print("data 2",data2);
|
||||
}
|
||||
|
||||
void CLicenceWeb::SetRegistration() { mRegistration = Hash( mProductName + "_" + mAccount ); }
|
||||
|
||||
string CLicenceWeb::LicencePath() { return ( "Orchard\\Licence\\" + Hash( mProductName + "_" + mAccount ) + ".lic" ); }
|
||||
|
||||
bool CLicenceWeb::LoadData( string &data ) {
|
||||
Print("load 01");
|
||||
string headers = "";
|
||||
char postData[];
|
||||
char resultData[];
|
||||
string resultHeaders;
|
||||
int timeout = 5000; // 1 second, may be too short for a slow connection
|
||||
|
||||
string url = "https://raw.githubusercontent.com";
|
||||
// string api = StringFormat( "https://drive.google.com/uc?id=%s&export=download", mRegistration );
|
||||
// string api = StringFormat( "%s/OrchardForexTutorials/Licence/raw/main/%s.txt", url, mRegistration );
|
||||
string api = StringFormat( "%s/amirghadiri1987/License/refs/heads/main/%s.lic", url, mRegistration );
|
||||
Print("api ",api);
|
||||
|
||||
ResetLastError();
|
||||
int response = WebRequest( "GET", api, headers, timeout, postData, resultData, resultHeaders );
|
||||
int errorCode = GetLastError();
|
||||
|
||||
// Add this code to handle 303 redirect but it creates more problems
|
||||
// if (response==303) {
|
||||
// int locStart = StringFind(resultHeaders, "Location: ", 0)+10;
|
||||
// int locEnd = StringFind(resultHeaders, "\r", locStart);
|
||||
// api = StringSubstr(resultHeaders, locStart, locEnd-locStart);
|
||||
// ResetLastError();
|
||||
// response = WebRequest( "GET", api, headers, timeout, postData, resultData, resultHeaders );
|
||||
// errorCode = GetLastError();
|
||||
//}
|
||||
|
||||
data = CharArrayToString( resultData );
|
||||
|
||||
switch ( response ) {
|
||||
case -1:
|
||||
Print( "Error in WebRequest. Error code =", errorCode );
|
||||
Print( "Add the address " + url + " in the list of allowed URLs" );
|
||||
return false;
|
||||
break;
|
||||
case 200:
|
||||
//--- Success
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
PrintFormat( "Unexpected response code %i", response );
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
WebLicenceTest
|
||||
Copyright 2021, Orchard Forex
|
||||
https://www.orchardforex.com
|
||||
*/
|
||||
|
||||
#include <Orchard/LicenceCheck/LicenceWebCheck.mqh>
|
||||
|
||||
input string InpProductName = "product1"; // Product name used in file name
|
||||
input string InpProductKey = "key1"; // Secret product key
|
||||
input int InpAccount = 123456; // Customer Account number
|
||||
input bool InpTesting = false; // Is this a test
|
||||
|
||||
CLicenceWeb *licenceWeb;
|
||||
|
||||
void OnStart_() {
|
||||
|
||||
licenceWeb = new CLicenceWeb( InpProductName, InpProductKey, "", InpAccount );
|
||||
licenceWeb.SetRegistration();
|
||||
if ( !InpTesting ) {
|
||||
Make();
|
||||
}
|
||||
else {
|
||||
Test();
|
||||
}
|
||||
string data1;
|
||||
licenceWeb.chekload1(data1);
|
||||
|
||||
Print("data1 ",data1);
|
||||
delete licenceWeb;
|
||||
}
|
||||
|
||||
void Make() {
|
||||
|
||||
// Just making up some data here
|
||||
// You could use anything that works for you
|
||||
// Account number, expiry time, grace expiry time
|
||||
string data = licenceWeb.Hash( string( InpAccount ) ) + "\n" + licenceWeb.Hash( InpProductName ) + "\n" + TimeToString( TimeCurrent() + ( 86400 * 30 ) ) + "\n" +
|
||||
TimeToString( TimeCurrent() + ( 86400 * 33 ) );
|
||||
|
||||
// Not necessary to do this, just for demonstration
|
||||
string signature = licenceWeb.KeyGen( data );
|
||||
Print( "The signature is " + signature );
|
||||
|
||||
// Create the file to ship to the customer
|
||||
if ( !licenceWeb.FileGen( data ) ) {
|
||||
Print( "Failed to create licence file" );
|
||||
return;
|
||||
}
|
||||
|
||||
Print( "Created licence file" );
|
||||
}
|
||||
|
||||
void Test() {
|
||||
|
||||
Print( "Now testing licence" );
|
||||
if ( !licenceWeb.Check() ) {
|
||||
Print( "Oops, problem with the licence" );
|
||||
return;
|
||||
}
|
||||
|
||||
Print( "Valid Licence" );
|
||||
string parts[];
|
||||
string licenceData = licenceWeb.GetData();
|
||||
StringSplit( licenceData, '\n', parts );
|
||||
|
||||
PrintFormat( "Account=%s, %s", parts[0], ( parts[0] == licenceWeb.Hash( string( InpAccount ) ) ) ? "correct" : "fail" );
|
||||
|
||||
PrintFormat( "Product=%s, %s", parts[1], ( parts[1] == licenceWeb.Hash( InpProductName ) ) ? "correct" : "fail" );
|
||||
|
||||
PrintFormat( "Expires at %s", parts[2] );
|
||||
PrintFormat( "Grace expires at %s", parts[3] );
|
||||
}
|
||||
|
||||
// bnH1yjYYpwp+dBDfzfvgUzmOGVhtv6hTHeYX7MwVhcQ=.lic
|
||||
// bnH1yjYYpwp+dBDfzfvgUzmOGVhtv6hTHeYX7MwVhcQ=
|
||||
Reference in New Issue
Block a user