У меня есть приложение, которое запрашивает имя пользователя и пароль пользователя. В настоящее время для Unix систем (большинство из них) я прочитал пароль ha sh из /etc/shadow
, но для macOS это намного более громоздко (они используют свой собственный стандарт), поэтому я хотел знать, есть ли простой способ проверьте имена пользователей и пароли.
Я думал об использовании программы login
странным образом, но это не лучшее решение.
Я использую golang, но решение в C или C ++ тоже было бы полезно.
Редактировать
Ответ от @TheNextman - именно то, о чем я просил, но разговаривая с другими людьми, они предлагают мне используйте PAM, потому что он работает с несколькими ОС. Мне потребовались некоторые усилия, чтобы понять это, потому что я искал простой API для проверки пользователей и паролей, что-то вроде verify(username string, password string) -> boolean
, но я понял, что PAM является более общим и, следовательно, более сложным.
Но это код, который я использовал в итоге, он сделан в GO с C привязками.
package Authentication
import "C"
import (
"encoding/json"
"fmt"
"github.com/vvanpo/golang-pam"
)
func ValidateUser(username, password string) (bool, error) {
// TODO correct handle of errors
UserPssword := userPassword{
Username : username,
Password : password,
}
b, _ := json.Marshal(UserPssword)
conn := myConHand{
username:C.CString(string(b)),
}
tx, _ := pam.Start("sshd", username, conn)
r := tx.Authenticate(0)
if r == pam.SUCCESS{
return true, nil
} else {
return false, nil
}
}
type userPassword struct {
Username string
Password string
}
type myConHand struct {
username *C.char
}
//C.GoString
func (m myConHand) RespondPAM(msg_style int, msg string) (string, bool) {
str := C.GoString(m.username)
var UserPssword userPassword
_ = json.Unmarshal([]byte(str), &UserPssword)
switch msg_style {
case pam.PROMPT_ECHO_OFF:
fmt.Println("Password!!")
return UserPssword.Password, true
case pam.PROMPT_ECHO_ON:
fmt.Println("Username!!")
return UserPssword.Username, true
case pam.ERROR_MSG:
fmt.Println(msg)
return "", true
case pam.TEXT_INFO:
fmt.Println(msg)
return "", true
default:
return "", true
}
}
У него есть некоторые проблемы, например, я использую сервис /etc/pam.d/sshd
, потому что я знаю, что компьютеры Я буду использовать тот же сервис, но я не знаю, какая ОС имеет /etc/pam.d/sshd
, другой вариант - создать свой собственный сервис, но мне придется создать его для каждого отдельного стандарта, который я нашел 3 Linux PAM, openPAM (macos) и Solaris PAM.
Но в целом я считаю, что это надежное решение, поскольку я повторно использую существующий механизм аутентификации.