一个适用于 WHMCS 6.1/6.2 的开心版授权文件 12月25日
在去年四月份的时候曾发表过《WHMCS 5.2/5.3 授权文件》,今天发一份互联网上流传的 WHMCS 6 授权文件
这个“开心版”的概念相信大家看标题进来的应该都知道,就是你用完就会很开心会嘿嘿嘿的那种东西。这个文件在好久之前我这里就已经有了,昨天有空拿出来尝试了一下、是可以用的。由于是网上流传的一个 php 文件,我也无法确保其安全性。懂 php 的可以自行查看一下是否有威胁,不建议用于商业。下载地址就不贴了,我直接放代码吧,把 includes/classes/WHMCS/License.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 官方包?自己想办法吧~嘿嘿嘿!
小结
最近要抓紧时间转 Typecho 了,这博客内存占用的把虚拟主机搞挂了。
目前有28条回应
Comment
Trackback
Loading ....
- 本篇文章没有Trackback
对啊,升级过一次但是失败了,怎么办呢?
请问一下,我是whmcs5.1.14升级到6的时候,提示我什么数据库upg600.sql已存在是什么鬼
升级过程中失败过一次对吧
@Tomas: 有没有方法帮我解决一下?
现在可以了,小蒋大神帮我看看。小蒋你有QQ吗
并不是啊。。。我是腾讯云的一台机器。环境什么应该没有问题 。。也能打开那个网站,但是就一直跳出登陆,怎么都登录不进去 ymgblog.cc/admin 你帮我看看好吗 谢谢了 账号admin qwe123
这个地址无法访问啊。。。
小蒋大大,为什么我不管装哪个版本的,进入后台后,就一直让登录啊,都输过用户名密码了登录了又跳出登录,无线循环,是为啥啊
你当地网络是内网吧,外网 IP 总是变动所以他会这么提示。
可以在后台关掉 IP 检查,Setup -> General Setting
我发现你用了缓存,这当然不是本人。。。。哈哈~(猜一猜这种写法的有谁?)
看域名 green 我就猜到了 。。是幽森
@tutugreen: www,我好像看到了我自己?(雾。。。
两年没来了 蒋老板发财了啊
看你也发财了啊,卖游戏吗?
@Tomas: 不卖啊 你两年前卖给我的息壤到期了 不知道怎么续费啊
我建议你别续费息壤啦,买新款的促销计划买两年送一年啊。
然后叫技术给你发工单。
@Tomas: 太贵了 我在某宝买的国内小鸡 一个月60软 20M无限流量
20M 带宽绝对是假的了,在国内独享 20M 带宽的 VPS 花 600 都未必买得到。
@Tomas:
价钱是,可否透传河南铁通线路,有人需要
说反了,发工单叫技术 。。。不是叫技术发工单 。。。hhhhh
@Tomas: 买了个你的备份主机 居然是K总的ip 有趣
备份主机就是用的 Kvmla 美国 OpenVZ VPS 呀,
注意啊,我们没对备份主机提供备份的、所以别用来做网站。
等着收DMCA
我不嘿嘿嘿,我要 嘿咻嘿咻 !
嘿嘿嘿,我来发个大概会是出处的地方好了
嘿嘿嘿
嘿嘿嘿
Ray Zone,你好邪恶。老是想着嘿嘿嘿