<?php

class trustotechLicenseChecker {

    private static $computer_id = null;

    public function __construct() {
        $today = date("j-n-Y");
        if (session_status() != PHP_SESSION_ACTIVE)
            session_start();
        if (isset(smc_session()['currentLastCheckDay']) && smc_session()['currentLastCheckDay'] == $today)
            return;
        if (!isset(smc_session()['currentComputerID']))
            smc_session()['currentComputerID'] = self::getComputerID();
        $lic = null;
        if (!$this->readLicense($lic) || smc_session()['currentComputerID'] != $lic['cid'])
            $this->exitApp();
        $lastCheck = date("j-n-Y", strtotime($lic['lastCheck']));
        $expiry = date("j-n-Y", strtotime($lic['expiry']));
        if ((strtotime($expiry) - strtotime($lastCheck) < 0) || ((strtotime($today) - strtotime($lastCheck)) < 0))
            $this->exitApp();
        $lic['lastCheck'] = $today;
        //we put this condition so if just one user update last check, just update it one time only
        if ($today != $lastCheck) {
            @unlink(dirname(__FILE__) . '/license.txt');
            file_put_contents(dirname(__FILE__) . '/license.txt', self::encrypt(json_encode($lic)));
        }
        smc_session()['currentLastCheckDay'] = $lic['lastCheck'];
    }

    public static function getComputerID() {
        if (is_null(self::$computer_id)) {
            self::$computer_id = '';
            //
            $is_win = $is_mac = $is_linux = false;
            if (strpos(strtolower(php_uname('s')), 'darwin') !== false)
                $is_mac = true;
            elseif (strpos(strtolower(php_uname('s')), 'linux') !== false)
                $is_linux = true;
            else//if (substr(strtolower(php_uname('s')), 0, 3) == 'win')
                $is_win = true;
            /**
             * for windows
             */
            if ($is_win) {
                $ret1 = array();
                exec('wmic baseboard get SerialNumber', $ret1);
                if (isset($ret1[1]) && strlen($ret1[1]) > 4)
                    self::$computer_id .= $ret1[1];
                //
                $ret2 = array();
//                exec('wmic DISKDRIVE get SerialNumber', $ret2);   //or 'wmic path win32_physicalmedia get SerialNumber'
//                if (isset($ret2[1]) && strlen($ret2[1]) > 4)
//                    self::$computer_id .= $ret2[1];
                //below we exclude the removable disk so if insert usb flash memory ignore it just get the first fixed disk
                exec('wmic DISKDRIVE  where "not MediaType like \'%removable%\'" get MediaType,SerialNumber /Format:csv', $ret2);
                if (isset($ret2[2])) {
                    $flds = explode(',', strtolower($ret2[1]));
                    $vals = empty($ret2[2]) ? array() : explode(',', strtolower($ret2[2]));
                    $col = -1;
                    foreach ($flds as $col => $fld)
                        if (trim($fld) == 'serialnumber')
                            break;
                    $serial_val = empty($vals[$col]) ? '' : trim($vals[$col]);
                    if ($col >= 0 && !empty($serial_val))
                        self::$computer_id .= $serial_val;
                }
                //
                if (empty(self::$computer_id)) {
                    //we can check: but must check that it is not changed 'wmic cpu get ProcessorId'
                    //or 'wmic bios get SerialNumber'
                    $ret3 = array();
                    exec('wmic csproduct get UUID', $ret3); //or 'wmic path win32_computersystemproduct get UUID'
                    if (isset($ret3[1]) && strlen($ret3[1]) > 4 && $ret3[1] != 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF')
                        self::$computer_id .= $ret3[1];
                }
            }
            /**
             * for linux
             */
            if ($is_linux) {
                $ret1 = array();
                exec("lsblk -o MODEL -d  /dev/sda", $ret1);
                if (isset($ret1[1]) && strlen($ret1[1]) > 4)
                    self::$computer_id .= $ret1[1];
                //
                $ret2 = array();
                exec("lsblk --nodeps -no serial /dev/sda", $ret2);
                if (isset($ret2[0]) && strlen($ret2[0]) > 4)
                    self::$computer_id .= $ret2[0];
            }
            /**
             * for mac
             */
            if ($is_mac) {
                $ret1 = array();
                //"system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'"  |   "ioreg -rd1 -c IOPlatformExpertDevice"
                exec("system_profiler SPHardwareDataType | awk '/UUID/ {print $3}'", $ret1);
                if (isset($ret1[0]) && strlen($ret1[0]) > 4)
                    self::$computer_id .= $ret1[0];
            }
            //
            if (!empty(self::$computer_id))
                self::$computer_id = sha1(md5('T5m6' . strtolower(self::$computer_id) . 'R@nd0m'));
        }
        return self::$computer_id;
    }

    private function readLicense(&$lic) {
        if (file_exists(dirname(__FILE__) . '/license.txt')) {
            $content = json_decode(self::decrypt(file_get_contents(dirname(__FILE__) . '/license.txt')), true);
            if (isset($content['cid'])) {
                $lic = $content;
                return true;
            }
        }
        return false;
    }

    private function exitApp() {
        ob_clean();
        $computer_id = self::getComputerID();
        echo '<div style="background-color: #f2dede;border: 1px solid #a94442;color: #a94442;padding: 15px;font-family: Arial;font-size: 14px;text-align: center;">',
        'You are not authorized to use this product. <strong>(code 51)(' . (empty($computer_id) ? 'Unable to Generate Computer ID!' : $computer_id) . ')</strong>',
        '</div>';
        die;
    }

    public static function encrypt($string) {
        $encrypt_method = 'AES-256-CBC';
        $encrypt_password = 'Sm@rtC1icqT6chn0lo9y'; //must be the same in encrypt/decrypt
        //here $iv must be generated using [openssl_random_pseudo_bytes(openssl_cipher_iv_length($encrypt_method));]
        //and send it then decrypt using it.. and since it return binary we bsae64 encode it and fix it here
        $iv = base64_decode("+Vks1GO3YzbDZgw55hU2YA==");    //openssl_random_pseudo_bytes(openssl_cipher_iv_length($encrypt_method));
        $encrypted_string = openssl_encrypt($string, $encrypt_method, $encrypt_password, 0, $iv);
        //we can't use it directly as it is binary we use base64_encode() or bin2hex() to make it textual representation
        $encrypted_string = base64_encode($encrypted_string);
        return $encrypted_string;
    }

//
    public static function decrypt($string) {
        $encrypt_method = 'AES-256-CBC';
        $encrypt_password = 'Sm@rtC1icqT6chn0lo9y'; //must be the same in encrypt/decrypt
        $iv = base64_decode("+Vks1GO3YzbDZgw55hU2YA==");
        $string = base64_decode($string);
        $decrypted_string = openssl_decrypt($string, $encrypt_method, $encrypt_password, 0, $iv);
        return $decrypted_string;
    }

}

if (basename($_SERVER['SCRIPT_FILENAME']) != 'generateLicense.php')
    new trustotechLicenseChecker();
