3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00

prevent nick reservation land-grabs

This commit is contained in:
Shivaram Lingamneni 2019-02-05 19:03:42 -05:00
parent 726dbedab6
commit 775ead700f
4 changed files with 31 additions and 26 deletions

View File

@ -306,8 +306,16 @@ func (am *AccountManager) Register(client *Client, account string, callbackNames
return errAccountAlreadyRegistered
}
// can't register a guest nickname
config := am.server.AccountConfig()
// if nick reservation is enabled, you can only register your current nickname
// as an account; this prevents "land-grab" situations where someone else
// registers your nick out from under you and then NS GHOSTs you
// n.b. client is nil during a SAREGISTER:
if config.NickReservation.Enabled && client != nil && client.Nick() != account {
return errAccountMustHoldNick
}
// can't register a guest nickname
renamePrefix := strings.ToLower(config.NickReservation.RenamePrefix)
if renamePrefix != "" && strings.HasPrefix(casefoldedAccount, renamePrefix) {
return errAccountAlreadyRegistered

View File

@ -9,14 +9,14 @@ import "errors"
// Runtime Errors
var (
errAccountAlreadyRegistered = errors.New("Account already exists")
errAccountAlreadyVerified = errors.New("Account is already verified")
errAccountAlreadyRegistered = errors.New(`Account already exists`)
errAccountAlreadyVerified = errors.New(`Account is already verified`)
errAccountCantDropPrimaryNick = errors.New("Can't unreserve primary nickname")
errAccountCreation = errors.New("Account could not be created")
errAccountCredUpdate = errors.New("Could not update password hash to new method")
errAccountDoesNotExist = errors.New("Account does not exist")
errAccountInvalidCredentials = errors.New("Invalid account credentials")
errAccountBadPassphrase = errors.New("Passphrase contains forbidden characters or is otherwise invalid")
errAccountBadPassphrase = errors.New(`Passphrase contains forbidden characters or is otherwise invalid`)
errAccountNickReservationFailed = errors.New("Could not (un)reserve nick")
errAccountNotLoggedIn = errors.New("You're not logged into an account")
errAccountTooManyNicks = errors.New("Account has too many reserved nicks")
@ -24,8 +24,9 @@ var (
errAccountVerificationFailed = errors.New("Account verification failed")
errAccountVerificationInvalidCode = errors.New("Invalid account verification code")
errAccountUpdateFailed = errors.New("Error while updating your account information")
errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`)
errCallbackFailed = errors.New("Account verification could not be sent")
errCertfpAlreadyExists = errors.New("An account already exists with your certificate")
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
errChannelAlreadyRegistered = errors.New("Channel is already registered")
errChannelNameInUse = errors.New("Channel name in use")
errInvalidChannelName = errors.New("Invalid channel name")

View File

@ -153,19 +153,7 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
err = server.accounts.Register(client, account, callbackNamespace, callbackValue, passphrase, certfp)
if err != nil {
msg := "Unknown"
code := ERR_UNKNOWNERROR
if err == errCertfpAlreadyExists {
msg = "An account already exists for your certificate fingerprint"
} else if err == errAccountAlreadyRegistered {
msg = "Account already exists"
code = ERR_ACCOUNT_ALREADY_EXISTS
} else if err == errAccountBadPassphrase {
msg = "Passphrase contains forbidden characters or is otherwise invalid"
}
if err == errAccountAlreadyRegistered || err == errAccountCreation || err == errCertfpAlreadyExists {
msg = err.Error()
}
msg, code := registrationErrorToMessageAndCode(err)
rb.Add(nil, server.name, code, nick, "ACC", "REGISTER", client.t(msg))
return false
}
@ -186,6 +174,21 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
return false
}
func registrationErrorToMessageAndCode(err error) (message, numeric string) {
// default responses: let's be risk-averse about displaying internal errors
// to the clients, especially for something as sensitive as accounts
message = `Could not register`
numeric = ERR_UNKNOWNERROR
switch err {
case errAccountAlreadyRegistered, errAccountAlreadyVerified:
message = err.Error()
numeric = ERR_ACCOUNT_ALREADY_EXISTS
case errAccountCreation, errAccountMustHoldNick, errAccountBadPassphrase, errCertfpAlreadyExists:
message = err.Error()
}
return
}
// helper function to dispatch messages when a client successfully registers
func sendSuccessfulRegResponse(client *Client, rb *ResponseBuffer, forNS bool) {
if forNS {

View File

@ -376,14 +376,7 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
// details could not be stored and relevant numerics have been dispatched, abort
if err != nil {
errMsg := client.t("Could not register")
if err == errCertfpAlreadyExists {
errMsg = client.t("An account already exists for your certificate fingerprint")
} else if err == errAccountAlreadyRegistered || err == errAccountAlreadyVerified {
errMsg = client.t("Account already exists")
} else if err == errAccountBadPassphrase {
errMsg = client.t("Passphrase contains forbidden characters or is otherwise invalid")
}
errMsg, _ := registrationErrorToMessageAndCode(err)
nsNotice(rb, errMsg)
return
}