初始化奇妙小屏幕控制器项目

This commit is contained in:
2026-09-08 22:56:52 +08:00
commit 8d368de3b5
491 changed files with 67678 additions and 0 deletions
@@ -0,0 +1,284 @@
from __future__ import annotations
import argparse
import ipaddress
import os
import re
import subprocess
import sys
from pathlib import Path, PurePosixPath
SCRIPT_PATH = Path(__file__).resolve()
WORKSPACE_ROOT = SCRIPT_PATH.parents[2]
PRIVATE_CREDENTIAL = PurePosixPath("测试相关资料/核桃派的用户名和密码和ip/用户名密码ip.txt")
EXAMPLE_CREDENTIAL = PurePosixPath(
"测试相关资料/核桃派的用户名和密码和ip/用户名密码ip.example.txt"
)
BINARY_EXTENSIONS = {
".deb",
".dll",
".docx",
".exe",
".gif",
".gz",
".img",
".jpeg",
".jpg",
".otf",
".ota",
".pdf",
".png",
".rar",
".so",
".ttf",
".whl",
".woff",
".woff2",
".zip",
}
PRIVATE_IP_ALLOWED_PREFIXES = (
"整体开发需求/",
"测试相关资料/如何测试/",
"核桃派软件源代码/",
"发布更新相关/其他依赖/",
)
SAFE_SECRET_VALUES = {
"changeme",
"example",
"example123",
"fake",
"fake-secret",
"password",
"secret123",
"test",
"test-password",
}
# The password is a high-confidence private marker. Addresses, usernames and
# hostnames are checked structurally because common fixture values also occur in
# provisioning source and tests.
CURRENT_DEVICE_KEYS = ("密码",)
PUBLIC_IMAGE_KEYS = (
"镜像默认用户名",
"镜像默认账户密码",
"镜像默认WiFi SSID",
"镜像默认WiFi密码",
)
class HygieneError(RuntimeError):
"""Repository state cannot be audited safely."""
def _git(*arguments: str, check: bool = True) -> subprocess.CompletedProcess[bytes]:
return subprocess.run(
("git", *arguments),
cwd=WORKSPACE_ROOT,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=check,
)
def _decode_paths(payload: bytes) -> list[PurePosixPath]:
return [
PurePosixPath(item.decode("utf-8", errors="surrogateescape"))
for item in payload.split(b"\0")
if item
]
def candidate_paths(staged: bool) -> list[PurePosixPath]:
if staged:
result = _git("diff", "--cached", "--name-only", "--diff-filter=ACMR", "-z")
return _decode_paths(result.stdout)
tracked = _decode_paths(_git("ls-files", "-z").stdout)
untracked = _decode_paths(_git("ls-files", "--others", "--exclude-standard", "-z").stdout)
return sorted(set((*tracked, *untracked)), key=str)
def _is_binary(path: Path) -> bool:
if path.suffix.casefold() in BINARY_EXTENSIONS:
return True
try:
return b"\0" in path.read_bytes()[:8192]
except OSError as error:
raise HygieneError(f"无法读取候选文件:{path.relative_to(WORKSPACE_ROOT)}") from error
def _host_text_patterns() -> list[re.Pattern[str]]:
windows_prefix = r"[A-Za-z]:[\\/]" + r"(?:Users|Documents and Settings)[\\/]"
mac_prefix = r"/" + r"Users/[A-Za-z0-9._-]+/"
linux_home = r"/" + r"home/[A-Za-z0-9._-]+/"
patterns = [re.compile(windows_prefix, re.IGNORECASE), re.compile(mac_prefix), re.compile(linux_home)]
for value in (Path.home().name, os.environ.get("COMPUTERNAME", "")):
if value and len(value) >= 4:
patterns.append(re.compile(re.escape(value), re.IGNORECASE))
return patterns
def _private_value_markers() -> tuple[str, ...]:
path = WORKSPACE_ROOT.joinpath(*PRIVATE_CREDENTIAL.parts)
if not path.is_file():
return ()
fields: dict[str, str] = {}
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue
separator = ":" if ":" in line else ":" if ":" in line else None
if separator is None:
continue
key, value = (part.strip() for part in line.split(separator, 1))
fields[key] = value
public_values = {fields.get(key, "") for key in PUBLIC_IMAGE_KEYS}
return tuple(
value
for key in CURRENT_DEVICE_KEYS
if len(value := fields.get(key, "")) >= 4 and value not in public_values
)
def _binary_markers(private_values: tuple[str, ...] = ()) -> list[bytes]:
markers: list[bytes] = []
host_values = {
str(Path.home()),
str(WORKSPACE_ROOT),
Path.home().name,
os.environ.get("COMPUTERNAME", ""),
}
for value in (*host_values, *private_values):
if value and len(value) >= 4:
variants = {value, value.replace("\\", "/")}
for variant in variants:
markers.extend((variant.encode("utf-8"), variant.encode("utf-16le")))
return markers
def _binary_contains_forbidden_marker(path: Path, private_values: tuple[str, ...]) -> bool:
markers = _binary_markers(private_values)
overlap = max(map(len, markers)) - 1
tail = b""
with path.open("rb") as stream:
while chunk := stream.read(8 * 1024 * 1024):
sample = tail + chunk
lowered_sample = sample.lower()
if any(marker.lower() in lowered_sample for marker in markers):
return True
tail = sample[-overlap:] if overlap else b""
return False
def _text_issues(
relative: PurePosixPath,
text: str,
private_values: tuple[str, ...] = (),
) -> list[str]:
issues: list[str] = []
if any(pattern.search(text) for pattern in _host_text_patterns()):
issues.append("包含开发电脑专属路径、用户名或主机名")
if any(value in text for value in private_values):
issues.append("包含当前设备私有凭据值")
key_header = re.compile("-----BEGIN " + r"(?:OPENSSH |RSA |EC |DSA )?PRIVATE KEY-----")
if key_header.search(text):
issues.append("包含私钥正文")
relative_string = relative.as_posix()
if not (
relative_string.startswith("核桃派软件源代码/tests/")
or PurePosixPath(relative_string).name.startswith("test_")
or relative == EXAMPLE_CREDENTIAL
):
assignment = re.compile(
r"(?i)(?:password|passwd|token|secret|api[_-]?key|密码)\s*[:=]\s*[\"']([^\"']{4,})[\"']"
)
for match in assignment.finditer(text):
if match.group(1).casefold() not in SAFE_SECRET_VALUES:
issues.append("包含疑似硬编码秘密")
break
if not (
relative_string.startswith(PRIVATE_IP_ALLOWED_PREFIXES)
or "/tests/" in f"/{relative_string}"
):
for token in re.findall(r"(?<![0-9])(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?![0-9])", text):
try:
address = ipaddress.ip_address(token)
except ValueError:
continue
if address.is_private and not address.is_loopback and not address.is_unspecified:
issues.append("归档或普通文档包含私有 IPv4 地址")
break
return issues
def audit_paths(paths: list[PurePosixPath], *, scan_binary: bool) -> list[tuple[str, str]]:
findings: list[tuple[str, str]] = []
private_values = _private_value_markers()
for relative in paths:
if relative == PRIVATE_CREDENTIAL:
findings.append((relative.as_posix(), "真实凭据进入 Git 候选集合"))
continue
path = WORKSPACE_ROOT.joinpath(*relative.parts)
if not path.is_file():
continue
if _is_binary(path):
if scan_binary and _binary_contains_forbidden_marker(path, private_values):
findings.append((relative.as_posix(), "二进制包含开发电脑标识、主目录路径或当前设备秘密"))
continue
try:
text = path.read_text(encoding="utf-8")
except UnicodeDecodeError:
findings.append((relative.as_posix(), "文本候选不是有效 UTF-8"))
continue
findings.extend(
(relative.as_posix(), issue) for issue in _text_issues(relative, text, private_values)
)
return findings
def _check_repository_contract(paths: list[PurePosixPath], staged: bool) -> list[tuple[str, str]]:
findings: list[tuple[str, str]] = []
ignored = _git("check-ignore", "--quiet", "--", PRIVATE_CREDENTIAL.as_posix(), check=False)
if ignored.returncode != 0:
findings.append((PRIVATE_CREDENTIAL.as_posix(), "真实凭据未被 .gitignore 精确排除"))
if staged:
example_in_index = _git("cat-file", "-e", f":{EXAMPLE_CREDENTIAL.as_posix()}", check=False)
if example_in_index.returncode != 0:
findings.append((EXAMPLE_CREDENTIAL.as_posix(), "示例凭据没有进入本次提交"))
elif EXAMPLE_CREDENTIAL not in paths:
findings.append((EXAMPLE_CREDENTIAL.as_posix(), "示例凭据不在 Git 候选集合"))
return findings
def main() -> int:
parser = argparse.ArgumentParser(description="检查 Git 候选文件中的凭据、主机路径和秘密")
parser.add_argument("--staged", action="store_true", help="只检查已暂存的新建或修改文件")
parser.add_argument(
"--skip-binary-scan",
action="store_true",
help="跳过大体积二进制字节扫描,仅供快速诊断",
)
args = parser.parse_args()
try:
paths = candidate_paths(args.staged)
findings = _check_repository_contract(paths, args.staged)
findings.extend(audit_paths(paths, scan_binary=not args.skip_binary_scan))
except (HygieneError, OSError, subprocess.CalledProcessError) as error:
print(f"仓库卫生检查无法完成:{error}", file=sys.stderr)
return 2
if findings:
print("仓库卫生检查失败;以下输出只包含文件路径和问题类型:", file=sys.stderr)
for path, issue in findings:
print(f"- {path}: {issue}", file=sys.stderr)
return 1
print(f"仓库卫生检查通过:已检查 {len(paths)} 个 Git 候选文件,未输出任何秘密值。")
return 0
if __name__ == "__main__":
raise SystemExit(main())