This commit is contained in:
parent
0a192851a8
commit
9f23c07b7b
@ -1,10 +1,14 @@
|
||||
[CmdletBinding()]
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$PackageRoot = (Split-Path -Parent $PSScriptRoot),
|
||||
[string]$PackageRoot = $null,
|
||||
[string]$InstallRoot = (Join-Path $env:ProgramData "Smail"),
|
||||
[switch]$StartService
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($PackageRoot)) {
|
||||
$PackageRoot = Split-Path -Parent $PSScriptRoot
|
||||
}
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Assert-Administrator {
|
||||
@ -130,8 +134,6 @@ try {
|
||||
if (Test-Path -LiteralPath $adminTarget) { Move-Item -LiteralPath $adminTarget -Destination $adminBackup }
|
||||
Move-Item -LiteralPath (Join-Path $transactionRoot "smail.exe") -Destination $mainTarget
|
||||
Move-Item -LiteralPath (Join-Path $transactionRoot "smail-admin.exe") -Destination $adminTarget
|
||||
Set-RestrictedAcl -Root $resolvedInstallRoot
|
||||
|
||||
$service = Get-Service -Name "Smail" -ErrorAction SilentlyContinue
|
||||
if ($null -eq $service) {
|
||||
$binaryPath = '"' + $mainTarget + '"'
|
||||
@ -147,6 +149,11 @@ try {
|
||||
"start=", "auto", "obj=", "NT SERVICE\Smail"
|
||||
)
|
||||
}
|
||||
Invoke-Native -FilePath "sc.exe" -Arguments @(
|
||||
"sidtype", "Smail", "unrestricted"
|
||||
)
|
||||
Set-RestrictedAcl -Root $resolvedInstallRoot
|
||||
|
||||
$failureActions = "restart/60000/restart/60000/"
|
||||
Invoke-Native -FilePath "sc.exe" -Arguments @(
|
||||
"failure", "Smail", "reset=", "86400", "actions=", $failureActions
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[CmdletBinding()]
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$InstallRoot = (Join-Path $env:ProgramData "Smail")
|
||||
)
|
||||
|
||||
@ -1426,3 +1426,14 @@ AD-065 + CG-053~CG-056 → AD-066 → CG-057
|
||||
### 发布结论
|
||||
|
||||
三份清单要求的可在当前工作区完成的代码实现已进入待复审状态;真实 Ubuntu 22.04/24.04、Windows Service/ACL/Named Pipe、真实 SMTP Relay、MySQL、PostgreSQL、浏览器三角色、多实例和最终发布安全评审保持阻塞。超级管理员自身重置仍只允许受保护的 UDS 或 Named Pipe,本轮未增加 HTTP、localhost TCP、局域网或公网 TCP 重置入口。
|
||||
|
||||
|
||||
## 2026-09-01 Windows 部署脚本兼容性复核记录
|
||||
|
||||
- **关联任务**:AD-009~AD-011、AD-061~AD-063。
|
||||
- **本轮状态**:`[x] 已完成,等待 Windows 实机复审`。
|
||||
- **发现并修复**:Windows PowerShell 5.1 直接执行时,原部署脚本因中文内容缺少 UTF-8 BOM 发生解析错误;安装脚本的 `$PSScriptRoot` 参数默认值在参数绑定阶段为空;ACL 在创建 `NT SERVICE\Smail` 服务 SID 前执行,存在真实安装失败风险。
|
||||
- **修改内容**:为 `deploy/install-windows.ps1` 和 `deploy/uninstall-windows.ps1` 增加 UTF-8 BOM;将安装脚本的 `PackageRoot` 改为参数绑定后回退到 `$PSScriptRoot`;创建或配置 `Smail` 服务后先执行 `sc.exe sidtype Smail unrestricted`,再应用服务 ACL。
|
||||
- **自动化验证**:`go test ./cmd/smail-admin -count=1 -v` 通过;两个脚本使用 Windows PowerShell 5.1 解析并进入预期的管理员权限拒绝分支;`git diff --check` 通过。
|
||||
- **未完成真实验收**:当前用户不是管理员,尚未执行真实 SCM 注册、服务 SID、ACL 拒绝和升级失败回滚验收;Ubuntu、MySQL、PostgreSQL、真实 SMTP、浏览器三角色和最终安全评审仍保持原阻塞。
|
||||
- **复审日期**:2026-09-01(本机自动化复核)。
|
||||
|
||||
@ -1328,3 +1328,13 @@ CG-053~CG-056 → AD-066 → CG-057
|
||||
- **自动化验证**:新增外键等价比较和差异拒绝测试;`go test ./... -count=1 -timeout 30m`、`go test -race ./... -count=1 -timeout 45m`、`go vet ./...`、前端 ESLint 和生产构建均通过。
|
||||
- **发布边界**:真实 MySQL/PostgreSQL/SQLite 迁移、跨平台部署、Nginx、浏览器、邮件系统、多实例和生产故障恢复仍待实机复审;CG-051、CG-056、CG-057 不升级为最终复审通过。
|
||||
- **复审日期**:2026-08-31(本机自动化复审)。
|
||||
|
||||
|
||||
## 2026-09-01 Windows 部署脚本兼容性复核记录
|
||||
|
||||
- **关联任务**:CG-031、CG-051~CG-057。
|
||||
- **本轮状态**:`[x] 已完成,等待 Windows 实机复审`。
|
||||
- **实施内容**:修复 Windows PowerShell 5.1 的 UTF-8 中文脚本解析兼容性、安装脚本 `PackageRoot` 参数绑定问题,并确保 `Smail` 服务创建和 SID 类型设置完成后再应用服务 ACL;新增静态顺序和脚本编码回归检查。
|
||||
- **自动化验证**:`go test ./cmd/smail-admin -count=1 -v`、`go test ./... -count=1 -timeout 30m`、`go vet ./...`、前端生产构建、ESLint 和 `git diff --check` 均通过。
|
||||
- **发布边界**:真实 Windows 管理员安装、Ubuntu systemd、三数据库、SMTP、浏览器三角色、多实例和最终安全评审仍未完成,CG-045、CG-051、CG-056、CG-057 不升级为最终复审通过。
|
||||
- **复审日期**:2026-09-01(本机自动化复核)。
|
||||
|
||||
@ -18,6 +18,9 @@ func TestWindowsDeploymentScriptsKeepAdminChannelManual(t *testing.T) {
|
||||
"sc.exe",
|
||||
"smail-admin.exe",
|
||||
"Set-RestrictedAcl",
|
||||
"sidtype",
|
||||
"$PackageRoot = $null",
|
||||
"$PackageRoot = Split-Path -Parent $PSScriptRoot",
|
||||
"NT SERVICE\\Smail:(F)",
|
||||
".backup-",
|
||||
"$mainBackup",
|
||||
@ -28,6 +31,14 @@ func TestWindowsDeploymentScriptsKeepAdminChannelManual(t *testing.T) {
|
||||
t.Fatalf("Windows installer is missing %q", required)
|
||||
}
|
||||
}
|
||||
if !hasUTF8BOM(installer) {
|
||||
t.Fatal("Windows installer must be encoded as UTF-8 with BOM for Windows PowerShell")
|
||||
}
|
||||
serviceSetup := strings.Index(content, `"sidtype", "Smail", "unrestricted"`)
|
||||
aclSetup := strings.Index(content, "Set-RestrictedAcl -Root $resolvedInstallRoot")
|
||||
if serviceSetup < 0 || aclSetup < 0 || serviceSetup > aclSetup {
|
||||
t.Fatal("Windows installer must create the service SID before applying service ACLs")
|
||||
}
|
||||
for _, forbidden := range []string{
|
||||
"create SmailAdmin",
|
||||
"Start-Service -Name \"SmailAdmin\"",
|
||||
@ -39,6 +50,10 @@ func TestWindowsDeploymentScriptsKeepAdminChannelManual(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func hasUTF8BOM(data []byte) bool {
|
||||
return len(data) >= 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF
|
||||
}
|
||||
|
||||
func TestWindowsUninstallerPreservesData(t *testing.T) {
|
||||
root := filepath.Clean(filepath.Join("..", "..", ".."))
|
||||
uninstaller, err := os.ReadFile(filepath.Join(root, "deploy", "uninstall-windows.ps1"))
|
||||
@ -46,6 +61,9 @@ func TestWindowsUninstallerPreservesData(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content := string(uninstaller)
|
||||
if !hasUTF8BOM(uninstaller) {
|
||||
t.Fatal("Windows uninstaller must be encoded as UTF-8 with BOM for Windows PowerShell")
|
||||
}
|
||||
if strings.Contains(content, "Remove-Item -LiteralPath $resolvedInstallRoot -Recurse") {
|
||||
t.Fatal("Windows uninstaller recursively removes the data root")
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user