From c639aac2411f27a55eedfae8c443c2fc517fc53b Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 16 Oct 2020 16:11:43 -0400 Subject: [PATCH 1/3] log the unfolded account name during registration --- irc/accounts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/accounts.go b/irc/accounts.go index 6a2ddd60..388a6006 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -886,7 +886,7 @@ func (am *AccountManager) Verify(client *Client, account string, code string) er if client != nil { nick = client.Nick() } - am.server.logger.Info("accounts", "client", nick, "registered account", casefoldedAccount) + am.server.logger.Info("accounts", "client", nick, "registered account", account) raw.Verified = true clientAccount, err := am.deserializeRawAccount(raw, casefoldedAccount) if err != nil { From cf463778636559f2f5b32e0e179bfa7e97b5c43d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 16 Oct 2020 16:50:02 -0400 Subject: [PATCH 2/3] fix #1332 --- irc/accounts.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/irc/accounts.go b/irc/accounts.go index 388a6006..9fd73186 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -268,10 +268,18 @@ func (am *AccountManager) NickToAccount(nick string) string { if err != nil { return "" } + skel, err := Skeleton(nick) + if err != nil { + return "" + } am.RLock() defer am.RUnlock() - return am.nickToAccount[cfnick] + account := am.nickToAccount[cfnick] + if account != "" { + return account + } + return am.skeletonToAccount[skel] } // given an account, combine stored enforcement method with the config settings @@ -457,7 +465,7 @@ func (am *AccountManager) Register(client *Client, account string, callbackNames defer am.serialCacheUpdateMutex.Unlock() // can't register an account with the same name as a registered nick - if am.NickToAccount(casefoldedAccount) != "" { + if am.NickToAccount(account) != "" { return errAccountAlreadyRegistered } @@ -946,7 +954,11 @@ func (am *AccountManager) SetNickReserved(client *Client, nick string, saUnreser account := client.Account() if saUnreserve { // unless this is a sadrop: - account = am.NickToAccount(cfnick) + account := func() string { + am.RLock() + defer am.RUnlock() + return am.nickToAccount[cfnick] + }() if account == "" { // nothing to do return nil From 347cc30ed4ec36dbe10c8500941a6ea7f6a1fd50 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 16 Oct 2020 16:57:33 -0400 Subject: [PATCH 3/3] fix a potential conflict with delayed verification of confusable names 0. Enable email verification 1. Register `dog` 2. Register `d0g` 3. Verify `dog` 4. Verify `d0g`: verification succeeds but the nick cannot be used --- irc/accounts.go | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/irc/accounts.go b/irc/accounts.go index 9fd73186..61e83b79 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -830,6 +830,34 @@ func (am *AccountManager) Verify(client *Client, account string, code string) er am.serialCacheUpdateMutex.Lock() defer am.serialCacheUpdateMutex.Unlock() + // do a final check for confusability (in case someone already verified + // a confusable identifier): + var unfoldedName string + err = am.server.store.View(func(tx *buntdb.Tx) error { + unfoldedName, err = tx.Get(accountNameKey) + return err + }) + if err != nil { + err = errAccountDoesNotExist + return + } + skeleton, err = Skeleton(unfoldedName) + if err != nil { + err = errAccountDoesNotExist + return + } + err = func() error { + am.RLock() + defer am.RUnlock() + if _, ok := am.skeletonToAccount[skeleton]; ok { + return errConfusableIdentifier + } + return nil + }() + if err != nil { + return + } + err = am.server.store.Update(func(tx *buntdb.Tx) error { raw, err = am.loadRawAccount(tx, casefoldedAccount) if err == errAccountDoesNotExist { @@ -878,7 +906,6 @@ func (am *AccountManager) Verify(client *Client, account string, code string) er }) if err == nil { - skeleton, _ = Skeleton(raw.Name) am.Lock() am.nickToAccount[casefoldedAccount] = casefoldedAccount am.skeletonToAccount[skeleton] = casefoldedAccount