downstream: add support for ANONYMOUS SASL auth
This clears any saved SASL credentials. Closes: https://todo.sr.ht/~emersion/soju/198
This commit is contained in:
parent
92796248d2
commit
b3be05559b
@ -685,7 +685,7 @@ func (dc *downstreamConn) handleMessageUnregistered(ctx context.Context, msg *ir
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unexpected SASL mechanism %q", credentials.mechanism))
|
err = fmt.Errorf("unsupported SASL mechanism")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -929,6 +929,10 @@ func (dc *downstreamConn) handleAuthenticate(msg *irc.Message) (result *downstre
|
|||||||
dc.sasl.oauthBearer = &options
|
dc.sasl.oauthBearer = &options
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
case "ANONYMOUS":
|
||||||
|
server = sasl.NewAnonymousServer(func(trace string) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
return nil, ircError{&irc.Message{
|
return nil, ircError{&irc.Message{
|
||||||
Prefix: dc.srv.prefix(),
|
Prefix: dc.srv.prefix(),
|
||||||
@ -1065,7 +1069,7 @@ func (dc *downstreamConn) updateSupportedCaps() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if uc := dc.upstream(); uc != nil && uc.supportsSASL("PLAIN") {
|
if uc := dc.upstream(); uc != nil && uc.supportsSASL("PLAIN") {
|
||||||
dc.setSupportedCap("sasl", "PLAIN")
|
dc.setSupportedCap("sasl", "PLAIN,ANONYMOUS")
|
||||||
} else if dc.network != nil {
|
} else if dc.network != nil {
|
||||||
dc.unsetSupportedCap("sasl")
|
dc.unsetSupportedCap("sasl")
|
||||||
}
|
}
|
||||||
@ -2495,33 +2499,53 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
|||||||
credentials, err := dc.handleAuthenticate(msg)
|
credentials, err := dc.handleAuthenticate(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if credentials == nil {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if credentials != nil {
|
if uc.saslClient != nil {
|
||||||
if credentials.mechanism != "PLAIN" {
|
dc.endSASL(&irc.Message{
|
||||||
dc.endSASL(&irc.Message{
|
Prefix: dc.srv.prefix(),
|
||||||
Prefix: dc.srv.prefix(),
|
Command: irc.ERR_SASLFAIL,
|
||||||
Command: irc.ERR_SASLFAIL,
|
Params: []string{dc.nick, "Another authentication attempt is already in progress"},
|
||||||
Params: []string{dc.nick, "Unsupported SASL authentication mechanism"},
|
})
|
||||||
})
|
break
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if uc.saslClient != nil {
|
|
||||||
dc.endSASL(&irc.Message{
|
|
||||||
Prefix: dc.srv.prefix(),
|
|
||||||
Command: irc.ERR_SASLFAIL,
|
|
||||||
Params: []string{dc.nick, "Another authentication attempt is already in progress"},
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch credentials.mechanism {
|
||||||
|
case "PLAIN":
|
||||||
uc.logger.Printf("starting post-registration SASL PLAIN authentication with username %q", credentials.plain.Username)
|
uc.logger.Printf("starting post-registration SASL PLAIN authentication with username %q", credentials.plain.Username)
|
||||||
uc.saslClient = sasl.NewPlainClient("", credentials.plain.Username, credentials.plain.Password)
|
uc.saslClient = sasl.NewPlainClient("", credentials.plain.Username, credentials.plain.Password)
|
||||||
uc.enqueueCommand(dc, &irc.Message{
|
uc.enqueueCommand(dc, &irc.Message{
|
||||||
Command: "AUTHENTICATE",
|
Command: "AUTHENTICATE",
|
||||||
Params: []string{"PLAIN"},
|
Params: []string{"PLAIN"},
|
||||||
})
|
})
|
||||||
|
case "ANONYMOUS":
|
||||||
|
if uc.network.SASL.Mechanism != "" {
|
||||||
|
record := uc.network.Network // copy network record because we'll mutate it
|
||||||
|
record.SASL.Plain.Username = ""
|
||||||
|
record.SASL.Plain.Password = ""
|
||||||
|
record.SASL.External.CertBlob = nil
|
||||||
|
record.SASL.External.PrivKeyBlob = nil
|
||||||
|
record.SASL.Mechanism = ""
|
||||||
|
_, err := dc.user.updateNetwork(ctx, &record)
|
||||||
|
if err != nil {
|
||||||
|
dc.logger.Printf("failed to clear SASL credentials")
|
||||||
|
dc.endSASL(&irc.Message{
|
||||||
|
Prefix: dc.srv.prefix(),
|
||||||
|
Command: irc.ERR_SASLFAIL,
|
||||||
|
Params: []string{dc.nick, "Internal server error"},
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dc.endSASL(nil)
|
||||||
|
default:
|
||||||
|
dc.endSASL(&irc.Message{
|
||||||
|
Prefix: dc.srv.prefix(),
|
||||||
|
Command: irc.ERR_SASLFAIL,
|
||||||
|
Params: []string{dc.nick, "Unsupported SASL authentication mechanism"},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
case "REGISTER", "VERIFY":
|
case "REGISTER", "VERIFY":
|
||||||
// Check number of params here, since we'll use that to save the
|
// Check number of params here, since we'll use that to save the
|
||||||
|
Loading…
Reference in New Issue
Block a user