mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 10:42:52 +01:00
fix a bug
In the previous commit, the client would receive a failure message but would actually remain logged in after an authzid/authcid mismatch. This was a correctness rather than a security issue, but now it's fixed so that the client never logs in in the first place.
This commit is contained in:
parent
c8ccf94936
commit
33c8b2177e
@ -971,7 +971,7 @@ func (am *AccountManager) ChannelsForAccount(account string) (channels []string)
|
|||||||
return unmarshalRegisteredChannels(channelStr)
|
return unmarshalRegisteredChannels(channelStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) AuthenticateByCertFP(client *Client) error {
|
func (am *AccountManager) AuthenticateByCertFP(client *Client, authzid string) error {
|
||||||
if client.certfp == "" {
|
if client.certfp == "" {
|
||||||
return errAccountInvalidCredentials
|
return errAccountInvalidCredentials
|
||||||
}
|
}
|
||||||
@ -991,6 +991,10 @@ func (am *AccountManager) AuthenticateByCertFP(client *Client) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if authzid != "" && authzid != account {
|
||||||
|
return errAuthzidAuthcidMismatch
|
||||||
|
}
|
||||||
|
|
||||||
// ok, we found an account corresponding to their certificate
|
// ok, we found an account corresponding to their certificate
|
||||||
clientAccount, err := am.LoadAccount(account)
|
clientAccount, err := am.LoadAccount(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,6 +27,7 @@ var (
|
|||||||
errAccountVerificationInvalidCode = errors.New("Invalid account verification code")
|
errAccountVerificationInvalidCode = errors.New("Invalid account verification code")
|
||||||
errAccountUpdateFailed = errors.New(`Error while updating your account information`)
|
errAccountUpdateFailed = errors.New(`Error while updating your account information`)
|
||||||
errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`)
|
errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`)
|
||||||
|
errAuthzidAuthcidMismatch = errors.New(`authcid and authzid must be the same`)
|
||||||
errCallbackFailed = errors.New("Account verification could not be sent")
|
errCallbackFailed = errors.New("Account verification could not be sent")
|
||||||
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
|
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
|
||||||
errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account")
|
errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account")
|
||||||
|
@ -446,13 +446,14 @@ func authPlainHandler(server *Server, client *Client, mechanism string, value []
|
|||||||
}
|
}
|
||||||
|
|
||||||
func authErrorToMessage(server *Server, err error) (msg string) {
|
func authErrorToMessage(server *Server, err error) (msg string) {
|
||||||
if err == errAccountDoesNotExist || err == errAccountUnverified || err == errAccountInvalidCredentials {
|
switch err {
|
||||||
msg = err.Error()
|
case errAccountDoesNotExist, errAccountUnverified, errAccountInvalidCredentials, errAuthzidAuthcidMismatch:
|
||||||
} else {
|
return err.Error()
|
||||||
|
default:
|
||||||
|
// don't expose arbitrary error messages to the user
|
||||||
server.logger.Error("internal", "sasl authentication failure", err.Error())
|
server.logger.Error("internal", "sasl authentication failure", err.Error())
|
||||||
msg = "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTHENTICATE EXTERNAL
|
// AUTHENTICATE EXTERNAL
|
||||||
@ -462,24 +463,27 @@ func authExternalHandler(server *Server, client *Client, mechanism string, value
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.accounts.AuthenticateByCertFP(client)
|
// EXTERNAL doesn't carry an authentication ID (this is determined from the
|
||||||
|
// certificate), but does carry an optional authorization ID.
|
||||||
|
var authzid string
|
||||||
|
var err error
|
||||||
|
if len(value) != 0 {
|
||||||
|
authzid, err = CasefoldName(string(value))
|
||||||
|
if err != nil {
|
||||||
|
err = errAuthzidAuthcidMismatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
err = server.accounts.AuthenticateByCertFP(client, authzid)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := authErrorToMessage(server, err)
|
msg := authErrorToMessage(server, err)
|
||||||
rb.Add(nil, server.name, ERR_SASLFAIL, client.nick, fmt.Sprintf("%s: %s", client.t("SASL authentication failed"), client.t(msg)))
|
rb.Add(nil, server.name, ERR_SASLFAIL, client.nick, fmt.Sprintf("%s: %s", client.t("SASL authentication failed"), client.t(msg)))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXTERNAL doesn't carry an authentication ID (this is determined from the
|
|
||||||
// certificate), but does carry an optional authorization ID.
|
|
||||||
if len(value) != 0 {
|
|
||||||
authcid := client.Account()
|
|
||||||
cfAuthzid, err := CasefoldName(string(value))
|
|
||||||
if err != nil || cfAuthzid != authcid {
|
|
||||||
rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(), client.t("SASL authentication failed: authcid and authzid should be the same"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendSuccessfulAccountAuth(client, rb, false, true)
|
sendSuccessfulAccountAuth(client, rb, false, true)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ func nsIdentifyHandler(server *Server, client *Client, command string, params []
|
|||||||
|
|
||||||
// try certfp
|
// try certfp
|
||||||
if !loginSuccessful && client.certfp != "" {
|
if !loginSuccessful && client.certfp != "" {
|
||||||
err := server.accounts.AuthenticateByCertFP(client)
|
err := server.accounts.AuthenticateByCertFP(client, "")
|
||||||
loginSuccessful = (err == nil)
|
loginSuccessful = (err == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user