diff --git a/gencapdefs.py b/gencapdefs.py index 2f9e642b..e1cfbc7f 100644 --- a/gencapdefs.py +++ b/gencapdefs.py @@ -219,12 +219,6 @@ CAPDEFS = [ url="https://github.com/ircv3/ircv3-specifications/pull/527", standard="proposed IRCv3", ), - CapDef( - identifier="Bearer", - name="draft/bearer", - url="https://gist.github.com/slingamn/4fabc7a3d5f335da7bb313a7f0648f37", - standard="proposed IRCv3", - ), ] def validate_defs(): diff --git a/irc/accounts.go b/irc/accounts.go index ffdb0179..87a1d0c2 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -20,7 +20,6 @@ import ( "github.com/tidwall/buntdb" "github.com/xdg-go/scram" - "github.com/ergochat/ergo/irc/caps" "github.com/ergochat/ergo/irc/connection_limits" "github.com/ergochat/ergo/irc/email" "github.com/ergochat/ergo/irc/migrations" @@ -1398,10 +1397,6 @@ func (am *AccountManager) AuthenticateByPassphrase(client *Client, accountName s } } - if strings.HasPrefix(accountName, caps.BearerTokenPrefix) { - return am.AuthenticateByBearerToken(client, strings.TrimPrefix(accountName, caps.BearerTokenPrefix), passphrase) - } - if throttled, remainingTime := client.checkLoginThrottle(); throttled { return &ThrottleError{remainingTime} } @@ -1448,11 +1443,14 @@ func (am *AccountManager) AuthenticateByBearerToken(client *Client, tokenType, t func (am *AccountManager) AuthenticateByOAuthBearer(client *Client, opts oauth2.OAuthBearerOptions) (err error) { config := am.server.Config() - // we need to check this here since we can get here via SASL PLAIN: if !config.Accounts.OAuth2.Enabled { return errFeatureDisabled } + if throttled, remainingTime := client.checkLoginThrottle(); throttled { + return &ThrottleError{remainingTime} + } + var username string if config.Accounts.AuthScript.Enabled && config.Accounts.OAuth2.AuthScript { username, err = am.authenticateByOAuthBearerScript(client, config, opts) @@ -2220,6 +2218,7 @@ var ( "EXTERNAL": authExternalHandler, "SCRAM-SHA-256": authScramHandler, "OAUTHBEARER": authOauthBearerHandler, + "IRCV3BEARER": authIRCv3BearerHandler, } ) diff --git a/irc/caps/constants.go b/irc/caps/constants.go index f8ad3c48..57f088e3 100644 --- a/irc/caps/constants.go +++ b/irc/caps/constants.go @@ -64,10 +64,6 @@ const ( BotTagName = "bot" // https://ircv3.net/specs/extensions/chathistory ChathistoryTargetsBatchType = "draft/chathistory-targets" - - // draft/bearer defines this prefix namespace for authcids, enabling tunneling bearer tokens - // in SASL PLAIN: - BearerTokenPrefix = "*bearer*" ) func init() { diff --git a/irc/caps/defs.go b/irc/caps/defs.go index 39464506..18ff5759 100644 --- a/irc/caps/defs.go +++ b/irc/caps/defs.go @@ -7,7 +7,7 @@ package caps const ( // number of recognized capabilities: - numCapabs = 35 + numCapabs = 34 // length of the uint32 array that represents the bitset: bitsetLen = 2 ) @@ -41,10 +41,6 @@ const ( // https://github.com/ircv3/ircv3-specifications/pull/435 AccountRegistration Capability = iota - // Bearer is the proposed IRCv3 capability named "draft/bearer": - // https://gist.github.com/slingamn/4fabc7a3d5f335da7bb313a7f0648f37 - Bearer Capability = iota - // ChannelRename is the draft IRCv3 capability named "draft/channel-rename": // https://ircv3.net/specs/extensions/channel-rename ChannelRename Capability = iota @@ -164,7 +160,6 @@ var ( "cap-notify", "chghost", "draft/account-registration", - "draft/bearer", "draft/channel-rename", "draft/chathistory", "draft/event-playback", diff --git a/irc/config.go b/irc/config.go index 96fa4ef4..ebc6e953 100644 --- a/irc/config.go +++ b/irc/config.go @@ -1402,6 +1402,9 @@ func LoadConfig(filename string) (config *Config, err error) { if config.Accounts.OAuth2.Enabled { saslCapValues = append(saslCapValues, "OAUTHBEARER") } + if config.Accounts.OAuth2.Enabled || config.Accounts.JWTAuth.Enabled { + saslCapValues = append(saslCapValues, "IRCV3BEARER") + } config.Server.capValues[caps.SASL] = strings.Join(saslCapValues, ",") } else { config.Server.supportedCaps.Disable(caps.SASL) @@ -1419,19 +1422,6 @@ func LoadConfig(filename string) (config *Config, err error) { return nil, fmt.Errorf("oauth2 is enabled with auth-script, but no auth-script is enabled") } - var bearerCapValues []string - if config.Accounts.OAuth2.Enabled { - bearerCapValues = append(bearerCapValues, "oauth2") - } - if config.Accounts.JWTAuth.Enabled { - bearerCapValues = append(bearerCapValues, "jwt") - } - if len(bearerCapValues) != 0 { - config.Server.capValues[caps.Bearer] = strings.Join(bearerCapValues, ",") - } else { - config.Server.supportedCaps.Disable(caps.Bearer) - } - if !config.Accounts.Registration.Enabled { config.Server.supportedCaps.Disable(caps.AccountRegistration) } else { diff --git a/irc/handlers.go b/irc/handlers.go index 9031d40b..8b4cd9a1 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -306,6 +306,27 @@ func authPlainHandler(server *Server, client *Client, session *Session, value [] return false } +// AUTHENTICATE IRCV3BEARER +func authIRCv3BearerHandler(server *Server, client *Client, session *Session, value []byte, rb *ResponseBuffer) bool { + defer session.sasl.Clear() + + // \x00 \x00 + splitValue := bytes.SplitN(value, []byte{'\000'}, 3) + if len(splitValue) != 3 { + rb.Add(nil, server.name, ERR_SASLFAIL, client.Nick(), client.t("SASL authentication failed: Invalid auth blob")) + return false + } + + err := server.accounts.AuthenticateByBearerToken(client, string(splitValue[1]), string(splitValue[2])) + if err != nil { + sendAuthErrorResponse(client, rb, err) + return false + } + + sendSuccessfulAccountAuth(nil, client, rb, true) + return false +} + func sendAuthErrorResponse(client *Client, rb *ResponseBuffer, err error) { msg := authErrorToMessage(client.server, err) rb.Add(nil, client.server.name, ERR_SASLFAIL, client.nick, fmt.Sprintf("%s: %s", client.t("SASL authentication failed"), client.t(msg)))