mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-23 06:20:48 +02:00
* sftp: reject empty passwords in PasswordAuthenticator FileStore.ValidatePassword already refuses a zero-length stored or supplied password, but the guard belongs at the authenticator too: an empty password is never valid, and checking before the store call keeps any user.Store implementation without its own empty-secret check from matching on zero-length input. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * sftp: keep the brute-force delay on empty-password failures The early rejection returned before the shared failure path, so an empty password failed instantly while other failures slept 100-199 ms. Folding the length check into the store call keeps the store untouched and every failed attempt equally slow. --------- Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
44 lines
1.3 KiB
Go
44 lines
1.3 KiB
Go
package auth
|
|
|
|
import "testing"
|
|
|
|
// acceptAllStore records whether the store was consulted and accepts any password.
|
|
type acceptAllStore struct {
|
|
stubStore
|
|
called bool
|
|
}
|
|
|
|
func (s *acceptAllStore) ValidatePassword(string, []byte) bool {
|
|
s.called = true
|
|
return true
|
|
}
|
|
|
|
// An empty password must be rejected before the store is consulted, so a store
|
|
// without its own empty-secret check cannot authenticate on zero-length input.
|
|
func TestPasswordAuthenticatorRejectsEmptyPassword(t *testing.T) {
|
|
store := &acceptAllStore{}
|
|
a := NewPasswordAuthenticator(store, true)
|
|
|
|
for _, password := range [][]byte{nil, {}} {
|
|
if _, err := a.Authenticate(&fakeConnMetadata{user: "alice"}, password); err == nil {
|
|
t.Fatalf("expected empty password %v to be rejected", password)
|
|
}
|
|
}
|
|
if store.called {
|
|
t.Fatal("store must not be consulted for an empty password")
|
|
}
|
|
}
|
|
|
|
func TestPasswordAuthenticatorConsultsStore(t *testing.T) {
|
|
store := &acceptAllStore{}
|
|
a := NewPasswordAuthenticator(store, true)
|
|
|
|
perms, err := a.Authenticate(&fakeConnMetadata{user: "alice"}, []byte("s3cret"))
|
|
if err != nil {
|
|
t.Fatalf("expected non-empty password to reach the store: %v", err)
|
|
}
|
|
if perms.Extensions["username"] != "alice" {
|
|
t.Fatalf("expected username extension alice, got %q", perms.Extensions["username"])
|
|
}
|
|
}
|