diff --git a/AUTHORS b/AUTHORS index 94103979f..4e1ebe01f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,6 +65,7 @@ Tim Abell Tobias Nygren Tomas Cerveny Tully Robinson +Tyler Brazier Veeti Paananen Vil Brekin Yannic A. diff --git a/cmd/syncthing/gui_auth.go b/cmd/syncthing/gui_auth.go index 869302543..1344a43e4 100644 --- a/cmd/syncthing/gui_auth.go +++ b/cmd/syncthing/gui_auth.go @@ -15,6 +15,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/sync" "golang.org/x/crypto/bcrypt" ) @@ -24,6 +25,13 @@ var ( sessionsMut = sync.NewMutex() ) +func emitLoginAttempt(success bool, username string) { + events.Default.Log(events.LoginAttempt, map[string]interface{}{ + "success": success, + "username": username, + }) +} + func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguration, next http.Handler) http.Handler { apiKey := cfg.APIKey() return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -70,12 +78,15 @@ func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguratio return } - if string(fields[0]) != cfg.User { + username := string(fields[0]) + if username != cfg.User { + emitLoginAttempt(false, username) error() return } if err := bcrypt.CompareHashAndPassword([]byte(cfg.Password), fields[1]); err != nil { + emitLoginAttempt(false, username) error() return } @@ -90,6 +101,7 @@ func basicAuthAndSessionMiddleware(cookieName string, cfg config.GUIConfiguratio MaxAge: 0, }) + emitLoginAttempt(true, username) next.ServeHTTP(w, r) }) } diff --git a/cmd/syncthing/verbose.go b/cmd/syncthing/verbose.go index 7fd215f00..1d830479b 100644 --- a/cmd/syncthing/verbose.go +++ b/cmd/syncthing/verbose.go @@ -149,6 +149,16 @@ func (s *verboseSvc) formatEvent(ev events.Event) string { data := ev.Data.(map[string][]string) newRelays := data["new"] return fmt.Sprintf("Relay state changed; connected relay(s) are %s.", strings.Join(newRelays, ", ")) + case events.LoginAttempt: + data := ev.Data.(map[string]interface{}) + username := data["username"].(string) + var success string + if data["success"].(bool) { + success = "successful" + } else { + success = "failed" + } + return fmt.Sprintf("Login %s for username %s.", success, username) } diff --git a/lib/events/events.go b/lib/events/events.go index bd0161ce4..8c456d385 100644 --- a/lib/events/events.go +++ b/lib/events/events.go @@ -41,6 +41,7 @@ const ( FolderScanProgress ExternalPortMappingChanged RelayStateChanged + LoginAttempt AllEvents = (1 << iota) - 1 ) @@ -93,6 +94,8 @@ func (t EventType) String() string { return "ExternalPortMappingChanged" case RelayStateChanged: return "RelayStateChanged" + case LoginAttempt: + return "LoginAttempt" default: return "Unknown" }