2016-07-21 20:55:31 +00:00
|
|
|
package irc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SASLResult struct {
|
|
|
|
Failed bool
|
|
|
|
Err error
|
|
|
|
}
|
|
|
|
|
2019-03-01 10:20:59 +00:00
|
|
|
// Check if a space-separated list of arguments contains a value.
|
|
|
|
func listContains(list string, value string) bool {
|
|
|
|
for _, arg_name := range strings.Split(strings.TrimSpace(list), " ") {
|
|
|
|
if arg_name == value {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-02-11 15:40:29 +00:00
|
|
|
func (irc *Connection) setupSASLCallbacks(result chan<- *SASLResult) (callbacks []CallbackID) {
|
|
|
|
id := irc.AddCallback("CAP", func(e *Event) {
|
2016-07-21 20:55:31 +00:00
|
|
|
if len(e.Arguments) == 3 {
|
|
|
|
if e.Arguments[1] == "LS" {
|
2019-03-01 10:20:59 +00:00
|
|
|
if !listContains(e.Arguments[2], "sasl") {
|
2016-07-21 20:55:31 +00:00
|
|
|
result <- &SASLResult{true, errors.New("no SASL capability " + e.Arguments[2])}
|
|
|
|
}
|
|
|
|
}
|
2019-03-01 10:20:59 +00:00
|
|
|
if e.Arguments[1] == "ACK" && listContains(e.Arguments[2], "sasl") {
|
2021-07-03 13:59:00 +00:00
|
|
|
if irc.SASLMech != "PLAIN" && irc.SASLMech != "EXTERNAL" {
|
|
|
|
result <- &SASLResult{true, errors.New("only PLAIN and EXTERNAL supported")}
|
2016-07-21 20:55:31 +00:00
|
|
|
}
|
|
|
|
irc.SendRaw("AUTHENTICATE " + irc.SASLMech)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"CAP", id})
|
|
|
|
|
|
|
|
id = irc.AddCallback("AUTHENTICATE", func(e *Event) {
|
2021-07-03 13:59:00 +00:00
|
|
|
if irc.SASLMech == "EXTERNAL" {
|
|
|
|
irc.SendRaw("AUTHENTICATE +")
|
|
|
|
return
|
|
|
|
}
|
2016-07-21 20:55:31 +00:00
|
|
|
str := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s\x00%s\x00%s", irc.SASLLogin, irc.SASLLogin, irc.SASLPassword)))
|
|
|
|
irc.SendRaw("AUTHENTICATE " + str)
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"AUTHENTICATE", id})
|
|
|
|
|
|
|
|
id = irc.AddCallback("901", func(e *Event) {
|
2016-07-21 20:55:31 +00:00
|
|
|
irc.SendRaw("CAP END")
|
|
|
|
irc.SendRaw("QUIT")
|
|
|
|
result <- &SASLResult{true, errors.New(e.Arguments[1])}
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"901", id})
|
|
|
|
|
|
|
|
id = irc.AddCallback("902", func(e *Event) {
|
2016-07-21 20:55:31 +00:00
|
|
|
irc.SendRaw("CAP END")
|
|
|
|
irc.SendRaw("QUIT")
|
|
|
|
result <- &SASLResult{true, errors.New(e.Arguments[1])}
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"902", id})
|
|
|
|
|
|
|
|
id = irc.AddCallback("903", func(e *Event) {
|
2016-07-21 20:55:31 +00:00
|
|
|
result <- &SASLResult{false, nil}
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"903", id})
|
|
|
|
|
|
|
|
id = irc.AddCallback("904", func(e *Event) {
|
2016-07-21 20:55:31 +00:00
|
|
|
irc.SendRaw("CAP END")
|
|
|
|
irc.SendRaw("QUIT")
|
|
|
|
result <- &SASLResult{true, errors.New(e.Arguments[1])}
|
|
|
|
})
|
2021-02-11 15:40:29 +00:00
|
|
|
callbacks = append(callbacks, CallbackID{"904", id})
|
|
|
|
|
|
|
|
return
|
2016-07-21 20:55:31 +00:00
|
|
|
}
|