@@ -10,8 +10,10 @@ package irc
1010
1111import (
1212 "bufio"
13+ "bytes"
1314 "crypto/tls"
1415 "crypto/x509"
16+ "encoding/base64"
1517 "expvar"
1618 "fmt"
1719 "io"
@@ -525,6 +527,7 @@ func (bot *ircBot) login() {
525527
526528 bot .isAuthenticating = true
527529
530+ bot .SendRaw ("CAP REQ :sasl" )
528531 // We use the botname as the 'realname', because bot's don't have real names!
529532 bot .SendRaw ("USER " + bot .nick + " 0 * :" + bot .realname )
530533
@@ -541,6 +544,20 @@ func (bot *ircBot) sendPassword() {
541544 bot .Send ("NickServ" , "identify " + bot .password )
542545}
543546
547+ func (bot * ircBot ) sendSaslStart () {
548+ bot .SendRaw ("AUTHENTICATE PLAIN" )
549+ }
550+
551+ func (bot * ircBot ) sendSaslPass () {
552+ out := bytes .Join ([][]byte {[]byte (bot .nick ), []byte (bot .nick ), []byte (bot .password )}, []byte {0 })
553+ encpass := base64 .StdEncoding .EncodeToString (out )
554+ bot .SendRaw ("AUTHENTICATE " + encpass )
555+ }
556+
557+ func (bot * ircBot ) sendSaslEnd () {
558+ bot .SendRaw ("CAP END" )
559+ }
560+
544561// Read from the conn
545562func (bot * ircBot ) readSocket (quit chan struct {}, receive chan string , conn io.ReadWriteCloser ) {
546563
@@ -596,6 +613,29 @@ func (bot *ircBot) act(theLine *line.Line) {
596613 return
597614 }
598615
616+ isAskingForSasl := strings .ToUpper (theLine .Command ) == "CAP" && len (theLine .Args ) == 2 && strings .ToUpper (theLine .Args [1 ]) == "ACK" && theLine .Content == "sasl"
617+ if isAskingForSasl {
618+ bot .sendSaslStart ()
619+ return
620+ }
621+
622+ isAskingForSaslPass := theLine .User == "" && strings .ToUpper (theLine .Command ) == "AUTHENTICATE" && theLine .Args [0 ] == "+"
623+ if isAskingForSaslPass {
624+ bot .sendSaslPass ()
625+ return
626+ }
627+
628+ isSaslConfirm := theLine .User == "" && theLine .Command == "903"
629+ // After SASL is accepted, join all the channels
630+ if isSaslConfirm {
631+ bot .sendSaslEnd ()
632+ bot .Lock ()
633+ bot .isAuthenticating = false
634+ bot .Unlock ()
635+ bot .JoinAll ()
636+ return
637+ }
638+
599639 // NickServ interactions
600640 isNickServ := strings .Contains (theLine .User , "NickServ" )
601641
0 commit comments