一个适用于 WHMCS 6.1/6.2 的开心版授权文件

By | 05/27/2016

今天发一份互联网上流传的 WHMCS 6 授权文件

whmcs

这个“开心版”的概念相信大家看标题进来的应该都知道,就是你用完就会很开心会嘿嘿嘿的那种东西。这个文件在好久之前我这里就已经有了,昨天有空拿出来尝 试了一下、是可以用的。由于是网上流传的一个 php 文件,我也无法确保其安全性。懂 php 的可以自行查看一下是否有威胁,不建议用于商业。下载地址就不贴了,我直接放代码吧,把 includes/lasses/HMCS/icense.php 替换为如下代码:

<?php
namespace WHMCS;
class License {
protected $licensekey = ”;
protected $localkey = ”;
protected $keydata = array(  );
protected $salt = ”;
protected $date = ”;
protected $localkeydecoded = ”;
protected $responsedata = ”;
protected $postmd5hash = ”;
protected $localkeydays = ’10’;
protected $allowcheckfaildays = ‘5’;
protected $debuglog = array(  );
protected $version = ‘7a1bbff560de83ab800c4d1d2f215b91006be8e6’;

function __construct() {
$whmcs = Application::getinstance(  );
$this->licensekey = $whmcs->get_license_key(  );
$this->localkey = $whmcs->get_config( ‘License’ );
$this->salt = sha1( ‘WHMCS’ . $whmcs->get_config( ‘Version’ ) . ‘TFB’ . $whmcs->get_hash(  ) );
$this->date = date( ‘Ymd’ );
$this->decodeLocalOnce(  );

if (isset( $_GET[‘forceremote’] )) {
$this->forceRemoteCheck(  );
Terminus::getinstance(  )->doExit(  );
}

}

function setInstance($license) {
$license = self::$instance;
return $license;
}

function destroyInstance() {
self::$instance = null;
}

function getInstance() {
if (is_null(self::$instance))
{
self::setinstance(new License());
}

return self::$instance;
}

function getHosts() {
$hosts = gethostbynamel( ‘licensing28.whmcs.com’ );

if ($hosts === false) {
$hosts = array(  );
}

return $hosts;
}

function getLicenseKey() {
return $this->licensekey;
}

function getHostIP() {
if (isset( $_SERVER[‘SERVER_ADDR’] )) {
$ip = $_SERVER[‘SERVER_ADDR’];
} else {
if (isset( $_SERVER[‘LOCAL_ADDR’] )) {
$ip = $_SERVER[‘LOCAL_ADDR’];
} else {
if (function_exists( ‘gethostname’ )) {
$ip = gethostbyname( gethostname(  ) );
} else {
$ip = ”;
}
}
}

return $ip;
}

function getHostDomain() {
return (isset( $_SERVER[‘SERVER_NAME’] ) ? $_SERVER[‘SERVER_NAME’] : ”);
}

function getHostDir() {
return ROOTDIR;
}

function getSalt() {
return $this->salt;
}

function getDate() {
return $this->date;
}

function checkLocalKeyExpiry() {
$originalcheckdate = $this->getKeyData( ‘checkdate’ );
$localexpirymax = date( ‘Ymd’, mktime( 0, 0, 0, date( ‘m’ ), date( ‘d’ ) – $this->localkeydays, date( ‘Y’ ) ) );

if ($originalcheckdate < $localexpirymax) {
return false;
}

$localmax = date( ‘Ymd’, mktime( 0, 0, 0, date( ‘m’ ), date( ‘d’ ) + 2, date( ‘Y’ ) ) );

if ($localmax < $originalcheckdate) {
return false;
}

return true;
}

function remoteCheck($forceRemote = false) {
try {
$localkeyvalid = $this->decodeLocalOnce(  );
$this->debug( ” . ‘Local Key Valid: ‘ . $localkeyvalid );

if ($localkeyvalid) {
$localkeyvalid = $this->checkLocalKeyExpiry(  );
$this->debug( ” . ‘Local Key Expiry: ‘ . $localkeyvalid );

if ($localkeyvalid) {
$localkeyvalid = $this->validateLocalKey(  );
$this->debug( ” . ‘Local Key Validation: ‘ . $localkeyvalid );
}
}

if ( !$localkeyvalid || $forceRemote ) {
$whmcs                     = Application::getinstance();
$results[“status”]         = “Active”;
$results[“key”]            = $this->licensekey;
$results[“registeredname”] = $whmcs->get_config(“CompanyName”);
$results[“productname”]    = “Owned License No Branding”;
$results[“productid”]      = “5”;
$results[“billingcycle”]   = “One Time”;
$results[“validdomains”]   = $this->getHostDomain();
$results[“validips”]       = $this->getHostIP();
$results[“validdirs”]      = $this->getHostDir();
$results[“checkdate”]      = $this->getDate();
$results[“version”]        = $whmcs->getVersion()->getCanonical();
$results[“regdate”]        = “2014-02-06”;
$results[“nextduedate”]    = “2050-02-06”;
$results[“addons”]         = array(
array(
‘name’ => ‘Branding Removal’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Support and Updates’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Project Management Addon’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Licensing Addon’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Mobile Edition’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘iPhone App’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Android App’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Configurable Package Addon’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
),
array(
‘name’ => ‘Live Chat Monthly No Branding’,
‘nextduedate’ => ‘2050-12-30’,
‘status’ => ‘Active’
)
);
$this->setKeyData($results);
$this->updateLocalKey();
}

$this->debug( ‘Remote Check Done’ );
}
catch (Exception $exception) {
$this->debug( sprintf( ‘License Error: %s’, $exception->getMessage(  ) ) );
return false;
}
return true;
}

function getLocalMaxExpiryDate() {
return date( ‘Ymd’, mktime( 0, 0, 0, date( ‘m’ ), date( ‘d’ ) – ( $this->localkeydays + $this->allowcheckfaildays ), date( ‘Y’ ) ) );
}

function buildQuery($postfields) {
$query_string = ”;
foreach ($postfields as $k => $v) {
$query_string .= $k . ‘=’ . urlencode( $v ) . ‘&’;
}

return $query_string;
}

function callHome($postfields) {
$query_string = $this->buildQuery( $postfields );
$res = $this->callHomeLoop( $query_string, 5 );

if ($res) {
return $res;
}

return $this->callHomeLoop( $query_string, 30 );
}

function callHomeLoop($query_string, $timeout = 5) {
$hostips = $this->getHosts(  );
foreach ($hostips as $hostip) {
$responsecode = $this->makeCall( $hostip, $query_string, $timeout );

if ($responsecode == 200) {
return $this->responsedata;
}
}

return false;
}

function makeCall($ip, $query_string, $timeout = 5) {
$url = ‘https://’ . $ip . ‘/license/verify53.php’;
$this->debug( ” . ‘Request URL ‘ . $url );
$ch = curl_init(  );
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $query_string );
curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
$this->responsedata = curl_exec( $ch );
$responsecode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$this->debug( ” . ‘Response Code: ‘ . $responsecode . ‘ Data: ‘ . $this->responsedata );

if (curl_error( $ch )) {
$this->debug( ‘Curl Error: ‘ . curl_error( $ch ) . ‘ – ‘ . curl_errno( $ch ) );
}

curl_close( $ch );
return $responsecode;
}

function processResponse($data) {
$data = strrev( $data );
$data = base64_decode( $data );
$results = unserialize( $data );
$this->posthash = $results[‘hash’];
unset( $results[‘hash’] );
$results[‘checkdate’] = $this->getDate(  );
return $results;
}

function updateLocalKey()
{
$data_encoded = serialize($this->keydata);
$data_encoded = base64_encode($data_encoded);
$data_encoded = sha1($this->getDate() . $this->getSalt()) . $data_encoded;
$data_encoded = strrev($data_encoded);
$splpt = strlen($data_encoded) / 2;
$data_encoded = substr($data_encoded, $splpt) . substr($data_encoded, 0, $splpt);
$data_encoded = sha1($data_encoded . $this->getSalt()) . $data_encoded . sha1($data_encoded . $this->getSalt() . time());
$data_encoded = base64_encode($data_encoded);
$data_encoded = wordwrap($data_encoded, 80, “\n”, true);
Application::getinstance()->set_config(“License”, $data_encoded);
$this->debug(“Updated Local Key”);
return null;
}

function forceRemoteCheck() {
$this->remoteCheck( true );
}

function setInvalid($reason = ‘Invalid’) {
$this->keydata = array( ‘status’ => $reason );
}

function decodeLocal()
{
$this->debug(“Decoding local key”);
$localkey = $this->localkey;

if (!$localkey)
{
return false;
}

$localkey = str_replace(“\n”, “”, $localkey);
$localkey = base64_decode($localkey);
$localdata = substr($localkey, 40, 0 – 40);
$md5hash = substr($localkey, 0, 40);

if ($md5hash == sha1($localdata . $this->getSalt()))
{
$splpt = strlen($localdata) / 2;
$localdata = substr($localdata, $splpt) . substr($localdata, 0, $splpt);
$localdata = strrev($localdata);
$md5hash = substr($localdata, 0, 40);
$localdata = substr($localdata, 40);
$localdata = base64_decode($localdata);
$localkeyresults = unserialize($localdata);
$originalcheckdate = $localkeyresults[‘checkdate’];

if ($md5hash == sha1($originalcheckdate . $this->getSalt()))
{
if (isset($localkeyresults[‘key’]) && $localkeyresults[‘key’] == Application::getinstance()->get_license_key())
{
$this->debug(“Local Key Decode Successful”);
$this->setKeyData($localkeyresults);
}
else
{
$this->debug(“License Key Invalid”);
}
}
else
{
$this->debug(“Local Key MD5 Hash 2 Invalid”);
}
}
else
{
$this->debug(“Local Key MD5 Hash Invalid”);
}

$this->localkeydecoded = true;
return $this->getKeyData(“status”) == “Active” ? true : false;
}

function decodeLocalOnce() {
if ($this->localkeydecoded) {
return true;
}

return $this->decodeLocal(  );
}

function isRunningInCLI() {
return ( php_sapi_name(  ) == ‘cli’ && empty( $_SERVER[‘REMOTE_ADDR’] ) );
}

function validateLocalKey() {
if ($this->getKeyData( ‘status’ ) != ‘Active’) {
$this->debug( ‘Local Key Status Check Failure’ );
return false;
}

if ($this->isRunningInCLI(  )) {
$this->debug( ‘Running in CLI Mode’ );
} else {
$this->debug( ‘Running in Browser Mode’ );

if ($this->isValidDomain( $this->getHostDomain(  ) )) {
$this->debug( ‘Domain Validated Successfully’ );
} else {
$this->debug( ‘Local Key Domain Check Failure’ );
return false;
}

$ip = $this->getHostIP(  );
$this->debug( ” . ‘Host IP Address: ‘ . $ip );

if (!$ip) {
$this->debug( ‘IP Could Not Be Determined – Skipping Local Validation of IP’ );
} else {
if (!trim( $this->getKeyData( ‘validips’ ) )) {
$this->debug( ‘No Valid IPs returned by license check – Cloud Based License – Skipping Local Validation of IP’ );
} else {
if ($this->isValidIP( $ip )) {
$this->debug( ‘IP Validated Successfully’ );
} else {
$this->debug( ‘Local Key IP Check Failure’ );
return false;
}
}
}
}

if ($this->isValidDir( $this->getHostDir(  ) )) {
$this->debug( ‘Directory Validated Successfully’ );
}
else {
$this->debug( ‘Local Key Directory Check Failure’ );
return false;
}

return true;
}

function isValidDomain($domain) {
$validdomains = $this->getArrayKeyData( ‘validdomains’ );
return in_array( $domain, $validdomains );
}

function isValidIP($ip) {
$validips = $this->getArrayKeyData( ‘validips’ );
return in_array( $ip, $validips );
}

function isValidDir($dir) {
$validdirs = $this->getArrayKeyData( ‘validdirs’ );
return in_array( $dir, $validdirs );
}

function revokeLocal() {
Application::getinstance(  )->set_config( ‘License’, ” );
}

function getKeyData($var) {
return (isset( $this->keydata[$var] ) ? $this->keydata[$var] : ”);
}

function setKeyData($data) {
$this->keydata = $data;
}

function getArrayKeyData($var) {
$listData = array(  );
$rawData = $this->getKeyData( $var );

if (is_string( $rawData )) {
$listData = explode( ‘,’, $rawData );
foreach ($listData as $k => $v) {
if (is_string( $v )) {
$listData[$k] = trim( $v );
continue;
}

throw new Exception( ‘Invalid license data structure’ );
}
} else {
if (!is_null( $rawData )) {
throw new Exception( ‘Invalid license data structure’ );
}
}

return $listData;
}

function getRegisteredName() {
return $this->getKeyData( ‘registeredname’ );
}

function getProductName() {
return $this->getKeyData( ‘productname’ );
}

function getStatus() {
return $this->getKeyData( ‘status’ );
}

function getSupportAccess() {
return $this->getKeyData( ‘supportaccess’ );
}

function getLicensedAddons() {
$licensedAddons = $this->getKeyData( ‘addons’ );

if (!is_array( $licensedAddons )) {
$licensedAddons = array(  );
}

return $licensedAddons;
}

function getActiveAddons() {
$licensedAddons = $this->getLicensedAddons(  );
$activeAddons = array(  );
foreach ($licensedAddons as $addon) {
if ($addon[‘status’] == ‘Active’) {
$activeAddons[] = $addon[‘name’];
continue;
}
}

return $activeAddons;
}

function isActiveAddon($addon) {
return (in_array( $addon, $this->getActiveAddons(  ) ) ? true : false);
}

function getExpiryDate($showday = false) {
$expiry = $this->getKeyData( ‘nextduedate’ );

if (!$expiry) {
$expiry = ‘Never’;
} else {
if ($showday) {
$expiry = date( ‘l, jS F Y’, strtotime( $expiry ) );
} else {
$expiry = date( ‘jS F Y’, strtotime( $expiry ) );
}
}

return $expiry;
}

function getLatestPublicVersion() {
try {
$latestVersion = new Version\SemanticVersion ($this->getKeyData( ‘latestpublicversion’ ));
}
catch (Exception\Version\BadVersionNumber $e) {
$whmcs = Application::getinstance(  );
$latestVersion = $whmcs->getVersion(  );
}
return $latestVersion;
}

function getLatestPreReleaseVersion() {
try {
$latestVersion = new Version\SemanticVersion($this->getKeyData( ‘latestprereleaseversion’ ));
}
catch (Exception\Version\BadVersionNumber $e) {
$whmcs = Application::getinstance(  );
$latestVersion = $whmcs->getVersion(  );
}
return $latestVersion;
}

function getLatestVersion() {
$whmcs = Application::getinstance(  );
$installedVersion = $whmcs->getVersion(  );

if (in_array( $installedVersion->getPreReleaseIdentifier(  ), array( ‘beta’, ‘rc’ ) )) {
$latestVersion = $this->getLatestPreReleaseVersion(  );
} else {
$latestVersion = $this->getLatestPublicVersion(  );
}

return $latestVersion;
}

function isUpdateAvailable() {
$whmcs = Application::getinstance(  );
$installedVersion = $whmcs->getVersion(  );
$latestVersion = $this->getLatestVersion(  );
return Version\SemanticVersion::compare( $latestVersion, $installedVersion, ‘>’ );
}

function getRequiresUpdates() {
return ($this->getKeyData( ‘requiresupdates’ ) ? true : false);
}

function checkOwnedUpdates() {
if (!$this->getRequiresUpdates(  )) {
return true;
}

$whmcs = Application::getinstance(  );
$licensedAddons =  $this->getLicensedAddons(  );
foreach ($licensedAddons as $addon) {
if ( $addon[‘name’] == ‘Support and Updates’ && $addon[‘status’] == ‘Active’ ) {
if (str_replace( ‘-‘, ”, $whmcs->getReleaseDate(  ) ) <= str_replace( ‘-‘, ”, $addon[‘nextduedate’] )) {
return true;
continue;
}

continue;
}
}

return false;
}

function getBrandingRemoval() {
if (in_array( $this->getProductName(  ), array( ‘Owned License No Branding’, ‘Monthly Lease No Branding’ ) )) {
return true;
}

$licensedAddons = $this->getLicensedAddons(  );
foreach ($licensedAddons as $addon) {
if ( $addon[‘name’] == ‘Branding Removal’ && $addon[‘status’] == ‘Active’ ) {
return true;
continue;
}
}

return false;
}

function getVersionHash() {
return $this->version;
}

function debug($msg) {
$this->debuglog[] = $msg;
}

function getDebugLog() {
return $this->debuglog;
}

function isClientLimitsEnabled() {
return (string)$this->getKeyData( ‘ClientLimitsEnabled’ );
}

function getClientLimit() {
$clientLimit = $this->getKeyData( ‘ClientLimit’ );

if ($clientLimit == ”) {
return 0 – 1;
}

if (!is_numeric( $clientLimit )) {
$this->debug( ‘Invalid client limit value in license’ );
return 0;
}

return (int)$clientLimit;
}

function getTextClientLimit($admin = null) {
$clientLimit = $this->getClientLimit(  );
$result = ‘Unlimited’;

if (0 < $clientLimit) {
$result = number_format( $clientLimit, 0, ”, ‘,’ );
} else {
if ($admin && $text = $admin->lang( ‘global’, ‘unlimited’ )) {
$result = $text;
}
}

return $result;
}

function getNumberOfActiveClients() {
return (int)get_query_val( ‘tblclients’, ‘count(id)’, ‘status=\’Active\” );
}

function getTextNumberOfActiveClients($admin = null) {
$clientLimit = $this->getNumberOfActiveClients(  );
$result = ‘None’;

if (0 < $clientLimit) {
$result = number_format( $clientLimit, 0, ”, ‘,’ );
} else {
if ($admin && $text = $admin->lang( ‘global’, ‘none’ )) {
$result = $text;
}
}

return $result;
}

function getClientBoundaryId() {
return (int)get_query_val( ‘tblclients’, ‘id’, ‘status=\’Active\”, ‘id’, ‘ASC’, (int)$this->getClientLimit(  ) . ‘,1’ );
}

function isNearClientLimit() {
$clientLimit = $this->getClientLimit(  );
$numClients = $this->getNumberOfActiveClients(  );

if ($numClients < 1 || $clientLimit < 1) {
return false;
}

$percentageBound = (250 < $clientLimit ? 0.0500000000000000027755576 : 0.100000000000000005551115);
return $clientLimit * ( 1 – $percentageBound ) <= $numClients;
}

function getMemberPublicKey() {
return ‘—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7OMhxWvu3FOqMblJGXjh
vZQLhQa2wRQoetxAM7j/c+SzFVHmLteAZrn06FeoU1RhjQz9TE0kD6BzoBBuE1bm
JkybOuhVJGVlI8QqLnl2F/jDFP3xshm2brRUt9vNBWXhGDRvOLOgmxaFtVjCiNAT
9n4dtG+344xN7w568Rw3hnnGApypGFtypaKHSeNV6waeFgHeePXSPFMUpe9evZJa
pyc9ENEWvi6nK9hWm1uZ+CfoeRjIKqW2QlgazGDqQtQev05LbDihK0Nc8LBqmVQS
NB/N2CueyYKrzVUmNqbrkJaBVm6N3EnSNBOR7WXOPf1VOjGDu79kYrbhT1MUlKpp
LQIDAQAB
—–END PUBLIC KEY—–‘;
}

function encryptMemberData($data = array(  ), &$publicKey = ”) {
if (!$publicKey) {
$publicKey = $this->getMemberPublicKey(  );
}

$publicKey = str_replace( array( “\n”, “\r”, ” ” ), array( ”, ”, ” ), $publicKey );
$cipherText = ”;

if (is_array( $data )) {
try {
$rsa = new Crypt_RSA(  );
$rsa->loadKey( $publicKey );
$rsa->setEncryptionMode( CRYPT_RSA_ENCRYPTION_OAEP );
$cipherText = $rsa->encrypt( json_encode( $data ) );

if (!$cipherText) {
throw new Exception( ‘Could not perform rsa encryption’ );
} else {
$cipherText = base64_encode( $cipherText );
}
}
catch (Exception $e) {
$this->debug( ‘Failed to encrypt member data’ );
}
}

return $cipherText;
}
}

至于 WHMCS 6 官方包?自己想办法吧~嘿嘿嘿!

本文由 [Justin] 原创或整理发布,如需要转载请注明出处!本文链接:https://ijustin.pw/justin/337
如果你觉得本博内容不错,欢迎 [订阅我的博客],以便第一时间了解本博更新内容。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据