Skip to content
This repository was archived by the owner on Nov 26, 2018. It is now read-only.

Commit e721bca

Browse files
authored
Merge pull request #47 from BotBotMe/sasl-auth
🚀 SASL auth
2 parents 7649e9c + 8035acc commit e721bca

2 files changed

Lines changed: 43 additions & 3 deletions

File tree

main_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ func TestBotBotIRC(t *testing.T) {
7070

7171
// Check IRC server expectations
7272

73-
if server.GotLength() != 6 {
74-
t.Fatal("Expected exactly 6 IRC messages from the bot. Got ", server.GotLength())
73+
if server.GotLength() != 7 {
74+
t.Fatal("Expected exactly 7 IRC messages from the bot. Got ", server.GotLength())
7575
}
7676

7777
glog.Infoln("[Debug] server.Got", server.Got)
78-
expect := []string{"PING", "USER", "NICK", "NickServ", "JOIN", "PRIVMSG"}
78+
expect := []string{"PING", "CAP", "USER", "NICK", "NickServ", "JOIN", "PRIVMSG"}
7979
for i := 0; i < 5; i++ {
8080
if !strings.Contains(string(server.Got[i]), expect[i]) {
8181
t.Error("Line ", i, " did not contain ", expect[i], ". It is: ", server.Got[i])

network/irc/irc.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ package irc
1010

1111
import (
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
545562
func (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

Comments
 (0)