Spaces:
Sleeping
Sleeping
| class license_application extends Padl | |
| { | |
| /** | |
| * The number of allowed differences between the $_SERVER vars and the vars | |
| * stored in the key | |
| * | |
| * @var number | |
| */ | |
| public $_ALLOWED_SERVER_DIFS = 0; | |
| /** | |
| * The number of allowed differences between the $ip vars in the key and the ip | |
| * vars collected from the server | |
| * | |
| * @var number | |
| */ | |
| public $_ALLOWED_IP_DIFS = 0; | |
| /** | |
| * the path of the license key file, remember this would be relative to the | |
| * include path of the class file. | |
| */ | |
| public $_LICENSE_PATH; | |
| /** | |
| * Constructor | |
| * | |
| * @access public | |
| * @param $use_mcrypt boolean Determines if mcrypt encryption is used or not (defaults to true, | |
| * however if mcrypt is not available, it is set to false) | |
| * @param $use_time boolean Sets if time binding should be used in the key (defaults to true) | |
| * @param $use_server boolean Sets if server binding should be used in the key (defaults to true) | |
| * @param $allow_local boolean Sets if server binding is in use then localhost servers are valid (defaults to false) | |
| * */ | |
| public function license_application($license_path = 'license.dat', $use_mcrypt = true, $use_time = true, $use_server = true, $allow_local = false, $challenge = false) | |
| { | |
| //Check to see if the class has been secured | |
| if (isset($_SESSION)) { | |
| unset($_SESSION["__sw__"]); | |
| if ($challenge) { | |
| $_SESSION["__sw__"] = true; | |
| } | |
| } | |
| $this->_check_secure(); | |
| $this->_LICENSE_PATH = $license_path; | |
| $this->init($use_mcrypt, $use_time, $use_server, $allow_local); | |
| if ($this->USE_SERVER) { | |
| $this->_MAC = $this->_get_mac_address(); | |
| } | |
| } | |
| /** | |
| * set_server_vars | |
| * | |
| * to protect against spoofing you should copy the $_SERVER vars into a | |
| * seperate array right at the first line of your script so parameters can't | |
| * be changed in unencoded php files. This doesn't have to be set. If it is | |
| * not set then the $_SERVER is copied when _get_server_info (private) function | |
| * is called. | |
| * | |
| * @access public | |
| * @param $array array The copied $_SERVER array | |
| * */ | |
| public function set_server_vars($array) | |
| { | |
| # check to see if the class has been secured | |
| $this->_check_secure(); | |
| $this->_SERVER_VARS = $array; | |
| # some of the ip data is dependant on the $_SERVER vars, so update them | |
| # after the vars have been set | |
| $this->_IPS = $this->_get_ip_address(); | |
| # update the server info | |
| $this->_SERVER_INFO = $this->_get_server_info(); | |
| } | |
| /** | |
| * _get_os_var | |
| * | |
| * gets various vars depending on the os type | |
| * | |
| * @access private | |
| * @return string various values | |
| * */ | |
| public function _get_os_var($var_name, $os) | |
| { | |
| $var_name = strtolower($var_name); | |
| # switch between the os's | |
| switch ($os) { | |
| # not sure if the string is correct for FreeBSD | |
| # not tested | |
| case 'freebsd': | |
| # not sure if the string is correct for NetBSD | |
| # not tested | |
| case 'netbsd': | |
| # not sure if the string is correct for Solaris | |
| # not tested | |
| case 'solaris': | |
| # not sure if the string is correct for SunOS | |
| # not tested | |
| case 'sunos': | |
| # darwin is mac os x | |
| # tested only on the client os | |
| case 'darwin': | |
| # switch the var name | |
| switch ($var_name) { | |
| case 'conf': | |
| $var = '/sbin/ifconfig'; | |
| break; | |
| case 'mac': | |
| $var = 'ether'; | |
| break; | |
| case 'ip': | |
| $var = 'inet '; | |
| break; | |
| } | |
| break; | |
| # linux variation | |
| # tested on server | |
| case 'linux': | |
| # switch the var name | |
| switch ($var_name) { | |
| case 'conf': | |
| $var = '/sbin/ifconfig'; | |
| break; | |
| case 'mac': | |
| $var = 'HWaddr'; | |
| break; | |
| case 'ip': | |
| $var = 'inet addr:'; | |
| break; | |
| } | |
| break; | |
| } | |
| return $var; | |
| } | |
| /** | |
| * _get_config | |
| * | |
| * gets the server config file and returns it. tested on Linux, | |
| * Darwin (Mac OS X), and Win XP. It may work with others as some other | |
| * os's have similar ifconfigs to Darwin but they haven't been tested | |
| * | |
| * @access private | |
| * @return string config file data | |
| * */ | |
| public function _get_config() | |
| { | |
| # check to see if the class has been secured | |
| $this->_check_secure(); | |
| if (ini_get('safe_mode')) { | |
| # returns invalid because server is in safe mode thus not allowing | |
| # sbin reads but will still allow it to open. a bit weird that one. | |
| return 'SAFE_MODE'; | |
| } | |
| # if anyone has any clues for windows environments | |
| # or other server types let me know | |
| $os = strtolower(PHP_OS); | |
| if (substr($os, 0, 3) == 'win') { | |
| # this windows version works on xp running apache | |
| # based server. it has not been tested with anything | |
| # else, however it should work with NT, and 2000 also | |
| # execute the ipconfig | |
| @exec('ipconfig/all', $lines); | |
| # count number of lines, if none returned return MAC_404 | |
| # thanks go to Gert-Rainer Bitterlich <bitterlich -at- ima-dresden -dot- de> | |
| if (count($lines) == 0) { | |
| return 'ERROR_OPEN'; | |
| } | |
| # $path the lines together | |
| $conf = implode($this->_LINEBREAK, $lines); | |
| } else { | |
| # get the conf file name | |
| $os_file = $this->_get_os_var('conf', $os); | |
| # open the ipconfig | |
| $fp = @popen($os_file, "rb"); | |
| # returns invalid, cannot open ifconfig | |
| if (!$fp) { | |
| return 'ERROR_OPEN'; | |
| } | |
| # read the config | |
| $conf = @fread($fp, 4096); | |
| @pclose($fp); | |
| } | |
| return $conf; | |
| } | |
| /** | |
| * _get_ip_address | |
| * | |
| * Used to get the MAC address of the host server. It works with Linux, | |
| * Darwin (Mac OS X), and Win XP. It may work with others as some other | |
| * os's have similar ifconfigs to Darwin but they haven't been tested | |
| * | |
| * @access private | |
| * @return array IP Address(s) if found (Note one machine may have more than one ip) | |
| * @return string ERROR_OPEN means config can't be found and thus not opened | |
| * @return string IP_404 means ip adress doesn't exist in the config file and can't be found in the $_SERVER | |
| * @return string SAFE_MODE means server is in safe mode so config can't be read | |
| * */ | |
| public function _get_ip_address() | |
| { | |
| $ips = array(); | |
| # get the cofig file | |
| $conf = $this->_get_config(); | |
| # if the conf has returned and error return it | |
| if ($conf != 'SAFE_MODE' && $conf != 'ERROR_OPEN') { | |
| # if anyone has any clues for windows environments | |
| # or other server types let me know | |
| $os = strtolower(PHP_OS); | |
| if (substr($os, 0, 3) == 'win') { | |
| # anyone any clues on win ip's | |
| } else { | |
| # explode the conf into seperate lines for searching | |
| $lines = explode($this->_LINEBREAK, $conf); | |
| # get the ip delim | |
| $ip_delim = $this->_get_os_var('ip', $os); | |
| # ip pregmatch | |
| $num = "(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])"; | |
| # seperate the lines | |
| foreach ($lines as $key => $line) { | |
| # check for the ip signature in the line | |
| if (!preg_match("/^$num\\.$num\\.$num\\.$num$/", $line) && strpos($line, $ip_delim)) { | |
| # seperate out the ip | |
| $ip = substr($line, strpos($line, $ip_delim) + strlen($ip_delim)); | |
| $ip = trim(substr($ip, 0, strpos($ip, " "))); | |
| # add the ip to the collection | |
| if (!isset($ips[$ip])) { | |
| $ips[$ip] = $ip; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| # if the conf has returned nothing | |
| # attempt to use the $_SERVER data | |
| if (isset($this->_SERVER_VARS['SERVER_NAME'])) { | |
| $ip = gethostbyname($this->_SERVER_VARS['SERVER_NAME']); | |
| if (!isset($ips[$ip])) { | |
| $ips[$ip] = $ip; | |
| } | |
| } | |
| # count return ips and return if found | |
| if (count($ips) > 0) { | |
| return $ips; | |
| } | |
| if (isset($this->_SERVER_VARS['SERVER_ADDR'])) { | |
| $name = gethostbyaddr($this->_SERVER_VARS['SERVER_ADDR']); | |
| $ip = gethostbyname($name); | |
| if (!isset($ips[$ip])) { | |
| $ips[$ip] = $ip; | |
| } | |
| # if the $_SERVER addr is not the same as the returned ip include it aswell | |
| if ($ip != $this->_SERVER_VARS['SERVER_ADDR']) { | |
| if (!isset($ips[$this->_SERVER_VARS['SERVER_ADDR']])) { | |
| $ips[$this->_SERVER_VARS['SERVER_ADDR']] = $this->_SERVER_VARS['SERVER_ADDR']; | |
| } | |
| } | |
| } | |
| # count return ips and return if found | |
| if (count($ips) > 0) { | |
| return $ips; | |
| } | |
| # failed to find an ip check for conf error or return 404 | |
| if ($conf == 'SAFE_MODE' || $conf == 'ERROR_OPEN') { | |
| return $conf; | |
| } | |
| return 'IP_404'; | |
| } | |
| /** | |
| * _get_mac_address | |
| * | |
| * Used to get the MAC address of the host server. It works with Linux, | |
| * Darwin (Mac OS X), and Win XP. It may work with others as some other | |
| * os's have similar ifconfigs to Darwin but they haven't been tested | |
| * | |
| * @access private | |
| * @return string Mac address if found | |
| * @return string ERROR_OPEN means config can't be found and thus not opened | |
| * @return string MAC_404 means mac adress doesn't exist in the config file | |
| * @return string SAFE_MODE means server is in safe mode so config can't be read | |
| * */ | |
| public function _get_mac_address() | |
| { | |
| # open the config file | |
| $conf = $this->_get_config(); | |
| # if anyone has any clues for windows environments | |
| # or other server types let me know | |
| $os = strtolower(PHP_OS); | |
| if (substr($os, 0, 3) == 'win') { | |
| # explode the conf into lines to search for the mac | |
| $lines = explode($this->_LINEBREAK, $conf); | |
| # seperate the lines for analysis | |
| foreach ($lines as $key => $line) { | |
| # check for the mac signature in the line | |
| # originally the check was checking for the existence of string 'physical address' | |
| # however Gert-Rainer Bitterlich pointed out this was for english language | |
| # based servers only. preg_match updated by Gert-Rainer Bitterlich. Thanks | |
| if (preg_match("/([0-9a-f][0-9a-f][-:]){5}([0-9a-f][0-9a-f])/i", $line)) { | |
| $trimmed_line = trim($line); | |
| # take of the mac addres and return | |
| return trim(substr($trimmed_line, strrpos($trimmed_line, " "))); | |
| } | |
| } | |
| } else { | |
| # get the mac delim | |
| $mac_delim = $this->_get_os_var('mac', $os); | |
| # get the pos of the os_var to look for | |
| $pos = strpos($conf, $mac_delim); | |
| if ($pos) { | |
| # seperate out the mac address | |
| $str1 = trim(substr($conf, ($pos + strlen($mac_delim)))); | |
| return trim(substr($str1, 0, strpos($str1, "\n"))); | |
| } | |
| } | |
| # failed to find the mac address | |
| return 'MAC_404'; | |
| } | |
| /** | |
| * _get_server_info | |
| * | |
| * used to generate the server binds when server binding is needed. | |
| * | |
| * @access private | |
| * @return array server bindings | |
| * @return boolean false means that the number of bindings failed to | |
| * meet the required number | |
| * */ | |
| public function _get_server_info() | |
| { | |
| if (empty($this->_SERVER_VARS)) { | |
| $this->set_server_vars($_SERVER); | |
| } | |
| # get the server specific uris | |
| $a = array(); | |
| if (isset($this->_SERVER_VARS['SERVER_ADDR']) && (!strrpos($this->_SERVER_VARS['SERVER_ADDR'], '127.0.0.1') || $this->ALLOW_LOCAL)) { | |
| $a['SERVER_ADDR'] = $this->_SERVER_VARS['SERVER_ADDR']; | |
| } | |
| # corrected by Gert-Rainer Bitterlich <bitterlich -at- ima-dresden -dot- de>, Thanks | |
| if (isset($this->_SERVER_VARS['HTTP_HOST']) && (!strrpos($this->_SERVER_VARS['HTTP_HOST'], '127.0.0.1') || $this->ALLOW_LOCAL)) { | |
| $a['HTTP_HOST'] = $this->_SERVER_VARS['HTTP_HOST']; | |
| } | |
| if (isset($this->_SERVER_VARS['SERVER_NAME'])) { | |
| $a['SERVER_NAME'] = $this->_SERVER_VARS['SERVER_NAME']; | |
| } | |
| if (isset($this->_SERVER_VARS['PATH_TRANSLATED'])) { | |
| $a['PATH_TRANSLATED'] = substr($this->_SERVER_VARS['PATH_TRANSLATED'], 0, strrpos($this->_SERVER_VARS['PATH_TRANSLATED'], '/')); | |
| } elseif (isset($this->_SERVER_VARS['SCRIPT_FILENAME'])) { | |
| $a['SCRIPT_FILENAME'] = substr($this->_SERVER_VARS['SCRIPT_FILENAME'], 0, strrpos($this->_SERVER_VARS['SCRIPT_FILENAME'], '/')); | |
| } | |
| if (isset($_SERVER['SCRIPT_URI'])) { | |
| $a['SCRIPT_URI'] = substr($this->_SERVER_VARS['SCRIPT_URI'], 0, strrpos($this->_SERVER_VARS['SCRIPT_URI'], '/')); | |
| } | |
| # if the number of different uris is less than the required amount, | |
| # fail the request | |
| if (count($a) < $this->REQUIRED_URIS) { | |
| return 'SERVER_FAILED'; | |
| } | |
| return $a; | |
| } | |
| /** | |
| * validate | |
| * | |
| * validates the server key and returns a data array. | |
| * | |
| * @access public | |
| * @return array Main object in array is 'RESULT', it contains the result | |
| * of the validation. | |
| * OK - key is valid | |
| * CORRUPT - key has been tampered with | |
| * TMINUS - the key is being used before the valid start date | |
| * EXPIRED - the key has expired | |
| * ILLEGAL - the key is not on the same server the license was registered to | |
| * ILLEGAL_LOCAL - the key is not allowed to be installed on a local machine | |
| * INVALID - the the encryption key used to encrypt the key differs or the key is not complete | |
| * EMPTY - the the key is empty | |
| * 404 - the the key is missing | |
| * */ | |
| public function validate($str = false, $dialhome = false, $dialhost = "", $dialpath = "", $dialport = "80") | |
| { | |
| # check to see if the class has been secured | |
| $this->_check_secure(); | |
| # get the dat string | |
| $dat_str = (!$str) ? @file_get_contents($this->_LICENSE_PATH) : $str; | |
| if (strlen($dat_str) > 0) { | |
| # decrypt the data | |
| $DATA = $this->_unwrap_license($dat_str); | |
| if (is_array($DATA)) { | |
| # missing / incorrect id therefore it has been tampered with | |
| /* | |
| *Disable to accept licenses from other workspaces | |
| *if ($DATA['ID'] != G::encryptOld($this->ID1)) { | |
| $DATA['RESULT'] = 'CORRUPT'; | |
| }*/ | |
| if ($this->USE_TIME) { | |
| # the license is being used before it's official start | |
| if ($DATA['DATE']['START'] > time() + $this->START_DIF) { | |
| $DATA['RESULT'] = 'TMINUS'; | |
| } | |
| # the license has expired | |
| if ($DATA['DATE']['END'] - time() < 0 && $DATA['DATE']['SPAN'] != 'NEVER' && $DATA['DATE']['SPAN'] != '~') { | |
| $DATA['RESULT'] = 'EXPIRED'; | |
| } | |
| $DATA['DATE']['HUMAN']['START'] = date($this->DATE_STRING, $DATA['DATE']['START']); | |
| if (($DATA['DATE']['END'] == "") || ($DATA['DATE']['END'] == "NEVER")) { | |
| $DATA['DATE']['HUMAN']['END'] = "PERPETUAL"; | |
| } else { | |
| $DATA['DATE']['HUMAN']['END'] = date($this->DATE_STRING, $DATA['DATE']['END']); | |
| } | |
| } | |
| if ($this->USE_SERVER) { | |
| $mac = $DATA['SERVER']['MAC'] == $this->_MAC; | |
| $path = count(array_diff($this->_SERVER_INFO, $DATA['SERVER']['PATH'])) <= $this->_ALLOWED_SERVER_DIFS; | |
| $domain = $this->_compare_domain_ip($DATA['SERVER']['DOMAIN'], $this->_IPS); | |
| $ip = count(array_diff($this->_IPS, $DATA['SERVER']['IP'])) <= $this->_ALLOWED_IP_DIFS; | |
| # the server details | |
| if (!$mac || !$path || !$domain || !$ip) { | |
| $DATA['RESULT'] = 'ILLEGAL'; | |
| } | |
| # check if local | |
| $local = $this->ALLOW_LOCAL && (in_array('127.0.0.1', $DATA['SERVER']['IP']) || $DATA['PATH']['SERVER_ADDR'] == '127.0.0.1' || $DATA['PATH']['HTTP_HOST'] == '127.0.0.1'); | |
| if (!$local) { | |
| $DATA['RESULT'] = 'ILLEGAL_LOCAL'; | |
| } | |
| } | |
| # passed all current test so license is ok | |
| if (!isset($DATA['RESULT'])) { | |
| # dial to home server if required | |
| if ($dialhome) { | |
| # create the details to send to the home server | |
| $stuff_to_send = array(); | |
| $stuff_to_send['LICENSE_DATA'] = $DATA; | |
| $stuff_to_send['LICENSE_DATA']['KEY'] = G::encryptOld($dat_str); | |
| # dial home | |
| $DATA['RESULT'] = $this->_call_home($stuff_to_send, $dialhost, $dialpath, $dialport); | |
| } else { | |
| # result is ok all test passed, license is legal | |
| $DATA['RESULT'] = 'OK'; | |
| } | |
| } | |
| /* | |
| */ | |
| # data is returned for use | |
| return $DATA; | |
| } else { | |
| # the are two reason that mean a invalid return | |
| # 1 - the other hash key is different | |
| # 2 - the key has been tampered with | |
| return array('RESULT' => 'INVALID'); | |
| } | |
| } | |
| # returns empty because there is nothing in the dat_string | |
| return array('RESULT' => 'EMPTY'); | |
| } | |
| /** | |
| * _call_home | |
| * | |
| * calls the dial home server (your server) andvalidates the clients license | |
| * with the info in the mysql db | |
| * | |
| * @access private | |
| * @param $data array Array that contains the info to be validated | |
| * @param $dialhost string Host name of the server to be contacted | |
| * @param $dialpath string Path of the script for the data to be sent to | |
| * @param $dialport number Port Number to send the data through | |
| * @return string Returns: the encrypted server validation result from the dial home call | |
| * : SOCKET_FAILED => socket failed to connect to the server | |
| * */ | |
| public function _call_home($data, $dialhost, $dialpath, $dialport) | |
| { | |
| print "_call_home($data, $dialhost, $dialpath, $dialport)"; | |
| # post the data home | |
| $data = $this->_post_data($dialhost, $dialpath, $data, $dialport); | |
| return (empty($data['RESULT'])) ? 'SOCKET_FAILED' : $data['RESULT']; | |
| } | |
| } | |