Skip to content

Commit

Permalink
Test coverage for login attempts.
Browse files Browse the repository at this point in the history
  • Loading branch information
russjones committed Oct 11, 2017
1 parent 6a1c045 commit 3d0ce56
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/auth/tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,10 @@ func TunClientStorage(storage utils.AddrStorage) TunClientOption {
}

// TunDisableRefresh will disable refreshing the list of auth servers. This is
// required when requesting user certificates.
// required when requesting user certificates because we only allow a single
// HTTP request to be made over the tunnel. This is because each request does
// keyAuth, and for situations like password+otp where the OTP token is invalid
// after the first use, that means all other requests would fail.
func TunDisableRefresh() TunClientOption {
return func(t *TunClient) {
t.disableRefresh = true
Expand Down
70 changes: 70 additions & 0 deletions lib/auth/tun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,76 @@ func (s *TunSuite) TestSessionsBadPassword(c *C) {
c.Assert(ws, IsNil)
}

// TestLoginAttempts makes sure the login attempt counter is incremented and
// reset correctly.
func (s *TunSuite) TestLoginAttempts(c *C) {
c.Assert(s.a.UpsertCertAuthority(
suite.NewTestCA(services.UserCA, "localhost")), IsNil)

user := "system-test"
pass := []byte("system-abc123")
rawSecret := "def456"
otpSecret := base32.StdEncoding.EncodeToString([]byte(rawSecret))

err := s.a.UpsertPassword(user, pass)
c.Assert(err, IsNil)

err = s.a.UpsertTOTP(user, otpSecret)
c.Assert(err, IsNil)

otpURL, _, err := s.a.GetOTPData(user)
c.Assert(err, IsNil)

// make sure label in url is correct
u, err := url.Parse(otpURL)
c.Assert(err, IsNil)
c.Assert(u.Path, Equals, "/system-test")

// create a valid otp token
validToken, err := totp.GenerateCode(otpSecret, time.Now())
c.Assert(err, IsNil)

// try first to login with an invalid password
authMethod, err := NewWebPasswordAuth(user, []byte("invalid-password"), validToken)
c.Assert(err, IsNil)

clt, err := NewTunClient("test",
[]utils.NetAddr{{AddrNetwork: "tcp", Addr: s.tsrv.Addr()}}, user, authMethod, TunDisableRefresh())
c.Assert(err, IsNil)
c.Assert(err, IsNil)

// we can make any request and don't care about the result. the code keyAuth
// code we care about is run during the ssh handshake.
clt.GetUsers()
err = clt.Close()
c.Assert(err, IsNil)

// should only create a single failed login attempt
loginAttempts, err := s.a.GetUserLoginAttempts(user)
c.Assert(err, IsNil)
c.Assert(loginAttempts, HasLen, 1)

// try again with the correct password
authMethod, err = NewWebPasswordAuth(user, pass, validToken)
c.Assert(err, IsNil)

clt, err = NewTunClient("test",
[]utils.NetAddr{{AddrNetwork: "tcp", Addr: s.tsrv.Addr()}}, user, authMethod, TunDisableRefresh())
c.Assert(err, IsNil)
c.Assert(err, IsNil)

// once again, we can make any request and don't care about the result. the
// code keyAuth code we care about is run during the ssh handshake.
clt.GetUsers()
err = clt.Close()
c.Assert(err, IsNil)

// login was successful, attempts should be reset back to 0
loginAttempts, err = s.a.GetUserLoginAttempts(user)
c.Assert(err, IsNil)
c.Assert(loginAttempts, HasLen, 0)
}

func (s *TunSuite) TestFailover(c *C) {
node := newServer(
services.KindNode,
Expand Down

0 comments on commit 3d0ce56

Please sign in to comment.