Commit 62ccd5a5 authored by ale's avatar ale
Browse files

Log all authentication requests

parent 65647f60
......@@ -389,7 +389,14 @@ func (s *Server) Authenticate(ctx context.Context, req *auth.Request) *auth.Resp
return newError()
}
resp := s.authenticateUser(req, serviceConfig, user)
resp, err := s.authenticateUser(req, serviceConfig, user)
if err != nil {
resp = newError()
log.Printf("auth: user=%s status=%s error=%s", req.Username, resp.Status.String(), err)
} else {
// Log the request and response.
log.Printf("auth: user=%s status=%s", req.Username, resp.Status.String())
}
// Notify blacklists of the result.
serviceConfig.notifyBlacklists(user, req, resp)
......@@ -397,19 +404,23 @@ func (s *Server) Authenticate(ctx context.Context, req *auth.Request) *auth.Resp
return resp
}
func (s *Server) authenticateUser(req *auth.Request, serviceConfig *ServiceConfig, user *User) *auth.Response {
// Authenticate a user. Returning an error should result in an
// AuthResponse with StatusError.
func (s *Server) authenticateUser(req *auth.Request, serviceConfig *ServiceConfig, user *User) (resp *auth.Response, err error) {
// Verify different credentials depending on whether the user
// has 2FA enabled or not, and on whether the service itself
// supports challenge-response authentication.
var resp *auth.Response
if serviceConfig.Enforce2FA || user.Has2FA() {
if serviceConfig.ChallengeResponse {
resp = s.authenticateUserWith2FA(user, req)
resp, err = s.authenticateUserWith2FA(user, req)
} else {
resp = s.authenticateUserWithASP(user, req)
resp, err = s.authenticateUserWithASP(user, req)
}
} else {
resp = s.authenticateUserWithPassword(user, req)
resp, err = s.authenticateUserWithPassword(user, req)
}
if err != nil {
return
}
// Process the response through filters (device info checks,
......@@ -425,34 +436,30 @@ func (s *Server) authenticateUser(req *auth.Request, serviceConfig *ServiceConfi
if resp.Status == auth.StatusOK {
resp.UserInfo = user.UserInfo()
}
return resp
return
}
func (s *Server) authenticateUserWithPassword(user *User, req *auth.Request) *auth.Response {
func (s *Server) authenticateUserWithPassword(user *User, req *auth.Request) (*auth.Response, error) {
// Ok we only need to check the password here.
if checkPassword(req.Password, user.EncryptedPassword) {
return newOK()
return newOK(), nil
}
log.Printf("wrong password")
return newError()
return nil, errors.New("wrong password")
}
func (s *Server) authenticateUserWithASP(user *User, req *auth.Request) *auth.Response {
func (s *Server) authenticateUserWithASP(user *User, req *auth.Request) (*auth.Response, error) {
for _, asp := range user.AppSpecificPasswords {
if asp.Service == req.Service && checkPassword(req.Password, asp.EncryptedPassword) {
return newOK()
return newOK(), nil
}
}
log.Printf("wrong app-specific password")
return newError()
return nil, errors.New("wrong app-specific password")
}
func (s *Server) authenticateUserWith2FA(user *User, req *auth.Request) *auth.Response {
func (s *Server) authenticateUserWith2FA(user *User, req *auth.Request) (*auth.Response, error) {
// First of all verify the password.
if !checkPassword(req.Password, user.EncryptedPassword) {
log.Printf("wrong password")
return newError()
return nil, errors.New("wrong password")
}
// If the request contains one of the 2FA attributes, verify
......@@ -462,16 +469,14 @@ func (s *Server) authenticateUserWith2FA(user *User, req *auth.Request) *auth.Re
switch {
case req.U2FResponse != nil:
if user.HasU2F() && s.checkU2F(user, req.U2FResponse) {
return newOK()
return newOK(), nil
}
log.Printf("bad U2F response")
return newError()
return nil, errors.New("bad U2F response")
case req.OTP != "":
if user.HasOTP() && checkOTP(req.OTP, user.TOTPSecret) {
return newOK()
return newOK(), nil
}
log.Printf("bad OTP")
return newError()
return nil, errors.New("bad OTP")
default:
resp := &auth.Response{
Status: auth.StatusInsufficientCredentials,
......@@ -480,13 +485,13 @@ func (s *Server) authenticateUserWith2FA(user *User, req *auth.Request) *auth.Re
resp.TFAMethod = auth.TFAMethodU2F
signReq, err := s.u2fSignRequest(user, req.U2FAppID)
if err != nil {
return newError()
return nil, err
}
resp.U2FSignRequest = signReq
} else if user.HasOTP() {
resp.TFAMethod = auth.TFAMethodOTP
}
return resp
return resp, nil
}
}
......
......@@ -11,12 +11,12 @@ import (
)
// Inject an interface for testing purposes.
type userMetaDB interface {
type checkDeviceClient interface {
CheckDevice(context.Context, string, *auth.DeviceInfo) (bool, error)
}
type deviceFilter struct {
client userMetaDB
client checkDeviceClient
}
var usermetadbTimeout = 3 * time.Second
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment