diff --git a/auth.go b/auth.go index 8fe59e3..017dd98 100644 --- a/auth.go +++ b/auth.go @@ -31,9 +31,9 @@ type AuthCtx struct { userlookup func(string) (*user.User, error) // eg. os/user.Lookup() } -func NewAuthCtx(/*reader func(string) ([]byte, error), userlookup func(string) (*user.User, error)*/) (ret *AuthCtx) { - ret = &AuthCtx{ioutil.ReadFile, user.Lookup} - return +func NewAuthCtx( /*reader func(string) ([]byte, error), userlookup func(string) (*user.User, error)*/ ) (ret *AuthCtx) { + ret = &AuthCtx{ioutil.ReadFile, user.Lookup} + return } // --------- System passwd/shadow auth routine(s) -------------- diff --git a/auth_test.go b/auth_test.go index 3672607..cfcec60 100644 --- a/auth_test.go +++ b/auth_test.go @@ -21,19 +21,29 @@ disableduser:!:18310::::::` dummyAuthTokenFile = "hostA:abcdefg\nhostB:wxyz\n" + dummyXsPasswdFile = `#username:salt:authCookie +bobdobbs:$2a$12$9vqGkFqikspe/2dTARqu1O:$2a$12$9vqGkFqikspe/2dTARqu1OuDKCQ/RYWsnaFjmi.HtmECRkxcZ.kBK +notbob:$2a$12$cZpiYaq5U998cOkXzRKdyu:$2a$12$cZpiYaq5U998cOkXzRKdyuJ2FoEQyVLa3QkYdPQk74VXMoAzhvuP6 +` + testGoodUsers = []userVerifs{ {"johndoe", "testpass", true}, {"joebloggs", "testpass2", true}, {"johndoe", "badpass", false}, } + testXsPasswdUsers = []userVerifs{ + {"bobdobbs", "praisebob", true}, + {"notbob", "imposter", false}, + } + userlookup_arg_u string readfile_arg_f string ) func newMockAuthCtx(reader func(string) ([]byte, error), userlookup func(string) (*user.User, error)) (ret *AuthCtx) { - ret = &AuthCtx{reader, userlookup} - return + ret = &AuthCtx{reader, userlookup} + return } func _mock_user_Lookup(username string) (*user.User, error) { @@ -52,6 +62,10 @@ func _mock_ioutil_ReadFile(f string) ([]byte, error) { fmt.Println(" [mocking ReadFile(\"/etc/shadow\")]") return []byte(dummyShadowA), nil } + if f == "/etc/xs.passwd" { + fmt.Println(" [mocking ReadFile(\"/etc/xs.passwd\")]") + return []byte(dummyXsPasswdFile), nil + } if strings.Contains(f, "/.xs_id") { fmt.Println(" [mocking ReadFile(\".xs_id\")]") return []byte(dummyAuthTokenFile), nil @@ -146,3 +160,53 @@ func TestAuthUserByTokenSucceedsWithMatchedUserAndToken(t *testing.T) { t.Fatal("failed with valid user and token") } } + +func TestAuthUserByPasswdFailsOnEmptyFile(t *testing.T) { + ctx := newMockAuthCtx(_mock_ioutil_ReadFileEmpty, _mock_user_Lookup) + userlookup_arg_u = "bobdobbs" + readfile_arg_f = "/etc/xs.passwd" + stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "praisebob", readfile_arg_f) + if stat { + t.Fatal("failed to fail with missing xs.passwd file") + } +} + +func TestAuthUserByPasswdFailsOnBadAuth(t *testing.T) { + ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup) + userlookup_arg_u = "bobdobbs" + readfile_arg_f = "/etc/xs.passwd" + stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "wrongpass", readfile_arg_f) + if stat { + t.Fatal("failed to fail with valid user, incorrect passwd in xs.passwd file") + } +} + +func TestAuthUserByPasswdFailsOnBadUser(t *testing.T) { + ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup) + userlookup_arg_u = "bobdobbs" + readfile_arg_f = "/etc/xs.passwd" + stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "theotherbob", readfile_arg_f) + if stat { + t.Fatal("failed to fail on invalid user vs. xs.passwd file") + } +} + +func TestAuthUserByPasswdPassesOnGoodAuth(t *testing.T) { + ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup) + userlookup_arg_u = "bobdobbs" + readfile_arg_f = "/etc/xs.passwd" + stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "praisebob", readfile_arg_f) + if !stat { + t.Fatal("failed on valid user w/correct passwd in xs.passwd file") + } +} + +func TestAuthUserByPasswdPassesOnOtherGoodAuth(t *testing.T) { + ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup) + userlookup_arg_u = "notbob" + readfile_arg_f = "/etc/xs.passwd" + stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "imposter", readfile_arg_f) + if !stat { + t.Fatal("failed on valid user 2nd entry w/correct passwd in xs.passwd file") + } +}