ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性

被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
This commit is contained in:
xmz7891
2026-10-06 19:01:05 +08:00
commit b62ac865ea
3195 changed files with 203292 additions and 0 deletions
+273
View File
@@ -0,0 +1,273 @@
# -*- coding: utf-8 -*-
"""功能全量模糊测试:找出会"崩"的功能。
约定:参数不合法应该抛 ValueError(会被转成给用户看的错误提示)。
抛其它异常(TypeError / KeyError / AttributeError / IndexError / OSError…)
就是 bug。
设计要点(第一版太慢,这里改过):
* 只 fuzz 功能**自己声明**的参数(key / key2),不再瞎塞 13 个 key。
之前 perf / installed_apps 这类会真去调 PowerShell,被调了几百次。
* 有副作用的功能用 DANGEROUS 列表跳过实测。
* 全屏类每次调用后立刻关掉,避免堆窗口。
"""
from __future__ import annotations
import sys
import tempfile
import tkinter as tk
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "windows"))
# 会真的动系统,不实测
DANGEROUS = {
"empty_recycle", "close_windows", "sign_out", "sleep", "hibernate",
"restart_graphics", "minimize_all", "task_view", "restart_explorer",
"lock_only", "lock_and_off", "clear_clip", "open_recycle", "open_file",
"display_mode", "fade_volume", "monitor_on", "volume_up", "volume_down",
"mute_all", "flush_dns", "password_gen", "cinema_mode", "random_song",
"play_video", "stop_after", "pomodoro", "reminder", "cheer",
"clip_fav_add", "download_file", "qr_code", "speed_test", "public_ip",
}
# 会开全屏窗口的:能测,但测完要关
FULLSCREEN = {
"big_text", "big_text_quiet", "countdown_screen", "roll_call", "whiteboard",
"danmaku", "marquee", "lottery", "dice", "coin_flip", "countdown_321",
"score_board", "score_change", "matrix_rain", "starfield", "dashboard",
"stopwatch",
}
# 读一次就够、不跟参数走的(避免重复 shell 调用拖慢测试)
EXPENSIVE = {
"perf", "disk", "battery", "uptime", "installed_apps", "top_services",
"event_errors", "temperature", "hardware_info", "startup_items",
"scheduled_tasks", "system_detail", "recent_files", "network_speed",
"gpu_info", "arp_devices", "net_adapters", "wifi_password", "disk_by_type",
"world_clock", "timestamp_now", "uuid_gen", "screen_color",
}
JUNK = [None, [], {}, "", "abc", 999999, -1, 0, "a" * 3000]
PASSED = 0
CRASHES: list[tuple[str, str, str]] = []
SLOW_SKIPPED: list[str] = []
def main() -> int:
global PASSED
from lanremote.actions import Actions
from lanremote.config import Store
from lanremote.features import Features
tmp = Path(tempfile.mkdtemp())
store = Store(tmp)
class FakeUI:
root = tk.Tk()
root.withdraw()
def ui_call(self, fn, timeout=5.0):
return fn()
def screen_size(self):
return (1920, 1080)
def notify(self, *a, **k):
pass
def log(self, *a, **k):
pass
def show_message(self, *a, **k):
pass
def close_image(self):
pass
actions = Actions(FakeUI(), store)
features = Features(actions)
defs = {d["name"]: d for d in features.defs()}
print(f"功能总数: {len(defs)}", flush=True)
def cleanup_fullscreen(name):
if name in FULLSCREEN:
try:
features.run("big_text_clear", {})
except Exception: # noqa: BLE001
pass
try:
FakeUI.root.update()
except tk.TclError:
pass
# ---------------- 一、空参数 ----------------
print()
print("=" * 74)
print("一、空参数({})")
print("=" * 74, flush=True)
for name in sorted(defs):
if name in DANGEROUS:
continue
try:
features.run(name, {})
PASSED += 1
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append((name, "{}", f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {name}({{}}) -> {type(exc).__name__}: {exc}", flush=True)
cleanup_fullscreen(name)
# ---------------- 二、垃圾参数 ----------------
print()
print("=" * 74)
print("二、垃圾参数(只喂功能自己声明的 key)")
print("=" * 74, flush=True)
for name in sorted(defs):
if name in DANGEROUS:
continue
spec = defs[name]
keys = [k for k in (spec.get("key"), spec.get("key2")) if k]
if not keys:
continue # 不接参数的功能,上面那轮已经覆盖
if name in EXPENSIVE:
SLOW_SKIPPED.append(name)
continue
for key in keys:
for junk in JUNK:
try:
features.run(name, {key: junk})
PASSED += 1
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append((name, f"{key}={junk!r}"[:40],
f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {name}({key}={junk!r}) -> "
f"{type(exc).__name__}: {exc}", flush=True)
break
cleanup_fullscreen(name)
# ---------------- 三、越权路径 ----------------
print()
print("=" * 74)
print("三、路径越权(必须全部拒绝)")
print("=" * 74, flush=True)
escapes = [
r"C:\Windows\System32\drivers\etc\hosts",
r"..\..\Windows\win.ini",
r"C:\Windows",
"/etc/passwd",
r"\\?\C:\Windows\win.ini",
r"C:Windows\win.ini",
r"\Windows\win.ini",
r"C:\Windows\..\Windows\win.ini",
" C:\\Windows\\win.ini ",
]
for path in escapes:
try:
resolved = features.resolve_in_roots(path)
allowed = [str(r.resolve()).lower() for r in features.allowed_roots()]
inside = any(str(resolved).lower().startswith(a) for a in allowed)
if inside:
PASSED += 1
else:
CRASHES.append(("resolve_in_roots", repr(path),
f"逃出允许范围: {resolved}"))
print(f" [越权!] {path!r} -> {resolved}", flush=True)
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append(("resolve_in_roots", repr(path),
f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {path!r} -> {type(exc).__name__}: {exc}", flush=True)
# 注意:search_files 接的是 keyword(拿去当文件名匹配),不是路径,
# 它本来就逃不出允许目录,所以不放在路径测试里。
file_features = ["list_dir", "make_dir", "rename_file",
"delete_file", "open_file", "copy_file", "move_file",
"zip_dir", "unzip", "file_info", "folder_size"]
for name in file_features:
for path in escapes[:5]:
try:
features.run(name, {"path": path, "to": path, "name": "zz",
"keyword": "zz"})
CRASHES.append((name, repr(path), "越权路径竟然被执行了"))
print(f" [越权!] {name}({path!r}) 竟然执行了", flush=True)
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append((name, repr(path), f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {name}({path!r}) -> "
f"{type(exc).__name__}: {exc}", flush=True)
# ---------------- 四、目录守卫 ----------------
print()
print("=" * 74)
print("四、目录守卫(不能对允许目录本身动手)")
print("=" * 74, flush=True)
for name, params in (("rename_file", {"path": "Downloads", "name": "zz"}),
("delete_file", {"path": "Desktop"}),
("move_file", {"path": "Downloads", "to": "Documents"}),
("copy_file", {"path": "Desktop", "to": "Downloads"})):
try:
features.run(name, params)
CRASHES.append((name, str(params), "竟然允许对允许目录本身动手"))
print(f" [危险!] {name} 竟然允许了", flush=True)
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append((name, str(params), f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {name} -> {type(exc).__name__}: {exc}", flush=True)
# ---------------- 五、数据目录 ----------------
print()
print("五、数据目录(配对码 / 设备令牌)不可访问")
# 用真实的 store.dir 构成绝对路径来测 —— 相对路径会解析到 Downloads 下,
# 那是允许目录,测不出东西。真正的 CWD 相对路径由端到端测试覆盖。
probes = [str(store.dir / "settings.json"), str(store.dir / "devices.json"),
str(store.dir)]
for probe in probes:
try:
features.resolve_in_roots(probe)
CRASHES.append(("resolve_in_roots", probe, "数据目录竟然可访问"))
print(f" [危险!] {probe} 竟然可访问", flush=True)
except ValueError:
PASSED += 1
except Exception as exc: # noqa: BLE001
CRASHES.append(("resolve_in_roots", probe,
f"{type(exc).__name__}: {exc}"))
print(f" [崩溃] {probe} -> {type(exc).__name__}: {exc}", flush=True)
try:
FakeUI.root.destroy()
except tk.TclError:
pass
print()
print("=" * 74)
print("汇总")
print("=" * 74)
print(f" 正常: {PASSED}")
print(f" 崩溃/越权: {len(CRASHES)}")
if SLOW_SKIPPED:
print(f" 跳过的慢功能(只测了空参数): {', '.join(SLOW_SKIPPED)}")
if CRASHES:
print()
print(" ---- 需要修 ----")
seen = set()
for name, arg, err in CRASHES:
key = (name, err.split(":")[0])
if key in seen:
continue
seen.add(key)
print(f" {name}({arg})\n {err}")
return 1 if CRASHES else 0
if __name__ == "__main__":
sys.exit(main())