之前一直有童鞋抱怨说由于忘记为WHMCS续费,导致后台因欠费被禁止登录的问题。
笔者写了一个小工具,用于检查WHMCS授权合法性及最新版本。该工具可与WHMCS同时工作,自动从数据库中读取版本和授权信息,无需人工干预。
部署说明
1. 将LicenseCheck.php保存在WHMCS的根目录下,class.smtp.custom.php保存在/includes/classes下;
2. 根据实际情况修改LicenseCheck.php的高亮代码行;
3. 将LicenseCheck.php添加为计划任务定时执行。
4. 如需禁用该工具,可以在WHMCS的根目录下/configuration.php中增加(设置为true则启用):
$license_check = false;
核心代码
LicenseCheck.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
<?php debug('License & Updates Checker Initialized.'); require 'init.php'; require 'configuration.php'; if(isset($license_check) && !$license_check){debug('License & Updates Checker is Disabled.');exit;}else RemoteCheck(); function getHosts() { $hosts = gethostbynamel('licensing28.whmcs.com'); return $hosts; } function getLicenseKey() { global $whmcs; return $whmcs->get_license_key(); } function getHostIP() { return (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : (isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : '')); } function getHostDomain() { return $_SERVER['SERVER_NAME']; } function getHostDir() { return ROOTDIR; } function remoteCheck() { $postfields = array(); $postfields['licensekey'] = getLicenseKey(); $postfields['domain'] = getHostDomain(); $postfields['ip'] = getHostIP(); $postfields['dir'] = getHostDir(); $postfields['check_token'] = sha1(time() . getLicenseKey() . mt_rand(1000000000, 9999999999)); debug('Performing Remote Check: ' . print_r($postfields, true)); $data = callHome($postfields); $results = $data; $posthash = $results['hash']; unset($results['hash']); } function buildQuery($postfields) { $query_string = ''; foreach ($postfields as $k => $v) { $query_string .= '' . $k . '=' . urlencode($v) . '&'; } return $query_string; } function callHome($postfields) { $query_string = buildQuery($postfields); $res = callHomeLoop($query_string, 5); return $res; } function callHomeLoop($query_string, $timeout = 5) { $hostips = getHosts(); foreach ($hostips as $hostip) { $responsecode = makeCall($hostip, $query_string, $timeout); if ($responsecode == 200) { break; } } } function makeCall($licsrv, $query_string, $timeout = 5) { global $whmcs,$db_host,$db_username,$db_password,$db_name; $dbhost=$db_host; $dbuser=$db_username; $dbpass=$db_password; $dbname=$db_name; $curver=$whmcs->get_config('Version'); $postinfo = array( CURLOPT_POST => 1, CURLOPT_HEADER => 0, CURLOPT_URL => "https://$licsrv/license/verify52.php", CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 5, CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_POSTFIELDS => $query_string); $ch = curl_init(); curl_setopt_array($ch, ($postinfo)); if(!$result = curl_exec($ch))trigger_error(curl_error($ch)); $responsecode=curl_getinfo($ch, CURLINFO_HTTP_CODE); debug('Response Code: HTTP '.$responsecode); curl_close($ch); debug('Curl Returned: '.$result); $result = strrev($result); $result = base64_decode($result); $results = unserialize($result); $posthash = $results['hash']; unset($results['hash']); debug('License Status: '.$results['status']); if($results['status']<>'Active'){LicenseInvaild($results['status']);return $responsecode;}; debug('Latest Version: '.$results['latestversion']); if($results['latestversion']>$curver)NewVersion($curver,$results['latestversion']); debug('License & Updates Checker Exited.'); return $responsecode; } function LicenseInvaild($licstatus) { $subject = "WHMCS License Error Alert"; $body = "We have detected that your WHMCS License is invaild.<br />License Key: <b>".getLicenseKey()."</b><br />License Status: <b>$licstatus</b><br /><br />Please contact WHMCS as soon as possible to avoid service suspension."; smtpmail($subject,$body); debug('License Invaild Alert Email Sent.'); } function NewVersion($curver,$latestver) { $subject = "WHMCS New Version Notification"; $body = "We have released a new version of WHMCS.<br />Latest Version: <b>$latestver</b><br />Current Version: <b>$curver</b><br /><br />Please upgrade your WHMCS to latest version as soon as possible."; smtpmail($subject,$body); debug('New Version Notification Email Sent.'); } function smtpmail($subject,$body) { require("includes/classes/class.smtp.custom.php"); $smtpserver = "SMTP SERVER"; $smtpserverport = 25; $smtpusermail = "SENDER EMAIL"; $smtpemailto = "RECEIVER EMAIL"; $smtpuser = "SENDER USERNAME"; $smtppass = "SENDER PASSWORD"; $mailsubject = $subject; $mailbody = $body; $mailtype = "HTML"; $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass); // 3rd Parameter: Enable/Disable SMTP Authorization $smtp->debug = false; // Display/Hide Debug Information WARNING: SET TO FALSE IN LIVE USE $smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype); } function debug($msg) { echo "[".date("Y-m-d H:i:s")."] ".$msg."<br />"; // WARNING: COMMENT THIS LINE IN LIVE USE } ?> |
class.smtp.custom.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
<?php error_reporting(0); class smtp { /* Public Variables */ var $smtp_port; var $time_out; var $host_name; var $log_file; var $relay_host; var $debug; var $auth; var $user; var $pass; /* Private Variables */ var $sock; /* Constractor */ function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass) { $this->debug = FALSE; $this->smtp_port = $smtp_port; $this->relay_host = $relay_host; $this->time_out = 30; //is used in fsockopen() $this->auth = $auth;//auth $this->user = $user; $this->pass = $pass; $this->host_name = "localhost"; //is used in HELO command $this->log_file = ""; $this->sock = FALSE; } /* Main Function */ function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "") { $mail_from = $this->get_address($this->strip_comment($from)); $body = ereg_replace("(^|(\r\n))(\.)", "\1.\3", $body); $header .= "MIME-Version:1.0\r\n"; if($mailtype=="HTML") { $header .= "Content-Type:text/html\r\n"; } $header .= "To: ".$to."\r\n"; if ($cc != "") { $header .= "Cc: ".$cc."\r\n"; } $header .= "From: $from<".$from.">\r\n"; $header .= "Subject: ".$subject."\r\n"; $header .= $additional_headers; $header .= "Date: ".date("r")."\r\n"; $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n"; list($msec, $sec) = explode(" ", microtime()); $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n"; $TO = explode(",", $this->strip_comment($to)); if ($cc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($cc))); } if ($bcc != "") { $TO = array_merge($TO, explode(",", $this->strip_comment($bcc))); } $sent = TRUE; foreach ($TO as $rcpt_to) { $rcpt_to = $this->get_address($rcpt_to); if (!$this->smtp_sockopen($rcpt_to)) { $this->log_write("Error: Cannot send email to ".$rcpt_to."\n"); $sent = FALSE; continue; } if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) { $this->log_write("E-mail has been sent to <".$rcpt_to.">\n"); } else { $this->log_write("Error: Cannot send email to <".$rcpt_to.">\n"); $sent = FALSE; } fclose($this->sock); $this->log_write("Disconnected from remote host\n"); } return $sent; } /* Private Functions */ function smtp_send($helo, $from, $to, $header, $body = "") { if (!$this->smtp_putcmd("HELO", $helo)) { return $this->smtp_error("sending HELO command"); } #auth if($this->auth) { if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) { return $this->smtp_error("sending HELO command"); } if (!$this->smtp_putcmd("", base64_encode($this->pass))) { return $this->smtp_error("sending HELO command"); } } if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">")) { return $this->smtp_error("sending MAIL FROM command"); } if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">")) { return $this->smtp_error("sending RCPT TO command"); } if (!$this->smtp_putcmd("DATA")) { return $this->smtp_error("sending DATA command"); } if (!$this->smtp_message($header, $body)) { return $this->smtp_error("sending message"); } if (!$this->smtp_eom()) { return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]"); } if (!$this->smtp_putcmd("QUIT")) { return $this->smtp_error("sending QUIT command"); } return TRUE; } function smtp_sockopen($address) { if ($this->relay_host == "") { return $this->smtp_sockopen_mx($address); } else { return $this->smtp_sockopen_relay(); } } function smtp_sockopen_relay() { $this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); return FALSE; } $this->log_write("Connected to relay host ".$this->relay_host."\n"); return TRUE;; } function smtp_sockopen_mx($address) { $domain = ereg_replace("^.+@([^@]+)$", "\1", $address); if (!@getmxrr($domain, $MXHOSTS)) { $this->log_write("Error: Cannot resolve MX \"".$domain."\"\n"); return FALSE; } foreach ($MXHOSTS as $host) { $this->log_write("Trying to ".$host.":".$this->smtp_port."\n"); $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out); if (!($this->sock && $this->smtp_ok())) { $this->log_write("Warning: Cannot connect to mx host ".$host."\n"); $this->log_write("Error: ".$errstr." (".$errno.")\n"); continue; } $this->log_write("Connected to mx host ".$host."\n"); return TRUE; } $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n"); return FALSE; } function smtp_message($header, $body) { fputs($this->sock, $header."\r\n".$body); $this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> ")); return TRUE; } function smtp_eom() { fputs($this->sock, "\r\n.\r\n"); $this->smtp_debug(". [EOM]\n"); return $this->smtp_ok(); } function smtp_ok() { $response = str_replace("\r\n", "", fgets($this->sock, 512)); $this->smtp_debug($response."\n"); if (!ereg("^[23]", $response)) { fputs($this->sock, "QUIT\r\n"); fgets($this->sock, 512); $this->log_write("Error: Remote host returned \"".$response."\"\n"); return FALSE; } return TRUE; } function smtp_putcmd($cmd, $arg = "") { if ($arg != "") { if($cmd=="") { $cmd = $arg; } else { $cmd = $cmd." ".$arg; } } fputs($this->sock, $cmd."\r\n"); $this->smtp_debug("> ".$cmd."\n"); return $this->smtp_ok(); } function smtp_error($string) { $this->log_write("Error: Error occurred while ".$string.".\n"); return FALSE; } function log_write($message) { $this->smtp_debug($message); if ($this->log_file == "") { return TRUE; } $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message; if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) { $this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n"); return FALSE;; } flock($fp, LOCK_EX); fputs($fp, $message); fclose($fp); return TRUE; } function strip_comment($address) { $comment = "\([^()]*\)"; while (ereg($comment, $address)) { $address = ereg_replace($comment, "", $address); } return $address; } function get_address($address) { $address = ereg_replace("([ \t\r\n])+", "", $address); $address = ereg_replace("^.*<(.+)>.*$", "\1", $address); return $address; } function smtp_debug($message) { if ($this->debug) { echo $message; } } } ?> |
PS:弱弱地说一句,LicenseCheck.php可有其他用途,请读者自己猜想
更新日志
2013/8/28:① 增加了对多个授权验证服务器的循环检查,提高验证成功率。
② 增加了检查工具整体开关。
2013/8/27:初始版本发布。
本文为转载,转载地址:http://go.green-vine.net/p5vvw
转载请注明:网页阁吧 » WHMCS授权及更新检查工具