id_install; // Only the GE-close call sends elapsed times; the GE-start call omits // them, and 0 is what routes a request to the start branch below. $ge_seconds = $data->ge_seconds ?? 0; $ge_gametime_seconds = $data->ge_gametime_seconds ?? 0; $harpoon_uuid_session = $data->harpoon_uuid_session; $hc_build = $data->hc_build; $matrix_sn_hash = $data->license->matrix_sn_hash; $hclicense_dt_expire = $data->license->hclicense->dt_expire; $hclicense_licensee = $data->license->hclicense->licensee; $usblicense_desc = $data->license->usblicense->desc; $ipv4 = $_SERVER["REMOTE_ADDR"]; // Add extra fields $id = guidv4(); // ALE 20200109 write to the DB // Create connection $conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // ALE 20201119 look at incoming data and see if this is a GE load or GE close call_user_func if ($ge_seconds > 0) { // ALE 20201119 this is GE closing // ALE 20201119 first look up the id to see if it exists, in which case update $stmt = $conn->prepare("SELECT id, harpoon_uuid_session FROM metrics_raw WHERE harpoon_uuid_session = ?"); $stmt->bind_param('s', $harpoon_uuid_session); $stmt->execute(); $stmt->store_result(); $row_count = $stmt->num_rows; $stmt->close(); if ($row_count > 0) { // ALE 20201119 looks like the GE opening call succeeded, update the row $stmt = $conn->prepare("UPDATE metrics_raw SET ge_seconds = ?, ge_gametime_seconds = ? WHERE harpoon_uuid_session = ?"); if ($stmt == false) { echo "\n". serialize($conn->error_list); } else { $stmt->bind_param('sss', $ge_seconds, $ge_gametime_seconds, $harpoon_uuid_session); } } else { // ALE 20201119 looks like the GE openeing call failed, create new row // Eight columns, eight values: seven bound plus utc_timestamp(). $stmt = $conn->prepare("INSERT INTO metrics_raw (id, id_install, harpoon_uuid_session, ge_seconds, ge_gametime_seconds, ipv4, hc_build, dt_create) VALUES (?, ?, ?, ?, ?, ?, ?, utc_timestamp())"); $stmt->bind_param('sssssss', $id, $id_install, $harpoon_uuid_session, $ge_seconds, $ge_gametime_seconds, $ipv4, $hc_build); // ALE 20201119 we want to record license information too license_info_insert($conn, $id_install, $matrix_sn_hash, $hclicense_dt_expire, $hclicense_licensee, $usblicense_desc); } $stmt->execute(); $stmt->close(); } else { // ALE 20201119 this is GE opening $stmt = $conn->prepare("INSERT INTO metrics_raw (id, id_install, harpoon_uuid_session, ipv4, hc_build, dt_create) VALUES (?, ?, ?, ?, ?, utc_timestamp())"); $stmt->bind_param('sssss', $id, $id_install, $harpoon_uuid_session, $ipv4, $hc_build); $stmt->execute(); $stmt->close(); // ALE 20201119 we want to record license information too license_info_insert($conn, $id_install, $matrix_sn_hash, $hclicense_dt_expire, $hclicense_licensee, $usblicense_desc); } // prepare and bind //$stmt = $conn->prepare("INSERT INTO metrics_raw (id, id_install, harpoon_uuid_session, ge_seconds, ge_gametime_seconds, ipv4, dt_create) VALUES (?, ?, ?, ?, ?, utc_timestamp())"); //$stmt->bind_param('ssssss', $id, $id_install, $harpoon_uuid_session, $ge_seconds, $ge_gametime_seconds, $ipv4); //if (!$stmt->execute()) //{ // echo $mysqli->error; //} //$stmt->close(); $conn->close(); /* { "status": "success", "id": "" } */ // ALE 20200109 send back success send_json(201, array('status' => 'success', 'harpoon_uuid_session' => $harpoon_uuid_session)); //echo "\n" . $id . "\n" . $id_install . "\n" . $ge_seconds . "\n" . $ge_gametime_seconds . "\n" . $ipv4 . "\n" . $dt_create . "\njson=" . // $json . "\ndone."; //var_dump($_SERVER["REMOTE_ADDR"]); } else { /* { "status": "fail", "data": { "format": "failure decoding json" } } { "error": { "code": "500", "message": "Unsupported functionality", } } */ // ALE 20200109 send back failure // The request body is deliberately not echoed back: reflecting // arbitrary input into a response is how the page was exploitable. send_json(500, array('status' => 'fail', 'data' => array('format' => 'failure decoding json'))); //echo '{failure decoding json}'; } } else { /* { "status": "error", "message": "Unsupported functionality" } { "error": { "code": "500", "message": "Unsupported functionality", } } */ // ALE 20200109 send back failure send_json(500, array('status' => 'error', 'message' => 'submitted data does not fit')); //echo '{failure}'; } // Writes a JSON response. The status is set before any output, so it // doesn't rely on output buffering; the JSON_HEX_* flags escape < > & ' " // so a value can never be read as markup even if a client ignores the // content type. function send_json($p_code, $p_payload) { http_response_code($p_code); echo json_encode($p_payload, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); } function license_info_insert($p_conn,$p_id_install, $p_matrix_sn_hash='', $p_hclicense_dt_expire=0, $p_hclicense_licensee='', $p_usblicense_desc='') { $id_license = guidv4(); // ALE 20201119 null our data if ($p_matrix_sn_hash == '') { $p_matrix_sn_hash = NULL; } if ($p_hclicense_dt_expire == 0) { $hclic_dt_expire = NULL; } else { $hclic_dt_expire = gmdate('Y-m-d H:i:s', $p_hclicense_dt_expire); } if ($p_hclicense_licensee == '') { $p_hclicense_licensee = NULL; } if ($p_usblicense_desc == '') { $p_usblicense_desc = NULL; } // ALE 20201119 and update the DB $stmt = $p_conn->prepare("INSERT INTO license (id, id_install, matrix_sn_hash, hclicense_dt_expire, hclicense_licensee, usblicense_desc, dt_create) VALUES (?, ?, ?, ?, ?, ?, utc_timestamp())"); $stmt->bind_param('ssssss', $id_license, $p_id_install, $p_matrix_sn_hash, $hclic_dt_expire, $p_hclicense_licensee, $p_usblicense_desc); $stmt->execute(); $stmt->close(); } function guidv4() { $data = openssl_random_pseudo_bytes(16); //assert(strlen($data) == 16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } ?>