package main import ( "context" "errors" "fmt" "os" "os/signal" "strings" "syscall" "time" "git.pcux.cn/xuans/Smail/internal/buildinfo" "git.pcux.cn/xuans/Smail/services/adminreset" ) func main() { code := run(os.Args[1:]) if code != 0 { os.Exit(code) } } func run(args []string) int { if len(args) == 1 && (args[0] == "version" || args[0] == "--version") { fmt.Println(buildinfo.Current().Version) return 0 } if len(args) == 1 && (args[0] == "doctor" || args[0] == "--doctor") { return runDoctor() } if len(args) != 0 || hasPasswordArgument(args) { fmt.Fprintln(os.Stderr, "smail-admin 只允许由 systemctl start smail-admin 无参数启动") return 2 } signalContext, stopSignals := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stopSignals() invocationContext, closeInvocation, err := adminreset.OpenInvocation(signalContext) if err != nil { fmt.Fprintln(os.Stderr, "超级管理员重置已拒绝:请在本机管理员终端使用 systemctl start smail-admin,停止请使用 systemctl stop smail-admin") return 1 } defer closeInvocation() ctx, cancel := context.WithTimeout(invocationContext, 5*time.Minute) defer cancel() conn, err := adminreset.DialControl(ctx, adminreset.DefaultControlPath) if err != nil { return finishResetContext(ctx, "超级管理员重置通道不可用", 1) } defer conn.Close() stopClosing := context.AfterFunc(ctx, func() { _ = conn.Close() }) defer stopClosing() if err := adminreset.SendVerifiedResetWithInput(ctx, conn, adminreset.ReadVisibleInputContext, func() (string, error) { return adminreset.ReadProtectedPasswordContext(ctx) }); err != nil { if ctx.Err() != nil { fmt.Fprintln(os.Stderr, "超级管理员重置已取消") return 0 } return finishResetContext(ctx, "超级管理员重置失败:"+safeError(err), 1) } return finishResetContext(ctx, "超级管理员密码重置成功,请使用新密码登录", 0) } func finishReset(message string, code int) int { return finishResetContext(context.Background(), message, code) } func finishResetContext(ctx context.Context, message string, code int) int { fmt.Fprintln(os.Stderr, message) adminreset.ShowResultContext(ctx, message) return code } func runDoctor() int { report := adminreset.CheckEnvironment() status := "正常" if !report.Supported { status = "不支持" } else if !report.Privileged || !report.ServiceManaged || !report.PasswordAgentAvailable { status = "不满足重置条件" } fmt.Printf("平台:%s\n重置支持:%t\n部署管理员身份:%t\n系统服务上下文:%t\n密码代理:%t\n控制通道:%s\n状态:%s\n", report.Platform, report.Supported, report.Privileged, report.ServiceManaged, report.PasswordAgentAvailable, report.ControlPath, status, ) return 0 } func hasPasswordArgument(args []string) bool { for _, arg := range args { lower := strings.ToLower(arg) if strings.Contains(lower, "password") || strings.Contains(lower, "passwd") || strings.Contains(lower, "secret") { return true } } return false } func safeError(err error) string { if err == nil { return "" } if errors.Is(err, adminreset.ErrVerificationUnavailable) { return "没有可用的安全验证方式,请先登录安全中心配置邮箱、手机动态码或安全码" } if errors.Is(err, adminreset.ErrVerificationFailed) { return "安全验证失败、已过期或请求过于频繁,请稍后重新启动重置" } if errors.Is(err, adminreset.ErrEmailDeliveryFailed) { return "邮件验证码发送失败或请求过于频繁,请稍后重试或选择其他验证方式" } if errors.Is(err, adminreset.ErrExpiredSession) { return "重置会话已过期,请重新启动重置" } if errors.Is(err, adminreset.ErrInvalidRequest) || errors.Is(err, adminreset.ErrUnsupported) { return "请求无效或当前平台不支持" } return "本机受保护通道拒绝了请求" } func clearString(value *string) { if value == nil { return } buffer := []byte(*value) for i := range buffer { buffer[i] = 0 } *value = "" }