Smail/server/services/adminreset/password_linux.go

63 lines
1.4 KiB
Go

//go:build linux
package adminreset
import (
"errors"
"io"
"os/exec"
"git.pcux.cn/xuans/Smail/utils/password"
)
func ReadProtectedPassword() (string, error) {
first, err := askPassword("请输入新的超级管理员密码")
if err != nil {
return "", err
}
second, err := askPassword("请再次输入新的超级管理员密码")
if err != nil {
clearPassword(&first)
return "", err
}
if first == "" || first != second {
clearPassword(&first)
clearPassword(&second)
return "", errors.New("密码为空或两次输入不一致")
}
clearPassword(&second)
return first, nil
}
func askPassword(prompt string) (string, error) {
command := exec.Command("systemd-ask-password", "--no-tty", prompt)
command.Stderr = io.Discard
output, err := command.Output()
if err != nil {
return "", errors.New("受保护密码代理不可用")
}
output = stripPasswordLineEnding(output)
value := string(output)
defer clearBytes(output)
if password.ValidateUserPassword(value) != nil {
return "", errors.New("密码长度无效")
}
return value, nil
}
func stripPasswordLineEnding(value []byte) []byte {
if len(value) > 0 && value[len(value)-1] == '\n' {
value = value[:len(value)-1]
}
if len(value) > 0 && value[len(value)-1] == '\r' {
value = value[:len(value)-1]
}
return value
}
func clearBytes(value []byte) {
for index := range value {
value[index] = 0
}
}