2015-03-29 11:25:00 -05:00
|
|
|
package pam
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
2015-03-30 14:53:16 -05:00
|
|
|
"os/user"
|
2015-03-29 11:25:00 -05:00
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestPAM_001(t *testing.T) {
|
2015-03-30 14:53:16 -05:00
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
2015-12-04 09:21:38 -06:00
|
|
|
p := "secret"
|
2015-03-29 11:25:00 -05:00
|
|
|
tx, err := StartFunc("", "test", func(s Style, msg string) (string, error) {
|
2015-12-04 09:21:38 -06:00
|
|
|
return p, nil
|
2015-03-29 11:25:00 -05:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
2015-04-09 11:37:39 -05:00
|
|
|
err = tx.AcctMgmt(Silent)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("acct_mgmt #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.SetCred(Silent | EstablishCred)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("setcred #error: %v", err)
|
|
|
|
|
}
|
2015-03-29 11:25:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_002(t *testing.T) {
|
2015-03-30 14:53:16 -05:00
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
2015-03-29 11:25:00 -05:00
|
|
|
tx, err := StartFunc("", "", func(s Style, msg string) (string, error) {
|
|
|
|
|
switch s {
|
|
|
|
|
case PromptEchoOn:
|
|
|
|
|
return "test", nil
|
|
|
|
|
case PromptEchoOff:
|
|
|
|
|
return "secret", nil
|
|
|
|
|
}
|
|
|
|
|
return "", errors.New("unexpected")
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Credentials struct {
|
|
|
|
|
User string
|
|
|
|
|
Password string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c Credentials) RespondPAM(s Style, msg string) (string, error) {
|
|
|
|
|
switch s {
|
|
|
|
|
case PromptEchoOn:
|
|
|
|
|
return c.User, nil
|
|
|
|
|
case PromptEchoOff:
|
|
|
|
|
return c.Password, nil
|
|
|
|
|
}
|
|
|
|
|
return "", errors.New("unexpected")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_003(t *testing.T) {
|
2015-03-30 14:53:16 -05:00
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
2015-03-29 11:25:00 -05:00
|
|
|
c := Credentials{
|
|
|
|
|
User: "test",
|
|
|
|
|
Password: "secret",
|
|
|
|
|
}
|
|
|
|
|
tx, err := Start("", "", c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_004(t *testing.T) {
|
2015-03-30 14:53:16 -05:00
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
2015-03-29 11:25:00 -05:00
|
|
|
c := Credentials{
|
|
|
|
|
Password: "secret",
|
|
|
|
|
}
|
|
|
|
|
tx, err := Start("", "test", c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
2015-04-09 11:37:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_005(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
|
|
|
|
tx, err := StartFunc("passwd", "test", func(s Style, msg string) (string, error) {
|
|
|
|
|
return "secret", nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.ChangeAuthTok(Silent)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("chauthtok #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_006(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
|
|
|
|
tx, err := StartFunc("passwd", u.Username, func(s Style, msg string) (string, error) {
|
|
|
|
|
return "secret", nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.OpenSession(Silent)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("open_session #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.CloseSession(Silent)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("close_session #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_007(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
if u.Uid != "0" {
|
|
|
|
|
t.Skip("run this test as root")
|
|
|
|
|
}
|
|
|
|
|
tx, err := StartFunc("", "test", func(s Style, msg string) (string, error) {
|
|
|
|
|
return "", errors.New("Sorry, it didn't work")
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err == nil {
|
2015-04-10 15:04:52 -05:00
|
|
|
t.Fatalf("authenticate #expected an error")
|
2015-04-09 11:37:39 -05:00
|
|
|
}
|
|
|
|
|
s := err.Error()
|
|
|
|
|
if len(s) == 0 {
|
|
|
|
|
t.Fatalf("error #expected an error message")
|
|
|
|
|
}
|
2015-03-29 11:25:00 -05:00
|
|
|
}
|
2015-03-30 14:53:16 -05:00
|
|
|
|
2022-09-16 08:49:02 +02:00
|
|
|
func TestPAM_ConfDir(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
c := Credentials{
|
|
|
|
|
// the custom service always permits even with wrong password.
|
|
|
|
|
Password: "wrongsecret",
|
|
|
|
|
}
|
2023-09-19 18:17:54 +02:00
|
|
|
tx, err := StartConfDir("permit-service", u.Username, c, "test-services")
|
2022-09-16 08:49:02 +02:00
|
|
|
if !CheckPamHasStartConfdir() {
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("start should have errored out as pam_start_confdir is not available: %v", err)
|
|
|
|
|
}
|
|
|
|
|
// nothing else we do, we don't support it.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_ConfDir_FailNoServiceOrUnsupported(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
c := Credentials{
|
|
|
|
|
Password: "secret",
|
|
|
|
|
}
|
2023-09-19 18:18:56 +02:00
|
|
|
_, err := StartConfDir("does-not-exists", u.Username, c, ".")
|
2022-09-16 08:49:02 +02:00
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("authenticate #expected an error")
|
|
|
|
|
}
|
|
|
|
|
s := err.Error()
|
|
|
|
|
if len(s) == 0 {
|
|
|
|
|
t.Fatalf("error #expected an error message")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-19 18:21:03 +02:00
|
|
|
func TestPAM_ConfDir_InfoMessage(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
var infoText string
|
|
|
|
|
tx, err := StartConfDir("echo-service", u.Username,
|
|
|
|
|
ConversationFunc(func(s Style, msg string) (string, error) {
|
|
|
|
|
switch s {
|
|
|
|
|
case TextInfo:
|
|
|
|
|
infoText = msg
|
|
|
|
|
return "", nil
|
|
|
|
|
}
|
|
|
|
|
return "", errors.New("unexpected")
|
|
|
|
|
}), "test-services")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
2023-09-23 10:38:09 -05:00
|
|
|
if infoText != "This is an info message for user "+u.Username+" on echo-service" {
|
2023-09-19 18:21:03 +02:00
|
|
|
t.Fatalf("Unexpected info message: %v", infoText)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_ConfDir_Deny(t *testing.T) {
|
|
|
|
|
u, _ := user.Current()
|
|
|
|
|
tx, err := StartConfDir("deny-service", u.Username, Credentials{}, "test-services")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("authenticate #expected an error")
|
|
|
|
|
}
|
|
|
|
|
s := err.Error()
|
|
|
|
|
if len(s) == 0 {
|
|
|
|
|
t.Fatalf("error #expected an error message")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-19 18:40:17 +02:00
|
|
|
func TestPAM_ConfDir_PromptForUserName(t *testing.T) {
|
|
|
|
|
c := Credentials{
|
|
|
|
|
User: "testuser",
|
|
|
|
|
// the custom service only cares about correct user name.
|
|
|
|
|
Password: "wrongsecret",
|
|
|
|
|
}
|
|
|
|
|
tx, err := StartConfDir("succeed-if-user-test", "", c, "test-services")
|
|
|
|
|
if !CheckPamHasStartConfdir() {
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("start should have errored out as pam_start_confdir is not available: %v", err)
|
|
|
|
|
}
|
|
|
|
|
// nothing else we do, we don't support it.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("authenticate #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPAM_ConfDir_WrongUserName(t *testing.T) {
|
|
|
|
|
c := Credentials{
|
2023-09-23 10:38:09 -05:00
|
|
|
User: "wronguser",
|
2023-09-19 18:40:17 +02:00
|
|
|
Password: "wrongsecret",
|
|
|
|
|
}
|
|
|
|
|
tx, err := StartConfDir("succeed-if-user-test", "", c, "test-services")
|
|
|
|
|
if !CheckPamHasStartConfdir() {
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("start should have errored out as pam_start_confdir is not available: %v", err)
|
|
|
|
|
}
|
|
|
|
|
// nothing else we do, we don't support it.
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = tx.Authenticate(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("authenticate #expected an error")
|
|
|
|
|
}
|
|
|
|
|
s := err.Error()
|
|
|
|
|
if len(s) == 0 {
|
|
|
|
|
t.Fatalf("error #expected an error message")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-30 18:26:47 -05:00
|
|
|
func TestItem(t *testing.T) {
|
2019-02-15 12:06:59 -06:00
|
|
|
tx, _ := StartFunc("passwd", "test", func(s Style, msg string) (string, error) {
|
2015-03-30 18:26:47 -05:00
|
|
|
return "", nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
s, err := tx.GetItem(Service)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("getitem #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if s != "passwd" {
|
|
|
|
|
t.Fatalf("getitem #error: expected passwd, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s, err = tx.GetItem(User)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("getitem #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if s != "test" {
|
|
|
|
|
t.Fatalf("getitem #error: expected test, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = tx.SetItem(User, "root")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("setitem #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
s, err = tx.GetItem(User)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("getitem #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
if s != "root" {
|
|
|
|
|
t.Fatalf("getitem #error: expected root, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestEnv(t *testing.T) {
|
2015-03-30 18:13:10 -05:00
|
|
|
tx, err := StartFunc("", "", func(s Style, msg string) (string, error) {
|
2015-03-30 14:53:16 -05:00
|
|
|
return "", nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("start #error: %v", err)
|
|
|
|
|
}
|
2015-03-30 18:13:10 -05:00
|
|
|
|
2015-03-30 14:53:16 -05:00
|
|
|
m, err := tx.GetEnvList()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("getenvlist #error: %v", err)
|
|
|
|
|
}
|
2015-03-30 18:13:10 -05:00
|
|
|
n := len(m)
|
|
|
|
|
if n != 0 {
|
|
|
|
|
t.Fatalf("putenv #error: expected 0 items, got %v", n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vals := []string{
|
|
|
|
|
"VAL1=1",
|
|
|
|
|
"VAL2=2",
|
|
|
|
|
"VAL3=3",
|
|
|
|
|
}
|
|
|
|
|
for _, s := range vals {
|
|
|
|
|
err = tx.PutEnv(s)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("putenv #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-09 11:37:39 -05:00
|
|
|
s := tx.GetEnv("VAL0")
|
|
|
|
|
if s != "" {
|
|
|
|
|
t.Fatalf("getenv #error: expected \"\", got %v", s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s = tx.GetEnv("VAL1")
|
2015-03-30 18:13:10 -05:00
|
|
|
if s != "1" {
|
|
|
|
|
t.Fatalf("getenv #error: expected 1, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
s = tx.GetEnv("VAL2")
|
|
|
|
|
if s != "2" {
|
|
|
|
|
t.Fatalf("getenv #error: expected 2, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
s = tx.GetEnv("VAL3")
|
|
|
|
|
if s != "3" {
|
|
|
|
|
t.Fatalf("getenv #error: expected 3, got %v", s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m, err = tx.GetEnvList()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("getenvlist #error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
n = len(m)
|
|
|
|
|
if n != 3 {
|
|
|
|
|
t.Fatalf("getenvlist #error: expected 3 items, got %v", n)
|
|
|
|
|
}
|
|
|
|
|
if m["VAL1"] != "1" {
|
|
|
|
|
t.Fatalf("getenvlist #error: expected 1, got %v", m["VAL1"])
|
|
|
|
|
}
|
|
|
|
|
if m["VAL2"] != "2" {
|
|
|
|
|
t.Fatalf("getenvlist #error: expected 2, got %v", m["VAL1"])
|
|
|
|
|
}
|
|
|
|
|
if m["VAL3"] != "3" {
|
|
|
|
|
t.Fatalf("getenvlist #error: expected 3, got %v", m["VAL1"])
|
|
|
|
|
}
|
2015-03-30 14:53:16 -05:00
|
|
|
}
|
2015-04-10 15:28:23 -05:00
|
|
|
|
|
|
|
|
func TestFailure_001(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
_, err := tx.GetEnvList()
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_002(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.PutEnv("")
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_003(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.CloseSession(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_004(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.OpenSession(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_005(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.ChangeAuthTok(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_006(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.AcctMgmt(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_007(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.SetCred(0)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_008(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
err := tx.SetItem(User, "test")
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFailure_009(t *testing.T) {
|
|
|
|
|
tx := Transaction{}
|
|
|
|
|
_, err := tx.GetItem(User)
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("getenvlist #expected an error")
|
|
|
|
|
}
|
|
|
|
|
}
|