whoami7 - Manager
:
/
home
/
simspala
/
yoursimzone.com
/
Upload File:
files >> /home/simspala/yoursimzone.com/mtn_refresh.php
<?php declare(strict_types=1); date_default_timezone_set('Africa/Lagos'); set_time_limit(0); ini_set('memory_limit', '1024M'); /** * Combined MTN refresh & RSA key renewal script * - refreshes access_tokens (every 5min) * - regenerates RSA keys when expiry <= 24h * - uploads new public key (storePublicKey) * - performs signIn and updates server_token, keys, expiry * * Run as cron: php /path/to/mtn_refresh.php */ // ------------------------------- CONSTANTS ----------------------------------- define('CLIENT_ID', 'WO5BbTyEWLSFvFPw5TsYoioTQqcq8Mq3'); define('MTN_TOKEN_URL', 'https://auth.mtnonline.com/oauth/token'); define('STORE_KEY_URL', 'https://mtn-dxl-biometrics-authorization.mymtnnxgeaprod.mtnnigeria.net/v1/biometrics/storePublicKey'); define('SIGNIN_URL', 'https://mtn-dxl-biometrics-authorization.mymtnnxgeaprod.mtnnigeria.net/v1/biometrics/signIn'); const REFRESH_INTERVAL = 300; // 5 minutes const KEY_BUFFER_HOURS = 24; // regenerate keys when <= 24 hours before expiry const MAX_JWT_RETRIES = 5; // for key upload retries // ------------------------------- DB CONNECTION -------------------------------- $dsn = 'mysql:host=localhost;dbname=simspala_yoursim;charset=utf8mb4'; $dbUser = 'simspala_yoursim'; $dbPass = 'simspala_yoursim'; try { $pdo = new PDO($dsn, $dbUser, $dbPass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); } catch (PDOException $e) { echo "❌ DB connection failed: " . $e->getMessage() . PHP_EOL; exit(1); } // ------------------------------- HELPER FUNCTIONS ----------------------------- function base64url_decode(string $input): string { $remainder = strlen($input) % 4; if ($remainder) $input .= str_repeat('=', 4 - $remainder); return base64_decode(strtr($input, '-_', '+/')); } function postJson(string $url, array $headers, array $payload): array { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => array_merge(['Content-Type: application/json'], $headers), CURLOPT_TIMEOUT => 45, CURLOPT_CONNECTTIMEOUT => 10, ]); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $errno= curl_errno($ch); $err = curl_error($ch); curl_close($ch); return [$code,$resp,$errno,$err]; } function refreshAccessToken(PDO $pdo, array $srv): ?array { $payload = http_build_query([ 'grant_type' => 'refresh_token', 'client_id' => CLIENT_ID, 'refresh_token' => $srv['refresh_token'] ]); $ch = curl_init(MTN_TOKEN_URL); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'], CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 10, ]); $raw = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code !== 200) return null; $json = json_decode((string)$raw, true); if (empty($json['access_token'])) return null; $token = $json['access_token']; $parts = explode('.', $token); $payloadArr = isset($parts[1]) ? json_decode(base64url_decode($parts[1]), true) : []; $expiryTs = $payloadArr['exp'] ?? (time()+3600*12); $pdo->prepare("UPDATE servers SET server_token = :tok, expired_at = :exp, attempts = 0 WHERE id = :id") ->execute([ ':tok' => $token, ':exp' => date('Y-m-d H:i:s',$expiryTs), ':id' => $srv['id'] ]); $srv['server_token'] = $token; return $srv; } function handleFailure(PDO $pdo, array $srv, string $msg): void { $attempts = (int)$srv['attempts'] + 1; if ($attempts >= 5) { $pdo->prepare("UPDATE servers SET attempts=?, server_on=0 WHERE id=?") ->execute([$attempts,$srv['id']]); $msg .= ' (disabled)'; } else { $pdo->prepare("UPDATE servers SET attempts=? WHERE id=?") ->execute([$attempts,$srv['id']]); } file_put_contents(__DIR__.'/keepalive_errors.log', "[".date('Y-m-d H:i:s')."] {$srv['phone_number']}: {$msg}\n", FILE_APPEND ); } // ------------------------------- MAIN LOOP ----------------------------------- while (true) { echo "\n===== MTN KeepAlive ".date('Y-m-d H:i:s')." =====\n"; $now = time(); $bufferLimit = $now + (KEY_BUFFER_HOURS*3600); // Fetch all servers that require either refresh or key renewal $stmt = $pdo->query(" SELECT * FROM servers WHERE server_on = 1 AND ( expired_at IS NULL OR UNIX_TIMESTAMP(expired_at) <= $bufferLimit ) "); $servers = $stmt->fetchAll(); if (!$servers) { echo "✅ All servers healthy. Sleeping...\n"; sleep(REFRESH_INTERVAL); continue; } foreach ($servers as $srv) { $id = (int)$srv['id']; $phone = $srv['phone_number']; $expTs = $srv['expired_at'] ? strtotime($srv['expired_at']) : null; // ==== 1) key renewal (if expiry <= bufferLimit) ==== if ($expTs !== null && $expTs <= $bufferLimit) { echo "🔁 Key renewal for {$phone} (expires ".($srv['expired_at'] ?? 'N/A').")... "; // (a) generate RSA keys $res = openssl_pkey_new(['private_key_bits'=>2048,'private_key_type'=>OPENSSL_KEYTYPE_RSA]); if (!$res) { handleFailure($pdo,$srv,'OpenSSL key generation failed'); continue; } openssl_pkey_export($res, $privateKey); $detail = openssl_pkey_get_details($res); $publicKey = $detail['key'] ?? null; if (!$publicKey) { handleFailure($pdo,$srv,'Public key extraction failed'); continue; } $plainPub = trim(str_replace(['-----BEGIN PUBLIC KEY-----','-----END PUBLIC KEY-----'], '', $publicKey)); // (b) upload public key (with auto JWT refresh retry) $srvUpdated = $srv; $uploaded = false; for ($i=0; $i<=MAX_JWT_RETRIES; $i++) { [$code,$resp,$errno,$err] = postJson(STORE_KEY_URL, [ 'channel: MTNAPPNXG', 'Authorization: Bearer '.$srvUpdated['server_token'] ], ['publicKey'=>$plainPub]); if ($errno!==0) { handleFailure($pdo,$srv,"cURL error $err"); break; } if ($code===200) { $uploaded=true; break; } $j = json_decode((string)$resp,true); $msg = $j['message'] ?? ''; if (stripos($msg,'JWT Token is expired')!==false) { $tmp = refreshAccessToken($pdo,$srvUpdated); if (!$tmp) break; $srvUpdated = array_merge($srvUpdated,$tmp); continue; } handleFailure($pdo,$srv,"storePublicKey HTTP {$code}"); break; } if (!$uploaded) continue; // (c) signIn using new private key $msisdn = substr((string)$phone,1); openssl_sign($msisdn,$signature,$res,OPENSSL_ALGO_SHA256); $b64Sig = base64_encode($signature); [$code2,$resp2,$errno2,$err2] = postJson(SIGNIN_URL,[ 'channel: MTNAPPNXG' ],[ 'signature'=>$b64Sig, 'msisdn' =>$msisdn ]); if ($errno2!==0 || $code2!==200) { handleFailure($pdo,$srv,"signIn failed HTTP {$code2}"); continue; } $json2 = json_decode((string)$resp2,true); if (empty($json2['access_token'])) { handleFailure($pdo,$srv,'signIn missing access_token'); continue; } $token = $json2['access_token']; $parts = explode('.', $token); $pArr = isset($parts[1]) ? json_decode(base64url_decode($parts[1]), true) : []; $newExp= $pArr['exp'] ?? ($now+3600*12); // update all fields $pdo->prepare("UPDATE servers SET server_token = :tok, refresh_token= :ref, expired_at = :exp, publickey = :pub, privatekey = :priv, signature = :sig, attempts = 0 WHERE id = :id")->execute([ ':tok'=>$token, ':ref'=>$json2['refresh_token'] ?? $srv['refresh_token'], ':exp'=>date('Y-m-d H:i:s',$newExp), ':pub'=>$publicKey, ':priv'=>$privateKey, ':sig'=>$b64Sig, ':id'=>$id ]); echo "✅ renewed\n"; continue; // skip normal refresh (already done via signIn) } // ==== 2) normal refresh ==== echo "🔄 Refreshing token for {$phone}... "; $updated = refreshAccessToken($pdo,$srv); if (!$updated) { handleFailure($pdo,$srv,'refresh failed'); } else { echo "✅\n"; } } echo "🕒 Sleeping " . REFRESH_INTERVAL . " seconds...\n"; sleep(REFRESH_INTERVAL); }
Copyright ©2021 || Defacer Indonesia