|
- <?php
- require "vendor/autoload.php";
- require "config.php";
-
-
- class LicenseRegistration {
- private $db = null;
- private $m_request_body = "";
- private $m_input = FALSE;
-
- function __construct()
- {
- // Takes raw data from the request
- $this->m_request_body = file_get_contents('php://input');
- $this->m_input = json_decode(($this->m_request_body));
- $this->db = new MeekroDB(DB_HOST, DB_USER, DB_PASS,DB_NAME); // from config file
- //enable exception
- $this->db->error_handler = false;
- $this->db->nonsql_error_handler = false;
- $this->db->throw_exception_on_error = true;
- $this->db->throw_exception_on_nonsql_error = true;
-
- }
-
-
- private function is_valid_input()
- {
- //if it's not a valid json
- if ( $this->m_input != FALSE &&
- property_exists($this->m_input, "license") &&
- property_exists($this->m_input, "mid")
- ){
-
- if ( strlen($this->m_input->license) >= 10 &&
- strlen($this->m_input->mid) >=10
- ){
- return true;
- }
-
- }
- $this->record_possible_hack();
- return false;
- }
-
- private function is_legit_code()
- {
- $code = $this->m_input->license;
- $f = $this->db->query("SELECT * FROM volume WHERE code='$code'");
- return count($f) == 1 ;
- }
-
- //record possible hack input
- //save ip, date, request header, and invalid inputs
- private function record_possible_hack()
- {
- $dump = new DumpHTTPRequestToString();
- $req = $dump->execute();
- $err = $this->db->insert("hack", array(
- "ip" => $this->get_client_ip(),
- "input" => $this->m_request_body,
- "request" => $req
- ));
- }
-
- private function fresh_registration()
- {
- $config = $this->get_license_config();
- //inser it into database
- $license = [
- 'code' => $this->m_input->license,
- 'mid' => $this->m_input->mid,
- 'seat' => 1,
- 'quota' => $this->get_license_quota() ,
- 'config' => intVal($config["id"]),
- 'enabled' => 1,
- 'ip' => $this->get_client_ip()
- ];
-
- try {
- $this->db->insert("register", $license);
- $this->send_config($config, $license);
- }catch (MeekroDBException $e){
- $this->send_error("Failed to add registration, please try again later" );
- }
- }
-
- private function get_exact_match()
- {
- $code = $this->m_input->license;
- $mid = $this->m_input->mid;
- $match = $this->db->query("SELECT * FROM register WHERE code='$code' AND mid='$mid';");
- if (count($match) !=1 ){
- return FALSE;
- }else{
- return $match[0];
- }
- }
-
- private function get_license_by_code()
- {
- $code = $this->m_input->license;
- $matches = $this->db->query("SELECT * FROM register WHERE code='$code';");
- if (count($matches) < 1 ){
- return FALSE;
- }else{
- return $matches;
- }
- }
-
- private function quota_available($matches)
- {
- return count($matches) < $this->get_license_quota();
-
- }
-
- private function allocate_seat($matches){
- $seat = $this->find_empty_seat($matches);
- $config = $this->get_license_config();
-
- $license = array(
- 'code' => $this->m_input->license,
- 'mid' => $this->m_input->mid,
- 'seat' => $seat,
- 'quota' => $this->get_license_quota() ,
- 'config' => intVal($config["id"]),
- 'enabled' => 1,
- 'ip' => $this->get_client_ip()
- );
- try {
- $this->db->insert("register",$license);
- $this->send_config($config, $license);
- }catch (MeekroDBException $e){
- $this->send_error("Allocate Seats $seat failed");
- }
-
-
- }
-
- private function find_empty_seat($matches)
- {
- for ($i=1; $i <= $this->get_license_quota(); $i++) {
- if ( $this->seats_occupied($matches, $i) )
- continue;
- return $i;
- }
- }
-
- private function seats_occupied($matches, $seat)
- {
- for ($i=0; $i< count($matches); $i++){
- if ( $matches[$i]["seat"] == $seat )
- return true;
- }
- return false;
- }
-
- //main routine
- public function start_registration()
- {
- if (! $this->is_valid_input() ){
- $this->send_error("Sorry, your input is invalid");
- return; //stop everything
- }
-
- if (! $this->is_legit_code()) {
- $this->send_error("Sorry, Your license is not valid");
- return;
- }
-
- //check mid see if a matched license code and mid already exist
- $license = $this->get_exact_match();
- if ( $license != FALSE ){ //we found the match both license-code and machine-id
- //get existing config
- if ( $license['enabled'] == 1 ) {
- $existing_config = $this->get_config_by_id($license["config"]);
- $this->send_config($existing_config, $license);
- }else{
- $this->send_error("Sorry, Your license is disabled");
- }
- }else{
- $licenses = $this->get_license_by_code();
-
- if ( $licenses == FALSE ) {//not found
- $this->fresh_registration();
- }else{//we found, existing records
- if ( $this->quota_available($licenses) ){
- $this->allocate_seat($licenses);
- }else{
- $this->send_error("Sorry, Your license has been fully allocated");
- }
- }
- }
- }
-
- private function get_config_by_id($id)
- {
- $f= $this->db->query("SELECT * FROM servers WHERE id=$id");
- return $f[0];
- }
-
- private function send_config($config, $license)
- {
-
- $msg = "" ;
- if ($license["quota"] >1){
- $msg = "Seat " . $license["seat"] . "/" . $license["quota"] . " has been allocated to you";
-
- }else{
- $msg = "Single user license registered sucessfully";
- }
-
- $result= array(
- "success" => true,
- "type" => $config["type"],
- "host" => $config["host"],
- "port" => $config["port"],
- "username" => $config["user"],
- "password" => $config["pass"],
- "license" => $license["code"],
- "mid" => $license["mid"],
- "proxyDNS" => true,
- "enable" => true,
- "errMsg" => $msg,
- "link" => "https://hk-01.biukop.com/",
- "linkText" => "Check My IP",
- );
- $myJSON = json_encode($result);
- echo $myJSON;
- }
-
- private function send_error($msg){
- echo $msg;
- die();
- }
-
- private function decode_pass($encrypt)
- {
- $buf = base64_decode($encrypt);
- if ( substr($buf, -3, 2) != "#!" )
- return "invalid-encrypt";
-
- $magic_digit = intVal(substr($buf, 2 , 1));
- $pass = substr($buf,5, -$magic_digit);
- return $pass;
- }
-
- private function encode_pass($pass) {
- // prefix: "xxyxx"; Y is digit
- $magic_digit = $this->rand_digit();
- $prefix = $this->build_prefix($magic_digit);
- $suffix = $this->build_suffix($magic_digit);
- //surffix yyyyy#!xx , max 9
- return base64_encode($prefix . $pass . $suffix);
- }
-
- private function rand_char() {
- $pool="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+:{}|<>?[]\;,./";
- $idx = rand(0, strlen($pool) -1 );
- return substr($pool, $idx, 1);
- }
-
- private function rand_digit() {
- return rand(3,9);
- }
-
- private function build_prefix($magic_digit)
- {
- return $this->rand_char() . $this->rand_char() .
- "$magic_digit" .
- $this->rand_char() . $this->rand_char();
- }
-
- private function build_suffix($magic_digit)
- { //$magic_digit >=3
- $suffix = "";
- for ($i=1; $i<= $magic_digit-3; $i++) {
- $suffix .= $this->rand_char();
- }
- $suffix .= "#!";
- $suffix .= $this->rand_char();
- return $suffix;
- }
-
- private function get_client_ip ()
- {
- //whether ip is from share internet
- if (!empty($_SERVER['HTTP_CLIENT_IP']))
- {
- $ip_address = $_SERVER['HTTP_CLIENT_IP'];
- }
- //whether ip is from proxy
- elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
- {
- $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
- }
- //whether ip is from remote address
- else
- {
- $ip_address = $_SERVER['REMOTE_ADDR'];
- }
- return $ip_address;
- }
-
- private function get_license_quota()
- {
- $code = $this->m_input->license;
- $f = $this->db->query("SELECT * FROM volume WHERE code='$code'");
- return intVal($f[0]["max"]);
- }
-
- private function get_license_config()
- {
- $code = $this->m_input->license;
- $f = $this->db->query("SELECT * FROM servers WHERE code='$code'");
- return $f[0];
- }
-
- public function test_password() {
- $encrypt = $this->encode_pass("superforex");
- $pass1 = $this->decode_pass($encrypt);
- $pass = $this->decode_pass("Y2Q1ZDFzdXBlcmZvcmV4MTIjITU=");
- if ($pass != $pass1){
- echo "wrong";
- }
- }
-
- public function test_license_quota() {
- $this->m_input = new stdClass();
- $this->m_input->license = "VOL-XDTG-ADQE-DQERG-QERFDA";
- $six = $this->get_license_quota();
- if ($six != 6)
- echo "wrong: license quota";
- }
-
- public function test_get_config() {
- $this->m_input = new stdClass();
- $this->m_input->license = "VOL-XDTG-ADQE-DQERG-QERFDA";
- $config = $this->get_license_config();
- }
-
- public function test_fresh_registration() {
- $this->m_input = new stdClass();
- $this->m_input->license = "VOL-XDTG-ADQE-DQERG-QERFDA";
- $this->m_input->mid = "AFDAFDSAFDSAFSDAFSAFSDA";
- $this->fresh_registration();
-
- }
-
- public function test_licenses() {
- $this->m_input = new stdClass();
- $this->m_input->license = "VOL-XDTG-ADQE-DQERG-QERFDA";
- $this->m_input->mid = "2-AFDAFDSAFDSAFSDAFSAFSDA";
- $this->start_registration();
- }
-
- public function test() {
- $this->m_input = new stdClass();
- $this->m_input->license = "VOL";
- $this->m_input->mid = "2-AFD";
- $this->start_registration();
- }
-
- }
-
- class DumpHTTPRequestToString {
- public function execute() {
- $data = sprintf(
- "%s %s %s %s\n\nHTTP headers:\n",
- $_SERVER['REQUEST_METHOD'],
- $_SERVER['REQUEST_URI'],
- $_SERVER['SERVER_PROTOCOL'],
- $_SERVER['REMOTE_ADDR']
- );
- foreach ($this->getHeaderList() as $name => $value) {
- $data .= $name . ': ' . $value . "\n";
- }
- $data .= "\nRequest body:\n" . file_get_contents('php://input');
- return $data;
- }
- private function getHeaderList() {
- $headerList = [];
- foreach ($_SERVER as $name => $value) {
- if (preg_match('/^HTTP_/',$name)) {
- // convert HTTP_HEADER_NAME to Header-Name
- $name = strtr(substr($name,5),'_',' ');
- $name = ucwords(strtolower($name));
- $name = strtr($name,' ','-');
- // add to list
- $headerList[$name] = $value;
- }
- }
- return $headerList;
- }
- }
-
- $bb = new LicenseRegistration();
- $bb->start_registration();
- //$bb->test();
-
- ?>
|