This commit is contained in:
parent
e603295df3
commit
3a6582c722
@ -79,12 +79,6 @@ func (a action) User(session *gopop.Session, username string) error {
|
||||
session.Ctx = tc
|
||||
}
|
||||
log.WithContext(session.Ctx).Debug("POP3 USER received")
|
||||
|
||||
infos := strings.Split(username, "@")
|
||||
if len(infos) > 1 {
|
||||
username = infos[0]
|
||||
}
|
||||
|
||||
log.WithContext(session.Ctx).Debug("POP3 user name normalized")
|
||||
|
||||
session.User = username
|
||||
|
||||
@ -62,3 +62,13 @@ func Test_email(t *testing.T) {
|
||||
fmt.Printf("%s", b.String())
|
||||
|
||||
}
|
||||
|
||||
func TestActionUserPreservesFullEmailIdentifier(t *testing.T) {
|
||||
session := &gopop.Session{}
|
||||
if err := (action{}).User(session, "Alice@Example.com"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if session.User != "Alice@Example.com" {
|
||||
t.Fatalf("POP3 user identifier = %q, want full email identifier", session.User)
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,6 @@ func (s *Session) Auth(mech string) (sasl.Server, error) {
|
||||
}
|
||||
|
||||
func (s *Session) AuthPlain(username, pwd string) error {
|
||||
username = auth.NormalizeAccount(username)
|
||||
user, err := auth.AuthenticateProtocol("smtp", s.RemoteAddress.String(), username, pwd)
|
||||
if err != nil {
|
||||
log.WithContext(s.Ctx).Info("SMTP authentication failed")
|
||||
|
||||
@ -106,3 +106,46 @@ func TestHasAuthRequiresMailboxOwnershipForAdministrators(t *testing.T) {
|
||||
t.Fatal("administrator bypassed mailbox ownership")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProtocolAuthenticationAcceptsConfiguredFullEmailIdentifier(t *testing.T) {
|
||||
oldConfig := config.Instance
|
||||
oldDB := db.Instance
|
||||
config.Instance = &config.Config{
|
||||
DbType: config.DBTypeSQLite,
|
||||
DbDSN: filepath.Join(t.TempDir(), "full-email-auth.db"),
|
||||
Domain: "example.com",
|
||||
Domains: []string{"example.com"},
|
||||
}
|
||||
if err := db.Init(""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if db.Instance != nil && db.Instance != oldDB {
|
||||
_ = db.Instance.Close()
|
||||
}
|
||||
db.Instance = oldDB
|
||||
config.Instance = oldConfig
|
||||
})
|
||||
|
||||
user := models.User{Account: "alice", Name: "Alice"}
|
||||
if err := SetPassword(&user, "CorrectP12"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := db.Instance.Insert(&user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, protocol := range []string{"smtp", "imap", "pop3"} {
|
||||
got, err := AuthenticateProtocol(protocol, "192.0.2.10:12345", " Alice@Example.com ", "CorrectP12")
|
||||
if err != nil {
|
||||
t.Fatalf("%s full email authentication failed: %v", protocol, err)
|
||||
}
|
||||
if got == nil || got.Account != "alice" {
|
||||
t.Fatalf("%s authenticated user = %+v", protocol, got)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := AuthenticateProtocol("imap", "192.0.2.10:12345", "alice@other.example", "CorrectP12"); err == nil {
|
||||
t.Fatal("unconfigured email domain should be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,10 @@ var (
|
||||
)
|
||||
|
||||
func AuthenticateProtocol(protocol string, remoteAddress string, account string, plain string) (*models.User, error) {
|
||||
normalizedAccount := strings.ToLower(NormalizeAccount(account))
|
||||
normalizedAccount := strings.ToLower(strings.TrimSpace(account))
|
||||
if resolvedAccount, err := NormalizeIdentifier(account); err == nil {
|
||||
normalizedAccount = resolvedAccount
|
||||
}
|
||||
normalizedRemote := protocolRemoteHost(remoteAddress)
|
||||
pairKey := hashedProtocolLoginKey("pair", protocol, normalizedRemote, normalizedAccount)
|
||||
accountKey := hashedProtocolLoginKey("account", normalizedAccount)
|
||||
@ -51,7 +54,7 @@ func AuthenticateProtocol(protocol string, remoteAddress string, account string,
|
||||
if protocolPairAttempts.blocked(pairKey) || protocolAccountAttempts.blocked(accountKey) || protocolRemoteAttempts.blocked(remoteKey) {
|
||||
return nil, errors.New("invalid credentials")
|
||||
}
|
||||
user, err := Authenticate(account, plain)
|
||||
user, err := AuthenticateIdentifier(account, plain)
|
||||
if err != nil {
|
||||
protocolPairAttempts.recordFailure(pairKey)
|
||||
protocolAccountAttempts.recordFailure(accountKey)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user