Add support for SASL EXTERNAL mechanism
This commit is contained in:
parent
272c4d1650
commit
7309af6dbf
52
examples/simple-tor.go/simple-tor.go
Normal file
52
examples/simple-tor.go/simple-tor.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thoj/go-ircevent"
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
const addr = "libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion:6697"
|
||||||
|
|
||||||
|
// This demos connecting to Libera.Chat over TOR using SASL EXTERNAL and a TLS
|
||||||
|
// client cert. It assumes a TOR SOCKS service is running on localhost:9050
|
||||||
|
// and requires an existing account with a fingerprint already registered. See
|
||||||
|
// https://libera.chat/guides/connect#accessing-liberachat-via-tor for details.
|
||||||
|
//
|
||||||
|
// Pass the full path to your cert and key on the command line like so:
|
||||||
|
// $ go run simple-tor.go my-nick my-cert.pem my-key.pem
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Setenv("ALL_PROXY", "socks5h://localhost:9050")
|
||||||
|
nick, certFile := os.Args[1], os.Args[2]
|
||||||
|
keyFile := certFile
|
||||||
|
if len(os.Args) == 4 {
|
||||||
|
keyFile = os.Args[3]
|
||||||
|
}
|
||||||
|
clientCert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
ircnick1 := nick
|
||||||
|
irccon := irc.IRC(ircnick1, nick)
|
||||||
|
irccon.VerboseCallbackHandler = true
|
||||||
|
irccon.UseSASL = true
|
||||||
|
irccon.SASLMech = "EXTERNAL"
|
||||||
|
irccon.Debug = true
|
||||||
|
irccon.UseTLS = true
|
||||||
|
irccon.TLSConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
Certificates: []tls.Certificate{clientCert},
|
||||||
|
}
|
||||||
|
irccon.AddCallback("001", func(e *irc.Event) {})
|
||||||
|
irccon.AddCallback("376", func(e *irc.Event) {
|
||||||
|
log.Println("Quitting")
|
||||||
|
irccon.Quit()
|
||||||
|
})
|
||||||
|
err = irccon.Connect(addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
irccon.Loop()
|
||||||
|
}
|
@ -31,8 +31,8 @@ func (irc *Connection) setupSASLCallbacks(result chan<- *SASLResult) (callbacks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if e.Arguments[1] == "ACK" && listContains(e.Arguments[2], "sasl") {
|
if e.Arguments[1] == "ACK" && listContains(e.Arguments[2], "sasl") {
|
||||||
if irc.SASLMech != "PLAIN" {
|
if irc.SASLMech != "PLAIN" && irc.SASLMech != "EXTERNAL" {
|
||||||
result <- &SASLResult{true, errors.New("only PLAIN is supported")}
|
result <- &SASLResult{true, errors.New("only PLAIN and EXTERNAL supported")}
|
||||||
}
|
}
|
||||||
irc.SendRaw("AUTHENTICATE " + irc.SASLMech)
|
irc.SendRaw("AUTHENTICATE " + irc.SASLMech)
|
||||||
}
|
}
|
||||||
@ -41,6 +41,10 @@ func (irc *Connection) setupSASLCallbacks(result chan<- *SASLResult) (callbacks
|
|||||||
callbacks = append(callbacks, CallbackID{"CAP", id})
|
callbacks = append(callbacks, CallbackID{"CAP", id})
|
||||||
|
|
||||||
id = irc.AddCallback("AUTHENTICATE", func(e *Event) {
|
id = irc.AddCallback("AUTHENTICATE", func(e *Event) {
|
||||||
|
if irc.SASLMech == "EXTERNAL" {
|
||||||
|
irc.SendRaw("AUTHENTICATE +")
|
||||||
|
return
|
||||||
|
}
|
||||||
str := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s\x00%s\x00%s", irc.SASLLogin, irc.SASLLogin, irc.SASLPassword)))
|
str := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s\x00%s\x00%s", irc.SASLLogin, irc.SASLLogin, irc.SASLPassword)))
|
||||||
irc.SendRaw("AUTHENTICATE " + str)
|
irc.SendRaw("AUTHENTICATE " + str)
|
||||||
})
|
})
|
||||||
|
@ -41,3 +41,49 @@ func TestConnectionSASL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
irccon.Loop()
|
irccon.Loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 1. Register fingerprint with IRC network
|
||||||
|
// 2. Add SASLKeyPem="-----BEGIN PRIVATE KEY-----..."
|
||||||
|
// and SASLCertPem="-----BEGIN CERTIFICATE-----..."
|
||||||
|
// to CI environment as masked variables
|
||||||
|
func TestConnectionSASLExternal(t *testing.T) {
|
||||||
|
SASLServer := "irc.freenode.net:7000"
|
||||||
|
keyPem := os.Getenv("SASLKeyPem")
|
||||||
|
certPem := os.Getenv("SASLCertPem")
|
||||||
|
|
||||||
|
if certPem == "" || keyPem == "" {
|
||||||
|
t.Skip("Env vars SASLKeyPem SASLCertPem not present, skipping")
|
||||||
|
}
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
}
|
||||||
|
cert, err := tls.X509KeyPair([]byte(certPem), []byte(keyPem))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("SASL EXTERNAL cert creation failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
irccon := IRC("go-eventirc", "go-eventirc")
|
||||||
|
irccon.VerboseCallbackHandler = true
|
||||||
|
irccon.Debug = true
|
||||||
|
irccon.UseTLS = true
|
||||||
|
irccon.UseSASL = true
|
||||||
|
irccon.SASLMech = "EXTERNAL"
|
||||||
|
irccon.TLSConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
}
|
||||||
|
irccon.AddCallback("001", func(e *Event) { irccon.Join("#go-eventirc") })
|
||||||
|
|
||||||
|
irccon.AddCallback("366", func(e *Event) {
|
||||||
|
irccon.Privmsg("#go-eventirc", "Test Message SASL EXTERNAL\n")
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
irccon.Quit()
|
||||||
|
})
|
||||||
|
|
||||||
|
err = irccon.Connect(SASLServer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("SASL EXTERNAL failed: %s", err)
|
||||||
|
}
|
||||||
|
irccon.Loop()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user